diff --git a/Kconfig b/Kconfig new file mode 100644 index 0000000..c90d003 --- /dev/null +++ b/Kconfig @@ -0,0 +1,3 @@ +source "drivers/net/wireless/hugeic/hgic_smac/Kconfig" +source "drivers/net/wireless/hugeic/hgic_fmac/Kconfig" +source "drivers/net/wireless/hugeic/utils/Kconfig" diff --git a/Makefile b/Makefile index 39dc0b2..4bc31c1 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,8 @@ CURRENT_PATH := $(shell pwd) #FH8852 #ARCH := arm #COMPILER := arm-fullhan-linux-uclibcgnueabi- -#LINUX_KERNEL_PATH := /home/matt/FH8852/FH8856_IPC_V1.1.0_20190125/board_support/kernel/linux-3.0.8 +#LINUX_KERNEL_PATH := $(CURRENT_PATH)/../linux-3.0.8 +#CFLAGS += -DFH8852 -DCONFIG_USB_ZERO_PACKET #Hi3536d #ARCH := arm @@ -29,101 +30,78 @@ CURRENT_PATH := $(shell pwd) #MTK SDK ARCH := mips COMPILER := /opt/buildroot-gcc463/usr/bin/mipsel-linux- -LINUX_KERNEL_PATH := /home/dongyun/work/disk4/AH6001/RT288x_AHv1.2/source/linux-3.10.14.x +LINUX_KERNEL_PATH := $(CURRENT_PATH)/../source/linux-3.10.14.x #Raspberry Pi #ARCH := arm #LINUX_KERNEL := $(shell uname -r) #LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL) +################################################################################################# +#CFLAGS += -DCONFIG_HGIC_AH +#export CONFIG_HGIC_AH = y -CFLAGS += -DCONFIG_HGIC_AH -#CFLAGS += -DCONFIG_HGIC_2G +CFLAGS += -DCONFIG_HGIC_2G +export CONFIG_HGIC_2G = y -export CONFIG_HGIC_AH = y -#export CONFIG_HGIC_2G = y +#CFLAGS += -DCONFIG_HGIC_STABR +#export CONFIG_HGIC_STABR = y + +CFLAGS += -DCONFIG_SDIO_REINIT help: - @echo "-------------------------------------------------------------------------------------------------------------------" + @echo "--------------------------------------------------------------------------------------" @echo "usage:" - @echo " make smac : compile SMAC driver. generate 3 ko files : hgics.ko, hgic_sdio.ko hgic_usb.ko." - @echo " make smac_usb : compile SMAC driver. generate 1 ko file : hgics_usb.ko (combined hgics.ko and hgic_usb.ko)." - @echo " make smac_sdio: compile SMAC driver. generate 1 ko file : hgics_sdio.ko (combined hgics.ko and hgic_sdio.ko)." + @echo " make smac : compile SMAC driver. support sdio/usb interface. generate hgics.ko" + @echo " make smac_usb : compile SMAC driver. only support usb interface. generate hgics.ko" + @echo " make smac_sdio: compile SMAC driver. only support sdio interface. generate hgics.ko" @echo "" - @echo " make fmac : compile FMAC driver. generate 3 ko files : hgicf.ko, hgic_sdio.ko hgic_usb.ko." - @echo " make fmac_usb : compile FMAC driver. generate 1 ko file : hgicf_usb.ko (combined hgicf.ko and hgic_usb.ko)." - @echo " make fmac_sdio: compile FMAC driver. generate 1 ko file : hgicf_sdio.ko (combined hgicf.ko and hgic_sdio.ko)." + @echo " make fmac : compile FMAC driver. support sdio/usb interface. generate hgicf.ko" + @echo " make fmac_usb : compile FMAC driver. only support usb interface. generate hgicf.ko" + @echo " make fmac_sdio: compile FMAC driver. only support sdio interface. generate hgicf.ko" @echo "" @echo " make clean" - @echo "-------------------------------------------------------------------------------------------------------------------" - -smac: prepare _smac _driver_smac - -fmac: prepare _fmac _driver_fmac - -smac_usb: prepare _smac_usb - -smac_sdio: prepare _smac_sdio - -fmac_usb: prepare _fmac_usb - -fmac_sdio: prepare _fmac_sdio + @echo "--------------------------------------------------------------------------------------" prepare: mkdir -p ko -_fmac: - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_fmac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICF=hgicf EXTRA_CFLAGS=$(CFLAGS) modules - cp -f hgic_fmac/hgicf.ko ko/hgicf.ko - $(COMPILER)strip -g ko/hgicf.ko - -_smac: - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_smac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICS=hgics EXTRA_CFLAGS=$(CFLAGS) modules +smac: prepare + $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_smac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICS=m CONFIG_HGIC_USB=y CONFIG_HGIC_SDIO=y EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_SDIO -DCONFIG_HGIC_USB" modules cp -f hgic_smac/hgics.ko ko/hgics.ko $(COMPILER)strip -g ko/hgics.ko -_fmac_sdio: - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_fmac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICF=hgicf_sdio EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_SDIOIN" modules - cp -f hgic_fmac/hgicf_sdio.ko ko/hgicf_sdio.ko - $(COMPILER)strip -g ko/hgicf_sdio.ko - -_fmac_usb: - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_fmac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICF=hgicf_usb EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_USBIN" modules - cp -f hgic_fmac/hgicf_usb.ko ko/hgicf_usb.ko - $(COMPILER)strip -g ko/hgicf_usb.ko - -_smac_sdio: - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_smac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICS=hgics_sdio EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_SDIOIN" modules - cp -f hgic_smac/hgics_sdio.ko ko/hgics_sdio.ko - $(COMPILER)strip -g ko/hgics_sdio.ko - -_smac_usb: - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_smac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICS=hgics_usb EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_USBIN" modules - cp -f hgic_smac/hgics_usb.ko ko/hgics_usb.ko - $(COMPILER)strip -g ko/hgics_usb.ko +smac_usb: prepare + $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_smac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICS=m CONFIG_HGIC_USB=y EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_USB" modules + cp -f hgic_smac/hgics.ko ko/hgics.ko + $(COMPILER)strip -g ko/hgics.ko -_driver_fmac: - cp -f hgic_fmac/Module.symvers utils/Module.symvers - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/utils ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) EXTRA_CFLAGS=$(CFLAGS) modules - cp -f utils/hgic_usb.ko ko/hgic_usb.ko - cp -f utils/hgic_sdio.ko ko/hgic_sdio.ko - $(COMPILER)strip -g ko/hgic_usb.ko - $(COMPILER)strip -g ko/hgic_sdio.ko +smac_sdio: prepare + $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_smac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICS=m CONFIG_HGIC_SDIO=y EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_SDIO" modules + cp -f hgic_smac/hgics.ko ko/hgics.ko + $(COMPILER)strip -g ko/hgics.ko -_driver_smac: - cp -f hgic_smac/Module.symvers utils/Module.symvers - $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/utils ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) EXTRA_CFLAGS=$(CFLAGS) modules - cp -f utils/hgic_usb.ko ko/hgic_usb.ko - cp -f utils/hgic_sdio.ko ko/hgic_sdio.ko - $(COMPILER)strip -g ko/hgic_usb.ko - $(COMPILER)strip -g ko/hgic_sdio.ko +fmac: prepare + $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_fmac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICF=m CONFIG_HGIC_USB=y CONFIG_HGIC_SDIO=y EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_SDIO -DCONFIG_HGIC_USB" modules + cp -f hgic_fmac/hgicf.ko ko/hgicf.ko + $(COMPILER)strip -g ko/hgicf.ko + +fmac_usb: prepare + $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_fmac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICF=m CONFIG_HGIC_USB=y EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_USB" modules + cp -f hgic_fmac/hgicf.ko ko/hgicf.ko + $(COMPILER)strip -g ko/hgicf.ko + +fmac_sdio: prepare + $(MAKE) -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH)/hgic_fmac ARCH=$(ARCH) CROSS_COMPILE=$(COMPILER) CONFIG_HGICF=m CONFIG_HGIC_SDIO=y EXTRA_CFLAGS="$(CFLAGS) -DCONFIG_HGIC_SDIO" modules + cp -f hgic_fmac/hgicf.ko ko/hgicf.ko + $(COMPILER)strip -g ko/hgicf.ko clean: - rm -fr Module.symvers ; rm -fr Module.markers ; rm -fr modules.order - cd hgic_fmac ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko Module.symvers modules.order - cd hgic_smac ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko Module.symvers modules.order - cd hgic_smac/umac ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko - cd hgic_smac/umac/cfg80211 ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko - cd hgic_smac/umac/mac80211 ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko - cd utils ; rm -fr *.mod.c *.mod *.o .*.cmd *.ko Module.symvers modules.order - rm -rf ko + @find ./ -name "*.o" | xargs rm -fv + @find ./ -name "*.ko" | xargs rm -fv + @find ./ -name "*.cmd" | xargs rm -fv + @find ./ -name "*.symvers" | xargs rm -fv + @find ./ -name "*.markers" | xargs rm -fv + @find ./ -name "*.order" | xargs rm -fv + @find ./ -name "*.mod.c" | xargs rm -fv + @rm -rf ko diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..adeb20f --- /dev/null +++ b/Makefile.in @@ -0,0 +1,3 @@ +#this makefile is used to build driver with kernel +obj-$(CONFIG_HGICS) += hgic_smac/ +obj-$(CONFIG_HGICF) += hgic_fmac/ diff --git a/build_ahtool.sh b/build_ahtool.sh new file mode 100644 index 0000000..9051977 --- /dev/null +++ b/build_ahtool.sh @@ -0,0 +1,5 @@ +#! /bin/sh + +rm -rf bin; mkdir bin +cd tools/ah_tool/;./build.sh;cd - +cp -fv tools/ah_tool/bin/* bin diff --git a/changelog.txt b/changelog.txt index c4b9248..d74a2cb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,50 +1,53 @@ -2022/01/12 - 修改bug:sdio remove过程中,执行hgic_core_remove时可能会rx data,此时会出现死机现象。 - ------------------------------------------------------ -2022/01/10 - 固件下载功能优化:在固件下载阶段,屏蔽其它数据和cmd的发送, 避免干扰固件下载过程。 - ------------------------------------------------------ -2021/12/22 - fmac: 新增event:HGIC_EVENT_UNPAIR_STA, 解除配对时,固件产生此event。 - 新增:tx maxcnt 命令,用于设置最大帧重传次数。 +2023/08/04 + 1. 支持接口聚合收发功能,此功能默认关闭,1.x版本固件不支持聚合功能。 + 2. sleep流程调整:sleep命令发送完成后立即设置sleep标识,拦截后续所有的数据;sleep命令的resp失败时再清除sleep标识。 + 3. 修复sdio remove流程低概率异常出错问题。 + 4. 修复detect_work功能异常,造成驱动不执行reload流程。 + 5. 调整tx window最小值,多预留1个window,保证驱动命令可以发送。 ------------------------------------------------------ -2021/11/19 - fmac: 添加AP隐藏功能, iwpriv hg0 set ap_hide 1 +2023/06/08 + 添加 hgic_iwpriv_send_custmgmt 和 hgic_iwpriv_send_custmgmt2 API。支持发送自定义管理帧。 + +2023/05/31 + set agg_cnt/get agg_cnt 修改,支持设置 tx agg 和 rx agg。 + 修复get signal错误 + 添加漫游参数,支持设置 漫游rssi切换差值 和 rssi 检测周期。 + 新增漫游成功事件: HGIC_EVENT_ROAM_CONECTED + 添加 hgpriv hg0 open/close 命令 + hgics_rx_sigfrm: reserve hgic_frm_hdr。 + +2023/05/06 + fix bug: detect_work 被 tx_complete触发执行时,hg->bus->reinit 可能为NULL,造成驱动出错。 ------------------------------------------------------ -2021/11/08 - 解决驱动卸载死机问题。 +2023/04/26 + fmac: 添加 hgic_iwpriv_get_sta_info 接口。 ------------------------------------------------------ -2021/11/01 - fmac: 添加漫游功能设置接口。 +2023/04/21 + 添加 hgic_iwpriv_set_max_tx_delay 接口,设置最大tx busy delay时间,超过就强行发送。 + +2023/04/14 + tx fail 时触发 detect_work,用于快速检测到模块复位。 + fmac: needed_headroom 多预留4byte。 +2023/4/11 + test_app/iwpriv.c:使用 blenc_mode 全局变量代替宏定义 BLE_ADVCFG, 支持动态切换BLE配网模式。 + + +2023/4/7 + iwpriv.c: get bssid 同时返回AID信息。 + +2022/12/24 + 数据接收调整:if_sdio/if_usb 使用预分配的buffer接收数据,根据实际长度再copy到skb。 + 避免部分主控出现alloc skb fail。 + +2021/10/28 ----------------------------------------------------- -2021/09/28 - smac: - 1. 修改bug: remove 时 先 确保 alive_timer/alive_work/delay_init 已经停止运行 - 2. hgic_frm_hdr.tx_info : 清零 - 3. ETH_P_PAE 类型数据使用最高优先级 - fmac: - 1. 修改bug: remove 时 先 确保 alive_timer/alive_work/delay_init 已经停止运行 + 驱动代码整理,解决大小端模式问题。 ----------------------------------------------------- 2021/09/27 添加 macfilter/atcmd 命令接口。 ------------------------------------------------------ -2021/09/23 - 1. 优化固件下载功能,减少对 memory 的需求。 - 2. 模块监测功能修改:接口只要支持reinit,就默认开启该功能,用于监测是否需要重新下载固件。 - ------------------------------------------------------ -2021/09/13 - get module_type 修改,定义了 struct hgic_module_hwinfo 结构体。 - 使用方法参考: hgic_fmac.c - ----------------------------------------------------- 2021/08/26 添加 HGIC_HDR_TYPE_CMD2 和 HGIC_HDR_TYPE_EVENT2,扩展 cmd id 和 event id 到 uint16. diff --git a/doc/泰芯Linux_WiFi_FMAC驱动开发指南.pdf b/doc/泰芯Linux_WiFi_FMAC驱动开发指南.pdf new file mode 100644 index 0000000..0693959 Binary files /dev/null and b/doc/泰芯Linux_WiFi_FMAC驱动开发指南.pdf differ diff --git a/fmac.sh b/fmac.sh deleted file mode 100755 index 6f1e18e..0000000 --- a/fmac.sh +++ /dev/null @@ -1,83 +0,0 @@ -#! /bin/sh - -#interface name -IFNAME="hg0" - -# ko file path -FMAC_KO_PATH="/lib/modules/3.10.14/kernel/drivers/net/wireless/hugeic/hgic_fmac/hgicf.ko" -USB_KO_PATH="/lib/modules/3.10.14/kernel/drivers/net/wireless/hugeic/utils/hgic_usb.ko" -SDIO_KO_PATH="/lib/modules/3.10.14/kernel/drivers/net/wireless/hugeic/utils/hgic_sdio.ko" - -#read paramters from system. -AH_MODE=ap -AH_SSID=ah_test_ssid -AH_PSK=00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff -AH_KEY_MGMT=NONE -AH_FREQ_START=7600 -AH_FREQ_END=7680 -AH_BSS_BW=8 -AH_TX_MCS=255 -AH_CHAN_LIST= - -#set default values -[ -z "$AH_MODE" ] && AH_MODE="ap" -[ -z "$AH_FREQ_START" ] && AH_FREQ_START="7800" -[ -z "$AH_FREQ_END" ] && AH_FREQ_END="8000" -[ -z "$AH_BSS_BW" ] && AH_BSS_BW="8" -[ -z "$AH_TX_MCS" ] && AH_TX_MCS="7" -[ -z "$AH_CHANNEL" ] && AH_CHANNEL="1" -[ -z "$AH_ACS" ] && AH_ACS="0" -[ -z "$AH_ACS_TM" ] && AH_ACS_TM="10" -[ -z "$AH_TX_POWER" ] && AH_TX_POWER="1" -[ "$AH_MODE" == "sta" ] && AH_ACS="0" -[ "$AH_ACS" == "1" ] && AH_CHANNEL="1" - -#insmod driver -ko_exist=$(lsmod|grep hgicf) -if [ -z "$ko_exist" ]; then -[ -n "$FMAC_KO_PATH" ] && insmod $FMAC_KO_PATH $ARG_IF_TEST -[ -n "$SDIO_KO_PATH" ] && insmod $SDIO_KO_PATH -[ -n "$USB_KO_PATH" ] && insmod $USB_KO_PATH -sleep 1 -fi - -#set param -CONN_STATE=$(cat /proc/hgic/conn_state|grep CONNECTED) -if [ -z "$CONN_STATE" ]; then - ifconfig $IFNAME down - iwpriv $IFNAME set freq_range=$AH_FREQ_START,$AH_FREQ_END,$AH_BSS_BW - iwpriv $IFNAME set mode=$AH_MODE - iwpriv $IFNAME set bss_bw=$AH_BSS_BW - iwpriv $IFNAME set tx_mcs=$AH_TX_MCS - iwpriv $IFNAME set tx_power=$AH_TX_POWER - iwpriv $IFNAME set channel=$AH_CHANNEL - iwpriv $IFNAME set acs="$AH_ACS,$AH_ACS_TM" - if [ x"$AH_KEY_MGMT" == "xWPA-PSK" ]; then - iwpriv $IFNAME set key_mgmt=WPA-PSK - iwpriv $IFNAME set wpa_psk=$AH_PSK - else - iwpriv $IFNAME set key_mgmt=NONE - fi - iwpriv $IFNAME set ssid=$AH_SSID - #save config - iwpriv $IFNAME save - [ "$AH_BSS_BW" == "1" ] && ifconfig $IFNAME mtu 380 -fi - -#up interface -ifconfig $IFNAME up - - -############################################################ -# 可以设置驱动参数文件,由驱动自动加载参数,需要如下3个步骤: -# 1. 生成参数文件:/etc/hgicf.conf,内容如下: -# freq_range=9000,9240,8 -# mode=ap -# ssid=ah_test_ssid -# key_mgmt=WPA-PSK -# wpa_psk=00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff -# [以上参数是最基本的参数设置,其他参数设置请参考 Linux开发指南] -# -# 2. insmod 驱动 -# 3. ifconfig up 接口 -########################################################### diff --git a/hgic.h b/hgic.h index f963318..212aad2 100644 --- a/hgic.h +++ b/hgic.h @@ -10,6 +10,10 @@ extern "C" { #define HGIC_CMD_START 0 #endif +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + typedef void (*hgic_init_cb)(void *args); typedef void (*hgic_event_cb)(char *ifname, int event, int param1, int param2); @@ -17,7 +21,7 @@ struct hgic_bss_info { unsigned char bssid[6]; unsigned char ssid[32]; unsigned char encrypt; - char signal; + signed char signal; unsigned short freq; }; @@ -27,14 +31,19 @@ struct hgic_fw_info { unsigned short chip_id; unsigned short cpu_id; unsigned char mac[6]; + unsigned char resv[2]; + unsigned int app_version; + unsigned int smt_dat; }; struct hgic_sta_info { - unsigned char aid; - unsigned char ps:1; - unsigned char addr[6]; - char rssi; - char evm; + unsigned char aid; + unsigned char ps:1; + unsigned char addr[6]; + signed char rssi; + signed char evm; + signed char tx_snr; + signed char rx_snr; }; struct hgic_freqinfo { @@ -53,163 +62,440 @@ struct hgic_module_hwinfo{ }; }; +struct hgic_txq_param { + unsigned short txop; + unsigned short cw_min; + unsigned short cw_max; + unsigned char aifs; + unsigned char acm; +}; + +struct hgic_mcast_txparam { + unsigned char dupcnt; + unsigned char tx_bw; + unsigned char tx_mcs; + unsigned char clearch; +}; + +struct hgic_rx_info { + unsigned char band; + unsigned char mcs: 4, bw: 4; + char evm; + char signal; + unsigned short freq; + short freq_off; + unsigned char rx_flags; + unsigned char antenna; + unsigned char nss : 4, s1g_nss : 4; + unsigned char vht_flag : 3, s1g_flag : 5; +}; + +struct hgic_tx_info { + unsigned char band; + unsigned char tx_bw; + unsigned char tx_mcs; + unsigned char antenna; + unsigned int tx_flags; + unsigned int tx_flags2; +}; + +struct bt_rx_info { + unsigned char channel; //current channel + unsigned char con_handle; //hci handle + signed char rssi; + unsigned char frm_type; + unsigned int rev; +}; + + +/*data packet header*/ +struct hgic_hdr { + unsigned short magic; + unsigned char type; + unsigned char ifidx: 4, flags: 4; + unsigned short length; + unsigned short cookie; +} __packed; + +struct hgic_frm_hdr { + struct hgic_hdr hdr; + union { + struct hgic_rx_info rx_info; + struct hgic_tx_info tx_info; + unsigned char rev[24]; + }; +} __packed; + +struct hgic_frm_hdr2 { + struct hgic_hdr hdr; +} __packed; + + +/*contro pakcet header*/ +struct hgic_ctrl_hdr { + struct hgic_hdr hdr; + union { + struct { + unsigned char cmd_id; + short status; + } cmd; + struct { + unsigned short cmd_id; + short status; + } cmd2; + struct { + unsigned char event_id; + short value; + } event; + struct { + unsigned short event_id; + short value; + } event2; + struct { + unsigned char type; + } hci; + unsigned char info[4]; + }; +} __packed; + +struct hgic_key_conf { + unsigned int cipher; + unsigned int flags; + unsigned char keyidx; + unsigned char keylen; + unsigned char key[0]; +}; + +struct hgic_cca_ctl { + char start_th; + char mid_th; + char ed_th; + /* CCA auto adjustment. + * When the cca automatic adjustment takes effect, the + * above three parameters are invalid. + */ + char auto_en : 1; +}; + +struct hgic_acs_result{ + unsigned int freq;//KHz + unsigned char sync_cnt; + signed char min; + signed char max; + signed char avg; +}; + +struct hgic_fallback_mcs { + unsigned char original_type; + unsigned char original_mcs; + unsigned char fallback_type; + unsigned char fallback_mcs; +}; + +#define HDR_CMDID(ctl) ((ctl)->hdr.type==HGIC_HDR_TYPE_CMD2? le16_to_cpu((ctl)->cmd2.cmd_id):(ctl)->cmd.cmd_id) +#define HDR_EVTID(ctl) ((ctl)->hdr.type==HGIC_HDR_TYPE_EVENT2?le16_to_cpu((ctl)->event2.event_id):(ctl)->event.event_id) +#define HDR_CMDID_SET(ctl, id) if(id>255){\ + (ctl)->hdr.type =HGIC_HDR_TYPE_CMD2;\ + (ctl)->cmd2.cmd_id = cpu_to_le16(id);\ + }else{\ + (ctl)->hdr.type =HGIC_HDR_TYPE_CMD;\ + (ctl)->cmd.cmd_id = id;\ + } +#define HDR_EVTID_SET(ctl, id) if(id>255){\ + (ctl)->hdr.type =HGIC_HDR_TYPE_EVENT2;\ + (ctl)->event2.event_id = cpu_to_le16(id);\ + }else{\ + (ctl)->hdr.type =HGIC_HDR_TYPE_EVENT;\ + (ctl)->event.event_id = id;\ + } + +enum hgic_hdr_type { + HGIC_HDR_TYPE_ACK = 1, + HGIC_HDR_TYPE_FRM = 2, + HGIC_HDR_TYPE_CMD = 3, + HGIC_HDR_TYPE_EVENT = 4, + HGIC_HDR_TYPE_FIRMWARE = 5, + HGIC_HDR_TYPE_NLMSG = 6, + HGIC_HDR_TYPE_BOOTDL = 7, + HGIC_HDR_TYPE_TEST = 8, + HGIC_HDR_TYPE_FRM2 = 9, + HGIC_HDR_TYPE_TEST2 = 10, + HGIC_HDR_TYPE_SOFTFC = 11, + HGIC_HDR_TYPE_OTA = 12, + HGIC_HDR_TYPE_CMD2 = 13, + HGIC_HDR_TYPE_EVENT2 = 14, + HGIC_HDR_TYPE_BOOTDL_DATA = 15, + HGIC_HDR_TYPE_IFBR = 16, + HGIC_HDR_TYPE_BEACON = 17, + HGIC_HDR_TYPE_AGGFRM = 18, + HGIC_HDR_TYPE_BLUETOOTH = 19, + + HGIC_HDR_TYPE_MAX, +}; + enum hgic_cmd { - HGIC_CMD_DEV_OPEN = HGIC_CMD_START + 0x01, // 1 - HGIC_CMD_DEV_CLOSE, // 2 - HGIC_CMD_SET_MAC, // 3 - HGIC_CMD_SET_SSID, // 4 - HGIC_CMD_SET_BSSID, // 5 - HGIC_CMD_SET_COUNTERY, // 6 - HGIC_CMD_SET_CHANNEL, // 7 - HGIC_CMD_SET_CENTER_FREQ, // 8 - HGIC_CMD_SET_RTS_THRESHOLD, // 9 - HGIC_CMD_SET_FRG_THRESHOLD, // 10 - HGIC_CMD_SET_KEY_MGMT, // 11 - HGIC_CMD_SET_WPA_PSK, // 12 - HGIC_CMD_SET_KEY, // 13 - HGIC_CMD_SCAN, // 14 - HGIC_CMD_GET_SCAN_LIST, // 15 - HGIC_CMD_SET_BSSID_FILTER, // 16 - HGIC_CMD_DISCONNECT, // 17 - HGIC_CMD_GET_BSSID, // 18 - HGIC_CMD_SET_WBNAT, // 19 - HGIC_CMD_GET_STATUS, // 20 - HGIC_CMD_SET_LISTEN_INTERVAL, // 21 - HGIC_CMD_SET_TX_POWER, // 22 - HGIC_CMD_GET_TX_POWER, // 23 - HGIC_CMD_SET_TX_LCOUNT, // 24 - HGIC_CMD_SET_TX_SCOUNT, // 25 - HGIC_CMD_ADD_STA, // 26 - HGIC_CMD_REMOVE_STA, // 27 - HGIC_CMD_SET_TX_BW, // 28 - HGIC_CMD_SET_TX_MCS, // 29 - HGIC_CMD_SET_FREQ_RANGE, // 30 - HGIC_CMD_ACS_ENABLE, // 31 - HGIC_CMD_SET_PRIMARY_CHAN, // 32 - HGIC_CMD_SET_BG_RSSI, // 33 - HGIC_CMD_SET_BSS_BW, // 34 - HGIC_CMD_TESTMODE_CMD, // 35 - HGIC_CMD_SET_AID, // 36 - HGIC_CMD_GET_FW_STATE, // 37 - HGIC_CMD_SET_TXQ_PARAM, // 38 - HGIC_CMD_SET_CHAN_LIST, // 39 - HGIC_CMD_GET_CONN_STATE, // 40 - HGIC_CMD_SET_WORK_MODE, // 41 - HGIC_CMD_SET_PAIRED_STATIONS, // 42 - HGIC_CMD_GET_FW_INFO, // 43 - HGIC_CMD_PAIRING, // 44 - HGIC_CMD_GET_TEMPERATURE, // 45 - HGIC_CMD_ENTER_SLEEP, // 46 - HGIC_CMD_OTA, // 47 - HGIC_CMD_GET_SSID, // 48 - HGIC_CMD_GET_WPA_PSK, // 49 - HGIC_CMD_GET_SIGNAL, // 50 - HGIC_CMD_GET_TX_BITRATE, // 51 - HGIC_CMD_SET_BEACON_INT, // 52 - HGIC_CMD_GET_STA_LIST, // 53 - HGIC_CMD_SAVE_CFG, // 54 - HGIC_CMD_JOIN_GROUP, // 55 - HGIC_CMD_SET_ETHER_TYPE, // 56 - HGIC_CMD_GET_STA_COUNT, // 57 - HGIC_CMD_SET_HEARTBEAT_INT, // 58 - HGIC_CMD_SET_MCAST_KEY, // 59 - HGIC_CMD_SET_AGG_CNT, // 60 - HGIC_CMD_GET_AGG_CNT, // 61 - HGIC_CMD_GET_BSS_BW , // 62 - HGIC_CMD_GET_FREQ_RANGE, // 63 - HGIC_CMD_GET_CHAN_LIST, // 64 - HGIC_CMD_RADIO_ONOFF, // 65 - HGIC_CMD_SET_PS_HEARTBEAT, // 66 - HGIC_CMD_SET_WAKEUP_STA, // 67 - HGIC_CMD_SET_PS_HEARTBEAT_RESP, // 68 - HGIC_CMD_SET_PS_WAKEUP_DATA, // 69 - HGIC_CMD_SET_PS_CONNECT, // 70 - HGIC_CMD_SET_BSS_MAX_IDLE, // 71 - HGIC_CMD_SET_WKIO_MODE, // 72 - HGIC_CMD_SET_DTIM_PERIOD, // 73 - HGIC_CMD_SET_PS_MODE, // 74 - HGIC_CMD_LOAD_DEF, // 75 - HGIC_CMD_DISASSOC_STA, // 76 - HGIC_CMD_SET_APLOST_TIME, // 77 - HGIC_CMD_GET_WAKEUP_REASON, // 78 - HGIC_CMD_UNPAIR, // 79 - HGIC_CMD_SET_AUTO_CHAN_SWITCH, // 80 - HGIC_CMD_SET_REASSOC_WKHOST, // 81 - HGIC_CMD_SET_WAKEUP_IO, // 82 - HGIC_CMD_DBGINFO_OUTPUT, // 83 - HGIC_CMD_SET_SYSDBG, // 84 - HGIC_CMD_SET_AUTO_SLEEP_TIME, // 85 - HGIC_CMD_GET_KEY_MGMT, // 86 - HGIC_CMD_SET_PAIR_AUTOSTOP, // 87 - HGIC_CMD_SET_SUPPER_PWR, // 88 - HGIC_CMD_SET_REPEATER_SSID, // 89 - HGIC_CMD_SET_REPEATER_PSK, // 90 - HGIC_CMD_CFG_AUTO_SAVE, // 91 - HGIC_CMD_SEND_CUST_MGMT, // 92 - HGIC_CMD_GET_BATTERY_LEVEL, // 93 - HGIC_CMD_SET_DCDC13, // 94 - HGIC_CMD_SET_ACKTMO, // 95 - HGIC_CMD_GET_MODULETYPE, // 96 - HGIC_CMD_PA_PWRCTRL_DIS, // 97 - HGIC_CMD_SET_DHCPC, // 98 - HGIC_CMD_GET_DHCPC_RESULT, // 99 - HGIC_CMD_SET_WKUPDATA_MASK, // 100 - HGIC_CMD_GET_WKDATA_BUFF, // 101 - HGIC_CMD_GET_DISASSOC_REASON, // 102 - HGIC_CMD_SET_WKUPDATA_SAVEEN, // 103 - HGIC_CMD_SET_CUST_DRIVER_DATA, // 104 - HGIC_CMD_SET_MCAST_TXPARAM, // 105 - HGIC_CMD_SET_STA_FREQINFO, // 106 - HGIC_CMD_SET_RESET_STA, // 107 - HGIC_CMD_SET_UART_FIXLEN, // 108 - HGIC_CMD_GET_UART_FIXLEN, // 109 - HGIC_CMD_SET_ANT_AUTO, // 110 - HGIC_CMD_SET_ANT_SEL, // 111 - HGIC_CMD_GET_ANT_SEL, // 112 - HGIC_CMD_SET_WKUP_HOST_REASON, // 113 - HGIC_CMD_SET_MAC_FILTER_EN, // 114 - HGIC_CMD_SET_ATCMD, // 115 - HGIC_CMD_SET_ROAMING, // 116 - HGIC_CMD_SET_AP_HIDE, // 117 - HGIC_CMD_SET_DUAL_ANT, // 118 - HGIC_CMD_SET_MAX_TCNT, // 119 - HGIC_CMD_SET_ASSERT_HOLDUP, // 120 - HGIC_CMD_SET_AP_PSMODE_EN, // 121 - HGIC_CMD_SET_DUPFILTER_EN, // 122 - HGIC_CMD_SET_DIS_1V1_M2U, // 123 + HGIC_CMD_DEV_OPEN = 1, /* fmac/smac */ + HGIC_CMD_DEV_CLOSE = 2, /* fmac/smac */ + HGIC_CMD_SET_MAC = 3, /* fmac/smac */ + HGIC_CMD_SET_SSID = 4, /* fmac */ + HGIC_CMD_SET_BSSID = 5, /* fmac */ + HGIC_CMD_SET_COUNTERY = 6, /* fmac */ + HGIC_CMD_SET_CHANNEL = 7, /* fmac */ + HGIC_CMD_SET_CENTER_FREQ = 8, /* smac */ + HGIC_CMD_SET_RTS_THRESHOLD = 9, /* smac */ + HGIC_CMD_SET_FRG_THRESHOLD = 10, /* smac */ + HGIC_CMD_SET_KEY_MGMT = 11, /* fmac */ + HGIC_CMD_SET_WPA_PSK = 12, /* fmac */ + HGIC_CMD_SET_KEY = 13, /* smac */ + HGIC_CMD_SCAN = 14, /* fmac */ + HGIC_CMD_GET_SCAN_LIST = 15, /* fmac */ + HGIC_CMD_SET_BSSID_FILTER = 16, /* fmac */ + HGIC_CMD_DISCONNECT = 17, /* fmac */ + HGIC_CMD_GET_BSSID = 18, /* fmac */ + HGIC_CMD_SET_WBNAT = 19, /* unused */ + HGIC_CMD_GET_STATUS = 20, /* fmac */ + HGIC_CMD_SET_LISTEN_INTERVAL = 21, /* smac */ + HGIC_CMD_SET_TX_POWER = 22, /* fmac/smac */ + HGIC_CMD_GET_TX_POWER = 23, /* fmac/smac */ + HGIC_CMD_SET_TX_LCOUNT = 24, /* unused */ + HGIC_CMD_SET_TX_SCOUNT = 25, /* unused */ + HGIC_CMD_ADD_STA = 26, /* smac */ + HGIC_CMD_REMOVE_STA = 27, /* smac */ + HGIC_CMD_SET_TX_BW = 28, /* fmac */ + HGIC_CMD_SET_TX_MCS = 29, /* fmac/smac */ + HGIC_CMD_SET_FREQ_RANGE = 30, /* fmac */ + HGIC_CMD_ACS_ENABLE = 31, /* fmac */ + HGIC_CMD_SET_PRIMARY_CHAN = 32, /* fmac */ + HGIC_CMD_SET_BG_RSSI = 33, /* fmac */ + HGIC_CMD_SET_BSS_BW = 34, /* fmac/smac */ + HGIC_CMD_TESTMODE_CMD = 35, /* fmac/smac */ + HGIC_CMD_SET_AID = 36, /* smac */ + HGIC_CMD_GET_FW_STATE = 37, /* unused */ + HGIC_CMD_SET_TXQ_PARAM = 38, /* smac */ + HGIC_CMD_SET_CHAN_LIST = 39, /* fmac */ + HGIC_CMD_GET_CONN_STATE = 40, /* fmac */ + HGIC_CMD_SET_WORK_MODE = 41, /* fmac */ + HGIC_CMD_SET_PAIRED_STATIONS = 42, /* fmac */ + HGIC_CMD_GET_FW_INFO = 43, /* fmac/smac */ + HGIC_CMD_PAIRING = 44, /* fmac */ + HGIC_CMD_GET_TEMPERATURE = 45, /* fmac/smac */ + HGIC_CMD_ENTER_SLEEP = 46, /* fmac */ + HGIC_CMD_OTA = 47, /* fmac */ + HGIC_CMD_GET_SSID = 48, /* fmac */ + HGIC_CMD_GET_WPA_PSK = 49, /* fmac */ + HGIC_CMD_GET_SIGNAL = 50, /* fmac */ + HGIC_CMD_GET_TX_BITRATE = 51, /* fmac */ + HGIC_CMD_SET_BEACON_INT = 52, /* fmac */ + HGIC_CMD_GET_STA_LIST = 53, /* fmac */ + HGIC_CMD_SAVE_CFG = 54, /* fmac */ + HGIC_CMD_JOIN_GROUP = 55, /* unused */ + HGIC_CMD_SET_ETHER_TYPE = 56, /* unused */ + HGIC_CMD_GET_STA_COUNT = 57, /* fmac */ + HGIC_CMD_SET_HEARTBEAT_INT = 58, /* fmac */ + HGIC_CMD_SET_MCAST_KEY = 59, /* unused */ + HGIC_CMD_SET_AGG_CNT = 60, /* fmac/smac */ + HGIC_CMD_GET_AGG_CNT = 61, /* fmac/smac */ + HGIC_CMD_GET_BSS_BW = 62, /* fmac/smac */ + HGIC_CMD_GET_FREQ_RANGE = 63, /* fmac */ + HGIC_CMD_GET_CHAN_LIST = 64, /* fmac */ + HGIC_CMD_RADIO_ONOFF = 65, /* fmac/smac */ + HGIC_CMD_SET_PS_HEARTBEAT = 66, /* fmac */ + HGIC_CMD_SET_WAKEUP_STA = 67, /* fmac */ + HGIC_CMD_SET_PS_HEARTBEAT_RESP = 68, /* fmac */ + HGIC_CMD_SET_PS_WAKEUP_DATA = 69, /* fmac */ + HGIC_CMD_SET_PS_CONNECT = 70, /* fmac */ + HGIC_CMD_SET_BSS_MAX_IDLE = 71, /* fmac */ + HGIC_CMD_SET_WKIO_MODE = 72, /* fmac */ + HGIC_CMD_SET_DTIM_PERIOD = 73, /* fmac */ + HGIC_CMD_SET_PS_MODE = 74, /* fmac */ + HGIC_CMD_LOAD_DEF = 75, /* fmac */ + HGIC_CMD_DISASSOC_STA = 76, /* fmac */ + HGIC_CMD_SET_APLOST_TIME = 77, /* fmac */ + HGIC_CMD_GET_WAKEUP_REASON = 78, /* fmac */ + HGIC_CMD_UNPAIR = 79, /* fmac */ + HGIC_CMD_SET_AUTO_CHAN_SWITCH = 80, /* fmac */ + HGIC_CMD_SET_REASSOC_WKHOST = 81, /* fmac */ + HGIC_CMD_SET_WAKEUP_IO = 82, /* fmac */ + HGIC_CMD_DBGINFO_OUTPUT = 83, /* fmac/smac */ + HGIC_CMD_SET_SYSDBG = 84, /* fmac/smac */ + HGIC_CMD_SET_AUTO_SLEEP_TIME = 85, /* fmac */ + HGIC_CMD_GET_KEY_MGMT = 86, /* fmac */ + HGIC_CMD_SET_PAIR_AUTOSTOP = 87, /* fmac */ + HGIC_CMD_SET_SUPER_PWR = 88, /* fmac */ + HGIC_CMD_SET_REPEATER_SSID = 89, /* fmac */ + HGIC_CMD_SET_REPEATER_PSK = 90, /* fmac */ + HGIC_CMD_CFG_AUTO_SAVE = 91, /* fmac */ + HGIC_CMD_SEND_CUST_MGMT = 92, /* fmac */ + HGIC_CMD_GET_BATTERY_LEVEL = 93, /* unused */ + HGIC_CMD_SET_DCDC13 = 94, /* fmac */ + HGIC_CMD_SET_ACKTMO = 95, /* fmac/smac */ + HGIC_CMD_GET_MODULETYPE = 96, /* fmac/smac */ + HGIC_CMD_PA_PWRCTRL_DIS = 97, /* fmac */ + HGIC_CMD_SET_DHCPC = 98, /* fmac */ + HGIC_CMD_GET_DHCPC_RESULT = 99, /* fmac */ + HGIC_CMD_SET_WKUPDATA_MASK = 100, /* fmac */ + HGIC_CMD_GET_WKDATA_BUFF = 101, /* fmac */ + HGIC_CMD_GET_DISASSOC_REASON = 102, /* fmac */ + HGIC_CMD_SET_WKUPDATA_SAVEEN = 103, /* fmac */ + HGIC_CMD_SET_CUST_DRIVER_DATA = 104, /* fmac */ + HGIC_CMD_SET_MCAST_TXPARAM = 105, /* unused */ + HGIC_CMD_SET_STA_FREQINFO = 106, /* fmac */ + HGIC_CMD_SET_RESET_STA = 107, /* fmac */ + HGIC_CMD_SET_UART_FIXLEN = 108, /* unused */ + HGIC_CMD_GET_UART_FIXLEN = 109, /* unused */ + HGIC_CMD_SET_ANT_AUTO = 110, /* fmac */ + HGIC_CMD_SET_ANT_SEL = 111, /* fmac */ + HGIC_CMD_GET_ANT_SEL = 112, /* fmac */ + HGIC_CMD_SET_WKUP_HOST_REASON = 113, /* fmac */ + HGIC_CMD_SET_MAC_FILTER_EN = 114, /* unused */ + HGIC_CMD_SET_ATCMD = 115, /* fmac/smac */ + HGIC_CMD_SET_ROAMING = 116, /* fmac */ + HGIC_CMD_SET_AP_HIDE = 117, /* fmac */ + HGIC_CMD_SET_DUAL_ANT = 118, /* fmac */ + HGIC_CMD_SET_MAX_TCNT = 119, /* fmac/smac */ + HGIC_CMD_SET_ASSERT_HOLDUP = 120, /* fmac/smac */ + HGIC_CMD_SET_AP_PSMODE_EN = 121, /* fmac */ + HGIC_CMD_SET_DUPFILTER_EN = 122, /* fmac */ + HGIC_CMD_SET_DIS_1V1_M2U = 123, /* fmac */ + HGIC_CMD_SET_DIS_PSCONNECT = 124, /* fmac */ + HGIC_CMD_SET_RTC = 125, /* fmac */ + HGIC_CMD_GET_RTC = 126, /* fmac */ + HGIC_CMD_SET_KICK_ASSOC = 127, /* fmac */ + HGIC_CMD_START_ASSOC = 128, /* fmac */ + HGIC_CMD_SET_AUTOSLEEP = 129, /* fmac */ + HGIC_CMD_SEND_BLENC_DATA = 130, /* smac */ + HGIC_CMD_SET_BLENC_EN = 131, /* smac */ + HGIC_CMD_RESET = 132, /* fmac/smac */ + HGIC_CMD_SET_HWSCAN = 133, /* smac */ + HGIC_CMD_GET_TXQ_PARAM = 134, /* smac */ + HGIC_CMD_SET_PROMISC = 135, /* smac */ + HGIC_CMD_SET_USER_EDCA = 136, /* fmac */ + HGIC_CMD_SET_FIX_TXRATE = 137, /* smac */ + HGIC_CMD_SET_NAV_MAX = 138, /* smac */ + HGIC_CMD_CLEAR_NAV = 139, /* smac */ + HGIC_CMD_SET_CCA_PARAM = 140, /* smac */ + HGIC_CMD_SET_TX_MODGAIN = 141, /* smac */ + HGIC_CMD_GET_NAV = 142, /* smac */ + HGIC_CMD_SET_BEACON_START = 143, /* smac */ + HGIC_CMD_SET_BLE_OPEN = 144, /* smac */ + HGIC_CMD_GET_MODE = 145, /* fmac */ + HGIC_CMD_GET_BGRSSI = 146, /* fmac */ + HGIC_CMD_SEND_BLENC_ADVDATA = 147, /* smac */ + HGIC_CMD_SEND_BLENC_SCANRESP = 148, /* smac */ + HGIC_CMD_SEND_BLENC_DEVADDR = 149, /* smac */ + HGIC_CMD_SEND_BLENC_ADVINTERVAL = 150, /* smac */ + HGIC_CMD_SEND_BLENC_STARTADV = 151, /* smac */ + HGIC_CMD_SET_RTS_DURATION = 152, /* smac */ + HGIC_CMD_STANDBY_CFG = 153, /* fmac */ + HGIC_CMD_SET_CONNECT_PAIRONLY = 154, /* fmac */ + HGIC_CMD_SET_DIFFCUST_CONN = 155, /* fmac */ + HGIC_CMD_GET_CENTER_FREQ = 156, /* smac */ + HGIC_CMD_SET_WAIT_PSMODE = 157, /* fmac */ + HGIC_CMD_SET_AP_CHAN_SWITCH = 158, /* fmac */ + HGIC_CMD_SET_CCA_FOR_CE = 159, /* fmac */ + HGIC_CMD_SET_DISABLE_PRINT = 160, /* fmac/smac */ + HGIC_CMD_SET_APEP_PADDING = 161, /* smac */ + HGIC_CMD_GET_ACS_RESULT = 162, /* fmac/smac */ + HGIC_CMD_GET_WIFI_STATUS_CODE = 163, /* fmac */ + HGIC_CMD_GET_WIFI_REASON_CODE = 164, /* fmac */ + HGIC_CMD_SET_WATCHDOG = 165, /* fmac/smac */ + HGIC_CMD_SET_RETRY_FALLBACK_CNT = 166, /* smac */ + HGIC_CMD_SET_FALLBACK_MCS = 167, /* smac */ + HGIC_CMD_GET_XOSC_VALUE = 168, /* smac */ + HGIC_CMD_SET_XOSC_VALUE = 169, /* smac */ + HGIC_CMD_GET_FREQ_OFFSET = 170, /* smac */ + HGIC_CMD_SET_CALI_PERIOD = 171, /* smac */ + HGIC_CMD_SET_BLENC_ADVFILTER = 172, /* smac */ + HGIC_CMD_SET_MAX_TX_DELAY = 173, /* smac */ + HGIC_CMD_GET_STA_INFO = 174, /* fmac */ + HGIC_CMD_SEND_MGMTFRAME = 175, /* fmac */ + }; enum hgic_event { - HGIC_EVENT_STATE_CHG = 0x1, // 1 - HGIC_EVENT_CH_SWICH, // 2 - HGIC_EVENT_DISCONNECT_REASON, // 3 - HGIC_EVENT_ASSOC_STATUS, // 4 - HGIC_EVENT_SCANNING, // 5 - HGIC_EVENT_SCAN_DONE, // 6 - HGIC_EVENT_TX_BITRATE, // 7 - HGIC_EVENT_PAIR_START, // 8 - HGIC_EVENT_PAIR_SUCCESS, // 9 - HGIC_EVENT_PAIR_DONE, // 10 - HGIC_EVENT_CONECT_START, // 11 - HGIC_EVENT_CONECTED, // 12 - HGIC_EVENT_DISCONECTED, // 13 - HGIC_EVENT_SIGNAL, // 14 - HGIC_EVENT_DISCONNET_LOG, // 15 - HGIC_EVENT_REQUEST_PARAM, // 16 - HGIC_EVENT_TESTMODE_STATE, // 17 - HGIC_EVENT_FWDBG_INFO, // 18 - HGIC_EVENT_CUSTOMER_MGMT, // 19 - HGIC_EVENT_SLEEP_FAIL, // 20 - HGIC_EVENT_DHCPC_DONE, // 21 - HGIC_EVENT_CONNECT_FAIL, // 22 - HGIC_EVENT_CUST_DRIVER_DATA, // 23 - HGIC_EVENT_UNPAIR_STA, // 24 + HGIC_EVENT_STATE_CHG = 1, + HGIC_EVENT_CH_SWICH = 2, + HGIC_EVENT_DISCONNECT_REASON = 3, + HGIC_EVENT_ASSOC_STATUS = 4, + HGIC_EVENT_SCANNING = 5, + HGIC_EVENT_SCAN_DONE = 6, + HGIC_EVENT_TX_BITRATE = 7, + HGIC_EVENT_PAIR_START = 8, + HGIC_EVENT_PAIR_SUCCESS = 9, + HGIC_EVENT_PAIR_DONE = 10, + HGIC_EVENT_CONECT_START = 11, + HGIC_EVENT_CONECTED = 12, + HGIC_EVENT_DISCONECTED = 13, + HGIC_EVENT_SIGNAL = 14, + HGIC_EVENT_DISCONNET_LOG = 15, + HGIC_EVENT_REQUEST_PARAM = 16, + HGIC_EVENT_TESTMODE_STATE = 17, + HGIC_EVENT_FWDBG_INFO = 18, + HGIC_EVENT_CUSTOMER_MGMT = 19, + HGIC_EVENT_SLEEP_FAIL = 20, + HGIC_EVENT_DHCPC_DONE = 21, + HGIC_EVENT_CONNECT_FAIL = 22, + HGIC_EVENT_CUST_DRIVER_DATA = 23, + HGIC_EVENT_UNPAIR_STA = 24, + HGIC_EVENT_BLENC_DATA = 25, + HGIC_EVENT_HWSCAN_RESULT = 26, + HGIC_EVENT_EXCEPTION_INFO = 27, + HGIC_EVENT_DSLEEP_WAKEUP = 28, + HGIC_EVENT_STA_MIC_ERROR = 29, + HGIC_EVENT_ACS_DONE = 30, + HGIC_EVENT_FW_INIT_DONE = 31, + HGIC_EVENT_ROAM_CONECTED = 32, + HGIC_EVENT_MGMT_FRAME = 33, }; -extern int hgic_sdio_init(void); -extern void hgic_sdio_exit(void); -extern int hgic_usb_init(void); -extern void hgic_usb_exit(void); +enum hgicf_hw_state { + HGICF_HW_DISCONNECTED = 0, + HGICF_HW_DISABLED = 1, + HGICF_HW_INACTIVE = 2, + HGICF_HW_SCANNING = 3, + HGICF_HW_AUTHENTICATING = 4, + HGICF_HW_ASSOCIATING = 5, + HGICF_HW_ASSOCIATED = 6, + HGICF_HW_4WAY_HANDSHAKE = 7, + HGICF_HW_GROUP_HANDSHAKE = 8, + HGICF_HW_CONNECTED = 9, +}; + +enum HGIC_EXCEPTION_NUM{ + HGIC_EXCEPTION_CPU_USED_OVERTOP = 1, + HGIC_EXCEPTION_HEAP_USED_OVERTOP = 2, + HGIC_EXCEPTION_WIFI_BUFFER_USED_OVERTOP = 3, + HGIC_EXCEPTION_TX_BLOCKED = 4, + HGIC_EXCEPTION_TXDELAY_TOOLONG = 5, + HGIC_EXCEPTION_STRONG_BGRSSI = 6, + HGIC_EXCEPTION_TEMPERATURE_OVERTOP = 7, + HGIC_EXCEPTION_WRONG_PASSWORD = 8, +}; + +struct hgic_exception_info { + int num; + union { + struct { + int max, avg, min; + } txdelay; + struct { + int max, avg, min; + } bgrssi; + struct { + int total, used; + } buffer_usage; + struct { + int total, used; + } heap_usage; + struct { + int temp; + } temperature; + } info; +}; + +struct hgic_dhcp_result { + unsigned int ipaddr, netmask, svrip, router, dns1, dns2; +}; #ifdef __RTOS__ struct firmware { diff --git a/hgic_def.h b/hgic_def.h index d432ecc..8e30231 100644 --- a/hgic_def.h +++ b/hgic_def.h @@ -3,7 +3,7 @@ #include "hgic.h" #include "version.h" -#define HGIC_VERSION "v1.3.0" +#define HGIC_VERSION "v2.2.1" #ifndef SVN_VERSION #error "SVN_VERSION undefined" @@ -13,17 +13,18 @@ printk("** HUGE-IC WLAN Card Driver("name") "HGIC_VERSION"-"SVN_VERSION"\r\n");\ }while(0) -#define HGIC_WDEV_ID_AP 0 +#define HGIC_WDEV_ID_AP 2 #define HGIC_WDEV_ID_STA 1 #define HGIC_SCAN_MAX_NUM 32 #define HGIC_HDR_TX_MAGIC 0x1A2B #define HGIC_HDR_RX_MAGIC 0x2B1A -#define HGIC_VENDOR_ID (0xA012) -#define HGIC_WLAN_AH_4001 (0x4001) -#define HGIC_WLAN_AH_4002 (0x4002) -#define HGIC_WLAN_AH_4102 (0x4102) +#define HGIC_VENDOR_ID (0xA012) +#define HGIC_WLAN_4002 (0x4002) +#define HGIC_WLAN_4104 (0x4104) +#define HGIC_WLAN_8400 (0x8400) + #define HGIC_CTRL_TIMEOUT 100 #define HGIC_CMD_PRIORITY 0 @@ -37,9 +38,13 @@ #define hgic_enter() printk("enter %s\r\n", __FUNCTION__) #define hgic_leave() printk("leave %s\r\n", __FUNCTION__) +#ifndef ARRAYSIZE +#define ARRAYSIZE(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + #define HGIC_CMD_TIMEOUT 500 #define HGIC_TX_TIMEOUT 10 -#define HGIC_ALIVE_TIMER 5000 +#define HGIC_DETECT_TIMER 5000 enum hgic_bus_type { HGIC_BUS_SDIO = 0x1, @@ -49,28 +54,6 @@ enum hgic_bus_type { HGIC_BUS_SDSPI, }; - -enum hgic_hdr_type { - HGIC_HDR_TYPE_ACK = 0x1, - HGIC_HDR_TYPE_FRM, - HGIC_HDR_TYPE_CMD, - HGIC_HDR_TYPE_EVENT, - HGIC_HDR_TYPE_FIRMWARE, - HGIC_HDR_TYPE_NLMSG, - HGIC_HDR_TYPE_BOOTDL, - HGIC_HDR_TYPE_TEST, - HGIC_HDR_TYPE_FRM2, - HGIC_HDR_TYPE_TEST2, - HGIC_HDR_TYPE_SOFTFC, - HGIC_HDR_TYPE_OTA, - HGIC_HDR_TYPE_CMD2, - HGIC_HDR_TYPE_EVENT2, - HGIC_HDR_TYPE_BOOTDL_DATA, - - HGIC_HDR_TYPE_MAX, -}; - - enum hgic_hdr_flags2 { HGIC_HDR_FLAGS2_AFT_BEACON = BIT(0), }; @@ -80,118 +63,21 @@ enum hgic_bus_flag { HGIC_BUS_FLAGS_SLEEP, HGIC_BUS_FLAGS_INBOOT, HGIC_BUS_FLAGS_NOPOLL, + HGIC_BUS_FLAGS_SOFTFC, + HGIC_BUS_FLAGS_ERROR, }; -struct hgic_txq_param { - unsigned short txop; - unsigned short cw_min; - unsigned short cw_max; - unsigned char aifs; - unsigned char acm; -}; +#define hgic_pick_values(pick_type, str, array, size) do{\ + char *__ptr = NULL;\ + memset(array, 0, size*sizeof(pick_type));\ + if((str) && strlen((str)) > 0){\ + while ((__ptr = strsep((char **)&(str), ",")) != NULL) {\ + if (argcnt >= size) break;\ + array[argcnt++] = (pick_type)simple_strtol(__ptr, 0, 0);\ + }\ + }\ + }while(0) -struct hgic_mcast_txparam { - unsigned char dupcnt; - unsigned char tx_bw; - unsigned char tx_mcs; - unsigned char clearch; -}; - -/*data packet header*/ -struct hgic_hdr { - unsigned short magic; - unsigned char type; - unsigned char ifidx: 4, flags: 4; - unsigned short length; - unsigned short cookie; -} __packed; - -struct hgic_rx_info { - unsigned char band; - unsigned char mcs: 4, bw: 4; - char evm; - char signal; - unsigned short freq; - s16 freq_off; - unsigned char rx_flags; - unsigned char antenna; - unsigned char nss : 4, s1g_nss : 4; - unsigned char vht_flag : 3, s1g_flag : 5; -}; - -struct hgic_tx_info { - unsigned char band; - unsigned char tx_bw; - unsigned char tx_mcs; - unsigned char antenna; - unsigned int tx_flags; - unsigned int tx_flags2; -}; - -struct hgic_key_info { - unsigned int cipher; - unsigned char icv_len; - unsigned char iv_len; - unsigned char hw_key_idx; - unsigned char flags; - char keyidx; - unsigned char keylen; - unsigned char key[0]; -}; - -struct hgic_frm_hdr { - struct hgic_hdr hdr; - union { - struct hgic_rx_info rx_info; - struct hgic_tx_info tx_info; - unsigned char rev[24]; - }; -} __packed; - -struct hgic_frm_hdr2 { - struct hgic_hdr hdr; -} __packed; - -#define HDR_CMDID(ctl) ((ctl)->hdr.type==HGIC_HDR_TYPE_CMD2?(ctl)->cmd2.cmd_id:(ctl)->cmd.cmd_id) -#define HDR_EVTID(ctl) ((ctl)->hdr.type==HGIC_HDR_TYPE_EVENT2?(ctl)->event2.event_id:(ctl)->event.event_id) -#define HDR_CMDID_SET(ctl, id) if(id>255){\ - (ctl)->hdr.type =HGIC_HDR_TYPE_CMD2;\ - (ctl)->cmd2.cmd_id = id;\ - }else{\ - (ctl)->hdr.type =HGIC_HDR_TYPE_CMD;\ - (ctl)->cmd.cmd_id = id;\ - } -#define HDR_EVTID_SET(ctl, id) if(id>255){\ - (ctl)->hdr.type =HGIC_HDR_TYPE_EVENT2;\ - (ctl)->event2.event_id = id;\ - }else{\ - (ctl)->hdr.type =HGIC_HDR_TYPE_EVENT;\ - (ctl)->event.event_id = id;\ - } - -/*contro pakcet header*/ -struct hgic_ctrl_hdr { - struct hgic_hdr hdr; - union { - struct { - unsigned char cmd_id; - short status; - } cmd; - struct { - unsigned short cmd_id; - short status; - } cmd2; - struct { - unsigned char event_id; - short value; - } event; - struct { - unsigned short event_id; - short value; - } event2; - unsigned char info[4]; - }; -} __packed; //ack packet struct hgic_dack_hdr { @@ -273,7 +159,7 @@ struct hgic_fw_status { struct hgic_sta_status sta[0]; }; -enum HGIC_BUS_BOOTDL_CKSUM{ +enum HGIC_BUS_BOOTDL_CKSUM { HGIC_BUS_BOOTDL_CHECK_SUM = 0, HGIC_BUS_BOOTDL_CHECK_CRC8, HGIC_BUS_BOOTDL_CHECK_0XFD, @@ -289,18 +175,17 @@ struct hgic_bus { int bootdl_pktlen; int bootdl_cksum; int blk_size; + int (*probe)(void *dev, struct hgic_bus *bus); int (*tx_packet)(void *bus, struct sk_buff *skb); void (*tx_complete)(void *hg, struct sk_buff *skb, int success); - int (*rx_packet)(void *hg, struct sk_buff *skb, int len); + int (*rx_packet)(void *hg, u8 *data, int len); int (*reinit)(void *bus); + void (*probe_post)(void *priv); + void (*remove)(void *priv); + int (*suspend)(void *priv); + int (*resume)(void *priv); }; -extern int hgic_core_probe(void *dev, struct hgic_bus *bus); -extern void hgic_core_probe_post(void *priv); -extern int hgic_core_remove(void *arg); -extern int hgic_core_suspend(void *hgobj); -extern int hgic_core_resume(void *hgobj); - #ifdef __RTOS__ #define ALLOC_ORDERED_WORKQUEUE alloc_ordered_workqueue #define ALLOC_NETDEV_MQS alloc_netdev_mqs @@ -322,39 +207,51 @@ extern int hgic_core_resume(void *hgobj); #define ALLOC_NETDEV_MQS(size,name,setup,txqs,rxqs) alloc_netdev_mqs(size,name,setup,txqs,rxqs) #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,1) -#define _KERNEL_READ(fp, buff, size, off) kernel_read(fp, buff, size, off) -#define _KERNEL_WRITE(fp, buff, size, off) kernel_write(fp, buff, size, off) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,42) +#define _KERNEL_READ(fp, buff, size) ({ \ + ssize_t __ret__ = 0; \ + unsigned long long offset = 0;\ + __ret__ = kernel_read(fp, buff, size, &offset); \ + __ret__;\ + }) #else -#define _KERNEL_READ(fp, buff, size, off) kernel_read(fp, 0, buff, size) -#define _KERNEL_WRITE(fp, buff, size, off) kernel_write(fp, buff, size, off) +#define _KERNEL_READ(fp, buff, size) kernel_read(fp, 0, buff, size) #endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) #define setup_timer(a, b, c) timer_setup(a, b, 0) #define init_timer(...) #endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) #define ACCESS_OK(type, addr, size) access_ok(addr, size) -#define DEV_OPEN(x) dev_open(x, NULL) +#define DEV_OPEN(x) do { rtnl_lock(); dev_open(x, NULL); rtnl_unlock(); } while(0) +#define DEV_CLOSE(x) do { rtnl_lock(); dev_close(x); rtnl_unlock(); } while(0) #else #define ACCESS_OK(type, addr, size) access_ok(type, addr, size) -#define DEV_OPEN(x) dev_open(x) +#define DEV_OPEN(x) do { rtnl_lock(); dev_open(x); rtnl_unlock(); } while(0) +#define DEV_CLOSE(x) do { rtnl_lock(); dev_close(x); rtnl_unlock(); } while(0) #endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) && defined CONFIG_HGIC_2G #define IEEE80211_NUM_BANDS NUM_NL80211_BANDS #define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ #define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ #endif + #ifndef IEEE80211_NUM_ACS #define IEEE80211_NUM_ACS 4 #endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) && defined CONFIG_HGIC_2G #define vht_nss nss #endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) && defined CONFIG_HGIC_2G #define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR #define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR #endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(5,5,0) #define proc_ops file_operations #define proc_open open @@ -363,15 +260,18 @@ extern int hgic_core_resume(void *hgobj); #define proc_write write #define proc_release release #endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) #define ieee80211_free_txskb(hw, skb) dev_kfree_skb_any(skb) #endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0) #define RX_FLAG_MACTIME_START RX_FLAG_MACTIME_MPDU #define IEEE80211_ITERATE_ACTIVE_INTERFACES_ATOMIC(hw, flags, iterator, vif) ieee80211_iterate_active_interfaces_atomic(hw, iterator, vif) #else #define IEEE80211_ITERATE_ACTIVE_INTERFACES_ATOMIC(hw, flags, iterator, vif) ieee80211_iterate_active_interfaces_atomic(hw, flags, iterator, vif) #endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) static inline void *__PDE_DATA(const struct inode *inode) { @@ -383,4 +283,16 @@ static inline void *PDE_DATA(const struct inode *inode) } #endif #endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0) +#define tasklet_hrtimer hrtimer +#define tasklet_hrtimer_cancel hrtimer_cancel +#define tasklet_hrtimer_start hrtimer_start +#endif + +typedef int (*hgic_probe)(void *dev, struct hgic_bus *bus); +extern int hgic_sdio_init(hgic_probe probe, u32 max_pkt); +extern void hgic_sdio_exit(void); +extern int hgic_usb_init(hgic_probe probe, u32 max_pkt); +extern void hgic_usb_exit(void); #endif diff --git a/hgic_fmac/Kconfig b/hgic_fmac/Kconfig new file mode 100644 index 0000000..f0f4608 --- /dev/null +++ b/hgic_fmac/Kconfig @@ -0,0 +1,2 @@ +config HGICF + tristate " HUGE-IC FullMac WLAN Driver" diff --git a/hgic_fmac/Makefile b/hgic_fmac/Makefile index b2d5b13..646e4d5 100644 --- a/hgic_fmac/Makefile +++ b/hgic_fmac/Makefile @@ -1,23 +1,15 @@ -$(CONFIG_HGICF)-objs += cfg.o -$(CONFIG_HGICF)-objs += ctrl.o -$(CONFIG_HGICF)-objs += core.o -$(CONFIG_HGICF)-objs += event.o -$(CONFIG_HGICF)-objs += procfs.o -$(CONFIG_HGICF)-objs += ../utils/fwdl.o -$(CONFIG_HGICF)-objs += ../utils/utils.o -$(CONFIG_HGICF)-objs += ../utils/fwctrl.o -$(CONFIG_HGICF)-objs += ../utils/ota.o -$(CONFIG_HGICF)-objs += ../utils/fwinfo.o - -ifeq ($(CONFIG_HGICF), hgicf_sdio) -$(CONFIG_HGICF)-objs += ../utils/if_sdio.o -obj-m += hgicf_sdio.o -else ifeq ($(CONFIG_HGICF), hgicf_usb) -$(CONFIG_HGICF)-objs += ../utils/if_usb.o -obj-m += hgicf_usb.o -else -obj-m += hgicf.o -endif - +hgicf-objs += ctrl.o +hgicf-objs += core.o +hgicf-objs += event.o +hgicf-objs += procfs.o +hgicf-objs += ../utils/fwdl.o +hgicf-objs += ../utils/utils.o +hgicf-objs += ../utils/fwctrl.o +hgicf-objs += ../utils/ota.o +hgicf-objs += ../utils/fwinfo.o +hgicf-objs += ../utils/iwpriv.o +hgicf-$(CONFIG_HGIC_SDIO) += ../utils/if_sdio.o +hgicf-$(CONFIG_HGIC_USB) += ../utils/if_usb.o +obj-$(CONFIG_HGICF) += hgicf.o diff --git a/hgic_fmac/cfg.c b/hgic_fmac/cfg.c deleted file mode 100644 index 09c5f1f..0000000 --- a/hgic_fmac/cfg.c +++ /dev/null @@ -1,1178 +0,0 @@ -#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)); -} - diff --git a/hgic_fmac/cfg.h b/hgic_fmac/cfg.h deleted file mode 100644 index 091e002..0000000 --- a/hgic_fmac/cfg.h +++ /dev/null @@ -1,13 +0,0 @@ - -#ifndef _HGICF_CFG_H_ -#define _HGICF_CFG_H_ -#ifndef __RTOS__ -int hgicf_ioctl_set_proc(struct net_device *dev, struct iwreq *wrqin); -int hgicf_ioctl_get_proc(struct net_device *dev, struct iwreq *wrqin); -int hgicf_ioctl_stat(struct net_device *dev, struct iwreq *wrqin); -int hgicf_ioctl_e2p(struct net_device *dev, struct iwreq *wrqin); -int hgicf_ioctl_scan(struct net_device *dev, struct iwreq *wrqin); -int hgicf_ioctl_savecfg(struct net_device *dev, struct iwreq *wrqin); -#endif -#endif - diff --git a/hgic_fmac/core.c b/hgic_fmac/core.c index 91d387b..a47d026 100644 --- a/hgic_fmac/core.c +++ b/hgic_fmac/core.c @@ -30,28 +30,30 @@ #include "hgicf.h" #include "ctrl.h" -#include "cfg.h" #include "event.h" static int txq_size = 1024; -static char *conf_file = "/etc/hgicf.conf"; -static char *fw_file = "hgicf.bin"; -static int if_test = 0; -static int soft_fc = 1; +static int if_test = 0; static int no_bootdl = 0; static int qc_mode = 0; static char *ifname = "hg%d"; -static hgic_init_cb init_cb = NULL; +static int if_agg = 0; +static char *conf_file = "/etc/hgicf.conf"; +static int proc_dev = 0; +static char *fw_file = "hgicf.bin"; #ifdef __RTOS__ +static hgic_init_cb init_cb = NULL; static hgic_event_cb event_cb = NULL; #endif -#define TXWND_INIT_VAL (2) -#define MATCH_NDEV(fwidx,hg) ((fwidx) == HGIC_WDEV_ID_STA ? (hg->sta ? hg->sta->ndev : NULL) : \ - (hg->ap ? hg->ap->ndev : NULL)) +static const u16 hgic_fmac_devid[] = { + HGIC_WLAN_4002, + HGIC_WLAN_8400, +}; + +#define TXWND_INIT_VAL (3) #ifdef __RTOS__ -static int iface_cnt = 1; void dev_queue_xmit(struct sk_buff *skb) { struct net_device *ndev = skb->dev; @@ -63,7 +65,18 @@ void dev_queue_xmit(struct sk_buff *skb) } #endif -u16 hgicf_data_cookie(struct hgicf_wdev *hg) +static u8 hgicf_match_devid(u16 dev_id) +{ + int i = 0; + for (i = 0; i < ARRAYSIZE(hgic_fmac_devid); i++) { + if (dev_id == hgic_fmac_devid[i]) { + return 1; + } + } + return 0; +} + +static u16 hgicf_data_cookie(struct hgicf_wdev *hg) { unsigned long flags; uint16_t cookie = 0; @@ -74,39 +87,38 @@ u16 hgicf_data_cookie(struct hgicf_wdev *hg) return cookie; } -void hgicf_load_config(struct hgicf_wdev *hg) +static void hgicf_load_config(struct hgicf_wdev *hg) { #ifndef __RTOS__ struct file *fp = NULL; struct iwreq wrqin; - struct net_device *ndev = NULL; + struct net_device *ndev = hg->vif->ndev; ssize_t ret = 0; - unsigned long long __maybe_unused offset = 0 ; char *conf = kzalloc(2048, GFP_KERNEL); char *ptr, *str; + char path[64]; - if (hg->sta) {ndev = hg->sta->ndev; } - else if (hg->ap) {ndev = hg->ap->ndev; } - else { - hgic_err("No netdev!! \r\n"); - goto __out; + if (strstr(conf_file, ".conf")) { + strcpy(path, conf_file); + } else { + sprintf(path, "%s/%s.conf", conf_file, ndev->name); } - fp = filp_open(conf_file, O_RDONLY, 0); + fp = filp_open(path, O_RDONLY, 0); if (!IS_ERR(fp) && conf) { - ret = _KERNEL_READ(fp, conf, 2048, &offset); + hgic_err("load conf file: %s\r\n", path); + ret = _KERNEL_READ(fp, conf, 2048); str = conf; - hgic_fwctrl_close_dev(&(hg->ctrl)); while (str) { - ptr = strstr(str, "\r\n"); + ptr = strchr(str, '\n'); if (ptr) { - *ptr = 0; - ptr += 2; - } else { - ptr = strstr(str, "\n"); - if (ptr) { *ptr++ = 0;} + if (*(ptr - 1) == '\r') { + *(ptr - 1) = 0; + } + *ptr++ = 0; } + wrqin.u.data.length = strlen(str); if (wrqin.u.data.length > 0) { hgic_dbg("param: [%s]\r\n", str); @@ -118,12 +130,16 @@ void hgicf_load_config(struct hgicf_wdev *hg) } str = ptr; } - hgic_fwctrl_open_dev(&(hg->ctrl)); + } else { + hgic_err("can not open %s\r\n", path); } -__out: - if (!IS_ERR(fp)) { filp_close(fp, NULL); } - if (conf) { kfree(conf); } + if (!IS_ERR(fp)) { + filp_close(fp, NULL); + } + if (conf) { + kfree(conf); + } #endif } @@ -133,8 +149,8 @@ static int hgicf_netif_open(struct net_device *dev) if (!test_bit(HGICF_DEV_FLAGS_RUNNING, &vif->hg->flags)) { return 0; } - vif->hg->radio_off = 0; - return hgic_fwctrl_open_dev(&(vif->hg->ctrl)); + vif->opened = 1; + return hgic_fwctrl_open_dev(&(vif->hg->ctrl), vif->fwifidx); } static int hgicf_netif_stop(struct net_device *dev) @@ -143,8 +159,8 @@ static int hgicf_netif_stop(struct net_device *dev) if (!test_bit(HGICF_DEV_FLAGS_RUNNING, &vif->hg->flags)) { return 0; } - vif->hg->radio_off = 1; - return hgic_fwctrl_close_dev(&(vif->hg->ctrl)); + vif->opened = 0; + return hgic_fwctrl_close_dev(&(vif->hg->ctrl), vif->fwifidx); } static void hgicf_netif_uninit(struct net_device *dev) @@ -159,12 +175,12 @@ static netdev_tx_t hgicf_netif_xmit(struct sk_buff *skb, struct net_device *dev) { struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); struct hgic_frm_hdr2 *hdr = NULL; - u8 pad = ((ulong)skb->data & 0x3) ? (4 - ((ulong)skb->data & 0x3)) : 0; + u8 pad = ((ulong)skb->data & 0x3); //push offset | <--|data .....| - if (!test_bit(HGICF_DEV_FLAGS_RUNNING, &vif->hg->flags) || - (vif->hg->tx_dataq.qlen > txq_size) || + if (!test_bit(HGICF_DEV_FLAGS_RUNNING, &vif->hg->flags) || (vif->hg->tx_dataq.qlen > txq_size) || test_bit(HGIC_BUS_FLAGS_SLEEP, &vif->hg->bus->flags)) { dev_kfree_skb(skb); + vif->stats.tx_dropped += skb->len; return NETDEV_TX_OK; } @@ -177,19 +193,19 @@ static netdev_tx_t hgicf_netif_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } skb = nskb; - pad = ((ulong)skb->data & 0x3) ? (4 - ((ulong)skb->data & 0x3)) : 0; + pad = ((ulong)skb->data & 0x3); } #endif hdr = (struct hgic_frm_hdr2 *)skb_push(skb, sizeof(struct hgic_frm_hdr2) + pad); hdr->hdr.ifidx = vif->fwifidx; - hdr->hdr.length = skb->len; - hdr->hdr.magic = HGIC_HDR_TX_MAGIC; + hdr->hdr.length = cpu_to_le16(skb->len); + hdr->hdr.magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); hdr->hdr.type = HGIC_HDR_TYPE_FRM2; hdr->hdr.flags = pad; - hdr->hdr.cookie = hgicf_data_cookie(vif->hg); skb_queue_tail(&vif->hg->tx_dataq, skb); queue_work(vif->hg->tx_wq, &vif->hg->tx_work); + vif->stats.tx_bytes += skb->len; return NETDEV_TX_OK; } @@ -205,7 +221,7 @@ static int hgicf_netif_change_mac(struct net_device *dev, void *addr) if (!test_bit(HGICF_DEV_FLAGS_RUNNING, &vif->hg->flags)) { return 0; } - ret = hgic_fwctrl_set_mac(&(vif->hg->ctrl), sa->sa_data); + ret = hgic_fwctrl_set_mac(&(vif->hg->ctrl), vif->fwifidx, sa->sa_data); if (!ret) { ret = eth_mac_addr(dev, addr); } @@ -245,6 +261,12 @@ static int hgicf_netif_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } #endif +static struct net_device_stats *hgicf_netdev_get_stats(struct net_device *ndev) +{ + struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(ndev); + return &vif->stats; +} + static const struct net_device_ops hgicf_netif_ops = { .ndo_open = hgicf_netif_open, .ndo_stop = hgicf_netif_stop, @@ -253,6 +275,7 @@ static const struct net_device_ops hgicf_netif_ops = { .ndo_set_rx_mode = hgicf_netif_set_multicast_list, .ndo_set_mac_address = hgicf_netif_change_mac, .ndo_do_ioctl = hgicf_netif_ioctl, + .ndo_get_stats = hgicf_netdev_get_stats, }; static void hgicf_netif_setup(struct net_device *dev) @@ -275,54 +298,74 @@ static int hgicf_request_txwnd(struct hgic_bus *bus) struct hgic_hdr *hdr = NULL; struct sk_buff *skb = dev_alloc_skb(sizeof(struct hgic_hdr) + 2); - if (skb == NULL) { return -ENOMEM; } + if (skb == NULL) { + return -ENOMEM; + } + hdr = (struct hgic_hdr *)skb->data; - hdr->magic = HGIC_HDR_TX_MAGIC; - hdr->type = HGIC_HDR_TYPE_SOFTFC; - hdr->length = sizeof(struct hgic_hdr) + 2; - hdr->ifidx = 0; - hdr->flags = 0; + hdr->magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + hdr->length = cpu_to_le16(sizeof(struct hgic_hdr) + 2); hdr->cookie = 0; + hdr->type = HGIC_HDR_TYPE_SOFTFC; + hdr->ifidx = 1; + hdr->flags = 0; skb_put(skb, sizeof(struct hgic_hdr) + 2); return bus->tx_packet(bus, skb); } -static int hgicf_check_txwnd(struct hgicf_wdev *hg) +static int hgicf_check_txwnd(struct hgicf_wdev *hg, u8 min_wnd) { - int err = 0; - if (!hg->soft_fc || test_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags)) { return 0; } - - while (hg->soft_fc && atomic_read(&hg->txwnd) < TXWND_INIT_VAL && - test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags) && - !test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) && - !test_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags) && - !test_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags)) { - - err = hgicf_request_txwnd(hg->bus); - if (!err) { - wait_for_completion_timeout(&hg->txwnd_cp, msecs_to_jiffies(100)); - } - - if(atomic_read(&hg->txwnd) < TXWND_INIT_VAL) - msleep(10); + + if(test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) || + test_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags) || + !test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)){ + return -1; } - if (!hg->soft_fc || test_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags)) { - return 0; + if(atomic_read(&hg->txwnd) < min_wnd){ + hgicf_request_txwnd(hg->bus); } - if (atomic_read(&hg->txwnd) < TXWND_INIT_VAL) { + if (atomic_read(&hg->txwnd) < min_wnd) { return -1; } else { atomic_dec(&hg->txwnd); } - return 0; } +static void hgicf_tx_complete(void *hgobj, struct sk_buff *skb, int success) +{ + struct hgic_ctrl_hdr *hdr = (struct hgic_ctrl_hdr *)skb->data; + struct hgicf_wdev *hg = (struct hgicf_wdev *)hgobj; + + if (hg->if_test) { + hg->test_tx_len += skb->len; + } + + if (success) { + clear_bit(HGIC_BUS_FLAGS_ERROR, &hg->bus->flags); + } else { + hgic_err("tx failed\r\n"); + + if (hdr->hdr.magic == cpu_to_le16(HGIC_HDR_TX_MAGIC)) { + if ((hdr->hdr.type == HGIC_HDR_TYPE_CMD || hdr->hdr.type == HGIC_HDR_TYPE_CMD2) && HDR_CMDID(hdr) == HGIC_CMD_ENTER_SLEEP) { + clear_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); + } + } + + hg->status.tx_fail++; + set_bit(HGIC_BUS_FLAGS_ERROR, &hg->bus->flags); + if (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + schedule_work(&hg->detect_work); + } + } + dev_kfree_skb_any(skb); +} + static void hgicf_test_work(struct work_struct *work) { int ret = 0; @@ -354,16 +397,21 @@ static void hgicf_test_work(struct work_struct *work) if (skb) { skb_reserve(skb, hg->bus->drv_tx_headroom); frmhdr = (struct hgic_frm_hdr *)skb->data; - frmhdr->hdr.magic = HGIC_HDR_TX_MAGIC; + frmhdr->hdr.magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + frmhdr->hdr.length = cpu_to_le16(1500); + frmhdr->hdr.cookie = cpu_to_le16(hgicf_data_cookie(hg)); frmhdr->hdr.type = (hg->if_test == 1 ? HGIC_HDR_TYPE_TEST : HGIC_HDR_TYPE_TEST2); - frmhdr->hdr.length = 1500; frmhdr->hdr.ifidx = 0; - frmhdr->hdr.cookie = hgicf_data_cookie(hg); - if(hg->if_test == 3) memset(skb->data+8, 0xAA, 1500-8); + + if (hg->if_test == 3) { + memset(skb->data + 8, 0xAA, 1500 - 8); + } + skb_put(skb, 1500); - while (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags) && hgicf_check_txwnd(hg)) { + while (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags) && hgicf_check_txwnd(hg, TXWND_INIT_VAL)) { msleep(10); } + ret = hg->bus->tx_packet(hg->bus, skb); if (ret) { msleep(10); @@ -372,69 +420,144 @@ static void hgicf_test_work(struct work_struct *work) msleep(10); } } - printk("if test stop!\r\n"); + hgic_dbg("if test stop!\r\n"); +} + +static void hgicf_tx_single_frm(struct hgicf_wdev *hg, struct sk_buff *skb) +{ + struct hgic_frm_hdr2 *hdr = NULL; + hg->status.tx_data++; + hdr = (struct hgic_frm_hdr2 *)skb->data; + hdr->hdr.cookie = cpu_to_le16(hgicf_data_cookie(hg)); + hg->bus->tx_packet(hg->bus, skb); +} + +static void hgicf_tx_agg_frm(struct hgicf_wdev *hg, struct sk_buff *skb) +{ + struct sk_buff *agg_skb; + struct hgic_frm_hdr2 *hdr = NULL; + struct hgic_hdr *agghdr = NULL; + int cpylen = 0; + + agg_skb = dev_alloc_skb(hg->bus->drv_tx_headroom + if_agg); + if (agg_skb) { + agghdr = (struct hgic_hdr *)agg_skb->data; + memset(agghdr, 0, sizeof(struct hgic_hdr)); + agghdr->magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + agghdr->type = HGIC_HDR_TYPE_AGGFRM; + agghdr->length = sizeof(struct hgic_hdr); + agghdr->cookie = cpu_to_le16(hgicf_data_cookie(hg)); + + do { + hdr = (struct hgic_frm_hdr2 *)skb->data; + cpylen = hdr->hdr.length; + if (agghdr->length + ALIGN(cpylen, 4) > if_agg) { + skb_queue_head(&hg->tx_dataq, skb); + break; + } + + hdr->hdr.length = ALIGN(cpylen, 4); + + hdr->hdr.cookie = cpu_to_le16(hgicf_data_cookie(hg)); + memcpy(agg_skb->data + agghdr->length, skb->data, cpylen); + agghdr->length += hdr->hdr.length; + hgicf_tx_complete(hg, skb, 1); + + skb = skb_dequeue(&hg->tx_dataq); + } while (skb); + + if (agghdr->length > sizeof(struct hgic_hdr)) { + hg->status.tx_data++; + skb_put(agg_skb, agghdr->length); + hg->bus->tx_packet(hg->bus, agg_skb); + } else { + hgic_err("invalid agg frm, cookie:%d\r\n", agghdr->cookie); + dev_kfree_skb(agg_skb); + } + } else { + hgicf_tx_single_frm(hg, skb); + } +} + +static void hgicf_tx_ctrl_frm(struct hgicf_wdev *hg) +{ + int err = 0; + struct hgic_ctrl_hdr *hdr = NULL; + struct sk_buff *skb = skb_dequeue(&hg->ctrl.txq); + if (skb) { + hdr = (struct hgic_ctrl_hdr *)skb->data; + switch (hdr->hdr.type) { + case HGIC_HDR_TYPE_BOOTDL: + break; + case HGIC_HDR_TYPE_BOOTDL_DATA: + skb_pull(skb, sizeof(struct hgic_bootdl_cmd_hdr)); + break; + default: + if (test_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags)) { + kfree_skb(skb); + skb = NULL; + } + break; + } + } + + if (skb) { + hg->status.tx_ctrl++; + err = hg->bus->tx_packet(hg->bus, skb); + if (!err && (hdr->hdr.type == HGIC_HDR_TYPE_CMD || hdr->hdr.type == HGIC_HDR_TYPE_CMD2)) { + if (HDR_CMDID(hdr) == HGIC_CMD_ENTER_SLEEP) { + set_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); + } + } + } } static void hgicf_tx_work(struct work_struct *work) { - struct sk_buff *skb = NULL; + struct sk_buff *skb; struct hgicf_wdev *hg = container_of(work, struct hgicf_wdev, tx_work); - struct hgic_hdr *hdr = NULL; //hgic_dbg("Enter\n"); _CTRLQ_TX: while (!skb_queue_empty(&hg->ctrl.txq)) { if (test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) || - !test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + !test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { hgic_clear_queue(&hg->ctrl.txq); goto _CTRLQ_TX; } - - if (hgicf_check_txwnd(hg)) { +#if 0 + if (hgicf_check_txwnd(hg, 1)) { msleep(10); continue; } - - skb = skb_dequeue(&hg->ctrl.txq); - if(skb){ - hdr = (struct hgic_hdr *)skb->data; - switch(hdr->type){ - case HGIC_HDR_TYPE_BOOTDL: - break; - case HGIC_HDR_TYPE_BOOTDL_DATA: - skb_pull(skb, sizeof(struct hgic_bootdl_cmd_hdr)); - break; - default: - if(test_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags)){ - kfree_skb(skb); - skb = NULL; - } - break; - } - } - - if(skb){ - hg->bus->tx_packet(hg->bus, skb); - } +#endif + hgicf_tx_ctrl_frm(hg); } - while (!skb_queue_empty(&hg->tx_dataq) && - test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags) && + while (!skb_queue_empty(&hg->tx_dataq) && hg->fw_state == STATE_FW && + test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags) && !test_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags)) { - - if (test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) || + + if (test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) || test_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags)) { hgic_clear_queue(&hg->tx_dataq); goto _CTRLQ_TX; } - if (hgicf_check_txwnd(hg)) { + if (hgicf_check_txwnd(hg, TXWND_INIT_VAL)) { msleep(10); goto _CTRLQ_TX; } skb = skb_dequeue(&hg->tx_dataq); - hg->bus->tx_packet(hg->bus, skb); + if (skb) { + if (!skb_queue_empty(&hg->tx_dataq) && if_agg) { + hgicf_tx_agg_frm(hg, skb); + } else { + hgicf_tx_single_frm(hg, skb); + } + } + if (!skb_queue_empty(&hg->ctrl.txq)) { goto _CTRLQ_TX; } @@ -454,65 +577,114 @@ static struct hgicf_vif *hgicf_create_iface(struct hgicf_wdev *hg) hgic_err("%s: alloc_netdev_mqs failed\n", __func__); return NULL; } + vif = (struct hgicf_vif *)netdev_priv(ndev); vif->ndev = ndev; vif->hg = hg; - vif->state = 0; - ndev->needed_headroom += (hg->bus->drv_tx_headroom + sizeof(struct hgic_frm_hdr2)); - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) + vif->opened = 0; + ndev->needed_headroom += (hg->bus->drv_tx_headroom + sizeof(struct hgic_frm_hdr2) + 4); memcpy(ndev->dev_addr, hg->fwinfo.mac, ETH_ALEN); -#else - eth_hw_addr_set(ndev, hg->fwinfo.mac); -#endif + ret = register_netdev(ndev); if (ret) { free_netdev(ndev); return NULL; } -#ifndef __RTOS__ - rtnl_lock(); - DEV_OPEN(ndev); - rtnl_unlock(); -#endif return vif; } -static int hgicf_rx_data(void *hgobj, struct sk_buff *skb, int len) +static void hgicf_rx_single_frm(struct hgicf_wdev *hg, u8 *data, int len) +{ + struct sk_buff *skb; + struct hgic_hdr *hdr = (struct hgic_hdr *)data; + + if (hg->vif && len > sizeof(struct hgic_frm_hdr2)) { + hg->rx_cookie = hdr->cookie; + hg->vif->stats.rx_bytes += len; + data += sizeof(struct hgic_frm_hdr2); + len -= (sizeof(struct hgic_frm_hdr2) + hdr->flags); + skb = dev_alloc_skb(len + hg->vif->ndev->needed_headroom + hg->vif->ndev->needed_tailroom); + if (skb) { + skb_reserve(skb, hg->vif->ndev->needed_headroom); + memcpy(skb->data, data, len); + skb_put(skb, len); + skb->dev = hg->vif->ndev; + skb->protocol = eth_type_trans(skb, skb->dev); + if (in_interrupt()) { + netif_rx(skb); + } else { + netif_rx_ni(skb); + } + } else { + hg->vif->stats.rx_dropped += len; + hgic_err("alloc skb fail, len=%d\r\n", len); + } + } +} + +static void hgicf_rx_agg_frm(struct hgicf_wdev *hg, u8 *data, int len) +{ + struct hgic_hdr *hdr = (struct hgic_hdr *)data; + + if ((u16)(hg->rx_cookie + 1) != hdr->cookie) { + hgic_err("cookie:%d-%d\r\n", hg->rx_cookie, hdr->cookie); + } + hg->rx_cookie = hdr->cookie; + + data += sizeof(struct hgic_hdr); + len -= sizeof(struct hgic_hdr); + while (len > sizeof(struct hgic_frm_hdr2)) { + hdr = (struct hgic_hdr *)data; + hdr->magic = le16_to_cpu(hdr->magic); + hdr->length = le16_to_cpu(hdr->length); + hdr->cookie = le16_to_cpu(hdr->cookie); + if (hdr->magic == HGIC_HDR_RX_MAGIC && hdr->type == HGIC_HDR_TYPE_FRM2 && len >= hdr->length) { + hgicf_rx_single_frm(hg, data, hdr->length); + data += hdr->length; + len -= hdr->length; + } else { + break; + } + } +} + +static int hgicf_rx_data(void *hgobj, u8 *data, int len) { int i = 0; struct hgic_frm_hdr2 *hdr = NULL; struct hgicf_wdev *hg = hgobj; - hgic_skip_padding(skb); - hdr = (struct hgic_frm_hdr2 *) skb->data; - skb->dev = MATCH_NDEV(hdr->hdr.ifidx, hg); + i = hgic_skip_padding(data); + data += i; len -= i; + hdr = (struct hgic_frm_hdr2 *)data; + hdr->hdr.magic = le16_to_cpu(hdr->hdr.magic); + hdr->hdr.length = le16_to_cpu(hdr->hdr.length); + hdr->hdr.cookie = le16_to_cpu(hdr->hdr.cookie); + if (hdr->hdr.magic != HGIC_HDR_RX_MAGIC) { hgic_err("invalid magic unmber:%x\r\n", hdr->hdr.magic); - hgic_print_hex(skb->data, 16); - dev_kfree_skb_any(skb); + hgic_print_hex(data, 16); return -1; } - if (hdr->hdr.type != HGIC_HDR_TYPE_BOOTDL) { - if (len < hdr->hdr.length) { - hgic_err("invalid data length: %x/%x,cookie:%d\r\n", len, hdr->hdr.length, hdr->hdr.cookie); - dev_kfree_skb_any(skb); - return -1; - } + if (len < hdr->hdr.length && hdr->hdr.type != HGIC_HDR_TYPE_BOOTDL) { + hgic_err("invalid data length: %x/%x,cookie:%d\r\n", len, hdr->hdr.length, hdr->hdr.cookie); + return -1; } - skb_put(skb, len > hdr->hdr.length ? hdr->hdr.length : len); + len = (len < hdr->hdr.length ? len : hdr->hdr.length); switch (hdr->hdr.type) { case HGIC_HDR_TYPE_FRM2: + case HGIC_HDR_TYPE_AGGFRM: hg->last_rx = jiffies; - if (skb->dev == NULL || hg->if_test) { - dev_kfree_skb_any(skb); + if (hg->vif == NULL || hg->if_test) { break; } - skb_pull(skb, sizeof(struct hgic_frm_hdr2)); - skb->protocol = eth_type_trans(skb, skb->dev); - netif_rx(skb); + if (hdr->hdr.type == HGIC_HDR_TYPE_AGGFRM) { + hgicf_rx_agg_frm(hg, data, len); + } else { + hgicf_rx_single_frm(hg, data, len); + } break; case HGIC_HDR_TYPE_CMD: case HGIC_HDR_TYPE_CMD2: @@ -521,51 +693,34 @@ static int hgicf_rx_data(void *hgobj, struct sk_buff *skb, int len) case HGIC_HDR_TYPE_OTA: case HGIC_HDR_TYPE_BOOTDL: if (hg->if_test) { - dev_kfree_skb_any(skb); break; } - hgic_fwctrl_rx(&hg->ctrl, skb); + hgic_fwctrl_rx(&hg->ctrl, data, len); break; case HGIC_HDR_TYPE_TEST2: hg->last_rx = jiffies; hg->test_rx_len += len; if (hg->if_test == 3) { for (i = 8; i < 1500; i++) { - if (skb->data[i] != 0xAA) { - printk("data verify fail\r\n"); + if (data[i] != 0xAA) { + hgic_err("data verify fail\r\n"); break; } } } - dev_kfree_skb(skb); break; case HGIC_HDR_TYPE_SOFTFC: hg->last_rx = jiffies; atomic_set(&hg->txwnd, hdr->hdr.cookie); complete(&hg->txwnd_cp); - dev_kfree_skb_any(skb); break; default: hgic_err("invalid data:%d\r\n", hdr->hdr.type); - dev_kfree_skb_any(skb); break; } return 0; } -static void hgicf_tx_complete(void *hgobj, struct sk_buff *skb, int success) -{ - struct hgicf_wdev *hg = hgobj; - - if (hg->if_test) { - hg->test_tx_len += skb->len; - } - dev_kfree_skb_any(skb); - if (!success) { - hgic_err("tx failed\r\n"); - } -} - static int hgicf_download_fw(struct hgicf_wdev *hg) { int err = -1; @@ -573,7 +728,9 @@ static int hgicf_download_fw(struct hgicf_wdev *hg) int status = -1; hgic_dbg("Enter\n"); - if (no_bootdl || qc_mode) { status = STATE_FW; } + if (no_bootdl || qc_mode) { + status = STATE_FW; + } set_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags); while (status != STATE_FW && retry-- > 0 && err) { @@ -581,6 +738,9 @@ static int hgicf_download_fw(struct hgicf_wdev *hg) if (status == STATE_BOOT) { err = hgic_bootdl_download(&hg->bootdl, fw_file); } + if (status < 0 || err) { + msleep(10); + } } clear_bit(HGIC_BUS_FLAGS_INBOOT, &hg->bus->flags); @@ -597,128 +757,160 @@ static int hgicf_download_fw(struct hgicf_wdev *hg) } } - if(!no_bootdl && hg->bus->reinit){ - mod_timer(&hg->alive_tmr, jiffies + msecs_to_jiffies(HGIC_ALIVE_TIMER*4)); + if (!no_bootdl && hg->bus->reinit && test_bit(HGIC_BUS_FLAGS_NOPOLL, &hg->bus->flags)) { + mod_timer(&hg->detect_tmr, jiffies + msecs_to_jiffies(HGIC_DETECT_TIMER * 4)); } + hg->fw_state = status; return (status == STATE_FW); } static void hgicf_delay_init(struct work_struct *work) { int ret = 0; - u8 retry = 0; - int conn_stat = 0; - struct hgicf_wdev *hg = container_of(work, struct hgicf_wdev, delay_init); + struct hgicf_wdev *hg = container_of(work, struct hgicf_wdev, delay_init); - hgic_dbg("Enter\n"); - while(!test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) && test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)){ - if((retry & 0xf) == 0){ - ret = hgicf_download_fw(hg); - if(ret) break; - } - msleep(10); - retry++; - } + ret = hgicf_download_fw(hg); + clear_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags); if (ret) { - clear_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags); hg->last_rx = jiffies; - hg->soft_fc = soft_fc; - conn_stat = hgic_fwctrl_get_conn_state(&hg->ctrl); -#ifndef __RTOS__ - hgic_fwctrl_get_dhcpc_result(&hg->ctrl, (u8 *)&hg->dhcpc, sizeof(hg->dhcpc)); -#endif - hgic_fwctrl_get_fwinfo(&hg->ctrl, &hg->fwinfo); - printk("hgic fw info:%d.%d.%d.%d, svn version:%d, %pM, conn_state:%d\r\n", + hgic_fwctrl_get_fwinfo(&hg->ctrl, HGIC_WDEV_ID_STA, &hg->fwinfo); + printk("hgic fw info:%d.%d.%d.%d, svn version:%d, %pM, smt_dat:%u\r\n", (hg->fwinfo.version >> 24) & 0xff, (hg->fwinfo.version >> 16) & 0xff, (hg->fwinfo.version >> 8) & 0xff, (hg->fwinfo.version & 0xff), - hg->fwinfo.svn_version, hg->fwinfo.mac, conn_stat); + hg->fwinfo.svn_version, hg->fwinfo.mac, hg->fwinfo.smt_dat); + + hg->soft_fc = (hg->fwinfo.version < 0x2000000); + hg->ctrl.fwinfo = &hg->fwinfo; + if (hg->soft_fc) { + set_bit(HGIC_BUS_FLAGS_SOFTFC, &hg->bus->flags); + } else { + clear_bit(HGIC_BUS_FLAGS_SOFTFC, &hg->bus->flags); + } if (!test_bit(HGICF_DEV_FLAGS_INITED, &hg->flags)) { - hg->sta = hgicf_create_iface(hg); - if (!hg->sta) { + hg->vif = hgicf_create_iface(hg); + if (!hg->vif) { hgic_err("create iface fail, ret:%d\r\n", ret); return; } - hg->sta->fwifidx = HGIC_WDEV_ID_STA; - hg->sta->hw_state = conn_stat; + + hg->vif->fwifidx = HGIC_WDEV_ID_STA; hgicf_create_procfs(hg); + +#ifdef __RTOS__ if (init_cb) { init_cb(0); } +#endif + if (if_test) { hg->if_test = if_test; queue_work(hg->tx_wq, &hg->test_work); } set_bit(HGICF_DEV_FLAGS_INITED, &hg->flags); } - if ((test_bit(HGICF_DEV_FLAGS_BOOTDL, &hg->flags) || conn_stat != HGICF_HW_CONNECTED) && !qc_mode) { + + if (!qc_mode) { hgicf_load_config(hg); } } - hgic_dbg("Leave, ret=%d\n", ret); + hgic_dbg("Leave, ret=%d, soft_fc=%d\n", ret, hg->soft_fc); } -static void hgicf_alive_work(struct work_struct *work) +static void hgicf_detect_work(struct work_struct *work) { int retry = 4; int status = -1; - struct hgicf_wdev *hg = container_of(work, struct hgicf_wdev, alive_work); - - //hgic_dbg("SLEEP:%d\r\n", test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags)); - if(!test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags)){ - if(time_after(jiffies, hg->last_rx + msecs_to_jiffies(HGIC_ALIVE_TIMER))){ - //hgic_dbg("detect device status ...\r\n"); - while(retry-- > 0 && status != STATE_FW){ + struct hgicf_wdev *hg = container_of(work, struct hgicf_wdev, detect_work); + + hg->status.detect_tmr++; + if (!test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags) && test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + if (test_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags) || + test_bit(HGIC_BUS_FLAGS_ERROR, &hg->bus->flags) || + time_after(jiffies, hg->last_rx + msecs_to_jiffies(HGIC_DETECT_TIMER))) { + while (retry-- > 0 && status != STATE_FW) { status = hgic_bootdl_cmd_enter(&hg->bootdl); } - if (status != STATE_FW) { + + if (status != STATE_FW || hg->fw_state != STATE_FW) { hgic_dbg("need reload firmware ...\r\n"); - hg->soft_fc = 0; - set_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags); hgic_clear_queue(&hg->ctrl.txq); hgic_clear_queue(&hg->tx_dataq); - hg->bus->reinit(hg->bus); - schedule_work(&hg->delay_init); + if (hg->bus->reinit) { + hg->bus->reinit(hg->bus); + } + if (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + hg->soft_fc = 0; + hg->fw_state = -1; + set_bit(HGICF_DEV_FLAGS_SUSPEND, &hg->flags); + schedule_work(&hg->delay_init); + } } } } - //hgic_dbg("next detect after %d sec.\r\n", HGIC_ALIVE_TIMER); - mod_timer(&hg->alive_tmr, jiffies + msecs_to_jiffies(HGIC_ALIVE_TIMER)); + if (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + mod_timer(&hg->detect_tmr, jiffies + msecs_to_jiffies(HGIC_DETECT_TIMER)); + } } -#ifdef __RTOS__ -static void hgicf_alive_timer(unsigned long arg) +#if !defined(__RTOS__) && LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) +static void hgicf_detect_timer(struct timer_list *t) { - struct hgicf_wdev *hg = (struct hgicf_wdev *) arg; - schedule_work(&hg->alive_work); + struct hgicf_wdev *hg = from_timer(hg, t, detect_tmr); + if (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + schedule_work(&hg->detect_work); + } } #else -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0) -static void hgicf_alive_timer(struct timer_list *t) -{ - struct hgicf_wdev *hg = from_timer(hg, t, alive_tmr); - schedule_work(&hg->alive_work); -} -#else -static void hgicf_alive_timer(unsigned long arg) +static void hgicf_detect_timer(unsigned long arg) { struct hgicf_wdev *hg = (struct hgicf_wdev *) arg; - schedule_work(&hg->alive_work); + if (test_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags)) { + schedule_work(&hg->detect_work); + } } #endif -#endif -void hgic_schedule(struct hgic_fwctrl *ctrl) +static void hgicf_schedule(struct hgic_fwctrl *ctrl) { struct hgicf_wdev *hg = container_of(ctrl, struct hgicf_wdev, ctrl); queue_work(hg->tx_wq, &hg->tx_work); } -void hgic_rx_fw_event(struct hgic_fwctrl *ctrl, struct sk_buff *skb) +static void hgicf_probe_post(void *priv) { - struct hgicf_wdev *hg = container_of(ctrl, struct hgicf_wdev, ctrl); - hgicf_rx_fw_event(hg, skb); + struct hgicf_wdev *hg = (struct hgicf_wdev *)priv; + schedule_work(&hg->delay_init); } -int hgic_core_remove(void *hgobj) +#ifdef CONFIG_PM +static int hgicf_core_suspend(void *hgobj) +{ + int err = 0; + struct hgicf_wdev *hg = (struct hgicf_wdev *)hgobj; + if (!test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags)) { + err = hgic_fwctrl_enter_sleep(&hg->ctrl, HGIC_WDEV_ID_STA, 1, 0xffffffff); + } + return err; +} + +static int hgicf_core_resume(void *hgobj) +{ + int err = 0; + struct hgicf_wdev *hg = (struct hgicf_wdev *)hgobj; + + clear_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); + if (hg->bus->reinit) { + hg->bus->reinit(hg->bus); + } + + err = hgic_fwctrl_enter_sleep(&hg->ctrl, HGIC_WDEV_ID_STA, 0, 0); + if (err) { + hgic_err("exit sleep fail, ret=%d\r\n", err); + } + return err; +} +#endif + +static void hgicf_core_remove(void *hgobj) { struct hgicf_wdev *hg = hgobj; @@ -726,69 +918,65 @@ int hgic_core_remove(void *hgobj) hgic_dbg("Enter\n"); clear_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags); - del_timer_sync(&hg->alive_tmr); - cancel_work_sync(&hg->alive_work); - cancel_work_sync(&hg->delay_init); hgic_dbg(" trace ...\r\n"); - if (hg->ap) { - netif_stop_queue(hg->ap->ndev); - } - if (hg->sta) { - netif_stop_queue(hg->sta->ndev); + cancel_work_sync(&hg->detect_work); + hgic_dbg(" trace ...\r\n"); + del_timer_sync(&hg->detect_tmr); + hgic_dbg(" trace ...\r\n"); + cancel_work_sync(&hg->detect_work); + hgic_dbg(" trace ...\r\n"); + cancel_work_sync(&hg->delay_init); + if (hg->vif) { + netif_stop_queue(hg->vif->ndev); } + hgic_dbg(" trace ...\r\n"); + //while (!test_bit(HGICF_DEV_FLAGS_STOP, &hg->flags)); + cancel_work_sync(&hg->tx_work); + hgic_dbg(" trace ...\r\n"); + cancel_work_sync(&hg->test_work); + hgic_dbg(" trace ...\r\n"); hgicf_delete_procfs(hg); + hgic_dbg(" trace ...\r\n"); hgic_fwctrl_release(&hg->ctrl); hgic_dbg(" trace ...\r\n"); hgic_ota_release(&hg->ota); hgic_dbg(" trace ...\r\n"); hgic_bootdl_release(&hg->bootdl, 0); - hgic_dbg(" trace ...\r\n"); - //while (!test_bit(HGICF_DEV_FLAGS_STOP, &hg->flags)); - cancel_work_sync(&hg->tx_work); - hgic_dbg(" trace ...\r\n"); - cancel_work_sync(&hg->test_work); - hgic_dbg(" trace ... %p\r\n", hg->ap); - if (hg->ap) { - unregister_netdev(hg->ap->ndev); - } - hgic_dbg(" trace ... %p\r\n", hg->sta); - if (hg->sta) { - unregister_netdev(hg->sta->ndev); - } - hgic_dbg(" trace ...\r\n"); - hgic_clear_queue(&hg->tx_dataq); - hgic_dbg(" trace ...\r\n"); -#ifdef __RTOS__ - skb_queue_head_deinit(&hg->tx_dataq); -#else - hgic_clear_queue(&hg->custmgmt_q); - hgic_clear_queue(&hg->dbginfo_q); - hgic_clear_queue(&hg->cust_driverdata_q); -#endif hgic_dbg(" trace ...\r\n"); if (hg->tx_wq) { flush_workqueue(hg->tx_wq); destroy_workqueue(hg->tx_wq); } + hgic_dbg(" trace ... %p\r\n", hg->vif); + if (hg->vif) { + unregister_netdev(hg->vif->ndev); + } + hgic_dbg(" trace ...\r\n"); + + hgic_clear_queue(&hg->tx_dataq); hgic_dbg(" trace ...\r\n"); #ifdef __RTOS__ + skb_queue_head_deinit(&hg->tx_dataq); deinit_completion(&hg->txwnd_cp); spin_lock_deinit(&hg->lock); +#else + hgic_clear_queue(&hg->evt_list); #endif - if(hg->paired_stas) - kfree(hg->paired_stas); kfree(hg); hgic_dbg("Leave\n"); } - return 0; } -EXPORT_SYMBOL(hgic_core_remove); -int hgic_core_probe(void *dev, struct hgic_bus *bus) +static int hgicf_core_probe(void *dev, struct hgic_bus *bus) { struct hgicf_wdev *hg = NULL; - hgic_dbg("Enter,qc_mode=%d, no_bootdl=%d\n", qc_mode, no_bootdl); + if (!hgicf_match_devid(bus->dev_id)) { + hgic_err("FMAC driver not support device %x\n", bus->dev_id); + return -1; + } + + hgic_dbg("qc_mode=%d, no_bootdl=%d, if_agg=%d, txq_size=%d\n", qc_mode, no_bootdl, if_agg, txq_size); hg = kzalloc(sizeof(struct hgicf_wdev), GFP_KERNEL); if (hg) { memset(hg, 0, sizeof(struct hgicf_wdev)); @@ -796,82 +984,52 @@ int hgic_core_probe(void *dev, struct hgic_bus *bus) hg->bus = bus; hg->dev = dev; hg->dev_id = bus->dev_id; - hgic_fwctrl_init(&hg->ctrl, dev); + hg->proc_dev = proc_dev; + hg->fw_state = -1; + hgic_fwctrl_init(&hg->ctrl, dev, bus); + hg->ctrl.schedule = hgicf_schedule; + hg->ctrl.rx_event = hgicf_rx_fw_event; hgic_ota_init(&hg->ota, &hg->ctrl, &hg->fwinfo); spin_lock_init(&hg->lock); INIT_WORK(&hg->tx_work, hgicf_tx_work); INIT_WORK(&hg->delay_init, hgicf_delay_init); - INIT_WORK(&hg->alive_work, hgicf_alive_work); + INIT_WORK(&hg->detect_work, hgicf_detect_work); INIT_WORK(&hg->test_work, hgicf_test_work); - init_timer(&hg->alive_tmr); - setup_timer(&hg->alive_tmr, hgicf_alive_timer, (unsigned long)hg); + init_timer(&hg->detect_tmr); + setup_timer(&hg->detect_tmr, hgicf_detect_timer, (unsigned long)hg); skb_queue_head_init(&hg->tx_dataq); init_completion(&hg->txwnd_cp); hgic_bootdl_init(&hg->bootdl, hg->bus, &hg->ctrl); #ifndef __RTOS__ - skb_queue_head_init(&hg->custmgmt_q); - skb_queue_head_init(&hg->dbginfo_q); - skb_queue_head_init(&hg->cust_driverdata_q); - sema_init(&hg->evtq.sema, 0); + skb_queue_head_init(&hg->evt_list); + sema_init(&hg->evt_sema, 0); #endif + atomic_set(&hg->txwnd, TXWND_INIT_VAL); - bus->rx_packet = hgicf_rx_data; - bus->tx_complete = hgicf_tx_complete; - bus->bus_priv = hg; hg->tx_wq = ALLOC_ORDERED_WORKQUEUE("hgicf_tx", 4096); if (!hg->tx_wq) { goto __failed; } + set_bit(HGICF_DEV_FLAGS_RUNNING, &hg->flags); + bus->tx_complete = hgicf_tx_complete; + bus->rx_packet = hgicf_rx_data; + bus->probe_post = hgicf_probe_post; + bus->remove = hgicf_core_remove; +#ifdef CONFIG_PM + bus->suspend = hgicf_core_suspend; + bus->resume = hgicf_core_resume; +#endif + bus->bus_priv = hg; hgic_dbg("ok\n"); return 0; } __failed: - bus->rx_packet = NULL; - bus->tx_complete = NULL; - bus->bus_priv = NULL; - hgic_core_remove(hg); + hgicf_core_remove(hg); hgic_dbg("fail\n"); return -1; } -EXPORT_SYMBOL(hgic_core_probe); - -#ifdef CONFIG_PM -int hgic_core_suspend(void *hgobj) -{ - int err = 0; - struct hgicf_wdev *hg = (struct hgicf_wdev *)hgobj; - err = hgic_fwctrl_enter_sleep(&hg->ctrl, 1); - set_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); - return err; -} -EXPORT_SYMBOL(hgic_core_suspend); - -int hgic_core_resume(void *hgobj) -{ - int err = 0; - struct hgicf_wdev *hg = (struct hgicf_wdev *)hgobj; - clear_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); - if (hg->bus->reinit) { - hg->bus->reinit(hg->bus); - } - err = hgic_fwctrl_enter_sleep(&hg->ctrl, 0); - if(err) { - hgic_err("exit sleep fail, ret=%d\r\n", err); - } - schedule_work(&hg->alive_work); - return err; -} -EXPORT_SYMBOL(hgic_core_resume); -#endif - -void hgic_core_probe_post(void *priv) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)priv; - schedule_work(&hg->delay_init); -} -EXPORT_SYMBOL(hgic_core_probe_post); #ifdef __RTOS__ int hgic_ifbus_reinit(const char *ifname) @@ -901,59 +1059,58 @@ struct hgic_ota *hgic_devota(struct net_device *dev) int __init hgicf_init(void) { VERSOIN_SHOW("fmac"); + #ifdef __RTOS__ rcu_init(); tasklet_core_init(); net_device_init(); -#else -#ifdef CONFIG_HGIC_USBIN - hgic_usb_init(); #endif -#ifdef CONFIG_HGIC_SDIOIN - hgic_sdio_init(); + +#ifdef CONFIG_HGIC_USB + hgic_usb_init(hgicf_core_probe, if_agg); #endif +#ifdef CONFIG_HGIC_SDIO + hgic_sdio_init(hgicf_core_probe, if_agg); #endif + hgic_leave(); return 0; } void __exit hgicf_exit(void) { -#ifndef __RTOS__ -#ifdef CONFIG_HGIC_USBIN +#ifdef CONFIG_HGIC_USB hgic_usb_exit(); #endif -#ifdef CONFIG_HGIC_SDIOIN +#ifdef CONFIG_HGIC_SDIO hgic_sdio_exit(); #endif -#endif - #ifdef __RTOS__ net_device_exit(); tasklet_core_exit(); #endif } +#ifdef __RTOS__ const char *hgic_param_ifname(const char *name) { - if (name) ifname = (char *)name; + if (name) { + ifname = (char *)name; + } return ifname; } -#ifdef __RTOS__ + void hgic_param_iftest(int iftest) { if_test = iftest; } char *hgic_param_fwfile(const char *fw) { - if (fw) fw_file = fw; + if (fw) { + fw_file = fw; + } return fw_file; } -int hgic_param_ifcount(int count) -{ - if (count) iface_cnt = count; - return iface_cnt; -} void hgic_param_initcb(hgic_init_cb cb) { init_cb = cb; @@ -966,29 +1123,27 @@ void hgic_param_bootdl(int enable) { no_bootdl = !enable; } -#endif void hgicf_event(struct hgicf_wdev *hg, char *name, int event, int param1, int param2) { -#ifdef __RTOS__ - if(event_cb) + if (event_cb) { event_cb(name, event, param1, param2); -#else - FWEVTQ_SET(&hg->evtq, event); - up(&hg->evtq.sema); -#endif + } } +#endif module_init(hgicf_init); module_exit(hgicf_exit); module_param(txq_size, int, 0); module_param(fw_file, charp, 0644); module_param(if_test, int, 0); -module_param(soft_fc, int, 0); module_param(ifname, charp, 0644); -module_param(conf_file, charp, 0644); module_param(no_bootdl, int, 0); module_param(qc_mode, int, 0); +module_param(if_agg, int, 0); +module_param(conf_file, charp, 0644); +module_param(proc_dev, int, 0); + MODULE_DESCRIPTION("HUGE-IC FullMAC Wireless Card Driver"); MODULE_AUTHOR("Dongyun"); MODULE_LICENSE("GPL"); diff --git a/hgic_fmac/ctrl.c b/hgic_fmac/ctrl.c index 5fcd57a..6ba0897 100644 --- a/hgic_fmac/ctrl.c +++ b/hgic_fmac/ctrl.c @@ -8,7 +8,6 @@ #include "hgicf.h" #include "ctrl.h" -#include "cfg.h" #include "event.h" /* cmd id, Odd : get (world access), even : set (root access) */ @@ -20,14 +19,48 @@ #define HG_PRIV_IOCTL_SAVE (SIOCIWFIRSTPRIV + 0x06) struct iw_priv_args hgicf_privtab[] = { - {HG_PRIV_IOCTL_SET , IW_PRIV_TYPE_CHAR | 1536, 0, "set"}, - {HG_PRIV_IOCTL_GET , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, "get"}, + {HG_PRIV_IOCTL_SET, IW_PRIV_TYPE_CHAR | 1536, 0, "set"}, + {HG_PRIV_IOCTL_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, "get"}, {HG_PRIV_IOCTL_SCAN, IW_PRIV_TYPE_CHAR | 1536, 0, "scan"}, - {HG_PRIV_IOCTL_E2P , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, "e2p"}, + {HG_PRIV_IOCTL_E2P, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024, "e2p"}, {HG_PRIV_IOCTL_STAT, 0, IW_PRIV_TYPE_CHAR | 1024, "stat"}, {HG_PRIV_IOCTL_SAVE, IW_PRIV_TYPE_CHAR | 1024, 0, "save"}, }; +int hgicf_ioctl_set_proc(struct net_device *dev, struct iwreq *wrqin) +{ + struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); + return hgic_iwpriv_set_proc(&(vif->hg->ctrl), vif->fwifidx, wrqin); +} + +int hgicf_ioctl_get_proc(struct net_device *dev, struct iwreq *wrqin) +{ + struct hgicf_vif *vif = (struct hgicf_vif *)netdev_priv(dev); + return hgic_iwpriv_get_proc(&(vif->hg->ctrl), vif->fwifidx, wrqin); +} + +int hgicf_ioctl_stat(struct net_device *dev, struct iwreq *wrqin) +{ + return 0; +} + +int hgicf_ioctl_e2p(struct net_device *dev, struct iwreq *wrqin) +{ + 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), vif->fwifidx); +} + +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), vif->fwifidx); +} + int hgicf_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { int ret = 0; diff --git a/hgic_fmac/ctrl.h b/hgic_fmac/ctrl.h index 593cfe5..3b7b006 100644 --- a/hgic_fmac/ctrl.h +++ b/hgic_fmac/ctrl.h @@ -6,6 +6,14 @@ int hgicf_ioctl(struct net_device *dev, u32 cmd, u32 param1, u32 param2); #else int hgicf_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -#endif +int hgicf_ioctl_set_proc(struct net_device *dev, struct iwreq *wrqin); +int hgicf_ioctl_get_proc(struct net_device *dev, struct iwreq *wrqin); +int hgicf_ioctl_stat(struct net_device *dev, struct iwreq *wrqin); +int hgicf_ioctl_e2p(struct net_device *dev, struct iwreq *wrqin); +int hgicf_ioctl_savecfg(struct net_device *dev, struct iwreq *wrqin); +int hgicf_ioctl_scan(struct net_device *dev, struct iwreq *wrqin); +#endif + + #endif diff --git a/hgic_fmac/event.c b/hgic_fmac/event.c index 63ba73d..9181c89 100644 --- a/hgic_fmac/event.c +++ b/hgic_fmac/event.c @@ -21,176 +21,54 @@ #endif #include "hgicf.h" -#include "../utils/fwctrl.h" -#include "cfg.h" #include "event.h" -char *hgicf_hw_state(int state) -{ - switch (state) { - case HGICF_HW_DISCONNECTED: - return "Disconnect"; - case HGICF_HW_DISABLED: - return "DISABLED"; - case HGICF_HW_INACTIVE: - return "INACTIVE"; - case HGICF_HW_SCANNING: - return "SCANNING"; - case HGICF_HW_AUTHENTICATING: - return "AUTHENTICATING"; - case HGICF_HW_ASSOCIATING: - return "ASSOCIATING"; - case HGICF_HW_ASSOCIATED: - return "ASSOCIATED"; - case HGICF_HW_4WAY_HANDSHAKE: - return "4WAY_HANDSHAKE"; - case HGICF_HW_GROUP_HANDSHAKE: - return "GROUP_HANDSHAKE"; - case HGICF_HW_CONNECTED: - return "CONNECTED"; - default: - return "Unknown"; - } -} +#define HGIC_EVENT_MAX (16) -int hgicf_rx_fw_event(struct hgicf_wdev *hg, struct sk_buff *skb) +void hgicf_rx_fw_event(struct hgic_fwctrl *ctrl, struct sk_buff *skb) { - char drop = 1; + char drop = 0; char *data = NULL; + u32 data_len; u32 evt_id = 0; struct hgic_ctrl_hdr *evt = NULL; - struct hgicf_vif *vif = NULL; + struct hgicf_wdev *hg = container_of(ctrl, struct hgicf_wdev, ctrl); - if (skb == NULL || skb->dev == NULL || skb->len < sizeof(struct hgic_ctrl_hdr)) { + if (skb == NULL || skb->len < sizeof(struct hgic_ctrl_hdr)) { dev_kfree_skb(skb); - return -1; + return; } - vif = (struct hgicf_vif *)netdev_priv(skb->dev); evt = (struct hgic_ctrl_hdr *)skb->data; - skb_pull(skb, sizeof(struct hgic_ctrl_hdr)); - data = skb->data; + data = (char *)(evt + 1); + data_len = skb->len - sizeof(struct hgic_ctrl_hdr); evt_id = HDR_EVTID(evt); //hgic_dbg("event id:%d\r\n", evt->event.event_id); switch (evt_id) { - case HGIC_EVENT_STATE_CHG: - vif->hw_state = data[0]; - switch (vif->hw_state) { - case HGICF_HW_CONNECTED: - memcpy(vif->hw_bssid, data + 1, ETH_ALEN); - break; - default: - break; - } - break; - case HGIC_EVENT_DISCONNECT_REASON: - memcpy(&vif->disconnect_reason, data, sizeof(int)); - break; - case HGIC_EVENT_ASSOC_STATUS: - memcpy(&vif->assoc_status_code, data, sizeof(int)); - break; - case HGIC_EVENT_SCANNING: - hgicf_event(hg, skb->dev->name, HGIC_EVENT_SCANNING, 0, 0); - break; - case HGIC_EVENT_SCAN_DONE: - hgicf_event(hg, skb->dev->name, HGIC_EVENT_SCAN_DONE, 0, 0); - break; - case HGIC_EVENT_TX_BITRATE: - hg->status.tx_bitrate = get_unaligned_le32((u8 *)(evt + 1)); - hgicf_event(hg, skb->dev->name, HGIC_EVENT_TX_BITRATE, hg->status.tx_bitrate, 0); - break; - case HGIC_EVENT_PAIR_START: - hg->status.pair_state = 0; - memset(hg->pairing_sta, 0, 6); - hgicf_event(hg, skb->dev->name, HGIC_EVENT_PAIR_START, 0, 0); - break; - case HGIC_EVENT_PAIR_SUCCESS: - hg->status.pair_state = 1; - if(skb->len >= 6) memcpy(hg->pairing_sta, data, 6); - hgicf_event(hg, skb->dev->name, HGIC_EVENT_PAIR_SUCCESS, (long)hg->pairing_sta, 0); - break; - case HGIC_EVENT_PAIR_DONE: - hg->paired_stas_cnt = (evt->hdr.length - sizeof(struct hgic_ctrl_hdr)) / 6; - if (hg->paired_stas) { - kfree(hg->paired_stas); - } - hg->paired_stas = kzalloc(evt->hdr.length, GFP_KERNEL); - if (hg->paired_stas) { - memcpy(hg->paired_stas, data, hg->paired_stas_cnt * 6); - } - hgicf_event(hg, skb->dev->name, HGIC_EVENT_PAIR_DONE, (long)hg->paired_stas, (long)hg->paired_stas_cnt); - break; - case HGIC_EVENT_CONECT_START: - vif->hw_state = HGICF_HW_ASSOCIATING; - hgicf_event(hg, skb->dev->name, HGIC_EVENT_CONECT_START, 0, 0); - break; - case HGIC_EVENT_CONECTED: - vif->hw_state = HGICF_HW_CONNECTED; - hgicf_event(hg, skb->dev->name, HGIC_EVENT_CONECTED, (long)skb->data, skb->len); - break; - case HGIC_EVENT_DISCONECTED: - vif->hw_state = HGICF_HW_DISCONNECTED; - hgicf_event(hg, skb->dev->name, HGIC_EVENT_DISCONECTED, (long)skb->data, skb->len); - break; - case HGIC_EVENT_SIGNAL: - hg->status.signal = (s8)data[0]; - hg->status.evm = (s8)data[1]; - hgicf_event(hg, skb->dev->name, HGIC_EVENT_SIGNAL, hg->status.signal, hg->status.evm); - break; case HGIC_EVENT_FWDBG_INFO: - hgicf_event(hg, skb->dev->name, HGIC_EVENT_FWDBG_INFO, (long)skb->data, skb->len); -#ifndef __RTOS__ - printk("%s", skb->data); - if (skb_queue_len(&hg->dbginfo_q) > 4) { - kfree_skb(skb_dequeue(&hg->dbginfo_q)); - } - skb_queue_tail(&hg->dbginfo_q, skb); - drop = 0; -#endif - break; - case HGIC_EVENT_REQUEST_PARAM: - schedule_work(&hg->ctrl.flush_work); - break; - case HGIC_EVENT_CUSTOMER_MGMT: - hgic_dbg("rx mgmt from %pM, %d bytes\r\n", data, skb->len - 6); - hgicf_event(hg, skb->dev->name, HGIC_EVENT_CUSTOMER_MGMT, (long)skb->data, skb->len); -#ifndef __RTOS__ - if (skb_queue_len(&hg->custmgmt_q) > 16) { - kfree_skb(skb_dequeue(&hg->custmgmt_q)); - } - skb_queue_tail(&hg->custmgmt_q, skb); - drop = 0; -#endif - break; - case HGIC_EVENT_CUST_DRIVER_DATA: - hgicf_event(hg, skb->dev->name, HGIC_EVENT_CUST_DRIVER_DATA, (long)skb->data, skb->len); -#ifndef __RTOS__ - if (skb_queue_len(&hg->cust_driverdata_q) > 16) { - kfree_skb(skb_dequeue(&hg->cust_driverdata_q)); - } - skb_queue_tail(&hg->cust_driverdata_q, skb); - drop = 0; -#endif - break; - case HGIC_EVENT_DHCPC_DONE: -#ifndef __RTOS__ - memcpy(&hg->dhcpc, skb->data, sizeof(hg->dhcpc)); -#endif - hgicf_event(hg, skb->dev->name, HGIC_EVENT_DHCPC_DONE, (long)skb->data, skb->len); - break; - case HGIC_EVENT_CONNECT_FAIL: - hg->status.conntect_fail = data[0]; - hgicf_event(hg, skb->dev->name, HGIC_EVENT_CONNECT_FAIL, data[0], 0); - break; - case HGIC_EVENT_UNPAIR_STA: - hgic_dbg("unpair sta: %pM\r\n", data); - hgicf_event(hg, skb->dev->name, HGIC_EVENT_UNPAIR_STA, data, 0); + drop = 1; + printk(data); break; default: break; } - if (drop) { dev_kfree_skb(skb); } - return 0; + +#ifdef __RTOS__ + hgicf_event(hg, hg->vif->ndev->name, evt_id, data, data_len); + dev_kfree_skb(skb); +#else + if (!drop) { + if (skb_queue_len(&hg->evt_list) > HGIC_EVENT_MAX) { + kfree_skb(skb_dequeue(&hg->evt_list)); + hgic_err("event list is full (max %d), drop old event\r\n", HGIC_EVENT_MAX); + } + skb_queue_tail(&hg->evt_list, skb); + up(&hg->evt_sema); + } else { + dev_kfree_skb(skb); + } +#endif + } diff --git a/hgic_fmac/event.h b/hgic_fmac/event.h index 48e6f9c..9005668 100644 --- a/hgic_fmac/event.h +++ b/hgic_fmac/event.h @@ -2,7 +2,7 @@ #ifndef _HGICF_EVENT_H_ #define _HGICF_EVENT_H_ -int hgicf_rx_fw_event(struct hgicf_wdev *hg, struct sk_buff *skb); +void hgicf_rx_fw_event(struct hgic_fwctrl *ctrl, struct sk_buff *skb); void hgicf_event(struct hgicf_wdev *hg, char *name, int event, int param1, int param2); #endif diff --git a/hgic_fmac/hgicf.h b/hgic_fmac/hgicf.h index 8e23784..24cdfe0 100644 --- a/hgic_fmac/hgicf.h +++ b/hgic_fmac/hgicf.h @@ -12,8 +12,9 @@ #include "../utils/utils.h" #include "../utils/fwdl.h" #include "../utils/fwctrl.h" -#include "procfs.h" +#include "../utils/iwpriv.h" #include "../utils/ota.h" +#include "procfs.h" #define FWEVNTQ_SIZE (128) enum hgicf_dev_flags { @@ -32,31 +33,14 @@ enum hgicf_state { HGICF_STATE_QUEUE_STOPPED, }; -enum hgicf_hw_state { - HGICF_HW_DISCONNECTED, - HGICF_HW_DISABLED, - HGICF_HW_INACTIVE, - HGICF_HW_SCANNING, - HGICF_HW_AUTHENTICATING, - HGICF_HW_ASSOCIATING, - HGICF_HW_ASSOCIATED, - HGICF_HW_4WAY_HANDSHAKE, - HGICF_HW_GROUP_HANDSHAKE, - HGICF_HW_CONNECTED, -}; - struct hgicf_wdev; struct hgicf_vif { u8 fwifidx; - unsigned long state; + u32 opened; struct net_device *ndev; struct hgicf_wdev *hg; - int hw_state; - char hw_ssid[32]; - char hw_bssid[ETH_ALEN]; - int disconnect_reason; - int assoc_status_code; + struct net_device_stats stats; }; struct hgicf_status { @@ -65,6 +49,10 @@ struct hgicf_status { s8 evm; s8 pair_state; u8 conntect_fail; + u32 detect_tmr; + u32 tx_ctrl; + u32 tx_data; + u32 tx_fail; }; struct hgicf_wdev { @@ -74,22 +62,22 @@ struct hgicf_wdev { u16 data_cookie; u16 ctrl_cookie; u16 rx_cookie; + u8 fw_state; spinlock_t lock; + char *conf_file; struct hgic_fw_info fwinfo; struct hgic_bus *bus; - struct hgicf_vif *ap; - struct hgicf_vif *sta; + struct hgicf_vif *vif; struct sk_buff_head tx_dataq; struct work_struct tx_work; struct work_struct delay_init; /*delay init work*/ - struct work_struct alive_work; + struct work_struct detect_work; struct workqueue_struct *tx_wq; - struct delayed_work status_work; /*status print work*/ struct hgic_fwctrl ctrl; struct hgic_bootdl bootdl; struct hgicf_procfs proc; struct hgicf_status status; - struct timer_list alive_tmr; + struct timer_list detect_tmr; unsigned long last_rx; /*if test*/ struct work_struct test_work; @@ -97,27 +85,15 @@ struct hgicf_wdev { u32 test_jiff, if_test; /*soft fc*/ int soft_fc; + int proc_dev; atomic_t txwnd; struct completion txwnd_cp; -#ifndef __RTOS__ - struct sk_buff_head custmgmt_q; - struct sk_buff_head dbginfo_q; - struct sk_buff_head cust_driverdata_q; -#endif struct hgic_ota ota; - u8 pairing_sta[6]; - u8 *paired_stas; - u32 paired_stas_cnt; u8 radio_off; + #ifndef __RTOS__ - struct { - u8 buf[FWEVNTQ_SIZE]; - u8 wpos, rpos; - struct semaphore sema; - }evtq; - struct { - u32 ipaddr, netmask, svrip, router, dns1, dns2; - }dhcpc; + struct sk_buff_head evt_list; + struct semaphore evt_sema; #endif }; @@ -127,30 +103,5 @@ struct hgicf_hw_status { } __packed; extern void hgic_print_hex(char *buf, int len); -extern char *hgicf_hw_state(int state); -u16 hgicf_data_cookie(struct hgicf_wdev *hg); -#ifndef __RTOS__ -#define FWEVTQ_NPOS(evtq,pos) ((((evtq)->pos)+1 >= FWEVNTQ_SIZE) ? (0) : (((evtq)->pos)+1)) -#define FWEVTQ_EMPTY(evtq) ((evtq)->wpos == (evtq)->rpos) -#define FWEVTQ_FULL(evtq) (FWEVTQ_NPOS(evtq, wpos) == (evtq)->rpos) -#define FWEVTQ_COUNT(evtq) (((evtq)->rpos <= (evtq)->wpos)?\ - ((evtq)->wpos - (evtq)->rpos):\ - (FWEVNTQ_SIZE-(evtq)->rpos + (evtq)->wpos)) - -#define FWEVTQ_GET(evtq, val) do{\ - if(!FWEVTQ_EMPTY(evtq)){\ - val = (evtq)->buf[(evtq)->rpos];\ - (evtq)->rpos = FWEVTQ_NPOS((evtq), rpos);\ - }\ - } while(0) - -#define FWEVTQ_SET(evtq, val) do{\ - if(FWEVTQ_FULL(evtq)){\ - (evtq)->rpos = FWEVTQ_NPOS((evtq), rpos);\ - }\ - (evtq)->buf[(evtq)->wpos] = val;\ - (evtq)->wpos = FWEVTQ_NPOS((evtq), wpos);\ - } while (0) -#endif #endif diff --git a/hgic_fmac/procfs.c b/hgic_fmac/procfs.c index a4bd22c..9e37301 100644 --- a/hgic_fmac/procfs.c +++ b/hgic_fmac/procfs.c @@ -3,129 +3,43 @@ #include #include #include +#include #include "hgicf.h" -#include "cfg.h" +#include "ctrl.h" -#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 16, 0) -#define PDE_DATA(inode) pde_data(inode) -#endif - -static int hgicf_signal_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d\r\n", hg->status.signal); - return 0; -} -static int hgicf_signal_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_signal_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_signal = { - .proc_open = hgicf_signal_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_evm_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d\r\n", hg->status.evm); - return 0; -} -static int hgicf_evm_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_evm_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_evm = { - .proc_open = hgicf_evm_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_conn_state_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - if (hg->sta) { - hg->sta->hw_state = hgic_fwctrl_get_conn_state(&hg->ctrl); - seq_printf(seq, "%s\r\n", hgicf_hw_state(hg->sta->hw_state)); - } else { - seq_printf(seq, "CONNECTED\r\n"); - } - return 0; -} -static int hgicf_conn_state_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_conn_state_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_conn_state = { - .proc_open = hgicf_conn_state_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// - - -static int hgicf_txrate_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d\r\n", hg->status.tx_bitrate); - return 0; -} -static int hgicf_txrate_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_txrate_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_txrate = { - .proc_open = hgicf_txrate_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_testmode_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%s\r\n", hg->proc.testmode_buf); - return 0; -} -static int hgicf_testmode_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_testmode_show, PDE_DATA(inode)); -} -static ssize_t hgicf_testmode_send_cmd(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - memset(hg->proc.testmode_buf, 0, HGIC_TESTMODE_BUFF_SIZE); - ret = copy_from_user(hg->proc.testmode_buf, buffer, count); - hgic_fwctrl_testmode_cmd(&hg->ctrl, hg->proc.testmode_buf, HGIC_TESTMODE_BUFF_SIZE); - return ret ? -EINVAL : count; -} -static const struct proc_ops hgicf_pops_testmode = { - .proc_open = hgicf_testmode_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_testmode_send_cmd, - .proc_release = single_release, -}; -//////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// static int hgicf_status_show(struct seq_file *seq, void *v) { struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "fw info:%d.%d.%d.%d, svn version:%d, bootdl:%d\r\n", + + seq_printf(seq, "fw info:%d.%d.%d.%d, svn version:%d\r\n", (hg->fwinfo.version >> 24) & 0xff, (hg->fwinfo.version >> 16) & 0xff, (hg->fwinfo.version >> 8) & 0xff, (hg->fwinfo.version & 0xff), - hg->fwinfo.svn_version, test_bit(HGICF_DEV_FLAGS_BOOTDL, &hg->flags)); + hg->fwinfo.svn_version); + seq_printf(seq, "hgicf status:\r\n"); + seq_printf(seq, " RADIO:%d, FW_STATE:%d, SOFT_FC:%d, TXWND:%d\r\n", hg->ctrl.radio_onoff, hg->fw_state, hg->soft_fc, atomic_read(&hg->txwnd)); + seq_printf(seq, " FLAGS:%lx, BUS FLAGS:%lx, ALIVE_TMR:%d, TX_CTRL:%d, TX_DATA:%d, TX_FAIL:%d\r\n", + hg->flags, hg->bus->flags, hg->status.detect_tmr, hg->status.tx_ctrl, hg->status.tx_data, hg->status.tx_fail); + if (hg->ctrl.rxq.qlen) { + seq_printf(seq, " ctrl_rxq: %d\r\n", hg->ctrl.rxq.qlen); + } + if (hg->ctrl.txq.qlen) { + seq_printf(seq, " ctrl_txq: %d\r\n", hg->ctrl.txq.qlen); + } + if (hg->tx_dataq.qlen) { + seq_printf(seq, " tx_dataq : %d\r\n", hg->tx_dataq.qlen); + } + if (hg->evt_list.qlen) { + seq_printf(seq, " evt_list : %d\r\n", hg->evt_list.qlen); + } + if (hg->vif) { + seq_printf(seq, " tx_bytes: %lu, rx_bytes: %lu, tx_dropped: %lu\r\n", + hg->vif->stats.tx_bytes, hg->vif->stats.rx_bytes, hg->vif->stats.tx_dropped); + } return 0; } + static int hgicf_status_open(struct inode *inode, struct file *file) { return single_open(file, hgicf_status_show, PDE_DATA(inode)); @@ -136,16 +50,10 @@ static const struct proc_ops hgicf_pops_status = { .proc_lseek = seq_lseek, .proc_release = single_release, }; -/////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_ota_show(struct seq_file *seq, void *v) -{ - seq_printf(seq, "Enter OTA,SDK Version:20200402\r\n"); - return 0; -} static int hgicf_ota_open(struct inode *inode, struct file *file) { - return single_open(file, hgicf_ota_show, PDE_DATA(inode)); + return single_open(file, NULL, PDE_DATA(inode)); } static ssize_t hgicf_ota_send_data(struct file *file, const char __user *buffer, @@ -153,7 +61,6 @@ static ssize_t hgicf_ota_send_data(struct file *file, const char __user *buffer, { ssize_t ret = -1; char *fw_path = NULL; - char *ptr = NULL; struct seq_file *seq = (struct seq_file *)file->private_data; struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; @@ -174,99 +81,27 @@ static ssize_t hgicf_ota_send_data(struct file *file, const char __user *buffer, return -EFAULT; } - ptr = &fw_path[count - 1]; - while (*ptr == '\r' || *ptr == '\n') { *ptr-- = 0; } - + hgic_strip_tail(fw_path, count); hgic_dbg("ota firmware: %s\r\n", fw_path); ret = hgic_ota_send_fw(&hg->ota, fw_path, HG_OTA_WRITE_MEM_TMO); kfree(fw_path); return (ret ? -EIO : count); } static const struct proc_ops hgicf_pops_ota = { - .proc_open = hgicf_ota_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_ota_send_data, + .proc_open = hgicf_ota_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = hgicf_ota_send_data, .proc_release = single_release, }; -/////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_temperature_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - int temp = hgic_fwctrl_get_temperature(&hg->ctrl); - if (temp < 0) { temp = 0; } - seq_printf(seq, "%d\r\n", temp); - return 0; -} -static int hgicf_temperature_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_temperature_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_temperature = { - .proc_open = hgicf_temperature_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_sleep_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d\r\n", test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags)); - return 0; -} -static int hgicf_sleep_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_sleep_show, PDE_DATA(inode)); -} - -static ssize_t hgicf_enter_sleep(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int err = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u8 str[2] = {0, 0}; - int sleep = 0; - - err = copy_from_user(str, buffer, 1); - sleep = simple_strtol(str, 0, 10); - hgic_dbg("enter sleep :%d ...\r\n", sleep); - if (sleep) { - if(!test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags)){ - err = hgic_fwctrl_enter_sleep(&hg->ctrl, 1); - if (!err) { - set_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); - }else{ - hgic_err("sleep fail, ret=%d\r\n", err); - } - } - } else { - if(test_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags)){ - clear_bit(HGIC_BUS_FLAGS_SLEEP, &hg->bus->flags); - if (hg->bus->reinit) { - hg->bus->reinit(hg->bus); - } - err = hgic_fwctrl_enter_sleep(&hg->ctrl, 0); - if(err) hgic_err("exit sleep fail, ret=%d\r\n", err); - } - } - return count; -} -static const struct proc_ops hgicf_pops_sleep = { - .proc_open = hgicf_sleep_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_enter_sleep, - .proc_release = single_release, -}; /////////////////////////////////////////////////////////////////////////////////////////// static int hgicf_iwpriv_show(struct seq_file *seq, void *v) { struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%s\r\n", hg->proc.iwpriv_buf); - memset(hg->proc.iwpriv_buf, 0, sizeof(hg->proc.iwpriv_buf)); + if (hg->proc.iwpriv_result > 0) { + seq_write(seq, hg->proc.iwpriv_buf, hg->proc.iwpriv_result); + } return 0; } @@ -279,800 +114,182 @@ static ssize_t hgicf_iwpriv_write(struct file *file, const char __user *buffer, size_t count, loff_t *data) { int ret = 0; - int i = 0; + struct iwreq wrqin; + char *buf, *ifname, *cmd, *args; struct seq_file *seq = (struct seq_file *)file->private_data; struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - char *cmd_buf = kzalloc(count + 1, GFP_KERNEL); - char *ifname, *cmd, *args; - struct iwreq wrqin; - struct net_device *ndev = NULL; + struct hgicf_vif *vif = hg->vif; - if (count <= 0) { return -1; } - memset(hg->proc.iwpriv_buf, 0, sizeof(hg->proc.iwpriv_buf)); - if (cmd_buf) { - i = count - 1; - ret = copy_from_user(cmd_buf, buffer, count); - while (i >= 0 && (cmd_buf[i] == '\r' || cmd_buf[i] == '\n')) { - cmd_buf[i--] = 0; + if (count <= 0) { + return -1; + } + + buf = kzalloc(count + 32, GFP_KERNEL); + if (buf) { + ret = copy_from_user(buf, buffer, count); + if (ret) { + hgic_err("copy_from_user err: %d\r\n", ret); + kfree(buf); + return -EINVAL; } - ifname = cmd_buf; + ifname = buf; cmd = strchr(ifname, ' '); if (cmd == NULL) { - sprintf(hg->proc.iwpriv_buf, "invalid paramters:%s", cmd_buf); - goto __out; + wrqin.u.data.pointer = buf; + wrqin.u.data.length = count; + ret = hgic_iwpriv_dump(&hg->ctrl, &wrqin); + if (ret) { + if (copy_to_user((void *)(buffer + 4), (const void *)buf, ret <= count ? ret : count)) { + kfree(buf); + hgic_err("copy_to_user fail\r\n"); + return -EINVAL; + } + } + + if (copy_to_user((void *)buffer, (const void *)&ret, 4)) { + kfree(buf); + hgic_err("copy_to_user fail\r\n"); + return -EINVAL; + } + + hgic_err("**Empty CMD**\r\n"); + kfree(buf); + return count; } + *cmd++ = 0; args = strchr(cmd, ' '); - if (args) { *args++ = 0; } - - //hgic_dbg("ifname:%s, cmd:%s, args:%s\r\n", ifname, cmd, args); - if (hg->sta && strcmp(hg->sta->ndev->name, ifname) == 0) { - ndev = hg->sta->ndev; - } else if (hg->ap && strcmp(hg->ap->ndev->name, ifname) == 0) { - ndev = hg->ap->ndev; - } else { - strcpy(hg->proc.iwpriv_buf, "no such device"); - goto __out; + if (args) { + *args++ = 0; } + memset(&wrqin, 0, sizeof(wrqin)); + wrqin.u.data.pointer = args; + wrqin.u.data.length = args ? count - (args - buf) : 0; if (strcasecmp(cmd, "set") == 0) { - wrqin.u.data.pointer = args; - wrqin.u.data.length = args ? strlen(args) : 0; - ret = hgicf_ioctl_set_proc(ndev, &wrqin); - if (ret) { - sprintf(hg->proc.iwpriv_buf, "%s error:%d", args, ret); - } else { - sprintf(hg->proc.iwpriv_buf, "%s OK", args); + ret = hgic_iwpriv_set_proc(&hg->ctrl, vif->fwifidx, &wrqin); + } else if (strcasecmp(cmd, "get") == 0) { + ret = hgic_iwpriv_get_proc(&hg->ctrl, vif->fwifidx, &wrqin); + if (ret == 0 && wrqin.u.data.length) { + ret = wrqin.u.data.length; + if (copy_to_user((void *)(buffer + 4), (const void *)args, ret <= count ? ret : count)) { + kfree(buf); + hgic_err("copy_to_user fail\r\n"); + return -EINVAL; + } } - } else if (strcasecmp(cmd, "get") == 0 && args) { - wrqin.u.data.pointer = hg->proc.iwpriv_buf; - wrqin.u.data.length = strlen(args); - strcpy(hg->proc.iwpriv_buf, args); - ret = hgicf_ioctl_get_proc(ndev, &wrqin); } else if (strcasecmp(cmd, "scan") == 0) { - wrqin.u.data.pointer = hg->proc.iwpriv_buf; - ret = hgicf_ioctl_scan(ndev, &wrqin); - strcpy(hg->proc.iwpriv_buf, ret ? "Fail" : "OK"); + ret = hgic_fwctrl_scan(&hg->ctrl, vif->fwifidx); } else if (strcasecmp(cmd, "save") == 0) { - ret = hgicf_ioctl_savecfg(ndev, &wrqin); - strcpy(hg->proc.iwpriv_buf, ret ? "Fail" : "OK"); - } else if (strcasecmp(cmd, "stat") == 0) { - wrqin.u.data.pointer = hg->proc.iwpriv_buf; - ret = hgicf_ioctl_stat(ndev, &wrqin); - } else if (strcasecmp(cmd, "e2p") == 0) { - strcpy(hg->proc.iwpriv_buf, "not support now"); + ret = hgic_fwctrl_save_cfg(&hg->ctrl, vif->fwifidx); +#if 0 + } else if (strcasecmp(cmd, "open") == 0) { + if(vif->opened == 0){ + ret = vif->ndev->netdev_ops->ndo_open(vif->ndev); + DEV_OPEN(vif->ndev); + }else{ + ret = 0; + } + } else if (strcasecmp(cmd, "close") == 0) { + if(vif->opened == 1){ + ret = vif->ndev->netdev_ops->ndo_stop(vif->ndev); + DEV_CLOSE(vif->ndev); + }else{ + ret = 0; + } +#endif } else { - strcpy(hg->proc.iwpriv_buf, "invalid parameters"); + kfree(buf); + hgic_err("invalid cmd: [%s]\r\n", cmd); + return -EINVAL; } - } else { - strcpy(hg->proc.iwpriv_buf, "no memory"); - } -__out: - if (cmd_buf) { - kfree(cmd_buf); - } - return ret ? -EINVAL : count; -} -static const struct proc_ops hgicf_pops_iwpriv = { - .proc_open = hgicf_iwpriv_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_iwpriv_write, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_paired_stas_show(struct seq_file *seq, void *v) -{ - int i = 0; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - if (hg->paired_stas && hg->paired_stas_cnt) { - for (i = 0; i < hg->paired_stas_cnt; i++) { - seq_printf(seq, "%pM", hg->paired_stas + i * 6); + if (copy_to_user((void *)buffer, &ret, 4)) { + kfree(buf); + hgic_err("copy_to_user fail\r\n"); + return -EINVAL; } - } - return 0; -} -static int hgicf_paired_stas_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_paired_stas_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_paired_stas = { - .proc_open = hgicf_paired_stas_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_radio_off_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "Radio %s\r\n", hg->radio_off ? "OFF" : "ON"); - return 0; -} -static int hgicf_radio_off_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_radio_off_show, PDE_DATA(inode)); -} -static ssize_t hgicf_radio_off_config(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u8 str[2] = {0, 0}; - ret = copy_from_user(str, buffer, 1); - if(ret) - return -EINVAL; - - hg->radio_off = simple_strtol(str, 0, 10); - hgic_dbg("radio %s \r\n", hg->radio_off ? "OFF" : "ON"); - if (hg->radio_off) { - hgic_fwctrl_close_dev(&hg->ctrl); - } else { - hgic_fwctrl_open_dev(&hg->ctrl); - } - return count; -} -static const struct proc_ops hgicf_pops_radio_off = { - .proc_open = hgicf_radio_off_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_radio_off_config, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_sta_count_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d\r\n", hgic_fwctrl_get_sta_count(&hg->ctrl)); - return 0; -} -static int hgicf_sta_count_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_sta_count_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_sta_count = { - .proc_open = hgicf_sta_count_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_ps_heartbeat_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_ps_heartbeat_set(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u8 str[32]; - u32 ip[4] = {0}; - u32 port = 0; - u32 ipaddr = 0; - u32 period = 0; - u32 hb_tmo = 300; - - memset(str, 0, sizeof(str)); - ret = copy_from_user(str, buffer, count > 32 ? 32 : count); - if(ret) - return -EINVAL; - - sscanf(str, "%d.%d.%d.%d,%d,%d,%d", &ip[0], &ip[1], &ip[2], &ip[3], &port, &period, &hb_tmo); - ipaddr = ((ip[0] & 0xff) << 24) | ((ip[1] & 0xff) << 16) | (((ip[2] & 0xff) << 8)) | (ip[3] & 0xff); - hgic_fwctrl_set_ps_heartbeat(&hg->ctrl, ipaddr, port, period, hb_tmo); - return count; -} -static const struct proc_ops hgicf_pops_ps_heartbeat = { - .proc_open = hgicf_ps_heartbeat_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_ps_heartbeat_set, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_ps_heartbeat_resp_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_ps_heartbeat_resp_set(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u8 *ptr = kzalloc(count, GFP_KERNEL); - if (ptr) { - ret = copy_from_user(ptr, buffer, count); - if(!ret) - ret = hgic_fwctrl_set_ps_heartbeat_resp(&hg->ctrl, ptr, count); - kfree(ptr); - } - return ret ? -EINVAL: count; -} -static const struct proc_ops hgicf_pops_ps_heartbeat_resp = { - .proc_open = hgicf_ps_heartbeat_resp_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_ps_heartbeat_resp_set, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_ps_wakeup_data_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_ps_wakeup_data_set(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u8 *ptr = kzalloc(count, GFP_KERNEL); - if (ptr) { - ret = copy_from_user(ptr, buffer, count); - if(!ret){ - ret = hgic_fwctrl_set_ps_wakeup_data(&hg->ctrl, ptr, count); - } - kfree(ptr); - } - return ret ? -EINVAL: count; -} -static const struct proc_ops hgicf_pops_ps_wakeup_data = { - .proc_open = hgicf_ps_wakeup_data_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_ps_wakeup_data_set, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_wakeup_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_wakeup_sta(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - u8 addr[6]; - u8 addr_str[32]; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - ret = copy_from_user(addr_str, buffer, count > 32 ? 32 : count); - if(ret) return -EINVAL; - if (!hgic_pick_macaddr(addr_str, addr)) { - memset(addr, 0, 6); - } - ret = hgic_fwctrl_wakeup_sta(&hg->ctrl, addr); - return ret ? -EINVAL : count; -} -static const struct proc_ops hgicf_pops_wakeup = { - .proc_open = hgicf_wakeup_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_wakeup_sta, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_pair_state_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d\r\n", hg->status.pair_state); - return 0; -} -static int hgicf_pair_state_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_pair_state_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_pair_state = { - .proc_open = hgicf_pair_state_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_fw_ver_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%d.%d.%d.%d-%d\r\n", - (hg->fwinfo.version >> 24) & 0xff, (hg->fwinfo.version >> 16) & 0xff, - (hg->fwinfo.version >> 8) & 0xff, (hg->fwinfo.version & 0xff), - hg->fwinfo.svn_version); - return 0; -} -static int hgicf_fw_ver_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_fw_ver_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_fw_ver = { - .proc_open = hgicf_fw_ver_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_wkreason_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - int reason = hgic_fwctrl_get_wkreason(&hg->ctrl); - seq_printf(seq, "%d\r\n", reason); - return 0; -} -static int hgicf_wkreason_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_wkreason_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_wkreason = { - .proc_open = hgicf_wkreason_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_fwevent_show(struct seq_file *seq, void *v) -{ - u8 event = 0; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - if(down_timeout(&hg->evtq.sema, msecs_to_jiffies(100))) - return 0; - FWEVTQ_GET(&hg->evtq, event); - seq_printf(seq, "%d\r\n", event); - return 0; -} -static int hgicf_fwevent_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_fwevent_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_fwevent = { - .proc_open = hgicf_fwevent_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_mgmt_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_send_mgmt(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - u8 *buff; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - buff = kzalloc(count+1, GFP_KERNEL); - if(buff == NULL) - return -ENOMEM; - ret = copy_from_user(buff, buffer, count); - if(!ret) - ret = hgic_fwctrl_send_cust_mgmt(&hg->ctrl, buff, count); - kfree(buff); - return ret ? -EINVAL : count; -} -static ssize_t hgicf_mgmt_read(struct file *file, char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct sk_buff *skb = NULL; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - if(!skb_queue_empty(&hg->custmgmt_q)){ - skb = skb_dequeue(&hg->custmgmt_q); - if(skb){ - ret = copy_to_user(buffer, skb->data, skb->len); - kfree(skb); - } - } - return ret; -} - -static const struct proc_ops hgicf_pops_mgmt = { - .proc_open = hgicf_mgmt_open, - .proc_read = hgicf_mgmt_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_send_mgmt, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_battery_level_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - int soc = hgic_fwctrl_get_battery_level(&hg->ctrl); - seq_printf(seq, "%d\r\n", soc); - return 0; -} -static int hgicf_battery_level_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_battery_level_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_battery_level = { - .proc_open = hgicf_battery_level_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_fwdbginfo_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - struct sk_buff *skb = skb_dequeue(&hg->dbginfo_q); - if(skb){ - seq_printf(seq, "%s", skb->data); - } - return 0; -} -static int hgicf_fwdbginfo_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_fwdbginfo_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_fwdbginfo = { - .proc_open = hgicf_fwdbginfo_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; -///////////////////////////////////////////////////////////////////////////////////////////////// - -static int hgicf_pairing_sta_show(struct seq_file *seq, void *v) -{ - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - seq_printf(seq, "%pM", hg->pairing_sta); - return 0; -} -static int hgicf_pairing_sta_open(struct inode *inode, struct file *file) -{ - return single_open(file, hgicf_pairing_sta_show, PDE_DATA(inode)); -} -static const struct proc_ops hgicf_pops_pairing_sta = { - .proc_open = hgicf_pairing_sta_open, - .proc_read = seq_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; - -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_dhcpc_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_dhcpc_read(struct file *file, char __user *buffer, - size_t count, loff_t *data) -{ - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - return copy_to_user(buffer, &hg->dhcpc, sizeof(hg->dhcpc)); -} -static const struct proc_ops hgicf_pops_dhcpc = { - .proc_open = hgicf_dhcpc_open, - .proc_read = hgicf_dhcpc_read, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; - -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_wkdata_buff_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_wkdata_buff_read(struct file *file, char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u8 *buff = (u8 *)kzalloc(1600, GFP_KERNEL); - - if(buff){ - ret = hgic_fwctrl_get_wkdata_buff(&hg->ctrl, buff, 1600); - if(ret > 0){ - ret = copy_to_user(buffer, buff, ret); - //printk("wkdata buff:%d\r\n", ret); - } - kfree(buff); - return ret; + kfree(buf); + return count; } return -ENOMEM; } -static const struct proc_ops hgicf_pops_wkdata_buff = { - .proc_open = hgicf_wkdata_buff_open, - .proc_read = hgicf_wkdata_buff_read, - .proc_lseek = seq_lseek, +static const struct proc_ops hgicf_pops_iwpriv = { + .proc_open = hgicf_iwpriv_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_write = hgicf_iwpriv_write, .proc_release = single_release, }; -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_ps_wkdata_mask_open(struct inode *inode, struct file *file) +/////////////////////////////////////////////////////////////////////////////////////////// + +static int hgicf_fwevent_open(struct inode *inode, struct file *file) { return single_open(file, NULL, PDE_DATA(inode)); } -static ssize_t hgicf_ps_wkdata_mask_write(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - u16 buff[64]; - u8 len = count>128 ? 128 : count; - ret = copy_from_user((u8 *)buff, buffer, len); - if(!ret){ - ret = hgic_fwctrl_set_wkdata_mask(&hg->ctrl, buff[0], (u8 *)(buff+1), len - 2); - } - return ret ? -EINVAL : count; -} -static const struct proc_ops hgicf_pops_wkdata_mask = { - .proc_open = hgicf_ps_wkdata_mask_open, - .proc_write = hgicf_ps_wkdata_mask_write, - .proc_lseek = seq_lseek, - .proc_release = single_release, -}; - -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_cust_driverdata_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_cust_driverdata_write(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - u8 *buff; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - if(count > 1500) count = 1500; - buff = kzalloc(count+1, GFP_KERNEL); - if(buff == NULL) - return -ENOMEM; - ret = copy_from_user(buff, buffer, count); - if(!ret) - ret = hgic_fwctrl_set_cust_driver_data(&hg->ctrl, buff, count); - kfree(buff); - return ret ? -EINVAL : count; -} -static ssize_t hgicf_cust_driverdata_read(struct file *file, char __user *buffer, - size_t count, loff_t *data) +static ssize_t hgicf_fwevent_read(struct file *file, char __user *buffer, + size_t count, loff_t *data) { int ret = 0; struct sk_buff *skb = NULL; struct seq_file *seq = (struct seq_file *)file->private_data; struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - if(!skb_queue_empty(&hg->cust_driverdata_q)){ - skb = skb_dequeue(&hg->cust_driverdata_q); - if(skb){ - ret = copy_to_user(buffer, skb->data, skb->len); - kfree(skb); + if (down_timeout(&hg->evt_sema, msecs_to_jiffies(100))) { + return 0; + } + + if (!skb_queue_empty(&hg->evt_list)) { + skb = skb_dequeue(&hg->evt_list); + if (skb) { + if (!copy_to_user(buffer, skb->data, skb->len)) { + ret = skb->len; + } + kfree_skb(skb); } } return ret; } - -static const struct proc_ops hgicf_pops_cust_driverdata = { - .proc_open = hgicf_cust_driverdata_open, - .proc_read = hgicf_cust_driverdata_read, - .proc_lseek = seq_lseek, - .proc_write = hgicf_cust_driverdata_write, +static const struct proc_ops hgicf_pops_fwevent = { + .proc_open = hgicf_fwevent_open, + .proc_read = hgicf_fwevent_read, + .proc_lseek = seq_lseek, .proc_release = single_release, }; -/////////////////////////////////////////////////////////////////////////////////////////// - -///////////////////////////////////////////////////////////////////////////////////////////////// -static int hgicf_freqinfo_open(struct inode *inode, struct file *file) -{ - return single_open(file, NULL, PDE_DATA(inode)); -} -static ssize_t hgicf_freqinfo_write(struct file *file, const char __user *buffer, - size_t count, loff_t *data) -{ - int ret = 0; - u8 *buff; - struct seq_file *seq = (struct seq_file *)file->private_data; - struct hgicf_wdev *hg = (struct hgicf_wdev *)seq->private; - - buff = kzalloc(count+1, GFP_KERNEL); - if(buff == NULL) - return -ENOMEM; - ret = copy_from_user(buff, buffer, count); - if(!ret) - ret = hgic_fwctrl_set_freqinfo(&hg->ctrl, buff, count); - kfree(buff); - return ret ? -EINVAL : count; -} - -static const struct proc_ops hgicf_pops_freqinfo = { - .proc_open = hgicf_freqinfo_open, - .proc_lseek = seq_lseek, - .proc_write = hgicf_freqinfo_write, - .proc_release = single_release, -}; -/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// void hgicf_create_procfs(struct hgicf_wdev *hg) { hgic_dbg("enter\r\n"); - hg->proc.rootdir = proc_mkdir("hgic", NULL); + hg->proc.rootdir = proc_mkdir(hg->proc_dev ? hg->vif->ndev->name : "hgicf", NULL); if (hg->proc.rootdir == NULL) { hgic_err("create proc dir: hgic failed\r\n"); return; } - hg->proc.tx_bitrate = proc_create_data("tx_bitrate", 0x0444, - hg->proc.rootdir, &hgicf_pops_txrate, hg); - if (hg->proc.tx_bitrate == NULL) { - hgic_err("create proc file: tx_bitrate failed\r\n"); - } - - hg->proc.testmode = proc_create_data("testmode", 0x0666, - hg->proc.rootdir, &hgicf_pops_testmode, hg); - if (hg->proc.testmode == NULL) { - hgic_err("create proc file: testmode failed\r\n"); - } - hg->proc.status = proc_create_data("status", 0x0444, hg->proc.rootdir, &hgicf_pops_status, hg); if (hg->proc.status == NULL) { hgic_err("create proc file: status failed\r\n"); } - - hg->proc.signal = proc_create_data("signal", 0x0444, - hg->proc.rootdir, &hgicf_pops_signal, hg); - if (hg->proc.signal == NULL) { - hgic_err("create proc file: signal failed\r\n"); - } - - hg->proc.evm = proc_create_data("evm", 0x0444, - hg->proc.rootdir, &hgicf_pops_evm, hg); - if (hg->proc.evm == NULL) { - hgic_err("create proc file: evm failed\r\n"); - } - - hg->proc.conn_state = proc_create_data("conn_state", 0x0444, - hg->proc.rootdir, &hgicf_pops_conn_state, hg); - if (hg->proc.conn_state == NULL) { - hgic_err("create proc file: conn_state failed\r\n"); - } - - hg->proc.ota = proc_create_data("ota", 0x0666, - hg->proc.rootdir, &hgicf_pops_ota, hg); + hg->proc.ota = proc_create_data("ota", 0x0666, hg->proc.rootdir, &hgicf_pops_ota, hg); if (hg->proc.ota == NULL) { hgic_err("create proc file: testmode failed\r\n"); } - hg->proc.temp = proc_create_data("temperature", 0x0444, - hg->proc.rootdir, &hgicf_pops_temperature, hg); - if (hg->proc.temp == NULL) { - hgic_err("create proc file: temperature failed\r\n"); - } - - hg->proc.sleep = proc_create_data("sleep", 0x0666, - hg->proc.rootdir, &hgicf_pops_sleep, hg); - if (hg->proc.sleep == NULL) { - hgic_err("create proc file: sleep failed\r\n"); - } - - hg->proc.iwpriv = proc_create_data("iwpriv", 0x0666, - hg->proc.rootdir, &hgicf_pops_iwpriv, hg); + hg->proc.iwpriv = proc_create_data("iwpriv", 0x0666, hg->proc.rootdir, &hgicf_pops_iwpriv, hg); if (hg->proc.iwpriv == NULL) { hgic_err("create proc file: iwpriv failed\r\n"); } - hg->proc.paired_stas = proc_create_data("paired_stas", 0x0444, - hg->proc.rootdir, &hgicf_pops_paired_stas, hg); - if (hg->proc.paired_stas == NULL) { - hgic_err("create proc file: paired_stas failed\r\n"); - } - hg->proc.radio_off = proc_create_data("radio_off", 0x0666, - hg->proc.rootdir, &hgicf_pops_radio_off, hg); - if (hg->proc.radio_off == NULL) { - hgic_err("create proc file: radio_off failed\r\n"); - } - hg->proc.sta_count = proc_create_data("sta_count", 0x0444, - hg->proc.rootdir, &hgicf_pops_sta_count, hg); - if (hg->proc.sta_count == NULL) { - hgic_err("create proc file: sta_count failed\r\n"); - } - hg->proc.heartbeat = proc_create_data("heartbeat", 0x0666, - hg->proc.rootdir, &hgicf_pops_ps_heartbeat, hg); - if (hg->proc.heartbeat == NULL) { - hgic_err("create proc file: wakeup failed\r\n"); - } - hg->proc.heartbeat_resp = proc_create_data("heartbeat_resp", 0x0666, - hg->proc.rootdir, &hgicf_pops_ps_heartbeat_resp, hg); - if (hg->proc.heartbeat_resp == NULL) { - hgic_err("create proc file: wakeup failed\r\n"); - } - hg->proc.wakeup_data = proc_create_data("wakeup_data", 0x0666, - hg->proc.rootdir, &hgicf_pops_ps_wakeup_data, hg); - if (hg->proc.wakeup_data == NULL) { - hgic_err("create proc file: wakeup failed\r\n"); - } - hg->proc.wakeup = proc_create_data("wakeup", 0x0666, - hg->proc.rootdir, &hgicf_pops_wakeup, hg); - if (hg->proc.wakeup == NULL) { - hgic_err("create proc file: wakeup failed\r\n"); - } - hg->proc.pair_state = proc_create_data("pair_state", 0x0444, - hg->proc.rootdir, &hgicf_pops_pair_state, hg); - if (hg->proc.pair_state == NULL) { - hgic_err("create proc file: pair_state failed\r\n"); - } - hg->proc.fw_ver = proc_create_data("fw_ver", 0x0444, - hg->proc.rootdir, &hgicf_pops_fw_ver, hg); - if (hg->proc.fw_ver == NULL) { - hgic_err("create proc file: fw_ver failed\r\n"); - } - hg->proc.wkreason = proc_create_data("wkreason", 0x0444, - hg->proc.rootdir, &hgicf_pops_wkreason, hg); - if (hg->proc.wkreason == NULL) { - hgic_err("create proc file: wkreason failed\r\n"); - } - hg->proc.fwevent = proc_create_data("event", 0x0444, - hg->proc.rootdir, &hgicf_pops_fwevent, hg); + hg->proc.fwevent = proc_create_data("fwevnt", 0x0444, hg->proc.rootdir, &hgicf_pops_fwevent, hg); if (hg->proc.fwevent == NULL) { hgic_err("create proc file: event failed\r\n"); } - hg->proc.mgmt = proc_create_data("mgmt", 0x0666, - hg->proc.rootdir, &hgicf_pops_mgmt, hg); - if (hg->proc.mgmt == NULL) { - hgic_err("create proc file: mgmt failed\r\n"); - } - hg->proc.battery_level = proc_create_data("battery_level", 0x0444, - hg->proc.rootdir, &hgicf_pops_battery_level, hg); - if (hg->proc.battery_level == NULL) { - hgic_err("create proc file: battery_soc failed\r\n"); - } - hg->proc.fwdbginfo = proc_create_data("fwdbginfo", 0x0444, - hg->proc.rootdir, &hgicf_pops_fwdbginfo, hg); - if (hg->proc.fwdbginfo == NULL) { - hgic_err("create proc file: fwdbginfo failed\r\n"); - } - hg->proc.pairing_sta = proc_create_data("pairing_sta", 0x0444, - hg->proc.rootdir, &hgicf_pops_pairing_sta, hg); - if (hg->proc.pairing_sta == NULL) { - hgic_err("create proc file: pairing_sta failed\r\n"); - } - hg->proc.dhcpc = proc_create_data("dhcpc", 0x0444, - hg->proc.rootdir, &hgicf_pops_dhcpc, hg); - if (hg->proc.dhcpc == NULL) { - hgic_err("create proc file: dhcpc failed\r\n"); - } - hg->proc.wkdata_buff = proc_create_data("wkdata_buff", 0x0444, - hg->proc.rootdir, &hgicf_pops_wkdata_buff, hg); - if (hg->proc.wkdata_buff == NULL) { - hgic_err("create proc file: wkdata_buff failed\r\n"); - } - hg->proc.wkdata_mask = proc_create_data("wkdata_mask", 0x0666, - hg->proc.rootdir, &hgicf_pops_wkdata_mask, hg); - if (hg->proc.wkdata_mask == NULL) { - hgic_err("create proc file: wkdata_mask failed\r\n"); - } - hg->proc.cust_driverdata = proc_create_data("cust_driverdata", 0x0666, - hg->proc.rootdir, &hgicf_pops_cust_driverdata, hg); - if (hg->proc.cust_driverdata == NULL) { - hgic_err("create proc file: cust_driverdata failed\r\n"); - } - hg->proc.freqinfo = proc_create_data("freqinfo", 0x0444, - hg->proc.rootdir, &hgicf_pops_freqinfo, hg); - if (hg->proc.freqinfo == NULL) { - hgic_err("create proc file: freqinfo failed\r\n"); - } + hgic_dbg("leave\r\n"); } @@ -1080,128 +297,26 @@ void hgicf_delete_procfs(struct hgicf_wdev *hg) { hgic_dbg("enter\r\n"); if (hg->proc.rootdir) { - if (hg->proc.tx_bitrate) { - remove_proc_entry("tx_bitrate", hg->proc.rootdir); - hg->proc.tx_bitrate = NULL; - } - if (hg->proc.testmode) { - remove_proc_entry("testmode", hg->proc.rootdir); - hg->proc.testmode = NULL; - } if (hg->proc.status) { remove_proc_entry("status", hg->proc.rootdir); hg->proc.status = NULL; } - if (hg->proc.signal) { - remove_proc_entry("signal", hg->proc.rootdir); - hg->proc.signal = NULL; - } - if (hg->proc.evm) { - remove_proc_entry("evm", hg->proc.rootdir); - hg->proc.evm = NULL; - } - if (hg->proc.conn_state) { - remove_proc_entry("conn_state", hg->proc.rootdir); - hg->proc.conn_state = NULL; - } if (hg->proc.ota) { remove_proc_entry("ota", hg->proc.rootdir); hg->proc.ota = NULL; } - if (hg->proc.temp) { - remove_proc_entry("temperature", hg->proc.rootdir); - hg->proc.temp = NULL; - } - if (hg->proc.sleep) { - remove_proc_entry("sleep", hg->proc.rootdir); - hg->proc.sleep = NULL; - } if (hg->proc.iwpriv) { remove_proc_entry("iwpriv", hg->proc.rootdir); hg->proc.iwpriv = NULL; } - if (hg->proc.paired_stas) { - remove_proc_entry("paired_stas", hg->proc.rootdir); - hg->proc.paired_stas = NULL; - } - if (hg->proc.radio_off) { - remove_proc_entry("radio_off", hg->proc.rootdir); - hg->proc.radio_off = NULL; - } - if (hg->proc.sta_count) { - remove_proc_entry("sta_count", hg->proc.rootdir); - hg->proc.sta_count = NULL; - } - if (hg->proc.heartbeat) { - remove_proc_entry("heartbeat", hg->proc.rootdir); - hg->proc.heartbeat = NULL; - } - if (hg->proc.heartbeat_resp) { - remove_proc_entry("heartbeat_resp", hg->proc.rootdir); - hg->proc.heartbeat_resp = NULL; - } - if (hg->proc.wakeup_data) { - remove_proc_entry("wakeup_data", hg->proc.rootdir); - hg->proc.wakeup_data = NULL; - } - if (hg->proc.wakeup) { - remove_proc_entry("wakeup", hg->proc.rootdir); - hg->proc.wakeup = NULL; - } - if (hg->proc.pair_state) { - remove_proc_entry("pair_state", hg->proc.rootdir); - hg->proc.pair_state = NULL; - } - if (hg->proc.fw_ver) { - remove_proc_entry("fw_ver", hg->proc.rootdir); - hg->proc.fw_ver = NULL; - } - if (hg->proc.wkreason) { - remove_proc_entry("wkreason", hg->proc.rootdir); - hg->proc.wkreason = NULL; - } if (hg->proc.fwevent) { - remove_proc_entry("event", hg->proc.rootdir); + remove_proc_entry("fwevnt", hg->proc.rootdir); hg->proc.fwevent = NULL; } - if (hg->proc.mgmt) { - remove_proc_entry("mgmt", hg->proc.rootdir); - hg->proc.mgmt = NULL; - } - if (hg->proc.battery_level) { - remove_proc_entry("battery_level", hg->proc.rootdir); - hg->proc.battery_level = NULL; - } - if (hg->proc.fwdbginfo) { - remove_proc_entry("fwdbginfo", hg->proc.rootdir); - hg->proc.fwdbginfo = NULL; - } - if (hg->proc.pairing_sta) { - remove_proc_entry("pairing_sta", hg->proc.rootdir); - hg->proc.pairing_sta = NULL; - } - if (hg->proc.dhcpc) { - remove_proc_entry("dhcpc", hg->proc.rootdir); - hg->proc.dhcpc = NULL; - } - if (hg->proc.wkdata_buff) { - remove_proc_entry("wkdata_buff", hg->proc.rootdir); - hg->proc.wkdata_buff = NULL; - } - if (hg->proc.wkdata_mask) { - remove_proc_entry("wkdata_mask", hg->proc.rootdir); - hg->proc.wkdata_mask = NULL; - } - if (hg->proc.cust_driverdata) { - remove_proc_entry("cust_driverdata", hg->proc.rootdir); - hg->proc.cust_driverdata = NULL; - } - if (hg->proc.freqinfo) { - remove_proc_entry("freqinfo", hg->proc.rootdir); - hg->proc.freqinfo = NULL; - } - remove_proc_entry("hgic", NULL); + remove_proc_entry(hg->proc_dev ? hg->vif->ndev->name : "hgicf", NULL); hg->proc.rootdir = NULL; + } else { + hgic_err("hg->proc.rootdir is NULL\r\n"); } hgic_dbg("leave\r\n"); } diff --git a/hgic_fmac/procfs.h b/hgic_fmac/procfs.h index 544f060..5289eea 100644 --- a/hgic_fmac/procfs.h +++ b/hgic_fmac/procfs.h @@ -17,38 +17,12 @@ struct hgicf_wdev; #define HGIC_TESTMODE_BUFF_SIZE (4096) struct hgicf_procfs { struct proc_dir_entry *rootdir; - struct proc_dir_entry *tx_bitrate; - struct proc_dir_entry *testmode; struct proc_dir_entry *status; - struct proc_dir_entry *signal; - struct proc_dir_entry *evm; - struct proc_dir_entry *conn_state; - u8 testmode_buf[HGIC_TESTMODE_BUFF_SIZE]; struct proc_dir_entry *ota; - struct proc_dir_entry *temp; - struct proc_dir_entry *sleep; struct proc_dir_entry *iwpriv; u8 iwpriv_buf[4096]; - struct proc_dir_entry *paired_stas; - struct proc_dir_entry *radio_off; - struct proc_dir_entry *sta_count; - struct proc_dir_entry *wakeup; - struct proc_dir_entry *wakeup_data; - struct proc_dir_entry *heartbeat; - struct proc_dir_entry *heartbeat_resp; - struct proc_dir_entry *pair_state; - struct proc_dir_entry *fw_ver; - struct proc_dir_entry *wkreason; + u32 iwpriv_result; struct proc_dir_entry *fwevent; - struct proc_dir_entry *mgmt; - struct proc_dir_entry *battery_level; - struct proc_dir_entry *fwdbginfo; - struct proc_dir_entry *pairing_sta; - struct proc_dir_entry *dhcpc; - struct proc_dir_entry *wkdata_buff; - struct proc_dir_entry *wkdata_mask; - struct proc_dir_entry *cust_driverdata; - struct proc_dir_entry *freqinfo; }; void hgicf_create_procfs(struct hgicf_wdev *hg); diff --git a/hgtest b/hgtest deleted file mode 100755 index c579ff2..0000000 --- a/hgtest +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -echo $1 > /proc/hgic/testmode;cat /proc/hgic/testmode \ No newline at end of file diff --git a/how_to_build_with_kernel.txt b/how_to_build_with_kernel.txt new file mode 100644 index 0000000..b4fc109 --- /dev/null +++ b/how_to_build_with_kernel.txt @@ -0,0 +1,14 @@ +1. copy driver files to drivers/net/wireless/hugeic. + +2. cd drivers/net/wireless/hugeic + cp Makefile.in Makefile + +3. modify drivers/net/wireless/Kconfig, add new line: + source "drivers/net/wireless/hugeic/Kconfig" + +4. modify drivers/net/wireless/Makefile, add new line: + obj-$(CONFIG_HGICS) += hugeic/ + or + obj-$(CONFIG_HGICF) += hugeic/ + +5. run make menuconfig and select hugeic wifi driver. diff --git a/iwpriv b/iwpriv deleted file mode 100755 index 8554366..0000000 --- a/iwpriv +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -echo $* > /proc/hgic/iwpriv;cat /proc/hgic/iwpriv \ No newline at end of file diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 7978640..0000000 --- a/readme.txt +++ /dev/null @@ -1,34 +0,0 @@ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -fmac - 1.޸Makefile: ޸ıá - mtk 뻷£ - #MTK SDK - ARCH := mips - COMPILER := /opt/buildroot-gcc463/usr/bin/mipsel-linux- - LINUX_KERNEL_PATH := /home/dongyun/work/disk4/RT288x_AHv1.2/source/linux-3.10.14.x - - 2. ִ: make fmac - - - : - 1. error implicit declaration of function 'PDE_DATA' - ñLinux kernel汾죬proc fs ȱʧ PDE_DATA С - error hgic_fmac/procfs.f ļ鿴δ룬 LINUX_VERSION_CODE ޸һversion codeж - #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) - static inline struct proc_dir_entry *PDE(const struct inode *inode) - { - return PROC_I(inode)->pde; - } - static inline void *PDE_DATA(const struct inode *inode) - { - return PDE(inode)->data; - } - #endif - - - -hgicf.conf : fmacļapģʽ -fmac.sh : fmacű -hgtest : ģʽtoolڷͲģʽ -iwpriv : ̩оרõiwprivߡԭϵͳûiwprivʹô˹ߡ diff --git a/tools/ah_tool/build.sh b/tools/ah_tool/build.sh new file mode 100644 index 0000000..c784093 --- /dev/null +++ b/tools/ah_tool/build.sh @@ -0,0 +1,38 @@ +#! /bin/sh + +########################################################################### +export PATH=$PATH:/opt/buildroot-gcc463/usr/bin +ARCH=mipsel-linux +COMPILER=/opt/buildroot-gcc463/usr/bin/mipsel-linux + +########################################################################### + +# +rm -rf bin +mkdir lib bin + +# if [ ! -d libnl-3.2.25 ]; then + # tar xfz ../libnl-3.2.25.tar.gz + # cd libnl-3.2.25 + # ./configure CFLAGS="-ffunction-sections -fdata-sections" --host=${ARCH} --prefix=$(pwd)/lib --enable-shared --enable-static CC=${COMPILER}-gcc + # make clean;make;cd - +# fi +# cp -fv libnl-3.2.25/lib/.libs/libnl-3.a lib/libnl-3.a +# cp -fv libnl-3.2.25/lib/.libs/libnl-genl-3.a lib/libnl-genl-3.a + +# +cd ../test_app;make clean;make CC=${COMPILER}-gcc all;cd - +mv -fv ../test_app/bin/* bin/ + +# +# cd hostapd-2.6/hostapd +# make clean; make CC=${COMPILER}-gcc STRIP=${COMPILER}-strip; cd - +# cp -fv hostapd-2.6/hostapd/hostapd bin/hostapd +# cp -fv hostapd-2.6/hostapd/hostapd_cli bin/hostapd_cli + +# +# cd wpa_supplicant-2.6/wpa_supplicant +# make clean; make CC=${COMPILER}-gcc STRIP=${COMPILER}-strip; cd - +# cp -fv wpa_supplicant-2.6/wpa_supplicant/wpa_supplicant bin/wpa_supplicant +# cp -fv wpa_supplicant-2.6/wpa_supplicant/wpa_passphrase bin/wpa_passphrase +# cp -fv wpa_supplicant-2.6/wpa_supplicant/wpa_cli bin/wpa_cli diff --git a/tools/test_app/Makefile b/tools/test_app/Makefile new file mode 100644 index 0000000..5a1beb4 --- /dev/null +++ b/tools/test_app/Makefile @@ -0,0 +1,36 @@ +EXEC = hgota libnetat hgics hgicf hgpriv + +CFLAGS += -D__linux__ +LDFLAGS += -lm + +all: $(EXEC) + $(shell rm -rf bin; mkdir bin) + for i in $(EXEC) ; do mv -fv $$i bin/$$i ; done + +tcp_test: tcp_test.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +dsleep_test: dsleep_test.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +hgota: libota.o hgota.o fwinfo.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ libota.o hgota.o fwinfo.o $(LDLIBS) + +hguevent: hguevent.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +libnetat: libnetat.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +hgics: hgics.o blenc.o hgics_blenc.o hgics_relay.o + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ hgics.o hgics_blenc.o hgics_relay.o blenc.o $(LDLIBS) + +hgicf: hgicf.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +hgpriv: hgpriv.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +clean: + -rm -f $(EXEC) *.elf *.gdb *.o + diff --git a/hgota/fwinfo.c b/tools/test_app/fwinfo.c similarity index 100% rename from hgota/fwinfo.c rename to tools/test_app/fwinfo.c diff --git a/hgota/fwinfo.h b/tools/test_app/fwinfo.h similarity index 100% rename from hgota/fwinfo.h rename to tools/test_app/fwinfo.h diff --git a/tools/test_app/hgic.h b/tools/test_app/hgic.h new file mode 100644 index 0000000..212aad2 --- /dev/null +++ b/tools/test_app/hgic.h @@ -0,0 +1,541 @@ +#ifndef _HUGE_IC_H_ +#define _HUGE_IC_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __RTOS__ +#define HGIC_CMD_START 100 +#else +#define HGIC_CMD_START 0 +#endif + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +typedef void (*hgic_init_cb)(void *args); +typedef void (*hgic_event_cb)(char *ifname, int event, int param1, int param2); + +struct hgic_bss_info { + unsigned char bssid[6]; + unsigned char ssid[32]; + unsigned char encrypt; + signed char signal; + unsigned short freq; +}; + +struct hgic_fw_info { + unsigned int version; + unsigned int svn_version; + unsigned short chip_id; + unsigned short cpu_id; + unsigned char mac[6]; + unsigned char resv[2]; + unsigned int app_version; + unsigned int smt_dat; +}; + +struct hgic_sta_info { + unsigned char aid; + unsigned char ps:1; + unsigned char addr[6]; + signed char rssi; + signed char evm; + signed char tx_snr; + signed char rx_snr; +}; + +struct hgic_freqinfo { + unsigned char bss_bw, chan_cnt; + unsigned short freq_start, freq_end; + unsigned short chan_list[16]; +}; + +struct hgic_module_hwinfo{ + union{ + struct{ + unsigned char type; + unsigned char saw:1, rev:7; + }; + unsigned short v; + }; +}; + +struct hgic_txq_param { + unsigned short txop; + unsigned short cw_min; + unsigned short cw_max; + unsigned char aifs; + unsigned char acm; +}; + +struct hgic_mcast_txparam { + unsigned char dupcnt; + unsigned char tx_bw; + unsigned char tx_mcs; + unsigned char clearch; +}; + +struct hgic_rx_info { + unsigned char band; + unsigned char mcs: 4, bw: 4; + char evm; + char signal; + unsigned short freq; + short freq_off; + unsigned char rx_flags; + unsigned char antenna; + unsigned char nss : 4, s1g_nss : 4; + unsigned char vht_flag : 3, s1g_flag : 5; +}; + +struct hgic_tx_info { + unsigned char band; + unsigned char tx_bw; + unsigned char tx_mcs; + unsigned char antenna; + unsigned int tx_flags; + unsigned int tx_flags2; +}; + +struct bt_rx_info { + unsigned char channel; //current channel + unsigned char con_handle; //hci handle + signed char rssi; + unsigned char frm_type; + unsigned int rev; +}; + + +/*data packet header*/ +struct hgic_hdr { + unsigned short magic; + unsigned char type; + unsigned char ifidx: 4, flags: 4; + unsigned short length; + unsigned short cookie; +} __packed; + +struct hgic_frm_hdr { + struct hgic_hdr hdr; + union { + struct hgic_rx_info rx_info; + struct hgic_tx_info tx_info; + unsigned char rev[24]; + }; +} __packed; + +struct hgic_frm_hdr2 { + struct hgic_hdr hdr; +} __packed; + + +/*contro pakcet header*/ +struct hgic_ctrl_hdr { + struct hgic_hdr hdr; + union { + struct { + unsigned char cmd_id; + short status; + } cmd; + struct { + unsigned short cmd_id; + short status; + } cmd2; + struct { + unsigned char event_id; + short value; + } event; + struct { + unsigned short event_id; + short value; + } event2; + struct { + unsigned char type; + } hci; + unsigned char info[4]; + }; +} __packed; + +struct hgic_key_conf { + unsigned int cipher; + unsigned int flags; + unsigned char keyidx; + unsigned char keylen; + unsigned char key[0]; +}; + +struct hgic_cca_ctl { + char start_th; + char mid_th; + char ed_th; + /* CCA auto adjustment. + * When the cca automatic adjustment takes effect, the + * above three parameters are invalid. + */ + char auto_en : 1; +}; + +struct hgic_acs_result{ + unsigned int freq;//KHz + unsigned char sync_cnt; + signed char min; + signed char max; + signed char avg; +}; + +struct hgic_fallback_mcs { + unsigned char original_type; + unsigned char original_mcs; + unsigned char fallback_type; + unsigned char fallback_mcs; +}; + +#define HDR_CMDID(ctl) ((ctl)->hdr.type==HGIC_HDR_TYPE_CMD2? le16_to_cpu((ctl)->cmd2.cmd_id):(ctl)->cmd.cmd_id) +#define HDR_EVTID(ctl) ((ctl)->hdr.type==HGIC_HDR_TYPE_EVENT2?le16_to_cpu((ctl)->event2.event_id):(ctl)->event.event_id) +#define HDR_CMDID_SET(ctl, id) if(id>255){\ + (ctl)->hdr.type =HGIC_HDR_TYPE_CMD2;\ + (ctl)->cmd2.cmd_id = cpu_to_le16(id);\ + }else{\ + (ctl)->hdr.type =HGIC_HDR_TYPE_CMD;\ + (ctl)->cmd.cmd_id = id;\ + } +#define HDR_EVTID_SET(ctl, id) if(id>255){\ + (ctl)->hdr.type =HGIC_HDR_TYPE_EVENT2;\ + (ctl)->event2.event_id = cpu_to_le16(id);\ + }else{\ + (ctl)->hdr.type =HGIC_HDR_TYPE_EVENT;\ + (ctl)->event.event_id = id;\ + } + +enum hgic_hdr_type { + HGIC_HDR_TYPE_ACK = 1, + HGIC_HDR_TYPE_FRM = 2, + HGIC_HDR_TYPE_CMD = 3, + HGIC_HDR_TYPE_EVENT = 4, + HGIC_HDR_TYPE_FIRMWARE = 5, + HGIC_HDR_TYPE_NLMSG = 6, + HGIC_HDR_TYPE_BOOTDL = 7, + HGIC_HDR_TYPE_TEST = 8, + HGIC_HDR_TYPE_FRM2 = 9, + HGIC_HDR_TYPE_TEST2 = 10, + HGIC_HDR_TYPE_SOFTFC = 11, + HGIC_HDR_TYPE_OTA = 12, + HGIC_HDR_TYPE_CMD2 = 13, + HGIC_HDR_TYPE_EVENT2 = 14, + HGIC_HDR_TYPE_BOOTDL_DATA = 15, + HGIC_HDR_TYPE_IFBR = 16, + HGIC_HDR_TYPE_BEACON = 17, + HGIC_HDR_TYPE_AGGFRM = 18, + HGIC_HDR_TYPE_BLUETOOTH = 19, + + HGIC_HDR_TYPE_MAX, +}; + +enum hgic_cmd { + HGIC_CMD_DEV_OPEN = 1, /* fmac/smac */ + HGIC_CMD_DEV_CLOSE = 2, /* fmac/smac */ + HGIC_CMD_SET_MAC = 3, /* fmac/smac */ + HGIC_CMD_SET_SSID = 4, /* fmac */ + HGIC_CMD_SET_BSSID = 5, /* fmac */ + HGIC_CMD_SET_COUNTERY = 6, /* fmac */ + HGIC_CMD_SET_CHANNEL = 7, /* fmac */ + HGIC_CMD_SET_CENTER_FREQ = 8, /* smac */ + HGIC_CMD_SET_RTS_THRESHOLD = 9, /* smac */ + HGIC_CMD_SET_FRG_THRESHOLD = 10, /* smac */ + HGIC_CMD_SET_KEY_MGMT = 11, /* fmac */ + HGIC_CMD_SET_WPA_PSK = 12, /* fmac */ + HGIC_CMD_SET_KEY = 13, /* smac */ + HGIC_CMD_SCAN = 14, /* fmac */ + HGIC_CMD_GET_SCAN_LIST = 15, /* fmac */ + HGIC_CMD_SET_BSSID_FILTER = 16, /* fmac */ + HGIC_CMD_DISCONNECT = 17, /* fmac */ + HGIC_CMD_GET_BSSID = 18, /* fmac */ + HGIC_CMD_SET_WBNAT = 19, /* unused */ + HGIC_CMD_GET_STATUS = 20, /* fmac */ + HGIC_CMD_SET_LISTEN_INTERVAL = 21, /* smac */ + HGIC_CMD_SET_TX_POWER = 22, /* fmac/smac */ + HGIC_CMD_GET_TX_POWER = 23, /* fmac/smac */ + HGIC_CMD_SET_TX_LCOUNT = 24, /* unused */ + HGIC_CMD_SET_TX_SCOUNT = 25, /* unused */ + HGIC_CMD_ADD_STA = 26, /* smac */ + HGIC_CMD_REMOVE_STA = 27, /* smac */ + HGIC_CMD_SET_TX_BW = 28, /* fmac */ + HGIC_CMD_SET_TX_MCS = 29, /* fmac/smac */ + HGIC_CMD_SET_FREQ_RANGE = 30, /* fmac */ + HGIC_CMD_ACS_ENABLE = 31, /* fmac */ + HGIC_CMD_SET_PRIMARY_CHAN = 32, /* fmac */ + HGIC_CMD_SET_BG_RSSI = 33, /* fmac */ + HGIC_CMD_SET_BSS_BW = 34, /* fmac/smac */ + HGIC_CMD_TESTMODE_CMD = 35, /* fmac/smac */ + HGIC_CMD_SET_AID = 36, /* smac */ + HGIC_CMD_GET_FW_STATE = 37, /* unused */ + HGIC_CMD_SET_TXQ_PARAM = 38, /* smac */ + HGIC_CMD_SET_CHAN_LIST = 39, /* fmac */ + HGIC_CMD_GET_CONN_STATE = 40, /* fmac */ + HGIC_CMD_SET_WORK_MODE = 41, /* fmac */ + HGIC_CMD_SET_PAIRED_STATIONS = 42, /* fmac */ + HGIC_CMD_GET_FW_INFO = 43, /* fmac/smac */ + HGIC_CMD_PAIRING = 44, /* fmac */ + HGIC_CMD_GET_TEMPERATURE = 45, /* fmac/smac */ + HGIC_CMD_ENTER_SLEEP = 46, /* fmac */ + HGIC_CMD_OTA = 47, /* fmac */ + HGIC_CMD_GET_SSID = 48, /* fmac */ + HGIC_CMD_GET_WPA_PSK = 49, /* fmac */ + HGIC_CMD_GET_SIGNAL = 50, /* fmac */ + HGIC_CMD_GET_TX_BITRATE = 51, /* fmac */ + HGIC_CMD_SET_BEACON_INT = 52, /* fmac */ + HGIC_CMD_GET_STA_LIST = 53, /* fmac */ + HGIC_CMD_SAVE_CFG = 54, /* fmac */ + HGIC_CMD_JOIN_GROUP = 55, /* unused */ + HGIC_CMD_SET_ETHER_TYPE = 56, /* unused */ + HGIC_CMD_GET_STA_COUNT = 57, /* fmac */ + HGIC_CMD_SET_HEARTBEAT_INT = 58, /* fmac */ + HGIC_CMD_SET_MCAST_KEY = 59, /* unused */ + HGIC_CMD_SET_AGG_CNT = 60, /* fmac/smac */ + HGIC_CMD_GET_AGG_CNT = 61, /* fmac/smac */ + HGIC_CMD_GET_BSS_BW = 62, /* fmac/smac */ + HGIC_CMD_GET_FREQ_RANGE = 63, /* fmac */ + HGIC_CMD_GET_CHAN_LIST = 64, /* fmac */ + HGIC_CMD_RADIO_ONOFF = 65, /* fmac/smac */ + HGIC_CMD_SET_PS_HEARTBEAT = 66, /* fmac */ + HGIC_CMD_SET_WAKEUP_STA = 67, /* fmac */ + HGIC_CMD_SET_PS_HEARTBEAT_RESP = 68, /* fmac */ + HGIC_CMD_SET_PS_WAKEUP_DATA = 69, /* fmac */ + HGIC_CMD_SET_PS_CONNECT = 70, /* fmac */ + HGIC_CMD_SET_BSS_MAX_IDLE = 71, /* fmac */ + HGIC_CMD_SET_WKIO_MODE = 72, /* fmac */ + HGIC_CMD_SET_DTIM_PERIOD = 73, /* fmac */ + HGIC_CMD_SET_PS_MODE = 74, /* fmac */ + HGIC_CMD_LOAD_DEF = 75, /* fmac */ + HGIC_CMD_DISASSOC_STA = 76, /* fmac */ + HGIC_CMD_SET_APLOST_TIME = 77, /* fmac */ + HGIC_CMD_GET_WAKEUP_REASON = 78, /* fmac */ + HGIC_CMD_UNPAIR = 79, /* fmac */ + HGIC_CMD_SET_AUTO_CHAN_SWITCH = 80, /* fmac */ + HGIC_CMD_SET_REASSOC_WKHOST = 81, /* fmac */ + HGIC_CMD_SET_WAKEUP_IO = 82, /* fmac */ + HGIC_CMD_DBGINFO_OUTPUT = 83, /* fmac/smac */ + HGIC_CMD_SET_SYSDBG = 84, /* fmac/smac */ + HGIC_CMD_SET_AUTO_SLEEP_TIME = 85, /* fmac */ + HGIC_CMD_GET_KEY_MGMT = 86, /* fmac */ + HGIC_CMD_SET_PAIR_AUTOSTOP = 87, /* fmac */ + HGIC_CMD_SET_SUPER_PWR = 88, /* fmac */ + HGIC_CMD_SET_REPEATER_SSID = 89, /* fmac */ + HGIC_CMD_SET_REPEATER_PSK = 90, /* fmac */ + HGIC_CMD_CFG_AUTO_SAVE = 91, /* fmac */ + HGIC_CMD_SEND_CUST_MGMT = 92, /* fmac */ + HGIC_CMD_GET_BATTERY_LEVEL = 93, /* unused */ + HGIC_CMD_SET_DCDC13 = 94, /* fmac */ + HGIC_CMD_SET_ACKTMO = 95, /* fmac/smac */ + HGIC_CMD_GET_MODULETYPE = 96, /* fmac/smac */ + HGIC_CMD_PA_PWRCTRL_DIS = 97, /* fmac */ + HGIC_CMD_SET_DHCPC = 98, /* fmac */ + HGIC_CMD_GET_DHCPC_RESULT = 99, /* fmac */ + HGIC_CMD_SET_WKUPDATA_MASK = 100, /* fmac */ + HGIC_CMD_GET_WKDATA_BUFF = 101, /* fmac */ + HGIC_CMD_GET_DISASSOC_REASON = 102, /* fmac */ + HGIC_CMD_SET_WKUPDATA_SAVEEN = 103, /* fmac */ + HGIC_CMD_SET_CUST_DRIVER_DATA = 104, /* fmac */ + HGIC_CMD_SET_MCAST_TXPARAM = 105, /* unused */ + HGIC_CMD_SET_STA_FREQINFO = 106, /* fmac */ + HGIC_CMD_SET_RESET_STA = 107, /* fmac */ + HGIC_CMD_SET_UART_FIXLEN = 108, /* unused */ + HGIC_CMD_GET_UART_FIXLEN = 109, /* unused */ + HGIC_CMD_SET_ANT_AUTO = 110, /* fmac */ + HGIC_CMD_SET_ANT_SEL = 111, /* fmac */ + HGIC_CMD_GET_ANT_SEL = 112, /* fmac */ + HGIC_CMD_SET_WKUP_HOST_REASON = 113, /* fmac */ + HGIC_CMD_SET_MAC_FILTER_EN = 114, /* unused */ + HGIC_CMD_SET_ATCMD = 115, /* fmac/smac */ + HGIC_CMD_SET_ROAMING = 116, /* fmac */ + HGIC_CMD_SET_AP_HIDE = 117, /* fmac */ + HGIC_CMD_SET_DUAL_ANT = 118, /* fmac */ + HGIC_CMD_SET_MAX_TCNT = 119, /* fmac/smac */ + HGIC_CMD_SET_ASSERT_HOLDUP = 120, /* fmac/smac */ + HGIC_CMD_SET_AP_PSMODE_EN = 121, /* fmac */ + HGIC_CMD_SET_DUPFILTER_EN = 122, /* fmac */ + HGIC_CMD_SET_DIS_1V1_M2U = 123, /* fmac */ + HGIC_CMD_SET_DIS_PSCONNECT = 124, /* fmac */ + HGIC_CMD_SET_RTC = 125, /* fmac */ + HGIC_CMD_GET_RTC = 126, /* fmac */ + HGIC_CMD_SET_KICK_ASSOC = 127, /* fmac */ + HGIC_CMD_START_ASSOC = 128, /* fmac */ + HGIC_CMD_SET_AUTOSLEEP = 129, /* fmac */ + HGIC_CMD_SEND_BLENC_DATA = 130, /* smac */ + HGIC_CMD_SET_BLENC_EN = 131, /* smac */ + HGIC_CMD_RESET = 132, /* fmac/smac */ + HGIC_CMD_SET_HWSCAN = 133, /* smac */ + HGIC_CMD_GET_TXQ_PARAM = 134, /* smac */ + HGIC_CMD_SET_PROMISC = 135, /* smac */ + HGIC_CMD_SET_USER_EDCA = 136, /* fmac */ + HGIC_CMD_SET_FIX_TXRATE = 137, /* smac */ + HGIC_CMD_SET_NAV_MAX = 138, /* smac */ + HGIC_CMD_CLEAR_NAV = 139, /* smac */ + HGIC_CMD_SET_CCA_PARAM = 140, /* smac */ + HGIC_CMD_SET_TX_MODGAIN = 141, /* smac */ + HGIC_CMD_GET_NAV = 142, /* smac */ + HGIC_CMD_SET_BEACON_START = 143, /* smac */ + HGIC_CMD_SET_BLE_OPEN = 144, /* smac */ + HGIC_CMD_GET_MODE = 145, /* fmac */ + HGIC_CMD_GET_BGRSSI = 146, /* fmac */ + HGIC_CMD_SEND_BLENC_ADVDATA = 147, /* smac */ + HGIC_CMD_SEND_BLENC_SCANRESP = 148, /* smac */ + HGIC_CMD_SEND_BLENC_DEVADDR = 149, /* smac */ + HGIC_CMD_SEND_BLENC_ADVINTERVAL = 150, /* smac */ + HGIC_CMD_SEND_BLENC_STARTADV = 151, /* smac */ + HGIC_CMD_SET_RTS_DURATION = 152, /* smac */ + HGIC_CMD_STANDBY_CFG = 153, /* fmac */ + HGIC_CMD_SET_CONNECT_PAIRONLY = 154, /* fmac */ + HGIC_CMD_SET_DIFFCUST_CONN = 155, /* fmac */ + HGIC_CMD_GET_CENTER_FREQ = 156, /* smac */ + HGIC_CMD_SET_WAIT_PSMODE = 157, /* fmac */ + HGIC_CMD_SET_AP_CHAN_SWITCH = 158, /* fmac */ + HGIC_CMD_SET_CCA_FOR_CE = 159, /* fmac */ + HGIC_CMD_SET_DISABLE_PRINT = 160, /* fmac/smac */ + HGIC_CMD_SET_APEP_PADDING = 161, /* smac */ + HGIC_CMD_GET_ACS_RESULT = 162, /* fmac/smac */ + HGIC_CMD_GET_WIFI_STATUS_CODE = 163, /* fmac */ + HGIC_CMD_GET_WIFI_REASON_CODE = 164, /* fmac */ + HGIC_CMD_SET_WATCHDOG = 165, /* fmac/smac */ + HGIC_CMD_SET_RETRY_FALLBACK_CNT = 166, /* smac */ + HGIC_CMD_SET_FALLBACK_MCS = 167, /* smac */ + HGIC_CMD_GET_XOSC_VALUE = 168, /* smac */ + HGIC_CMD_SET_XOSC_VALUE = 169, /* smac */ + HGIC_CMD_GET_FREQ_OFFSET = 170, /* smac */ + HGIC_CMD_SET_CALI_PERIOD = 171, /* smac */ + HGIC_CMD_SET_BLENC_ADVFILTER = 172, /* smac */ + HGIC_CMD_SET_MAX_TX_DELAY = 173, /* smac */ + HGIC_CMD_GET_STA_INFO = 174, /* fmac */ + HGIC_CMD_SEND_MGMTFRAME = 175, /* fmac */ + +}; + +enum hgic_event { + HGIC_EVENT_STATE_CHG = 1, + HGIC_EVENT_CH_SWICH = 2, + HGIC_EVENT_DISCONNECT_REASON = 3, + HGIC_EVENT_ASSOC_STATUS = 4, + HGIC_EVENT_SCANNING = 5, + HGIC_EVENT_SCAN_DONE = 6, + HGIC_EVENT_TX_BITRATE = 7, + HGIC_EVENT_PAIR_START = 8, + HGIC_EVENT_PAIR_SUCCESS = 9, + HGIC_EVENT_PAIR_DONE = 10, + HGIC_EVENT_CONECT_START = 11, + HGIC_EVENT_CONECTED = 12, + HGIC_EVENT_DISCONECTED = 13, + HGIC_EVENT_SIGNAL = 14, + HGIC_EVENT_DISCONNET_LOG = 15, + HGIC_EVENT_REQUEST_PARAM = 16, + HGIC_EVENT_TESTMODE_STATE = 17, + HGIC_EVENT_FWDBG_INFO = 18, + HGIC_EVENT_CUSTOMER_MGMT = 19, + HGIC_EVENT_SLEEP_FAIL = 20, + HGIC_EVENT_DHCPC_DONE = 21, + HGIC_EVENT_CONNECT_FAIL = 22, + HGIC_EVENT_CUST_DRIVER_DATA = 23, + HGIC_EVENT_UNPAIR_STA = 24, + HGIC_EVENT_BLENC_DATA = 25, + HGIC_EVENT_HWSCAN_RESULT = 26, + HGIC_EVENT_EXCEPTION_INFO = 27, + HGIC_EVENT_DSLEEP_WAKEUP = 28, + HGIC_EVENT_STA_MIC_ERROR = 29, + HGIC_EVENT_ACS_DONE = 30, + HGIC_EVENT_FW_INIT_DONE = 31, + HGIC_EVENT_ROAM_CONECTED = 32, + HGIC_EVENT_MGMT_FRAME = 33, +}; + +enum hgicf_hw_state { + HGICF_HW_DISCONNECTED = 0, + HGICF_HW_DISABLED = 1, + HGICF_HW_INACTIVE = 2, + HGICF_HW_SCANNING = 3, + HGICF_HW_AUTHENTICATING = 4, + HGICF_HW_ASSOCIATING = 5, + HGICF_HW_ASSOCIATED = 6, + HGICF_HW_4WAY_HANDSHAKE = 7, + HGICF_HW_GROUP_HANDSHAKE = 8, + HGICF_HW_CONNECTED = 9, +}; + +enum HGIC_EXCEPTION_NUM{ + HGIC_EXCEPTION_CPU_USED_OVERTOP = 1, + HGIC_EXCEPTION_HEAP_USED_OVERTOP = 2, + HGIC_EXCEPTION_WIFI_BUFFER_USED_OVERTOP = 3, + HGIC_EXCEPTION_TX_BLOCKED = 4, + HGIC_EXCEPTION_TXDELAY_TOOLONG = 5, + HGIC_EXCEPTION_STRONG_BGRSSI = 6, + HGIC_EXCEPTION_TEMPERATURE_OVERTOP = 7, + HGIC_EXCEPTION_WRONG_PASSWORD = 8, +}; + +struct hgic_exception_info { + int num; + union { + struct { + int max, avg, min; + } txdelay; + struct { + int max, avg, min; + } bgrssi; + struct { + int total, used; + } buffer_usage; + struct { + int total, used; + } heap_usage; + struct { + int temp; + } temperature; + } info; +}; + +struct hgic_dhcp_result { + unsigned int ipaddr, netmask, svrip, router, dns1, dns2; +}; + +#ifdef __RTOS__ +struct firmware { + unsigned char *data; + unsigned int size; +}; +int request_firmware(const struct firmware **fw, const char *name, void *dev); +void release_firmware(struct firmware *fw); + +extern int hgicf_init(void); +extern int hgicf_cmd(char *ifname, unsigned int cmd, unsigned int param1, unsigned int param2); +extern int hgics_init(void); +extern void hgics_exit(void); +extern int wpas_init(void); +extern int wpas_start(char *ifname); +extern int wpas_stop(char *ifname); +extern int wpas_cli(char *ifname, char *cmd, char *reply_buff, int reply_len); +extern int wpas_passphrase(char *ssid, char *passphrase, char psk[32]); +extern int hapd_init(void); +extern int hapd_start(char *ifname); +extern int hapd_stop(char *ifname); +extern int hapd_cli(char *ifname, char *cmd, char *reply_buff, int reply_len); +extern void hgic_param_iftest(int iftest); +extern const char *hgic_param_ifname(const char *name); +extern char *hgic_param_fwfile(const char *fw); +extern int hgic_param_ifcount(int count); +extern void hgic_param_initcb(hgic_init_cb cb); +extern void hgic_param_eventcb(hgic_event_cb cb); +extern int hgic_ota_start(char *ifname, char *fw_name); + +void hgic_raw_init(void); +int hgic_raw_send(char *dest, char *data, int len); +int hgic_raw_rcev(char *buf, int size, char *src); + +#ifdef HGIC_SMAC +#include "umac_config.h" +#endif +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/tools/test_app/hgicf.c b/tools/test_app/hgicf.c new file mode 100644 index 0000000..059451c --- /dev/null +++ b/tools/test_app/hgicf.c @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * @file hgicf.c + * @author HUGE-IC Application Team + * @version V1.0.0 + * @date 2021-06-23 + * @brief hgic fmac driver daemon. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2022 HUGE-IC

+ * + ****************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hgic.h" + +#include "iwpriv.c" + +/////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// +#define IFNAME "hg0" + + +static void hgic_test_read_wakeupdata() +{ + int i = 0; + char *buff = malloc(4096); + do { + i = hgic_iwpriv_read_wkdata_buff(IFNAME, buff, 4096); + if (i > 0) { + buff[i] = 0; + printf("get wkdata, len:%d, %s\r\n", i, buff + 42); + } + } while (i > 0); + free(buff); +} + +int hgicf_fwevent_parse(u8 *event_data, u32 event_len) +{ + int i = 0; + u32 data_len = 0; + u32 evt_id = 0; + char *data = NULL; + char *buff; + struct hgic_exception_info *exp; + struct hgic_dhcp_result *dhcpc; + struct hgic_ctrl_hdr *evt = (struct hgic_ctrl_hdr *)event_data; + + data = (char *)(evt + 1); + data_len = event_len - sizeof(struct hgic_ctrl_hdr); + evt_id = HDR_EVTID(evt); + + printf("recv firmware event %d\r\n", evt_id); + buff = malloc(4096); + if (buff == NULL) { + return -1; + } + + switch (evt_id) { + case HGIC_EVENT_SCANNING: + printf("start scan ...\r\n"); + break; + case HGIC_EVENT_SCAN_DONE: + printf("scan done!\r\n"); + hgic_iwpriv_get_scan_list(IFNAME, buff, 4096); + printf("%s\r\n", buff); + break; + case HGIC_EVENT_TX_BITRATE: + printf("estimate tx bitrate:%dKbps\r\n", *(unsigned int *)data); + break; + case HGIC_EVENT_PAIR_START: + printf("start pairing ...\r\n"); + break; + case HGIC_EVENT_PAIR_SUCCESS: + printf("pairing success! ["MACSTR"]\r\n", MACARG(data)); + hgic_iwpriv_set_pairing(IFNAME, 0); //stop pair + break; + case HGIC_EVENT_PAIR_DONE: + printf("pairing done!\r\n"); + for(i=0; i*6 < data_len;i++){ + printf(" sta%d:"MACSTR"\r\n", i, MACARG(data+6*i)); + } + break; + case HGIC_EVENT_CONECT_START: + printf("start connecting ...\r\n"); + break; + case HGIC_EVENT_CONECTED: + printf("new sta "MACSTR" connected!\r\n", MACARG(data)); + hgic_test_read_wakeupdata(); + break; + case HGIC_EVENT_ROAM_CONECTED: + printf("roam success to "MACSTR"!\r\n", MACARG(data)); + break; + case HGIC_EVENT_DISCONECTED: + printf("sta "MACSTR" disconnected, reason_code=%d\r\n", MACARG(data), get_unaligned_le16(data+6)); + break; + case HGIC_EVENT_SIGNAL: + printf("signal changed: rssi:%d, evm:%d\r\n", (signed char)data[0], (signed char)data[1]); + break; + case HGIC_EVENT_CUSTOMER_MGMT: + printf("rx customer mgmt frame from "MACSTR", %d bytes \r\n", MACARG(data), data_len-6); + break; + case HGIC_EVENT_DHCPC_DONE: + dhcpc = (struct hgic_dhcp_result *)data; + printf("fw dhcpc result: ipaddr:"IPSTR", netmask:"IPSTR", svrip:"IPSTR", router:"IPSTR", dns:"IPSTR"/"IPSTR"\r\n", + IPARG(dhcpc->ipaddr), IPARG(dhcpc->netmask), IPARG(dhcpc->svrip), + IPARG(dhcpc->router), IPARG(dhcpc->dns1), IPARG(dhcpc->dns2)); + break; + case HGIC_EVENT_CONNECT_FAIL: + printf("connect fail, status_code=%d\r\n", get_unaligned_le16(data)); + break; + case HGIC_EVENT_CUST_DRIVER_DATA: + printf("rx customer driver data %d bytes\r\n", data_len); + break; + case HGIC_EVENT_UNPAIR_STA: + printf("unpair sta:"MACSTR"\r\n", MACARG(data)); + break; + case HGIC_EVENT_EXCEPTION_INFO: + exp = (struct hgic_exception_info *)data; + switch(exp->num){ + case HGIC_EXCEPTION_TX_BLOCKED: + printf("*wireless tx blocked, maybe need reset wifi module*\r\n"); + break; + case HGIC_EXCEPTION_TXDELAY_TOOLONG: + printf("*wireless txdelay too loog, %d:%d:%d *\r\n", + exp->info.txdelay.max, exp->info.txdelay.min, exp->info.txdelay.avg); + break; + case HGIC_EXCEPTION_STRONG_BGRSSI: + printf("*detect strong backgroud noise. %d:%d:%d *\r\n", + exp->info.bgrssi.max, exp->info.bgrssi.min, exp->info.bgrssi.avg); + break; + case HGIC_EXCEPTION_TEMPERATURE_OVERTOP: + printf("*chip temperature too overtop: %d *\r\n", exp->info.temperature.temp); + break; + case HGIC_EXCEPTION_WRONG_PASSWORD: + printf("*password maybe is wrong *\r\n"); + break; + } + break; + } + + free(buff); +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + int fd = -1; + u8 *buff = malloc(4096); + + HGIC = "hgicf"; + if (buff == NULL) { + printf("malloc fail\r\n"); + return -1; + } + +__open: + fd = open("/proc/hgicf/fwevnt", O_RDONLY); + if (fd == -1) { + //printf("open /proc/hgicf/fwevnt fail\r\n"); + sleep(1); + goto __open; + } + + while (1) { + ret = read(fd, buff, 4096); + if (ret > 0) { + hgicf_fwevent_parse(buff, ret); + }else if(ret < 0){ + close(fd); + goto __open; + } + } + + close(fd); + free(buff); + return 0; +} + diff --git a/hgota/hgota.c b/tools/test_app/hgota.c similarity index 100% rename from hgota/hgota.c rename to tools/test_app/hgota.c diff --git a/tools/test_app/hgpriv.c b/tools/test_app/hgpriv.c new file mode 100644 index 0000000..e608c46 --- /dev/null +++ b/tools/test_app/hgpriv.c @@ -0,0 +1,84 @@ +/** + ****************************************************************************** + * @file hgics.c + * @author HUGE-IC Application Team + * @version V1.0.0 + * @date 2022-05-18 + * @brief hgic smac driver daemon. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2022 HUGE-IC

+ * + ****************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hgic.h" + +#include "iwpriv.c" + +int main(int argc, char *argv[]) +{ + int fd = -1; + int i = 0; + int len = 0; + char cmd[512]; + char *buff; + int ret = 0; + + if (argc < 2) { + return -1; + } + + buff = malloc(4096); + if (buff == NULL) { + printf("no mem\r\n"); + return -1; + } + + fd = open("/proc/hgics/iwpriv", O_RDONLY); + if (fd != -1) { + HGIC = "hgics"; + } else { + fd = open("/proc/hgicf/iwpriv", O_RDONLY); + if (fd != -1) { + HGIC = "hgicf"; + } else { + printf("open iwpriv file fail\r\n"); + free(buff); + return -1; + } + } + close(fd); + + for (i = 1; i < argc; i++) { + len += sprintf(cmd + len, "%s ", argv[i]); + } + cmd[len - 1] = 0; + + memset(buff, 0, 4096); + ret = hgic_iwpriv_do(cmd, 0, 0, buff, 4096); + printf("RESP:%d\r\n%s\r\n", ret, buff); + free(buff); + return 0; +} + diff --git a/tools/test_app/iwpriv.c b/tools/test_app/iwpriv.c new file mode 100644 index 0000000..29cf005 --- /dev/null +++ b/tools/test_app/iwpriv.c @@ -0,0 +1,1399 @@ +/** + ****************************************************************************** + * @file iwpriv.c + * @author HUGE-IC Application Team + * @version V1.0.0 + * @date 2022-06-23 + * @brief app library for hgic wifi driver. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT 2022 HUGE-IC

+ * + ****************************************************************************** + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hgic.h" + +#define iwpriv_dbg(fmt, ...) printf("%s:%d::"fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) + +#define __packed __attribute__((packed)) +#define le16_to_cpu(p) (p) + +#define HCI_OPCODE(ogf, ocf) ((ocf) | ((ogf) << 10)) + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; + +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#define MACARG(a) (a)[0]&0xff, (a)[1]&0xff, (a)[2]&0xff, (a)[3]&0xff, (a)[4]&0xff, (a)[5]&0xff +#define IPSTR "%d.%d.%d.%d" +#define IPARG(a) ((a)>>24)&0xff, ((a)>>16)&0xff, ((a)>>8)&0xff, (a)&0xff +#define MAC2STR(mac, str) (sprintf((str), MACSTR, MACARG(mac))) +#define STR_EQ(s1,s2) (strcmp(s1,s2)==0) +#define MAC_EQ(a1,a2) (memcmp(a1,a2,6)==0) +#define MAX(a,b) ((a)>(b)?(a):(b)) + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; + +#define WLAN_FC_TODS 0x0100 +#define WLAN_FC_FROMDS 0x0200 +struct ieee80211_hdr { + uint16 frame_control; + uint16 duration_id; + uint8 addr1[6]; + uint8 addr2[6]; + uint8 addr3[6]; + uint16 seq_ctrl; +}; + +enum FMAC_CONNECT_REASON { + FMAC_ASSOC_SUCCESS = 0, + FMAC_ASSOC_REFUSED = 1, + FMAC_ASSOC_DENIED_NO_MORE_STAS = 17, + FMAC_ASSOC_DENIED_INSUFFICIENT_BANDWIDTH = 33, + FMAC_ASSOC_REFUSED_AP_OUT_OF_MEMORY = 93, + FMAC_ASSOC_NO_AP = 0xff +}; + +enum HGIC_MODULE_TYPE { + HGIC_MODULE_TYPE_700M = 1, + HGIC_MODULE_TYPE_900M = 2, + HGIC_MODULE_TYPE_860M = 3, + HGIC_MODULE_TYPE_810M = 5, +}; + +char *HGIC = "hgics"; +int blenc_mode = 0; + +void hgics_dump_hex(char *str, char *data, int len, int newline) +{ + int i = 0; + if (data && len) { + if (str) { + printf("%s", str); + } + + for (i = 0; i < len; i++) { + if (i > 0 && newline) { + if ((i & 0x7) == 0) printf(" "); + if ((i & 0xf) == 0) printf("\r\n"); + } + printf("%02x ", data[i] & 0xFF); + } + + printf("\r\n"); + } +} + +static inline void put_unaligned_le16(unsigned short val, unsigned char *p) +{ + *p++ = val; + *p++ = val >> 8; +} +static inline unsigned short get_unaligned_le16(const unsigned char *p) +{ + return p[0] | p[1] << 8; +} + +char *hgic_hw_state(int state) +{ + switch (state) { + case HGICF_HW_DISCONNECTED: + return "Disconnect"; + case HGICF_HW_DISABLED: + return "DISABLED"; + case HGICF_HW_INACTIVE: + return "INACTIVE"; + case HGICF_HW_SCANNING: + return "SCANNING"; + case HGICF_HW_AUTHENTICATING: + return "AUTHENTICATING"; + case HGICF_HW_ASSOCIATING: + return "ASSOCIATING"; + case HGICF_HW_ASSOCIATED: + return "ASSOCIATED"; + case HGICF_HW_4WAY_HANDSHAKE: + return "4WAY_HANDSHAKE"; + case HGICF_HW_GROUP_HANDSHAKE: + return "GROUP_HANDSHAKE"; + case HGICF_HW_CONNECTED: + return "CONNECTED"; + default: + return "Unknown"; + } +} + +int hgic_str2mac(char *mac_str, unsigned char *mac) +{ + int tmp[6]; + if (mac_str && mac) { + memset(tmp, 0, sizeof(tmp)); + memset(mac, 0, 6); + if (6 == sscanf(mac_str, MACSTR, &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5])) { + mac[0] = (unsigned char)tmp[0]; + mac[1] = (unsigned char)tmp[1]; + mac[2] = (unsigned char)tmp[2]; + mac[3] = (unsigned char)tmp[3]; + mac[4] = (unsigned char)tmp[4]; + mac[5] = (unsigned char)tmp[5]; + return 1; + } + } + return 0; +} + +int hgic_get_if_mac(char *ifname, char *mac) +{ + int sock; + struct ifreq ifr; + + memset(mac, 0, 6); + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + perror("socket"); + return -1; + } + + strcpy(ifr.ifr_name, ifname); + if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { + close(sock); + perror("ioctl"); + return -1; + } + + close(sock); + memcpy(mac, ifr.ifr_hwaddr.sa_data, 6); + return 0; +} + +int hgic_iwpriv_write(char *buff, int len) +{ + int ret = 0; + int fd = -1; + char file[32]; + + if (buff == NULL || len <= 0) { + return 0; + } + memset(file, 0, sizeof(file)); + sprintf(file, "/proc/%s/iwpriv", HGIC); + fd = open(file, O_WRONLY); + if (fd != -1) { + ret = write(fd, buff, len); + close(fd); + } else { + printf("open %s fail\r\n", file); + } + return ret; +} + +int hgic_iwpriv_do(char *cmd, char *in, int in_len, char *out, int out_len) +{ + int ret = strlen(cmd); + int len = ret + MAX(in_len, out_len); + char *ptr = NULL; + char *buff = NULL; + int set = (strstr(cmd, " set ") != NULL); + + buff = malloc(len); + if (buff == NULL) { + printf("no mem, alloc %d\r\n", (ret + in_len + out_len)); + return -1; + } + + memset(buff, 0, len); + strcpy(buff, cmd); + if (in && in_len) { + memcpy(buff + ret, in, in_len); + } + + ret = hgic_iwpriv_write(buff, len); + if (ret > 0) { + ret = *(int *)buff; + if (ret > 0 && out && out_len) { + memcpy(out, buff + 4, ret <= out_len ? ret : out_len); + } + } + + free(buff); + if (ret < 0) { + printf("hgic_iwpriv_write fail, ret=%d\r\n", ret); + } + return ret; +} + +int hgic_iwpriv_set_int(char *ifname, char *name, int val) +{ + char cmd[64]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s set %s=%d", ifname, name, val); + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} + +int hgic_iwpriv_set_mac(char *ifname, char *name, char *mac) +{ + char cmd[64]; + memset(cmd, 0, sizeof(cmd)); + if (strlen(mac) == 17 && mac[2] == ':' && mac[5] == ':' && mac[8] == ':' && mac[11] == ':' && mac[14] == ':') { + sprintf(cmd, "%s set %s=%s", ifname, name, mac); + } else { + sprintf(cmd, "%s set %s="MACSTR, ifname, name, MACARG(mac)); + } + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} + +int hgic_iwpriv_set_ints(char *ifname, char *name, int cnt, ...) +{ + int i = 0; + int val = 0; + char cmd[256]; + char *ptr = cmd; + va_list argptr; + + memset(cmd, 0, sizeof(cmd)); + sprintf(ptr, "%s set %s=", ifname, name); + ptr += strlen(ptr); + + va_start(argptr, cnt); + for (i = 0; i < cnt; i++) { + val = va_arg(argptr, int); + sprintf(ptr, (i == 0 ? "%d" : ",%d"), val); + ptr += strlen(ptr); + } + va_end(argptr); + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} + +int hgic_iwpriv_set_intarray(char *ifname, char *name, int *vals, int cnt) +{ + int i = 0; + char cmd[512]; + char *ptr = cmd; + + memset(cmd, 0, sizeof(cmd)); + sprintf(ptr, "%s set %s=", ifname, name); + ptr += strlen(ptr); + + for (i = 0; i < cnt; i++) { + sprintf(ptr, (i == 0 ? "%d" : ",%d"), vals[i]); + ptr += strlen(ptr); + } + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} + +int hgic_iwpriv_set_bytes(char *ifname, char *name, char *data, int len) +{ + char cmd[128]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s set %s=", ifname, name); + return hgic_iwpriv_do(cmd, data, len, 0, 0); +} + +int hgic_iwpriv_get_int(char *ifname, char *name) +{ + char cmd[128]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s get %s", ifname, name); + hgic_iwpriv_do(cmd, 0, 0, cmd, sizeof(cmd)); + return atoi(cmd); +} + +int hgic_iwpriv_get_bytes(char *ifname, char *name, char *buff, int count) +{ + char cmd[128]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s get %s", ifname, name); + return hgic_iwpriv_do(cmd, 0, 0, buff, count); +} + +int hgic_iwpriv_get_mac(char *ifname, char *name, char *mac) +{ + int ret = 0; + char cmd[128]; + + memset(mac, 0, 6); + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s get %s", ifname, name); + ret = hgic_iwpriv_do(cmd, 0, 0, cmd, sizeof(cmd)); + if (ret > 0) { + hgic_str2mac(cmd, mac); + } + return ret; +} + +/* proc fs api */ +int hgic_proc_read_bytes(char *name, char *buff, int len) +{ + char file[32]; + int ret = 0; + int fd = -1; + + if (buff == NULL || len <= 0) { + return 0; + } + + memset(buff, 0, len); + memset(file, 0, sizeof(file)); + sprintf(file, "/proc/%s/%s", HGIC, name); + fd = open(file, O_RDONLY); + if (fd != -1) { + ret = read(fd, buff, len); + close(fd); + } + return ret; +} + +int hgic_proc_write_bytes(char *name, char *buff, int len) +{ + int ret = 0; + char file[32]; + int fd = -1; + + if (buff == NULL || len == 0) { + return 0; + } + + memset(file, 0, sizeof(file)); + sprintf(file, "/proc/%s/%s", HGIC, name); + fd = open(file, O_WRONLY); + if (fd != -1) { + ret = write(fd, buff, len); + close(fd); + if (ret < 0) { + perror("error"); + } + } + return ret > 0; +} + +int hgic_proc_read_int(char *name) +{ + char buff[32]; + hgic_proc_read_bytes(name, buff, 32); + return atoi(buff); +} + +int hgic_proc_read_mac(char *name, char *mac) +{ + char buff[32]; + memset(mac, 0, 6); + hgic_proc_read_bytes(name, buff, 32); + return hgic_str2mac(buff, mac); +} + +int hgic_proc_write_int(char *name, int val) +{ + char buff[12]; + memset(buff, 0, sizeof(buff)); + sprintf(buff, "%d", val); + return hgic_proc_write_bytes(name, buff, strlen(buff)); +} + +int hgic_proc_write_mac(char *name, char *mac) +{ + char str[18]; + memset(str, 0, sizeof(str)); + if (strlen(mac) == 17 && mac[2] == ':' && mac[5] == ':' && mac[8] == ':' && mac[11] == ':' && mac[14] == ':') { + strncpy(str, mac, 17); + } else { + MAC2STR(mac, str); + } + return hgic_proc_write_bytes(name, str, strlen(str)); +} + +int hgic_proc_write_ints(char *name, int cnt, ...) +{ + int i = 0; + int val = 0; + char buff[512]; + char *ptr = buff; + va_list argptr; + + memset(buff, 0, sizeof(buff)); + va_start(argptr, cnt); + for (i = 0; i < cnt; i++) { + val = va_arg(argptr, int); + sprintf(ptr, (i == 0 ? "%d" : ",%d"), val); + ptr += strlen(ptr); + } + va_end(argptr); + return hgic_proc_write_bytes(name, buff, strlen(buff)); +} + +int hgic_proc_write_intarray(char *name, int *values, int cnt) +{ + int i = 0; + char buff[512]; + char *ptr = buff; + + memset(buff, 0, sizeof(buff)); + for (i = 0; i < cnt; i++) { + sprintf(ptr, (i == 0 ? "%d" : ",%d"), values[i]); + ptr += strlen(ptr); + } + return hgic_proc_write_bytes(name, buff, strlen(buff)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +int hgic_iwpriv_open_dev(char *ifname) +{ + char cmd[32]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s open", ifname); + return hgic_iwpriv_do(cmd, NULL, 0, NULL, 0); +} +int hgic_iwpriv_close_dev(char *ifname) +{ + char cmd[32]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s close", ifname); + return hgic_iwpriv_do(cmd, NULL, 0, NULL, 0); +} +int hgic_iwpriv_set_ssid(char *ifname, char *ssid) +{ + return hgic_iwpriv_set_bytes(ifname, "ssid", ssid, strlen(ssid)); +} +int hgic_iwpriv_set_bssid(char *ifname, char *bssid) +{ + return hgic_iwpriv_set_mac(ifname, "bssid", bssid); +} +int hgic_iwpriv_set_channel(char *ifname, int channel) +{ + return hgic_iwpriv_set_int(ifname, "channel", channel); +} +int hgic_iwpriv_set_keymgmt(char *ifname, char *key_mgmt) +{ + return hgic_iwpriv_set_bytes(ifname, "key_mgmt", key_mgmt, strlen(key_mgmt)); +} +int hgic_iwpriv_set_wpapsk(char *ifname, char *wpa_psk) +{ + return hgic_iwpriv_set_bytes(ifname, "wpa_psk", wpa_psk, strlen(wpa_psk)); +} +int hgic_iwpriv_set_freqrange(char *ifname, int freq_start, int freq_end, int bw) +{ + return hgic_iwpriv_set_ints(ifname, "freq_range", 3, freq_start, freq_end, bw); +} +int hgic_iwpriv_set_bss_bw(char *ifname, int bss_bw) +{ + return hgic_iwpriv_set_int(ifname, "bss_bw", bss_bw); +} +int hgic_iwpriv_set_tx_bw(char *ifname, int tx_bw) +{ + return hgic_iwpriv_set_int(ifname, "tx_bw", tx_bw); +} +int hgic_iwpriv_set_tx_mcs(char *ifname, int tx_mcs) +{ + return hgic_iwpriv_set_int(ifname, "tx_mcs", tx_mcs); +} +int hgic_iwpriv_set_max_txcnt(char *ifname, int max_txcnt) +{ + return hgic_iwpriv_set_int(ifname, "max_txcnt", max_txcnt); +} +int hgic_iwpriv_set_acs(char *ifname, int start, int tmo) +{ + return hgic_iwpriv_set_ints(ifname, "acs", 2, start, tmo); +} +int hgic_iwpriv_set_chan_list(char *ifname, int *chan_list, int chan_count) +{ + return hgic_iwpriv_set_intarray(ifname, "chan_list", chan_list, chan_count); +} +int hgic_iwpriv_set_mode(char *ifname, char *mode) +{ + return hgic_iwpriv_set_bytes(ifname, "mode", mode, strlen(mode)); +} +int hgic_iwpriv_set_paired_stas(char *ifname, char *paired_stas) +{ + return hgic_iwpriv_set_bytes(ifname, "paired_stas", paired_stas, strlen(paired_stas)); +} +int hgic_iwpriv_set_pairing(char *ifname, int pair_number) +{ + return hgic_iwpriv_set_int(ifname, "pairing", pair_number); +} +int hgic_iwpriv_set_beacon_int(char *ifname, int beacon_int) +{ + return hgic_iwpriv_set_int(ifname, "beacon_int", beacon_int); +} +int hgic_iwpriv_set_radio_onoff(char *ifname, int off) +{ + return hgic_iwpriv_set_int(ifname, "radio_onoff", off); +} +int hgic_iwpriv_set_join_group(char *ifname, char *mcast_addr, int aid) +{ + char cmd[64]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s set join_group="MACSTR",%d", ifname, MACARG(mcast_addr), aid); + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} +int hgic_iwpriv_set_txpower(char *ifname, int txpower) +{ + return hgic_iwpriv_set_int(ifname, "txpower", txpower); +} +int hgic_iwpriv_set_ps_connect(char *ifname, int period, int roundup) +{ + return hgic_iwpriv_set_ints(ifname, "ps_connect", 2, period, roundup); +} +int hgic_iwpriv_set_bss_max_idle(char *ifname, int bss_max_idle) +{ + return hgic_iwpriv_set_int(ifname, "bss_max_idle", bss_max_idle); +} +int hgic_iwpriv_set_wkio_mode(char *ifname, int wkio_mode) +{ + return hgic_iwpriv_set_int(ifname, "wkio_mode", wkio_mode); +} +int hgic_iwpriv_set_dtim_period(char *ifname, int dtim_period) +{ + return hgic_iwpriv_set_int(ifname, "dtim_period", dtim_period); +} +int hgic_iwpriv_set_ps_mode(char *ifname, int ps_mode) +{ + return hgic_iwpriv_set_int(ifname, "ps_mode", ps_mode); +} +int hgic_iwpriv_set_aplost_time(char *ifname, int aplost_time) +{ + return hgic_iwpriv_set_int(ifname, "aplost_time", aplost_time); +} +int hgic_iwpriv_unpair(char *ifname, char *mac) +{ + return hgic_iwpriv_set_mac(ifname, "unpair", mac); +} +int hgic_iwpriv_scan(char *ifname) +{ + char cmd[32]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s scan", ifname); + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} +int hgic_iwpriv_save(char *ifname) +{ + char cmd[32]; + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s save", ifname); + return hgic_iwpriv_do(cmd, 0, 0, 0, 0); +} +int hgic_iwpriv_set_auto_chswitch(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "auto_chswitch", enable); +} +int hgic_iwpriv_set_mcast_key(char *ifname, char *mcast_key) +{ + return hgic_iwpriv_set_bytes(ifname, "mcast_key", mcast_key, strlen(mcast_key)); +} +int hgic_iwpriv_set_reassoc_wkhost(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "reassoc_wkhost", enable); +} +int hgic_iwpriv_set_wakeup_io(char *ifname, int wakeup_io) +{ + return hgic_iwpriv_set_int(ifname, "wakeup_io", wakeup_io); +} +int hgic_iwpriv_set_dbginfo(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "dbginfo", enable); +} +int hgic_iwpriv_set_sysdbg(char *ifname, char *sysdbg) +{ + return hgic_iwpriv_set_bytes(ifname, "sysdbg", sysdbg, strlen(sysdbg)); +} +int hgic_iwpriv_set_primary_chan(char *ifname, int primary_chan) +{ + return hgic_iwpriv_set_int(ifname, "primary_chan", primary_chan); +} +int hgic_iwpriv_set_autosleep_time(char *ifname, int autosleep_time) +{ + return hgic_iwpriv_set_int(ifname, "autosleep_time", autosleep_time); +} +int hgic_iwpriv_set_super_pwr(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "super_pwr", enable); +} +int hgic_iwpriv_set_repeater_ssid(char *ifname, char *r_ssid) +{ + return hgic_iwpriv_set_bytes(ifname, "r_ssid", r_ssid, strlen(r_ssid)); +} +int hgic_iwpriv_set_repeater_psk(char *ifname, char *r_psk) +{ + return hgic_iwpriv_set_bytes(ifname, "r_psk", r_psk, strlen(r_psk)); +} +int hgic_iwpriv_set_auto_save(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "auto_save", enable); +} +int hgic_iwpriv_set_pair_autostop(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "pair_autostop", enable); +} +int hgic_iwpriv_set_dcdc13(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "dcdc13", enable); +} +int hgic_iwpriv_set_acktmo(char *ifname, int acktmo) +{ + return hgic_iwpriv_set_int(ifname, "acktmo", acktmo); +} +int hgic_iwpriv_get_sta_list(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "sta_list=1", buff, size);//output binary structure +} +int hgic_iwpriv_get_scan_list(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "scan_list", buff, size); +} +int hgic_iwpriv_get_ssid(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "ssid", buff, size); +} +int hgic_iwpriv_get_bssid(char *ifname, char *mac) +{ + char buf[32]; + int tmp[7]; + if(hgic_iwpriv_get_bytes(ifname, "bssid", buf, sizeof(buf)) > 0){ + if (6 == sscanf(buf, MACSTR",%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5], &tmp[6])) { + mac[0] = (unsigned char)tmp[0]; + mac[1] = (unsigned char)tmp[1]; + mac[2] = (unsigned char)tmp[2]; + mac[3] = (unsigned char)tmp[3]; + mac[4] = (unsigned char)tmp[4]; + mac[5] = (unsigned char)tmp[5]; + return tmp[6]; + } + } + return -1; +} +int hgic_iwpriv_get_wpa_psk(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "wpa_psk", buff, size); +} +int hgic_iwpriv_get_txpower(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "txpower"); +} +int hgic_iwpriv_get_aggcnt(char *ifname, int *tx_agg, int *rx_agg) +{ + char buff[32]; + if(hgic_iwpriv_get_bytes(ifname, "agg_cnt", buff, 32) > 0){ + sscanf(buff, "tx:%d,rx:%d", tx_agg, rx_agg); + return 0; + } + return -1; +} +int hgic_iwpriv_set_aggcnt(char *ifname, int tx_agg, int rx_agg) +{ + return hgic_iwpriv_set_ints(ifname, "agg_cnt", 2, tx_agg, rx_agg); +} +int hgic_iwpriv_set_load_def(char *ifname, int reboot) +{ + return hgic_iwpriv_set_int(ifname, "loaddef", reboot); +} +int hgic_iwpriv_set_dbginfo_output(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "dbginfo", enable); +} +int hgic_iwpriv_set_unpair(char *ifname, char *sta_mac) +{ + return hgic_iwpriv_set_mac(ifname, "unpair", sta_mac); +} +int hgic_iwpriv_get_bss_bw(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "bss_bw"); +} +int hgic_iwpriv_get_chan_list(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "chan_list", buff, size); +} +int hgic_iwpriv_get_freq_range(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "freq_range", buff, size); +} +int hgic_iwpriv_get_txq_param(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "txq_param", buff, size); +} +int hgic_iwpriv_get_key_mgmt(char *ifname, char *buff, int size) +{ + return hgic_iwpriv_get_bytes(ifname, "key_mgmt", buff, size); +} +int hgic_iwpriv_get_battery_level(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "battery_level"); +} +int hgic_iwpriv_get_module_type(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "module_type"); +} +int hgic_iwpriv_set_pa_pwrctrl_dis(char *ifname, int disable) +{ + return hgic_iwpriv_set_int(ifname, "pa_pwrctl_dis", disable); +} +int hgic_iwpriv_set_dhcpc(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "dhcpc", enable); +} +int hgic_iwpriv_get_disassoc_reason(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "disassoc_reason"); +} +int hgic_iwpriv_set_wkdata_save(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "wkdata_save", enable); +} +int hgic_iwpriv_set_mcast_txparam(char *ifname, int dupcnt, int tx_bw, int tx_mcs, int clearch) +{ + return hgic_iwpriv_set_ints(ifname, "mcast_txparam", 4, dupcnt, tx_bw, tx_mcs, clearch); +} +int hgic_iwpriv_reset_sta(char *ifname, char *mac_addr) +{ + return hgic_iwpriv_set_mac(ifname, "reset_sta", mac_addr); +} +int hgic_iwpriv_ant_auto(char *ifname, int en) +{ + return hgic_iwpriv_set_int(ifname, "ant_auto", en); +} +int hgic_iwpriv_set_ant_sel(char *ifname, int ant) +{ + return hgic_iwpriv_set_int(ifname, "ant_sel", ant); +} +int hgic_iwpriv_get_ant_sel(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "ant_sel"); +} +int hgic_iwpriv_set_macfilter(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "macfilter", enable); +} +int hgic_iwpriv_send_atcmd(char *ifname, char *atcmd) +{ + return hgic_iwpriv_set_bytes(ifname, "atcmd", atcmd, strlen(atcmd)); +} +int hgic_iwpriv_set_roaming(char *ifname, int enable, int same_freq, int threshold, int rssi_diff, int rssi_interval) +{ + return hgic_iwpriv_set_ints(ifname, "roaming", 5, enable, same_freq, threshold, rssi_diff, rssi_interval); +} +int hgic_iwpriv_get_conn_state(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "conn_state"); +} + +int hgic_iwpriv_get_wkreason(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "wkreason"); +} + +int hgic_iwpriv_set_rts_threshold(char *ifname, int rts_threshold) +{ + return hgic_iwpriv_set_int(ifname, "rts_threshold", rts_threshold); +} + +int hgic_iwpriv_set_frag_threshold(char *ifname, int frag_threshold) +{ + return hgic_iwpriv_set_int(ifname, "frag_threshold", frag_threshold); +} + +int hgic_iwpriv_set_heartbeat(char *ifname, int ipaddr, int port, int period, int timeout) +{ + char str[64]; + struct in_addr in = { .s_addr = (in_addr_t)ipaddr }; + sprintf(str, "%s,%d,%d,%d", inet_ntoa(in), port, period, timeout); + return hgic_iwpriv_set_bytes(ifname, "heartbeat", str, strlen(str)); +} +int hgic_iwpriv_set_heartbeat_resp_data(char *ifname, char *resp_data, int len) +{ + return hgic_iwpriv_set_bytes(ifname, "heartbeat_resp", resp_data, len); +} +int hgic_iwpriv_set_wakeup_data(char *ifname, char *wakeup_data, int len) +{ + return hgic_iwpriv_set_bytes(ifname, "wakeup_data", wakeup_data, len); +} +int hgic_iwpriv_wakeup_sta(char *ifname, char *addr) +{ + return hgic_iwpriv_set_mac(ifname, "wakeup", addr); +} +int hgic_iwpriv_sleep(char *ifname, int sleep_type, unsigned int sleep_ms) +{ + return hgic_iwpriv_set_ints(ifname, "sleep", 2, sleep_type, sleep_ms); +} +int hgic_iwpriv_send_custmgmt(char *ifname, char *dest, struct hgic_tx_info *txinfo, char *data, int len) +{ /* "data" is just payload data, the firmware will build WiFi management frame. */ + int ret = -1; + char *buf = malloc(len+sizeof(struct hgic_tx_info)+6); + if(buf){ + memcpy(buf, dest, 6); + memcpy(buf+6, txinfo, sizeof(struct hgic_tx_info)); + memcpy(buf+6+sizeof(struct hgic_tx_info), data, len); + ret = hgic_iwpriv_set_bytes(ifname, "custmgmt", buf, len+6+sizeof(struct hgic_tx_info)); + free(buf); + } + return ret; +} +int hgic_iwpriv_send_mgmtframe(char *ifname, struct hgic_tx_info *txinfo, char *mgmt, int len) +{ /* "mgmt" should be a whole WiFi management frame. */ + int ret = -1; + char *buf = malloc(len + sizeof(struct hgic_tx_info)); + if(buf){ + memcpy(buf, txinfo, sizeof(struct hgic_tx_info)); + memcpy(buf + sizeof(struct hgic_tx_info), mgmt, len); + ret = hgic_iwpriv_set_bytes(ifname, "mgmtframe", buf, len + sizeof(struct hgic_tx_info)); + free(buf); + } + return ret; +} +int hgic_iwpriv_read_wkdata_buff(char *ifname, char *buff, int len) +{ + return hgic_iwpriv_get_bytes(ifname, "wkdata_buff", buff, len); +} +int hgic_proc_set_wkdata_mask(char *ifname, unsigned short offset, char *mask, int mask_len) +{ + char buff[128]; + if(mask_len > 16) mask_len = 16; + memcpy(buff, &offset, 2); + memcpy(buff+2, mask, mask_len); + return hgic_iwpriv_set_bytes(ifname, "wkdata_mask", buff, mask_len + 2); +} +int hgic_iwpriv_set_cust_driverdata(char *ifname, char *buff, int len) +{ + if(len > 1500){ + printf("data len:%d too big\r\n", len); + return -1; + } + return hgic_iwpriv_set_bytes(ifname, "driverdata", buff, len); +} +int hgic_iwpriv_set_stafreqinfo(char *ifname, char *sta_addr, struct hgic_freqinfo *freqinfo) +{ + int ret = -1; + char *buff = malloc(6+sizeof(struct hgic_freqinfo)); + if(buff){ + memset(buff, 0, 6+sizeof(struct hgic_freqinfo)); + if(sta_addr) memcpy(buff, sta_addr, 6); + memcpy(buff+6, freqinfo, sizeof(struct hgic_freqinfo)); + ret = hgic_iwpriv_set_bytes(ifname, "freqinfo", buff, 6+sizeof(struct hgic_freqinfo)); + free(buff); + } + return ret; +} +int hgic_iwpriv_blenc_start(char *ifname, int start, int channel) +{ + char str[8]; + sprintf(str, "EN:%d,%d", start, channel); + return hgic_iwpriv_set_bytes(ifname, "blenc", str, strlen(str)); +} +int hgic_iwpriv_send_blenc_data(char *ifname, char *data, int len) +{ + int ret = -1; + char *buff = malloc(5 + len); + if (buff) { + strcpy(buff, "DATA:"); + memcpy(buff + 5, data, len); + ret = hgic_iwpriv_set_bytes(ifname, "blenc", buff, 5 + len); + free(buff); + } + return ret; +} +int hgic_iwpriv_blenc_send_hcidata(char *ifname, int type, char *data, int len) +{ + int ret = -1; + char *buff = malloc(10 + len); + if (buff) { + strcpy(buff, "HCI_DATA:"); + buff[9] = (unsigned char)type; + memcpy(buff + 10, data, len); + ret = hgic_iwpriv_set_bytes(ifname, "blenc", buff, 10 + len); + free(buff); + } + return ret; +} + +int hgic_iwpriv_blenc_set_advdata(char *ifname, char *adv_data, int len) +{ + if(blenc_mode == 3){ + int ret = -ENOMEM; + int cmd_len = 3 + len; + char *cmd = malloc(cmd_len); + if(cmd){ + put_unaligned_le16(HCI_OPCODE(0x08, 0x08), cmd); + cmd[2] = len; + memcpy(cmd + 3, adv_data, len); + ret = hgic_iwpriv_blenc_send_hcidata(ifname, 0x01, cmd, cmd_len); + free(cmd); + } + return ret; + }else{ + int ret = -1; + char *buff = malloc(9 + len); + if (buff) { + strcpy(buff, "ADV_DATA:"); + memcpy(buff + 9, adv_data, len); + ret = hgic_iwpriv_set_bytes(ifname, "blenc", buff, 9 + len); + free(buff); + } + return ret; + } +} + +int hgic_iwpriv_blenc_set_scanresp(char *ifname, char *scan_resp, int len) +{ + if(blenc_mode == 3){ + int ret = -ENOMEM; + int cmd_len = 3 + len; + char *cmd = malloc(cmd_len); + if(cmd){ + put_unaligned_le16(HCI_OPCODE(0x08, 0x09), cmd); + cmd[2] = len; + memcpy(cmd + 3, scan_resp, len); + ret = hgic_iwpriv_blenc_send_hcidata(ifname, 0x01, cmd, cmd_len); + free(cmd); + } + return ret; + }else{ + int ret = -1; + char *buff = malloc(10 + len); + if (buff) { + strcpy(buff, "SCAN_RESP:"); + memcpy(buff + 10, scan_resp, len); + ret = hgic_iwpriv_set_bytes(ifname, "blenc", buff, 10 + len); + free(buff); + } + return ret; + } +} + +int hgic_iwpriv_blenc_set_devaddr(char *ifname, char *addr) +{ + if(blenc_mode == 3){ + int ret = -ENOMEM; + int cmd_len = 3 + 6; + char *cmd = malloc(cmd_len); + if(cmd){ + put_unaligned_le16(HCI_OPCODE(0x08, 0x05), cmd); + cmd[2] = 6; + memcpy(cmd + 3, addr, 6); + ret = hgic_iwpriv_blenc_send_hcidata(ifname, 0x01, cmd, cmd_len); + free(cmd); + } + return ret; + }else{ + char str[16]; + strcpy(str, "DEV_ADDR:"); + memcpy(str + 9, addr, 6); + return hgic_iwpriv_set_bytes(ifname, "blenc", str, 15); + } +} + +int hgic_iwpriv_blenc_set_adv_interval(char *ifname, int interval) +{ + if(blenc_mode == 3){ + return 0; + }else{ + char str[16]; + sprintf(str, "ADV_INT:%d", interval); + return hgic_iwpriv_set_bytes(ifname, "blenc", str, strlen(str)); + } +} + +int hgic_iwpriv_blenc_set_adv_filter(char *ifname, int filter) +{ + if(blenc_mode == 3){ + return 0; + }else{ + char str[16]; + sprintf(str, "ADV_FILTER:%d", filter); + return hgic_iwpriv_set_bytes(ifname, "blenc", str, strlen(str)); + } +} + +int hgic_iwpriv_blenc_start_adv(char *ifname, int start) +{ + if(blenc_mode == 3){ + int ret = -ENOMEM; + int cmd_len = 3 + 1; + char *cmd = malloc(cmd_len); + if(cmd){ + put_unaligned_le16(HCI_OPCODE(0x08, 0x0A), cmd); + cmd[2] = 1; + cmd[3] = start; + ret = hgic_iwpriv_blenc_send_hcidata(ifname, 0x01, cmd, cmd_len); + free(cmd); + } + return ret; + }else{ + char str[16]; + sprintf(str, "ADV_EN:%d", start); + return hgic_iwpriv_set_bytes(ifname, "blenc", str, strlen(str)); + + } +} + +int hgic_iwpriv_blenc_send_gatt_data(char *ifname, char *att_data, int len) +{ + int ret = -ENOMEM; + char *data = malloc(8 + len); + if(data){ + hgics_dump_hex("SEND:\r\n", att_data, len, 1); + // 0 - Connection handle : PB=pb : BC=00 + put_unaligned_le16(0x1, data); + // 2 - ACL length + put_unaligned_le16(len + 4u, data+2); + // 4 - L2CAP packet length + put_unaligned_le16(len + 0u, data+4); + // 6 - L2CAP CID + put_unaligned_le16(0x04, data+6); + memcpy(data+8, att_data, len); + ret = hgic_iwpriv_blenc_send_hcidata(ifname, 0x02, data, 8 + len); + free(data); + } + return ret; +} + +int hgic_iwpriv_set_hwscan(char *ifname, int period, int chan_tmo, int chan_bitmap, int max_cnt) +{ + return hgic_iwpriv_set_ints(ifname, "hwscan", 4, period, chan_tmo, chan_bitmap, max_cnt); +} +int hgic_proc_ota(char *fw_file) +{ + return hgic_proc_write_bytes("ota", fw_file, strlen(fw_file)); +} +int hgic_iwpriv_set_user_edca(char *ifname, int ac, struct hgic_txq_param *txq) +{ + char buf[32]; + buf[0] = ac; + memcpy(buf+1, txq, sizeof(struct hgic_txq_param)); + return hgic_iwpriv_set_bytes(ifname, "user_edca", buf, 1+sizeof(struct hgic_txq_param)); +} +int hgic_iwpriv_set_fix_txrate(char *ifname, unsigned int txrate) +{ + return hgic_iwpriv_set_int(ifname, "fix_txrate", txrate); +} +int hgic_iwpriv_set_nav_max(char *ifname, unsigned int nav_max) +{ + return hgic_iwpriv_set_int(ifname, "nav_max", nav_max); +} +int hgic_iwpriv_clear_nav(char *ifname) +{ + return hgic_iwpriv_set_int(ifname, "clr_nav", 0); +} +int hgic_iwpriv_set_cca_param(char *ifname, struct hgic_cca_ctl *cca) +{ + return hgic_iwpriv_set_bytes(ifname, "cca_param", (char *)cca, sizeof(struct hgic_cca_ctl)); +} +int hgic_iwpriv_set_tx_modulation_gain(char *ifname, char *gain_table, int size) +{ + return hgic_iwpriv_set_bytes(ifname, "tx_modgain", gain_table, size); +} + +int hgic_iwpriv_get_nav(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "nav"); +} + +int hgic_iwpriv_get_bgrssi(char *ifname, int channel, int bgrssi[3]) +{ + int ret = 0; + char cmd[32]; + + memset(cmd, 0, sizeof(cmd)); + sprintf(cmd, "%s get bgrssi=%d", ifname, channel); + hgic_iwpriv_do(cmd, 0, 0, cmd, sizeof(cmd)); + if(3 == sscanf(cmd, "%d,%d,%d", bgrssi, bgrssi+1, bgrssi+2)){ + return 0; + } + return -1; +} + +int hgic_iwpriv_reset(char *ifname) +{ + return hgic_iwpriv_set_int(ifname, "reset", 0); +} + +int hgic_iwpriv_set_rts_duration(char *ifname, unsigned int duration_us) +{ + return hgic_iwpriv_set_int(ifname, "rts_duration", duration_us); +} + +int hgic_iwpriv_set_disable_print(char *ifname, int disable) +{ + return hgic_iwpriv_set_int(ifname, "disable_print", disable); +} + +int hgic_iwpriv_set_conn_paironly(char *ifname, int en) +{ + return hgic_iwpriv_set_int(ifname, "conn_paironly", en); +} + +int hgic_iwpriv_get_center_freq(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "center_freq"); +} + +int hgic_iwpriv_set_wait_psmode(char *ifname, int mode) +{ + return hgic_iwpriv_set_int(ifname, "wait_psmode", mode); +} + +int hgic_iwpriv_set_diffcust_conn(char *ifname, int en) +{ + return hgic_iwpriv_set_int(ifname, "diffcust_conn", en); +} + +int hgic_iwpriv_set_standby(char *ifname, int channel, int sleep_period) +{ + return hgic_iwpriv_set_ints(ifname, "standby", 2, channel, sleep_period); +} + +int hgic_iwpriv_set_ap_chan_switch(char *ifname, int channel, int counter) +{ + return hgic_iwpriv_set_ints(ifname, "ap_chansw", 2, channel, counter); +} + +int hgic_iwpriv_set_cca_for_ce(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "cca_ce", enable); +} + +int hgic_iwpriv_set_rtc(char *ifname, int rtc) +{ + return hgic_iwpriv_set_int(ifname, "rtc", rtc); +} + +int hgic_iwpriv_get_rtc(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "rtc"); +} + +int hgic_iwpriv_set_apep_padding(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "apep_padding", enable); +} + +int hgic_iwpriv_set_freqinfo(char *ifname, char *sta_addr, struct hgic_freqinfo *freqinfo) +{ + int ret = -1; + char *data = malloc(6 + sizeof(struct hgic_freqinfo)); + if(data){ + memcpy(data, sta_addr, 6); + memcpy(data+6, freqinfo, sizeof(struct hgic_freqinfo)); + ret = hgic_iwpriv_set_bytes(ifname, "freqinfo", data, 6 + sizeof(struct hgic_freqinfo)); + free(data); + } + return ret; +} + +int hgic_iwpriv_get_acs_result(char *ifname, char *buff, int len) +{ + return hgic_iwpriv_get_bytes(ifname, "acs_result", buff, len); +} + +int hgic_iwpriv_get_reason_code(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "reason_code"); +} + +int hgic_iwpriv_get_status_code(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "status_code"); +} + +int hgic_iwpriv_set_watchdog(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "watchdog", enable); +} + +int hgic_iwpriv_set_retry_fallback_cnt(char *ifname, int count) +{ + return hgic_iwpriv_set_int(ifname, "retry_fallback_cnt", count); +} + +int hgic_iwpriv_set_fallback_mcs(char *ifname, int original_type, int original_mcs, int fallback_type, int fallback_mcs) +{ + return hgic_iwpriv_set_ints(ifname, "fallback_mcs", 4, original_type, original_mcs, fallback_type, fallback_mcs); +} + +int hgic_iwpriv_get_xosc(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "xosc"); +} + +int hgic_iwpriv_get_freq_offset(char *ifname, char *mac_addr) +{ + char cmd[128]; + memset(cmd, 0, sizeof(cmd)); + + if(mac_addr){ + if (strlen(mac_addr) == 17 && mac_addr[2] == ':' && mac_addr[5] == ':' && mac_addr[8] == ':' && mac_addr[11] == ':' && mac_addr[14] == ':') { + sprintf(cmd, "%s get freq_offset=%s", ifname, mac_addr); + } else { + sprintf(cmd, "%s get freq_offset="MACSTR, ifname, MACARG(mac_addr)); + } + }else{ + sprintf(cmd, "%s get freq_offset=00:00:00:00:00:00", ifname); + } + hgic_iwpriv_do(cmd, 0, 0, cmd, sizeof(cmd)); + return atoi(cmd); +} + +int hgic_iwpriv_set_xosc(char *ifname, int xosc) +{ + return hgic_iwpriv_set_int(ifname, "xosc", xosc); +} + +int hgic_iwpriv_set_freq_cali_period(char *ifname, int period) +{ + return hgic_iwpriv_set_int(ifname, "freq_cali_period", period); +} + +int hgic_iwpriv_set_customer_dvrdata(char *ifname, unsigned short cmd_id, char *data, int len) +{ + int ret = 0; + char *buff = malloc(2+len); + if(buff){ + put_unaligned_le16(cmd_id, buff); + memcpy(buff+2, data, len); + ret = hgic_iwpriv_set_bytes(ifname, "cust_drvdata", buff, 2+len); + free(buff); + return ret; + } + return -ENOMEM; +} + +int hgic_iwpriv_get_fwinfo(char *ifname, struct hgic_fw_info *fwifno) +{ + return hgic_iwpriv_get_bytes(ifname, "fwinfo", fwifno, sizeof(struct hgic_fw_info)); +} + +int hgic_iwpriv_set_disassoc_sta(char *ifname, char *sta_mac) +{ + return hgic_iwpriv_set_mac(ifname, "disassoc_sta", sta_mac); +} + +int hgic_iwpriv_set_pa_pwrctl_dis(char *ifname, int disable) +{ + return hgic_iwpriv_set_int(ifname, "pa_pwrctl_dis", disable); +} + +int hgic_iwpriv_set_ant_auto(char *ifname, int eanble) +{ + return hgic_iwpriv_set_int(ifname, "ant_auto", eanble); +} + +int hgic_iwpriv_set_select_ant(char *ifname, int ant) +{ + return hgic_iwpriv_set_int(ifname, "ant_sel", ant); +} + +int hgic_iwpriv_set_wkhost_reasons(char *ifname, int* reasons_array, int array_count) +{ + return hgic_iwpriv_set_intarray(ifname, "wkhost_reason", reasons_array, array_count); +} +int hgic_iwpriv_set_atcmd(char *ifname, char* atcmd) +{ + return hgic_iwpriv_set_bytes(ifname, "atcmd", atcmd, strlen(atcmd)); +} +int hgic_iwpriv_set_ap_hide(char *ifname, int hide) +{ + return hgic_iwpriv_set_int(ifname, "ap_hide", hide); +} +int hgic_iwpriv_set_assert_holdup(char *ifname, int hold) +{ + return hgic_iwpriv_set_int(ifname, "assert_holdup", hold); +} +int hgic_iwpriv_set_ap_psmode(char *ifname, int ap_psmode) +{ + return hgic_iwpriv_set_int(ifname, "ap_psmode", ap_psmode); +} +int hgic_iwpriv_set_dupfilter_en(char *ifname, int enable) +{ + return hgic_iwpriv_set_int(ifname, "dupfilter", enable); +} +int hgic_iwpriv_set_dis_1v1m2u(char *ifname, int disable) +{ + return hgic_iwpriv_set_int(ifname, "dis_1v1m2u", disable); +} +int hgic_iwpriv_set_dis_psconnect(char *ifname, int disable) +{ + return hgic_iwpriv_set_int(ifname, "dis_psconnect", disable); +} +int hgic_iwpriv_set_wkdata_mask(char *ifname, int offset/*from IP hdr*/, char *mask, int mask_len) +{ + char buff[64]; + if(mask_len > 32) mask_len = 32; + buff[0] = offset; + memcpy(buff + 1, mask, mask_len); + return hgic_iwpriv_set_bytes(ifname, "wkdata_mask", buff, mask_len + 1); +} +int hgic_iwpriv_get_mode(char *ifname, char *mode) +{ + return hgic_iwpriv_get_bytes(ifname, "mode", mode, 8); +} +int hgic_iwpriv_get_wkdata_buff(char *ifname, char *buff, int buff_size) +{ + return hgic_iwpriv_get_bytes(ifname, "wkdata_buff", buff, buff_size); +} +int hgic_iwpriv_get_temperature(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "temperature"); +} +int hgic_iwpriv_get_sta_count(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "sta_count"); +} +int hgic_iwpriv_get_dhcpc_result(char *ifname, struct hgic_dhcp_result *result) +{ + return hgic_iwpriv_get_bytes(ifname, "dhcpc_result", result, sizeof(struct hgic_dhcp_result)); +} + +int hgic_iwpriv_set_max_tx_delay(char *ifname, int tmo) +{ + return hgic_iwpriv_set_int(ifname, "max_txdelay", tmo); +} + +int hgic_iwpriv_set_heartbeat_int(char *ifname, int interval_ms) +{ + return hgic_iwpriv_set_int(ifname, "heartbeat_int", interval_ms); +} + +int hgic_iwpriv_get_sta_info(char *ifname, char *mac_addr, struct hgic_sta_info *stainfo) +{ + char cmd[128]; + memset(cmd, 0, sizeof(cmd)); + + if(mac_addr == NULL || stainfo == NULL){ + printf("get sta_info: invalid mac address\r\n"); + return -1; + } + + if (strlen(mac_addr) == 17 && mac_addr[2] == ':' && mac_addr[5] == ':' && mac_addr[8] == ':' && mac_addr[11] == ':' && mac_addr[14] == ':') { + sprintf(cmd, "%s get stainfo=%s,1", ifname, mac_addr); + } else { + sprintf(cmd, "%s get stainfo="MACSTR",1", ifname, MACARG(mac_addr)); + } + return hgic_iwpriv_do(cmd, 0, 0, stainfo, sizeof(struct hgic_sta_info)); +} + +int hgic_iwpriv_get_signal(char *ifname) +{ + return hgic_iwpriv_get_int(ifname, "signal"); +} + diff --git a/tools/test_app/libnetat.c b/tools/test_app/libnetat.c new file mode 100644 index 0000000..2e792e9 --- /dev/null +++ b/tools/test_app/libnetat.c @@ -0,0 +1,254 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MAC2STR(a) (a)[0]&0xff, (a)[1]&0xff, (a)[2]&0xff, (a)[3]&0xff, (a)[4]&0xff, (a)[5]&0xff +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" + +#define NETAT_BUFF_SIZE (1024) +#define NETAT_PORT (56789) + +enum WNB_NETAT_CMD { + WNB_NETAT_CMD_SCAN_REQ = 1, + WNB_NETAT_CMD_SCAN_RESP, + WNB_NETAT_CMD_AT_REQ, + WNB_NETAT_CMD_AT_RESP, +}; + +struct wnb_netat_cmd { + char cmd; + char len[2]; + char dest[6]; + char src[6]; + char data[0]; +}; + +struct netat_mgr { + int sock; + char dest[6]; + char cookie[6]; + char recvbuf[NETAT_BUFF_SIZE]; +} libnetat; + +static void random_bytes(char *buff, int len) +{ + int i = 0; + srand(time(NULL)); + for (i = 0; i < len; i++) { + buff[i] = (char)(rand() & 0xff); + } +} + +static int sock_send(int sock, char *data, int len) +{ + int addr_len = sizeof(struct sockaddr_in); + struct sockaddr_in dest; + + memset(&dest, 0, sizeof(struct sockaddr_in)); + dest.sin_family = AF_INET; + dest.sin_addr.s_addr = INADDR_BROADCAST; + dest.sin_port = htons(NETAT_PORT); + return sendto(sock, data, len, 0, (struct sockaddr *)&dest, addr_len); +} + +static int sock_recv(int sock, struct sockaddr_in *dest, char *data, int len, int tmo) +{ + int ret = 0; + fd_set rfd; + struct timeval timeout; + int addr_len = sizeof(struct sockaddr_in); + + FD_ZERO(&rfd); + FD_SET(sock, &rfd); + timeout.tv_sec = 0; + timeout.tv_usec = tmo * 1000; + + ret = select(sock + 1, &rfd, NULL, NULL, &timeout); + if (ret > 0 && FD_ISSET(sock, &rfd)) { + ret = recvfrom(sock, data, len, 0, (struct sockaddr *)dest, &addr_len); + } + + //printf("sock_recv, len=%d\r\n", ret); + return ret; +} + +static void netat_scan(void) +{ + struct wnb_netat_cmd scan; + + random_bytes(libnetat.cookie, 6); + memset(&scan, 0, sizeof(scan)); + scan.cmd = WNB_NETAT_CMD_SCAN_REQ; + memset(scan.dest, 0xff, 6); + memcpy(scan.src, libnetat.cookie, 6); + sock_send(libnetat.sock, (char *)&scan, sizeof(scan)); +} + +static void netat_send(char *atcmd) +{ + unsigned short len = strlen(atcmd); + struct wnb_netat_cmd *cmd = (struct wnb_netat_cmd *)malloc(strlen(atcmd) + sizeof(struct wnb_netat_cmd)); + + if (cmd) { + random_bytes(libnetat.cookie, 6); + len = htons(len); + memset(cmd, 0, sizeof(struct wnb_netat_cmd)); + cmd->cmd = WNB_NETAT_CMD_AT_REQ; + memcpy(cmd->len, &len, 2); + memcpy(cmd->dest, libnetat.dest, 6); + memcpy(cmd->src, libnetat.cookie, 6); + memcpy(cmd->data, atcmd, strlen(atcmd)); + sock_send(libnetat.sock, (char *)cmd, strlen(atcmd) + sizeof(struct wnb_netat_cmd)); + free(cmd); + //printf("send atcmd: %s\r\n", atcmd); + } +} + +static int netat_recv(char *buff, int len, int tmo) +{ + int ret; + int off = 0; + struct sockaddr_in from; + struct wnb_netat_cmd *cmd; + + do { + memset(libnetat.recvbuf, 0, NETAT_BUFF_SIZE); + ret = sock_recv(libnetat.sock, &from, libnetat.recvbuf, NETAT_BUFF_SIZE, tmo); + if (ret >= sizeof(struct wnb_netat_cmd)) { + cmd = (struct wnb_netat_cmd *)libnetat.recvbuf; + //printf("recv type=%d\r\n", cmd->cmd); + if (memcmp(cmd->dest, libnetat.cookie, 6) == 0) { + switch (cmd->cmd) { + case WNB_NETAT_CMD_SCAN_RESP: + memcpy(libnetat.dest, cmd->src, 6); + break; + case WNB_NETAT_CMD_AT_RESP: + if (buff) { + strncpy(buff + off, cmd->data, ret - sizeof(struct wnb_netat_cmd)); + off += (ret - sizeof(struct wnb_netat_cmd)); + } else { + printf("%s\r\n", cmd->data); + } + break; + default: + break; + } + } + } + } while (ret > 0); + if (buff) { buff[off] = 0; } +} + +int libnetat_init(char *ifname) +{ + int on = 1; + struct sockaddr_in local_addr; + struct ifreq req; + + memset(libnetat.dest, 0xff, 6); + libnetat.sock = socket(AF_INET, SOCK_DGRAM, 0); + if (libnetat.sock < 0) { + printf("create udp socket error:[%d:%s]\n", errno, strerror(errno)); + return -1; + } + + memset(&local_addr, 0, sizeof(struct sockaddr_in)); + local_addr.sin_family = AF_INET; + local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + local_addr.sin_port = htons(NETAT_PORT); + + if (setsockopt(libnetat.sock, SOL_SOCKET, SO_BROADCAST, (const char *)&on, sizeof(on)) < 0) { + close(libnetat.sock); + libnetat.sock = 0; + return -1; + } + + strcpy(req.ifr_name, ifname); + if (setsockopt(libnetat.sock, SOL_SOCKET, SO_BINDTODEVICE, (const char *)&req, sizeof(req)) < 0) { + close(libnetat.sock); + libnetat.sock = 0; + return -1; + } + + if (bind(libnetat.sock, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in)) < 0) { + printf("udp bind error:[%d:%s]\n", errno, strerror(errno)); + close(libnetat.sock); + return -1; + } + + netat_scan(); + netat_recv(NULL, 0, 1); + return 0; +} + +int libnetat_send(char *atcmd, char *resp_buff, int buf_size) +{ + if (libnetat.sock == 0) { + printf("libnetat is not inited!\r\n"); + return -1; + } + + if (libnetat.dest[0] & 0x1) { + netat_scan(); + netat_recv(NULL, 0, 100); + } + + if (libnetat.dest[0] & 0x1) { + printf("not detect device!\r\r"); + return -1; + } + + netat_send(atcmd); + return netat_recv(resp_buff, buf_size, 10); +} + +#if 1 //sample code +int main(int argc, char *argv[]) +{ + char *ifname = NULL; + char input[256]; + char response[1024]; + + if (argc == 2) { + ifname = argv[1]; + } else { + printf("please input interface name!\n"); + return -1; + } + + if (libnetat_init(ifname)) { + printf("libnetat init fail, inteface:%s\r\n", ifname); + return -1; + } + + while (1) { + memset(input, 0, sizeof(input)); + printf("\r\n>:"); + fflush(stdin); + fgets(input, sizeof(input), stdin); + if (strlen(input) > 0) { + if (strncmp(input, "at", 2) == 0 || strncmp(input, "AT", 2) == 0) { + libnetat_send(input, response, sizeof(response)); + printf("%s", response); + } + } + } +} +#endif diff --git a/hgota/libota.c b/tools/test_app/libota.c similarity index 100% rename from hgota/libota.c rename to tools/test_app/libota.c diff --git a/hgota/libota.h b/tools/test_app/libota.h similarity index 100% rename from hgota/libota.h rename to tools/test_app/libota.h diff --git a/utils/Kconfig b/utils/Kconfig new file mode 100644 index 0000000..12f9b7e --- /dev/null +++ b/utils/Kconfig @@ -0,0 +1,11 @@ +config HGIC_USB + bool " Support USB interface" + depends on USB && (HGICS||HGICF) + +config HGIC_SDIO + bool " Support SDIO interface" + depends on MMC && (HGICS||HGICF) + +config SDIO_REINIT + bool " Support Re-init SDIO interface" + depends on HGIC_SDIO diff --git a/utils/Makefile b/utils/Makefile deleted file mode 100644 index 2e0568d..0000000 --- a/utils/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-m += hgic_usb.o -obj-m += hgic_sdio.o - -hgic_usb-objs += if_usb.o -hgic_sdio-objs += if_sdio.o diff --git a/utils/bluetooth.c b/utils/bluetooth.c new file mode 100644 index 0000000..67d988e --- /dev/null +++ b/utils/bluetooth.c @@ -0,0 +1,107 @@ + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_BT +#include +#include + +#include "../hgic_def.h" +#include "fwdl.h" +#include "fwctrl.h" +#include "utils.h" + +static int hgic_hcidev_open(struct hci_dev *hdev) +{ + struct hgic_fwctrl *ctrl = hci_get_drvdata(hdev); + + if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) { + return 0; + } + + hgic_fwctrl_ble_open(ctrl, 1, 1); + return 0; +} + +static int hgic_hcidev_flush(struct hci_dev *hdev) +{ + return 0; +} + +static int hgic_hcidev_close(struct hci_dev *hdev) +{ + struct hgic_fwctrl *ctrl = hci_get_drvdata(hdev); + + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) { + return 0; + } + + hgic_fwctrl_ble_open(ctrl, 1, 0); + return 0; +} + +static int hgic_hcidev_send_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + struct hgic_fwctrl *ctrl; + + hgic_dbg("send bt data, type:%d len %d", bt_cb(skb)->pkt_type, skb->len); + + if (!hdev) { + hgic_err("skb->dev is NULLs\r\n"); + return -ENODEV; + } + + if (!test_bit(HCI_RUNNING, &hdev->flags)) { + hgic_err("bt device is not running\r\n"); + return -EBUSY; + } + + switch (bt_cb(skb)->pkt_type) { + case HCI_COMMAND_PKT: + hdev->stat.cmd_tx++; + break; + case HCI_ACLDATA_PKT: + hdev->stat.acl_tx++; + break; + case HCI_SCODATA_PKT: + hdev->stat.sco_tx++; + break; + }; + + ctrl = hci_get_drvdata(hdev); + hgic_fwctrl_send_hci_data(ctrl, bt_cb(skb)->pkt_type, skb->data, skb->len); + kfree_skb(skb); + return 0; +} + +static int hgic_hcidev_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + +int hgic_hcidev_init(struct hgic_fwctrl *ctrl, struct hci_dev *hci) +{ + int ret = -1; + if (hci) { + hci->bus = (ctrl->bus->type == HGIC_BUS_USB) ? HCI_USB : + (ctrl->bus->type == HGIC_BUS_SDIO ? HCI_SDIO : 0); + hci_set_drvdata(hci, ctrl); + SET_HCIDEV_DEV(hci, ctrl->dev); + hci->open = hgic_hcidev_open; + hci->close = hgic_hcidev_close; + hci->flush = hgic_hcidev_flush; + hci->send = hgic_hcidev_send_frame; + hci->ioctl = hgic_hcidev_ioctl; + ret = hci_register_dev(hci); + } + return ret; +} + +#endif diff --git a/utils/fwctrl.c b/utils/fwctrl.c index 93a3893..c1efd3e 100644 --- a/utils/fwctrl.c +++ b/utils/fwctrl.c @@ -19,33 +19,8 @@ #include "fwctrl.h" #include "utils.h" -#define ARG_DUP(arg,len) if(ctrl->param.arg != (void *)arg){ \ - if(ctrl->param.arg) kfree(ctrl->param.arg); \ - ctrl->param.arg = hgic_strdup(arg,len);\ - } - -#define ARG_FREE(arg) do{\ - if(ctrl->param.arg) kfree(ctrl->param.arg);\ - ctrl->param.arg = NULL;\ - } while (0) - #define STR_LEN(s) ((s)?strlen(s):0) -static void *hgic_strdup(void *arg, u32 len) -{ - int s = 0; - u8 *ptr = NULL; - if (arg) { - s = (len > 0) ? (len) : (strlen((char *)arg) + 1); - ptr = kzalloc(s, GFP_KERNEL); - if (ptr) { - if (len > 0) { memcpy(ptr, arg, len); } - else { strcpy(ptr, (char *)arg); } - } - } - return ptr; -} - u16 hgic_ctrl_cookie(struct hgic_fwctrl *ctrl) { unsigned long flags; @@ -58,189 +33,109 @@ u16 hgic_ctrl_cookie(struct hgic_fwctrl *ctrl) return cookie; } -static struct sk_buff *hgic_alloc_ctrl_skb(u32 size) +static struct sk_buff *hgic_alloc_ctrl_skb(struct hgic_fwctrl *ctrl, u32 size) { - struct sk_buff *skb = dev_alloc_skb(sizeof(struct hgic_ctrl_hdr) + size + 4); + struct sk_buff *skb = dev_alloc_skb(ctrl->bus->drv_tx_headroom + sizeof(struct hgic_ctrl_hdr) + size + 4); if (!skb) { return skb; } + skb_reserve(skb, ctrl->bus->drv_tx_headroom); memset(skb->data, 0, sizeof(struct hgic_ctrl_hdr) + size); skb_reserve(skb, sizeof(struct hgic_ctrl_hdr)); skb_put(skb, size); return skb; } -static struct sk_buff *hgic_fwctrl_send_cmd(struct hgic_fwctrl *ctrl, u32 cmd_id, struct sk_buff *skb, bool sync) +static struct sk_buff *hgic_fwctrl_send_cmd(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, struct sk_buff *skb, bool sync) { struct hgic_ctrl_hdr *hdr = NULL; struct hgic_cmd_response resp; u16 id = cmd_id - HGIC_CMD_START; - hdr = (struct hgic_ctrl_hdr *)skb_push(skb, sizeof(struct hgic_ctrl_hdr)); - hdr->hdr.magic = HGIC_HDR_TX_MAGIC; - hdr->hdr.length = skb->len; - hdr->hdr.ifidx = 1; - hdr->hdr.cookie = hgic_ctrl_cookie(ctrl); - if (id > 255) { - hdr->hdr.type = HGIC_HDR_TYPE_CMD2; - hdr->cmd2.cmd_id = id; - hdr->cmd2.status = 0; - } else { - hdr->hdr.type = HGIC_HDR_TYPE_CMD; - hdr->cmd.cmd_id = id; - hdr->cmd.status = 0; - } memset(&resp, 0, sizeof(resp)); - resp.cookie = hdr->hdr.cookie; + resp.cookie = hgic_ctrl_cookie(ctrl); + hdr = (struct hgic_ctrl_hdr *)skb_push(skb, sizeof(struct hgic_ctrl_hdr)); + memset(hdr->info, 0, sizeof(hdr->info)); + hdr->hdr.magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + hdr->hdr.length = cpu_to_le16(skb->len); + hdr->hdr.cookie = cpu_to_le16(resp.cookie); + hdr->hdr.ifidx = ifidx; + HDR_CMDID_SET(hdr, id); return hgic_fwctrl_send_data(ctrl, skb, &resp, HGIC_CMD_TIMEOUT); } -static int hgic_fwctrl_set_byte(struct hgic_fwctrl *ctrl, u32 cmd_id, u8 val) +int hgic_fwctrl_do_cmd(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 *in, u32 in_len, u8 *out, u32 out_size) { int ret = -1; struct sk_buff *skb = NULL; struct sk_buff *resp = NULL; struct hgic_ctrl_hdr *hdr = NULL; - skb = hgic_alloc_ctrl_skb(1); + if(in_len > 2000){ + hgic_err("data len is too long\r\n"); + return -EINVAL; + } + + skb = hgic_alloc_ctrl_skb(ctrl, in_len); if (skb) { - skb->data[0] = val; - resp = hgic_fwctrl_send_cmd(ctrl, cmd_id, skb, true); + if (in && in_len > 0) { + memcpy(skb->data, in, in_len); + skb->data[in_len] = 0; + } + + resp = hgic_fwctrl_send_cmd(ctrl, ifidx, cmd_id, skb, true); if (resp) { hdr = (struct hgic_ctrl_hdr *)resp->data; - ret = hdr->cmd.status; - dev_kfree_skb_any(resp); - } - } - if (ret) { - hgic_dbg("cmd:%d, ret:%d (%s)\r\n", cmd_id, ret, resp ? "Responsed" : "No Response"); - } - return ret; -} - -static int hgic_fwctrl_set_int_val(struct hgic_fwctrl *ctrl, u32 cmd_id, u32 val) -{ - int ret = -1; - struct sk_buff *skb = NULL; - struct sk_buff *resp = NULL; - struct hgic_ctrl_hdr *hdr = NULL; - - skb = hgic_alloc_ctrl_skb(4); - if (skb) { - put_unaligned_le32(val, skb->data); - resp = hgic_fwctrl_send_cmd(ctrl, cmd_id, skb, true); - if (resp) { - hdr = (struct hgic_ctrl_hdr *)resp->data; - ret = hdr->cmd.status; - dev_kfree_skb_any(resp); - } - } - if (ret) { - hgic_dbg("cmd:%d, ret:%d (%s)\r\n", cmd_id, ret, resp ? "Responsed" : "No Response"); - } - return ret; -} - -static short hgic_fwctrl_get_short_val(struct hgic_fwctrl *ctrl, u32 cmd_id) -{ - short ret = -1; - struct sk_buff *skb = NULL; - struct sk_buff *resp = NULL; - struct hgic_ctrl_hdr *hdr = NULL; - - skb = hgic_alloc_ctrl_skb(0); - if (skb) { - resp = hgic_fwctrl_send_cmd(ctrl, cmd_id, skb, true); - if (resp) { - hdr = (struct hgic_ctrl_hdr *)resp->data; - ret = hdr->cmd.status; - dev_kfree_skb_any(resp); - } - } - return ret; -} - -static int hgic_fwctrl_set_bytes(struct hgic_fwctrl *ctrl, u32 cmd_id, u8 *data, u32 len) -{ - int ret = -1; - struct sk_buff *skb = NULL; - struct sk_buff *resp = NULL; - struct hgic_ctrl_hdr *hdr = NULL; - - skb = hgic_alloc_ctrl_skb(len); - if (skb) { - if (data && len > 0) { - memcpy(skb->data, data, len); - skb->data[len] = 0; - } - resp = hgic_fwctrl_send_cmd(ctrl, cmd_id, skb, true); - if (resp) { - hdr = (struct hgic_ctrl_hdr *)resp->data; - ret = hdr->cmd.status; - dev_kfree_skb_any(resp); - } - if (ret) { - hgic_dbg("cmd:%d, ret:%d (%s)\r\n", cmd_id, ret, resp ? "Responsed" : "No Response"); - } - } - return ret; -} - -static int hgic_fwctrl_get_bytes(struct hgic_fwctrl *ctrl, u32 cmd_id, u8 *buff, u32 len) -{ - int ret = -1; - struct sk_buff *skb = NULL; - struct sk_buff *resp = NULL; - struct hgic_ctrl_hdr *hdr = NULL; - - skb = hgic_alloc_ctrl_skb(0); - if (skb) { - resp = hgic_fwctrl_send_cmd(ctrl, cmd_id, skb, true); - if (resp) { - hdr = (struct hgic_ctrl_hdr *)resp->data; - ret = hdr->cmd.status; - if (ret > 0 && len > 0) { - ret = ret > len ? len : ret; - memcpy(buff, (char *)(hdr + 1), ret); - } - dev_kfree_skb_any(resp); - } - } - if (ret < 0) { - hgic_dbg("get string: cmd:%d, ret:%d (%s)\r\n", cmd_id, ret, resp ? "Responsed" : "No Response"); - } - return ret; -} - -static int hgic_fwctrl_do_cmd(struct hgic_fwctrl *ctrl, u32 cmd_id, u8 *data, u32 len, u8 *buff, u32 size) -{ - int ret = -1; - struct sk_buff *skb = NULL; - struct sk_buff *resp = NULL; - struct hgic_ctrl_hdr *hdr = NULL; - - skb = hgic_alloc_ctrl_skb(len); - if (skb) { - if (data && len > 0) { - memcpy(skb->data, data, len); - skb->data[len] = 0; - } - resp = hgic_fwctrl_send_cmd(ctrl, cmd_id, skb, true); - if (resp) { - hdr = (struct hgic_ctrl_hdr *)resp->data; - ret = hdr->cmd.status; - if (ret > 0 && buff) { - memcpy(buff, (char *)(hdr + 1), ret > size ? size : ret); + ret = (short)le16_to_cpu(hdr->cmd.status); + if (ret > 0 && out) { + memcpy(out, (char *)(hdr + 1), ret > out_size ? out_size : ret); } dev_kfree_skb_any(resp); } if (ret < 0) { - hgic_dbg("cmd:%d, ret:%d (%s)\r\n", cmd_id, ret, resp ? "Responsed" : "No Response"); + printk("FWCTRL: cmd:%d, ret:%d (%s)\r\n", cmd_id, ret, resp ? "Responsed" : "No Response"); } } return ret; } +int hgic_fwctrl_set_byte(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 val) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, cmd_id, &val, 1, 0, 0); +} + +int hgic_fwctrl_set_int_val(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u32 val) +{ + u8 data[4]; + put_unaligned_le32(val, data); + return hgic_fwctrl_do_cmd(ctrl, ifidx, cmd_id, data, 4, 0, 0); +} + +int hgic_fwctrl_get_int_val(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id) +{ + u8 data[4]; + if (hgic_fwctrl_do_cmd(ctrl, ifidx, cmd_id, 0, 0, data, 4) == 4) { + return get_unaligned_le32(data); + } else { + return -1; + } +} + +short hgic_fwctrl_get_short_val(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, cmd_id, 0, 0, 0, 0); +} + +int hgic_fwctrl_set_bytes(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 *data, u32 len) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, cmd_id, data, len, 0, 0); +} + +int hgic_fwctrl_get_bytes(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 *buff, u32 len) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, cmd_id, 0, 0, buff, len); +} + static int hgic_fwctrl_rx_response(struct hgic_fwctrl *ctrl, struct sk_buff *skb) { int find = 0; @@ -295,7 +190,7 @@ static void hgic_fwctrl_work(struct work_struct *work) break; case HGIC_HDR_TYPE_EVENT: case HGIC_HDR_TYPE_EVENT2: - hgic_rx_fw_event(ctrl, skb); + ctrl->rx_event(ctrl, skb); break; default: dev_kfree_skb(skb); @@ -304,12 +199,6 @@ static void hgic_fwctrl_work(struct work_struct *work) } } -static void hgic_fwctrl_flush_work(struct work_struct *work) -{ - struct hgic_fwctrl *ctrl = container_of(work, struct hgic_fwctrl, flush_work); - hgic_fwctrl_flush_param(ctrl); -} - struct sk_buff *hgic_fwctrl_send_data(struct hgic_fwctrl *ctrl, struct sk_buff *skb, struct hgic_cmd_response *resp, u32 timeout) { unsigned long flags; @@ -319,10 +208,17 @@ struct sk_buff *hgic_fwctrl_send_data(struct hgic_fwctrl *ctrl, struct sk_buff * list_add(&resp->list, &ctrl->pd_list); spin_unlock_irqrestore(&ctrl->lock, flags); + if (ctrl->txq.qlen > 4) { + kfree_skb(skb_dequeue(&ctrl->txq)); + //hgic_err("ctrl txq full, drop data (%d)\r\n", ctrl->txq.qlen); + } + skb_queue_tail(&ctrl->txq, skb); - hgic_schedule(ctrl); + ctrl->schedule(ctrl); if (timeout) { - wait_for_completion_timeout(&resp->cmpl, msecs_to_jiffies(timeout)); + if (!wait_for_completion_timeout(&resp->cmpl, msecs_to_jiffies(timeout))) { + hgic_err("timeout, ctrl->rxq:%d\r\n", skb_queue_len(&ctrl->rxq)); + } } spin_lock_irqsave(&ctrl->lock, flags); list_del(&resp->list); @@ -333,29 +229,34 @@ struct sk_buff *hgic_fwctrl_send_data(struct hgic_fwctrl *ctrl, struct sk_buff * return resp->skb; } -void hgic_fwctrl_rx(struct hgic_fwctrl *ctrl, struct sk_buff *skb) +void hgic_fwctrl_rx(struct hgic_fwctrl *ctrl, u8 *data, int len) { - skb_queue_tail(&ctrl->rxq, skb); + struct sk_buff *skb; if (ctrl->wq) { - queue_work(ctrl->wq, &ctrl->work); + skb = dev_alloc_skb(len); + if (skb) { + memcpy(skb->data, data, len); + skb_put(skb, len); + skb_queue_tail(&ctrl->rxq, skb); + queue_work(ctrl->wq, &ctrl->work); + } else { + hgic_err("alloc skb fail\r\n"); + } } else { hgic_err("fwctrl workqueue is NULL\r\n"); } } -void hgic_fwctrl_init(struct hgic_fwctrl *ctrl, void *dev) +void hgic_fwctrl_init(struct hgic_fwctrl *ctrl, void *dev, struct hgic_bus *bus) { memset(ctrl, 0, sizeof(struct hgic_fwctrl)); ctrl->dev = dev; - ctrl->param.acs = 0x3; - ctrl->param.tx_mcs = 0xff; - ctrl->param.ps_mode = 0xff; - ctrl->param.wkio_mode = 0xff; + ctrl->bus = bus; + ctrl->radio_onoff = 1; spin_lock_init(&ctrl->lock); INIT_LIST_HEAD(&ctrl->pd_list); skb_queue_head_init(&ctrl->rxq); skb_queue_head_init(&ctrl->txq); - INIT_WORK(&ctrl->flush_work, hgic_fwctrl_flush_work); INIT_WORK(&ctrl->work, hgic_fwctrl_work); ctrl->wq = ALLOC_ORDERED_WORKQUEUE("fwctrl", 0); } @@ -363,7 +264,6 @@ void hgic_fwctrl_init(struct hgic_fwctrl *ctrl, void *dev) void hgic_fwctrl_release(struct hgic_fwctrl *ctrl) { cancel_work_sync(&ctrl->work); - cancel_work_sync(&ctrl->flush_work); hgic_fwctrl_clear_pdlist(ctrl); hgic_clear_queue(&ctrl->txq); hgic_clear_queue(&ctrl->rxq); @@ -376,121 +276,14 @@ void hgic_fwctrl_release(struct hgic_fwctrl *ctrl) flush_workqueue(ctrl->wq); destroy_workqueue(ctrl->wq); } - ARG_FREE(country_code); - ARG_FREE(ssid); - ARG_FREE(bssid); - ARG_FREE(bssid_filter); - ARG_FREE(key_mgmt); - ARG_FREE(wpa_psk); - ARG_FREE(mode); - ARG_FREE(mac_addr); - ARG_FREE(chan_list); - ARG_FREE(paired_stas); - ARG_FREE(mcast_key); -} - -void hgic_fwctrl_flush_param(struct hgic_fwctrl *ctrl) -{ - //int retry = 0; - - if (ctrl->param.bss_bw) { - hgic_fwctrl_set_bss_bw(ctrl, ctrl->param.bss_bw); - } - if (ctrl->param.chan_list) { - hgic_fwctrl_set_chan_list(ctrl, (u16 *)ctrl->param.chan_list, ctrl->param.chan_cnt); - } - if (ctrl->param.freq_start) { - hgic_fwctrl_set_freq_range(ctrl, ctrl->param.freq_start, ctrl->param.freq_end, ctrl->param.chan_bw); - } - if (ctrl->param.country_code) { - hgic_fwctrl_set_countryregion(ctrl, ctrl->param.country_code); - } - if (ctrl->param.ssid) { - hgic_fwctrl_set_ssid(ctrl, ctrl->param.ssid); - } - if (ctrl->param.bssid) { - hgic_fwctrl_set_bssid(ctrl, ctrl->param.bssid); - } - if (ctrl->param.bssid_filter) { - hgic_fwctrl_set_bssid_filter(ctrl, ctrl->param.bssid_filter); - } - if (ctrl->param.key_mgmt) { - hgic_fwctrl_set_key_mgmt(ctrl, ctrl->param.key_mgmt); - } - if (ctrl->param.wpa_psk) { - hgic_fwctrl_set_wpa_psk(ctrl, ctrl->param.wpa_psk); - } - if (ctrl->param.mcast_key) { - hgic_fwctrl_set_mcast_key(ctrl, ctrl->param.mcast_key); - } - if (ctrl->param.mac_addr) { - hgic_fwctrl_set_mac(ctrl, ctrl->param.mac_addr); - } - if (ctrl->param.channel) { - hgic_fwctrl_set_channel(ctrl, ctrl->param.channel); - } - if (ctrl->param.rts_threshold) { - hgic_fwctrl_set_rts_threshold(ctrl, ctrl->param.rts_threshold); - } - if (ctrl->param.frag_threshold) { - hgic_fwctrl_set_frag_threshold(ctrl, ctrl->param.frag_threshold); - } - if (ctrl->param.listen_interval) { - hgic_fwctrl_set_listen_interval(ctrl, ctrl->param.listen_interval); - } - if (ctrl->param.center_freq) { - hgic_fwctrl_set_center_freq(ctrl, ctrl->param.center_freq); - } - if (ctrl->param.beacon_int) { - hgic_fwctrl_set_beacon_int(ctrl, ctrl->param.beacon_int); - } - if (ctrl->param.ethertype) { - hgic_fwctrl_set_ethertype(ctrl, ctrl->param.ethertype); - } - if (ctrl->param.txpower) { - hgic_fwctrl_set_txpower(ctrl, ctrl->param.txpower); - } - if (ctrl->param.primary_chan) { - hgic_fwctrl_set_primary_chan(ctrl, ctrl->param.primary_chan); - } - if (ctrl->param.mode) { - hgic_fwctrl_set_mode(ctrl, ctrl->param.mode); - } - if (ctrl->param.acs != 0x3) { - hgic_fwctrl_set_acs(ctrl, ctrl->param.acs, ctrl->param.acs_tmo); - } - if (ctrl->param.bss_max_idle) { - hgic_fwctrl_set_bss_max_idle(ctrl, ctrl->param.bss_max_idle); - } - if (ctrl->param.dtim_period) { - hgic_fwctrl_set_dtim_period(ctrl, ctrl->param.dtim_period); - } - if (ctrl->param.ps_connect) { - hgic_fwctrl_set_ps_connect(ctrl, ctrl->param.ps_connect, ctrl->param.ps_connect_roundup); - } - if (ctrl->param.agg_cnt) { - hgic_fwctrl_set_agg_cnt(ctrl, ctrl->param.agg_cnt); - } - if (ctrl->param.wkio_mode != 0xff) { - hgic_fwctrl_set_wkio_mode(ctrl, ctrl->param.wkio_mode); - } - if (ctrl->param.ps_mode != 0xff) { - hgic_fwctrl_set_ps_mode(ctrl, ctrl->param.ps_mode); - } - if (ctrl->param.aplost_time) { - hgic_fwctrl_set_aplost_time(ctrl, ctrl->param.aplost_time); - } - if (ctrl->param.tx_mcs != 0xff) { - hgic_fwctrl_set_tx_mcs(ctrl, ctrl->param.tx_mcs); - } } /////////////////////////////////////////////////////////////////////////////////////////// -int hgic_fwctrl_testmode_cmd(struct hgic_fwctrl *ctrl, u8 *cmd, u32 size) +int hgic_fwctrl_testmode_cmd(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *cmd, u32 size) { int ret = 0; - ret = hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_TESTMODE_CMD, cmd, STR_LEN(cmd), cmd, size); + ret = hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_TESTMODE_CMD, cmd, STR_LEN(cmd), cmd, size); if (ret < 0) { strcpy(cmd, "failed"); } else { @@ -499,372 +292,377 @@ int hgic_fwctrl_testmode_cmd(struct hgic_fwctrl *ctrl, u8 *cmd, u32 size) return ret; } -int hgic_fwctrl_get_status(struct hgic_fwctrl *ctrl, u8 *buff, u32 len) +int hgic_fwctrl_get_status(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, u32 len) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_STATUS, buff, len); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_STATUS, buff, len); } -int hgic_fwctrl_get_conn_state(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_conn_state(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_GET_CONN_STATE, NULL, 0, NULL, 0); + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_GET_CONN_STATE, NULL, 0, NULL, 0); } -int hgic_fwctrl_get_fwinfo(struct hgic_fwctrl *ctrl, struct hgic_fw_info *info) +int hgic_fwctrl_get_fwinfo(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_fw_info *info) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_FW_INFO, (u8 *)info, sizeof(struct hgic_fw_info)); + int ret = 0; + struct hgic_fw_info _info; + ret = hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_FW_INFO, (u8 *)&_info, sizeof(struct hgic_fw_info)); + if (ret > 0) { + info->version = le32_to_cpu(_info.version); + info->svn_version = le32_to_cpu(_info.svn_version); + info->chip_id = le16_to_cpu(_info.chip_id); + info->cpu_id = le16_to_cpu(_info.cpu_id); + memcpy(info->mac, _info.mac, 6); + info->smt_dat = le32_to_cpu(_info.smt_dat); + } + return ret; } -int hgic_fwctrl_set_countryregion(struct hgic_fwctrl *ctrl, u8 *country_code) +int hgic_fwctrl_set_countryregion(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *country_code) { - ARG_DUP(country_code, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_COUNTERY, country_code, STR_LEN(country_code)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_COUNTERY, country_code, STR_LEN(country_code)); } -int hgic_fwctrl_set_ssid(struct hgic_fwctrl *ctrl, u8 *ssid) +int hgic_fwctrl_set_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid) { - ARG_DUP(ssid, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_SSID, ssid, STR_LEN(ssid)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_SSID, ssid, STR_LEN(ssid)); } -int hgic_fwctrl_set_bssid(struct hgic_fwctrl *ctrl, u8 *bssid) +int hgic_fwctrl_set_bssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *bssid) { - ARG_DUP(bssid, 6); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_BSSID, bssid, 6); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_BSSID, bssid, 6); } -int hgic_fwctrl_set_channel(struct hgic_fwctrl *ctrl, u32 channel) +int hgic_fwctrl_set_channel(struct hgic_fwctrl *ctrl, u8 ifidx, u32 channel) { - ctrl->param.acs = 0; - ctrl->param.channel = channel; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_CHANNEL, channel); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_CHANNEL, channel); } -int hgic_fwctrl_set_bssid_filter(struct hgic_fwctrl *ctrl, u8 *bssid_filter) +int hgic_fwctrl_set_bssid_filter(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *bssid_filter) { - ARG_DUP(bssid_filter, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_BSSID_FILTER, bssid_filter, STR_LEN(bssid_filter)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_BSSID_FILTER, bssid_filter, STR_LEN(bssid_filter)); } -int hgic_fwctrl_set_rts_threshold(struct hgic_fwctrl *ctrl, u32 rts_threshold) +int hgic_fwctrl_set_rts_threshold(struct hgic_fwctrl *ctrl, u8 ifidx, u32 rts_threshold) { - ctrl->param.rts_threshold = rts_threshold; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_RTS_THRESHOLD, rts_threshold); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_RTS_THRESHOLD, rts_threshold); } -int hgic_fwctrl_set_frag_threshold(struct hgic_fwctrl *ctrl, u32 frag_threshold) +int hgic_fwctrl_set_frag_threshold(struct hgic_fwctrl *ctrl, u8 ifidx, u32 frag_threshold) { - ctrl->param.frag_threshold = frag_threshold; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_FRG_THRESHOLD, frag_threshold); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_FRG_THRESHOLD, frag_threshold); } -int hgic_fwctrl_set_key_mgmt(struct hgic_fwctrl *ctrl, u8 *key_mgmt) +int hgic_fwctrl_set_key_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *key_mgmt) { - ARG_DUP(key_mgmt, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_KEY_MGMT, key_mgmt, STR_LEN(key_mgmt)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_KEY_MGMT, key_mgmt, STR_LEN(key_mgmt)); } -int hgic_fwctrl_set_wpa_psk(struct hgic_fwctrl *ctrl, u8 *wpa_psk) +int hgic_fwctrl_set_wpa_psk(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *wpa_psk) { - ARG_DUP(wpa_psk, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_WPA_PSK, wpa_psk, STR_LEN(wpa_psk)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_WPA_PSK, wpa_psk, STR_LEN(wpa_psk)); } -int hgic_fwctrl_set_wbnat(struct hgic_fwctrl *ctrl, u32 enable) +int hgic_fwctrl_set_wbnat(struct hgic_fwctrl *ctrl, u8 ifidx, u32 enable) { - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_WBNAT, enable); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_WBNAT, enable); } -int hgic_fwctrl_set_freq_range(struct hgic_fwctrl *ctrl, u32 freq_start, u32 freq_end, u32 bss_bw) +int hgic_fwctrl_set_freq_range(struct hgic_fwctrl *ctrl, u8 ifidx, u32 freq_start, u32 freq_end, u32 bss_bw) { u8 data[12]; put_unaligned_le32(freq_start, data); put_unaligned_le32(freq_end, data + 4); put_unaligned_le32(bss_bw, data + 8); - ctrl->param.freq_start = freq_start; - ctrl->param.freq_end = freq_end; - ctrl->param.chan_bw = bss_bw; - ARG_FREE(chan_list); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_FREQ_RANGE, data, 12); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_FREQ_RANGE, data, 12); } -int hgic_fwctrl_set_bss_bw(struct hgic_fwctrl *ctrl, u8 bss_bw) +int hgic_fwctrl_set_bss_bw(struct hgic_fwctrl *ctrl, u8 ifidx, u8 bss_bw) { - ctrl->param.bss_bw = bss_bw; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_BSS_BW, bss_bw); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_BSS_BW, bss_bw); } -int hgic_fwctrl_set_tx_bw(struct hgic_fwctrl *ctrl, u8 tx_bw) +int hgic_fwctrl_set_tx_bw(struct hgic_fwctrl *ctrl, u8 ifidx, u8 tx_bw) { - ctrl->param.tx_bw = tx_bw; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_TX_BW, tx_bw); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_TX_BW, tx_bw); } -int hgic_fwctrl_set_tx_mcs(struct hgic_fwctrl *ctrl, u8 tx_mcs) +int hgic_fwctrl_set_tx_mcs(struct hgic_fwctrl *ctrl, u8 ifidx, u8 tx_mcs) { - ctrl->param.tx_mcs = tx_mcs; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_TX_MCS, tx_mcs); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_TX_MCS, tx_mcs); } -int hgic_fwctrl_set_acs(struct hgic_fwctrl *ctrl, u8 acs, u8 acs_tmo) +int hgic_fwctrl_set_acs(struct hgic_fwctrl *ctrl, u8 ifidx, u8 acs, u8 acs_tmo) { u8 data[2] = {acs, acs_tmo}; - ctrl->param.acs = acs; - ctrl->param.acs_tmo = acs_tmo; - if (acs) { - ctrl->param.channel = 0; - ctrl->param.center_freq = 0; - } - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_ACS_ENABLE, data, 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_ACS_ENABLE, data, 2); } -int hgic_fwctrl_set_bgrssi(struct hgic_fwctrl *ctrl, u8 bgrssi) +int hgic_fwctrl_set_bgrssi(struct hgic_fwctrl *ctrl, u8 ifidx, u8 bgrssi) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_BG_RSSI, bgrssi); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_BG_RSSI, bgrssi); } -int hgic_fwctrl_set_chan_list(struct hgic_fwctrl *ctrl, u16 *chan_list, u32 cnt) +int hgic_fwctrl_set_chan_list(struct hgic_fwctrl *ctrl, u8 ifidx, u16 *chan_list, u32 cnt) { int ret = -1; int i = 0; u8 *buf = kzalloc((1 + cnt) * sizeof(u16), GFP_KERNEL); - ARG_DUP(chan_list, cnt * sizeof(u16)); - ctrl->param.chan_cnt = cnt; - ctrl->param.freq_start = 0; if (buf) { put_unaligned_le16(cnt, buf); for (i = 0; i < cnt; i++) { put_unaligned_le16(chan_list[i], buf + (i + 1) * sizeof(u16)); } - ret = hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_CHAN_LIST, buf, (1 + cnt) * sizeof(u16)); + ret = hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_CHAN_LIST, buf, (1 + cnt) * sizeof(u16)); kfree(buf); } return ret; } -int hgic_fwctrl_set_mode(struct hgic_fwctrl *ctrl, u8 *mode) +int hgic_fwctrl_set_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mode) { - ARG_DUP(mode, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_WORK_MODE, mode, STR_LEN(mode)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_WORK_MODE, mode, STR_LEN(mode)); } -int hgic_fwctrl_set_paired_stas(struct hgic_fwctrl *ctrl, u8 *paired_stas, u32 len) +int hgic_fwctrl_set_paired_stas(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *paired_stas, u32 len) { - ARG_DUP(paired_stas, len); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_PAIRED_STATIONS, paired_stas, len); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_PAIRED_STATIONS, paired_stas, len); } -int hgic_fwctrl_set_pairing(struct hgic_fwctrl *ctrl, u8 start) +int hgic_fwctrl_set_pairing(struct hgic_fwctrl *ctrl, u8 ifidx, u32 pair_number) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_PAIRING, start); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_PAIRING, pair_number); } -int hgic_fwctrl_open_dev(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_open_dev(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_DEV_OPEN, 0, 0, 0, 0); + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_DEV_OPEN, 0, 0, 0, 0); } -int hgic_fwctrl_close_dev(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_close_dev(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_DEV_CLOSE, 0, 0, 0, 0); + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_DEV_CLOSE, 0, 0, 0, 0); } -int hgic_fwctrl_set_txpower(struct hgic_fwctrl *ctrl, u32 tx_power) +int hgic_fwctrl_set_txpower(struct hgic_fwctrl *ctrl, u8 ifidx, u32 tx_power) { - ctrl->param.txpower = tx_power; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_TX_POWER, tx_power); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_TX_POWER, tx_power); } -int hgic_fwctrl_get_txpower(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_txpower(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_TX_POWER); + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_TX_POWER); } -int hgic_fwctrl_set_listen_interval(struct hgic_fwctrl *ctrl, u32 listen_interval) +int hgic_fwctrl_set_listen_interval(struct hgic_fwctrl *ctrl, u8 ifidx, u32 listen_interval) { - ctrl->param.listen_interval = listen_interval; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_LISTEN_INTERVAL, listen_interval); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_LISTEN_INTERVAL, listen_interval); } -int hgic_fwctrl_set_center_freq(struct hgic_fwctrl *ctrl, u32 center_freq) +int hgic_fwctrl_set_center_freq(struct hgic_fwctrl *ctrl, u8 ifidx, u32 center_freq) { - ctrl->param.acs = 0; - ctrl->param.center_freq = center_freq; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_CENTER_FREQ, center_freq); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_CENTER_FREQ, center_freq); } -int hgic_fwctrl_set_tx_count(struct hgic_fwctrl *ctrl, u32 short_frm_tx_count, u32 long_frm_tx_count) +int hgic_fwctrl_set_tx_count(struct hgic_fwctrl *ctrl, u8 ifidx, u32 short_frm_tx_count, u32 long_frm_tx_count) { u8 data[8]; put_unaligned_le32(short_frm_tx_count, data); put_unaligned_le32(long_frm_tx_count, data + 4); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_TX_LCOUNT, data, 8); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_TX_LCOUNT, data, 8); } -int hgic_fwctrl_set_key(struct hgic_fwctrl *ctrl, u8 cmd, u16 aid, u8 *key, u8 len) +int hgic_fwctrl_set_key(struct hgic_fwctrl *ctrl, u8 ifidx, u8 cmd, u8 *addr, u8 *key, u8 len) { - int ret = -ENOMEM; - u8 *buff = kmalloc(len + 4, GFP_KERNEL); + int ret = -ENOMEM; + u8 *buff = kmalloc(len + 10, GFP_KERNEL); if (buff) { buff[0] = cmd; - put_unaligned_le16(aid, buff + 1); - buff[3] = len; - memcpy(buff + 4, key, len); - ret = hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_KEY, buff, len + 4); + buff[1] = len; + memcpy(buff + 2, addr, 6); + memcpy(buff + 8, key, len); + ret = hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_KEY, buff, len + 8); kfree(buff); } return ret; } -int hgic_fwctrl_add_sta(struct hgic_fwctrl *ctrl, u16 aid, u8 *addr) +int hgic_fwctrl_add_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u16 aid, u8 *addr) { uint8_t sta_info[8]; put_unaligned_le16(aid, sta_info); memcpy(sta_info + 2, addr, 6); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_ADD_STA, sta_info, 8); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_ADD_STA, sta_info, 8); } -int hgic_fwctrl_del_sta(struct hgic_fwctrl *ctrl, u32 aid) +int hgic_fwctrl_del_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) { - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_REMOVE_STA, aid); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_REMOVE_STA, addr, 6); } -int hgic_fwctrl_set_primary_chan(struct hgic_fwctrl *ctrl, u8 primary_chan) +int hgic_fwctrl_set_primary_chan(struct hgic_fwctrl *ctrl, u8 ifidx, u8 primary_chan) { - ctrl->param.primary_chan = primary_chan; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_PRIMARY_CHAN, primary_chan); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_PRIMARY_CHAN, primary_chan); } -int hgic_fwctrl_set_aid(struct hgic_fwctrl *ctrl, u32 aid) +int hgic_fwctrl_set_aid(struct hgic_fwctrl *ctrl, u8 ifidx, u32 aid) { - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_AID, aid); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_AID, aid); } -int hgic_fwctrl_set_mac(struct hgic_fwctrl *ctrl, u8 *mac_addr) +int hgic_fwctrl_set_mac(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mac) { - ARG_DUP(mac_addr, 6); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_MAC, mac_addr, 6); + u8 mac_addr[7]; + memcpy(mac_addr, mac, 6); + mac_addr[6] = ifidx; + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_MAC, mac_addr, 7); } -int hgic_fwctrl_get_scan_list(struct hgic_fwctrl *ctrl, u8 *buff, u32 size) +int hgic_fwctrl_get_scan_list(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, u32 size) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_SCAN_LIST, buff, size); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_SCAN_LIST, buff, size); } -int hgic_fwctrl_scan(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_scan(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SCAN, 1); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SCAN, 1); } -int hgic_fwctrl_set_txq_param(struct hgic_fwctrl *ctrl, u8 *txq, u32 size) +int hgic_fwctrl_set_txq_param(struct hgic_fwctrl *ctrl, u8 ifidx, u8 ac, struct hgic_txq_param *param) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_TXQ_PARAM, txq, size); + int ret = -ENOMEM; + u8 *txq = (u8 *)kmalloc(1 + sizeof(struct hgic_txq_param), GFP_KERNEL); + if (txq) { + txq[0] = ac; + memcpy(txq + 1, param, sizeof(struct hgic_txq_param)); + ret = hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_TXQ_PARAM, txq, 1 + sizeof(struct hgic_txq_param)); + kfree(txq); + } + return ret; +} +int hgic_fwctrl_set_user_edca(struct hgic_fwctrl *ctrl, u8 ifidx, u8 ac, struct hgic_txq_param *param) +{ + int ret = -ENOMEM; + u8 *txq = (u8 *)kmalloc(1 + sizeof(struct hgic_txq_param), GFP_KERNEL); + if (txq) { + txq[0] = ac; + memcpy(txq + 1, param, sizeof(struct hgic_txq_param)); + ret = hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_USER_EDCA, txq, 1 + sizeof(struct hgic_txq_param)); + kfree(txq); + } + return ret; } int hgic_fwctrl_get_temperature(struct hgic_fwctrl *ctrl) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_TEMPERATURE); + return hgic_fwctrl_get_short_val(ctrl, 1, HGIC_CMD_GET_TEMPERATURE); } -int hgic_fwctrl_enter_sleep(struct hgic_fwctrl *ctrl, u8 sleep) +int hgic_fwctrl_enter_sleep(struct hgic_fwctrl *ctrl, u8 ifidx, u16 sleep, u32 sleep_ms) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_ENTER_SLEEP, sleep); + u8 buff[8]; + put_unaligned_le16(sleep, buff); + put_unaligned_le32(sleep_ms, buff + 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_ENTER_SLEEP, buff, 6); } -int hgic_fwctrl_get_sta_list(struct hgic_fwctrl *ctrl, struct hgic_sta_info *sta_list, u32 size) +int hgic_fwctrl_get_sta_list(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_sta_info *sta_list, u32 size) { - int ret = hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_STA_LIST, (u8 *)sta_list, size * sizeof(struct hgic_sta_info)); + int ret = hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_STA_LIST, (u8 *)sta_list, size * sizeof(struct hgic_sta_info)); return ret > 0 ? (ret / sizeof(struct hgic_sta_info)) : ret; } -int hgic_fwctrl_set_beacon_int(struct hgic_fwctrl *ctrl, u32 beacon_int) +int hgic_fwctrl_set_beacon_int(struct hgic_fwctrl *ctrl, u8 ifidx, u32 beacon_int) { - ctrl->param.beacon_int = beacon_int; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_BEACON_INT, beacon_int); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_BEACON_INT, beacon_int); } -int hgic_fwctrl_get_ssid(struct hgic_fwctrl *ctrl, u8 *ssid, u32 size) +int hgic_fwctrl_get_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mode, u32 size) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_SSID, ssid, size); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_MODE, mode, size); } -int hgic_fwctrl_get_bssid(struct hgic_fwctrl *ctrl, u8 *bssid) +int hgic_fwctrl_get_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid, u32 size) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_BSSID, bssid, 6); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_SSID, ssid, size); } -int hgic_fwctrl_get_wpapsk(struct hgic_fwctrl *ctrl, u8 *psk, u32 size) +int hgic_fwctrl_get_bssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *bssid, u32 len) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_WPA_PSK, psk, size); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_BSSID, bssid, len); } -int hgic_fwctrl_save_cfg(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_wpapsk(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *psk, u32 size) { - return hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_SAVE_CFG, 0, 0, 0, 0); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_WPA_PSK, psk, size); } -int hgic_fwctrl_join_group(struct hgic_fwctrl *ctrl, u8 *addr, u8 aid) +int hgic_fwctrl_save_cfg(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_SAVE_CFG, 0, 0, 0, 0); +} + +int hgic_fwctrl_join_group(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr, u8 aid) { u8 val[7]; memcpy(val, addr, 6); val[6] = aid; - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_JOIN_GROUP, val, 7); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_JOIN_GROUP, val, 7); } -int hgic_fwctrl_set_ethertype(struct hgic_fwctrl *ctrl, u16 ethertype) +int hgic_fwctrl_set_ethertype(struct hgic_fwctrl *ctrl, u8 ifidx, u16 ethertype) { u8 vals[2]; - ctrl->param.ethertype = ethertype; put_unaligned_le16(ethertype, vals); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_ETHER_TYPE, vals, 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_ETHER_TYPE, vals, 2); } -int hgic_fwctrl_get_sta_count(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_sta_count(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_GET_STA_COUNT, 0, 0, 0, 0); + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_GET_STA_COUNT, 0, 0, 0, 0); } -int hgic_fwctrl_get_agg_cnt(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_agg_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *agg, u8 size) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_AGG_CNT); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_AGG_CNT, agg, size); } -int hgic_fwctrl_set_agg_cnt(struct hgic_fwctrl *ctrl, u8 agg_cnt) +int hgic_fwctrl_set_agg_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 agg[2]) { - ctrl->param.agg_cnt = agg_cnt; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_AGG_CNT, agg_cnt); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_AGG_CNT, agg ,2); } -int hgic_fwctrl_get_bss_bw(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_bss_bw(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_BSS_BW); + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_BSS_BW); } -int hgic_fwctrl_get_freq_range(struct hgic_fwctrl *ctrl, u32 *freq_start, u32 *freq_end, u32 *bss_bw) +int hgic_fwctrl_get_freq_range(struct hgic_fwctrl *ctrl, u8 ifidx, u32 *freq_start, u32 *freq_end, u32 *bss_bw) { int ret = 0; u32 vals[3]; - ret = hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_FREQ_RANGE, (u8 *)&vals, sizeof(vals)); + ret = hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_FREQ_RANGE, (u8 *)&vals, sizeof(vals)); if (ret == 12) { - *freq_start = vals[0]; - *freq_end = vals[1]; - *bss_bw = vals[2]; + *freq_start = le32_to_cpu(vals[0]); + *freq_end = le32_to_cpu(vals[1]); + *bss_bw = le32_to_cpu(vals[2]); } return (ret == 12); } -int hgic_fwctrl_get_chan_list(struct hgic_fwctrl *ctrl, u16 *chan_list, u16 count) +int hgic_fwctrl_get_chan_list(struct hgic_fwctrl *ctrl, u8 ifidx, u16 *chan_list, u16 count) { - int ret = hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_CHAN_LIST, (u8 *)chan_list, count * sizeof(u16)); + int ret = hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_CHAN_LIST, (u8 *)chan_list, count * sizeof(u16)); return ret > 0 ? ret / sizeof(u16) : 0; } -int hgic_fwctrl_wakeup_sta(struct hgic_fwctrl *ctrl, u8 *addr) +int hgic_fwctrl_wakeup_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_WAKEUP_STA, addr, 6); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_WAKEUP_STA, addr, 6); } -int hgic_fwctrl_set_ps_heartbeat(struct hgic_fwctrl *ctrl, u32 ipaddr, u32 dport, u32 period, u32 hb_tmo) +int hgic_fwctrl_set_ps_heartbeat(struct hgic_fwctrl *ctrl, u8 ifidx, u32 ipaddr, u32 dport, u32 period, u32 hb_tmo) { u8 val[16]; put_unaligned_le32(ipaddr, val); @@ -872,288 +670,576 @@ int hgic_fwctrl_set_ps_heartbeat(struct hgic_fwctrl *ctrl, u32 ipaddr, u32 dport put_unaligned_le32(period, val + 8); put_unaligned_le32(hb_tmo, val + 12); hgic_dbg("ip:%x, port:%d, period:%d, hb_tmo:%d\r\n", ipaddr, dport, period, hb_tmo); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_PS_HEARTBEAT, val, 16); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_PS_HEARTBEAT, val, 16); } -int hgic_fwctrl_set_ps_heartbeat_resp(struct hgic_fwctrl *ctrl, u8 *data, u32 size) +int hgic_fwctrl_set_ps_heartbeat_resp(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 size) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_PS_HEARTBEAT_RESP, data, size); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_PS_HEARTBEAT_RESP, data, size); } -int hgic_fwctrl_set_ps_wakeup_data(struct hgic_fwctrl *ctrl, u8 *data, u32 size) +int hgic_fwctrl_set_ps_wakeup_data(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 size) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_PS_WAKEUP_DATA, data, size); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_PS_WAKEUP_DATA, data, size); } -int hgic_fwctrl_set_ps_connect(struct hgic_fwctrl *ctrl, u8 period, u8 roundup) +int hgic_fwctrl_set_ps_connect(struct hgic_fwctrl *ctrl, u8 ifidx, u8 period, u8 roundup) { u8 val[2] = {period, roundup}; - ctrl->param.ps_connect = period; - ctrl->param.ps_connect_roundup = roundup; - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_PS_CONNECT, val, 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_PS_CONNECT, val, 2); } -int hgic_fwctrl_radio_onoff(struct hgic_fwctrl *ctrl, u8 onoff) +int hgic_fwctrl_radio_onoff(struct hgic_fwctrl *ctrl, u8 ifidx, u8 onoff) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_RADIO_ONOFF, onoff); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_RADIO_ONOFF, onoff); } -int hgic_fwctrl_set_bss_max_idle(struct hgic_fwctrl *ctrl, u32 max_idle) +int hgic_fwctrl_set_bss_max_idle(struct hgic_fwctrl *ctrl, u8 ifidx, u32 max_idle) { - ctrl->param.bss_max_idle = max_idle; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_BSS_MAX_IDLE, max_idle); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_BSS_MAX_IDLE, max_idle); } -int hgic_fwctrl_set_wkio_mode(struct hgic_fwctrl *ctrl, u8 mode) +int hgic_fwctrl_set_wkio_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 mode) { - ctrl->param.wkio_mode = mode; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_WKIO_MODE, mode); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_WKIO_MODE, mode); } -int hgic_fwctrl_set_dtim_period(struct hgic_fwctrl *ctrl, u32 period) +int hgic_fwctrl_set_dtim_period(struct hgic_fwctrl *ctrl, u8 ifidx, u32 period) { - ctrl->param.dtim_period = period; - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_DTIM_PERIOD, period); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_DTIM_PERIOD, period); } -int hgic_fwctrl_set_ps_mode(struct hgic_fwctrl *ctrl, u8 mode) +int hgic_fwctrl_set_ps_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 mode) { - ctrl->param.ps_mode = mode; - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_PS_MODE, mode); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_PS_MODE, mode); } -int hgic_fwctrl_set_load_def(struct hgic_fwctrl *ctrl, u8 rst) +int hgic_fwctrl_set_load_def(struct hgic_fwctrl *ctrl, u8 ifidx, u8 rst) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_LOAD_DEF, rst); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_LOAD_DEF, rst); } -int hgic_fwctrl_disassoc_sta(struct hgic_fwctrl *ctrl, u8 *addr) +int hgic_fwctrl_disassoc_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_DISASSOC_STA, addr, 6); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_DISASSOC_STA, addr, 6); } -int hgic_fwctrl_set_aplost_time(struct hgic_fwctrl *ctrl, u32 aplost_time) +int hgic_fwctrl_set_aplost_time(struct hgic_fwctrl *ctrl, u8 ifidx, u32 aplost_time) { - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_APLOST_TIME, aplost_time); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_APLOST_TIME, aplost_time); } -int hgic_fwctrl_get_wkreason(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_wkreason(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_do_cmd(ctrl, HGIC_CMD_GET_WAKEUP_REASON, 0, 0, 0, 0); + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_GET_WAKEUP_REASON, 0, 0, 0, 0); } -int hgic_fwctrl_unpair(struct hgic_fwctrl *ctrl, u8 *addr) +int hgic_fwctrl_unpair(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) { - ARG_FREE(ssid); - ARG_FREE(bssid); - ARG_FREE(bssid_filter); - ARG_FREE(key_mgmt); - ARG_FREE(wpa_psk); - ARG_FREE(paired_stas); - ARG_FREE(mcast_key); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_UNPAIR, addr, 6); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_UNPAIR, addr, 6); } -int hgic_fwctrl_set_auto_chswitch(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_set_auto_chswitch(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_AUTO_CHAN_SWITCH, enable); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_AUTO_CHAN_SWITCH, enable); } -int hgic_fwctrl_set_mcast_key(struct hgic_fwctrl *ctrl, u8 *mcast_key) +int hgic_fwctrl_set_mcast_key(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mcast_key) { - ARG_DUP(mcast_key, 0); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_MCAST_KEY, mcast_key, STR_LEN(mcast_key)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_MCAST_KEY, mcast_key, STR_LEN(mcast_key)); } -int hgic_fwctrl_set_reassoc_wkhost(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_set_reassoc_wkhost(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_REASSOC_WKHOST, enable); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_REASSOC_WKHOST, enable); } -int hgic_fwctrl_set_wakeup_io(struct hgic_fwctrl *ctrl, u8 io, u8 edge) +int hgic_fwctrl_set_wakeup_io(struct hgic_fwctrl *ctrl, u8 ifidx, u8 io, u8 edge) { u8 val[2] = {io, edge}; - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_WAKEUP_IO, val, 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_WAKEUP_IO, val, 2); } -int hgic_fwctrl_set_dbginfo_output(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_set_dbginfo_output(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_DBGINFO_OUTPUT, enable); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_DBGINFO_OUTPUT, enable); } -int hgic_fwctrl_set_sysdbg(struct hgic_fwctrl *ctrl, u8 *cmd) +int hgic_fwctrl_set_sysdbg(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *cmd) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_SYSDBG, cmd, STR_LEN(cmd)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_SYSDBG, cmd, STR_LEN(cmd)); } -int hgic_fwctrl_set_autosleep_time(struct hgic_fwctrl *ctrl, u8 time) +int hgic_fwctrl_set_autosleep_time(struct hgic_fwctrl *ctrl, u8 ifidx, u8 time) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_AUTO_SLEEP_TIME, time); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_AUTO_SLEEP_TIME, time); } -int hgic_fwctrl_get_key_mgmt(struct hgic_fwctrl *ctrl, u8 *ssid, u32 size) +int hgic_fwctrl_get_key_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid, u32 size) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_KEY_MGMT, ssid, size); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_KEY_MGMT, ssid, size); } -int hgic_fwctrl_set_supper_pwr(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_set_super_pwr(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_SUPPER_PWR, enable); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_SUPER_PWR, enable); } -int hgic_fwctrl_set_repeater_ssid(struct hgic_fwctrl *ctrl, u8 *ssid) +int hgic_fwctrl_set_repeater_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_REPEATER_SSID, ssid, STR_LEN(ssid)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_REPEATER_SSID, ssid, STR_LEN(ssid)); } -int hgic_fwctrl_set_repeater_psk(struct hgic_fwctrl *ctrl, u8 *wpa_psk) +int hgic_fwctrl_set_repeater_psk(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *wpa_psk) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_REPEATER_PSK, wpa_psk, STR_LEN(wpa_psk)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_REPEATER_PSK, wpa_psk, STR_LEN(wpa_psk)); } -int hgic_fwctrl_set_auto_save(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_set_auto_save(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_CFG_AUTO_SAVE, enable); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_CFG_AUTO_SAVE, enable); } -int hgic_fwctrl_set_pair_autostop(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_set_pair_autostop(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_PAIR_AUTOSTOP, enable); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_PAIR_AUTOSTOP, enable); } -int hgic_fwctrl_send_cust_mgmt(struct hgic_fwctrl *ctrl, u8 *data, u32 len) +int hgic_fwctrl_send_cust_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SEND_CUST_MGMT, data, len); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SEND_CUST_MGMT, data, len); } - -int hgic_fwctrl_get_battery_level(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_send_mgmtframe(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_BATTERY_LEVEL); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SEND_MGMTFRAME, data, len); } -int hgic_fwctrl_set_dcdc13v(struct hgic_fwctrl *ctrl, u8 enable) +int hgic_fwctrl_get_battery_level(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_DCDC13, enable); + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_BATTERY_LEVEL); } -int hgic_fwctrl_set_acktmo(struct hgic_fwctrl *ctrl, u32 tmo) +int hgic_fwctrl_set_dcdc13v(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) { - return hgic_fwctrl_set_int_val(ctrl, HGIC_CMD_SET_ACKTMO, tmo); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DCDC13, enable); } -int hgic_fwctrl_get_module_type(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_set_acktmo(struct hgic_fwctrl *ctrl, u8 ifidx, u32 tmo) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_MODULETYPE); + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_ACKTMO, tmo); } -int hgic_fwctrl_set_pa_pwrctl_dis(struct hgic_fwctrl *ctrl, u8 dis) +int hgic_fwctrl_get_module_type(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_PA_PWRCTRL_DIS, dis); + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_MODULETYPE); } -int hgic_fwctrl_set_dhcpc(struct hgic_fwctrl *ctrl, u8 en) +int hgic_fwctrl_set_pa_pwrctl_dis(struct hgic_fwctrl *ctrl, u8 ifidx, u8 dis) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_DHCPC, en); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_PA_PWRCTRL_DIS, dis); } -int hgic_fwctrl_get_dhcpc_result(struct hgic_fwctrl *ctrl, u8 *buff, int len) +int hgic_fwctrl_set_dhcpc(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_DHCPC_RESULT, buff, len); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DHCPC, en); } -int hgic_fwctrl_set_wkdata_mask(struct hgic_fwctrl *ctrl, u16 offset, u8 *mask, u8 mask_len) +int hgic_fwctrl_get_dhcpc_result(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, int len) +{ + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_DHCPC_RESULT, buff, len); +} + +int hgic_fwctrl_set_wkdata_mask(struct hgic_fwctrl *ctrl, u8 ifidx, u16 offset, u8 *mask, u8 mask_len) { u8 data[128]; - if(mask_len > 16) mask_len = 16; + if (mask_len > 16) mask_len = 16; memset(data, 0, sizeof(data)); put_unaligned_le16(offset, data); memcpy(data + 2, mask, mask_len); - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_WKUPDATA_MASK, data, mask_len + 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_WKUPDATA_MASK, data, mask_len + 2); } -int hgic_fwctrl_get_wkdata_buff(struct hgic_fwctrl *ctrl, u8 *buff, int len) +int hgic_fwctrl_get_wkdata_buff(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, int len) { - return hgic_fwctrl_get_bytes(ctrl, HGIC_CMD_GET_WKDATA_BUFF, buff, len); + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_WKDATA_BUFF, buff, len); } -int hgic_fwctrl_get_disassoc_reason(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_disassoc_reason(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_DISASSOC_REASON); + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_DISASSOC_REASON); } -int hgic_fwctrl_set_wkdata_save(struct hgic_fwctrl *ctrl, u8 save) +int hgic_fwctrl_set_wkdata_save(struct hgic_fwctrl *ctrl, u8 ifidx, u8 save) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_WKUPDATA_SAVEEN, save); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_WKUPDATA_SAVEEN, save); } -int hgic_fwctrl_set_cust_driver_data(struct hgic_fwctrl *ctrl, u8 *data, u32 len) +int hgic_fwctrl_set_cust_driver_data(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_CUST_DRIVER_DATA, data, len); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_CUST_DRIVER_DATA, data, len); } -int hgic_fwctrl_set_mcast_txparam(struct hgic_fwctrl *ctrl, struct hgic_mcast_txparam *param) +int hgic_fwctrl_set_mcast_txparam(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_mcast_txparam *param) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_MCAST_TXPARAM, (u8 *)param, sizeof(struct hgic_mcast_txparam)); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_MCAST_TXPARAM, (u8 *)param, sizeof(struct hgic_mcast_txparam)); } -int hgic_fwctrl_set_freqinfo(struct hgic_fwctrl *ctrl, u8 *data, u32 len) +int hgic_fwctrl_set_freqinfo(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_STA_FREQINFO, data, len); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_STA_FREQINFO, data, len); } -int hgic_fwctrl_reset_sta(struct hgic_fwctrl *ctrl, u8 *addr) +int hgic_fwctrl_reset_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_RESET_STA, addr, 6); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_RESET_STA, addr, 6); } -int hgic_fwctrl_set_ant_auto(struct hgic_fwctrl *ctrl, u8 en) +int hgic_fwctrl_set_ant_auto(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_ANT_AUTO, en); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_ANT_AUTO, en); } -int hgic_fwctrl_select_ant(struct hgic_fwctrl *ctrl, u8 ant) +int hgic_fwctrl_select_ant(struct hgic_fwctrl *ctrl, u8 ifidx, u8 ant) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_ANT_SEL, ant); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_ANT_SEL, ant); } -int hgic_fwctrl_get_ant_sel(struct hgic_fwctrl *ctrl) +int hgic_fwctrl_get_ant_sel(struct hgic_fwctrl *ctrl, u8 ifidx) { - return hgic_fwctrl_get_short_val(ctrl, HGIC_CMD_GET_ANT_SEL); + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_ANT_SEL); } -int hgic_fwctrl_set_wkhost_reasons(struct hgic_fwctrl *ctrl, u8 *reasons, u8 count) +int hgic_fwctrl_set_wkhost_reasons(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *reasons, u8 count) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_WKUP_HOST_REASON, reasons, count); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_WKUP_HOST_REASON, reasons, count); } -int hgic_fwctrl_set_mac_filter(struct hgic_fwctrl *ctrl, u8 en) +int hgic_fwctrl_set_mac_filter(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_MAC_FILTER_EN, en); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_MAC_FILTER_EN, en); } -int hgic_fwctrl_set_atcmd(struct hgic_fwctrl *ctrl, char *atcmd) +int hgic_fwctrl_set_atcmd(struct hgic_fwctrl *ctrl, u8 ifidx, char *atcmd) { - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_ATCMD, atcmd, strlen(atcmd)); + int ret = 0; + if (strncasecmp(atcmd, "at+", 3)) { + char *tmp = kzalloc(strlen(atcmd) + 12, GFP_KERNEL); + if (tmp) { + strcpy(tmp, "at+"); + strcpy(tmp + 3, atcmd); + ret = hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_ATCMD, tmp, strlen(tmp)); + kfree(tmp); + return ret; + } + return -ENOMEM; + } else { + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_ATCMD, atcmd, strlen(atcmd)); + } } -int hgic_fwctrl_set_roaming(struct hgic_fwctrl *ctrl, u8 en, u8 same_freq) +int hgic_fwctrl_set_roaming(struct hgic_fwctrl *ctrl, u8 ifidx, s8 *vals, u8 count) { - u8 vals[2] = {en, same_freq}; - return hgic_fwctrl_set_bytes(ctrl, HGIC_CMD_SET_ROAMING, vals, 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_ROAMING, vals, count); } -int hgic_fwctrl_set_ap_hide(struct hgic_fwctrl *ctrl, u8 hide) +int hgic_fwctrl_set_ap_hide(struct hgic_fwctrl *ctrl, u8 ifidx, u8 hide) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_AP_HIDE, hide); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_AP_HIDE, hide); } -int hgic_fwctrl_set_frm_tx_maxcnt(struct hgic_fwctrl *ctrl, u8 txcnt) +int hgic_fwctrl_set_frm_tx_maxcnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 txcnt) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_MAX_TCNT, txcnt); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_MAX_TCNT, txcnt); } -int hgic_fwctrl_set_assert_holdup(struct hgic_fwctrl *ctrl, u8 holdup) +int hgic_fwctrl_set_assert_holdup(struct hgic_fwctrl *ctrl, u8 ifidx, u8 holdup) { - return hgic_fwctrl_set_byte(ctrl, HGIC_CMD_SET_ASSERT_HOLDUP, holdup); + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_ASSERT_HOLDUP, holdup); +} + +int hgic_fwctrl_set_ap_psmode_en(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_AP_PSMODE_EN, en); +} + +int hgic_fwctrl_set_dupfilter_en(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DUPFILTER_EN, en); +} + +int hgic_fwctrl_set_1v1_m2u_dis(struct hgic_fwctrl *ctrl, u8 ifidx, u8 dis) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DIS_1V1_M2U, dis); +} + +int hgic_fwctrl_set_psconnect_dis(struct hgic_fwctrl *ctrl, u8 ifidx, u8 dis) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DIS_PSCONNECT, dis); +} + +int hgic_fwctrl_set_blenc_en(struct hgic_fwctrl *ctrl, u8 ifidx, u8 data[2]) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_BLENC_EN, data, 2); +} + +int hgic_fwctrl_blenc_send_data(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SEND_BLENC_DATA, data, len); +} +int hgic_fwctrl_blenc_set_advdata(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SEND_BLENC_ADVDATA, data, len); +} +int hgic_fwctrl_blenc_set_scanresp(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SEND_BLENC_SCANRESP, data, len); +} +int hgic_fwctrl_blenc_set_devaddr(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SEND_BLENC_DEVADDR, addr, 6); +} +int hgic_fwctrl_blenc_set_advinterval(struct hgic_fwctrl *ctrl, u8 ifidx, u32 interval) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SEND_BLENC_ADVINTERVAL, interval); +} +int hgic_fwctrl_blenc_start_adv(struct hgic_fwctrl *ctrl, u8 ifidx, u32 en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SEND_BLENC_STARTADV, en); +} + +int hgic_fwctrl_reset(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_RESET, 0, 0, 0, 0); +} + +int hgic_fwctrl_set_hwscan(struct hgic_fwctrl *ctrl, u8 ifidx, u16 period, u16 interval, u16 chan, u16 max) +{ + u8 val[5]; + val[0] = period; + val[1] = interval; + val[4] = max; + put_unaligned_le16(chan, val + 2); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_HWSCAN, val, 5); +} + +int hgic_fwctrl_get_txq_param(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_txq_param param[4]) +{ + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_TXQ_PARAM, (u8 *)param, 4 * sizeof(struct hgic_txq_param)); +} + +int hgic_fwctrl_set_promisc(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_PROMISC, enable); +} + +int hgic_fwctrl_set_fix_txrate(struct hgic_fwctrl *ctrl, u8 ifidx, u32 txrate) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_FIX_TXRATE, txrate); +} + +int hgic_fwctrl_set_nav_max(struct hgic_fwctrl *ctrl, u8 ifidx, u32 nav_max) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_NAV_MAX, nav_max); +} + +int hgic_fwctrl_clear_nav(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_NAV_MAX, 0); +} + +int hgic_fwctrl_set_cca_param(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_cca_ctl *cca) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_CCA_PARAM, (u8 *)cca, sizeof(struct hgic_cca_ctl)); +} + +int hgic_fwctrl_set_tx_modulation_gain(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *gain_table, u32 size) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_TX_MODGAIN, gain_table, size); +} + +int hgic_fwctrl_get_nav(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_NAV); +} + +int hgic_fwctrl_get_bgrssi(struct hgic_fwctrl *ctrl, u8 ifidx, u8 channel, s8 resp[3]) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_GET_BGRSSI, &channel, 1, resp, 3); +} + +int hgic_fwctrl_send_hci_data(struct hgic_fwctrl *ctrl, u8 type, u8 *data, u32 len) +{ + struct hgic_ctrl_hdr *hdr; + struct sk_buff *skb = dev_alloc_skb(ctrl->bus->drv_tx_headroom + sizeof(struct hgic_ctrl_hdr) + len + 4); + if (skb) { + skb_reserve(skb, ctrl->bus->drv_tx_headroom); + hdr = (struct hgic_ctrl_hdr *)skb->data; + memcpy((u8 *)(hdr + 1), data, len); + skb_put(skb, sizeof(struct hgic_ctrl_hdr) + len); + memset(hdr, 0, sizeof(struct hgic_ctrl_hdr)); + hdr->hdr.magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + hdr->hdr.type = HGIC_HDR_TYPE_BLUETOOTH; + hdr->hdr.ifidx = 1; + hdr->hdr.length = cpu_to_le16(skb->len); + hdr->hci.type = type; + skb_queue_tail(&ctrl->txq, skb); + ctrl->schedule(ctrl); + return 0; + } + return -ENOMEM; +} + +int hgic_fwctrl_set_beacon_start(struct hgic_fwctrl *ctrl, u8 ifidx, u8 start) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_BEACON_START, start); +} + +int hgic_fwctrl_ble_open(struct hgic_fwctrl *ctrl, u8 ifidx, u8 open) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_BLE_OPEN, open); +} + +int hgic_fwctrl_set_rts_duration(struct hgic_fwctrl *ctrl, u8 ifidx, int duration) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_RTS_DURATION, duration); +} + +int hgic_fwctrl_set_disable_print(struct hgic_fwctrl *ctrl, u8 ifidx, int dis) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DISABLE_PRINT, dis); +} + +int hgic_fwctrl_set_conn_paironly(struct hgic_fwctrl *ctrl, u8 ifidx, int en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_CONNECT_PAIRONLY, en); +} + +int hgic_fwctrl_get_center_freq(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_CENTER_FREQ); +} + +int hgic_fwctrl_set_wait_psmode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 wait_psmode) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_WAIT_PSMODE, wait_psmode); +} + +int hgic_fwctrl_set_diffcust_conn(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_DIFFCUST_CONN, en); +} + +int hgic_fwctrl_set_ap_chan_switch(struct hgic_fwctrl *ctrl, u8 ifidx, u8 chan, u8 counter) +{ + u8 val[2] = {chan, counter}; + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_AP_CHAN_SWITCH, val, 2); +} + +int hgic_fwctrl_set_cca_for_ce(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_CCA_FOR_CE, en); +} + +int hgic_fwctrl_set_standby(struct hgic_fwctrl *ctrl, u8 ifidx, u8 channel, u32 sleep_period) +{ + u8 val[5]; + val[0] = channel; + put_unaligned_le32(sleep_period, val + 1); + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_STANDBY_CFG, val, 5); +} + +int hgic_fwctrl_set_rtc(struct hgic_fwctrl *ctrl, u8 ifidx, u32 rtc) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_RTC, rtc); +} + +int hgic_fwctrl_get_rtc(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *rtc) +{ + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_RTC, rtc, 4); +} + +int hgic_fwctrl_set_apep_padding(struct hgic_fwctrl *ctrl, u8 ifidx, int en) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_APEP_PADDING, en); +} + +int hgic_fwctrl_get_acs_result(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_acs_result *result, u8 size) +{ + return hgic_fwctrl_get_bytes(ctrl, ifidx, HGIC_CMD_GET_WIFI_STATUS_CODE, (u8 *)result, size * sizeof(struct hgic_acs_result)); +} + +int hgic_fwctrl_get_reason_code(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_WIFI_REASON_CODE); +} + +int hgic_fwctrl_get_status_code(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_WIFI_STATUS_CODE); +} + +int hgic_fwctrl_set_watchdog(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_WATCHDOG, enable); +} + +int hgic_fwctrl_set_retry_fallback_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 cnt) +{ + return hgic_fwctrl_set_byte(ctrl, ifidx, HGIC_CMD_SET_RETRY_FALLBACK_CNT, cnt); +} + +int hgic_fwctrl_set_fallback_mcs(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_fallback_mcs *mcs) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, HGIC_CMD_SET_FALLBACK_MCS, (u8 *)mcs, sizeof(struct hgic_fallback_mcs)); +} + +int hgic_fwctrl_get_xosc(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_get_int_val(ctrl, ifidx, HGIC_CMD_GET_XOSC_VALUE); +} + +int hgic_fwctrl_set_xosc(struct hgic_fwctrl *ctrl, u8 ifidx, int xosc) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_XOSC_VALUE, xosc); +} + +int hgic_fwctrl_get_freq_offset(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr) +{ + u8 data[4]; + if (hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_GET_FREQ_OFFSET, addr, 6, data, 4) == 4) { + return get_unaligned_le32(data); + } else { + return -1; + } +} + +int hgic_fwctrl_set_freq_cali_period(struct hgic_fwctrl *ctrl, u8 ifidx, u16 cali_period) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_CALI_PERIOD, cali_period); +} + +int hgic_fwctrl_set_blenc_adv_filter(struct hgic_fwctrl *ctrl, u8 ifidx, u32 filter) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_BLENC_ADVFILTER, filter); +} + +int hgic_fwctrl_set_max_tx_delay(struct hgic_fwctrl *ctrl, u8 ifidx, u32 tmo) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_MAX_TX_DELAY, tmo); +} + +int hgic_fwctrl_get_sta_info(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mac, struct hgic_sta_info *info) +{ + return hgic_fwctrl_do_cmd(ctrl, ifidx, HGIC_CMD_GET_STA_INFO, mac, 6, (u8 *)info, sizeof(struct hgic_sta_info)); +} + +int hgic_fwctrl_get_signal(struct hgic_fwctrl *ctrl, u8 ifidx) +{ + return hgic_fwctrl_get_short_val(ctrl, ifidx, HGIC_CMD_GET_SIGNAL); +} + +int hgic_fwctrl_set_heartbeat_int(struct hgic_fwctrl *ctrl, u8 ifidx, u32 val) +{ + return hgic_fwctrl_set_int_val(ctrl, ifidx, HGIC_CMD_SET_HEARTBEAT_INT, val); } diff --git a/utils/fwctrl.h b/utils/fwctrl.h index c695308..cccb2fd 100644 --- a/utils/fwctrl.h +++ b/utils/fwctrl.h @@ -15,32 +15,6 @@ struct hgic_cmd_response { struct sk_buff *skb; }; -struct hgic_fwctrl_params { - u8 *country_code; - u8 *ssid; - u8 *bssid; - u8 *bssid_filter; - u8 *key_mgmt; - u8 *wpa_psk; - u8 *mcast_key; - u8 *mode; - u8 *mac_addr; - u8 *paired_stas; - u8 *chan_list; - u8 channel, chan_bw, bss_bw, tx_mcs, tx_bw; - u16 rts_threshold, frag_threshold; - u16 freq_start, freq_end; - u16 listen_interval; - u16 center_freq; - u16 beacon_int; - u16 ethertype; - u8 acs: 2, acs_tmo: 6; - u8 chan_cnt, txpower, primary_chan, agg_cnt; - u8 ps_mode, wkio_mode, ps_connect, ps_connect_roundup; - u32 dtim_period, bss_max_idle; - u16 aplost_time; -}; - struct hgic_fwctrl { struct device *dev; u16 cookie; @@ -50,9 +24,12 @@ struct hgic_fwctrl { struct sk_buff_head txq; /*fw ctrl packet tx queue*/ struct work_struct work; /*fw ctrl rx packet process work*/ struct workqueue_struct *wq; - struct hgic_fwctrl_params param; - struct work_struct flush_work; u8 qc_mode; + u8 radio_onoff; + struct hgic_fw_info *fwinfo; + struct hgic_bus *bus; + void (*schedule)(struct hgic_fwctrl *ctrl); + void (*rx_event)(struct hgic_fwctrl *ctrl, struct sk_buff *skb); }; /* @@ -68,129 +45,189 @@ int hgic_fwctrl_set_bytes(struct hgic_fwctrl *ctrl, int cmd_id, char *data, int */ u16 hgic_ctrl_cookie(struct hgic_fwctrl *ctrl); struct sk_buff *hgic_fwctrl_send_data(struct hgic_fwctrl *ctrl, struct sk_buff *skb, struct hgic_cmd_response *resp, u32 timeout); +int hgic_fwctrl_do_cmd(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 *in, u32 in_len, u8 *out, u32 out_size); +int hgic_fwctrl_set_byte(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 val); +int hgic_fwctrl_set_int_val(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u32 val); +int hgic_fwctrl_get_int_val(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id); +short hgic_fwctrl_get_short_val(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id); +int hgic_fwctrl_set_bytes(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 *data, u32 len); +int hgic_fwctrl_get_bytes(struct hgic_fwctrl *ctrl, u8 ifidx, u32 cmd_id, u8 *buff, u32 len); -void hgic_fwctrl_init(struct hgic_fwctrl *ctrl, void *dev); +void hgic_fwctrl_init(struct hgic_fwctrl *ctrl, void *dev, struct hgic_bus *bus); void hgic_fwctrl_release(struct hgic_fwctrl *ctrl); -void hgic_fwctrl_rx(struct hgic_fwctrl *ctrl, struct sk_buff *skb); -void hgic_rx_fw_event(struct hgic_fwctrl *ctrl, struct sk_buff *skb); -void hgic_schedule(struct hgic_fwctrl *ctrl); +void hgic_fwctrl_rx(struct hgic_fwctrl *ctrl, u8 *data, int len); void hgic_fwctrl_flush_param(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_testmode_cmd(struct hgic_fwctrl *ctrl, u8 *cmd, u32 size); -int hgic_fwctrl_get_status(struct hgic_fwctrl *ctrl, u8 *buff, u32 len); -int hgic_fwctrl_get_conn_state(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_get_fwinfo(struct hgic_fwctrl *ctrl, struct hgic_fw_info *info); -int hgic_fwctrl_set_countryregion(struct hgic_fwctrl *ctrl, u8 *country_code); -int hgic_fwctrl_set_ssid(struct hgic_fwctrl *ctrl, u8 *ssid); -int hgic_fwctrl_set_bssid(struct hgic_fwctrl *ctrl, u8 *bssid); -int hgic_fwctrl_set_channel(struct hgic_fwctrl *ctrl, u32 channel); -int hgic_fwctrl_set_bssid_filter(struct hgic_fwctrl *ctrl, u8 *filter); -int hgic_fwctrl_set_rts_threshold(struct hgic_fwctrl *ctrl, u32 rts_threshold); -int hgic_fwctrl_set_frag_threshold(struct hgic_fwctrl *ctrl, u32 frag_threshold); -int hgic_fwctrl_set_key_mgmt(struct hgic_fwctrl *ctrl, u8 *key_mgmt); -int hgic_fwctrl_set_wpa_psk(struct hgic_fwctrl *ctrl, u8 *psk); -int hgic_fwctrl_set_wbnat(struct hgic_fwctrl *ctrl, u32 enable); -int hgic_fwctrl_set_freq_range(struct hgic_fwctrl *ctrl, u32 freq_start, u32 freq_end, u32 bss_bw); -int hgic_fwctrl_set_bss_bw(struct hgic_fwctrl *ctrl, u8 bss_bw); -int hgic_fwctrl_set_tx_bw(struct hgic_fwctrl *ctrl, u8 tx_bw); -int hgic_fwctrl_set_tx_mcs(struct hgic_fwctrl *ctrl, u8 tx_mcs); -int hgic_fwctrl_set_acs(struct hgic_fwctrl *ctrl, u8 acs, u8 acs_tm); -int hgic_fwctrl_set_bgrssi(struct hgic_fwctrl *ctrl, u8 bgrssi); -int hgic_fwctrl_set_chan_list(struct hgic_fwctrl *ctrl, u16 *chan_list, u32 cnt); -int hgic_fwctrl_set_mode(struct hgic_fwctrl *ctrl, u8 *mode); -int hgic_fwctrl_set_paired_stas(struct hgic_fwctrl *ctrl, u8 *stas, u32 len); -int hgic_fwctrl_set_pairing(struct hgic_fwctrl *ctrl, u8 start); -int hgic_fwctrl_open_dev(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_close_dev(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_txpower(struct hgic_fwctrl *ctrl, u32 tx_power); -int hgic_fwctrl_get_txpower(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_listen_interval(struct hgic_fwctrl *ctrl, u32 listen_interval); -int hgic_fwctrl_set_center_freq(struct hgic_fwctrl *ctrl, u32 channel); -int hgic_fwctrl_set_tx_count(struct hgic_fwctrl *ctrl, u32 short_frm_tx_count, u32 long_frm_tx_count); -int hgic_fwctrl_set_key(struct hgic_fwctrl *ctrl, u8 cmd, u16 aid, u8 *key, u8 len); -int hgic_fwctrl_add_sta(struct hgic_fwctrl *ctrl, u16 aid, u8 *addr); -int hgic_fwctrl_del_sta(struct hgic_fwctrl *ctrl, u32 aid); -int hgic_fwctrl_set_primary_chan(struct hgic_fwctrl *ctrl, u8 primary_chan); -int hgic_fwctrl_set_aid(struct hgic_fwctrl *ctrl, u32 aid); -int hgic_fwctrl_set_mac(struct hgic_fwctrl *ctrl, u8 *mac); -int hgic_fwctrl_get_scan_list(struct hgic_fwctrl *ctrl, u8 *buff, u32 size); -int hgic_fwctrl_scan(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_txq_param(struct hgic_fwctrl *ctrl, u8 *txq, u32 size); +int hgic_fwctrl_testmode_cmd(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *cmd, u32 size); +int hgic_fwctrl_get_status(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, u32 len); +int hgic_fwctrl_get_conn_state(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_fwinfo(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_fw_info *info); +int hgic_fwctrl_set_countryregion(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *country_code); +int hgic_fwctrl_set_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid); +int hgic_fwctrl_set_bssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *bssid); +int hgic_fwctrl_set_channel(struct hgic_fwctrl *ctrl, u8 ifidx, u32 channel); +int hgic_fwctrl_set_bssid_filter(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *filter); +int hgic_fwctrl_set_rts_threshold(struct hgic_fwctrl *ctrl, u8 ifidx, u32 rts_threshold); +int hgic_fwctrl_set_frag_threshold(struct hgic_fwctrl *ctrl, u8 ifidx, u32 frag_threshold); +int hgic_fwctrl_set_key_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *key_mgmt); +int hgic_fwctrl_set_wpa_psk(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *psk); +int hgic_fwctrl_set_wbnat(struct hgic_fwctrl *ctrl, u8 ifidx, u32 enable); +int hgic_fwctrl_set_freq_range(struct hgic_fwctrl *ctrl, u8 ifidx, u32 freq_start, u32 freq_end, u32 bss_bw); +int hgic_fwctrl_set_bss_bw(struct hgic_fwctrl *ctrl, u8 ifidx, u8 bss_bw); +int hgic_fwctrl_set_tx_bw(struct hgic_fwctrl *ctrl, u8 ifidx, u8 tx_bw); +int hgic_fwctrl_set_tx_mcs(struct hgic_fwctrl *ctrl, u8 ifidx, u8 tx_mcs); +int hgic_fwctrl_set_acs(struct hgic_fwctrl *ctrl, u8 ifidx, u8 acs, u8 acs_tm); +int hgic_fwctrl_set_bgrssi(struct hgic_fwctrl *ctrl, u8 ifidx, u8 bgrssi); +int hgic_fwctrl_set_chan_list(struct hgic_fwctrl *ctrl, u8 ifidx, u16 *chan_list, u32 cnt); +int hgic_fwctrl_set_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mode); +int hgic_fwctrl_set_paired_stas(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *stas, u32 len); +int hgic_fwctrl_set_pairing(struct hgic_fwctrl *ctrl, u8 ifidx, u32 start); +int hgic_fwctrl_open_dev(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_close_dev(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_txpower(struct hgic_fwctrl *ctrl, u8 ifidx, u32 tx_power); +int hgic_fwctrl_get_txpower(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_listen_interval(struct hgic_fwctrl *ctrl, u8 ifidx, u32 listen_interval); +int hgic_fwctrl_set_center_freq(struct hgic_fwctrl *ctrl, u8 ifidx, u32 channel); +int hgic_fwctrl_set_tx_count(struct hgic_fwctrl *ctrl, u8 ifidx, u32 short_frm_tx_count, u32 long_frm_tx_count); +int hgic_fwctrl_set_key(struct hgic_fwctrl *ctrl, u8 ifidx, u8 cmd, u8 *addr, u8 *key, u8 len); +int hgic_fwctrl_add_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u16 aid, u8 *addr); +int hgic_fwctrl_del_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_set_primary_chan(struct hgic_fwctrl *ctrl, u8 ifidx, u8 primary_chan); +int hgic_fwctrl_set_aid(struct hgic_fwctrl *ctrl, u8 ifidx, u32 aid); +int hgic_fwctrl_set_mac(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mac_addr); +int hgic_fwctrl_get_scan_list(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, u32 size); +int hgic_fwctrl_scan(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_txq_param(struct hgic_fwctrl *ctrl, u8 ifidx, u8 ac, struct hgic_txq_param *param); +int hgic_fwctrl_set_user_edca(struct hgic_fwctrl *ctrl, u8 ifidx, u8 ac, struct hgic_txq_param *param); int hgic_fwctrl_get_temperature(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_enter_sleep(struct hgic_fwctrl *ctrl, u8 sleep); -int hgic_fwctrl_get_sta_list(struct hgic_fwctrl *ctrl, struct hgic_sta_info *sta_list, u32 size); -int hgic_fwctrl_set_beacon_int(struct hgic_fwctrl *ctrl, u32 beacon_int); -int hgic_fwctrl_get_ssid(struct hgic_fwctrl *ctrl, u8 *ssid, u32 size); -int hgic_fwctrl_get_wpapsk(struct hgic_fwctrl *ctrl, u8 *psk, u32 size); -int hgic_fwctrl_save_cfg(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_join_group(struct hgic_fwctrl *ctrl, u8 *addr, u8 aid); -int hgic_fwctrl_set_ethertype(struct hgic_fwctrl *ctrl, u16 type); -int hgic_fwctrl_get_sta_count(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_get_bss_bw(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_get_freq_range(struct hgic_fwctrl *ctrl, u32 *freq_start, u32 *freq_end, u32 *bss_bw); -int hgic_fwctrl_get_chan_list(struct hgic_fwctrl *ctrl, u16 *chan_list, u16 count); -int hgic_fwctrl_get_agg_cnt(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_agg_cnt(struct hgic_fwctrl *ctrl, u8 agg_cnt); -int hgic_fwctrl_set_ps_addr(struct hgic_fwctrl *ctrl, u32 dport); -int hgic_fwctrl_wakeup_sta(struct hgic_fwctrl *ctrl, u8 *addr); -int hgic_fwctrl_set_ps_heartbeat(struct hgic_fwctrl *ctrl, u32 ipaddr, u32 dport, u32 period, u32 hb_tmo); -int hgic_fwctrl_set_ps_heartbeat_resp(struct hgic_fwctrl *ctrl, u8 *data, u32 size); -int hgic_fwctrl_set_ps_wakeup_data(struct hgic_fwctrl *ctrl, u8 *data, u32 size); -int hgic_fwctrl_set_ps_connect(struct hgic_fwctrl *ctrl, u8 period, u8 roundup); -int hgic_fwctrl_set_ps_connect_count(struct hgic_fwctrl *ctrl, u8 try_cnt); -int hgic_fwctrl_set_ps_connect_time(struct hgic_fwctrl *ctrl, u32 time); -int hgic_fwctrl_get_ps_connect(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_get_ps_connect_count(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_get_ps_connect_time(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_radio_onoff(struct hgic_fwctrl *ctrl, u8 onoff); -int hgic_fwctrl_set_bss_max_idle(struct hgic_fwctrl *ctrl, u32 max_idle); -int hgic_fwctrl_set_wkio_mode(struct hgic_fwctrl *ctrl, u8 mode); -int hgic_fwctrl_set_ps_mode(struct hgic_fwctrl *ctrl, u8 mode); -int hgic_fwctrl_set_load_def(struct hgic_fwctrl *ctrl, u8 rst); -int hgic_fwctrl_disassoc_sta(struct hgic_fwctrl *ctrl, u8 *addr); -int hgic_fwctrl_set_dtim_period(struct hgic_fwctrl *ctrl, u32 period); -int hgic_fwctrl_set_aplost_time(struct hgic_fwctrl *ctrl, u32 aplost_time); -int hgic_fwctrl_get_wkreason(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_unpair(struct hgic_fwctrl *ctrl, u8 *addr); -int hgic_fwctrl_set_auto_chswitch(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_set_mcast_key(struct hgic_fwctrl *ctrl, u8 *mcast_key); -int hgic_fwctrl_set_reassoc_wkhost(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_set_wakeup_io(struct hgic_fwctrl *ctrl, u8 io, u8 edge); -int hgic_fwctrl_set_dbginfo_output(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_set_sysdbg(struct hgic_fwctrl *ctrl, u8 *cmd); -int hgic_fwctrl_set_autosleep_time(struct hgic_fwctrl *ctrl, u8 time); -int hgic_fwctrl_get_key_mgmt(struct hgic_fwctrl *ctrl, u8 *ssid, u32 size); -int hgic_fwctrl_get_bssid(struct hgic_fwctrl *ctrl, u8 *bssid); -int hgic_fwctrl_set_supper_pwr(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_set_repeater_ssid(struct hgic_fwctrl *ctrl, u8 *ssid); -int hgic_fwctrl_set_repeater_psk(struct hgic_fwctrl *ctrl, u8 *wpa_psk); -int hgic_fwctrl_set_auto_save(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_set_pair_autostop(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_send_cust_mgmt(struct hgic_fwctrl *ctrl, u8 *data, u32 len); -int hgic_fwctrl_get_battery_level(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_dcdc13v(struct hgic_fwctrl *ctrl, u8 enable); -int hgic_fwctrl_set_acktmo(struct hgic_fwctrl *ctrl, u32 tmo); -int hgic_fwctrl_get_module_type(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_pa_pwrctl_dis(struct hgic_fwctrl *ctrl, u8 dis); -int hgic_fwctrl_set_dhcpc(struct hgic_fwctrl *ctrl, u8 en); -int hgic_fwctrl_get_dhcpc_result(struct hgic_fwctrl *ctrl, u8* buff, int len); -int hgic_fwctrl_set_wkdata_mask(struct hgic_fwctrl *ctrl, u16 offset, u8 *mask, u8 mask_len); -int hgic_fwctrl_get_wkdata_buff(struct hgic_fwctrl *ctrl, u8* buff, int len); -int hgic_fwctrl_get_disassoc_reason(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_wkdata_save(struct hgic_fwctrl *ctrl, u8 save); -int hgic_fwctrl_set_cust_driver_data(struct hgic_fwctrl *ctrl, u8 *data, u32 len); -int hgic_fwctrl_set_mcast_txparam(struct hgic_fwctrl *ctrl, struct hgic_mcast_txparam *param); -int hgic_fwctrl_set_freqinfo(struct hgic_fwctrl *ctrl, u8 *data, u32 len); -int hgic_fwctrl_reset_sta(struct hgic_fwctrl *ctrl, u8 *addr); -int hgic_fwctrl_set_ant_auto(struct hgic_fwctrl *ctrl, u8 en); -int hgic_fwctrl_select_ant(struct hgic_fwctrl *ctrl, u8 ant); -int hgic_fwctrl_get_ant_sel(struct hgic_fwctrl *ctrl); -int hgic_fwctrl_set_wkhost_reasons(struct hgic_fwctrl *ctrl, u8 *reasons, u8 len); -int hgic_fwctrl_set_mac_filter(struct hgic_fwctrl *ctrl, u8 en); -int hgic_fwctrl_set_atcmd(struct hgic_fwctrl *ctrl, char *atcmd); -int hgic_fwctrl_set_roaming(struct hgic_fwctrl *ctrl, u8 en, u8 same_freq); -int hgic_fwctrl_set_ap_hide(struct hgic_fwctrl *ctrl, u8 hide); -int hgic_fwctrl_set_frm_tx_maxcnt(struct hgic_fwctrl *ctrl, u8 txcnt); -int hgic_fwctrl_set_assert_holdup(struct hgic_fwctrl *ctrl, u8 holdup); +int hgic_fwctrl_enter_sleep(struct hgic_fwctrl *ctrl, u8 ifidx, u16 sleep, u32 sleep_ms); +int hgic_fwctrl_get_sta_list(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_sta_info *sta_list, u32 size); +int hgic_fwctrl_set_beacon_int(struct hgic_fwctrl *ctrl, u8 ifidx, u32 beacon_int); +int hgic_fwctrl_get_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid, u32 size); +int hgic_fwctrl_get_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mode, u32 size); +int hgic_fwctrl_get_wpapsk(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *psk, u32 size); +int hgic_fwctrl_save_cfg(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_join_group(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr, u8 aid); +int hgic_fwctrl_set_ethertype(struct hgic_fwctrl *ctrl, u8 ifidx, u16 type); +int hgic_fwctrl_get_sta_count(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_bss_bw(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_freq_range(struct hgic_fwctrl *ctrl, u8 ifidx, u32 *freq_start, u32 *freq_end, u32 *bss_bw); +int hgic_fwctrl_get_chan_list(struct hgic_fwctrl *ctrl, u8 ifidx, u16 *chan_list, u16 count); +int hgic_fwctrl_get_agg_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *agg, u8 size); +int hgic_fwctrl_set_agg_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 agg[2]); +int hgic_fwctrl_set_ps_addr(struct hgic_fwctrl *ctrl, u8 ifidx, u32 dport); +int hgic_fwctrl_wakeup_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_set_ps_heartbeat(struct hgic_fwctrl *ctrl, u8 ifidx, u32 ipaddr, u32 dport, u32 period, u32 hb_tmo); +int hgic_fwctrl_set_ps_heartbeat_resp(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 size); +int hgic_fwctrl_set_ps_wakeup_data(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 size); +int hgic_fwctrl_set_ps_connect(struct hgic_fwctrl *ctrl, u8 ifidx, u8 period, u8 roundup); +int hgic_fwctrl_set_ps_connect_count(struct hgic_fwctrl *ctrl, u8 ifidx, u8 try_cnt); +int hgic_fwctrl_set_ps_connect_time(struct hgic_fwctrl *ctrl, u8 ifidx, u32 time); +int hgic_fwctrl_get_ps_connect(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_ps_connect_count(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_ps_connect_time(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_radio_onoff(struct hgic_fwctrl *ctrl, u8 ifidx, u8 onoff); +int hgic_fwctrl_set_bss_max_idle(struct hgic_fwctrl *ctrl, u8 ifidx, u32 max_idle); +int hgic_fwctrl_set_wkio_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 mode); +int hgic_fwctrl_set_ps_mode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 mode); +int hgic_fwctrl_set_load_def(struct hgic_fwctrl *ctrl, u8 ifidx, u8 rst); +int hgic_fwctrl_disassoc_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_set_dtim_period(struct hgic_fwctrl *ctrl, u8 ifidx, u32 period); +int hgic_fwctrl_set_aplost_time(struct hgic_fwctrl *ctrl, u8 ifidx, u32 aplost_time); +int hgic_fwctrl_get_wkreason(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_unpair(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_set_auto_chswitch(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_mcast_key(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mcast_key); +int hgic_fwctrl_set_reassoc_wkhost(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_wakeup_io(struct hgic_fwctrl *ctrl, u8 ifidx, u8 io, u8 edge); +int hgic_fwctrl_set_dbginfo_output(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_sysdbg(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *cmd); +int hgic_fwctrl_set_autosleep_time(struct hgic_fwctrl *ctrl, u8 ifidx, u8 time); +int hgic_fwctrl_get_key_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid, u32 size); +int hgic_fwctrl_get_bssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *bssid, u32 len); +int hgic_fwctrl_set_super_pwr(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_repeater_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *ssid); +int hgic_fwctrl_set_repeater_psk(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *wpa_psk); +int hgic_fwctrl_set_auto_save(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_pair_autostop(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_send_cust_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_send_mgmtframe(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_get_battery_level(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_dcdc13v(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_acktmo(struct hgic_fwctrl *ctrl, u8 ifidx, u32 tmo); +int hgic_fwctrl_get_module_type(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_pa_pwrctl_dis(struct hgic_fwctrl *ctrl, u8 ifidx, u8 dis); +int hgic_fwctrl_set_dhcpc(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_get_dhcpc_result(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, int len); +int hgic_fwctrl_set_wkdata_mask(struct hgic_fwctrl *ctrl, u8 ifidx, u16 offset, u8 *mask, u8 mask_len); +int hgic_fwctrl_get_wkdata_buff(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *buff, int len); +int hgic_fwctrl_get_disassoc_reason(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_wkdata_save(struct hgic_fwctrl *ctrl, u8 ifidx, u8 save); +int hgic_fwctrl_set_cust_driver_data(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_set_mcast_txparam(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_mcast_txparam *param); +int hgic_fwctrl_set_freqinfo(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_reset_sta(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_set_ant_auto(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_select_ant(struct hgic_fwctrl *ctrl, u8 ifidx, u8 ant); +int hgic_fwctrl_get_ant_sel(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_wkhost_reasons(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *reasons, u8 len); +int hgic_fwctrl_set_mac_filter(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_set_atcmd(struct hgic_fwctrl *ctrl, u8 ifidx, char *atcmd); +int hgic_fwctrl_set_roaming(struct hgic_fwctrl *ctrl, u8 ifidx, s8 *vals, u8 count); +int hgic_fwctrl_set_ap_hide(struct hgic_fwctrl *ctrl, u8 ifidx, u8 hide); +int hgic_fwctrl_set_frm_tx_maxcnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 txcnt); +int hgic_fwctrl_set_assert_holdup(struct hgic_fwctrl *ctrl, u8 ifidx, u8 holdup); +int hgic_fwctrl_set_ap_psmode_en(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_set_dupfilter_en(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_set_1v1_m2u_dis(struct hgic_fwctrl *ctrl, u8 ifidx, u8 dis); +int hgic_fwctrl_set_psconnect_dis(struct hgic_fwctrl *ctrl, u8 ifidx, u8 dis); +int hgic_fwctrl_set_blenc_en(struct hgic_fwctrl *ctrl, u8 ifidx, u8 data[3]); +int hgic_fwctrl_blenc_send_data(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_reset(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_hwscan(struct hgic_fwctrl *ctrl, u8 ifidx, u16 period, u16 interval, u16 chan, u16 max); +int hgic_fwctrl_get_txq_param(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_txq_param param[4]); +int hgic_fwctrl_set_promisc(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_fix_txrate(struct hgic_fwctrl *ctrl, u8 ifidx, u32 txrate); +int hgic_fwctrl_set_nav_max(struct hgic_fwctrl *ctrl, u8 ifidx, u32 nav_max); +int hgic_fwctrl_clear_nav(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_cca_param(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_cca_ctl *cca); +int hgic_fwctrl_set_tx_modulation_gain(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *gain_table, u32 size); +int hgic_fwctrl_get_nav(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_send_hci_data(struct hgic_fwctrl *ctrl, u8 type, u8 *data, u32 len); +int hgic_fwctrl_set_beacon_start(struct hgic_fwctrl *ctrl, u8 ifidx, u8 start); +int hgic_fwctrl_ble_open(struct hgic_fwctrl *ctrl, u8 ifidx, u8 open); +int hgic_fwctrl_get_bgrssi(struct hgic_fwctrl *ctrl, u8 ifidx, u8 channel, s8 resp[3]); +int hgic_fwctrl_blenc_set_advdata(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_blenc_set_scanresp(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *data, u32 len); +int hgic_fwctrl_blenc_set_devaddr(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_blenc_set_advinterval(struct hgic_fwctrl *ctrl, u8 ifidx, u32 interval); +int hgic_fwctrl_blenc_start_adv(struct hgic_fwctrl *ctrl, u8 ifidx, u32 en); +int hgic_fwctrl_set_rts_duration(struct hgic_fwctrl *ctrl, u8 ifidx, int duration); +int hgic_fwctrl_set_disable_print(struct hgic_fwctrl *ctrl, u8 ifidx, int dis); +int hgic_fwctrl_set_conn_paironly(struct hgic_fwctrl *ctrl, u8 ifidx, int en); +int hgic_fwctrl_get_center_freq(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_wait_psmode(struct hgic_fwctrl *ctrl, u8 ifidx, u8 wait_psmode); +int hgic_fwctrl_set_diffcust_conn(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_set_ap_chan_switch(struct hgic_fwctrl *ctrl, u8 ifidx, u8 chan, u8 counter); +int hgic_fwctrl_set_cca_for_ce(struct hgic_fwctrl *ctrl, u8 ifidx, u8 en); +int hgic_fwctrl_set_standby(struct hgic_fwctrl *ctrl, u8 ifidx, u8 channel, u32 sleep_period); +int hgic_fwctrl_set_rtc(struct hgic_fwctrl *ctrl, u8 ifidx, u32 rtc); +int hgic_fwctrl_get_rtc(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *rtc); +int hgic_fwctrl_set_apep_padding(struct hgic_fwctrl *ctrl, u8 ifidx, int en); +int hgic_fwctrl_get_reason_code(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_status_code(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_get_acs_result(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_acs_result *result, u8 size); +int hgic_fwctrl_set_watchdog(struct hgic_fwctrl *ctrl, u8 ifidx, u8 enable); +int hgic_fwctrl_set_retry_fallback_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, u8 cnt); +int hgic_fwctrl_set_fallback_mcs(struct hgic_fwctrl *ctrl, u8 ifidx, struct hgic_fallback_mcs *mcs); +int hgic_fwctrl_get_xosc(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_xosc(struct hgic_fwctrl *ctrl, u8 ifidx, int xosc); +int hgic_fwctrl_get_freq_offset(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *addr); +int hgic_fwctrl_set_freq_cali_period(struct hgic_fwctrl *ctrl, u8 ifidx, u16 cali_period); +int hgic_fwctrl_set_blenc_adv_filter(struct hgic_fwctrl *ctrl, u8 ifidx, u32 filter); +int hgic_fwctrl_set_max_tx_delay(struct hgic_fwctrl *ctrl, u8 ifidx, u32 tmo); +int hgic_fwctrl_get_sta_info(struct hgic_fwctrl *ctrl, u8 ifidx, u8 *mac, struct hgic_sta_info *info); +int hgic_fwctrl_get_signal(struct hgic_fwctrl *ctrl, u8 ifidx); +int hgic_fwctrl_set_heartbeat_int(struct hgic_fwctrl *ctrl, u8 ifidx, u32 val); #endif diff --git a/utils/fwdl.c b/utils/fwdl.c index 0629215..03b315a 100644 --- a/utils/fwdl.c +++ b/utils/fwdl.c @@ -14,9 +14,9 @@ #endif #include "../hgic_def.h" -#include "fwinfo.h" #include "fwctrl.h" #include "fwdl.h" +#include "fwinfo.h" #include "utils.h" #define BOOT_CMD_KEY "@huge-ic" @@ -37,7 +37,7 @@ u32 hgic_bootdl_init(struct hgic_bootdl *hg_fwdl, struct hgic_bus *bus, struct h { if (hg_fwdl == NULL) { printk("%s:%d:Input para error!\n", __FUNCTION__, __LINE__); - return EINVAL; + return -EINVAL; } hgic_dbg("Enter ...\n"); @@ -65,6 +65,7 @@ static struct sk_buff *hgic_bootdl_alloc_cmd_skb(struct hgic_bootdl *hg, u8 cmd_ return skb; } cmd_hdr = (struct hgic_bootdl_cmd_hdr *)skb->data; + memset(cmd_hdr, 0, sizeof(struct hgic_bootdl_cmd_hdr)); cmd_hdr->cmd = cmd_id; cmd_hdr->cmd_len = 12; cmd_hdr->cmd_flag = hg->checksum_mode; @@ -111,15 +112,13 @@ struct sk_buff *hgic_bootdl_send_cmd(struct hgic_bootdl *hg_fwdl, struct sk_buff struct hgic_bootdl_cmd_hdr *hdr = NULL; struct hgic_cmd_response resp; - hdr = (struct hgic_bootdl_cmd_hdr *)skb->data; - hdr->hdr.magic = HGIC_HDR_TX_MAGIC; - hdr->hdr.type = HGIC_HDR_TYPE_BOOTDL; - hdr->hdr.length = skb->len; - hdr->hdr.cookie = hgic_ctrl_cookie(hg_fwdl->ctrl); - - //printk("hg_fwdl->ctrl=%p\r\n", hg_fwdl->ctrl); memset(&resp, 0, sizeof(resp)); - resp.cookie = hdr->hdr.cookie; + resp.cookie = hgic_ctrl_cookie(hg_fwdl->ctrl); + hdr = (struct hgic_bootdl_cmd_hdr *)skb->data; + hdr->hdr.magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + hdr->hdr.length = cpu_to_le16(skb->len); + hdr->hdr.cookie = cpu_to_le16(resp.cookie); + hdr->hdr.type = HGIC_HDR_TYPE_BOOTDL; hg_fwdl->last_cookie = resp.cookie; return hgic_fwctrl_send_data(hg_fwdl->ctrl, skb, &resp, timeout); } @@ -129,11 +128,12 @@ struct sk_buff *hgic_bootdl_send_data(struct hgic_bootdl *hg_fwdl, struct sk_buf struct hgic_bootdl_cmd_hdr *hdr = NULL; struct hgic_cmd_response resp; - hdr = (struct hgic_bootdl_cmd_hdr *)skb_push(skb, sizeof(struct hgic_bootdl_cmd_hdr)); - hdr->hdr.magic = HGIC_HDR_TX_MAGIC; - hdr->hdr.type = HGIC_HDR_TYPE_BOOTDL_DATA; memset(&resp, 0, sizeof(struct hgic_cmd_response)); resp.cookie = hg_fwdl->last_cookie; + hdr = (struct hgic_bootdl_cmd_hdr *)skb_push(skb, sizeof(struct hgic_bootdl_cmd_hdr)); + memset(hdr, 0, sizeof(struct hgic_bootdl_cmd_hdr)); + hdr->hdr.magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + hdr->hdr.type = HGIC_HDR_TYPE_BOOTDL_DATA; return hgic_fwctrl_send_data(hg_fwdl->ctrl, skb, &resp, timeout); } @@ -199,7 +199,7 @@ static int hgic_bootdl_send_fw(struct hgic_bootdl *hg, struct sk_buff *skb, u32 if (skb == NULL || hg == NULL) { hgic_dbg("input para error\n"); - return EINVAL; + return -EINVAL; } resp_skb = hgic_bootdl_send_data(hg, skb, tmo); @@ -215,7 +215,7 @@ static int hgic_bootdl_send_fw(struct hgic_bootdl *hg, struct sk_buff *skb, u32 return ret; } else { hgic_dbg("send fw data error, no resp!\n"); - return EFAULT; + return -EFAULT; } } @@ -232,6 +232,7 @@ static int hgic_bootdl_send_cmd_tmo(struct hgic_bootdl *hg, unsigned char cmd = 0; if (hg == NULL || skb == NULL) { + if(skb) kfree_skb(skb); return -EINVAL; } @@ -266,11 +267,11 @@ int hgic_bootdl_cmd_enter(struct hgic_bootdl *hg) skb = hgic_bootdl_alloc_cmd_skb(hg, HG_BOOTDL_CMD_ENTER); if (skb) { cmd_hdr = (struct hgic_bootdl_cmd_hdr *)skb->data; - memcpy((void *)cmd_hdr->addr, (void *)BOOT_CMD_KEY, sizeof(cmd_hdr->addr)); + memcpy((void *)cmd_hdr->addr, (void *)BOOT_CMD_KEY, BOOT_CMD_KEY_SIZE); cmd_hdr->check = hgic_bootdl_cmd_check_val(hg->checksum_mode, (u8 *)&cmd_hdr->cmd, 11); } else { hgic_err("malloc skb failed!\n"); - return ENOMEM; + return -ENOMEM; } ret = hgic_bootdl_send_cmd_tmo(hg, skb, HG_BOOTDL_CMD_NORMAL_TMO, NULL); if (ret == 0 || ret == HG_BOOTDL_RSP_ERR_IN_FW) { @@ -304,7 +305,7 @@ static int hgic_bootdl_cmd_write_memory(struct hgic_bootdl *hg, u32 write_addr, cmd_hdr->check = hgic_bootdl_cmd_check_val(hg->checksum_mode, (u8 *)&cmd_hdr->cmd, 11); } else { hgic_dbg("malloc skb failed!\n"); - return ENOMEM; + return -ENOMEM; } return hgic_bootdl_send_cmd_tmo(hg, skb, HG_BOOTDL_CMD_NORMAL_TMO, NULL); } @@ -335,7 +336,7 @@ static int hgic_bootdl_cmd_run(struct hgic_bootdl *hg) cmd_hdr->check = hgic_bootdl_cmd_check_val(hg->checksum_mode, (u8 *)&cmd_hdr->cmd, 11); } else { hgic_dbg("malloc skb failed!\n"); - return ENOMEM; + return -ENOMEM; } return hgic_bootdl_send_cmd_tmo(hg, skb, HG_BOOTDL_CMD_NORMAL_TMO, NULL); } @@ -343,17 +344,10 @@ static int hgic_bootdl_cmd_run(struct hgic_bootdl *hg) static unsigned int hgic_bootdl_fragment_proc(struct hgic_bootdl *hg, unsigned int copy_len) { unsigned int xfer_len = 0; - unsigned int blk = 0; if (hg->bus->type == HGIC_BUS_SDIO) { if (copy_len < hg->frag_size) { - blk = copy_len / hg->bus->blk_size; - if (blk) { - xfer_len = blk * hg->bus->blk_size; - } else { - //xfer_len = copy_len; - xfer_len = ALIGN(copy_len, 4); - } + xfer_len = ALIGN(copy_len, hg->bus->blk_size); } else { xfer_len = hg->frag_size; } @@ -368,14 +362,14 @@ int hgic_bootdl_download(struct hgic_bootdl *hg, const char *fw_path) int ret = 0; struct sk_buff *skb = NULL; u32 write_addr = 0; - u32 copy_len = 0; + s32 copy_len = 0; u32 xfer_len = 0; u32 addr_offset = 0; char *data = NULL; if (hg == NULL || fw_path == NULL) { printk("%s,%d:input para error!\n", __FUNCTION__, __LINE__); - return EINVAL; + return -EINVAL; } hgic_enter(); @@ -388,7 +382,7 @@ int hgic_bootdl_download(struct hgic_bootdl *hg, const char *fw_path) copy_len = hg->fw_info.fw_len; write_addr = hg->fw_info.write_addr; data = (char *)(hg->fw->data + hg->fw_info.hdr_len); - while (copy_len) { + while (copy_len > 0) { //xfer_len = copy_len > hg->frag_size ? hg->frag_size : copy_len; xfer_len = hgic_bootdl_fragment_proc(hg, copy_len); skb = dev_alloc_skb(xfer_len + sizeof(struct hgic_bootdl_cmd_hdr)); @@ -423,6 +417,8 @@ int hgic_bootdl_download(struct hgic_bootdl *hg, const char *fw_path) ret = hgic_bootdl_cmd_run(hg); if (ret) { printk("%s: Cmd run failed:%d\r\n", __FUNCTION__, ret); + } else { + hgic_dbg("Cmd run success!\n"); } __finish: if (hg->fw) { diff --git a/utils/fwdl.h b/utils/fwdl.h index 445f1b1..2617c76 100644 --- a/utils/fwdl.h +++ b/utils/fwdl.h @@ -75,7 +75,6 @@ struct hgic_bootdl { u8 checksum_mode; u16 last_cookie; u32 frag_size; - //struct sk_buff_head fw_dataq; struct hgic_bus *bus; struct hgic_fwctrl *ctrl; struct firmware *fw; diff --git a/utils/hgic_fmac.c b/utils/hgic_fmac.c deleted file mode 100644 index 2df0dd6..0000000 --- a/utils/hgic_fmac.c +++ /dev/null @@ -1,1141 +0,0 @@ -/** - ****************************************************************************** - * @file hgic_fmac.c - * @author HUGE-IC Application Team - * @version V1.0.0 - * @date 2021-06-23 - * @brief fmac api for application. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT 2021 HUGE-IC

- * - ****************************************************************************** - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define fmac_dbg(fmt, ...) printf("%s:%d::"fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__) - -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" -#define MACARG(a) (a)[0]&0xff, (a)[1]&0xff, (a)[2]&0xff, (a)[3]&0xff, (a)[4]&0xff, (a)[5]&0xff -#define IPSTR "%d.%d.%d.%d" -#define IPARG(a) ((a)>>24)&0xff, ((a)>>16)&0xff, ((a)>>8)&0xff, (a)&0xff -#define MAC2STR(mac, str) (sprintf((str), MACSTR, MACARG(mac))) -#define STR_EQ(s1,s2) (strcmp(s1,s2)==0) -#define MAC_EQ(a1,a2) (memcmp(a1,a2,6)==0) - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; - -enum FMAC_CONNECT_REASON { - FMAC_ASSOC_SUCCESS = 0, - FMAC_ASSOC_REFUSED = 1, - FMAC_ASSOC_DENIED_NO_MORE_STAS = 17, - FMAC_ASSOC_DENIED_INSUFFICIENT_BANDWIDTH = 33, - FMAC_ASSOC_REFUSED_AP_OUT_OF_MEMORY = 93, - FMAC_ASSOC_NO_AP = 0xff -}; - -struct hgic_tx_info { - uint8 band; - uint8 tx_bw; - uint8 tx_mcs; - uint8 freq_idx: 5, antenna: 3; - uint32 tx_flags; - uint16 tx_flags2; - uint8 priority; - uint8 tx_power; -}; - -struct hgic_freqinfo { - unsigned char bss_bw, chan_cnt; - unsigned short freq_start, freq_end; - unsigned short chan_list[16]; -}; - -enum HGIC_MODULE_TYPE{ - HGIC_MODULE_TYPE_700M = 1, - HGIC_MODULE_TYPE_900M = 2, - HGIC_MODULE_TYPE_860M = 3, - HGIC_MODULE_TYPE_810M = 5, -}; - -struct hgic_module_hwinfo{ - union{ - struct{ - unsigned char type; - unsigned char saw:1, rev:7; - }; - unsigned short v; - }; -}; - -int hgic_str2mac(char *mac_str, unsigned char *mac) -{ - int tmp[6]; - if (mac_str && mac) { - memset(tmp, 0, sizeof(tmp)); - memset(mac, 0, 6); - if (6 == sscanf(mac_str, MACSTR, &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5])) { - mac[0] = (unsigned char)tmp[0]; - mac[1] = (unsigned char)tmp[1]; - mac[2] = (unsigned char)tmp[2]; - mac[3] = (unsigned char)tmp[3]; - mac[4] = (unsigned char)tmp[4]; - mac[5] = (unsigned char)tmp[5]; - return 1; - } - } - return 0; -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -/* iwpriv api */ -int hgic_iwpriv_read(char *buff, int len) -{ - int ret = 0; - int fd = -1; - - if (buff == NULL || len <= 0) { - return 0; - } - memset(buff, 0, len); - fd = open("/proc/hgic/iwpriv", O_RDONLY); - if (fd != -1) { - ret = read(fd, buff, len); - close(fd); - } - return ret; -} - -int hgic_iwpriv_write(char *buff, int len) -{ - int ret = 0; - int fd = -1; - - if (buff == NULL || len <= 0) { - return 0; - } - fd = open("/proc/hgic/iwpriv", O_WRONLY); - if (fd != -1) { - ret = write(fd, buff, len); - close(fd); - } - return ret > 0; -} - -int hgic_iwpriv_do(char *ifname, char *cmd, char *args) -{ - int ret = 0; - int fd = -1; - char buff[512]; - char *ptr = NULL; - - memset(buff, 0, sizeof(buff)); - if (args) { - sprintf(buff, "%s %s %s", ifname, cmd, args); - } else { - sprintf(buff, "%s %s", ifname, cmd); - } - if (hgic_iwpriv_write(buff, strlen(buff))) { - if (STR_EQ(cmd, "set") || STR_EQ(cmd, "scan") || STR_EQ(cmd, "save")) { - if (hgic_iwpriv_read(buff, sizeof(buff)) && strstr(buff, "OK")) { - ret = 1; - } else { - ptr = strstr(buff, "error:"); - if (ptr) { - ret = atoi(ptr + 6); - fmac_dbg("error: %s\r\n", strerror(ret)); - } - } - } - } - return ret; -} - -int hgic_iwpriv_set_int(char *ifname, char *name, int value) -{ - char arg[64]; - memset(arg, 0, sizeof(arg)); - sprintf(arg, "%s=%d", name, value); - return hgic_iwpriv_do(ifname, "set", arg); -} - -int hgic_iwpriv_set_mac(char *ifname, char *name, char *mac) -{ - char arg[64]; - memset(arg, 0, sizeof(arg)); - sprintf(arg, "%s="MACSTR, name, MACARG(mac)); - return hgic_iwpriv_do(ifname, "set", arg); -} - -int hgic_iwpriv_set_ints(char *ifname, char *name, int cnt, ...) -{ - int i = 0; - int val = 0; - char arg[512]; - char *ptr = arg; - va_list argptr; - - memset(arg, 0, sizeof(arg)); - sprintf(ptr, "%s=", name); - ptr += strlen(ptr); - - va_start(argptr, cnt); - for (i = 0; i < cnt; i++) { - val = va_arg(argptr, int); - sprintf(ptr, (i == 0 ? "%d" : ",%d"), val); - ptr += strlen(ptr); - } - va_end(argptr); - return hgic_iwpriv_do(ifname, "set", arg); -} - -int hgic_iwpriv_set_intarray(char *ifname, char *name, int *values, int cnt) -{ - int i = 0; - char arg[512]; - char *ptr = arg; - - memset(arg, 0, sizeof(arg)); - sprintf(ptr, "%s=", name); - ptr += strlen(ptr); - - for (i = 0; i < cnt; i++) { - sprintf(ptr, (i == 0 ? "%d" : ",%d"), values[i]); - ptr += strlen(ptr); - } - return hgic_iwpriv_do(ifname, "set", arg); -} - -int hgic_iwpriv_set_bytes(char *ifname, char *name, char *value) -{ - char arg[512]; - memset(arg, 0, sizeof(arg)); - sprintf(arg, "%s=%s", name, value); - return hgic_iwpriv_do(ifname, "set", arg); -} - -int hgic_iwpriv_get_int(char *ifname, char *name) -{ - char buff[8]; - hgic_iwpriv_do(ifname, "get", name); - hgic_iwpriv_read(buff, 8); - return atoi(buff); -} - -int hgic_iwpriv_get_bytes(char *ifname, char *name, char *buff, int count) -{ - hgic_iwpriv_do(ifname, "get", name); - return hgic_iwpriv_read(buff, count); -} - -int hgic_iwpriv_get_mac(char *ifname, char *name, char *mac) -{ - char str[32]; - hgic_iwpriv_do(ifname, "get", name); - hgic_iwpriv_read(str, sizeof(str)); - return hgic_str2mac(str, mac); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////// -int hgic_iwpriv_set_ssid(char *ifname, char *ssid) -{ - return hgic_iwpriv_set_bytes(ifname, "ssid", ssid); -} -int hgic_iwpriv_set_bssid(char *ifname, char *bssid) -{ - return hgic_iwpriv_set_mac(ifname, "bssid", bssid); -} -int hgic_iwpriv_set_channel(char *ifname, int channel) -{ - return hgic_iwpriv_set_int(ifname, "channel", channel); -} -int hgic_iwpriv_set_keymgmt(char *ifname, char *key_mgmt) -{ - return hgic_iwpriv_set_bytes(ifname, "key_mgmt", key_mgmt); -} -int hgic_iwpriv_set_wpapsk(char *ifname, char *wpa_psk) -{ - return hgic_iwpriv_set_bytes(ifname, "wpa_psk", wpa_psk); -} -int hgic_iwpriv_set_freqrange(char *ifname, int freq_start, int freq_end, int bw) -{ - return hgic_iwpriv_set_ints(ifname, "freq_range", 3, freq_start, freq_end, bw); -} -int hgic_iwpriv_set_bss_bw(char *ifname, int bss_bw) -{ - return hgic_iwpriv_set_int(ifname, "bss_bw", bss_bw); -} -int hgic_iwpriv_set_tx_bw(char *ifname, int tx_bw) -{ - return hgic_iwpriv_set_int(ifname, "tx_bw", tx_bw); -} -int hgic_iwpriv_set_tx_mcs(char *ifname, int tx_mcs) -{ - return hgic_iwpriv_set_int(ifname, "tx_mcs", tx_mcs); -} -int hgic_iwpriv_set_acs(char *ifname, int start, int tmo) -{ - return hgic_iwpriv_set_ints(ifname, "acs", 2, start, tmo); -} -int hgic_iwpriv_set_chan_list(char *ifname, int *chan_list, int chan_count) -{ - return hgic_iwpriv_set_intarray(ifname, "chan_list", chan_list, chan_count); -} -int hgic_iwpriv_set_mode(char *ifname, char *mode) -{ - return hgic_iwpriv_set_bytes(ifname, "mode", mode); -} -int hgic_iwpriv_set_paired_stas(char *ifname, char *paired_stas) -{ - return hgic_iwpriv_set_bytes(ifname, "paired_stas", paired_stas); -} -int hgic_iwpriv_set_pairing(char *ifname, int start) -{ - return hgic_iwpriv_set_int(ifname, "pairing", start); -} -int hgic_iwpriv_set_beacon_int(char *ifname, int beacon_int) -{ - return hgic_iwpriv_set_int(ifname, "beacon_int", beacon_int); -} -int hgic_iwpriv_set_radio_off(char *ifname, int off) -{ - return hgic_iwpriv_set_int(ifname, "radio_off", off); -} -int hgic_iwpriv_set_join_group(char *ifname, char *mcast_addr, int aid) -{ - char arg[64]; - memset(arg, 0, sizeof(arg)); - sprintf(arg, "join_group="MACSTR",%d", MACARG(mcast_addr), aid); - return hgic_iwpriv_do(ifname, "set", arg); -} -int hgic_iwpriv_set_txpower(char *ifname, int txpower) -{ - return hgic_iwpriv_set_int(ifname, "txpower", txpower); -} -int hgic_iwpriv_set_ps_connect(char *ifname, int period, int roundup) -{ - return hgic_iwpriv_set_ints(ifname, "ps_connect", 2, period, roundup); -} -int hgic_iwpriv_set_bss_max_idle(char *ifname, int bss_max_idle) -{ - return hgic_iwpriv_set_int(ifname, "bss_max_idle", bss_max_idle); -} -int hgic_iwpriv_set_wkio_mode(char *ifname, int wkio_mode) -{ - return hgic_iwpriv_set_int(ifname, "wkio_mode", wkio_mode); -} -int hgic_iwpriv_set_dtim_period(char *ifname, int dtim_period) -{ - return hgic_iwpriv_set_int(ifname, "dtim_period", dtim_period); -} -int hgic_iwpriv_set_ps_mode(char *ifname, int ps_mode) -{ - return hgic_iwpriv_set_int(ifname, "ps_mode", ps_mode); -} -int hgic_iwpriv_set_aplost_time(char *ifname, int aplost_time) -{ - return hgic_iwpriv_set_int(ifname, "aplost_time", aplost_time); -} -int hgic_iwpriv_unpair(char *ifname, char *mac) -{ - return hgic_iwpriv_set_mac(ifname, "unpair", mac); -} -int hgic_iwpriv_scan(char *ifname) -{ - return hgic_iwpriv_do(ifname, "scan", NULL); -} -int hgic_iwpriv_save(char *ifname) -{ - return hgic_iwpriv_do(ifname, "save", NULL); -} -int hgic_iwpriv_set_auto_chswitch(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "auto_chswitch", enable); -} -int hgic_iwpriv_set_mcast_key(char *ifname, char *mcast_key) -{ - return hgic_iwpriv_set_bytes(ifname, "mcast_key", mcast_key); -} -int hgic_iwpriv_set_reassoc_wkhost(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "reassoc_wkhost", enable); -} -int hgic_iwpriv_set_wakeup_io(char *ifname, int wakeup_io) -{ - return hgic_iwpriv_set_int(ifname, "wakeup_io", wakeup_io); -} -int hgic_iwpriv_set_dbginfo(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "dbginfo", enable); -} -int hgic_iwpriv_set_sysdbg(char *ifname, char *sysdbg) -{ - return hgic_iwpriv_set_bytes(ifname, "sysdbg", sysdbg); -} -int hgic_iwpriv_set_primary_chan(char *ifname, int primary_chan) -{ - return hgic_iwpriv_set_int(ifname, "primary_chan", primary_chan); -} -int hgic_iwpriv_set_autosleep_time(char *ifname, int autosleep_time) -{ - return hgic_iwpriv_set_int(ifname, "autosleep_time", autosleep_time); -} -int hgic_iwpriv_set_supper_pwr(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "supper_pwr", enable); -} -int hgic_iwpriv_set_r_ssid(char *ifname, char *r_ssid) -{ - return hgic_iwpriv_set_bytes(ifname, "r_ssid", r_ssid); -} -int hgic_iwpriv_set_r_psk(char *ifname, char *r_psk) -{ - return hgic_iwpriv_set_bytes(ifname, "r_psk", r_psk); -} -int hgic_iwpriv_set_auto_save(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "auto_save", enable); -} -int hgic_iwpriv_set_pair_autostop(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "pair_autostop", enable); -} -int hgic_iwpriv_set_dcdc13(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "dcdc13", enable); -} -int hgic_iwpriv_set_acktmo(char *ifname, int acktmo) -{ - return hgic_iwpriv_set_int(ifname, "acktmo", acktmo); -} -int hgic_iwpriv_get_sta_list(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "sta_list", buff, size); -} -int hgic_iwpriv_get_scan_list(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "scan_list", buff, size); -} -int hgic_iwpriv_get_ssid(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "ssid", buff, size); -} -int hgic_iwpriv_get_bssid(char *ifname, char *mac) -{ - return hgic_iwpriv_get_mac(ifname, "bssid", mac); -} -int hgic_iwpriv_get_wpa_psk(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "wpa_psk", buff, size); -} -int hgic_iwpriv_get_txpower(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "txpower"); -} -int hgic_iwpriv_get_aggcnt(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "agg_cnt"); -} -int hgic_iwpriv_get_bss_bw(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "bss_bw"); -} -int hgic_iwpriv_get_chan_list(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "chan_list", buff, size); -} -int hgic_iwpriv_get_freq_range(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "freq_range", buff, size); -} -int hgic_iwpriv_get_key_mgmt(char *ifname, char *buff, int size) -{ - return hgic_iwpriv_get_bytes(ifname, "key_mgmt", buff, size); -} -int hgic_iwpriv_get_battery_level(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "battery_level"); -} -int hgic_iwpriv_get_module_type(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "module_type"); -} -int hgic_iwpriv_set_pa_pwrctrl_dis(char *ifname, int disable) -{ - return hgic_iwpriv_set_int(ifname, "pa_pwrctl_dis", disable); -} -int hgic_iwpriv_set_dhcpc(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "dhcpc", enable); -} -int hgic_iwpriv_get_disassoc_reason(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "disassoc_reason"); -} -int hgic_iwpriv_set_wkdata_save(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "wkdata_save", enable); -} -int hgic_iwpriv_set_mcast_txparam(char *ifname, int dupcnt, int tx_bw, int tx_mcs, int clearch) -{ - return hgic_iwpriv_set_ints(ifname, "mcast_txparam", 4, dupcnt, tx_bw, tx_mcs, clearch); -} -int hgic_iwpriv_reset_sta(char *ifname, char *mac_addr) -{ - return hgic_iwpriv_set_mac(ifname, "reset_sta", mac_addr); -} -int hgic_iwpriv_ant_auto(char *ifname, int en) -{ - return hgic_iwpriv_set_int(ifname, "ant_auto", en); -} -int hgic_iwpriv_set_ant_sel(char *ifname, int ant) -{ - return hgic_iwpriv_set_int(ifname, "ant_sel", ant); -} -int hgic_iwpriv_get_ant_sel(char *ifname) -{ - return hgic_iwpriv_get_int(ifname, "ant_sel"); -} -int hgic_iwpriv_set_macfilter(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "macfilter", enable); -} -int hgic_iwpriv_send_atcmd(char *ifname, char *atcmd) -{ - return hgic_iwpriv_set_bytes(ifname, "atcmd", atcmd); -} -int hgic_iwpriv_set_roaming(char *ifname, int enable) -{ - return hgic_iwpriv_set_int(ifname, "roaming", enable); -} -int hgic_iwpriv_set_max_txcnt(char *ifname, int txcnt) -{ - return hgic_iwpriv_set_int(ifname, "max_txcnt", txcnt); -} - -///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -/* proc fs api */ -int hgic_proc_read_bytes(char *name, char *buff, int len) -{ - char fname[32]; - int ret = 0; - int fd = -1; - - if (buff == NULL || len <= 0) { - return 0; - } - memset(buff, 0, len); - memset(fname, 0, sizeof(fname)); - sprintf(fname, "/proc/hgic/%s", name); - fd = open(fname, O_RDONLY); - if (fd != -1) { - ret = read(fd, buff, len); - close(fd); - } - return ret; -} - -int hgic_proc_read_int(char *name) -{ - char buff[32]; - hgic_proc_read_bytes(name, buff, 32); - return atoi(buff); -} - -int hgic_proc_read_mac(char *name, char *mac) -{ - char buff[32]; - hgic_proc_read_bytes(name, buff, 32); - return hgic_str2mac(buff, mac); -} - -int hgic_proc_write_bytes(char *name, char *buff, int len) -{ - int ret = 0; - char fname[32]; - int fd = -1; - - if (buff == NULL || len == 0) { - return 0; - } - memset(fname, 0, sizeof(fname)); - sprintf(fname, "/proc/hgic/%s", name); - fd = open(fname, O_WRONLY); - if (fd != -1) { - ret = write(fd, buff, len); - close(fd); - if(ret < 0) perror("error"); - } - return ret > 0; -} - -int hgic_proc_write_int(char *name, int val) -{ - char buff[12]; - memset(buff, 0, sizeof(buff)); - sprintf(buff, "%d", val); - return hgic_proc_write_bytes(name, buff, strlen(buff)); -} - -int hgic_proc_write_mac(char *name, char *mac) -{ - char str[18]; - memset(str, 0, sizeof(str)); - MAC2STR(mac, str); - return hgic_proc_write_bytes(name, str, strlen(str)); -} - -int hgic_proc_write_ints(char *name, int cnt, ...) -{ - int i = 0; - int val = 0; - char buff[512]; - char *ptr = buff; - va_list argptr; - - memset(buff, 0, sizeof(buff)); - va_start(argptr, cnt); - for (i = 0; i < cnt; i++) { - val = va_arg(argptr, int); - sprintf(ptr, (i==0?"%d":",%d"), val); - ptr += strlen(ptr); - } - va_end(argptr); - return hgic_proc_write_bytes(name, buff, strlen(buff)); -} - -int hgic_proc_write_intarray(char *name, int *values, int cnt) -{ - int i = 0; - char buff[512]; - char *ptr = buff; - - memset(buff, 0, sizeof(buff)); - for (i = 0; i < cnt; i++) { - sprintf(ptr, (i==0?"%d":",%d"), values[i]); - ptr += strlen(ptr); - } - return hgic_proc_write_bytes(name, buff, strlen(buff)); -} - -///////////////////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////////////////// -int hgic_proc_read_event(void) -{ - return hgic_proc_read_int("event"); -} -int hgic_proc_read_tx_bitrate(void) -{ - return hgic_proc_read_int("tx_bitrate"); -} -int hgic_proc_read_signal(void) -{ - return hgic_proc_read_int("signal"); -} -int hgic_proc_read_evm(void) -{ - return hgic_proc_read_int("evm"); -} -int hgic_proc_read_conn_state(void) -{ - char state[12]; - hgic_proc_read_bytes("conn_state", state, 12); - return (strstr(state, "CONNECTED") != NULL); -} -int hgic_proc_read_temperature(void) -{ - return hgic_proc_read_int("temperature"); -} -int hgic_proc_read_paired_stas(char *buff, int len) -{ - return hgic_proc_read_bytes("paired_stas", buff, len); -} -int hgic_proc_read_sta_count(void) -{ - return hgic_proc_read_int("sta_count"); -} -int hgic_proc_read_wkreason(void) -{ - return hgic_proc_read_int("wkreason"); -} -int hgic_proc_read_customer_mgmt(char *buff, int len) -{ - return hgic_proc_read_bytes("mgmt", buff, len); -} -int hgic_proc_read_fw_dbgifno(char *buff, int len) -{ - return hgic_proc_read_bytes("fwdbginfo", buff, len); -} -int hgic_proc_read_firmware_ver(char *ver_str, int size) -{ - return hgic_proc_read_bytes("fw_ver", ver_str, size); -} -int hgic_proc_read_battery_level(void) -{ - return hgic_proc_read_int("battery_level"); -} -int hgic_proc_set_heartbeat(int ipaddr, int port, int period, int timeout) -{ - struct in_addr in = { .s_addr = (in_addr_t)ipaddr }; - return hgic_proc_write_ints("heartbeat", 4, inet_ntoa(in), port, period, timeout); -} -int hgic_proc_set_heartbeat_resp_data(char *resp_data, int len) -{ - return hgic_proc_write_bytes("heartbeat_resp", resp_data, len); -} -int hgic_proc_set_wakeup_data(char *wakeup_data, int len) -{ - return hgic_proc_write_bytes("wakeup_data", wakeup_data, len); -} -int hgic_proc_wakeup_sta(char *addr) -{ - return hgic_proc_write_mac("wakeup", addr); -} -int hgic_proc_sleep(int sleep) -{ - return hgic_proc_write_int("sleep", sleep); -} -int hgic_proc_ota(char *fw_file) -{ - return hgic_proc_write_bytes("ota", fw_file, strlen(fw_file)); -} -int hgic_proc_read_pairing_sta(char *sta_mac) -{ - return hgic_proc_read_mac("pairing_sta", sta_mac); -} -int hgic_proc_send_custmgmt(char *dest, struct hgic_tx_info *txinfo, char *mgmt, int len) -{ - int ret = -1; - char *buf = malloc(len+sizeof(struct hgic_tx_info)+6); - if(buf){ - memcpy(buf, dest, 6); - memcpy(buf+6, txinfo, sizeof(struct hgic_tx_info)); - memcpy(buf+6+sizeof(struct hgic_tx_info), mgmt, len); - ret = hgic_proc_write_bytes("mgmt", buf, len+6+sizeof(struct hgic_tx_info)); - free(buf); - } - return ret; -} -int hgic_proc_read_dhcpc_result(char *buff, int len) -{ - return hgic_proc_read_bytes("dhcpc", buff, len); -} -int hgic_proc_read_wkdata_buff(char *buff, int len) -{ - return hgic_proc_read_bytes("wkdata_buff", buff, len); -} -int hgic_proc_set_wkdata_mask(unsigned short offset, char *mask, int mask_len) -{ - char buff[128]; - if(mask_len > 16) mask_len = 16; - memcpy(buff, &offset, 2); - memcpy(buff+2, mask, mask_len); - return hgic_proc_write_bytes("wkdata_mask", buff, mask_len + 2); -} -int hgic_proc_read_cust_driverdata(char *buff, int len) -{ - return hgic_proc_read_bytes("cust_driverdata", buff, len); -} -int hgic_proc_set_cust_driverdata(char *buff, int len) -{ - if(len > 1500){ - printf("data len:%d too big\r\n", len); - return -1; - } - return hgic_proc_write_bytes("cust_driverdata", buff, len); -} -int hgic_proc_set_stafreqinfo(char *sta_addr, struct hgic_freqinfo *freqinfo) -{ - int ret = -1; - char *buff = malloc(6+sizeof(struct hgic_freqinfo)); - if(buff){ - memset(buff, 0, 6+sizeof(struct hgic_freqinfo)); - if(sta_addr) memcpy(buff, sta_addr, 6); - memcpy(buff+6, freqinfo, sizeof(struct hgic_freqinfo)); - ret = hgic_proc_write_bytes("freqinfo", buff, 6+sizeof(struct hgic_freqinfo)); - free(buff); - } - return ret; -} - -/////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////// -#if 1 //sample code -#define IFNAME "hg0" - -#define AH_STA_COUNT (8) -struct hgic_ah_sta { - unsigned char mac[6]; - unsigned char used: 1, ps: 1, paired: 1, connected: 1, update:1; - unsigned char aid; - char rssi, evm; -}; - -struct hgic_ah_sta_mgr { - struct hgic_ah_sta stas[AH_STA_COUNT]; - int count; -}ah_sta_mgr; - -struct hgic_dhcp_result{ - unsigned int ipaddr, netmask, svrip, router, dns1, dns2; -}; - -static int hgic_parse_paired_stas(struct hgic_ah_sta *stas, char *paired_stas) -{ - int i = 0; - int cnt = 0; - char mac[6]; - char *ptr = paired_stas; - - memset(stas, 0, AH_STA_COUNT*sizeof(struct hgic_ah_sta)); - if(paired_stas && stas){ - cnt = strlen(paired_stas)/17; - if(cnt > AH_STA_COUNT) cnt = AH_STA_COUNT; - for(i=0; ipaired = 1; - sta->update = 1; - sta->used = 1; - } - } - } - else { - if(new_stas[i].connected){ - sta = hgic_find_sta(ah_sta_mgr.stas, new_stas[i].mac); - if(sta == NULL){ - sta = hgic_new_sta(new_stas[i].mac); - } - if(sta){ - sta->ps = new_stas[i].ps; - sta->rssi = new_stas[i].rssi; - sta->evm = new_stas[i].evm; - sta->aid = new_stas[i].aid; - sta->connected = 1; - sta->update = 1; - sta->used = 1; - } - } - } - } - - for(i=0; i 0){ - buff[i] = 0; - printf("get wkdata, len:%d, %s\r\n", i, buff+42); - } - }while(i>0); - free(buff); -} - -int hgic_event_proc(int event) -{ - int i = 0; - struct hgic_dhcp_result result; - struct hgic_ah_sta *sta = NULL; - struct hgic_ah_sta tmpstas[AH_STA_COUNT]; - char *buff = malloc(4096); - switch (event) { - case 5: /*HGIC_EVENT_SCANNING*/ - fmac_dbg("start scan ...\r\n"); - break; - case 6: /*HGIC_EVENT_SCAN_DONE*/ - fmac_dbg("scan done!\r\n"); - hgic_iwpriv_get_scan_list(IFNAME, buff, 4096); - if(buff) printf("%s\r\n", buff); - break; - case 7: /*HGIC_EVENT_TX_BITRATE*/ - fmac_dbg("estimate tx bitrate:%dKbps\r\n", hgic_proc_read_tx_bitrate()); - break; - case 8: /*HGIC_EVENT_PAIR_START*/ - fmac_dbg("start pairing ...\r\n"); - break; - case 9: /*HGIC_EVENT_PAIR_SUCCESS*/ - hgic_proc_read_pairing_sta(buff); - fmac_dbg("pairing success! ["MACSTR"]\r\n", MACARG(buff)); - hgic_iwpriv_set_pairing(IFNAME, 0); //stop pair - break; - case 10: /*HGIC_EVENT_PAIR_DONE*/ - fmac_dbg("pairing done!\r\n"); - hgic_proc_read_paired_stas(buff, 4096); - hgic_parse_paired_stas(tmpstas, buff); - for(i=0; ipaired){ - printf("new sta paired! "MACSTR"\r\n", MACARG(tmpstas[i].mac)); - } - } - } - hgic_update_stas(tmpstas, 1); - break; - case 11: /*HGIC_EVENT_CONECT_START*/ - fmac_dbg("start connecting ...\r\n"); - break; - case 12: /*HGIC_EVENT_CONECTED*/ - fmac_dbg("connected!\r\n"); - hgic_iwpriv_get_sta_list(IFNAME, buff, 4096); - hgic_parse_sta_list(tmpstas, buff); - for(i=0; iconnected){ - printf("new sta connected! "MACSTR"\r\n", MACARG(tmpstas[i].mac)); - } - } - } - hgic_update_stas(tmpstas, 0); - hgic_test_read_wakeupdata(); - break; - case 13: /*HGIC_EVENT_DISCONECTED*/ - fmac_dbg("disconnected!\r\n"); - hgic_iwpriv_get_sta_list(IFNAME, buff, 4096); - hgic_parse_sta_list(tmpstas, buff); - for(i=0;iconnected){ - printf("sta disconnected! "MACSTR"\r\n", MACARG(ah_sta_mgr.stas[i].mac)); - } - } - } - hgic_update_stas(tmpstas, 0); - break; - case 14: /*HGIC_EVENT_SIGNAL*/ - fmac_dbg("signal changed: rssi:%d, evm:%d\r\n", hgic_proc_read_signal(), hgic_proc_read_event()); - break; - case 18: /*HGIC_EVENT_FWDBG_INFO*/ - hgic_proc_read_fw_dbgifno(buff, 4096); - if(buff) printf("%s", buff); - break; - case 19: /*HGIC_EVENT_CUSTOMER_MGMT*/ - i = hgic_proc_read_customer_mgmt(buff, 4096); - fmac_dbg("rx customer mgmt frame from "MACSTR", %d bytes \r\n", MACARG(buff+6), i-6); - break; - case 21: /*HGIC_EVENT_DHCPC_DONE*/ - hgic_proc_read_dhcpc_result((char *)&result, sizeof(result)); - fmac_dbg("fw dhcpc result: ipaddr:"IPSTR", netmask:"IPSTR", svrip:"IPSTR", router:"IPSTR", dns:"IPSTR"/"IPSTR"\r\n", - IPARG(result.ipaddr), IPARG(result.netmask), IPARG(result.svrip), - IPARG(result.router), IPARG(result.dns1), IPARG(result.dns2)); - break; - case 22: /*HGIC_EVENT_CONNECT_FAIL*/ - fmac_dbg("connect fail, reason:%d\r\n", hgic_iwpriv_get_disassoc_reason(IFNAME)); - break; - case 23: /*HGIC_EVENT_CUST_DRIVER_DATA*/ - fmac_dbg("rx customer driver data %d bytes\r\n", hgic_proc_read_cust_driverdata(buff, 1024)); - break; - case 24: /*HGIC_EVENT_UNPAIR_STA*/ - fmac_dbg("unpair\r\n"); - break; - } - if (buff) { free(buff); } -} - -int main(int argc, char *argv[]) -{ - int event = 0; - char mask[4] = { 0x3, 0xff, 0x0f, 0xff}; - char dest[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - struct hgic_tx_info txinfo; - struct hgic_module_hwinfo hwinfo; - - struct hgic_freqinfo freqinfo={ - .bss_bw = 8, - .chan_cnt = 3, - .chan_list = {9080, 9160, 9240}, - }; - char *custmgmt = "this is customer mgmt data"; - - hwinfo.v = hgic_iwpriv_get_module_type("hg0"); - printf("Module HW info: type:%d, %s\r\n", hwinfo.type, hwinfo.saw?"SAW":"NO SAW"); - - /*test: send customer mgmt frame.*/ - memset(&txinfo, 0, sizeof(txinfo)); - txinfo.tx_mcs = 0xff; //auto mcs - txinfo.freq_idx = 1; //tx at channel 1 - hgic_proc_send_custmgmt(dest, &txinfo, custmgmt, strlen(custmgmt)); - txinfo.freq_idx = 2; //tx at channel 2 - hgic_proc_send_custmgmt(dest, &txinfo, custmgmt, strlen(custmgmt)); - txinfo.freq_idx = 3; //tx at channel 3 - hgic_proc_send_custmgmt(dest, &txinfo, custmgmt, strlen(custmgmt)); - - /*test: enable dhcp client function in firmware.*/ - hgic_iwpriv_set_dhcpc("hg0", 1); - - /*test: set wakedata match mask*/ - hgic_proc_set_wkdata_mask(42, mask, 4); - - /*test: enable firmware save wakeup data.*/ - hgic_iwpriv_set_wkdata_save("hg0", 1); - - /*test: get current bssid (for sta mode)*/ - hgic_iwpriv_get_bssid("hg0", dest); - printf("current bssid:"MACSTR"\r\n", MACARG(dest)); - - /*test: set remote AP's freqency info.*/ - hgic_proc_set_stafreqinfo(dest, &freqinfo); - - /*test: reset remote AP.*/ - hgic_iwpriv_reset_sta("hg0", dest); - - /*test: read wakeup data from firmware.*/ - hgic_test_read_wakeupdata(); - - /*loop read driver event and proc event.*/ - while (1) { - event = hgic_proc_read_event(); - if(event){ - hgic_event_proc(event); - } - } -} -#endif - diff --git a/utils/if_sdio.c b/utils/if_sdio.c index 2a49997..517a026 100644 --- a/utils/if_sdio.c +++ b/utils/if_sdio.c @@ -41,11 +41,19 @@ #define SDIO_INIT_STATUS_ADDR 0x04 #define SDIO_INIT_STATUS_ADDR2 0x48 #define SDIO_TRANS_COUNT_ADDR2 0x49 -#define SDIO_INIT_STATUS_DATA_READY 0x01 +#define SDIO_BUSY_ADDR2 0x4c +#define HGIC_PKT_MAX_LEN (8*1024) + +#define SDIO_INIT_STATUS_DATA_READY BIT(0) +#define SDIO_INIT_STATUS_BUSY BIT(3) + #define SDIO_STATUS_STOP BIT(0) #define SDIO_STATUS_ERROR BIT(1) #define SDIO_TX_HEADROM (4) +static hgic_probe probe_hdl = NULL; +static u32 max_pkt_len = HGIC_PKT_MAX_LEN; + struct hgic_sdio { struct sdio_func_t *func; u32 status; @@ -53,13 +61,16 @@ struct hgic_sdio { u32 trans_cnt_addr; /*sdio data length register address*/ u32 int_status_addr; /*interrupt status register address*/ struct hgic_bus bus; - u32 rx_retry; + u8 rx_retry; + u8 busypd; + struct completion busy; + u8 *rxbuf; }; const struct sdio_device_id_t hgic_sdio_wdev_ids[] = { - {SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_AH_4001)}, - {SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_AH_4002)}, - {SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_AH_4102)}, + {SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_4002)}, + {SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_4104)}, + {SDIO_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_8400)}, { /* end: all zeroes */ }, }; @@ -80,7 +91,7 @@ const struct sdio_device_id_t hgic_sdio_wdev_ids[] = { #define SDIO_CAP_POLL(func) ((func)->card->host->caps & MMC_CAP_NEEDS_POLL) #define HOST_SPI_CRC(func, crc) (func)->card->host->use_spi_crc=crc -#define mmc_card_disable_cd(c) (1) +//#define mmc_card_disable_cd(c) (1) #define hgic_card_disable_cd(func) mmc_card_disable_cd((func)->card) #define hgic_card_set_highspeed(func) mmc_card_set_highspeed((func)->card) #define hgic_host_is_spi(func) mmc_host_is_spi((func)->card->host) @@ -120,6 +131,11 @@ static inline int hgic_mmc_send_cmd(struct sdio_func_t *func, struct mmc_command { return mmc_wait_for_cmd(func->card->host, cmd, retries); } +static inline void hgic_mmc_set_blk_size(struct sdio_func_t *func, unsigned int blk_size) +{ + func->card->host->max_blk_size = blk_size; + func->card->host->ops->set_ios(func->card->host, &func->card->host->ios); +} #endif static int hgic_mmc_io_rw_direct(struct sdio_func_t *func, int write, unsigned fn, @@ -382,14 +398,14 @@ static int hgic_sdio_set_wire_width(struct sdio_func_t *func) return 1; } -static u32 hgic_sdio_select_card(struct sdio_func_t *func) +static u32 hgic_sdio_select_card(struct sdio_func_t *func, u32 rca) { int err; struct mmc_command_t cmd = {0}; cmd.opcode = MMC_SELECT_CARD; if (func) { - cmd.arg = hgic_func_rca(func) << 16; + cmd.arg = rca << 16; cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; } else { cmd.arg = 0; @@ -436,11 +452,12 @@ static int hgic_mmc_spi_set_crc(struct sdio_func_t *func, int use_crc) static int hgic_sdio_reinit_card(struct sdio_func_t *func) { +#ifdef CONFIG_SDIO_REINIT int i = 3; u32 ocr = 0; + u32 rca = 0; int retry = 0; struct hgic_sdio *sdiodev = sdio_get_drvdata(func); - u32 rca = 0; hgic_enter(); __RETRY: @@ -455,12 +472,17 @@ __RETRY: return -1; } - i = 5; + i = 5; ocr = 0; + rca = 0; hgic_mmc_set_clock(func, 400000); hgic_mmc_set_timing(func, MMC_TIMING_LEGACY); hgic_mmc_set_bus_width(func, MMC_BUS_WIDTH_1); + if (!hgic_sdio_get_card_addr(func, (u32 *)&rca)) { + hgic_sdio_select_card(func, rca); + } + hgic_sdio_reset(func); hgic_sdio_go_idle(func); hgic_mmc_send_if_cond(func, ocr); @@ -468,7 +490,8 @@ __RETRY: if (hgic_send_io_op_cond(func, 0, (u32 *)&ocr)) { goto __RETRY; } - if (hgic_send_io_op_cond(func, hgic_card_ocr(func), (u32 *)&ocr)) { + + if (hgic_send_io_op_cond(func, ocr, (u32 *)&ocr)) { goto __RETRY; } @@ -477,11 +500,10 @@ __RETRY: goto __RETRY; } } else { - rca = hgic_func_rca(func); if (hgic_sdio_get_card_addr(func, (u32 *)&rca)) { goto __RETRY; } - if (hgic_sdio_select_card(func)) { + if (hgic_sdio_select_card(func, rca)) { goto __RETRY; } if (hgic_sdio_disable_cd(func) < 0) { @@ -495,6 +517,8 @@ __RETRY: hgic_mmc_set_clock(func, hgic_card_highspeed(func) ? 50000000 : hgic_card_max_clock(func)); hgic_mmc_set_timing(func, MMC_TIMING_SD_HS); + hgic_mmc_set_blk_size(func, SDIO_BLOCK_SIZE); + if (hgic_sdio_set_wire_width(func) < 0) { goto __RETRY; } @@ -507,11 +531,13 @@ __RETRY: if (sdio_enable_func(func)) { goto __RETRY; } - hgic_leave(); + #ifndef __RTOS__ if (func->card->host->sdio_irq_thread) { wake_up_process(func->card->host->sdio_irq_thread); } +#endif + hgic_leave(); #endif return 0; } @@ -532,7 +558,10 @@ static int hgic_sdio_readb(struct sdio_func_t *func, u32 addr, int *err) int retry = 2; val = sdio_readb(func, addr, err); - if (val == 0) { *err = -1; } //if read 0, try again. + //if (val == 0) { + // *err = -1; + //} + while (*err && retry-- > 0) { val = sdio_readb(func, addr, err); } @@ -581,6 +610,7 @@ static int hgic_sdio_abort(struct sdio_func_t *func) hgic_sdio_writeb(&func0, 1, 6, &err_ret); return err_ret; } + static int hgic_sdio_read_cccr(struct sdio_func_t *func, u8 *pending) { int ret = 0; @@ -591,20 +621,44 @@ static int hgic_sdio_read_cccr(struct sdio_func_t *func, u8 *pending) return ret; } -static u32 hgic_sdio_data_len(struct hgic_sdio *sdiodev) +static u32 hgic_sdio_get_datalen(struct hgic_sdio *sdiodev, u8 addr) { int err = 0; u32 len = 0; u8 ret = 0; - u16 addr = test_bit(HGIC_BUS_FLAGS_INBOOT, &sdiodev->bus.flags) ? - sdiodev->trans_cnt_addr : SDIO_TRANS_COUNT_ADDR2; ret = hgic_sdio_readb(sdiodev->func, addr, &err); - if (err) { return 0xffffffff; } + if (err) { + return 0xffffffff; + } + len = ret; ret = hgic_sdio_readb(sdiodev->func, addr + 1, &err); - if (err) { return 0xffffffff; } + if (err) { + return 0xffffffff; + } + len |= ret << 8; + return len; +} + +static u32 hgic_sdio_data_len(struct hgic_sdio *sdiodev) +{ + int ret = 0; + u32 len = 0; + + if (!test_bit(HGIC_BUS_FLAGS_INBOOT, &sdiodev->bus.flags)) { + if(sdiodev->bus.dev_id == HGIC_WLAN_4002){ + len = hgic_sdio_get_datalen(sdiodev, SDIO_TRANS_COUNT_ADDR2); + }else{ + len = sdio_readb(sdiodev->func, SDIO_TRANS_COUNT_ADDR2, &ret); + len = len * SDIO_BLOCK_SIZE; + } + } + + if (len == 0 || len == 0xffffffff) { + len = hgic_sdio_get_datalen(sdiodev, sdiodev->trans_cnt_addr); + } if (len == 0) { if (test_bit(HGIC_BUS_FLAGS_INBOOT, &sdiodev->bus.flags)) { @@ -617,8 +671,7 @@ static u32 hgic_sdio_data_len(struct hgic_sdio *sdiodev) return len; } - -static int hgic_sdio_is_data_ready(struct hgic_sdio *sdiodev, struct sdio_func_t *func) +static u32 hgic_sdio_int_status(struct hgic_sdio *sdiodev, struct sdio_func_t *func) { int ret = 0; u8 pending = 0; @@ -627,9 +680,7 @@ static int hgic_sdio_is_data_ready(struct hgic_sdio *sdiodev, struct sdio_func_t ret = hgic_sdio_read_cccr(func, &pending); if (!ret && (pending & 02)) { - int_status1 = sdio_readb(func, sdiodev->int_status_addr, &ret); - if (ret) { int_status1 = sdio_readb(func, sdiodev->int_status_addr, &ret); } - int_status1 &= SDIO_INIT_STATUS_DATA_READY; + int_status1 = hgic_sdio_readb(func, sdiodev->int_status_addr, &ret); if (!ret && !int_status1 && !test_bit(HGIC_BUS_FLAGS_INBOOT, &sdiodev->bus.flags)) { int_status2 = hgic_sdio_readb(func, SDIO_INIT_STATUS_ADDR2, &ret); if (int_status1 != int_status2) { @@ -637,7 +688,9 @@ static int hgic_sdio_is_data_ready(struct hgic_sdio *sdiodev, struct sdio_func_t int_status1 = int_status2; } } - if (!int_status1) { hgic_sdio_abort(func); } + if (!int_status1) { + hgic_sdio_abort(func); + } } return int_status1; } @@ -647,15 +700,16 @@ static void hgic_sdio_interrupt(struct sdio_func_t *func) int ret = 0; u32 len = 0; int read_more = 0; - struct sk_buff *skb = NULL; + u32 int_status; struct hgic_sdio *sdiodev = sdio_get_drvdata(func); - if (sdiodev == NULL || (sdiodev->status&SDIO_STATUS_STOP) || test_bit(HGIC_BUS_FLAGS_SLEEP, &sdiodev->bus.flags)) { + if (sdiodev == NULL || (sdiodev->status & SDIO_STATUS_STOP)) { return; } read_more = sdiodev->rx_retry; do { - if (hgic_sdio_is_data_ready(sdiodev, func)) { + int_status = hgic_sdio_int_status(sdiodev, func); + if (int_status & SDIO_INIT_STATUS_DATA_READY) { read_more = sdiodev->rx_retry; len = hgic_sdio_data_len(sdiodev); if (len == 0xFFFFFFFF) { @@ -664,65 +718,101 @@ static void hgic_sdio_interrupt(struct sdio_func_t *func) hgic_sdio_reinit_card(func); return; } else if (len > 0) { - skb = dev_alloc_skb(len); - if (skb == NULL) { - hgic_err("no memory\r\n"); + if (len > max_pkt_len){ + hgic_err("len error: %d, max:%d\r\n", len, max_pkt_len); hgic_sdio_abort(func); return; } - ret = hgic_sdio_copy_fromio(sdiodev->func, skb->data, - sdiodev->data_addr, len); + + ret = hgic_sdio_copy_fromio(sdiodev->func, sdiodev->rxbuf, sdiodev->data_addr, len); if (ret) { - dev_kfree_skb(skb); hgic_err("sdio_copy_fromio err!, ret:%d\r\n", ret); return; } - ret = sdiodev->bus.rx_packet(sdiodev->bus.bus_priv, skb, len); + ret = sdiodev->bus.rx_packet(sdiodev->bus.bus_priv, sdiodev->rxbuf, len); if (ret) { hgic_sdio_abort(func); } } else { hgic_sdio_abort(func); } - } else if (read_more > 0) { + } + + if ((int_status & SDIO_INIT_STATUS_BUSY) && sdiodev->busypd) { + //printk("*\r\n"); + complete(&sdiodev->busy); + } + + if (int_status == 0 && read_more > 0) { udelay(20); } } while (!ret && read_more-- > 0); } +static int hgic_sdio_is_busy(struct hgic_sdio *sdiodev) +{ + int err = 0; + u8 val = 0; + val = hgic_sdio_readb(sdiodev->func, SDIO_BUSY_ADDR2, &err); + if(err) hgic_sdio_reinit_card(sdiodev->func); + return (err || (val & 0x01)) ? 1 : 0; +} + static int hgic_sdio_tx_packet(void *bus, struct sk_buff *skb) { int ret = 0; + int busy = 1; + struct list_head *head; struct hgic_sdio *sdiodev = container_of(bus, struct hgic_sdio, bus); int len = skb->len > SDIO_BLOCK_SIZE ? ALIGN(skb->len, SDIO_BLOCK_SIZE) : ALIGN(skb->len, 4); +#ifndef __RTOS__ + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,13,0) + head = &sdiodev->func->card->host->wq.head; + #else + head = &sdiodev->func->card->host->wq.task_list; + #endif + if (!list_empty(head) /*|| (!SDIO_CAP_IRQ(sdiodev->func) && time_after(jiffies, sdiodev->last_rxtick + msecs_to_jiffies(100)))*/) { + schedule(); + } +#endif + sdio_claim_host(sdiodev->func); if ((sdiodev->status & SDIO_STATUS_STOP) || test_bit(HGIC_BUS_FLAGS_SLEEP, &sdiodev->bus.flags)) { sdiodev->bus.tx_complete(sdiodev->bus.bus_priv, skb, 0); sdio_release_host(sdiodev->func); return -1; } + + while (busy && !test_bit(HGIC_BUS_FLAGS_SOFTFC, &sdiodev->bus.flags)) { + busy = hgic_sdio_is_busy(sdiodev); + if (busy) { + sdiodev->busypd = 1; + sdio_release_host(sdiodev->func); + wait_for_completion_timeout(&sdiodev->busy, msecs_to_jiffies(10)); + sdio_claim_host(sdiodev->func); + sdiodev->busypd = 0; + if ((sdiodev->status & SDIO_STATUS_STOP) || test_bit(HGIC_BUS_FLAGS_SLEEP, &sdiodev->bus.flags)) { + sdiodev->bus.tx_complete(sdiodev->bus.bus_priv, skb, 0); + sdio_release_host(sdiodev->func); + return -1; + } + } + } + ret = hgic_sdio_copy_toio(sdiodev->func, sdiodev->data_addr, skb->data, len); sdio_release_host(sdiodev->func); sdiodev->bus.tx_complete(sdiodev->bus.bus_priv, skb, !ret); return ret; } -static struct hgic_bus hgic_ifbus_sdio = { - .type = HGIC_BUS_SDIO, - .drv_tx_headroom = SDIO_TX_HEADROM, - .tx_packet = hgic_sdio_tx_packet, - .reinit = hgic_sdio_reinit, - .bootdl_pktlen = 32704, - .bootdl_cksum = HGIC_BUS_BOOTDL_CHECK_0XFD, -}; - static int hgic_sdio_enable(struct sdio_func_t *func) { int ret; hgic_dbg("Enter\n"); sdio_claim_host(func); + hgic_mmc_set_blk_size(func, SDIO_BLOCK_SIZE); ret = sdio_set_block_size(func, SDIO_BLOCK_SIZE); if (ret) { hgic_err("Set sdio block size %d failed: %d)\n", SDIO_BLOCK_SIZE, ret); @@ -735,6 +825,7 @@ static int hgic_sdio_enable(struct sdio_func_t *func) } ret = sdio_enable_func(func); if (ret) { + sdio_release_irq(func); hgic_err("enable sdio function failed: %d)\n", ret); goto out; } @@ -745,7 +836,7 @@ out: return ret; } -int hgic_sdio_probe(struct sdio_func_t *func, const struct sdio_device_id_t *id) +static int hgic_sdio_probe(struct sdio_func_t *func, const struct sdio_device_id_t *id) { int ret = 0; struct hgic_sdio *sdiodev = NULL; @@ -760,24 +851,41 @@ int hgic_sdio_probe(struct sdio_func_t *func, const struct sdio_device_id_t *id) return -ENOMEM; } + sdiodev->rxbuf = kmalloc(max_pkt_len, GFP_KERNEL); + if (sdiodev->rxbuf == NULL) { + hgic_err("alloc rxbuf fail, size:%d\r\n", max_pkt_len); + goto __failed; + } + hgic_dbg("new sdio card: vendor:%x, id:%x\n", id->vendor_id, id->device_id); sdiodev->func = func; sdiodev->data_addr = SDIO_DATA_ADDR; sdiodev->trans_cnt_addr = SDIO_TRANS_COUNT_ADDR; sdiodev->int_status_addr = SDIO_INIT_STATUS_ADDR; - sdiodev->status = SDIO_STATUS_STOP; - sdiodev->bus = hgic_ifbus_sdio; + //sdiodev->status = SDIO_STATUS_STOP; + sdiodev->bus.type = HGIC_BUS_SDIO; + sdiodev->bus.drv_tx_headroom = SDIO_TX_HEADROM; + sdiodev->bus.tx_packet = hgic_sdio_tx_packet; +#ifdef CONFIG_SDIO_REINIT + sdiodev->bus.reinit = hgic_sdio_reinit; +#endif + sdiodev->bus.bootdl_pktlen = 32704; + sdiodev->bus.bootdl_cksum = HGIC_BUS_BOOTDL_CHECK_0XFD; + sdiodev->bus.probe = probe_hdl; sdiodev->bus.dev_id = id->device_id; sdiodev->bus.blk_size = SDIO_BLOCK_SIZE; - sdiodev->rx_retry = SDIO_CAP_IRQ(func) ? 0 : 5; + sdiodev->rx_retry = SDIO_CAP_IRQ(func) ? 0 : 5; + init_completion(&sdiodev->busy); + if (!SDIO_CAP_POLL(func)) { set_bit(HGIC_BUS_FLAGS_NOPOLL, &sdiodev->bus.flags); } + if (hgic_host_is_spi(func)) { sdiodev->bus.bootdl_pktlen = 4096; } - hgic_core_probe(FUNC_DEV(func), &sdiodev->bus); + sdiodev->bus.probe(FUNC_DEV(func), &sdiodev->bus); if (sdiodev->bus.bus_priv == NULL) { hgic_err("err\r\n"); goto __failed; @@ -789,21 +897,28 @@ int hgic_sdio_probe(struct sdio_func_t *func, const struct sdio_device_id_t *id) goto __failed; } - sdiodev->status &= ~SDIO_STATUS_STOP; - hgic_core_probe_post(sdiodev->bus.bus_priv); + //sdiodev->status &= ~SDIO_STATUS_STOP; + if (sdiodev->bus.probe_post) { + sdiodev->bus.probe_post(sdiodev->bus.bus_priv); + } hgic_dbg("ok\n"); return ret; __failed: hgic_dbg("failed\n"); sdio_set_drvdata(func, NULL); - hgic_core_remove(sdiodev->bus.bus_priv); + if (sdiodev->bus.remove) { + sdiodev->bus.remove(sdiodev->bus.bus_priv); + } + if (sdiodev->rxbuf) { + kfree(sdiodev->rxbuf); + } kfree(sdiodev); hgic_dbg("failed 2\n"); return ret; } -void hgic_sdio_remove(struct sdio_func_t *func) +static void hgic_sdio_remove(struct sdio_func_t *func) { struct hgic_sdio *sdiodev = NULL; @@ -817,9 +932,17 @@ void hgic_sdio_remove(struct sdio_func_t *func) sdio_release_irq(func); sdio_release_host(func); hgic_dbg("remove ... 2\n"); - hgic_core_remove(sdiodev->bus.bus_priv); + if (sdiodev->bus.remove) { + sdiodev->bus.remove(sdiodev->bus.bus_priv); + } hgic_dbg("remove ... 3\n"); sdio_claim_host(func); +#ifdef __RTOS__ + deinit_completion(&sdiodev->busy); +#endif + if (sdiodev->rxbuf) { + kfree(sdiodev->rxbuf); + } sdio_set_drvdata(func, NULL); kfree(sdiodev); sdio_release_host(func); @@ -834,10 +957,9 @@ static int hgic_sdio_suspend(struct device *dev) int ret = 0; struct sdio_func_t *func = dev_to_sdio_func(dev); struct hgic_sdio *sdiodev = (struct hgic_sdio *)sdio_get_drvdata(func); - ret = hgic_core_suspend(sdiodev->bus.bus_priv); - sdio_claim_host(func); - ret = sdio_release_irq(func); - sdio_release_host(func); + if (sdiodev->bus.suspend) { + ret = sdiodev->bus.suspend(sdiodev->bus.bus_priv); + } return ret; } static int hgic_sdio_resume(struct device *dev) @@ -845,10 +967,9 @@ static int hgic_sdio_resume(struct device *dev) int ret = 0; struct sdio_func_t *func = dev_to_sdio_func(dev); struct hgic_sdio *sdiodev = (struct hgic_sdio *)sdio_get_drvdata(func); - sdio_claim_host(func); - ret = sdio_claim_irq(func, hgic_sdio_interrupt); - sdio_release_host(func); - ret = hgic_core_resume(sdiodev->bus.bus_priv); + if (sdiodev->bus.resume) { + ret = sdiodev->bus.resume(sdiodev->bus.bus_priv); + } return ret; } static const struct dev_pm_ops hgic_sdio_pm_ops = { @@ -856,6 +977,7 @@ static const struct dev_pm_ops hgic_sdio_pm_ops = { .resume = hgic_sdio_resume, }; #endif + #ifdef SDIO_DRIVER_EXT extern struct sdio_driver_t hgic_sdio_driver; #else @@ -867,16 +989,20 @@ static struct sdio_driver_t hgic_sdio_driver = { #ifdef CONFIG_PM .drv = { .pm = &hgic_sdio_pm_ops, - }, + }, #endif }; #endif -int __init hgic_sdio_init(void) +int __init hgic_sdio_init(hgic_probe probe, u32 max_pkt) { int ret; - hgic_dbg("Enter\n"); + hgic_dbg("Enter, max_pkt_len = %d\n", max_pkt_len); + probe_hdl = probe; + if(max_pkt > HGIC_PKT_MAX_LEN){ + max_pkt_len = max_pkt; + } ret = sdio_register_driver(&hgic_sdio_driver); hgic_dbg("Leave\n"); return ret; @@ -889,11 +1015,3 @@ void __exit hgic_sdio_exit(void) hgic_dbg("Leave\n"); } -#ifndef CONFIG_HGIC_SDIOIN -module_init(hgic_sdio_init); -module_exit(hgic_sdio_exit); -MODULE_DESCRIPTION("HUGE-IC WLAN Driver"); -MODULE_AUTHOR("Dongyun"); -MODULE_LICENSE("GPL"); -#endif - diff --git a/utils/if_usb.c b/utils/if_usb.c index f221eb3..e9bd292 100644 --- a/utils/if_usb.c +++ b/utils/if_usb.c @@ -14,22 +14,24 @@ #include "../hgic_def.h" #include "utils.h" -#define HGIC_PKT_MAX_LEN 2048 -#define HGIC_TX_URB_CNT 64 -#define HGIC_RX_URB_CNT 64 +#define HGIC_PKT_MAX_LEN (2*1024+512) +#define HGIC_TX_URB_CNT 16 +#define HGIC_RX_URB_CNT 32 #define HGIC_USB_STATUS_STOP BIT(0) #define HGIC_USB_STATUS_ERR BIT(1) -#define HGIC_USB_BUF_FLAG_USED 0x00000001 +#define HGIC_USB_BUF_FLAG_USED BIT(0) +#define HGIC_USB_BUF_FLAG_RX BIT(1) + #define USB_TX_HEADROM 4 struct hgic_usb_buf { struct list_head list; - struct hgic_usb *usbdev; + struct hgic_usb *usbdev; struct urb *urb; - struct sk_buff *skb; - int flag; + void *data; + int flag; }; struct hgic_usb { @@ -47,16 +49,30 @@ struct hgic_usb { static int txq_cnt = HGIC_TX_URB_CNT; static int rxq_cnt = HGIC_RX_URB_CNT; +static hgic_probe probe_hdl = NULL; +static u32 max_pkt_len = HGIC_PKT_MAX_LEN; static const struct usb_device_id hgic_usb_wdev_ids[] = { - { USB_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_AH_4001) }, - { USB_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_AH_4002) }, - { USB_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_AH_4102) }, + { USB_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_4002) }, + { USB_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_4104) }, + { USB_DEVICE(HGIC_VENDOR_ID, HGIC_WLAN_8400)}, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(usb, hgic_usb_wdev_ids); static void hgic_usb_receive(struct urb *urb); +static void hgic_usb_cancle(struct hgic_usb *usbdev) +{ + unsigned long flags; + struct hgic_usb_buf *buf, *n; + + spin_lock_irqsave(&usbdev->qlock, flags); + list_for_each_entry_safe(buf, n, &usbdev->used, list) { + usb_unlink_urb(buf->urb); + } + spin_unlock_irqrestore(&usbdev->qlock, flags); +} + static void hgic_usb_free(struct hgic_usb *usbdev) { unsigned long flags; @@ -66,25 +82,32 @@ static void hgic_usb_free(struct hgic_usb *usbdev) list_for_each_entry_safe(buf, n, &usbdev->tx_freeq, list) { list_del(&buf->list); usb_free_urb(buf->urb); + if(buf->data){ + hgic_err("skb is not free??\r\n"); + kfree_skb(buf->data); + buf->data = NULL; + } kfree(buf); - //hgic_dbg("free usb tx buff\r\n"); } list_for_each_entry_safe(buf, n, &usbdev->rx_freeq, list) { list_del(&buf->list); + kfree(buf->data); usb_free_urb(buf->urb); kfree(buf); - //hgic_dbg("free usb rx buff\r\n"); } list_for_each_entry_safe(buf, n, &usbdev->used, list) { usb_kill_urb(buf->urb); list_del(&buf->list); + if (buf->flag & HGIC_USB_BUF_FLAG_RX) { + kfree(buf->data); + } usb_free_urb(buf->urb); kfree(buf); } spin_unlock_irqrestore(&usbdev->qlock, flags); } -static int hgic_usb_qinit(struct hgic_usb *usb, struct list_head *q, int qsize) +static int hgic_usb_qinit(struct hgic_usb *usb, struct list_head *q, int qsize, u8 rx) { int i = 0; struct hgic_usb_buf *buf = NULL; @@ -92,12 +115,22 @@ static int hgic_usb_qinit(struct hgic_usb *usb, struct list_head *q, int qsize) for (i = 0; i < qsize; i++) { buf = kzalloc(sizeof(struct hgic_usb_buf), GFP_ATOMIC); if (buf == NULL) { + hgic_err("alloc fail, i=%d\r\n", i); break; } buf->usbdev = usb; buf->urb = usb_alloc_urb(0, GFP_KERNEL); if (buf->urb) { + if (rx) { + buf->data = kmalloc(max_pkt_len, GFP_KERNEL); + if (buf->data == NULL) { + kfree(buf); + hgic_err("alloc fail, len=%d\r\n", max_pkt_len); + break; + } + buf->flag |= HGIC_USB_BUF_FLAG_RX; + } list_add_tail(&buf->list, q); } else { kfree(buf); @@ -107,7 +140,7 @@ static int hgic_usb_qinit(struct hgic_usb *usb, struct list_head *q, int qsize) return i; } -struct hgic_usb_buf *hgic_usb_deq(struct hgic_usb *usbdev, struct list_head *q) +static struct hgic_usb_buf *hgic_usb_deq(struct hgic_usb *usbdev, struct list_head *q) { struct hgic_usb_buf *buf = NULL; unsigned long flags; @@ -123,12 +156,11 @@ struct hgic_usb_buf *hgic_usb_deq(struct hgic_usb *usbdev, struct list_head *q) return buf; } -void hgic_usb_enq(struct hgic_usb_buf *buf, struct list_head *q) +static void hgic_usb_enq(struct hgic_usb_buf *buf, struct list_head *q) { unsigned long flags; spin_lock_irqsave(&buf->usbdev->qlock, flags); - buf->skb = NULL; buf->flag &= ~HGIC_USB_BUF_FLAG_USED; list_del(&buf->list); list_add_tail(&buf->list, q); @@ -139,21 +171,20 @@ static int hgic_usb_submit_rx_urb(struct hgic_usb_buf *buf) { int ret = -1; - buf->skb = dev_alloc_skb(HGIC_PKT_MAX_LEN); - if (!buf->skb) { - hgic_err("alloc skb failed\r\n"); + if (buf->usbdev->status & (HGIC_USB_STATUS_STOP | HGIC_USB_STATUS_ERR)) { hgic_usb_enq(buf, &buf->usbdev->rx_freeq); return -1; } + usb_fill_bulk_urb(buf->urb, buf->usbdev->udev, usb_rcvbulkpipe(buf->usbdev->udev, buf->usbdev->ep_in), - buf->skb->data, HGIC_PKT_MAX_LEN, hgic_usb_receive, buf); + buf->data, max_pkt_len, hgic_usb_receive, buf); ret = usb_submit_urb(buf->urb, GFP_ATOMIC); if (ret) { - hgic_err("submit rx urb failed: %d\n", ret); - dev_kfree_skb_any(buf->skb); + hgic_err("submit rx urb %p failed: %d\n", buf->urb, ret); hgic_usb_enq(buf, &buf->usbdev->rx_freeq); buf->usbdev->status |= HGIC_USB_STATUS_ERR; + hgic_usb_cancle(buf->usbdev); return -1; } return 0; @@ -177,27 +208,29 @@ static void hgic_usb_receive(struct urb *urb) { struct hgic_usb_buf *buf = (struct hgic_usb_buf *)urb->context; - if (buf->usbdev->status & (HGIC_USB_STATUS_STOP | HGIC_USB_STATUS_ERR)) { - dev_kfree_skb_any(buf->skb); + //hgic_enter(); + if (buf->usbdev->status & HGIC_USB_STATUS_STOP) { hgic_usb_enq(buf, &buf->usbdev->rx_freeq); + hgic_err("STOP, drop data, status=%x\r\n", buf->usbdev->status); return; } if (urb->actual_length > 0) { - buf->usbdev->bus.rx_packet(buf->usbdev->bus.bus_priv, buf->skb, urb->actual_length); - } else { - dev_kfree_skb_any(buf->skb); + buf->usbdev->bus.rx_packet(buf->usbdev->bus.bus_priv, buf->data, urb->actual_length); } hgic_usb_submit_rx_urb(buf); + //hgic_leave(); } static void hgic_usb_tx_complete(struct urb *urb) { struct hgic_usb_buf *buf = (struct hgic_usb_buf *)urb->context; - //hgic_skip_padding(buf->skb); - buf->usbdev->bus.tx_complete(buf->usbdev->bus.bus_priv, buf->skb, !urb->status); - hgic_usb_enq(buf, &buf->usbdev->tx_freeq); - up(&buf->usbdev->tx_sema); + struct hgic_usb *usbdev = buf->usbdev; + + usbdev->bus.tx_complete(usbdev->bus.bus_priv, (struct sk_buff *)buf->data, !urb->status); + buf->data = NULL; + hgic_usb_enq(buf, &usbdev->tx_freeq); + up(&usbdev->tx_sema); } static int hgic_usb_tx_packet(void *bus, struct sk_buff *skb) @@ -207,30 +240,34 @@ static int hgic_usb_tx_packet(void *bus, struct sk_buff *skb) struct hgic_usb_buf *buf = NULL; struct hgic_usb *usbdev = container_of(bus, struct hgic_usb, bus); - if ((len & (usbdev->ep_out_size - 1)) == 0) { - len += 4; - } +#ifdef CONFIG_USB_ZERO_PACKET + if (IS_ALIGNED(len, usbdev->ep_out_size)) len += 4; +#endif + if (usbdev->status & (HGIC_USB_STATUS_STOP | HGIC_USB_STATUS_ERR)) { ret = -EIO; goto __fail; } ret = down_timeout(&usbdev->tx_sema, 1000); - if(ret){ + if (ret) { ret = -EIO; - goto __fail; + goto __fail; } - + + if (usbdev->status & (HGIC_USB_STATUS_STOP | HGIC_USB_STATUS_ERR)) { + ret = -EIO; + goto __fail; + } + buf = hgic_usb_deq(usbdev, &usbdev->tx_freeq); if (buf == NULL) { ret = -ENOMEM; goto __fail; } - buf->skb = skb; - usb_fill_bulk_urb(buf->urb, usbdev->udev, - usb_sndbulkpipe(usbdev->udev, usbdev->ep_out), - skb->data, len, /*ALIGN(skb->len, 4)*/ - hgic_usb_tx_complete, buf); + buf->data = skb; + usb_fill_bulk_urb(buf->urb, usbdev->udev, usb_sndbulkpipe(usbdev->udev, usbdev->ep_out), + skb->data, len, hgic_usb_tx_complete, buf); buf->urb->transfer_flags |= URB_ZERO_PACKET; ret = usb_submit_urb(buf->urb, GFP_ATOMIC); if (ret) { @@ -242,20 +279,13 @@ static int hgic_usb_tx_packet(void *bus, struct sk_buff *skb) __fail: if (buf) { + buf->data = NULL; hgic_usb_enq(buf, &usbdev->tx_freeq); } usbdev->bus.tx_complete(usbdev->bus.bus_priv, skb, 0); return ret; } -static struct hgic_bus hgic_bus_usb = { - .type = HGIC_BUS_USB, - .drv_tx_headroom = USB_TX_HEADROM, - .tx_packet = hgic_usb_tx_packet, - .bootdl_pktlen = 2048, - .bootdl_cksum = HGIC_BUS_BOOTDL_CHECK_0XFD, -}; - static int hgic_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { int i = 0; @@ -273,11 +303,16 @@ static int hgic_usb_probe(struct usb_interface *intf, const struct usb_device_id return -ENOMEM; } - memset(usbdev, 0, sizeof(struct hgic_usb)); usbdev->udev = udev; - usbdev->bus = hgic_bus_usb; + usbdev->bus.type = HGIC_BUS_USB; usbdev->bus.dev_id = id->idProduct; - usbdev->status = HGIC_USB_STATUS_STOP; + usbdev->bus.drv_tx_headroom = USB_TX_HEADROM; + usbdev->bus.tx_packet = hgic_usb_tx_packet; + usbdev->bus.bootdl_pktlen = 2048; + usbdev->bus.bootdl_cksum = HGIC_BUS_BOOTDL_CHECK_0XFD; + usbdev->bus.probe = probe_hdl; + + //usbdev->status = HGIC_USB_STATUS_STOP; for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; @@ -292,35 +327,41 @@ static int hgic_usb_probe(struct usb_interface *intf, const struct usb_device_id } } usbdev->bus.blk_size = usbdev->ep_out_size; - + spin_lock_init(&usbdev->qlock); INIT_LIST_HEAD(&usbdev->tx_freeq); INIT_LIST_HEAD(&usbdev->rx_freeq); INIT_LIST_HEAD(&usbdev->used); - ret = hgic_usb_qinit(usbdev, &usbdev->tx_freeq, txq_cnt); + ret = hgic_usb_qinit(usbdev, &usbdev->tx_freeq, txq_cnt, 0); sema_init(&usbdev->tx_sema, ret); hgic_dbg("usb txq:%d\r\n", ret); - ret = hgic_usb_qinit(usbdev, &usbdev->rx_freeq, rxq_cnt); + ret = hgic_usb_qinit(usbdev, &usbdev->rx_freeq, rxq_cnt, 1); hgic_dbg("usb rxq:%d\r\n", ret); - hgic_core_probe(&udev->dev, &usbdev->bus); + usbdev->bus.probe(&udev->dev, &usbdev->bus); if (!usbdev->bus.bus_priv) { ret = -ENOMEM; goto __failed; } + usb_get_dev(udev); + usb_set_intfdata(intf, usbdev); + //usbdev->status &= ~HGIC_USB_STATUS_STOP; + ret = hgic_usb_submit_rx_urbs(usbdev); if (ret) { goto __failed; } - usb_get_dev(udev); - usb_set_intfdata(intf, usbdev); - usbdev->status &= ~HGIC_USB_STATUS_STOP; - hgic_core_probe_post(usbdev->bus.bus_priv); + + if (usbdev->bus.probe_post) { + usbdev->bus.probe_post(usbdev->bus.bus_priv); + } return ret; __failed: - hgic_core_remove(usbdev->bus.bus_priv); + if (usbdev->bus.remove) { + usbdev->bus.remove(usbdev->bus.bus_priv); + } hgic_usb_free(usbdev); kfree(usbdev); return -1; @@ -329,14 +370,18 @@ __failed: static void hgic_usb_disconnect(struct usb_interface *intf) { struct hgic_usb *usbdev = usb_get_intfdata(intf); - hgic_dbg("hgic_usb_disconnect>>>>\r\n"); + hgic_dbg("Enter\n"); if (usbdev) { usbdev->status |= HGIC_USB_STATUS_STOP; - hgic_core_remove(usbdev->bus.bus_priv); + up(&usbdev->tx_sema); + if (usbdev->bus.remove) { + usbdev->bus.remove(usbdev->bus.bus_priv); + } hgic_usb_free(usbdev); kfree(usbdev); usb_set_intfdata(intf, NULL); } + hgic_dbg("Leave\n"); } static struct usb_driver hgic_usb_driver = { @@ -349,11 +394,15 @@ static struct usb_driver hgic_usb_driver = { .supports_autosuspend = 1, }; -int __init hgic_usb_init(void) +int __init hgic_usb_init(hgic_probe probe, u32 max_pkt) { int ret = 0; - hgic_dbg("Enter\n"); + hgic_dbg("Enter, max_pkt_len = %d\n", max_pkt_len); + probe_hdl = probe; + if(max_pkt > HGIC_PKT_MAX_LEN){ + max_pkt_len = max_pkt; + } ret = usb_register(&hgic_usb_driver); if (ret) { hgic_err("driver register failed: %d\n", ret); @@ -368,11 +417,4 @@ void __exit hgic_usb_exit(void) usb_deregister(&hgic_usb_driver); hgic_dbg("Leave\n"); } -#ifndef CONFIG_HGIC_USBIN -module_init(hgic_usb_init); -module_exit(hgic_usb_exit); -MODULE_DESCRIPTION("HUGE-IC WLAN Driver"); -MODULE_AUTHOR("Dongyun"); -MODULE_LICENSE("GPL"); -#endif diff --git a/utils/iwpriv.c b/utils/iwpriv.c new file mode 100644 index 0000000..6db0962 --- /dev/null +++ b/utils/iwpriv.c @@ -0,0 +1,1684 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "../hgic_def.h" +#include "utils.h" +#include "fwctrl.h" + +struct fwctrl_cfgset { + char *name; + int (*set)(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count); +}; +struct fwctrl_cfgget { + char *name; + int (*get)(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin); +}; + +static int hgic_copyfrom_iwreq(struct iwreq *wrqin, char *buf, int len) +{ + int ret = 0; + if (len > 0) { + memset(buf, 0, len); + len = (len <= wrqin->u.data.length ? len : wrqin->u.data.length); + if (ACCESS_OK(VERIFY_READ, wrqin->u.data.pointer, wrqin->u.data.length)) { + ret = copy_from_user(buf, wrqin->u.data.pointer, len); + } else { + memcpy(buf, wrqin->u.data.pointer, len); + } + } + return ret; +} + +static void hgic_copyto_iwreq(struct iwreq *wrqin, char *buf, int len) +{ + if (ACCESS_OK(VERIFY_WRITE, wrqin->u.data.pointer, len)) { + len = (len <= wrqin->u.data.length ? len : wrqin->u.data.length); + if (len > 0 && !__copy_to_user(wrqin->u.data.pointer, buf, len)) { + wrqin->u.data.length = (u16)len; + } else { + wrqin->u.data.length = 0; + } + } else { + if (len > 0) { + memcpy(wrqin->u.data.pointer, buf, len); + wrqin->u.data.length = (u16)len; + } else { + wrqin->u.data.length = 0; + } + } +} + +static int hgic_iwpriv_set_countryregion(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_countryregion(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_ssid(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_bssid(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 bssid[6]; + if (data == NULL || ifidx != HGIC_WDEV_ID_STA) { + return -EINVAL; + } + hgic_pick_macaddr(data, bssid); + return hgic_fwctrl_set_bssid(ctrl, ifidx, bssid); +} + +static int hgic_iwpriv_set_channel(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_channel(ctrl, ifidx, simple_strtol(data, 0, 10)); +} + +static int hgic_iwpriv_set_bssid_filter(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_bssid_filter(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_rts_threshold(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_rts_threshold(ctrl, ifidx, simple_strtol(data, 0, 10)); +} + +static int hgic_iwpriv_set_frag_threshold(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_frag_threshold(ctrl, ifidx, simple_strtol(data, 0, 10)); +} + +static int hgic_iwpriv_set_key_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_key_mgmt(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_wpa_psk(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_wpa_psk(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_freq_range(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 vals[3] = {0, 0, 0}; + u32 argcnt = 0; + + if (data == NULL || strlen(data) == 0) { + return -EINVAL; + } + hgic_pick_values(u32, data, vals, 3); + return hgic_fwctrl_set_freq_range(ctrl, ifidx, vals[0], vals[1], vals[2]); +} + +static int hgic_iwpriv_set_bss_bw(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 bss_bw = (u8)simple_strtol(data, 0, 10); + return hgic_fwctrl_set_bss_bw(ctrl, ifidx, bss_bw); +} + +static int hgic_iwpriv_set_tx_bw(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 tx_bw = (u8)simple_strtol(data, 0, 10); + return hgic_fwctrl_set_tx_bw(ctrl, ifidx, tx_bw); +} + +static int hgic_iwpriv_set_tx_mcs(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 tx_mcs = (u8)simple_strtol(data, 0, 10); + return hgic_fwctrl_set_tx_mcs(ctrl, ifidx, tx_mcs); +} + +static int hgic_iwpriv_set_acs(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u16 vals[2] = {0, 0}; + u32 argcnt = 0; + + if (data == NULL || strlen(data) == 0) { + return -EINVAL; + } + hgic_pick_values(u16, data, vals, 2); + return hgic_fwctrl_set_acs(ctrl, ifidx, vals[0], vals[1]); +} + +static int hgic_iwpriv_set_bgrssi(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 rssi = (u8)simple_strtol(data, 0, 10); + return hgic_fwctrl_set_bgrssi(ctrl, ifidx, rssi); +} + +static int hgic_iwpriv_set_chan_list(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u16 vals[32] = {0}; + u32 argcnt = 0; + + if (data == NULL || strlen(data) == 0) { + return -EINVAL; + } + hgic_pick_values(u16, data, vals, 32); + return hgic_fwctrl_set_chan_list(ctrl, ifidx, vals, argcnt); +} + +static int hgic_iwpriv_set_mode(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_mode(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_paired_stas(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 *mac = NULL; + int len = 0; + int ret = 0, i = 0; + char *ptr = data; + char *p = data; + + if (data == NULL || strlen(data) == 0) { + return -EINVAL; + } + + len = strlen(data); + mac = kzalloc(len, GFP_KERNEL); + if (mac == NULL) { + return -ENOMEM; + } + + hgic_dbg("set paired stas: %s\r\n", data); + while (p && *ptr) { + p = strchr(ptr, ','); + if(p) *p++ = 0; + if (hgic_pick_macaddr(ptr, mac + i * 6)) { + i++; + } else { + break; + } + ptr = p; + } + hgic_dbg("%d paired stas\r\n", i); + + ret = hgic_fwctrl_set_paired_stas(ctrl, ifidx, mac, i * 6); + kfree(mac); + return ret; +} + +static int hgic_iwpriv_set_pairing(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 number = 0; + + if (data == NULL) { + return -EINVAL; + } + number = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_pairing(ctrl, ifidx, number); +} + +static int hgic_iwpriv_set_beacon_int(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 beacon_int = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_beacon_int(ctrl, ifidx, beacon_int); +} + +static int hgic_iwpriv_set_radio_onoff(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + ctrl->radio_onoff = (u8)simple_strtol(data, 0, 10); + return hgic_fwctrl_radio_onoff(ctrl, ifidx, ctrl->radio_onoff); +} + +static int hgic_iwpriv_join_group(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 addr[6]; + u32 aid = 0; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_macaddr(data, addr); + aid = simple_strtol(data + 18, 0, 10); + return hgic_fwctrl_join_group(ctrl, ifidx, addr, aid); +} + +static int hgic_iwpriv_set_ethertype(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u16 type = 0; + + if (data == NULL) { + return -EINVAL; + } + type = simple_strtol(data, 0, 16); + return hgic_fwctrl_set_ethertype(ctrl, ifidx, type); +} + +static int hgic_iwpriv_set_txpower(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u16 type = 0; + + if (data == NULL) { + return -EINVAL; + } + type = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_txpower(ctrl, ifidx, type); +} + +static int hgic_iwpriv_set_aggcnt(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 agg[2]; //tx agg, rx agg + u32 argcnt = 0; + + if (data == NULL) { + return -EINVAL; + } + + hgic_pick_values(u8, data, agg, 2); + return hgic_fwctrl_set_agg_cnt(ctrl, ifidx, agg); +} +static int hgic_iwpriv_set_ps_connect(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 vals[2]; + u32 argcnt = 0; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_values(u8, data, vals, 2); + return hgic_fwctrl_set_ps_connect(ctrl, ifidx, vals[0], vals[1]); +} + +static int hgic_iwpriv_set_bss_max_idle(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 max_idle = 0; + + if (data == NULL) { + return -EINVAL; + } + max_idle = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_bss_max_idle(ctrl, ifidx, max_idle); +} + +static int hgic_iwpriv_set_dtim_period(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 period = 0; + + if (data == NULL) { + return -EINVAL; + } + period = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_dtim_period(ctrl, ifidx, period); +} + +static int hgic_iwpriv_set_wkio_mode(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 mode = 0; + + if (data == NULL) { + return -EINVAL; + } + mode = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_wkio_mode(ctrl, ifidx, mode); +} + +static int hgic_iwpriv_set_load_def(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 rst = 0; + + if (data == NULL) { + return -EINVAL; + } + rst = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_load_def(ctrl, ifidx, rst); +} + +static int hgic_iwpriv_set_disassoc_sta(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 addr[6]; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_macaddr(data, addr); + return hgic_fwctrl_disassoc_sta(ctrl, ifidx, addr); +} + +static int hgic_iwpriv_set_ps_mode(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 mode = 0; + + if (data == NULL) { + return -EINVAL; + } + mode = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_ps_mode(ctrl, ifidx, mode); +} + +static int hgic_iwpriv_set_aplost_time(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 time = 0; + + if (data == NULL) { + return -EINVAL; + } + time = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_aplost_time(ctrl, ifidx, time); +} + +static int hgic_iwpriv_set_unpair(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 addr[6]; + hgic_pick_macaddr(data, addr); + return hgic_fwctrl_unpair(ctrl, ifidx, addr); +} + +static int hgic_iwpriv_set_auto_chswitch(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data == NULL) { + return -EINVAL; + } + enable = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_auto_chswitch(ctrl, ifidx, enable == 1); +} + +static int hgic_iwpriv_set_mcast_key(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_mcast_key(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_reassoc_wkhost(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data == NULL) { + return -EINVAL; + } + enable = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_reassoc_wkhost(ctrl, ifidx, enable == 1); +} + +static int hgic_iwpriv_set_wakeup_io(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 vals[2] = {0, 0}; + u32 argcnt = 0; + + hgic_pick_values(u8, data, vals, 2); + return hgic_fwctrl_set_wakeup_io(ctrl, ifidx, vals[0], vals[1]); +} + +static int hgic_iwpriv_set_dbginfo_output(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data) { + enable = simple_strtol(data, 0, 10); + } + return hgic_fwctrl_set_dbginfo_output(ctrl, ifidx, enable == 1); +} + +static int hgic_iwpriv_set_sysdbg(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + if (data == NULL) { + return -EINVAL; + } + return hgic_fwctrl_set_sysdbg(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_primary_chan(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 chan = 0; + + if (data == NULL) { + return -EINVAL; + } + chan = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_primary_chan(ctrl, ifidx, chan); +} + +static int hgic_iwpriv_set_autosleep_time(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 time = 0; + + if (data == NULL) { + return -EINVAL; + } + time = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_autosleep_time(ctrl, ifidx, time); +} + +static int hgic_iwpriv_set_super_pwr(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data == NULL) { + return -EINVAL; + } + enable = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_super_pwr(ctrl, ifidx, enable); +} + +static int hgic_iwpriv_set_repeater_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_repeater_ssid(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_repeater_psk(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_repeater_psk(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_auto_save(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data == NULL) { + return -EINVAL; + } + enable = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_auto_save(ctrl, ifidx, enable); +} +static int hgic_iwpriv_set_pair_autostop(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data == NULL) { + return -EINVAL; + } + enable = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_pair_autostop(ctrl, ifidx, enable); +} +static int hgic_iwpriv_set_dcdc13v(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 enable = 0; + + if (data == NULL) { + return -EINVAL; + } + enable = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_dcdc13v(ctrl, ifidx, enable); +} +static int hgic_iwpriv_set_acktmo(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 tmo = 0; + + if (data == NULL) { + return -EINVAL; + } + tmo = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_acktmo(ctrl, ifidx, tmo); +} +static int hgic_iwpriv_set_pa_pwrctl_dis(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 dis = 0; + + if (data == NULL) { + return -EINVAL; + } + dis = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_pa_pwrctl_dis(ctrl, ifidx, dis); +} +static int hgic_iwpriv_set_dhcpc(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_dhcpc(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_wkdata_save(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_wkdata_save(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_mcast_txparam(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + struct hgic_mcast_txparam txparam; + u8 *vals = (u8 *)&txparam; + u32 argcnt = 0; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_values(u8, data, vals, 4); + return hgic_fwctrl_set_mcast_txparam(ctrl, ifidx, &txparam); +} + +static int hgic_iwpriv_set_resetsta(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 addr[6]; + + if (data == NULL || ifidx != HGIC_WDEV_ID_STA) { + return -EINVAL; + } + hgic_pick_macaddr(data, addr); + return hgic_fwctrl_reset_sta(ctrl, ifidx, addr); +} + +static int hgic_iwpriv_set_ant_auto(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_ant_auto(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_select_ant(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 ant = 0; + + if (data == NULL) { + return -EINVAL; + } + ant = simple_strtol(data, 0, 10); + return hgic_fwctrl_select_ant(ctrl, ifidx, ant); +} +static int hgic_iwpriv_set_wkhost_reasons(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 argcnt = 0; + u8 reasons[33]; + + if (data == NULL) { + return -EINVAL; + } + memset(reasons, 0, sizeof(reasons)); + hgic_pick_values(u8, data, reasons, 32); + return hgic_fwctrl_set_wkhost_reasons(ctrl, ifidx, reasons, argcnt + 1); //keep last one is 0. +} + +static int hgic_iwpriv_set_mac_filter(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_mac_filter(ctrl, ifidx, en); +} + +static int hgic_iwpriv_set_atcmd(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_atcmd(ctrl, ifidx, data); +} + +static int hgic_iwpriv_set_roaming(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + s8 vals[8]; + u32 argcnt = 0; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_values(s8, data, vals, sizeof(vals)); + return hgic_fwctrl_set_roaming(ctrl, ifidx, vals, argcnt); +} + +static int hgic_iwpriv_set_ap_hide(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 hide = 0; + + if (data == NULL) { + return -EINVAL; + } + hide = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_ap_hide(ctrl, ifidx, hide); +} + +static int hgic_iwpriv_set_max_txcnt(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 txcnt = 0; + + if (data == NULL) { + return -EINVAL; + } + txcnt = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_frm_tx_maxcnt(ctrl, ifidx, txcnt); +} +static int hgic_iwpriv_set_assert_holdup(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 holdup = 0; + + if (data == NULL) { + return -EINVAL; + } + holdup = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_assert_holdup(ctrl, ifidx, holdup); +} +static int hgic_iwpriv_set_ap_psmode(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_ap_psmode_en(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_dupfilter_en(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_dupfilter_en(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_dis_1v1m2u(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_1v1_m2u_dis(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_dis_psconnect(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = 0; + + if (data == NULL) { + return -EINVAL; + } + en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_psconnect_dis(ctrl, ifidx, en); +} +static int hgic_iwpriv_reset(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_reset(ctrl, ifidx); +} +static int hgic_iwpriv_set_heartbeat(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 ip[4] = {0}; + u32 port = 0; + u32 ipaddr = 0; + u32 period = 0; + u32 hb_tmo = 300; + + sscanf(data, "%d.%d.%d.%d,%d,%d,%d", &ip[0], &ip[1], &ip[2], &ip[3], &port, &period, &hb_tmo); + ipaddr = ((ip[0] & 0xff) << 24) | ((ip[1] & 0xff) << 16) | (((ip[2] & 0xff) << 8)) | (ip[3] & 0xff); + return hgic_fwctrl_set_ps_heartbeat(ctrl, ifidx, ipaddr, port, period, hb_tmo); +} +static int hgic_iwpriv_set_heartbeat_resp(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_ps_heartbeat_resp(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_set_wakeup_data(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_ps_wakeup_data(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_wakeup_sta(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 mac[6]; + hgic_pick_macaddr(data, mac); + hgic_err("wakeup sta: %pM\r\n", mac); + return hgic_fwctrl_wakeup_sta(ctrl, ifidx, mac); +} +static int hgic_iwpriv_send_custmgmt(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_send_cust_mgmt(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_send_mgmtframe(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_send_mgmtframe(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_set_wkdata_mask(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 len = count > 128 ? 128 : count; + return hgic_fwctrl_set_wkdata_mask(ctrl, ifidx, data[0], (u8 *)(data + 1), len - 1); +} +static int hgic_iwpriv_set_driverdata(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_cust_driver_data(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_set_freqinfo(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_freqinfo(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_set_blenc(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int ret = 0; + u8 vals[2]; + char *args; + u32 argcnt = 0; + + if (memcmp(data, "EN:", 3) == 0) { + args = data + 3; + hgic_pick_values(u8, args, vals, 2); + ret = hgic_fwctrl_set_blenc_en(ctrl, ifidx, vals); + } else if (memcmp(data, "DATA:", 5) == 0) { + ret = hgic_fwctrl_blenc_send_data(ctrl, ifidx, data + 5, count - 5); + } else if (memcmp(data, "DEV_ADDR:", 9) == 0) { + ret = hgic_fwctrl_blenc_set_devaddr(ctrl, ifidx, data + 9); + } else if (memcmp(data, "ADV_DATA:", 9) == 0) { + ret = hgic_fwctrl_blenc_set_advdata(ctrl, ifidx, data + 9, count - 9); + } else if (memcmp(data, "SCAN_RESP:", 10) == 0) { + ret = hgic_fwctrl_blenc_set_scanresp(ctrl, ifidx, data + 10, count - 10); + } else if (memcmp(data, "ADV_INT:", 8) == 0) { + ret = hgic_fwctrl_blenc_set_advinterval(ctrl, ifidx, simple_strtol(data + 8, 0, 10)); + } else if (memcmp(data, "ADV_EN:", 7) == 0) { + ret = hgic_fwctrl_blenc_start_adv(ctrl, ifidx, simple_strtol(data + 7, 0, 10)); + } else if (memcmp(data, "HCI_DATA:", 9) == 0) { + ret = hgic_fwctrl_send_hci_data(ctrl, data[9], data + 10, count - 10); + } else if (memcmp(data, "ADV_FILTER:", 11) == 0) { + ret = hgic_fwctrl_set_blenc_adv_filter(ctrl, ifidx, simple_strtol(data + 11, 0, 10)); + } else { + ret = -1; + } + return ret ? -EINVAL : 0; +} +static int hgic_iwpriv_enter_sleep(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int err = 0; + u32 vals[2] = {1, 0xffffffff}; + u32 argcnt = 0; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_values(u32, data, vals, 2); + if (vals[0]) { + if (!test_bit(HGIC_BUS_FLAGS_SLEEP, &ctrl->bus->flags)) { + if(ctrl->fwinfo->version < 0x02000000) vals[0] = 0xffff; + hgic_dbg("enter sleep : type:%d, sleep_ms:%d ...\r\n", vals[0], vals[1]); + err = hgic_fwctrl_enter_sleep(ctrl, ifidx, vals[0], vals[1]); + if (err) { + clear_bit(HGIC_BUS_FLAGS_SLEEP, &ctrl->bus->flags); + hgic_err("sleep fail, ret=%d\r\n", err); + } + } + } else { + hgic_dbg("exit sleep, SLEEP=%d\r\n", test_bit(HGIC_BUS_FLAGS_SLEEP, &ctrl->bus->flags)); + if (test_bit(HGIC_BUS_FLAGS_SLEEP, &ctrl->bus->flags)) { + clear_bit(HGIC_BUS_FLAGS_SLEEP, &ctrl->bus->flags); + if (ctrl->bus->reinit) { + ctrl->bus->reinit(ctrl->bus); + } + err = hgic_fwctrl_enter_sleep(ctrl, ifidx, 0, 0); + if (err) { + hgic_err("exit sleep fail, ret=%d\r\n", err); + } + } + } + return err ? -EINVAL : 0; +} +static int hgic_iwpriv_set_hwscan(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 argcnt = 0; + u16 vals[4]; + hgic_pick_values(u16, data, vals, 4); + return hgic_fwctrl_set_hwscan(ctrl, ifidx, vals[0], vals[1], vals[2], vals[3]); +} +static int hgic_iwpriv_set_user_edca(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 ac = data[0]; + struct hgic_txq_param txq; + memcpy(&txq, data + 1, sizeof(txq)); + return hgic_fwctrl_set_user_edca(ctrl, ifidx, ac, &txq); +} +static int hgic_iwpriv_set_fix_txrate(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 txrate = simple_strtoul(data, 0, 10); + return hgic_fwctrl_set_fix_txrate(ctrl, ifidx, txrate); +} +static int hgic_iwpriv_set_nav_max(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 nav = simple_strtoul(data, 0, 10); + return hgic_fwctrl_set_nav_max(ctrl, ifidx, nav); +} +static int hgic_iwpriv_clear_nav(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_clear_nav(ctrl, ifidx); +} +static int hgic_iwpriv_set_cca_param(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_cca_param(ctrl, ifidx, (struct hgic_cca_ctl *)data); +} +static int hgic_iwpriv_set_tx_modulation_gain(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_tx_modulation_gain(ctrl, ifidx, data, count); +} +static int hgic_iwpriv_set_rts_duration(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int duration = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_rts_duration(ctrl, ifidx, duration); +} +static int hgic_iwpriv_set_disable_print(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int dis = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_disable_print(ctrl, ifidx, dis); +} +static int hgic_iwpriv_set_conn_paironly(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int dis = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_conn_paironly(ctrl, ifidx, dis); +} +static int hgic_iwpriv_set_wait_psmode(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int mode = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_wait_psmode(ctrl, ifidx, mode); +} +static int hgic_iwpriv_set_diffcust_conn(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_diffcust_conn(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_standby(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 argcnt = 0; + u32 vals[2]; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_values(u32, data, vals, 2); + return hgic_fwctrl_set_standby(ctrl, ifidx, (u8)vals[0], vals[1]); +} +static int hgic_iwpriv_set_ap_chan_switch(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u8 argcnt = 0; + u8 vals[2]; + + if (data == NULL) { + return -EINVAL; + } + hgic_pick_values(u8, data, vals, 2); + return hgic_fwctrl_set_ap_chan_switch(ctrl, ifidx, vals[0], vals[1]); +} +static int hgic_iwpriv_set_cca_for_ce(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_cca_for_ce(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_rtc(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 rtc = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_rtc(ctrl, ifidx, rtc); +} +static int hgic_iwpriv_set_apep_padding(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_apep_padding(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_watchdog(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + u32 en = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_watchdog(ctrl, ifidx, en); +} +static int hgic_iwpriv_set_retry_fallback_cnt(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int cnt = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_retry_fallback_cnt(ctrl, ifidx, cnt); +} +static int hgic_iwpriv_set_fallback_mcs(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + struct hgic_fallback_mcs mcs; + u8 argcnt = 0; + u8 vals[4]; + hgic_pick_values(u8, data, vals, 4); + mcs.original_type = vals[0]; + mcs.original_mcs = vals[1]; + mcs.fallback_type = vals[2]; + mcs.fallback_mcs = vals[3]; + return hgic_fwctrl_set_fallback_mcs(ctrl, ifidx, &mcs); +} +static int hgic_iwpriv_set_xosc(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int val = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_xosc(ctrl, ifidx, val); +} +static int hgic_iwpriv_set_freq_cali_period(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int val = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_freq_cali_period(ctrl, ifidx, val); +} +static int hgic_iwpriv_set_customer_dvrdata(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + return hgic_fwctrl_set_bytes(ctrl, ifidx, get_unaligned_le16(data), data + 2, count - 2); +} +static int hgic_iwpriv_set_max_tx_delay(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int val = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_max_tx_delay(ctrl, ifidx, val); +} +static int hgic_iwpriv_set_heartbeat_int(struct hgic_fwctrl *ctrl, u8 ifidx, char *data, u32 count) +{ + int val = simple_strtol(data, 0, 10); + return hgic_fwctrl_set_heartbeat_int(ctrl, ifidx, val); +} + +static struct fwctrl_cfgset hgpriv_sets[] = { + {"country_region", hgic_iwpriv_set_countryregion}, + {"ssid", hgic_iwpriv_set_ssid}, + {"bssid", hgic_iwpriv_set_bssid}, + {"channel", hgic_iwpriv_set_channel}, + {"rts_threshold", hgic_iwpriv_set_rts_threshold}, + {"frag_threshold", hgic_iwpriv_set_frag_threshold}, + {"key_mgmt", hgic_iwpriv_set_key_mgmt}, + {"wpa_psk", hgic_iwpriv_set_wpa_psk}, + {"bssid_filter", hgic_iwpriv_set_bssid_filter}, + {"freq_range", hgic_iwpriv_set_freq_range}, + {"bss_bw", hgic_iwpriv_set_bss_bw}, + {"tx_bw", hgic_iwpriv_set_tx_bw}, + {"tx_mcs", hgic_iwpriv_set_tx_mcs}, + {"acs", hgic_iwpriv_set_acs}, + {"bgrssi", hgic_iwpriv_set_bgrssi}, + {"chan_list", hgic_iwpriv_set_chan_list}, + {"mode", hgic_iwpriv_set_mode}, + {"paired_stas", hgic_iwpriv_set_paired_stas}, + {"pairing", hgic_iwpriv_set_pairing}, + {"beacon_int", hgic_iwpriv_set_beacon_int}, + {"radio_onoff", hgic_iwpriv_set_radio_onoff}, + {"join_group", hgic_iwpriv_join_group}, + {"ether_type", hgic_iwpriv_set_ethertype}, + {"txpower", hgic_iwpriv_set_txpower}, + {"agg_cnt", hgic_iwpriv_set_aggcnt}, + {"ps_connect", hgic_iwpriv_set_ps_connect}, + {"bss_max_idle", hgic_iwpriv_set_bss_max_idle}, + {"wkio_mode", hgic_iwpriv_set_wkio_mode}, + {"loaddef", hgic_iwpriv_set_load_def}, + {"disassoc_sta", hgic_iwpriv_set_disassoc_sta}, + {"dtim_period", hgic_iwpriv_set_dtim_period}, + {"ps_mode", hgic_iwpriv_set_ps_mode}, + {"aplost_time", hgic_iwpriv_set_aplost_time}, + {"unpair", hgic_iwpriv_set_unpair}, + {"auto_chswitch", hgic_iwpriv_set_auto_chswitch}, + {"mcast_key", hgic_iwpriv_set_mcast_key}, + {"reassoc_wkhost", hgic_iwpriv_set_reassoc_wkhost}, + {"wakeup_io", hgic_iwpriv_set_wakeup_io}, + {"dbginfo", hgic_iwpriv_set_dbginfo_output}, + {"sysdbg", hgic_iwpriv_set_sysdbg}, + {"primary_chan", hgic_iwpriv_set_primary_chan}, + {"autosleep_time", hgic_iwpriv_set_autosleep_time}, + {"super_pwr", hgic_iwpriv_set_super_pwr}, + {"r_ssid", hgic_iwpriv_set_repeater_ssid}, + {"r_psk", hgic_iwpriv_set_repeater_psk}, + {"auto_save", hgic_iwpriv_set_auto_save}, + {"pair_autostop", hgic_iwpriv_set_pair_autostop}, + {"dcdc13", hgic_iwpriv_set_dcdc13v}, + {"acktmo", hgic_iwpriv_set_acktmo}, + {"pa_pwrctl_dis", hgic_iwpriv_set_pa_pwrctl_dis}, + {"dhcpc", hgic_iwpriv_set_dhcpc}, + {"wkdata_save", hgic_iwpriv_set_wkdata_save}, + {"mcast_txparam", hgic_iwpriv_set_mcast_txparam}, + {"reset_sta", hgic_iwpriv_set_resetsta}, + {"ant_auto", hgic_iwpriv_set_ant_auto}, + {"ant_sel", hgic_iwpriv_set_select_ant}, + {"wkhost_reason", hgic_iwpriv_set_wkhost_reasons}, + {"macfilter", hgic_iwpriv_set_mac_filter}, + {"atcmd", hgic_iwpriv_set_atcmd}, + {"roaming", hgic_iwpriv_set_roaming}, + {"ap_hide", hgic_iwpriv_set_ap_hide}, + {"max_txcnt", hgic_iwpriv_set_max_txcnt}, + {"assert_holdup", hgic_iwpriv_set_assert_holdup}, + {"ap_psmode", hgic_iwpriv_set_ap_psmode}, + {"dupfilter", hgic_iwpriv_set_dupfilter_en}, + {"dis_1v1m2u", hgic_iwpriv_set_dis_1v1m2u}, + {"dis_psconnect", hgic_iwpriv_set_dis_psconnect}, + {"reset", hgic_iwpriv_reset}, + {"heartbeat", hgic_iwpriv_set_heartbeat}, + {"heartbeat_resp", hgic_iwpriv_set_heartbeat_resp}, + {"wakeup_data", hgic_iwpriv_set_wakeup_data}, + {"wakeup", hgic_iwpriv_wakeup_sta}, + {"custmgmt", hgic_iwpriv_send_custmgmt}, + {"mgmtframe", hgic_iwpriv_send_mgmtframe}, + {"wkdata_mask", hgic_iwpriv_set_wkdata_mask}, + {"driverdata", hgic_iwpriv_set_driverdata}, + {"freqinfo", hgic_iwpriv_set_freqinfo}, + {"blenc", hgic_iwpriv_set_blenc}, + {"sleep", hgic_iwpriv_enter_sleep}, + {"hwscan", hgic_iwpriv_set_hwscan}, + {"user_edca", hgic_iwpriv_set_user_edca}, + {"fix_txrate", hgic_iwpriv_set_fix_txrate}, + {"nav_max", hgic_iwpriv_set_nav_max}, + {"clr_nav", hgic_iwpriv_clear_nav}, + {"cca_param", hgic_iwpriv_set_cca_param}, + {"tx_modgain", hgic_iwpriv_set_tx_modulation_gain}, + {"rts_duration", hgic_iwpriv_set_rts_duration}, + {"disable_print", hgic_iwpriv_set_disable_print}, + {"conn_paironly", hgic_iwpriv_set_conn_paironly}, + {"diffcust_conn", hgic_iwpriv_set_diffcust_conn}, + {"wait_psmode", hgic_iwpriv_set_wait_psmode}, + {"standby", hgic_iwpriv_set_standby}, + {"ap_chansw", hgic_iwpriv_set_ap_chan_switch}, + {"cca_ce", hgic_iwpriv_set_cca_for_ce}, + {"rtc", hgic_iwpriv_set_rtc}, + {"apep_padding", hgic_iwpriv_set_apep_padding}, + {"watchdog", hgic_iwpriv_set_watchdog}, + {"retry_fallback_cnt", hgic_iwpriv_set_retry_fallback_cnt}, + {"fallback_mcs", hgic_iwpriv_set_fallback_mcs}, + {"xosc", hgic_iwpriv_set_xosc}, + {"freq_cali_period", hgic_iwpriv_set_freq_cali_period}, + {"cust_drvdata", hgic_iwpriv_set_customer_dvrdata}, + {"max_txdelay", hgic_iwpriv_set_max_tx_delay}, + {"heartbeat_int", hgic_iwpriv_set_heartbeat_int}, + {NULL,} +}; + +int hgic_iwpriv_set_proc(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret = -ENOTSUPP; + char *ptr; + struct fwctrl_cfgset *set = NULL; + char *buff = kmalloc(wrqin->u.data.length + 1, GFP_KERNEL); + + if (buff == NULL) { + hgic_err("kmalloc fail\r\n"); + return -ENOMEM; + } + + if (hgic_copyfrom_iwreq(wrqin, buff, wrqin->u.data.length + 1) == 0) { + ptr = strchr(buff, '='); + if (ptr) { + *ptr++ = 0; + for (set = hgpriv_sets; set->name; set++) { + if (strcmp(buff, set->name) == 0) { + ret = set->set(ctrl, ifidx, ptr, wrqin->u.data.length - (ptr - buff)); + break; + } + } + } else { + hgic_err("invalid set cmd [%s]\r\n", buff); + } + } else { + hgic_err("copy_from_user fail\r\n"); + } + + kfree(buff); + return ret; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// +static int hgic_iwpriv_get_scan_list(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret = 0; + int i = 0; + int count = 0; + int len = 0; + 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(ctrl, ifidx, 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\n"); + for (i = 0; i < count; i++) { + len += sprintf(print_buf + len, "%pM\t%s\t%10s\t%10d\t%d\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; + } + hgic_copyto_iwreq(wrqin, print_buf, len); + kfree(buf); + kfree(print_buf); + return (0); +} + +static int hgic_iwpriv_get_sta_list(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int count = 0; + int len = 0; + int format = 0; + char *ptr; + char *buf = kzalloc(2048, GFP_ATOMIC); + char *print_buf = kzalloc(4096, GFP_ATOMIC); + 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; + } + + hgic_copyfrom_iwreq(wrqin, buf, 8); + ptr = strchr(buf, '='); + if (ptr) { + format = simple_strtol(ptr + 1, 0, 10); + } + + count = hgic_fwctrl_get_sta_list(ctrl, ifidx, (struct hgic_sta_info *)buf, (2048 / sizeof(struct hgic_sta_info))); + if (format == 1) { + hgic_copyto_iwreq(wrqin, buf, count * sizeof(struct hgic_sta_info)); + } else { + 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, tx_snr:%d, rx_snr:%d\r\n", + sta->aid, sta->addr, sta->ps, (s8)sta->rssi, (s8)sta->evm, (s8)sta->tx_snr, (s8)sta->rx_snr); + sta++; + } + } + hgic_copyto_iwreq(wrqin, print_buf, len); + } + + kfree(buf); + kfree(print_buf); + return (0); +} +static int hgic_iwpriv_get_mode(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int len = 0; + char mode[13]; + len = hgic_fwctrl_get_mode(ctrl, ifidx, mode, 12); + hgic_copyto_iwreq(wrqin, mode, len); + return (0); +} +static int hgic_iwpriv_get_ssid(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int len = 0; + char ssid[33]; + len = hgic_fwctrl_get_ssid(ctrl, ifidx, ssid, 32); + hgic_copyto_iwreq(wrqin, ssid, len); + return (0); +} +static int hgic_iwpriv_get_bssid(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char buf[24]; + char bssid[7]; + + memset(buf, 0, sizeof(buf)); + memset(bssid, 0, sizeof(bssid)); + if (hgic_fwctrl_get_bssid(ctrl, ifidx, bssid, 7) > 0) { + sprintf(buf, "%pM,%d", bssid, bssid[6]); + } + hgic_copyto_iwreq(wrqin, buf, strlen(buf)); + return (0); +} + +static int hgic_iwpriv_get_wpa_psk(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int len = 0; + char *buf = kzalloc(80, GFP_ATOMIC); + + if (buf == NULL) { + return -ENOMEM; + } + len = hgic_fwctrl_get_wpapsk(ctrl, ifidx, buf, 64); + hgic_copyto_iwreq(wrqin, buf, len); + kfree(buf); + return (0); +} + +static int hgic_iwpriv_get_txpower(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[4]; + int txpower = 0; + txpower = hgic_fwctrl_get_txpower(ctrl, ifidx); + sprintf(str, "%d", txpower); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_bss_bw(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[4]; + int bss_bw = 0; + bss_bw = hgic_fwctrl_get_bss_bw(ctrl, ifidx); + sprintf(str, "%d", bss_bw); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_aggcnt(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[32]; + int ret = 0; + u8 agg[2]; + + memset(agg, 0, sizeof(agg)); + ret = hgic_fwctrl_get_agg_cnt(ctrl, ifidx, agg, 2); + if (ret == 0xff) { + sprintf(str, "tx:%d,rx:%d", agg[0], agg[1]); + } else { + sprintf(str, "tx:%d,rx:0", ret); + } + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_chan_list(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int cnt = 0, i = 0; + int len = 0; + u16 chan_list[16]; + char *buf = kzalloc(128, GFP_KERNEL); + + if (buf) { + cnt = hgic_fwctrl_get_chan_list(ctrl, ifidx, chan_list, 16); + for (i = 0; i < cnt; i++) { + len += sprintf(buf + len, "%d,", chan_list[i]); + } + hgic_copyto_iwreq(wrqin, buf, len - 1); + kfree(buf); + } + return (0); +} + +static int hgic_iwpriv_get_freq_range(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[32] = {0}; + int ret; + u32 vals[3]; + + ret = hgic_fwctrl_get_freq_range(ctrl, ifidx, &vals[0], &vals[1], &vals[2]); + if (ret) { + sprintf(str, "%d,%d,%d", vals[0], vals[1], vals[2]); + } + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_key_mgmt(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int len = 0; + char str[32]; + len = hgic_fwctrl_get_key_mgmt(ctrl, ifidx, str, 32); + hgic_copyto_iwreq(wrqin, str, len); + return (0); +} + +static int hgic_iwpriv_get_battery_level(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[4]; + int val = 0; + + val = hgic_fwctrl_get_battery_level(ctrl, ifidx); + sprintf(str, "%d", val); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_module_type(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + u16 type = 0; + char str[12]; + + type = (u16)hgic_fwctrl_get_module_type(ctrl, ifidx); + if (type) { + sprintf(str, "%d", type); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + } + return (0); +} + +static int hgic_iwpriv_get_disassoc_reason(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int reason = 0; + + reason = hgic_fwctrl_get_disassoc_reason(ctrl, ifidx); + sprintf(str, "%d", reason); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_ant_sel(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int ant = 0; + + ant = hgic_fwctrl_get_ant_sel(ctrl, ifidx); + sprintf(str, "%d", ant); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_wkreason(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int reason = 0; + reason = hgic_fwctrl_get_wkreason(ctrl, ifidx); + sprintf(str, "%d", reason); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_wkdata_buff(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret; + char *buff = kmalloc(4096, GFP_KERNEL); + if (buff) { + ret = hgic_fwctrl_get_wkdata_buff(ctrl, ifidx, buff, 4096); + hgic_copyto_iwreq(wrqin, buff, ret); + kfree(buff); + } + return (0); +} + +static int hgic_iwpriv_get_temperature(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_temperature(ctrl); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_conn_state(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_conn_state(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_sta_count(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_sta_count(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_txq_param(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret = -1; + struct hgic_txq_param param[4]; + ret = hgic_fwctrl_get_txq_param(ctrl, ifidx, param); + if (ret == sizeof(param)) { + //printk("txq0: %d,%d,%d,%d\r\n", param[0].aifs, param[0].cw_min, param[0].cw_max, param[0].txop); + //printk("txq1: %d,%d,%d,%d\r\n", param[1].aifs, param[1].cw_min, param[1].cw_max, param[1].txop); + //printk("txq2: %d,%d,%d,%d\r\n", param[2].aifs, param[2].cw_min, param[2].cw_max, param[2].txop); + //printk("txq3: %d,%d,%d,%d\r\n", param[3].aifs, param[3].cw_min, param[3].cw_max, param[3].txop); + hgic_copyto_iwreq(wrqin, (char *)param, sizeof(param)); + } + return (ret == sizeof(param)) ? 0 : ret; +} + +static int hgic_iwpriv_get_nav(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_nav(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_rtc(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + u32 rtc = 0; + hgic_fwctrl_get_rtc(ctrl, ifidx, (u8 *)&rtc); + sprintf(str, "%u", rtc); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_bgrssi(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret; + char buff[64]; + char *ptr; + s8 resp[3] = { 0, 0, 0}; + + ret = hgic_copyfrom_iwreq(wrqin, buff, 64); + ptr = strchr(buff, '='); + if(ptr == NULL || ret) + return -EINVAL; + + ret = simple_strtoul(ptr + 1, 0, 10); + ret = hgic_fwctrl_get_bgrssi(ctrl, ifidx, ret, resp); + if (ret == 3) { + sprintf(buff, "%d,%d,%d", resp[0], resp[1], resp[2]); + hgic_copyto_iwreq(wrqin, buff, strlen(buff)); + } + return (0); +} + +static int hgic_iwpriv_get_center_freq(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_center_freq(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_acs_result(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int cnt = 0; + struct hgic_acs_result *result = kzalloc(32 * sizeof(struct hgic_acs_result), GFP_KERNEL); + if (result) { + cnt = hgic_fwctrl_get_acs_result(ctrl, ifidx, result, 32); + hgic_copyto_iwreq(wrqin, (char *)result, cnt); + kfree(result); + } + return (0); +} + +static int hgic_iwpriv_get_reason_code(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_reason_code(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static int hgic_iwpriv_get_status_code(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_status_code(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} +static int hgic_iwpriv_get_dhcpc_result(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + u32 result[6]; + int ret = hgic_fwctrl_get_dhcpc_result(ctrl, ifidx, (u8 *)result, sizeof(result)); + if (ret == 24) { + hgic_copyto_iwreq(wrqin, (char *)result, sizeof(result)); + return (0); + } + return ret; +} +static int hgic_iwpriv_get_xosc(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int temp = hgic_fwctrl_get_xosc(ctrl, ifidx); + sprintf(str, "%d", temp); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} +static int hgic_iwpriv_get_freq_offset(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret; + char buff[64]; + char *ptr; + char addr[6]; + + ret = hgic_copyfrom_iwreq(wrqin, buff, 64); + ptr = strchr(buff, '='); + if (ptr == NULL || ret) { + return -EINVAL; + } + + hgic_pick_macaddr(ptr + 1, addr); + ret = hgic_fwctrl_get_freq_offset(ctrl, ifidx, addr); + sprintf(buff, "%d", ret); + hgic_copyto_iwreq(wrqin, buff, strlen(buff)); + return (0); +} +static int hgic_iwpriv_get_fwinfo(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + hgic_copyto_iwreq(wrqin, (char *)ctrl->fwinfo, sizeof(struct hgic_fw_info)); + return (0); +} +static int hgic_iwpriv_get_sta_info(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + int ret; + char *ptr; + char buff[64]; + char addr[6]; + char format = 0; + struct hgic_sta_info stainfo; + char *print_buf = kzalloc(512, GFP_ATOMIC); + + if (print_buf == NULL) { + return -ENOMEM; + } + + ret = hgic_copyfrom_iwreq(wrqin, buff, 64); + ptr = strchr(buff, '='); + if (ptr == NULL || ret) { + kfree(print_buf); + return -EINVAL; + } + + hgic_pick_macaddr(ptr + 1, addr); + ptr = strchr(ptr, ','); + if (ptr) { + format = simple_strtol(ptr + 1, 0, 10); + } + + ret = hgic_fwctrl_get_sta_info(ctrl, ifidx, addr, &stainfo); + if (format == 1) { + hgic_copyto_iwreq(wrqin, (char *)&stainfo, ret); + } else { + if (ret > 0) { + ret = sprintf(print_buf, "aid:%d, %pM, ps:%d, rssi:%d, evm:%d, tx_snr:%d, rx_snr:%d\r\n", + stainfo.aid, stainfo.addr, stainfo.ps, (s8)stainfo.rssi, + (s8)stainfo.evm, (s8)stainfo.tx_snr, (s8)stainfo.rx_snr); + } + hgic_copyto_iwreq(wrqin, print_buf, ret); + } + kfree(print_buf); + return (0); +} +static int hgic_iwpriv_get_signal(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + char str[12]; + int signal = hgic_fwctrl_get_signal(ctrl, ifidx); + sprintf(str, "%d", signal); + hgic_copyto_iwreq(wrqin, str, strlen(str)); + return (0); +} + +static struct fwctrl_cfgget hgpriv_gets[] = { + {"mode", hgic_iwpriv_get_mode}, + {"sta_list", hgic_iwpriv_get_sta_list}, + {"scan_list", hgic_iwpriv_get_scan_list}, + {"ssid", hgic_iwpriv_get_ssid}, + {"bssid", hgic_iwpriv_get_bssid}, + {"wpa_psk", hgic_iwpriv_get_wpa_psk}, + {"txpower", hgic_iwpriv_get_txpower}, + {"agg_cnt", hgic_iwpriv_get_aggcnt}, + {"bss_bw", hgic_iwpriv_get_bss_bw}, + {"chan_list", hgic_iwpriv_get_chan_list}, + {"freq_range", hgic_iwpriv_get_freq_range}, + {"key_mgmt", hgic_iwpriv_get_key_mgmt}, + {"battery_level", hgic_iwpriv_get_battery_level}, + {"module_type", hgic_iwpriv_get_module_type}, + {"disassoc_reason", hgic_iwpriv_get_disassoc_reason}, + {"ant_sel", hgic_iwpriv_get_ant_sel}, + {"wkreason", hgic_iwpriv_get_wkreason}, + {"wkdata_buff", hgic_iwpriv_get_wkdata_buff}, + {"temperature", hgic_iwpriv_get_temperature}, + {"conn_state", hgic_iwpriv_get_conn_state}, + {"sta_count", hgic_iwpriv_get_sta_count}, + {"txq_param", hgic_iwpriv_get_txq_param}, + {"nav", hgic_iwpriv_get_nav}, + {"rtc", hgic_iwpriv_get_rtc}, + {"bgrssi", hgic_iwpriv_get_bgrssi}, + {"center_freq", hgic_iwpriv_get_center_freq}, + {"acs_result", hgic_iwpriv_get_acs_result}, + {"reason_code", hgic_iwpriv_get_reason_code}, + {"status_code", hgic_iwpriv_get_status_code}, + {"dhcpc_result", hgic_iwpriv_get_dhcpc_result}, + {"xosc", hgic_iwpriv_get_xosc}, + {"freq_offset", hgic_iwpriv_get_freq_offset}, + {"fwinfo", hgic_iwpriv_get_fwinfo}, + {"stainfo", hgic_iwpriv_get_sta_info}, + {"signal", hgic_iwpriv_get_signal}, + {NULL,} +}; + +int hgic_iwpriv_get_proc(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin) +{ + struct fwctrl_cfgget *get = NULL; + char *ptr; + char field[130]; + + memset(field, 0, sizeof(field)); + if (hgic_copyfrom_iwreq(wrqin, field, 128) == 0) { + ptr = strchr(field, '='); + if(ptr) *ptr = 0; + for (get = hgpriv_gets; get->name; get++) { + if (strcmp(field, get->name) == 0) { + return get->get(ctrl, ifidx, wrqin); + } + } + hgic_err("not support: [%s]\r\n", field); + } else { + hgic_err("copy_from_user fail\r\n"); + } + return -ENOTSUPP; +} + +int hgic_iwpriv_dump(struct hgic_fwctrl *ctrl, struct iwreq *wrqin) +{ + int len = 0; + struct fwctrl_cfgget *get = NULL; + struct fwctrl_cfgset *set = NULL; + + u8 *buf = kmalloc(4096, GFP_KERNEL); + if (buf) { + len += snprintf(buf + len, 4096 - len, "\r\nset:\r\n"); + for (set = hgpriv_sets; set->name; set++) { + len += snprintf(buf + len, 4096 - len, " %s\r\n", set->name); + } + len += snprintf(buf + len, 4096 - len, "get:\r\n"); + for (get = hgpriv_gets; get->name; get++) { + len += snprintf(buf + len, 4096 - len, " %s\r\n", get->name); + } + hgic_copyto_iwreq(wrqin, buf, len); + kfree(buf); + } + return len; +} + diff --git a/utils/iwpriv.h b/utils/iwpriv.h new file mode 100644 index 0000000..432d3a3 --- /dev/null +++ b/utils/iwpriv.h @@ -0,0 +1,11 @@ + +#ifndef _HGICF_CFG_H_ +#define _HGICF_CFG_H_ +#ifndef __RTOS__ +int hgic_iwpriv_set_proc(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin); +int hgic_iwpriv_get_proc(struct hgic_fwctrl *ctrl, u8 ifidx, struct iwreq *wrqin); +int hgic_iwpriv_dump(struct hgic_fwctrl *ctrl, struct iwreq *wrqin); + +#endif +#endif + diff --git a/utils/ota.c b/utils/ota.c index 54e3372..73333e1 100644 --- a/utils/ota.c +++ b/utils/ota.c @@ -42,14 +42,14 @@ static struct sk_buff *hgic_ota_send_packet_tmo(struct hgic_ota *ota, struct sk_ struct hgic_cmd_response resp; struct hgic_hdr *hdr = NULL; + resp.cookie = hgic_ctrl_cookie(ota->ctrl); + memset(&resp, 0, sizeof(resp)); hdr = (struct hgic_hdr *)skb_push(skb, sizeof(struct hgic_hdr)); - hdr->magic = HGIC_HDR_TX_MAGIC; + hdr->magic = cpu_to_le16(HGIC_HDR_TX_MAGIC); + hdr->length = cpu_to_le16(skb->len); + hdr->cookie = cpu_to_le16(resp.cookie); hdr->type = HGIC_HDR_TYPE_OTA; hdr->ifidx = HGIC_WDEV_ID_STA; - hdr->length = skb->len; - hdr->cookie = hgic_ctrl_cookie(ota->ctrl); - memset(&resp, 0, sizeof(resp)); - resp.cookie = hdr->cookie; hgic_fwctrl_send_data(ota->ctrl, skb, &resp, tmo); return resp.skb; } @@ -89,7 +89,7 @@ s32 hgic_ota_init(struct hgic_ota *ota, struct hgic_fwctrl *ctrl, struct hgic_fw static s32 hgic_ota_fill_hdr(struct hgic_ota *ota, struct sk_buff *skb, u32 offset) { struct hgic_ota_hdr *hdr = NULL; - u32 payload_len = 0; + u16 payload_len = 0; if (ota == NULL || skb == NULL || skb->len > ota->frag_size) { hgic_err("Input para error!\r\n"); @@ -103,12 +103,12 @@ static s32 hgic_ota_fill_hdr(struct hgic_ota *ota, struct sk_buff *skb, u32 offs hdr = (struct hgic_ota_hdr *)skb_push(skb, sizeof(struct hgic_ota_hdr)); memset(hdr, 0, sizeof(struct hgic_ota_hdr)); - hdr->chipid = ota->ori_fw_info->chip_id; - hdr->len = payload_len; - hdr->tot_len = ota->fw_len; - hdr->off = offset; - hdr->version = ota->ori_fw_info->version; - hdr->checksum = hgic_ota_check_sum(hdr->data, hdr->len); + hdr->chipid = cpu_to_le16(ota->ori_fw_info->chip_id); + hdr->len = cpu_to_le16(payload_len); + hdr->tot_len = cpu_to_le32(ota->fw_len); + hdr->off = cpu_to_le32(offset); + hdr->version = cpu_to_le32(ota->ori_fw_info->version); + hdr->checksum = cpu_to_le16(hgic_ota_check_sum(hdr->data, hdr->len)); return 0; } @@ -271,8 +271,8 @@ s32 hgic_ota_send_fw(struct hgic_ota *ota, char *fw_name, u32 tmo) skb_pull(resp, sizeof(struct hgic_hdr)); hdr = (struct hgic_ota_hdr *)resp->data; if (hdr->err_code) { - hgic_err("Responce Error:Error code:%d\n", hdr->err_code); - ret = hdr->err_code; + hgic_err("Responce Error:Error code:%d\n", le16_to_cpu(hdr->err_code)); + ret = le16_to_cpu(hdr->err_code); goto __failed; } else { hgic_dbg("OTA write to flash success!\n"); diff --git a/utils/utils.c b/utils/utils.c index e99ddb9..eca6b86 100644 --- a/utils/utils.c +++ b/utils/utils.c @@ -21,22 +21,12 @@ #define STATBUF_SIZE (64*1024) #define SAFE_DIV(a, b) (((b) == 0) ? 0 : ((a) / (b))) -int hgic_skip_padding(struct sk_buff *skb) +int hgic_skip_padding(u8* data) { int i = 0; - - for (i = 0; i < 3 && skb->data[i] == 0xFF; i++); - if (i) { - if (skb->len > 0) { - skb_pull(skb, i); - } else { - skb->data += i; - skb->tail += i; - } - } + for (i = 0; i < 3 && data[i] == 0xFF; i++); return i; } -EXPORT_SYMBOL(hgic_skip_padding); #if 0 int hgic_aligned_padding(struct sk_buff *skb) @@ -55,7 +45,6 @@ int hgic_aligned_padding(struct sk_buff *skb) } return count; } -EXPORT_SYMBOL(hgic_aligned_padding); #endif void hgic_print_hex(char *buf, int len) @@ -69,7 +58,6 @@ void hgic_print_hex(char *buf, int len) } printk("\r\n\r\n"); } -EXPORT_SYMBOL(hgic_print_hex); int hgic_config_read_int(char *conf, char *field) { @@ -79,7 +67,6 @@ int hgic_config_read_int(char *conf, char *field) } return 0; } -EXPORT_SYMBOL(hgic_config_read_int); int hgic_config_read_str(char *conf, char *field, char *str, int size) { @@ -94,7 +81,6 @@ int hgic_config_read_str(char *conf, char *field, char *str, int size) } return -1; } -EXPORT_SYMBOL(hgic_config_read_str); int hgic_config_read_u32_array(char *conf, char *field, u32 *arr, int count) { @@ -124,7 +110,6 @@ int hgic_config_read_u32_array(char *conf, char *field, u32 *arr, int count) return cnt; } -EXPORT_SYMBOL(hgic_config_read_u32_array); int hgic_config_read_u16_array(char *conf, char *field, u16 *arr, int count) { @@ -154,10 +139,10 @@ int hgic_config_read_u16_array(char *conf, char *field, u16 *arr, int count) return cnt; } -EXPORT_SYMBOL(hgic_config_read_u16_array); void hgic_clear_queue(struct sk_buff_head *q) { +#if 0 ulong flags = 0; struct sk_buff *skb = NULL; struct sk_buff *tmp = NULL; @@ -170,6 +155,13 @@ void hgic_clear_queue(struct sk_buff_head *q) } } spin_unlock_irqrestore(&q->lock, flags); +#else + struct sk_buff *skb = skb_dequeue(q); + while(skb){ + kfree_skb(skb); + skb = skb_dequeue(q); + } +#endif } int hgic_hex2num(char c) @@ -183,47 +175,48 @@ int hgic_hex2num(char c) if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } - return -1; + return 0; } - int hgic_hex2byte(const char *hex) { int a, b; a = hgic_hex2num(*hex++); - if (a < 0) { - return -1; - } b = hgic_hex2num(*hex++); - if (b < 0) { - return -1; - } return (a << 4) | b; } int hgic_pick_macaddr(char *mac_str, u8 *addr) { - int i = 0; - int val = 0; - const char *ptr = (const char *)mac_str; + int i = 0; + char tmp[20]; + char *ptr = tmp; + char *p = tmp; memset(addr, 0, 6); - while (ptr && i < 6 && strlen(mac_str) >= 17) { - if (i < 5 && ptr[2] != ':') { break; } - val = hgic_hex2byte(ptr); - if (val < 0) { break; } - addr[i++] = (u8)val; - ptr += 3; + memcpy(tmp, mac_str, 17); + while (ptr && *ptr && i < 6) { + p = strchr(ptr, ':'); + if(p) *p++ = 0; + addr[i++] = hgic_hex2byte(ptr); + ptr = p; } return (i == 6); } +void hgic_strip_tail(char *str, u32 len) +{ + u32 i = len - 1; + while (str[i] == '\r' || str[i] == '\n') { + str[i--] = 0; + } +} #if defined(__RTOS__) && defined(HGIC_SMAC) int umac_config_read(const char *name, char *buff, int size) { int ret = 0; - struct umac_config *cfg = sys_get_umaccfg(); + struct hgics_config *cfg = sys_get_umaccfg(); struct net_device *ndev = net_device_get_by_name(name); if (ndev == NULL) { @@ -246,7 +239,7 @@ int umac_config_read(const char *name, char *buff, int size) int umac_config_write(const char *name, char *buff, int size) { int ret = 0; - struct umac_config *cfg = sys_get_umaccfg(); + struct hgics_config *cfg = sys_get_umaccfg(); struct net_device *ndev = net_device_get_by_name(name); PRINTF("write %s:\r\n%s\r\n", name, buff); diff --git a/utils/utils.h b/utils/utils.h index 9714d96..f2490f0 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -165,7 +165,7 @@ struct hgic_fwstat { }; char *hgic_fwstat_print(u8 *stat_buf); -int hgic_skip_padding(struct sk_buff *skb); +int hgic_skip_padding(u8 *data); int hgic_aligned_padding(struct sk_buff *skb); void hgic_print_hex(char *buf, int len); int hgic_config_read_u32_array(char *conf, char *field, u32 *arr, int count); @@ -174,6 +174,8 @@ int hgic_config_read_str(char *conf, char *field, char *str, int size); int hgic_config_read_int(char *conf, char *field); void hgic_clear_queue(struct sk_buff_head *q); int hgic_hex2num(char c); +void hgic_strip_tail(char *str, u32 len); + int hgic_hex2byte(const char *hex); int hgic_pick_macaddr(char *mac_str, u8 *addr); diff --git a/version.h b/version.h index c8226e5..8c3e3ca 100644 --- a/version.h +++ b/version.h @@ -1 +1 @@ -#define SVN_VERSION "14988" +#define SVN_VERSION "24338"