garypang13 4 سال پیش
والد
کامیت
1e399e5229

+ 1 - 1
.github/workflows/Openwrt-AutoBuild.yml

@@ -150,7 +150,7 @@ jobs:
         cd openwrt
         find "devices/common/patches" -type f ! -path 'devices/common/patches/china_mirrors.patch' -name '*.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 -E --forward --no-backup-if-mismatch"
         if [ -n "$(ls -A "devices/${{matrix.target}}/patches" 2>/dev/null)" ]; then
-          find "devices/${{matrix.target}}/patches" -type f -name '*.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 -E --forward --no-backup-if-mismatch"
+          find "devices/${{matrix.target}}/patches" -type f -name '*.patch' ! -name '*.revert.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 -E --forward --no-backup-if-mismatch"
         fi
         
     - name: Default PPPOE Setting

+ 2 - 0
devices/common/diy.sh

@@ -53,6 +53,8 @@ sed -i "s/DISTRIB_DESCRIPTION.*/DISTRIB_DESCRIPTION='%D %V %C by GaryPang'/g" pa
 sed -i "s/# REVISION:=x/REVISION:= $date/g" include/version.mk
 sed -i '$a cgi-timeout = 300' package/feeds/packages/uwsgi/files-luci-support/luci-webui.ini
 
+patch -Rp1 < devices/common/patches/k2p.revert.patch
+
 if [ -f sdk.tar.xz ]; then
 	sed -i 's,$(STAGING_DIR_HOST)/bin/upx,upx,' package/feeds/custom/*/Makefile
 	mkdir sdk

+ 25 - 0
devices/common/patches/ipvlan.patch

@@ -0,0 +1,25 @@
+--- a/package/kernel/linux/modules/netdevices.mk
++++ b/package/kernel/linux/modules/netdevices.mk
+@@ -885,6 +885,22 @@ endef
+ $(eval $(call KernelPackage,macvlan))
+ 
+ 
++define KernelPackage/ipvlan
++  SUBMENU:=$(NETWORK_DEVICES_MENU)
++  TITLE:=IP-VLAN support
++  KCONFIG:=CONFIG_IPVLAN
++  FILES:=$(LINUX_DIR)/drivers/net/ipvlan/ipvlan.ko
++  AUTOLOAD:=$(call AutoProbe,ipvlan)
++endef
++
++define KernelPackage/ipvlan/description
++ A kernel module which allows one to create virtual interfaces that
++ map packets to or from specific IP addresses to a particular interface
++endef
++
++$(eval $(call KernelPackage,ipvlan))
++
++
+ define KernelPackage/tulip
+   TITLE:=Tulip family network device support
+   DEPENDS:=@PCI_SUPPORT +kmod-mii

+ 2960 - 0
devices/common/patches/k2p.revert.patch

@@ -0,0 +1,2960 @@
+--- a/package/feeds/custom/mt7615d/Makefile
++++ b/package/feeds/custom/mt7615d/Makefile
+@@ -11,5 +11,7 @@
+ PKG_VERSION:=5.0.4.0
+ 
+-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
++PKG_BUILD_PARALLEL:=1
++
++# PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
+ PKG_KCONFIG:= \
+ 	AP_SUPPORT \
+@@ -147,5 +149,4 @@
+ 	RT_THIRD_CARD_EEPROM \
+ 	SPECTRUM_SUPPORT \
+-	MULTI_PROFILE_SUPPORT \
+ 	PRE_CAL_TRX_SET1_SUPPORT \
+ 	MWDS \
+@@ -172,19 +173,21 @@
+ 	PCIE_ASPM_DYM_CTRL_SUPPORT \
+ 
+-PKG_CONFIG_DEPENDS:=$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c)))
++PKG_CONFIG_DEPENDS:=$(foreach c, $(PKG_KCONFIG), CONFIG_MTK_$(c) )
+ 
+ include $(INCLUDE_DIR)/package.mk
+ 
+-TAR_CMD=$(HOST_TAR) -C $(1)/ $(TAR_OPTIONS)
++# TAR_CMD=$(HOST_TAR) -C $(1)/ $(TAR_OPTIONS)
+ 
+ define KernelPackage/mt7615d
+   CATEGORY:=Kernel modules
+   TITLE:=MTK wifi AP driver
+-  DEPENDS:=@TARGET_ramips
++  DEPENDS:=@TARGET_ramips +MTK_CFG80211_SUPPORT:kmod-cfg80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT
+ ifneq ($(CONFIG_MTK_WHNAT_SUPPORT), )
+   FILES:=$(PKG_BUILD_DIR)/mt_wifi_ap/mt_wifi.ko \
+ 	$(PKG_BUILD_DIR)/mt_wifi/embedded/tools/plug_in/whnat/mt_whnat.ko
++  AUTOLOAD:=$(call AutoProbe,mt_wifi mt_whnat)
+ else
+   FILES:=$(PKG_BUILD_DIR)/mt_wifi_ap/mt_wifi.ko
++  AUTOLOAD:=$(call AutoProbe,mt_wifi)
+ endif
+   SUBMENU:=Wireless Drivers
+@@ -196,16 +199,54 @@
+ endef
+ 
++define KernelPackage/mt7615d_dbdc
++  CATEGORY:=Kernel modules
++  TITLE:=MTK wifi AP driver
++  DEPENDS:=@TARGET_ramips +kmod-mt7615d +maccalc
++  SUBMENU:=Wireless Drivers
++  MENU:=1
++endef
++
++define KernelPackage/mt7615d_dbdc/config
++	select MTK_WIFI_DRIVER
++	select MTK_FIRST_IF_MT7615E
++	select MTK_MT_WIFI
++	select MTK_WIFI_MT_MAC
++	select MTK_CHIP_MT7615E
++	select MTK_DBDC_MODE
++endef
++
++NOSTDINC_FLAGS = \
++	-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
++	-I$(STAGING_DIR)/usr/include/mac80211-backport \
++	-I$(STAGING_DIR)/usr/include/mac80211/uapi \
++	-I$(STAGING_DIR)/usr/include/mac80211 \
++	-include backport/autoconf.h \
++	-include backport/backport.h
++
+ define Build/Compile
+-	$(MAKE) -C "$(LINUX_DIR)" V=1 \
+-		CROSS_COMPILE="$(TARGET_CROSS)" \
+-		ARCH="$(LINUX_KARCH)" \
++	+$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
++		$(KERNEL_MAKE_FLAGS) \
++		$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c)=$(CONFIG_MTK_$(c)))) \
+ 		M="$(PKG_BUILD_DIR)/mt_wifi_ap" \
+-		$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c)=$(CONFIG_MTK_$(c)))) \
++		$(if $(CONFIG_MTK_CFG80211_SUPPORT),NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)") \
++		V=1 \
+ 		modules
+ endef
+ 
++define Build/Install
++        :
++endef
++
+ define KernelPackage/mt7615d/install
+-	$(INSTALL_DIR) $(1)/etc/wireless/mt7615/
++	:
++endef
++
++define KernelPackage/mt7615d_dbdc/install
++	$(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless $(1)/etc/uci-defaults
++	$(INSTALL_DATA) ./files/lib/wifi/mt_dbdc.sh $(1)/lib/wifi
++	$(INSTALL_BIN) ./files/lib/netifd/wireless/mt_dbdc.sh $(1)/lib/netifd/wireless
++	$(INSTALL_DATA) ./files/etc/uci-defaults/10_mt7615_dbdc $(1)/etc/uci-defaults/10_mt7615_dbdc
+ endef
+ 
+ $(eval $(call KernelPackage,mt7615d))
++$(eval $(call KernelPackage,mt7615d_dbdc))
+diff --git a/package/feeds/custom/mt7615d/config.in b/package/feeds/custom/mt7615d/config.in
+index 0c71a2da15d8..a5339ee7dcb8 100644
+--- a/package/feeds/custom/mt7615d/config.in
++++ b/package/feeds/custom/mt7615d/config.in
+@@ -273,25 +273,22 @@ config MTK_HDR_TRANS_RX_SUPPORT
+ config MTK_DBDC_MODE
+ 	bool "dbdc mode support"
+ 	depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7626
+-	select MULTI_PROFILE_SUPPORT
+-	select DEFAULT_5G_PROFILE
++	select MTK_MULTI_PROFILE_SUPPORT
+ 	default y if TARGET_ramips_mt7621_DEVICE_jcg_y2
+-	default y if TARGET_ramips_mt7621_DEVICE_phicomm_k2p
++	default y if TARGET_ramips_mt7621_DEVICE_phicomm_k2p || TARGET_DEVICE_ramips_mt7621_DEVICE_phicomm_k2p
+ 	default n
+ 
+ config MTK_MULTI_PROFILE_SUPPORT
+ 	bool "Multi Profile Support"
+ 	depends on MTK_DBDC_MODE
+-	default y if TARGET_ramips_mt7621_DEVICE_jcg_y2
+-	default y if TARGET_ramips_mt7621_DEVICE_phicomm_k2p
+ 	default n
+ 
+ config MTK_DEFAULT_5G_PROFILE
+ 	bool "5G default profile for DBDC"
+ 	depends on MTK_DBDC_MODE
+-#	depends on MTK_MULTI_PROFILE_SUPPORT
++	depends on !PACKAGE_kmod-mt7615d_dbdc
+ 	default y if TARGET_ramips_mt7621_DEVICE_jcg_y2
+-	default y if TARGET_ramips_mt7621_DEVICE_phicomm_k2p
++	default y if TARGET_ramips_mt7621_DEVICE_phicomm_k2p || TARGET_DEVICE_ramips_mt7621_DEVICE_phicomm_k2p
+ 	default n
+ 
+ config MTK_WSC_INCLUDED
+diff --git a/package/feeds/custom/mt7615d/files/etc/uci-defaults/10_mt7615_dbdc b/package/feeds/custom/mt7615d/files/etc/uci-defaults/10_mt7615_dbdc
+new file mode 100644
+index 000000000000..3bad18d41ea6
+--- /dev/null
++++ b/package/feeds/custom/mt7615d/files/etc/uci-defaults/10_mt7615_dbdc
+@@ -0,0 +1,9 @@
++#!/bin/sh
++
++# fix isolate
++sed -i 's/multicast_to_unicast:-1/multicast_to_unicast:-0/g' /lib/netifd/netifd-wireless.sh
++
++# generate default wireless config
++[ ! -f /etc/config/wireless ] && /sbin/wifi config
++
++exit 0
+diff --git a/package/feeds/custom/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh b/package/feeds/custom/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh
+new file mode 100644
+index 000000000000..394544f52f28
+--- /dev/null
++++ b/package/feeds/custom/mt7615d/files/lib/netifd/wireless/mt_dbdc.sh
+@@ -0,0 +1,895 @@
++#!/bin/sh
++#
++# Copyright (c) 2013-2015 D-Team Technology Co.,Ltd. ShenZhen
++# Copyright (c) 2005-2015, lintel <[email protected]>
++# Copyright (c) 2013, Hoowa <[email protected]>
++# Copyright (c) 2015-2017, GuoGuo <[email protected]>
++# Copyright (c) 2020, jjm2473 <[email protected]>
++#
++# 	netifd config script for MT7615 DBDC mode.
++#
++# 	嘿,对着屏幕的哥们,为了表示对原作者辛苦工作的尊重,任何引用跟借用都不允许你抹去所有作者的信息,请保留这段话。
++#
++. /lib/netifd/netifd-wireless.sh
++
++init_wireless_driver "$@"
++
++#Default configurations
++RTWIFI_PROFILE_DIR="/tmp/profiles/"
++RTWIFI_PROFILE_PATH=""
++RTWIFI_CMD_PATH=""
++RTWIFI_CMD_OPATH=""
++APCLI_IF=""
++APCLI_APCTRL=""
++WIFI_OP_LOCK=$RTWIFI_PROFILE_DIR"mt_dbdc.lock"
++RTWIFI_IFPREFIX=""
++RTWIFI_DEF_BAND=""
++RTWIFI_FORCE_HT=0
++RTWIFI_DEF_MAX_BSSID=4
++
++mt_cmd() {
++	echo "$@" >> $RTWIFI_CMD_PATH
++}
++
++#读取device相关设置项并写入json
++drv_mt_dbdc_init_device_config() { 
++	config_add_string channel hwmode htmode country macaddr
++	config_add_int beacon_int chanbw frag rts txburst
++	config_add_int rxantenna txantenna antenna_gain txpower distance wmm
++	config_add_boolean greenap diversity noscan ht_coex smart
++	config_add_int powersave
++	config_add_int maxassoc
++	config_add_boolean hidessid bndstrg
++	
++	config_add_boolean \
++		rxldpc \
++		short_gi_80 \
++		short_gi_160 \
++		tx_stbc_2by1 \
++		su_beamformer \
++		su_beamformee \
++		mu_beamformer \
++		mu_beamformee \
++		vht_txop_ps \
++		htc_vht \
++		rx_antenna_pattern \
++		tx_antenna_pattern
++	config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc
++	
++	config_add_boolean \
++		ldpc \
++		greenfield \
++		short_gi_20 \
++		short_gi_40 \
++		dsss_cck_40
++}
++
++#读取iface相关设置项并写入json
++drv_mt_dbdc_init_iface_config() { 
++	config_add_boolean disabled
++	config_add_string mode bssid ssid encryption
++	config_add_boolean hidden isolate doth ieee80211r
++	config_add_string key key1 key2 key3 key4
++	config_add_string wps
++	config_add_string pin
++	config_add_string macfilter
++	config_add_array maclist
++	
++	config_add_boolean wds
++	config_add_int max_listen_int
++	config_add_int dtim_period
++	config_add_int disassoc_low_ack rssiassoc
++	config_add_string wdsenctype wdskey wdsphymode
++	config_add_int wdswepid wdstxmcs
++}
++
++get_wep_key_type() {
++	local KeyLen=$(expr length "$1")
++	if [ $KeyLen -eq 10 ] || [ $KeyLen -eq 26 ]
++	then
++		echo 0
++	else
++		echo 1
++	fi	
++}
++
++mt_dbdc_ap_vif_pre_config() {
++	local name="$1"
++
++	json_select config
++	json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode wps pin isolate doth hidden disassoc_low_ack rssiassoc ieee80211r macfilter
++	json_get_values maclist maclist
++	json_select ..
++	[ "$disabled" == "1" ] && return
++	echo "Generating ap config for interface ra${RTWIFI_IFPREFIX}${ApBssidNum}"
++	ifname="ra${RTWIFI_IFPREFIX}${ApBssidNum}"
++
++	#MAC过滤方式相关设定 由于编号问题......我扔在这了......
++	ra_maclist="${maclist// /;};"
++	case "$macfilter" in
++	allow)
++		echo "Interface ${ifname} has MAC Policy.Allow list:${ra_maclist}"
++		echo "AccessPolicy${ApBssidNum}=1" >> $RTWIFI_PROFILE_PATH
++		echo "AccessControlList$ApBssidNum=${ra_maclist}" >> $RTWIFI_PROFILE_PATH
++	;;
++	deny)
++		echo "Interface ${ifname} has MAC Policy.Deny list:${ra_maclist}"
++		echo "AccessPolicy${ApBssidNum}=2" >> $RTWIFI_PROFILE_PATH
++		echo "AccessControlList${ApBssidNum}=${ra_maclist}" >> $RTWIFI_PROFILE_PATH
++	;;
++	esac
++
++	let ApBssidNum+=1
++	echo "SSID$ApBssidNum=${ssid}" >> $RTWIFI_PROFILE_PATH #SSID
++	case "$encryption" in #加密方式
++	wpa*|psk*|WPA*|Mixed|mixed)
++		local enc
++		local crypto
++		case "$encryption" in
++			Mixed|mixed|psk+psk2|psk-mixed*)
++				enc=WPAPSKWPA2PSK
++			;;
++			WPA2*|wpa2*|psk2*)
++				enc=WPA2PSK
++			;;
++			WPA*|WPA1*|wpa*|wpa1*|psk*)
++				enc=WPAPSK
++			;;
++			esac
++			crypto="AES"
++		case "$encryption" in
++			*tkip+aes*|*tkip+ccmp*|*aes+tkip*|*ccmp+tkip*)
++				crypto="TKIPAES"
++			;;
++			*aes*|*ccmp*)
++				crypto="AES"
++			;;
++			*tkip*) 
++				crypto="TKIP"
++				echo "Warning!!! TKIP is not support in 802.11n 40Mhz!!!"
++			;;
++			esac
++				ApAuthMode="${ApAuthMode}${enc};"
++				ApEncrypType="${ApEncrypType}${crypto};"
++				ApDefKId="${ApDefKId}2;"
++			echo "WPAPSK$ApBssidNum=${key}" >> $RTWIFI_PROFILE_PATH
++	;;
++	WEP|wep|wep-open|wep-shared)
++		if [ "$encryption" == "wep-shared" ]; then
++			ApAuthMode="${ApAuthMode}SHARED;"
++		else  
++			ApAuthMode="${ApAuthMode}OPEN;"
++		fi
++		ApEncrypType="${ApEncrypType}WEP;"
++		K1Tp=$(get_wep_key_type "$key1")
++		K2Tp=$(get_wep_key_type "$key2")
++		K3Tp=$(get_wep_key_type "$key3")
++		K4Tp=$(get_wep_key_type "$key4")
++
++		[ $K1Tp -eq 1 ] && key1=$(echo $key1 | cut -d ':' -f 2- )
++		[ $K2Tp -eq 1 ] && key2=$(echo $key2 | cut -d ':' -f 2- )
++		[ $K3Tp -eq 1 ] && key3=$(echo $key3 | cut -d ':' -f 2- )
++		[ $K4Tp -eq 1 ] && key4=$(echo $key4 | cut -d ':' -f 2- )
++		echo "Key1Str${ApBssidNum}=${key1}" >> $RTWIFI_PROFILE_PATH
++		echo "Key2Str${ApBssidNum}=${key2}" >> $RTWIFI_PROFILE_PATH
++		echo "Key3Str${ApBssidNum}=${key3}" >> $RTWIFI_PROFILE_PATH
++		echo "Key4Str${ApBssidNum}=${key4}" >> $RTWIFI_PROFILE_PATH
++		ApDefKId="${ApDefKId}${key};"
++		;;
++	none|open)
++		ApAuthMode="${ApAuthMode}OPEN;"
++		ApEncrypType="${ApEncrypType}NONE;"
++		ApDefKId="${ApDefKId}1;"
++		;;
++	esac
++	ApHideESSID="${ApHideESSID}${hidden:-0};"
++	ApK1Tp="${ApK1Tp}${K1Tp:-0};"
++	ApK2Tp="${ApK2Tp}${K2Tp:-0};"
++	ApK3Tp="${ApK3Tp}${K3Tp:-0};"
++	ApK4Tp="${ApK4Tp}${K4Tp:-0};"
++
++	mt_cmd ifconfig $ifname up
++	mt_cmd echo "Interface $ifname now up."
++	mt_cmd iwpriv $ifname set NoForwarding=${isolate:-0}
++	mt_cmd iwpriv $ifname set IEEE80211H=${doth:-0}
++	if [ "$wps" == "pbc" ]  && [ "$encryption" != "none" ]; then
++		echo "Enable WPS for ${ifname}."
++		mt_cmd iwpriv $ifname set WscConfMode=4
++		mt_cmd iwpriv $ifname set WscConfStatus=2
++		mt_cmd iwpriv $ifname set WscMode=2
++		mt_cmd iwpriv $ifname set WscV2Support=0
++	else
++		mt_cmd iwpriv $ifname set WscConfMode=0
++	fi
++	[ -n "$disassoc_low_ack" ]  && [ "$disassoc_low_ack" != "0" ] && mt_cmd iwpriv $ifname set KickStaRssiLow=$disassoc_low_ack
++	[ -n "$rssiassoc" ]  && [ "$rssiassoc" != "0" ] && mt_cmd iwpriv $ifname set AssocReqRssiThres=$rssiassoc
++	[ -n "$ieee80211r" ]  && [ "$ieee80211r" != "0" ] && mt_cmd iwpriv $ifname set ftenable=1
++}
++
++mt_dbdc_wds_vif_pre_config() {
++	local name="$1"
++
++	json_select config
++	json_get_vars disabled bssid wdsenctype wdskey wdswepid wdsphymode wdstxmcs
++	set_default wdswepid 1
++	set_default wdstxmcs 33
++	set_default wdsphymode "GREENFIELD"
++	json_select ..
++	[ "$disabled" == "1" ] && return
++	[ $WDSBssidNum -gt 3 ] && return
++	ifname="wds${RTWIFI_IFPREFIX}${WDSBssidNum}"
++	echo "Generating WDS config for interface $ifname"
++	WDSEN=1
++	WDSList="${WDSList}${bssid};"
++	WDSEncType="${WDSEncType}${wdsenctype};"
++	WDSDefKeyID="${WDSDefKeyID}${wdswepid};"
++	WDSPhyMode="${WDSPhyMode}${wdsphymode};"
++	WDSTxMCS="${WDSTxMCS}${wdstxmcs};"
++	echo "Wds${ApBssidNum}Key=${wdskey}" >> $RTWIFI_PROFILE_PATH #WDS Key
++	let WDSBssidNum+=1
++
++	mt_cmd ifconfig $ifname up
++	mt_cmd echo "WDS interface $ifname now up."
++}
++
++mt_dbdc_sta_vif_pre_config() {
++	local name="$1"
++
++	json_select config
++	json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode bssid
++	json_select ..
++
++	[ $stacount -gt 1 ] && {
++		return
++	}
++
++	[ "$disabled" == "1" ] && return
++	let stacount+=1
++
++	mt_cmd ifconfig $APCLI_IF up
++	killall  $APCLI_APCTRL
++	[ ! -z "$key" ] && APCTRL_KEY_ARG="-k"
++	[ ! -z "$bssid" ] && APCTRL_BSS_ARG="-b $(echo $bssid | tr 'A-Z' 'a-z')"
++	mt_cmd $APCLI_APCTRL ra${RTWIFI_IFPREFIX}0 connect -s "$ssid" $APCTRL_BSS_ARG $APCTRL_KEY_ARG "$key"
++}
++
++mt_dbdc_wds_vif_post_config() {
++	local name="$1"
++	json_select config
++	json_get_vars disabled
++	json_select ..
++
++	[ "$disabled" == "1" ] && return
++	[ $WDSBssidNum -gt 3 ] && return
++
++	ifname="wds${RTWIFI_IFPREFIX}${WDSBssidNum}"
++	let WDSBssidNum+=1
++
++	wireless_add_vif "$name" "$ifname"
++}
++
++mt_dbdc_ap_vif_post_config() {
++	local name="$1"
++
++	json_select config
++	json_get_vars disabled encryption key key1 key2 key3 key4 ssid mode wps pin isolate doth hidden disassoc_low_ack rssiassoc ieee80211r
++	json_select ..
++
++	[ "$disabled" == "1" ] && return
++
++	[ $ApIfCNT -gt $RTWIFI_DEF_MAX_BSSID ] && return 
++
++	ifname="ra${RTWIFI_IFPREFIX}${ApIfCNT}"
++	let ApIfCNT+=1
++
++	wireless_add_vif "$name" "$ifname"
++}
++
++mt_dbdc_sta_vif_post_config() {
++	local name="$1"
++
++	json_select config
++	json_get_vars disabled
++	json_select ..
++
++	[ $stacount -gt 1 ] && {
++		return
++	}
++
++	[ "$disabled" == "1" ] && return
++	let stacount+=1
++
++	wireless_add_vif "$name" "$APCLI_IF"
++}
++
++get_if_stat() {
++	[ ! -z "$1" ] && [ -d "/sys/class/net/$1" ] && cat /sys/class/net/$1/operstate
++}
++
++mt_dbdc_vif_down() {
++	phy_name=${1}
++	killall -9 -q apcli_2g
++	killall -9 -q apcli_5g
++	case "$phy_name" in
++		rax0)
++			for vif in ra0 ra1 ra2 ra3 ra4 ra5 ra6 ra7 wds0 wds1 wds2 wds3 apcli0; do
++				[ "$(get_if_stat $vif)" != "down" ] && ifconfig $vif down && echo $vif
++			done
++		;;
++		ra0)
++			for vif in rax0 rax1 rax2 rax3 rax4 rax5 rax6 rax7 wdsx0 wdsx1 wdsx2 wdsx3 apclix0; do
++				[ "$(get_if_stat $vif)" != "down" ] && ifconfig $vif down && echo $vif
++			done
++		;;
++	esac
++}
++
++drv_mt_dbdc_cleanup() {
++	return
++}
++
++drv_mt_dbdc_teardown() {
++	phy_name=${1}
++	case "$phy_name" in
++		ra0)
++			killall -9 -q apcli_2g
++			for vif in ra0 ra1 ra2 ra3 ra4 ra5 ra6 ra7 wds0 wds1 wds2 wds3 apcli0; do
++				# iwpriv $vif set DisConnectAllSta=1
++				[ -d "/sys/class/net/$vif" ] && ifconfig $vif down
++			done
++		;;
++		rax0)
++			killall -9 -q apcli_5g
++			for vif in rax0 rax1 rax2 rax3 rax4 rax5 rax6 rax7 wdsx0 wdsx1 wdsx2 wdsx3 apclix0; do
++				# iwpriv $vif set DisConnectAllSta=1
++				[ -d "/sys/class/net/$vif" ] && ifconfig $vif down
++			done
++		;;
++	esac
++}
++
++#接口启动
++drv_mt_dbdc_setup() {
++	json_select config
++	json_get_vars main_if macaddr channel mode hwmode wmm htmode \
++		txpower country macfilter maclist greenap \
++		diversity frag rts txburst distance hidden \
++		disabled maxassoc noscan ht_coex smart #device所有配置项
++		
++	json_get_vars \
++			ldpc:1 \
++			greenfield:0 \
++			short_gi_20:1 \
++			short_gi_40:1 \
++			tx_stbc:1 \
++			rx_stbc:3 \
++			max_amsdu:1 \
++			dsss_cck_40:1
++			
++	json_get_vars \
++			rxldpc:1 \
++			short_gi_80:1 \
++			short_gi_160:1 \
++			tx_stbc_2by1:1 \
++			su_beamformer:1 \
++			su_beamformee:1 \
++			mu_beamformer:1 \
++			mu_beamformee:1 \
++			vht_txop_ps:1 \
++			htc_vht:1 \
++			rx_antenna_pattern:1 \
++			tx_antenna_pattern:1 \
++			vht_max_a_mpdu_len_exp:7 \
++			vht_max_mpdu:11454 \
++			rx_stbc:4 \
++			vht_link_adapt:3 
++
++	json_select ..
++
++	phy_name=${1}
++	wireless_set_data phy=${phy_name}
++	case "$phy_name" in
++		ra0)
++			WirelessMode=9
++			APCLI_IF="apcli0"
++			APCLI_APCTRL="apcli_2g"
++			RTWIFI_IFPREFIX=""
++			RTWIFI_DEF_BAND="g"
++			RTWIFI_PROFILE_PATH="${RTWIFI_PROFILE_DIR}mt_dbdc_2g.dat"
++			RTWIFI_CMD_PATH="${RTWIFI_PROFILE_DIR}mt_dbdc_cmd_2g.sh"
++			RTWIFI_CMD_OPATH="${RTWIFI_PROFILE_DIR}mt_dbdc_cmd_5g.sh"
++		;;
++		rax0)
++			WirelessMode=14
++			APCLI_IF="apclix0"
++			APCLI_APCTRL="apcli_5g"
++			RTWIFI_IFPREFIX="x"
++			RTWIFI_DEF_BAND="a"
++			RTWIFI_PROFILE_PATH="${RTWIFI_PROFILE_DIR}mt_dbdc_5g.dat"
++			RTWIFI_CMD_PATH="${RTWIFI_PROFILE_DIR}mt_dbdc_cmd_5g.sh"
++			RTWIFI_CMD_OPATH="${RTWIFI_PROFILE_DIR}mt_dbdc_cmd_2g.sh"
++		;;
++		*)
++			echo "Unknown phy:$phy_name"
++			return 1
++	esac
++
++#检查配置文件目录是否存在,否则创建目录
++	[ ! -d $RTWIFI_PROFILE_DIR ] && mkdir $RTWIFI_PROFILE_DIR
++	echo > $RTWIFI_CMD_PATH
++
++	hwmode=${hwmode##11}
++	case "$hwmode" in
++		a)
++			WirelessMode=14
++			ITxBfEn=1
++			HT_HTC=1
++		;;
++		g)
++			WirelessMode=9
++			ITxBfEn=0
++			HT_HTC=1
++		;;
++		*) 
++			echo "Unknown wireless mode.Use default value:${WirelessMode}"
++			hwmode=${RTWIFI_DEF_BAND}
++		;;
++	esac
++	
++#HT默认模式设定
++	HT_BW=1  #允许HT40
++	HT_CE=1  #允许HT20/40共存
++	HT_DisallowTKIP=0 #是否允许TKIP加密
++	HT_GI=1 #HT_SHORT_GI
++	VHT_SGI=1 #VHT_SHORT_GI
++	#HT_MIMOPSMode用于省电模式设置
++	#HT_MIMOPSMode=3
++	
++#VHT默认模式设定
++	VHT_BW=1 #允许VHT
++	VHT_DisallowNonVHT=0 #是否禁止非VHT客户端连接,VHT80 only
++	
++	[ "$short_gi_20" == "0" -o "$short_gi_40" == "0" ] && HT_GI=0
++	[ "$short_gi_80" == "0" -o "$short_gi_160" == "0" ] && VHT_SGI=0
++	
++	case "$htmode" in
++		HT20 |\
++		VHT20) 
++			HT_BW=0
++			VHT_BW=0
++		;;
++		HT40 |\
++		VHT40)
++			HT_BW=1
++			VHT_BW=0
++			VHT_DisallowNonVHT=0
++		;;
++		HT80 |\
++		VHT80)
++			HT_BW=1
++			VHT_BW=1
++		;;
++		
++		VHT160)
++			echo "only VHT80 support!!"
++			HT_BW=1
++			VHT_BW=1
++		;;
++		*) 
++		echo "Unknown HT Mode."
++		;;
++	esac
++	
++#仅HT20以外才需要设置的参数
++     [ "$htmode" != "HT20" ] && {
++#强制HT40/VHT80
++		[ "$noscan" == "1" ] && HT_CE=0 && RTWIFI_FORCE_HT=1
++#HT HTC
++		[ "$ht_htc" == "1" ] && HT_HTC=1
++    }
++
++#自动处理CountryRegion:指定信道的时候支持全频段
++      [ "$channel" != "auto" ] && {
++		#CountryRegion CN
++		countryregion=5
++		countryregion_a=7
++      }
++
++#信道相关
++	case "$hwmode" in
++		a)
++			EXTCHA=1
++			[ "$channel" != "auto" ] && [ "$channel" != "0" ] && [ "$(( ($channel / 4) % 2 ))" == "0" ] && EXTCHA=0
++			[ "$channel" == "165" ] && EXTCHA=0
++			[ "$channel" == "auto" -o "$channel" == "0" ] && {
++				#CountryRegion CN
++				countryregion=1
++				countryregion_a=0
++				channel=149
++				AutoChannelSelect=2
++			}
++			ACSSKIP="36;38;40;42;44;46;48;52;56;60;64;100;104;108;112;116;120;124;128;132;136;140;165"
++		;;
++		g)
++			EXTCHA=0
++			[ "$channel" != "auto" ] && [ "$channel" != "0" ] && [ "$channel" -lt "7" ] && EXTCHA=1
++			[ "$channel" == "auto" -o "$channel" == "0" ] && {
++				channel=6
++				AutoChannelSelect=2
++				countryregion=1
++			}
++			ACSSKIP="12;13;14"
++		;;
++	esac
++
++#设备配置文件生成
++	cat > $RTWIFI_PROFILE_PATH <<EOF
++#The word of "Default" must not be removed
++Default
++DBDC_MODE=1
++BssidNum=${RTWIFI_DEF_MAX_BSSID}
++MacAddress=${macaddr}
++CountryRegion=${countryregion:-5}
++CountryRegionABand=${countryregion_a:-7}
++CountryCode=${country:-CN}
++WirelessMode=${WirelessMode}
++G_BAND_256QAM=1
++FixedTxMode=
++TxRate=0
++Channel=${channel}
++BasicRate=15
++BeaconPeriod=100
++DtimPeriod=1
++PERCENTAGEenable=1
++TxPower=${txpower:-100}
++SKUenable=1
++BFBACKOFFenable=0
++CalCacheApply=0
++DisableOLBC=0
++BGProtection=0
++TxAntenna=
++RxAntenna=
++TxPreamble=1
++RTSThreshold=${rts:-2347}
++FragThreshold=${frag:-2346}
++TxBurst=${txburst:-0}
++PktAggregate=1
++AutoProvisionEn=0
++FreqDelta=0
++TurboRate=0
++WmmCapable=${wmm:-0}
++APAifsn=3;7;1;1
++APCwmin=4;4;3;2
++APCwmax=6;10;4;3
++APTxop=0;0;94;47
++APACM=0;0;0;0
++BSSAifsn=3;7;2;2
++BSSCwmin=4;4;3;2
++BSSCwmax=10;10;4;3
++BSSTxop=0;0;94;47
++BSSACM=0;0;0;0
++AckPolicy=0;0;0;0
++APSDCapable=0
++DLSCapable=0
++NoForwarding=0
++NoForwardingBTNBSSID=0
++ShortSlot=1
++AutoChannelSelect=${AutoChannelSelect:-0}
++IEEE8021X=0
++IEEE80211H=0
++CarrierDetect=0
++ITxBfEn=${ITxBfEn}
++PreAntSwitch=
++PhyRateLimit=0
++DebugFlags=0
++ETxBfEnCond=${ITxBfEn}
++ITxBfTimeout=0
++ETxBfTimeout=0
++ETxBfNoncompress=0
++ETxBfIncapable=0
++MUTxRxEnable=3
++DfsEnable=0
++DfsZeroWait=0
++DfsZeroWaitCacTime=255
++FineAGC=0
++StreamMode=0
++StreamModeMac0=
++StreamModeMac1=
++StreamModeMac2=
++StreamModeMac3=
++CSPeriod=6
++RDRegion=
++StationKeepAlive=0
++DfsLowerLimit=0
++DfsUpperLimit=0
++DfsOutdoor=0
++SymRoundFromCfg=0
++BusyIdleFromCfg=0
++DfsRssiHighFromCfg=0
++DfsRssiLowFromCfg=0
++DFSParamFromConfig=0
++FCCParamCh0=
++FCCParamCh1=
++FCCParamCh2=
++FCCParamCh3=
++CEParamCh0=
++CEParamCh1=
++CEParamCh2=
++CEParamCh3=
++JAPParamCh0=
++JAPParamCh1=
++JAPParamCh2=
++JAPParamCh3=
++JAPW53ParamCh0=
++JAPW53ParamCh1=
++JAPW53ParamCh2=
++JAPW53ParamCh3=
++FixDfsLimit=0
++LongPulseRadarTh=0
++AvgRssiReq=0
++DFS_R66=0
++BlockCh=
++PreAuth=0
++WapiPsk1=0123456789
++WapiPsk2=
++WapiPsk3=
++WapiPsk4=
++WapiPsk5=
++WapiPsk6=
++WapiPsk7=
++WapiPsk8=
++WapiPskType=0
++Wapiifname=
++WapiAsCertPath=
++WapiUserCertPath=
++WapiAsIpAddr=
++WapiAsPort=
++RekeyMethod=DISABLE
++RekeyInterval=3600
++PMKCachePeriod=10
++MeshAutoLink=0
++MeshAuthMode=
++MeshEncrypType=
++MeshDefaultkey=0
++MeshWEPKEY=
++MeshWPAKEY=
++MeshId=
++HSCounter=0
++HT_HTC=${HT_HTC}
++HT_RDG=1
++HT_LDPC=${ldpc:-1}
++HT_LinkAdapt=0
++HT_OpMode=${greenfield:-0}
++HT_MpduDensity=4
++HT_EXTCHA=${EXTCHA}
++HT_BW=${HT_BW:-0}
++HT_AutoBA=1
++HT_BADecline=0
++HT_AMSDU=1
++HT_BAWinSize=64
++HT_GI=${HT_GI:-1}
++HT_STBC=${tx_stbc:-1}
++HT_LDPC=${ldpc:-1}
++HT_MCS=33
++VHT_BW=${VHT_BW:-0}
++VHT_SGI=1
++VHT_STBC=${tx_stbc:-1}
++VHT_BW_SIGNAL=0
++VHT_DisallowNonVHT=${VHT_DisallowNonVHT:-0}
++VHT_LDPC=${ldpc:-1}
++#HT_TxStream=2
++#HT_RxStream=2
++HT_PROTECT=0
++HT_DisallowTKIP=${HT_DisallowTKIP:-0}
++HT_BSSCoexistence=${HT_CE:-1}
++HT_BSSCoexApCntThr=10
++GreenAP=${greenap:-0}
++WscConfMode=0
++WscConfStatus=1
++WCNTest=0
++RADIUS_Server=
++RADIUS_Port=1812
++RADIUS_Key1=
++RADIUS_Key2=
++RADIUS_Key3=
++RADIUS_Key4=
++RADIUS_Key5=
++RADIUS_Key6=
++RADIUS_Key7=
++RADIUS_Key8=
++RADIUS_Acct_Server=
++RADIUS_Acct_Port=1813
++RADIUS_Acct_Key=
++own_ip_addr=
++Ethifname=
++EAPifname=
++PreAuthifname=
++session_timeout_interval=0
++idle_timeout_interval=0
++WiFiTest=0
++TGnWifiTest=0
++ApCliEnable=0
++ApCliSsid=
++ApCliBssid=
++ApCliAuthMode=
++ApCliEncrypType=
++ApCliWPAPSK=
++ApCliDefaultKeyID=0
++ApCliKey1Type=0
++ApCliKey1Str=
++ApCliKey2Type=0
++ApCliKey2Str=
++ApCliKey3Type=0
++ApCliKey3Str=
++ApCliKey4Type=0
++ApCliKey4Str=
++RadioOn=1
++WscManufacturer=PandoraBox
++WscModelName=PandoraBox Wireless Router
++WscDeviceName=PandoraBox WiFi
++WscModelNumber=
++WscSerialNumber=
++PMFMFPC=0
++PMFMFPR=0
++PMFSHA256=0
++LoadCodeMethod=0
++AutoChannelSkipList=${ACSSKIP}
++MaxStaNum=${maxassoc:-0}
++WirelessEvent=1
++AuthFloodThreshold=64
++AssocReqFloodThreshold=64
++ReassocReqFloodThreshold=64
++ProbeReqFloodThreshold=64
++DisassocFloodThreshold=64
++DeauthFloodThreshold=64
++EapReqFloodThreshold=64
++Thermal=100
++EnhanceMultiClient=1
++IgmpSnEnable=0
++#DetectPhy=1
++BGMultiClient=1
++EDCCA=0
++HT_MIMOPSMode=3
++PandoraBoxSmart=${smart:-1}
++RED_Enable=1
++VOW_Airtime_Fairness_En=1
++CP_SUPPORT=2
++BandSteering=0
++BndStrgRssiDiff=15
++BndStrgRssiLow=-86
++BndStrgAge=600000
++BndStrgHoldTime=3000
++BndStrgCheckTime=6000
++SCSEnable=1
++DyncVgaEnable=1
++SkipLongRangeVga=0
++VgaClamp=0
++FastRoaming=0
++AutoRoaming=0
++FtSupport=0
++FtRic=1;1;1;1
++FtOtd=0;0;0;0
++FtMdId1=A1
++FtMdId2=A2
++FtMdId3=A3
++FtMdId4=A4
++FtR0khId1=4f577274
++FtR0khId2=4f577276
++FtR0khId3=4f577278
++FtR0khId4=4f57727A
++BandDeltaRssi=-12
++ApProbeRspTimes=3
++#AuthRspFail=0
++#AuthRspRssi=0
++#AssocReqRssiThres=-68
++#AssocRspIgnor=0
++#KickStaRssiLow=-75
++KickStaRssiLowPSM=-77
++#KickStaRssiLowDelay=6
++#ProbeRspRssi=-72
++VideoClassifierEnable=1
++VideoHighTxMode=1
++VideoTurbine=1
++VideoTxLifeTimeMode=1
++EOF
++
++#接口配置生成
++#	STA模式
++	stacount=0
++	for_each_interface "sta" mt_dbdc_sta_vif_pre_config
++
++#	AP模式
++#	统一设置的内容:
++	ApEncrypType=""
++	ApAuthMode=""
++	ApBssidNum=0
++	ApHideESSID=""
++	ApDefKId=""
++	ApK1Tp=""
++	ApK2Tp=""
++	ApK3Tp=""
++	ApK4Tp=""
++
++	for_each_interface "ap" mt_dbdc_ap_vif_pre_config
++
++	[ "$phy_name" == "ra0" ] && [ "$ApBssidNum" == "0" ] && mt_cmd ifconfig ra0 down
++#For DBDC profile merging......
++	while [ $ApBssidNum -lt $RTWIFI_DEF_MAX_BSSID ]
++	do
++		ApEncrypType="${ApEncrypType}NONE;"
++		ApAuthMode="${ApAuthMode}OPEN;"
++		ApHideESSID="${ApHideESSID}0;"
++		ApDefKId="${ApDefKId}0;"
++		ApK1Tp="${ApK1Tp}0;"
++		ApK2Tp="${ApK2Tp}0;"
++		ApK3Tp="${ApK3Tp}0;"
++		ApK4Tp="${ApK4Tp}0;"
++		let ApBssidNum+=1
++	done
++
++	echo "AuthMode=${ApAuthMode%?}" >> $RTWIFI_PROFILE_PATH
++	echo "EncrypType=${ApEncrypType%?}" >> $RTWIFI_PROFILE_PATH
++	echo "HideSSID=${ApHideESSID%?}" >> $RTWIFI_PROFILE_PATH
++	echo "DefaultKeyID=${ApDefKId%?}" >> $RTWIFI_PROFILE_PATH
++	echo "Key1Type=${ApK1Tp%?}" >> $RTWIFI_PROFILE_PATH
++	echo "Key2Type=${ApK2Tp%?}" >> $RTWIFI_PROFILE_PATH
++	echo "Key3Type=${ApK3Tp%?}" >> $RTWIFI_PROFILE_PATH
++	echo "Key4Type=${ApK4Tp%?}" >> $RTWIFI_PROFILE_PATH
++
++#	WDS接口数目
++	WDSBssidNum=0
++	WDSEN=0
++	WDSList=""
++	WDSEncType=""
++	WDSDefKeyID=""
++	WDSPhyMode=""
++	WDSTxMCS=""
++	for_each_interface "wds" mt_dbdc_wds_vif_pre_config
++	echo "WdsEnable=${WDSEN%?}" >> $RTWIFI_PROFILE_PATH
++	echo "WdsList=${WDSList%?}" >> $RTWIFI_PROFILE_PATH
++	echo "WdsEncrypType=${WdsEncType%?}" >> $RTWIFI_PROFILE_PATH
++	echo "WdsDefaultKeyID=${WDSDefKeyID%?}" >> $RTWIFI_PROFILE_PATH
++	echo "WdsPhyMode=${WDSPhyMode%?}" >> $RTWIFI_PROFILE_PATH
++	echo "WdsTxMcs=${WDSTxMCS%?}" >> $RTWIFI_PROFILE_PATH
++
++#接口上线
++#加锁
++	echo "Pending..."
++	if lock -n $WIFI_OP_LOCK; then
++		sleep 3
++		RA_MAIN_UP=$(get_if_stat ra0)
++		drv_mt_dbdc_teardown $phy_name
++		RESET_IF=$(mt_dbdc_vif_down $phy_name)
++		echo "MT_DBDC:ra0:$RA_MAIN_UP.Later we'll restart $(echo ${RESET_IF} | tr '\n' ' ')"
++		sleep 1
++
++#Start root device
++		ifconfig ra0 up
++#restore interfaces
++		sh $RTWIFI_CMD_OPATH
++
++		sh $RTWIFI_CMD_PATH
++#重启HWNAT
++		[ -d /sys/module/hw_nat ] && {
++			/etc/init.d/hwacc restart
++		}
++	else
++		echo "Wait other process"
++		lock $WIFI_OP_LOCK
++	fi
++#AP模式
++	ApIfCNT=0
++	for_each_interface "ap" mt_dbdc_ap_vif_post_config
++#WDS接口
++	WDSBssidNum=0
++	for_each_interface "wds" mt_dbdc_wds_vif_post_config
++#STA模式
++	stacount=0
++	for_each_interface "sta" mt_dbdc_sta_vif_post_config
++
++#设置无线上线
++	wireless_set_up
++#解锁
++	lock -u $WIFI_OP_LOCK
++}
++add_driver mt_dbdc
+diff --git a/package/feeds/custom/mt7615d/files/lib/wifi/mt_dbdc.sh b/package/feeds/custom/mt7615d/files/lib/wifi/mt_dbdc.sh
+new file mode 100644
+index 000000000000..0ab5c92892cc
+--- /dev/null
++++ b/package/feeds/custom/mt7615d/files/lib/wifi/mt_dbdc.sh
+@@ -0,0 +1,75 @@
++#!/bin/sh
++#
++# Copyright (c) 2014 OpenWrt
++# Copyright (C) 2013-2015 D-Team Technology Co.,Ltd. ShenZhen
++# Copyright (c) 2005-2015, lintel <[email protected]>
++# Copyright (c) 2013, Hoowa <[email protected]>
++# Copyright (c) 2015-2017, GuoGuo <[email protected]>
++#
++# 	Detect script for MT7615 DBDC mode
++#
++# 	嘿,对着屏幕的哥们,为了表示对原作者辛苦工作的尊重,任何引用跟借用都不允许你抹去所有作者的信息,请保留这段话。
++#
++
++append DRIVERS "mt_dbdc"
++
++. /lib/functions.sh
++. /lib/functions/system.sh
++
++mt_get_first_if_mac() {
++	local wlan_mac=""
++	factory_part=$(find_mtd_part factory)
++	dd bs=1 skip=4 count=6 if=$factory_part 2>/dev/null | /usr/sbin/maccalc bin2mac	
++}
++
++detect_mt_dbdc() {
++	local macaddr
++	[ -d /sys/module/mt_wifi ] && [ $( grep -c ra0 /proc/net/dev) -eq 1 ] && {
++		for phyname in ra0 rax0; do
++			config_get type $phyname type
++			macaddr=$(mt_get_first_if_mac)
++			[ "$type" == "mt_dbdc" ] || {
++				case $phyname in
++					ra0)
++						hwmode=11g
++						htmode=HT20
++						pb_smart=1
++						noscan=0
++						ssid="OpenWRT-2.4G-$(echo $macaddr | awk -F ":" '{print $4""$5""$6 }'| tr a-z A-Z)"
++						;;
++					rax0)
++						hwmode=11a
++						htmode=VHT80
++						ssid="OpenWRT-5G-$(maccalc add $macaddr 3145728 | awk -F ":" '{print $4""$5""$6 }'| tr a-z A-Z)"
++						pb_smart=0
++						noscan=1
++						;;
++				esac
++				
++#				[ -n "$macaddr" ] && {
++#					dev_id="set wireless.${phyname}.macaddr=${macaddr}"
++#				}
++				uci -q batch <<-EOF
++					set wireless.${phyname}=wifi-device
++					set wireless.${phyname}.type=mt_dbdc
++					set wireless.${phyname}.hwmode=$hwmode
++					set wireless.${phyname}.channel=auto
++					set wireless.${phyname}.txpower=100
++					set wireless.${phyname}.htmode=$htmode
++					set wireless.${phyname}.country=CN
++					set wireless.${phyname}.txburst=1
++					set wireless.${phyname}.noscan=$noscan
++					set wireless.${phyname}.smart=$pb_smart
++
++					set wireless.default_${phyname}=wifi-iface
++					set wireless.default_${phyname}.device=${phyname}
++					set wireless.default_${phyname}.network=lan
++					set wireless.default_${phyname}.mode=ap
++					set wireless.default_${phyname}.ssid=${ssid}
++					set wireless.default_${phyname}.encryption=none
++				EOF
++				uci -q commit wireless
++			}
++		done
++	}
++}
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/cmm_info.c b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/cmm_info.c
+index cbae8ba9b454..04d6f0fb46c5 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/cmm_info.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/cmm_info.c
+@@ -4661,6 +4661,11 @@ max_len += OWETRANSIE_LINE_LEN;
+ 
+ 	memset(msg, 0, TotalLen);
+ 
++	WaitCnt = 0;
++
++	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
++		OS_WAIT(500);
++
+ 	if (pAdapter->ScanTab.BssNr == 0) {
+ 		sprintf(msg, "No BssInfo\n");
+ 		wrq->u.data.length = strlen(msg);
+@@ -4697,11 +4702,6 @@ max_len += OWETRANSIE_LINE_LEN;
+ 		sprintf(msg + strlen(msg) - 1, "%-10s\n", " OWETranIe");
+ #endif /* APCLI_OWE_SUPPORT */
+ 
+-	WaitCnt = 0;
+-
+-	while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
+-		OS_WAIT(500);
+-
+ 
+ 	for (i = bss_start_idx; i < pAdapter->ScanTab.BssNr; i++) {
+ 		pBss = &pAdapter->ScanTab.BssEntry[i];
+@@ -4948,7 +4948,7 @@ VOID RTMPIoctlGetMacTableStaInfo(
+ 	IN RTMP_IOCTL_INPUT_STRUCT *wrq)
+ {
+ 	INT i;
+-	BOOLEAN need_send = FALSE;
++	BOOLEAN need_send;
+ 	RT_802_11_MAC_TABLE *pMacTab = NULL;
+ 	PRT_802_11_MAC_ENTRY pDst;
+ 	MAC_TABLE_ENTRY *pEntry;
+@@ -4965,12 +4965,11 @@ VOID RTMPIoctlGetMacTableStaInfo(
+ 	for (i = 0; VALID_UCAST_ENTRY_WCID(pAd, i); i++) {
+ 		pEntry = &(pAd->MacTab.Content[i]);
+ 
++		need_send = FALSE;
+ 		if (pEntry->wdev != NULL) {
+ 			/* As per new GUI design ifname with index as ra0/ra1/rai0/rai1/... (may not work with older GUI)*/
+ 			if (!strcmp(wrq->ifr_ifrn.ifrn_name, pEntry->wdev->if_dev->name))
+ 				need_send = TRUE;
+-			else
+-				need_send = FALSE;
+ 		}
+ 		if (IS_ENTRY_CLIENT(pEntry) && (pEntry->Sst == SST_ASSOC) && (need_send == TRUE)) {
+ 			pDst = &pMacTab->Entry[pMacTab->Num];
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/multi_profile.c b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/multi_profile.c
+index 941251dac790..9cb5526642cb 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/multi_profile.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/common/multi_profile.c
+@@ -18,9 +18,9 @@
+ #include "rt_config.h"
+ 
+ /*Local definition*/
+-#define FIRST_AP_2G_PROFILE_PATH	"/etc/Wireless/RT2860/RT2860_2G.dat"
+-#define FIRST_AP_5G_PROFILE_PATH	"/etc/Wireless/RT2860/RT2860_5G.dat"
+-#define FIRST_AP_MERGE_PROFILE_PATH ""
++#define FIRST_AP_2G_PROFILE_PATH	"/tmp/profiles/mt_dbdc_2g.dat"
++#define FIRST_AP_5G_PROFILE_PATH	"/tmp/profiles/mt_dbdc_5g.dat"
++#define FIRST_AP_MERGE_PROFILE_PATH "/tmp/profiles/mt_dbdc.dat"
+ #if defined(BB_SOC) && !defined(MULTI_INF_SUPPORT)
+ #define FIRST_AP_5G_DEVNAME "rai0"
+ #define FIRST_MBSSID_5G_DEVNAME "rai"
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/cfg80211extr.h b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/cfg80211extr.h
+index 86b954cd7d13..b7bb693578c3 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/cfg80211extr.h
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/cfg80211extr.h
+@@ -70,6 +70,10 @@ CFG80211_Scaning((VOID *)__pAd, __BssIdx, __ChanId, __pFrame,			\
+ #define RT_CFG80211_LOST_AP_INFORM(__pAd)									\
+ 	CFG80211_LostApInform((VOID *)__pAd);
+ #endif /*CONFIG_STA_SUPPORT || APCLI_CFG80211_SUPPORT */
++#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
++#define RT_CFG80211_LOST_GO_INFORM(__pAd) 									\
++	CFG80211_LostP2pGoInform((VOID *)__pAd);
++#endif /*RT_CFG80211_P2P_CONCURRENT_DEVICE*/
+ #define RT_CFG80211_REINIT(__pAd, __wdev)											\
+ 	CFG80211_SupBandReInit((VOID *)__pAd, (VOID *)__wdev);
+ 
+@@ -118,7 +122,7 @@ CFG80211_Scaning((VOID *)__pAd, __BssIdx, __ChanId, __pFrame,			\
+ #define P2P_NOA_TX_ON    0x01
+ #define P2P_NOA_RX_ON    0x02
+ 
+-#define WLAN_AKM_SUITE_8021X		0x000FAC01
++//#define WLAN_AKM_SUITE_8021X		0x000FAC01
+ #define WDEV_NOT_FOUND				-1
+ 
+ 
+@@ -188,6 +192,7 @@ VOID CFG80211_ConnectResultInform(
+ 	UCHAR *pRspIe, UINT32 RspIeLen,	UCHAR FlgIsSuccess);
+ VOID CFG80211DRV_PmkidConfig(VOID *pAdOrg, VOID *pData);
+ VOID CFG80211_LostApInform(VOID *pAdCB);
++VOID CFG80211_LostP2pGoInform(VOID *pAdCB);
+ 
+ INT CFG80211_StaPortSecured(
+ 	VOID                         *pAdCB,
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/l1profile.h b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/l1profile.h
+index 998ffc3690eb..1c53d5dd2cd2 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/l1profile.h
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/l1profile.h
+@@ -1,8 +1,8 @@
+-#ifdef DEFAULT_5G_PROFILE
++#ifdef DBDC_MODE
+ UCHAR l1profile_default[] = {
+ "Default\n\
+ INDEX0=MT7615\n\
+-INDEX0_profile_path=/etc/Wireless/RT2860/RT2860_2G.dat;/etc/Wireless/RT2860/RT2860_5G.dat\n\
++INDEX0_profile_path=/tmp/profiles/mt_dbdc_2g.dat;/tmp/profiles/mt_dbdc_5g.dat\n\
+ INDEX0_EEPROM_offset=0x0\n\
+ INDEX0_EEPROM_size=0x4000\n\
+ INDEX0_EEPROM_name=e2p\n\
+@@ -13,27 +13,15 @@ INDEX0_apcli_ifname=apcli;apclix\n\
+ INDEX0_mesh_ifname=mesh;meshx\n\
+ INDEX0_nvram_zone=RT2860\n\
+ INDEX0_single_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU.dat\n\
+-INDEX0_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n\
+-INDEX1=MT7615\n\
+-INDEX1_profile_path=/etc/Wireless/iNIC/iNIC_ap.dat\n\
+-INDEX1_EEPROM_offset=0x8000\n\
+-INDEX1_EEPROM_size=0x4000\n\
+-INDEX1_EEPROM_name=e2p\n\
+-INDEX1_main_ifname=rai0\n\
+-INDEX1_ext_ifname=rai\n\
+-INDEX1_wds_ifname=wdsi\n\
+-INDEX1_apcli_ifname=apclii\n\
+-INDEX1_mesh_ifname=meshi\n\
+-INDEX1_nvram_zone=RTDEV\n\
+-INDEX1_single_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU.dat\n\
+-INDEX1_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n"
++INDEX0_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n"
+ };
+ 
+ #else
++
+ UCHAR l1profile_default[] = {
+ "Default\n\
+ INDEX0=MT7615\n\
+-INDEX0_profile_path=/etc/Wireless/RT2860/RT2860.dat\n\
++INDEX0_profile_path=/etc/wireless/mt7615/mt7615.1.dat\n\
+ INDEX0_EEPROM_offset=0x0\n\
+ INDEX0_EEPROM_size=0x4000\n\
+ INDEX0_EEPROM_name=e2p\n\
+@@ -41,12 +29,10 @@ INDEX0_main_ifname=ra0\n\
+ INDEX0_ext_ifname=ra\n\
+ INDEX0_wds_ifname=wds\n\
+ INDEX0_apcli_ifname=apcli\n\
+-INDEX0_mesh_ifname=mesh\n\
+-INDEX0_nvram_zone=RT2860\n\
+ INDEX0_single_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU.dat\n\
+ INDEX0_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n\
+ INDEX1=MT7615\n\
+-INDEX1_profile_path=/etc/Wireless/iNIC/iNIC_ap.dat\n\
++INDEX1_profile_path=/etc/wireless/mt7615/mt7615.2.dat\n\
+ INDEX1_EEPROM_offset=0x8000\n\
+ INDEX1_EEPROM_size=0x4000\n\
+ INDEX1_EEPROM_name=e2p\n\
+@@ -54,35 +40,8 @@ INDEX1_main_ifname=rai0\n\
+ INDEX1_ext_ifname=rai\n\
+ INDEX1_wds_ifname=wdsi\n\
+ INDEX1_apcli_ifname=apclii\n\
+-INDEX1_mesh_ifname=meshi\n\
+-INDEX1_nvram_zone=RTDEV\n\
+ INDEX1_single_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU.dat\n\
+-INDEX1_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n\
+-INDEX2=MT7615\n\
+-INDEX2_profile_path=/etc/Wireless/WIFI3/RT2870AP.dat\n\
+-INDEX2_EEPROM_offset=0x4000\n\
+-INDEX2_EEPROM_size=0x4000\n\
+-INDEX2_EEPROM_name=e2p\n\
+-INDEX2_main_ifname=rae0\n\
+-INDEX2_ext_ifname=rae\n\
+-INDEX2_wds_ifname=wdsex\n\
+-INDEX2_apcli_ifname=apclie\n\
+-INDEX2_mesh_ifname=meshe\n\
+-INDEX2_nvram_zone=WIFI3\n\
+-INDEX2_single_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU.dat\n\
+-INDEX2_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n\
+-INDEX3=MT7615A\n\
+-INDEX3_profile_path=/etc/Wireless/MT7615A_B0_5G.dat;/etc/Wireless/MT7615A_B1_5G.dat\n\
+-INDEX3_EEPROM_offset=0x0\n\
+-INDEX3_EEPROM_size=0x4000\n\
+-INDEX3_EEPROM_name=e2p\n\
+-INDEX3_main_ifname=ra0;rax0\n\
+-INDEX3_ext_ifname=ra;rax\n\
+-INDEX3_wds_ifname=wds;wdsx\n\
+-INDEX3_apcli_ifname=apcli;apclix\n\
+-INDEX3_mesh_ifname=mesh;meshx\n\
+-INDEX3_nvram_zone=RT2860\n\
+-INDEX3_single_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU.dat\n\
+-INDEX3_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n"
++INDEX1_bf_sku_path=/etc_ro/Wireless/RT2860AP/SingleSKU_BF.dat\n"
+ };
+-#endif
++
++#endif
+\ No newline at end of file
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp.h b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp.h
+index 9025f2221247..ab0bd6dc0d90 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp.h
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp.h
+@@ -5288,6 +5288,7 @@ typedef struct _CFG80211_CONTROL {
+ 	/* MainDevice Info. */
+ 	CFG80211_VIF_DEV cfg80211MainDev;
+ #if defined(RT_CFG80211_P2P_CONCURRENT_DEVICE) || defined(CFG80211_MULTI_STA)
++	BOOLEAN bP2pCliPmEnable;
+ 	/* For add_virtual_intf */
+ 	CFG80211_VIF_DEV_SET Cfg80211VifDevSet;
+ #endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE || CFG80211_MULTI_STA */
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp_comm.h b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp_comm.h
+index c70bd2cc652a..6f317da23bb4 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp_comm.h
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/include/rtmp_comm.h
+@@ -437,6 +437,6 @@ typedef struct  _PACKET_INFO    {
+ extern VOID *adapt_list[MAX_NUM_OF_INF];
+ #endif /* MULTI_INF_SUPPORT */
+ #ifdef CREATE_ALL_INTERFACE_AT_INIT
+-#define MAX_MBSS_NUM 8	
++#define MAX_MBSS_NUM 4
+ #endif
+ #endif /* __RT_COMM_H__ */
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/security/cmm_wpa.c b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/security/cmm_wpa.c
+index afe86d7c8f66..73ba68d892db 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/embedded/security/cmm_wpa.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/embedded/security/cmm_wpa.c
+@@ -5397,9 +5397,9 @@ VOID PeerPairMsg4Action(
+ 			MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("PTK:"));
+ 
+ 			for (i = 0; i < 64; i++)
+-				MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("%02x", pSecConfig->PTK[i]));
++				MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (KERN_CONT"%02x", pSecConfig->PTK[i]));
+ 
+-			MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, ("\n"));
++			MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_OFF, (KERN_CONT"\n"));
+ 		}
+ 	} else {
+ 		/* 5. init Group 2-way handshake if necessary.*/
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/include/os/rt_linux.h b/package/feeds/custom/mt7615d/src/mt_wifi/include/os/rt_linux.h
+index 42804616e665..4ffa7e804589 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/include/os/rt_linux.h
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/include/os/rt_linux.h
+@@ -801,6 +801,7 @@ void linux_pci_unmap_single(void *handle, ra_dma_addr_t dma_addr, size_t size, i
+ #define PCI_MAP_SINGLE_DEV(_pAd, _ptr, _size, _sd_idx, _dir)				\
+ 	linux_pci_map_single(((POS_COOKIE)(_pAd->OS_Cookie))->pDev, _ptr, _size, _sd_idx, _dir)
+ 
++#undef DMA_MAPPING_ERROR
+ #define DMA_MAPPING_ERROR(_handle, _ptr)	\
+ 	dma_mapping_error(&((struct pci_dev *)(_handle))->dev, _ptr)
+ 
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/ap_ioctl.c b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/ap_ioctl.c
+index 6d128ee8f51e..daa1f6172967 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/ap_ioctl.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/ap_ioctl.c
+@@ -32,6 +32,22 @@
+ #include <linux/wireless.h>
+ #include "rtmp_def.h"
+ 
++static const UCHAR Cfg80211_Chan[] = {
++	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //14
++
++	/* 802.11 UNI / HyperLan 2 */
++	36, 40, 44, 48, 52, 56, 60, 64, //8
++
++	/* 802.11 HyperLan 2 */
++	100, 104, 108, 112, 116, 120, 124, 128, 132, 136, //10
++
++	/* 802.11 UNII */
++	140, 144, 149, 153, 157, 161, 165, 169, 173, //9
++
++	/* Japan */
++	184, 188, 192, 196, 208, 212, 216, //7
++};
++
+ struct iw_priv_args ap_privtab[] = {
+ 	{
+ 		RTPRIV_IOCTL_SET,
+@@ -47,7 +63,7 @@ struct iw_priv_args ap_privtab[] = {
+ 	},
+ 	{
+ 		RTPRIV_IOCTL_GSITESURVEY,
+-		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
++		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ 		"get_site_survey"
+ 	},
+ 	{
+@@ -67,7 +83,7 @@ struct iw_priv_args ap_privtab[] = {
+ 	},
+ 	{
+ 		RTPRIV_IOCTL_E2P,
+-		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
++		IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ 		"e2p"
+ 	},
+ #if defined(DBG) || (defined(BB_SOC) && defined(CONFIG_ATE))
+@@ -131,6 +147,44 @@ const struct iw_handler_def rt28xx_ap_iw_handler_def = {
+ };
+ #endif /* CONFIG_APSTA_MIXED_SUPPORT */
+ 
++static int rtw_ch2freq(int chan)
++{
++	/* see 802.11 17.3.8.3.2 and Annex J
++	* there are overlapping channel numbers in 5GHz and 2GHz bands */
++
++	/*
++	* RTK: don't consider the overlapping channel numbers: 5G channel <= 14,
++	* because we don't support it. simply judge from channel number
++	*/
++
++	if (chan >= 1 && chan <= 14) {
++		if (chan == 14)
++			return 2484;
++		else if (chan < 14)
++			return 2407 + chan * 5;
++	} else if (chan >= 36 && chan <= 177)
++		return 5000 + chan * 5;
++
++	return 0; /* not supported */
++}
++
++static void setChans(struct iw_range *prange) {
++	/* channels */
++	int i;
++	int NumOfChan = CFG80211_NUM_OF_CHAN_2GHZ + CFG80211_NUM_OF_CHAN_5GHZ;
++	if (NumOfChan > 32) {
++		// iw_range::freq cannot exceed 32 items 
++		NumOfChan = 32;
++	}
++	for (i = 0; i < NumOfChan; i++) {
++		prange->freq[i].i = Cfg80211_Chan[i];
++		prange->freq[i].e = 6;
++		prange->freq[i].m = rtw_ch2freq(Cfg80211_Chan[i]);
++	}
++	prange->num_channels = NumOfChan;
++	prange->num_frequency = NumOfChan;
++
++}
+ 
+ INT rt28xx_ap_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
+ {
+@@ -285,9 +339,9 @@ INT rt28xx_ap_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
+ 		ULONG Channel;
+ 
+ 		RTMP_DRIVER_CHANNEL_GET(pAd, pIoctlConfig->apidx, &Channel);
+-		wrqin->u.freq.m = Channel; /*wdev->channel; */
+-		wrqin->u.freq.e = 0;
+-		wrqin->u.freq.i = 0;
++		wrqin->u.freq.m = rtw_ch2freq(Channel); /*wdev->channel; */
++		wrqin->u.freq.e = 6;
++		wrqin->u.freq.i = Channel;
+ 	}
+ 	break;
+ 
+@@ -365,7 +419,17 @@ INT rt28xx_ap_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
+ 
+ 		memset(prange, 0, sizeof(struct iw_range));
+ 		prange->we_version_compiled = WIRELESS_EXT;
+-		prange->we_version_source = 14;
++		prange->we_version_source = 16;
++		prange->retry_capa = IW_RETRY_LIMIT;
++		prange->retry_flags = IW_RETRY_LIMIT;
++		prange->min_retry = 0;
++		prange->max_retry = 255;
++		prange->min_rts = 0;
++		prange->max_rts = 2347;
++		prange->min_frag = 256;
++		prange->max_frag = 2346;
++
++		prange->max_encoding_tokens = 4;
+ 		/*
+ 		 *	what is correct max? This was not
+ 		 *	documented exactly. At least
+@@ -374,6 +438,16 @@ INT rt28xx_ap_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
+ 		prange->max_qual.qual = 100;
+ 		prange->max_qual.level = 0; /* dB */
+ 		prange->max_qual.noise = 0; /* dB */
++
++		/* channels */
++		setChans(prange);
++
++		/* encrypt */
++		prange->enc_capa |= (IW_ENC_CAPA_CIPHER_TKIP |
++					IW_ENC_CAPA_WPA |
++					IW_ENC_CAPA_CIPHER_CCMP |
++					IW_ENC_CAPA_WPA2);
++
+ 		len = copy_to_user(wrq->u.data.pointer, prange, sizeof(struct iw_range));
+ 		os_free_mem(prange);
+ 	}
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211.c b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211.c
+index 203642812e89..52da0ae89370 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211.c
+@@ -1687,6 +1687,30 @@ static void CFG80211_OpsMgmtFrameRegister(
+ 		CFG80211DBG(DBG_LVL_ERROR, ("Unkown frame_type = %x, req = %d\n", frame_type, reg));
+ }
+ 
++#ifdef CPTCFG_BACKPORTED_CFG80211_MODULE
++static void CFG80211_OpsUpdateMgmtFrameRegistrations(
++	struct wiphy *pWiphy,
++	struct wireless_dev *wdev,
++	struct mgmt_frame_regs *upd)
++{
++	VOID *pAd;
++	struct net_device *dev = NULL;
++	u32 preq_mask = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
++	u32 action_mask = BIT(IEEE80211_STYPE_ACTION >> 4);
++	MAC80211_PAD_GET_NO_RV(pAd, pWiphy);
++	RTMP_DRIVER_NET_DEV_GET(pAd, &dev);
++
++	CFG80211DBG(DBG_LVL_INFO, ("80211> %s ==>\n", __func__));
++	CFG80211DBG(DBG_LVL_INFO, ("IEEE80211_STYPE_PROBE_REQ = %x, IEEE80211_STYPE_ACTION = %d , (%d)\n", 
++		!!(upd->interface_stypes & preq_mask), !!(upd->interface_mcast_stypes & action_mask),  
++		dev->ieee80211_ptr->iftype));
++
++	RTMP_DRIVER_80211_MGMT_FRAME_REG(pAd, dev, !!(upd->interface_stypes & preq_mask));
++
++	RTMP_DRIVER_80211_ACTION_FRAME_REG(pAd, dev, !!(upd->interface_mcast_stypes & action_mask));
++}
++#endif
++
+ /* Supplicant_NEW_TDLS */
+ #ifdef CFG_TDLS_SUPPORT
+ static int CFG80211_OpsTdlsMgmt
+@@ -2568,10 +2592,15 @@ struct cfg80211_ops CFG80211_Ops = {
+ 	.set_cqm_rssi_config		= NULL,
+ #endif /* LINUX_VERSION_CODE */
+ 
++#ifdef CPTCFG_BACKPORTED_CFG80211_MODULE
++	.update_mgmt_frame_registrations =
++		CFG80211_OpsUpdateMgmtFrameRegistrations,
++#else
+ #if (KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE)
+ 	/* notify driver that a management frame type was registered */
+ 	.mgmt_frame_register		= CFG80211_OpsMgmtFrameRegister,
+ #endif /* LINUX_VERSION_CODE : 2.6.37 */
++#endif /* CPTCFG_BACKPORTED_CFG80211_MODULE */
+ 
+ #if (KERNEL_VERSION(2, 6, 38) <= LINUX_VERSION_CODE)
+ 	/* set antenna configuration (tx_ant, rx_ant) on the device */
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211_p2p.c b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211_p2p.c
+index 09c30759b5ef..e37238fcc41d 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211_p2p.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/cfg80211/cfg80211_p2p.c
+@@ -13,14 +13,1259 @@
+  ***************************************************************************/
+ 
+ /****************************************************************************
+- *
+- *	Abstract:
+- *
+- *	All related CFG80211 P2P function body.
+- *
+- *	History:
+- *
+- ***************************************************************************/
++ 
++	Abstract:
++
++	All related CFG80211 P2P function body.
++
++	History:
++
++***************************************************************************/
++
+ #define RTMP_MODULE_OS
+ 
++#ifdef RT_CFG80211_SUPPORT
++
++#include "rt_config.h"
++
++UCHAR CFG_WPS_OUI[4] = {0x00, 0x50, 0xf2, 0x04};
++UCHAR CFG_P2POUIBYTE[4] = {0x50, 0x6f, 0x9a, 0x9}; /* spec. 1.14 OUI */
++
++BUILD_TIMER_FUNCTION(CFG80211RemainOnChannelTimeout);
++
++static 
++VOID CFG80211_RemainOnChannelInit(RTMP_ADAPTER	 *pAd)
++{
++	if (pAd->cfg80211_ctrl.Cfg80211RocTimerInit == FALSE)
++	{
++		CFG80211DBG(RT_DEBUG_TRACE, ("CFG80211_ROC : INIT Cfg80211RocTimer\n"));
++		RTMPInitTimer(pAd, &pAd->cfg80211_ctrl.Cfg80211RocTimer, 
++			GET_TIMER_FUNCTION(CFG80211RemainOnChannelTimeout), pAd, FALSE);
++		pAd->cfg80211_ctrl.Cfg80211RocTimerInit = TRUE;
++	}
++}
++
++VOID CFG80211RemainOnChannelTimeout(
++	PVOID SystemSpecific1, PVOID FunctionContext,
++	PVOID SystemSpecific2, PVOID SystemSpecific3)
++{
++	RTMP_ADAPTER *pAd = (RTMP_ADAPTER *) FunctionContext;
++	PCFG80211_CTRL pCfg80211_ctrl = &pAd->cfg80211_ctrl;
++
++	DBGPRINT(RT_DEBUG_INFO, ("CFG80211_ROC: RemainOnChannelTimeout\n"));
++	
++#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
++#define RESTORE_COM_CH_TIME 100
++	APCLI_STRUCT *pApCliEntry = &pAd->ApCfg.ApCliTab[MAIN_MBSSID];
++
++	if (pApCliEntry->Valid && 
++	     	RTMP_CFG80211_VIF_P2P_CLI_ON(pAd) && 
++            	(pAd->LatchRfRegs.Channel != pApCliEntry->MlmeAux.Channel))
++	{
++		/* Extend the ROC_TIME for Common Channel When P2P_CLI on */
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_ROC: ROC_Timeout APCLI_ON Channel: %d\n", 
++								pApCliEntry->MlmeAux.Channel));
++
++        	AsicSwitchChannel(pAd, pApCliEntry->MlmeAux.Channel, FALSE);
++        	AsicLockChannel(pAd, pApCliEntry->MlmeAux.Channel);
++
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: P2P_CLI PWR_ACTIVE ROC_END\n"));
++		CFG80211_P2pClientSendNullFrame(pAd, PWR_ACTIVE);
++#ifdef CONFIG_STA_SUPPORT
++		if (INFRA_ON(pAd))
++		{
++			DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: CONCURRENT STA PWR_ACTIVE ROC_END\n"));
++			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, 
++					  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
++					  pAd->CommonCfg.bAPSDForcePowerSave ? PWR_SAVE : pAd->StaCfg.Psm);			
++		}
++#endif /*CONFIG_STA_SUPPORT*/
++		RTMPSetTimer(&pCfg80211_ctrl->Cfg80211RocTimer, RESTORE_COM_CH_TIME);
++	}
++	else if (INFRA_ON(pAd) &&
++	   	     (pAd->LatchRfRegs.Channel != pAd->CommonCfg.Channel))
++	{
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_ROC: ROC_Timeout INFRA_ON Channel: %d\n", 
++									pAd->CommonCfg.Channel));
++
++        	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
++        	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
++#ifdef CONFIG_STA_SUPPORT
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: INFRA_ON PWR_ACTIVE ROC_END\n"));
++		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, 
++				  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
++				  pAd->CommonCfg.bAPSDForcePowerSave ? PWR_SAVE : pAd->StaCfg.Psm);
++#endif /*CONFIG_STA_SUPPORT*/		
++		RTMPSetTimer(&pCfg80211_ctrl->Cfg80211RocTimer, RESTORE_COM_CH_TIME);		    	 
++	}
++	else
++#endif /*RT_CFG80211_P2P_CONCURRENT_DEVICE */		
++	{
++/* CFG TODO: move to cfg802_util */
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
++		PWIRELESS_DEV pwdev = NULL;
++		pwdev = pCfg80211_ctrl->Cfg80211ChanInfo.pWdev;
++		cfg80211_remain_on_channel_expired(pwdev, pCfg80211_ctrl->Cfg80211ChanInfo.cookie,
++            		pCfg80211_ctrl->Cfg80211ChanInfo.chan, GFP_ATOMIC);
++#else
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++		cfg80211_remain_on_channel_expired( CFG80211_GetEventDevice(pAd),	
++			pCfg80211_ctrl->Cfg80211ChanInfo.cookie, pCfg80211_ctrl->Cfg80211ChanInfo.chan, 
++        		pCfg80211_ctrl->Cfg80211ChanInfo.ChanType, GFP_ATOMIC);
++#endif /* LINUX_VERSION_CODE 2.6.34 */
++#endif /* LINUX_VERSION_CODE 3.8.0 */
++
++		pCfg80211_ctrl->Cfg80211RocTimerRunning = FALSE;
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_ROC: RemainOnChannelTimeout -- FINISH\n"));
++	}		
++}
++
++/* Set a given time on specific channel to listen action Frame */
++BOOLEAN CFG80211DRV_OpsRemainOnChannel(VOID *pAdOrg, VOID *pData, UINT32 duration)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
++	CMD_RTPRIV_IOCTL_80211_CHAN *pChanInfo;
++	BOOLEAN Cancelled;
++	PCFG80211_CTRL pCfg80211_ctrl = &pAd->cfg80211_ctrl;
++	UCHAR lock_channel;
++
++	pChanInfo = (CMD_RTPRIV_IOCTL_80211_CHAN *) pData;
++
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
++        PWIRELESS_DEV pwdev = NULL;
++        pwdev = pChanInfo->pWdev;
++#endif /* LINUX_VERSION_CODE: 3.6.0 */
++	
++	CFG80211DBG(RT_DEBUG_INFO, ("%s\n", __FUNCTION__));
++	
++#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
++	APCLI_STRUCT *pApCliEntry = &pAd->ApCfg.ApCliTab[MAIN_MBSSID];
++	/* Will be Exit the ApCli Connected Channel so send Null frame on current */
++	if (pApCliEntry->Valid && 
++	    RTMP_CFG80211_VIF_P2P_CLI_ON(pAd) &&
++	        (pApCliEntry->MlmeAux.Channel != pChanInfo->ChanId) &&
++                (pApCliEntry->MlmeAux.Channel == pAd->LatchRfRegs.Channel))	
++	{
++        	DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: APCLI PWR_SAVE ROC_START\n"));
++        	CFG80211_P2pClientSendNullFrame(pAd, PWR_SAVE);
++	}
++
++	if (INFRA_ON(pAd) &&
++	       (pAd->CommonCfg.Channel != pChanInfo->ChanId) &&
++               (pAd->CommonCfg.Channel == pAd->LatchRfRegs.Channel))	
++	{
++    		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_NULL: STA PWR_SAVE ROC_START\n"));
++		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, 
++				  (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) ? TRUE:FALSE),
++				  PWR_SAVE);				
++	}	
++#endif /*RT_CFG80211_P2P_CONCURRENT_DEVICE */
++
++	/* Channel Switch Case:
++	 * 1. P2P_FIND:    [SOCIAL_CH]->[COM_CH]->[ROC_CH]--N_TUs->[ROC_TIMEOUT]
++	 *                 Set COM_CH to ROC_CH for merge COM_CH & ROC_CH dwell section.
++     	 *	 
++	 * 2. OFF_CH_WAIT: [ROC_CH]--200ms-->[ROC_TIMEOUT]->[COM_CH]
++	 *                 Most in GO case.
++	 * 
++	 */
++	//lock_channel = CFG80211_getCenCh(pAd, pChanInfo->ChanId);
++	lock_channel = pChanInfo->ChanId;
++	if (pAd->LatchRfRegs.Channel != lock_channel
++#ifdef CONFIG_STA_SUPPORT
++	|| (INFRA_ON(pAd) && (pAd->CommonCfg.BBPCurrentBW == BW_40))
++#endif /* CONFIG_STA_SUPPORT */
++	) 
++	{
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_PKT: ROC CHANNEL_LOCK %d\n", pChanInfo->ChanId));
++		//AsicSetChannel(pAd, lock_channel, BW_20, EXTCHA_NONE, FALSE);
++		bbp_set_bw(pAd, BW_20);
++		AsicSwitchChannel(pAd, lock_channel, FALSE);
++		AsicLockChannel(pAd, lock_channel);	
++	}
++	else
++	{
++		DBGPRINT(RT_DEBUG_INFO, ("80211> ComCH == ROC_CH \n"));
++	}
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
++        cfg80211_ready_on_channel(pwdev,  pChanInfo->cookie, pChanInfo->chan, duration, GFP_ATOMIC);	
++#else
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
++	cfg80211_ready_on_channel(CFG80211_GetEventDevice(pAd), pChanInfo->cookie, 
++				  pChanInfo->chan, pChanInfo->ChanType, duration, GFP_ATOMIC);
++#endif /* LINUX_VERSION_CODE: 2.6.34 */
++#endif /* LINUX_VERSION_CODE: 3.6.0 */
++
++	NdisCopyMemory(&pCfg80211_ctrl->Cfg80211ChanInfo, pChanInfo, sizeof(CMD_RTPRIV_IOCTL_80211_CHAN));
++
++	CFG80211_RemainOnChannelInit(pAd);
++	
++	if (pCfg80211_ctrl->Cfg80211RocTimerRunning == TRUE)
++	{
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_ROC : CANCEL Cfg80211RocTimer\n"));
++		RTMPCancelTimer(&pCfg80211_ctrl->Cfg80211RocTimer, &Cancelled);
++		pCfg80211_ctrl->Cfg80211RocTimerRunning = FALSE;
++	}
++
++	RTMPSetTimer(&pCfg80211_ctrl->Cfg80211RocTimer, duration + 20);
++	pCfg80211_ctrl->Cfg80211RocTimerRunning = TRUE;
++
++	return TRUE;	
++}
++
++BOOLEAN CFG80211DRV_OpsCancelRemainOnChannel(VOID *pAdOrg, UINT32 cookie)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
++	BOOLEAN Cancelled;
++	CFG80211DBG(RT_DEBUG_TRACE, ("%s\n", __FUNCTION__));
++
++	if (pAd->cfg80211_ctrl.Cfg80211RocTimerRunning == TRUE)
++	{
++		DBGPRINT(RT_DEBUG_TRACE, ("CFG_ROC : CANCEL Cfg80211RocTimer\n"));
++		RTMPCancelTimer(&pAd->cfg80211_ctrl.Cfg80211RocTimer, &Cancelled);
++		pAd->cfg80211_ctrl.Cfg80211RocTimerRunning = FALSE;
++	}
++}
++
++INT CFG80211_setPowerMgmt(VOID *pAdCB, UINT Enable)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
++
++	DBGPRINT(RT_DEBUG_TRACE, ("@@@ %s: %d\n", __FUNCTION__, Enable));
++
++#ifdef RT_CFG80211_P2P_SUPPORT		
++	pAd->cfg80211_ctrl.bP2pCliPmEnable = Enable;
++#endif /* RT_CFG80211_P2P_SUPPORT */
++
++	return 0;	
++}
++
++#ifdef RT_CFG80211_P2P_SUPPORT
++/*	
++	==========================================================================
++	Description: 
++		Make a P2P Fake NoA Attribute to trigger myself to restart NoA. 
++		The Start time is changed. Duration and Interval and Count is 
++		the same as GO's beacon
++		
++	Parameters: 
++		 StartTime : A new Start time.
++		 pOutBuffer : pointer to buffer that should put data to.
++	Note:
++		 
++	==========================================================================
++ */
++VOID CFG80211_P2PMakeFakeNoATlv(PRTMP_ADAPTER pAd, ULONG StartTime, PUCHAR pOutBuffer)
++{
++	PUCHAR	pDest;
++	PP2PCLIENT_NOA_SCHEDULE pNoa = &pAd->cfg80211_ctrl.GONoASchedule;
++	pDest = pOutBuffer;
++
++	*(pDest) = SUBID_P2P_NOA;
++	/* Length is 13*n + 2 = 15 when n = 1 */
++	*(pDest+1) = 15;
++	/* Lenght 2nd byte */
++	*(pDest+2) = 0;
++	/* Index. */
++	*(pDest+3) = pNoa->Token;
++	/* CT Windows and OppPS parm. Don't turn on both. So Set CTWindows = 0 */
++	*(pDest+4) = 0;
++	/* Count.  Test Plan set to 255. */
++	*(pDest+5) = pNoa->Count;
++	/* Duration */
++	RTMPMoveMemory((pDest+6), pNoa->Duration, 4);
++	/* Interval */
++	RTMPMoveMemory((pDest+10), pNoa->Interval, 4);
++	RTMPMoveMemory((pDest+14), &StartTime, 4);
++}
++
++
++BOOLEAN	CFG80211_P2pAdjustSwNoATimer(PRTMP_ADAPTER pAd, ULONG CurrentTimeStamp, ULONG NextTimePoint) 
++{
++	PCFG80211_CTRL pP2PCtrl = &pAd->cfg80211_ctrl;	
++	ULONG AwakeDuration, NewStartTime;
++	UCHAR FakeNoAAttribute[32];
++	
++	RTMPZeroMemory(FakeNoAAttribute, 32);
++	AwakeDuration = pP2PCtrl->GONoASchedule.Interval - pP2PCtrl->GONoASchedule.Duration;
++	if (CurrentTimeStamp < pP2PCtrl->GONoASchedule.CurrentTargetTimePoint)
++	{
++		/* If offset is more than 1/4 of duration. */
++		if ((pP2PCtrl->GONoASchedule.OngoingAwakeTime) >= (AwakeDuration>> 2))
++		{
++			DBGPRINT(RT_DEBUG_TRACE,("P2pAdjustSwNoATimer HERE HERE!!!! \n"));
++			DBGPRINT(RT_DEBUG_TRACE,("OngoingAwakeTime = %ld. CurrentTimeStamp = %ld.!!!! \n", 
++							pP2PCtrl->GONoASchedule.OngoingAwakeTime, CurrentTimeStamp));
++
++			CFG80211_P2pStopNoA(pAd, &pAd->MacTab.Content[pP2PCtrl->MyGOwcid]);
++			FakeNoAAttribute[0] = SUBID_P2P_NOA;
++			NewStartTime = pP2PCtrl->GONoASchedule.StartTime + 
++				       (pP2PCtrl->GONoASchedule.SwTimerTickCounter - 1) * (pP2PCtrl->GONoASchedule.Interval);
++
++			CFG80211_P2PMakeFakeNoATlv(pAd, NewStartTime, &FakeNoAAttribute[0]);
++
++			pAd->MacTab.Content[pP2PCtrl->MyGOwcid].CFGP2pInfo.NoADesc[0].Token--;
++
++			CFG80211_P2pHandleNoAAttri(pAd, &pAd->MacTab.Content[pP2PCtrl->MyGOwcid], &FakeNoAAttribute[0]);
++		}
++
++		/* Update expected next Current Target Time Point with NextTimePoint */
++		pP2PCtrl->GONoASchedule.CurrentTargetTimePoint = NextTimePoint;
++		/* Can immediately dequeue packet because peer already in awake period. */
++		return TRUE;
++	}
++	else
++	{
++		/* Update expected next Current Target Time Point with NextTimePoint */
++		pP2PCtrl->GONoASchedule.CurrentTargetTimePoint = NextTimePoint;
++		return FALSE;	
++	}
++}
++
++VOID CFG80211_P2pGPTimeOutHandle(PRTMP_ADAPTER pAd) 
++{
++	PCFG80211_CTRL pP2PCtrl = &pAd->cfg80211_ctrl;
++	MAC_TABLE_ENTRY *pEntry=NULL;
++	ULONG MacValue, Value, GPDiff, NextDiff, SavedNextTargetTimePoint;
++
++	RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
++	Value &= 0xfffffffd;
++	RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
++	
++	/* GO operating or Autonomous GO */
++	if (CFG_P2PGO_ON(pAd))
++	{
++		/* Not Yet Ready */
++	}
++	else if (CFG_P2PCLI_ON(pAd))
++	{
++		if (pP2PCtrl->NoAIndex >= MAX_LEN_OF_MAC_TABLE)
++			return;
++	
++		if (pP2PCtrl->NoAIndex != pP2PCtrl->MyGOwcid)
++			DBGPRINT(RT_DEBUG_TRACE,("%s: !bug, please check driver %d. \n", 
++				__FUNCTION__, pP2PCtrl->NoAIndex));
++				
++		pEntry = &pAd->MacTab.Content[pP2PCtrl->NoAIndex];
++		if (pEntry && pEntry->CFGP2pInfo.NoADesc[0].bValid == TRUE)
++		{
++			if ((pEntry->CFGP2pInfo.NoADesc[0].Count > 0) && (pEntry->CFGP2pInfo.NoADesc[0].Count < 255))
++			{
++				/*
++					Sometimes go to awake, sometime go to silence. Two state counts One count down.
++					so only minus Count when I change from Sleep to Awake
++				 */
++				if (pEntry->CFGP2pInfo.NoADesc[0].bInAwake == FALSE)
++					pEntry->CFGP2pInfo.NoADesc[0].Count--;
++			}
++
++			if (pEntry->CFGP2pInfo.NoADesc[0].Count == 0)
++			{
++				CFG80211_P2pStopNoA(pAd, pEntry);
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS %s: Count down to zero!!StopGP.  return.1 \n", __FUNCTION__));
++				return;
++			}
++	
++			/* To enter absence period, stop transmission a little bit earlier to leave HW to clean the queue. */
++			if (pEntry->CFGP2pInfo.NoADesc[0].bInAwake == FALSE)
++				NextDiff = pEntry->CFGP2pInfo.NoADesc[0].Duration - 0x200;
++			else
++				NextDiff = pEntry->CFGP2pInfo.NoADesc[0].Interval - pEntry->CFGP2pInfo.NoADesc[0].Duration + 0x200;
++
++			/* Prepare next time. */
++
++
++			/*RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &MacValue); */
++			MacValue = pAd->cfg80211_ctrl.GONoASchedule.LastBeaconTimeStamp;
++			DBGPRINT(RT_DEBUG_TRACE,("P2P_PS 2 Tsf	Timer  = %ld,  NextTargetTimePoint = %ld.\n", 
++				MacValue, pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint));
++
++			SavedNextTargetTimePoint = pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint;
++			if (MacValue <= pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint)
++			{
++				GPDiff = pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint - MacValue;
++
++				pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint += NextDiff;
++				CFG80211_P2pResetNoATimer(pAd, GPDiff);
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS 3	Continue next NOA NextTargetTimePoint = %ld. \n", 
++						pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint));
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS 3	Value = %ld.  NextDiff = %ld.\n", MacValue, NextDiff));
++			}
++			else
++			{
++				CFG80211_P2pStopNoA(pAd, pEntry);
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS 4  NOA NextTargetTimePoint = %ld. \n", 
++							pEntry->CFGP2pInfo.NoADesc[0].NextTargetTimePoint));
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS 4  Value = %ld = 0x%lx.  NextDiff = %ld.\n", MacValue,  MacValue, NextDiff));
++				return;
++			}
++					
++			if (pEntry->CFGP2pInfo.NoADesc[0].bInAwake == TRUE)
++			{
++				pEntry->CFGP2pInfo.NoADesc[0].bInAwake = FALSE;
++				pP2PCtrl->bKeepSlient = TRUE;
++				pP2PCtrl->bPreKeepSlient = TRUE;
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS Enter Absence now ======> %d\n", pP2PCtrl->bKeepSlient));
++			}
++			else
++			{
++				pEntry->CFGP2pInfo.NoADesc[0].bInAwake = TRUE;
++				pP2PCtrl->bKeepSlient = FALSE;
++				pP2PCtrl->bPreKeepSlient = FALSE;
++				if (IS_SW_NOA_TIMER(pAd) && (pP2PCtrl->GONoASchedule.Count > 100))
++				{
++					if (TRUE == CFG80211_P2pAdjustSwNoATimer(pAd, Value, SavedNextTargetTimePoint))
++					{
++						RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
++					}
++				}
++				else
++				{
++					RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
++				}
++
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS Enter Awake now ======= %d\n", pAd->cfg80211_ctrl.bKeepSlient));
++	
++			}
++	
++		}
++					
++	}
++}
++
++VOID CFG80211_P2PCTWindowTimer(
++	PVOID SystemSpecific1, PVOID FunctionContext, 
++	PVOID SystemSpecific2, PVOID SystemSpecific3) 
++{
++	PRTMP_ADAPTER	pAd = (RTMP_ADAPTER *)FunctionContext;
++	PCFG80211_CTRL pP2pCtrl = &pAd->cfg80211_ctrl;	
++
++	if (CFG80211_P2P_TEST_BIT(pP2pCtrl->CTWindows, P2P_OPPS_BIT))
++		pP2pCtrl->bKeepSlient = TRUE;
++}
++
++
++/*	
++	==========================================================================
++	Description: 
++		When I am P2P Client , Handle NoA Attribute.
++		
++	Parameters: 
++		S - pointer to the association state machine
++	Note:
++		The state machine looks like the following as name implies its function
++	==========================================================================
++ */
++VOID CFG80211_P2pSwNoATimeOut(
++	PVOID SystemSpecific1, PVOID FunctionContext, 
++	PVOID SystemSpecific2, PVOID SystemSpecific3) 
++{
++	PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
++	CFG80211_P2pGPTimeOutHandle(pAd);
++}
++
++VOID CFG80211_P2pPreAbsenTimeOut(
++	PVOID SystemSpecific1, PVOID FunctionContext, 
++	PVOID SystemSpecific2, PVOID SystemSpecific3) 
++{
++	PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
++	pAd->cfg80211_ctrl.bPreKeepSlient = TRUE;
++}
++
++
++BOOLEAN CFG80211_P2pResetNoATimer(PRTMP_ADAPTER pAd, ULONG DiffTimeInUs)
++{
++	ULONG	GPDiff;
++	BOOLEAN	brc = FALSE;
++
++	/*
++		Software based timer means don't use GP interrupt to get precise timer calculation. 
++		So need to check time offset caused by software timer.
++	 */
++	if (IS_SW_NOA_TIMER(pAd))
++	{
++		GPDiff = (DiffTimeInUs>>10) & 0xffff;
++		printk("P2P_PS ==========> P2pResetNoATimer, %ld ==> %d\n", DiffTimeInUs, GPDiff);
++		if (GPDiff > 0)
++		{
++			GPDiff++;
++			RTMPSetTimer(&pAd->cfg80211_ctrl.P2pSwNoATimer, GPDiff);			
++			
++			/* Increase timer tick counter. */
++			pAd->cfg80211_ctrl.GONoASchedule.SwTimerTickCounter++;
++
++			brc = TRUE;
++			/* Will go to awake later. Set a pre-enter-absence timer that the time out is smaller the GPDiff. */
++			if (pAd->cfg80211_ctrl.GONoASchedule.bInAwake == FALSE)			
++			{
++				if (GPDiff > 10)
++				{
++					printk("P2P_PS ==========> P2pPreAbsenTimer, %d\n", (GPDiff - 10));
++					RTMPSetTimer(&pAd->cfg80211_ctrl.P2pPreAbsenTimer, (GPDiff - 10));					
++				}
++			}
++		}
++	}
++	return brc;
++
++}
++
++
++VOID CFG80211_P2pGOStartNoA(PRTMP_ADAPTER pAd)
++{
++
++}
++
++VOID	CFG80211_P2pStopNoA(PRTMP_ADAPTER pAd, PMAC_TABLE_ENTRY pMacClient)
++{
++	ULONG	Value;
++	BOOLEAN	Cancelled;
++	
++	DBGPRINT(RT_DEBUG_TRACE,("P2P_PS %s .!!!! \n",__FUNCTION__));
++	
++	RTMPCancelTimer(&pAd->cfg80211_ctrl.P2pPreAbsenTimer, &Cancelled);
++	pAd->cfg80211_ctrl.bKeepSlient = FALSE;
++	pAd->cfg80211_ctrl.bPreKeepSlient = FALSE;
++	if (pMacClient != NULL)
++	{
++		pMacClient->CFGP2pInfo.NoADesc[0].Count = 0xf3;
++		pMacClient->CFGP2pInfo.NoADesc[0].bValid = FALSE;
++		pMacClient->CFGP2pInfo.NoADesc[0].bInAwake = TRUE;
++		/*
++			Try set Token to a value that has smallest chane the same as the Next Token GO will use.
++			So decrease 1
++		 */
++		pMacClient->CFGP2pInfo.NoADesc[0].Token--;
++	}
++	RTMPCancelTimer(&pAd->cfg80211_ctrl.P2pSwNoATimer, &Cancelled);
++	pAd->cfg80211_ctrl.GONoASchedule.bValid = FALSE;
++	pAd->cfg80211_ctrl.GONoASchedule.bInAwake = TRUE;
++
++		
++	/* If need not resume NoA. Can reset all parameters. */
++	{
++		pAd->cfg80211_ctrl.GONoASchedule.Count = 1;
++		pAd->cfg80211_ctrl.GONoASchedule.Duration = 0xc800;
++		pAd->cfg80211_ctrl.GONoASchedule.Interval = 0x19000;
++	}
++
++	RTMP_IO_READ32(pAd, INT_TIMER_EN, &Value);
++	Value &= (0xfffffffd);
++	RTMP_IO_WRITE32(pAd, INT_TIMER_EN, Value);
++
++	pAd->cfg80211_ctrl.GONoASchedule.SwTimerTickCounter = 0;
++
++	/* Set to false again. */
++	pAd->cfg80211_ctrl.bPreKeepSlient = FALSE;
++
++}
++
++VOID CFG80211_P2pStartOpPS(PRTMP_ADAPTER pAd)
++{
++	if (pAd->cfg80211_ctrl.GONoASchedule.bValid == TRUE)
++		CFG80211_P2pStopNoA(pAd, NULL);
++	
++	DBGPRINT(RT_DEBUG_TRACE,("P2P : !! %s \n",__FUNCTION__));
++	pAd->cfg80211_ctrl.CTWindows = 0x8a;
++	/* Wait next beacon period to really start queue packet. */
++	pAd->cfg80211_ctrl.bKeepSlient = FALSE;
++
++}
++
++VOID CFG80211_P2pStopOpPS(PRTMP_ADAPTER pAd)
++{
++	if (pAd->cfg80211_ctrl.GONoASchedule.bValid == FALSE)
++		pAd->cfg80211_ctrl.bKeepSlient = FALSE;
++	pAd->cfg80211_ctrl.CTWindows = 0;
++}
++
++static
++ULONG CFG80211_P2pGetTimeStamp(PRTMP_ADAPTER pAd)
++{
++	ULONG Value = 0;	
++	/* RTMP_IO_FORCE_READ32(pAd, TSF_TIMER_DW0, &Value); */
++        Value = pAd->cfg80211_ctrl.GONoASchedule.LastBeaconTimeStamp;
++	
++	return Value;
++}
++
++BOOLEAN CFG80211_P2pHandleNoAAttri(PRTMP_ADAPTER pAd, PMAC_TABLE_ENTRY pMacClient, PUCHAR pData) 
++{
++	PP2P_NOA_DESC pNoADesc;
++	ULONG Value, GPDiff, NoALen, StartTime;
++	UCHAR index;
++	
++	if (pMacClient == NULL)
++		return FALSE;
++
++	if (*pData == SUBID_P2P_NOA)
++	{
++		NoALen = *(pData+1);
++		if (NoALen == 2)
++		{
++			pMacClient->CFGP2pInfo.CTWindow = *(pData+4); 
++			if (pMacClient->CFGP2pInfo.NoADesc[0].bValid == TRUE)
++				CFG80211_P2pStopNoA(pAd, pMacClient);
++			/*
++				Copy my GO's CTWindow to P2Pcfg.CTWindow parameters, 
++				Then As Client, I don't need to search for Client when I want to use CTWindow Value.
++			 */
++			pAd->cfg80211_ctrl.CTWindows = *(pData+4); 
++			return TRUE;
++		}
++			
++		index = *(pData+3);
++		
++		pMacClient->CFGP2pInfo.CTWindow = *(pData+4);
++		pAd->cfg80211_ctrl.CTWindows = *(pData+4); 
++		
++		pNoADesc = (PP2P_NOA_DESC)(pData+5);
++		pMacClient->CFGP2pInfo.NoADesc[0].Count = pNoADesc->Count;
++		pMacClient->CFGP2pInfo.NoADesc[0].Duration = *(PUINT32)&pNoADesc->Duration[0];
++		pMacClient->CFGP2pInfo.NoADesc[0].Interval = *(PUINT32)&pNoADesc->Interval[0];
++		pMacClient->CFGP2pInfo.NoADesc[0].StartTime = *(PUINT32)&pNoADesc->StartTime[0];
++		StartTime = *(PUINT32)&pNoADesc->StartTime[0];
++	
++		if (pMacClient->CFGP2pInfo.NoADesc[0].Token == index)
++		{
++			/* The same NoA. Doesn't need to set this NoA again. */
++			return FALSE;
++		}
++		
++		DBGPRINT(RT_DEBUG_TRACE,("P2P_PS : !!!NEW NOA Here =[%d, %d] Count = %d. Duration =  %ld \n", 
++					pMacClient->CFGP2pInfo.NoADesc[0].Token, index, pNoADesc->Count, 
++					pMacClient->CFGP2pInfo.NoADesc[0].Duration));
++		DBGPRINT(RT_DEBUG_TRACE,("P2P_PS : CTWindow =  %x \n", pMacClient->CFGP2pInfo.CTWindow));
++
++		pMacClient->CFGP2pInfo.NoADesc[0].Token = index;
++
++
++		/* RTMP_IO_FORCE_READ32(pAd, TSF_TIMER_DW0, &Value); */
++		Value = pAd->cfg80211_ctrl.GONoASchedule.LastBeaconTimeStamp;
++		DBGPRINT(RT_DEBUG_TRACE,("P2P_PS Interval = %ld. StartTime = %ld. TSF timer = %ld\n", 
++			pMacClient->CFGP2pInfo.NoADesc[0].Interval, pMacClient->CFGP2pInfo.NoADesc[0].StartTime, Value));
++
++		if ((pMacClient->CFGP2pInfo.NoADesc[0].Duration <= 0x40) || (pMacClient->CFGP2pInfo.NoADesc[0].Interval <= 0x40))
++		{
++			DBGPRINT(RT_DEBUG_TRACE, ("P2P_PS !!!!!Interval or Duration too small. ignore.  = %lx return 1\n", Value));
++			return FALSE;
++		}
++		else if ((pMacClient->CFGP2pInfo.NoADesc[0].Duration >= pMacClient->CFGP2pInfo.NoADesc[0].Interval)
++			&& (pMacClient->CFGP2pInfo.NoADesc[0].Count > 1))
++		{
++			DBGPRINT(RT_DEBUG_TRACE, ("P2P_PS !!!!!Duration > Inveral.  return 2\n"));
++			return FALSE;
++		}
++		
++		/* if Start time point is in the future. */
++		pAd->cfg80211_ctrl.GONoASchedule.CurrentTargetTimePoint = pMacClient->CFGP2pInfo.NoADesc[0].StartTime;
++		if (Value < StartTime)
++		{
++			GPDiff = pMacClient->CFGP2pInfo.NoADesc[0].StartTime - Value;
++			pMacClient->CFGP2pInfo.NoADesc[0].NextTargetTimePoint = 
++					pMacClient->CFGP2pInfo.NoADesc[0].StartTime + pMacClient->CFGP2pInfo.NoADesc[0].Duration;
++			pAd->cfg80211_ctrl.GONoASchedule.OngoingAwakeTime = 
++					pMacClient->CFGP2pInfo.NoADesc[0].NextTargetTimePoint;
++
++						
++			DBGPRINT(RT_DEBUG_TRACE,("P2P_PS !!!!! GPDiff = %ld. NextTargetTimePoint = %ld\n", 
++					GPDiff, pMacClient->CFGP2pInfo.NoADesc[0].NextTargetTimePoint));
++
++			/* try to set General Timer. */
++			pAd->cfg80211_ctrl.GONoASchedule.LastBeaconTimeStamp += GPDiff;
++			if (CFG80211_P2pResetNoATimer(pAd, GPDiff))
++			{
++				DBGPRINT(RT_DEBUG_TRACE,("P2P_PS !!!!!Start NoA 1  GPDiff = %ld \n", GPDiff));
++				pMacClient->CFGP2pInfo.NoADesc[0].bValid = TRUE;
++				pMacClient->CFGP2pInfo.NoADesc[0].bInAwake = TRUE;
++				pMacClient->CFGP2pInfo.NoADesc[0].Token = index;
++				return TRUE;
++			}
++		}
++		else if (Value >= StartTime)
++		{
++			/* Start time point is in the past. */
++			do
++			{
++				StartTime += pMacClient->CFGP2pInfo.NoADesc[0].Interval;
++				if ((StartTime > Value) && ((StartTime-Value) > 0x80))
++				{
++					GPDiff = StartTime - Value;
++					pMacClient->CFGP2pInfo.NoADesc[0].NextTargetTimePoint = StartTime 
++								/* + pMacClient->P2pInfo.NoADesc[0].Interval */ 
++								  - pMacClient->CFGP2pInfo.NoADesc[0].Duration;
++
++					pAd->cfg80211_ctrl.GONoASchedule.OngoingAwakeTime = 
++								pMacClient->CFGP2pInfo.NoADesc[0].NextTargetTimePoint;
++					pAd->cfg80211_ctrl.GONoASchedule.LastBeaconTimeStamp += GPDiff;
++
++					if (CFG80211_P2pResetNoATimer(pAd, GPDiff))
++					{
++						DBGPRINT(RT_DEBUG_TRACE,("P2P_PS !!!!!Start NoA 2  GPDiff = %ld\n", GPDiff));
++						pMacClient->CFGP2pInfo.NoADesc[0].bValid = TRUE;
++						pMacClient->CFGP2pInfo.NoADesc[0].bInAwake = TRUE;
++						pMacClient->CFGP2pInfo.NoADesc[0].Token = index;
++						return TRUE;
++					}
++				}
++
++			} while(TRUE);
++		}
++		else
++		{
++			DBGPRINT(RT_DEBUG_ERROR, ("Start time out of ctrl ..need Check \n"));
++		}
++	}
++
++	return FALSE;
++}
++
++
++VOID CFG80211_P2pParseNoASubElmt(PRTMP_ADAPTER pAd, VOID *Msg, ULONG MsgLen, 
++                                 UCHAR wcidindex, UINT32 Sequence)
++{
++	PCFG80211_CTRL pP2PCtrl = &pAd->cfg80211_ctrl;
++	ULONG Length = 0, AttriLen = 0, LeftLength = 0;
++	PP2PEID_STRUCT pP2pEid;
++	PEID_STRUCT pEid;
++	BOOLEAN brc = FALSE, bNoAAttriExist = FALSE;
++	PUCHAR pPtrEid = NULL;
++		
++	/* Intel sends multiple P2P IE... So I can't give each input a default value.. */
++	if (MsgLen == 0)
++		return;
++	
++	LeftLength = MsgLen; 
++	pEid = (PEID_STRUCT)Msg;
++	while ((ULONG)(pEid->Len + 2) <= LeftLength)
++	{
++		/* might contains P2P IE and WPS IE.  So use if else if enough for locate  P2P IE. */
++		if (RTMPEqualMemory(&pEid->Octet[0], CFG_P2POUIBYTE, 4))
++		{
++			/* Get Request content capability */
++			pP2pEid = (PP2PEID_STRUCT) &pEid->Octet[4];
++			pPtrEid = (PUCHAR) pP2pEid;
++			AttriLen = pP2pEid->Len[0] + pP2pEid->Len[1] *8;
++			Length = 0;
++
++			while ((Length + 3 + AttriLen) <= pEid->Len)	
++			{
++				switch(pP2pEid->Eid)
++				{
++					case SUBID_P2P_NOA:
++					{
++						PUCHAR pData = &pEid->Octet[0];
++						DBGPRINT(RT_DEBUG_TRACE, ("P2P_PS Get NoA Attr: %x %x %x %x %x %x %x %x %x \n", 
++									*(pData+0), *(pData+1), *(pData+2), *(pData+3), 
++									*(pData+4), *(pData+5), *(pData+6), *(pData+7), *(pData+8)));
++
++						bNoAAttriExist = TRUE;
++						brc = CFG80211_P2pHandleNoAAttri(pAd, &pAd->MacTab.Content[wcidindex], pPtrEid);
++
++						/* Got a NoA Attribute from this p2pindex. In fact, This should be GO. */
++						if (brc == TRUE)
++							pP2PCtrl->NoAIndex = wcidindex;
++					}
++						break;
++
++					default:
++						break;
++						
++				}
++
++				Length = Length + 3 + AttriLen;  /* Eid[1] + Len[1]+ content[Len] */
++				pP2pEid = (PP2PEID_STRUCT)((UCHAR*)pP2pEid + 3 + AttriLen);
++				pPtrEid = (PUCHAR) pP2pEid;
++				AttriLen = pP2pEid->Len[0] + pP2pEid->Len[1] *8;
++			}	
++		}
++		LeftLength = LeftLength - pEid->Len - 2;
++		pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len); 	   
++	}
++
++	if (bNoAAttriExist == FALSE)
++	{
++		if (CFG80211_P2P_TEST_BIT(pAd->cfg80211_ctrl.CTWindows, P2P_OPPS_BIT))
++		{
++			DBGPRINT(RT_DEBUG_TRACE,("Beacon and no NoA Attribute! \n"));
++			CFG80211_P2pStopOpPS(pAd);
++		}
++
++		if ((pAd->MacTab.Content[wcidindex].CFGP2pInfo.NoADesc[0].bValid == TRUE))
++		{
++			DBGPRINT(RT_DEBUG_TRACE,("Beacon and no NoA Attribute!Stop active NoA [%d]\n", Sequence));
++			CFG80211_P2pStopNoA(pAd, &pAd->MacTab.Content[wcidindex]);
++		}
++	}
++	else
++		printk("P2P_PS Debug: %s() %d ===> Get Entry\n", __FUNCTION__, __LINE__);
++
++}
++
++
++BOOLEAN CFG8211_PeerP2pBeaconSanity(
++	PRTMP_ADAPTER pAd, VOID *Msg, ULONG MsgLen, 
++	PUCHAR pAddr2, CHAR Ssid[], UCHAR *pSsidLen, 
++	ULONG *Peerip, ULONG *P2PSubelementLen, 
++	PUCHAR pP2pSubelement) 
++{
++	PFRAME_802_11 pFrame;
++	PEID_STRUCT pEid;
++	ULONG Length = 0;
++	BOOLEAN	brc = FALSE, bFirstP2pOUI = TRUE;
++	PUCHAR Ptr;
++
++	pFrame = (PFRAME_802_11)Msg;
++	Length += LENGTH_802_11;
++
++	*P2PSubelementLen = 0;
++	*pSsidLen = 0;
++	*Peerip = 0;
++	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
++
++	Ptr = pFrame->Octet;
++
++	/* get timestamp from payload and advance the pointer */
++	Ptr += TIMESTAMP_LEN;
++	Length += TIMESTAMP_LEN;
++
++	/* get beacon interval from payload and advance the pointer */
++	Ptr += 2;
++	Length += 2;
++
++	/* get capability info from payload and advance the pointer */
++	Ptr += 2;
++	Length += 2;
++
++	pEid = (PEID_STRUCT) Ptr;
++
++	/* get variable fields from payload and advance the pointer */
++	while ((Length + 2 + pEid->Len) <= MsgLen)    
++	{
++		switch(pEid->Eid)
++		{			
++			case IE_SSID:
++				if(pEid->Len <= MAX_LEN_OF_SSID)
++				{
++					RTMPMoveMemory(Ssid, pEid->Octet, pEid->Len);
++					*pSsidLen = pEid->Len;
++				}
++				break;
++			case IE_VENDOR_SPECIFIC:
++				/* Check the OUI version, filter out non-standard usage */
++				if (NdisEqualMemory(pEid->Octet, CFG_WPS_OUI, 4) && (pEid->Len >= 4))
++				{
++					if (*P2PSubelementLen == 0)
++					{
++						RTMPMoveMemory(pP2pSubelement, &pEid->Eid, pEid->Len +2);
++						*P2PSubelementLen = pEid->Len +2;
++					}
++					else if (*P2PSubelementLen > 0)
++					{
++						if (((*P2PSubelementLen) + (pEid->Len+2)) <= MAX_VIE_LEN)
++						{
++							RTMPMoveMemory(pP2pSubelement + *P2PSubelementLen, &pEid->Eid, pEid->Len+2);
++							*P2PSubelementLen += (pEid->Len+2);
++						}
++						else
++						{
++							DBGPRINT(RT_DEBUG_ERROR, ("%s: ERROR!! 111 Sum of P2PSubelementLen= %lu, > MAX_VIE_LEN !!\n", __FUNCTION__, ((*P2PSubelementLen) + (pEid->Len+2))));
++							return FALSE;
++						}
++					}
++
++				}
++				else if (NdisEqualMemory(pEid->Octet, CFG_P2POUIBYTE, 4) && (pEid->Len >= 4))
++				{
++					/*
++						If this is the first P2P OUI. Then also append P2P OUI. 
++						Beacon 's P2P attribute doesn't exceed 256 bytes. So not use acumulcated form.
++					 */
++					if (bFirstP2pOUI == TRUE)
++					{
++						if (*P2PSubelementLen == 0)
++						{
++							RTMPMoveMemory(pP2pSubelement, &pEid->Eid, pEid->Len +2);
++							*P2PSubelementLen = (pEid->Len +2);
++							brc = TRUE;
++						}
++						else if (*P2PSubelementLen > 0)
++						{
++							if (((*P2PSubelementLen) + (pEid->Len+2)) <= MAX_VIE_LEN)
++							{
++								RTMPMoveMemory(pP2pSubelement + *P2PSubelementLen, &pEid->Eid, pEid->Len+2);
++								*P2PSubelementLen += (pEid->Len+2);
++								brc = TRUE;
++							}
++							else
++							{
++								DBGPRINT(RT_DEBUG_ERROR, ("%s: ERROR!! 222 Sum of P2PSubelementLen= %lu, > MAX_VIE_LEN !!\n", __FUNCTION__, ((*P2PSubelementLen) + (pEid->Len+2))));
++								return FALSE;
++							}
++						}
++						bFirstP2pOUI = FALSE;
++					}
++					else
++					{
++						/*
++							If this is not the first P2P OUI. Then don't append P2P OUI.
++							because our parse function doesn't need so many P2P OUI.
++						 */
++						if ((*P2PSubelementLen > 0) && (pEid->Len > 4))
++						{
++							if (((*P2PSubelementLen) + (pEid->Len+2)) <= MAX_VIE_LEN)
++							{
++								RTMPMoveMemory(pP2pSubelement + *P2PSubelementLen, &pEid->Eid, pEid->Len+2);
++								*P2PSubelementLen += (pEid->Len+2);
++								brc = TRUE;
++							}
++							else
++							{
++								DBGPRINT(RT_DEBUG_ERROR, ("%s: ERROR!! 333 Sum of P2PSubelementLen= %lu, > MAX_VIE_LEN !!\n", __FUNCTION__, ((*P2PSubelementLen) + (pEid->Len+2))));
++								return FALSE;
++							}
++						}
++					}
++				}
++				break;
++		}
++		Length = Length + 2 + pEid->Len;  /* Eid[1] + Len[1]+ content[Len] */
++		pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);        
++	
++	}
++	return brc;
++}
++
++
++VOID CFG80211_PeerP2pBeacon(PRTMP_ADAPTER pAd, 
++	PUCHAR pAddr2, MLME_QUEUE_ELEM *Elem, LARGE_INTEGER TimeStamp) 
++{
++	PCFG80211_CTRL pP2PCtrl = &pAd->cfg80211_ctrl;
++	
++	UCHAR	Addr2[6], SsidLen, Ssid[32];
++	ULONG	PeerIp, P2PSubelementLen;
++	PUCHAR	P2pSubelement = NULL;
++	PFRAME_802_11		pFrame;
++	PMAC_TABLE_ENTRY pMacEntry = NULL;
++
++	pFrame = (PFRAME_802_11)Elem->Msg;
++	/* Only check beacon . */
++	if (pFrame->Hdr.FC.SubType == SUBTYPE_PROBE_RSP)
++		return;
++
++	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
++		return;
++
++	pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
++
++	/* Init P2pSubelement */
++       	if (P2pSubelement)
++        {
++                os_free_mem(NULL, P2pSubelement);
++                P2pSubelement = NULL;
++        }
++
++	os_alloc_mem(pAd, &P2pSubelement, MAX_VIE_LEN);
++	if (P2pSubelement == NULL)
++	{
++		DBGPRINT(RT_DEBUG_ERROR, ("%s::Allocate memory size(=%d) failed\n", __FUNCTION__, MAX_VIE_LEN));
++		goto CleanUp;
++	}
++	
++	if (CFG8211_PeerP2pBeaconSanity(pAd, Elem->Msg, Elem->MsgLen, 
++					Addr2, Ssid, &SsidLen, &PeerIp,
++					&P2PSubelementLen,P2pSubelement))
++	{
++		/* Parse the power managemenr parameters in here. */
++		pP2PCtrl->GONoASchedule.LastBeaconTimeStamp = TimeStamp.u.LowPart;
++		CFG80211_P2pParseNoASubElmt(pAd, P2pSubelement, P2PSubelementLen, Elem->Wcid, pFrame->Hdr.Sequence);
++
++		/* Since we get beacon, check if GO enable and OppPS. */
++		if (CFG80211_P2P_TEST_BIT(pAd->cfg80211_ctrl.CTWindows, P2P_OPPS_BIT))
++		{
++			pAd->cfg80211_ctrl.bKeepSlient = FALSE;
++			/* TO DO : sync with windows if necessary */
++			/*RTMPDeQueueNoAMgmtPacket(pAd);*/
++
++			RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
++			if (((pAd->cfg80211_ctrl.CTWindows&0x7f) > 0) && ((pAd->cfg80211_ctrl.CTWindows&0x7f) < 80))
++			{
++				DBGPRINT(RT_DEBUG_TRACE, ("%s::  set P2P CTWindows timer.\n", __FUNCTION__));
++				RTMPSetTimer(&pAd->cfg80211_ctrl.P2pCTWindowTimer, (pAd->cfg80211_ctrl.CTWindows&0x7f));
++			}
++		}
++	}
++	
++CleanUp:
++	if (P2pSubelement)
++	{
++		os_free_mem(NULL, P2pSubelement);
++		P2pSubelement = NULL;
++	}
++
++}
++
++#ifdef RT_CFG80211_P2P_CONCURRENT_DEVICE
++VOID CFG80211_P2pClientSendNullFrame(VOID *pAdCB, INT PwrMgmt)
++{
++        PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
++        MAC_TABLE_ENTRY *pEntry;
++
++        pEntry = MacTableLookup(pAd, pAd->ApCfg.ApCliTab[MAIN_MBSSID].MlmeAux.Bssid);
++        if (pEntry == NULL)
++        {
++                DBGPRINT(RT_DEBUG_TRACE, ("CFG80211_ROC: Can't Find In Table: %02x:%02x:%02x:%02x:%02x:%02x\n",
++                                                   PRINT_MAC(pAd->ApCfg.ApCliTab[MAIN_MBSSID].MlmeAux.Bssid)));
++        }
++        else
++        {
++                ApCliRTMPSendNullFrame(pAd,
++                                       RATE_6,
++                                       (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) ? TRUE:FALSE,
++                                       pEntry, PwrMgmt);
++                OS_WAIT(20);
++        }
++}
++
++VOID CFG80211DRV_P2pClientKeyAdd(VOID *pAdOrg, VOID *pData)
++{
++
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
++	CMD_RTPRIV_IOCTL_80211_KEY *pKeyInfo;
++	
++    	DBGPRINT(RT_DEBUG_TRACE, ("CFG Debug: CFG80211DRV_P2pClientKeyAdd\n"));
++    	pKeyInfo = (CMD_RTPRIV_IOCTL_80211_KEY *)pData;
++	
++	if (pKeyInfo->KeyType == RT_CMD_80211_KEY_WEP40 || pKeyInfo->KeyType == RT_CMD_80211_KEY_WEP104)
++		;
++	else
++	{	
++		INT 	BssIdx;
++		PAPCLI_STRUCT pApCliEntry;
++		MAC_TABLE_ENTRY	*pMacEntry=(MAC_TABLE_ENTRY *)NULL;
++	
++		BssIdx = pAd->ApCfg.BssidNum + MAX_MESH_NUM + MAIN_MBSSID;
++		pApCliEntry = &pAd->ApCfg.ApCliTab[MAIN_MBSSID];
++		pMacEntry = &pAd->MacTab.Content[pApCliEntry->MacTabWCID]; 
++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
++        	if (pKeyInfo->bPairwise == FALSE )
++#else
++        	if (pKeyInfo->KeyId > 0)
++#endif		
++		{
++			
++			if (pApCliEntry->wdev.WepStatus == Ndis802_11Encryption3Enabled)
++			{
++				printk("APCLI: Set AES Security Set. [%d] (GROUP) %d\n", BssIdx, pKeyInfo->KeyLen);
++				NdisZeroMemory(&pApCliEntry->SharedKey[pKeyInfo->KeyId], sizeof(CIPHER_KEY));  
++				pApCliEntry->SharedKey[pKeyInfo->KeyId].KeyLen = LEN_TK;
++				NdisMoveMemory(pApCliEntry->SharedKey[pKeyInfo->KeyId].Key, pKeyInfo->KeyBuf, pKeyInfo->KeyLen);
++				
++				pApCliEntry->SharedKey[pKeyInfo->KeyId].CipherAlg = CIPHER_AES;
++
++				AsicAddSharedKeyEntry(pAd, BssIdx, pKeyInfo->KeyId, 
++						      &pApCliEntry->SharedKey[pKeyInfo->KeyId]);
++						
++				RTMPAddWcidAttributeEntry(pAd, BssIdx, pKeyInfo->KeyId, 
++							  pApCliEntry->SharedKey[pKeyInfo->KeyId].CipherAlg, 
++							  NULL);				
++										  
++				if (pMacEntry->AuthMode >= Ndis802_11AuthModeWPA)
++				{
++					/* set 802.1x port control */
++					pMacEntry->PortSecured = WPA_802_1X_PORT_SECURED;
++					pMacEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
++				}
++			}
++		}	
++		else
++		{	
++			if(pMacEntry)
++			{
++				printk("APCLI: Set AES Security Set. [%d] (PAIRWISE) %d\n", BssIdx, pKeyInfo->KeyLen);
++				NdisZeroMemory(&pMacEntry->PairwiseKey, sizeof(CIPHER_KEY));  
++				pMacEntry->PairwiseKey.KeyLen = LEN_TK;
++				
++				NdisCopyMemory(&pMacEntry->PTK[OFFSET_OF_PTK_TK], pKeyInfo->KeyBuf, OFFSET_OF_PTK_TK);
++				NdisMoveMemory(pMacEntry->PairwiseKey.Key, &pMacEntry->PTK[OFFSET_OF_PTK_TK], pKeyInfo->KeyLen);
++				
++				pMacEntry->PairwiseKey.CipherAlg = CIPHER_AES;
++				
++				AsicAddPairwiseKeyEntry(pAd, (UCHAR)pMacEntry->Aid, &pMacEntry->PairwiseKey);
++				RTMPSetWcidSecurityInfo(pAd, BssIdx, 0, pMacEntry->PairwiseKey.CipherAlg, pMacEntry->Aid, PAIRWISEKEYTABLE);
++			}
++			else	
++			{
++				printk("APCLI: Set AES Security Set. (PAIRWISE) But pMacEntry NULL\n");
++			}			
++		}		
++	}
++}
++
++VOID CFG80211DRV_SetP2pCliAssocIe(VOID *pAdOrg, VOID *pData, UINT ie_len)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
++	APCLI_STRUCT *apcli_entry;
++	hex_dump("P2PCLI=", pData, ie_len);
++
++	apcli_entry = &pAd->ApCfg.ApCliTab[MAIN_MBSSID];
++	
++	if (ie_len > 0)	
++	{
++		if (apcli_entry->wpa_supplicant_info.pWpaAssocIe)
++		{
++			os_free_mem(NULL, apcli_entry->wpa_supplicant_info.pWpaAssocIe);
++			apcli_entry->wpa_supplicant_info.pWpaAssocIe = NULL;
++		}
++
++		os_alloc_mem(NULL, (UCHAR **)&apcli_entry->wpa_supplicant_info.pWpaAssocIe, ie_len);
++		if (apcli_entry->wpa_supplicant_info.pWpaAssocIe)
++		{
++			apcli_entry->wpa_supplicant_info.WpaAssocIeLen = ie_len;
++			NdisMoveMemory(apcli_entry->wpa_supplicant_info.pWpaAssocIe, pData, apcli_entry->wpa_supplicant_info.WpaAssocIeLen);
++		}
++		else
++			apcli_entry->wpa_supplicant_info.WpaAssocIeLen = 0;
++	}
++	else
++	{
++		if (apcli_entry->wpa_supplicant_info.pWpaAssocIe)
++		{
++			os_free_mem(NULL, apcli_entry->wpa_supplicant_info.pWpaAssocIe);
++			apcli_entry->wpa_supplicant_info.pWpaAssocIe = NULL;
++		}
++		apcli_entry->wpa_supplicant_info.WpaAssocIeLen = 0;
++	}
++}
++
++/* For P2P_CLIENT Connection Setting in AP_CLI SM */
++BOOLEAN CFG80211DRV_P2pClientConnect(VOID *pAdOrg, VOID *pData)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdOrg;
++	CMD_RTPRIV_IOCTL_80211_CONNECT *pConnInfo;
++	UCHAR Connect_SSID[NDIS_802_11_LENGTH_SSID];
++	UINT32 Connect_SSIDLen;
++	
++	APCLI_STRUCT *apcli_entry;
++	apcli_entry = &pAd->ApCfg.ApCliTab[MAIN_MBSSID];
++	
++	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
++	pObj->ioctl_if_type = INT_APCLI;
++	
++	pConnInfo = (CMD_RTPRIV_IOCTL_80211_CONNECT *)pData;
++	
++	DBGPRINT(RT_DEBUG_TRACE, ("APCLI Connection onGoing.....\n"));
++
++	Connect_SSIDLen = pConnInfo->SsidLen;
++	if (Connect_SSIDLen > NDIS_802_11_LENGTH_SSID)
++		Connect_SSIDLen = NDIS_802_11_LENGTH_SSID;
++	
++	memset(&Connect_SSID, 0, sizeof(Connect_SSID));
++	memcpy(Connect_SSID, pConnInfo->pSsid, Connect_SSIDLen);
++
++	apcli_entry->wpa_supplicant_info.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
++
++	/* Check the connection is WPS or not */
++	if (pConnInfo->bWpsConnection) 
++	{
++		DBGPRINT(RT_DEBUG_TRACE, ("AP_CLI WPS Connection onGoing.....\n"));
++		apcli_entry->wpa_supplicant_info.WpaSupplicantUP |= WPA_SUPPLICANT_ENABLE_WPS;
++	}		
++
++	/* Set authentication mode */
++	if (pConnInfo->WpaVer == 2)
++	{
++		if (!pConnInfo->FlgIs8021x == TRUE) 
++		{
++			DBGPRINT(RT_DEBUG_TRACE,("APCLI WPA2PSK\n"));
++			Set_ApCli_AuthMode_Proc(pAd, "WPA2PSK");
++		}
++	}
++	else if (pConnInfo->WpaVer == 1)
++	{
++		if (!pConnInfo->FlgIs8021x) 
++		{
++			DBGPRINT(RT_DEBUG_TRACE,("APCLI WPAPSK\n"));
++			Set_ApCli_AuthMode_Proc(pAd, "WPAPSK");
++		}
++	}
++	else
++		Set_ApCli_AuthMode_Proc(pAd, "OPEN");	
++
++	/* Set PTK Encryption Mode */
++	if (pConnInfo->PairwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_CCMP) {
++		DBGPRINT(RT_DEBUG_TRACE,("AES\n"));
++		Set_ApCli_EncrypType_Proc(pAd, "AES");
++	}
++	else if (pConnInfo->PairwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_TKIP) {
++		DBGPRINT(RT_DEBUG_TRACE,("TKIP\n"));
++		Set_ApCli_EncrypType_Proc(pAd, "TKIP");
++	}
++	else if (pConnInfo->PairwiseEncrypType & RT_CMD_80211_CONN_ENCRYPT_WEP)
++	{
++		DBGPRINT(RT_DEBUG_TRACE,("WEP\n"));
++		Set_ApCli_EncrypType_Proc(pAd, "WEP");
++	}
++	
++	
++	if (pConnInfo->pBssid != NULL)
++	{
++		NdisZeroMemory(apcli_entry->CfgApCliBssid, MAC_ADDR_LEN);
++		NdisCopyMemory(apcli_entry->CfgApCliBssid, pConnInfo->pBssid, MAC_ADDR_LEN);
++	}
++	
++	OPSTATUS_SET_FLAG(pAd, fOP_AP_STATUS_MEDIA_STATE_CONNECTED);
++
++	pAd->cfg80211_ctrl.FlgCfg80211Connecting = TRUE;
++	Set_ApCli_Ssid_Proc(pAd, (PSTRING)Connect_SSID);
++	Set_ApCli_Enable_Proc(pAd, "1");
++	CFG80211DBG(RT_DEBUG_OFF, ("80211> APCLI CONNECTING SSID = %s\n", Connect_SSID));
++
++	return TRUE;	
++}
++
++VOID CFG80211_P2pClientConnectResultInform(
++	VOID *pAdCB, UCHAR *pBSSID,
++        UCHAR *pReqIe, UINT32 ReqIeLen,
++        UCHAR *pRspIe, UINT32 RspIeLen,
++        UCHAR FlgIsSuccess)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
++
++	CFG80211OS_P2pClientConnectResultInform(pAd->ApCfg.ApCliTab[MAIN_MBSSID].wdev.if_dev, pBSSID, 
++					pReqIe, ReqIeLen, pRspIe, RspIeLen, FlgIsSuccess);
++
++	pAd->cfg80211_ctrl.FlgCfg80211Connecting = FALSE;
++}
++
++VOID CFG80211_LostP2pGoInform(VOID *pAdCB)
++{
++	PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pAdCB;
++	CFG80211_CB *p80211CB = pAd->pCfg80211_CB;
++	PNET_DEV pNetDev = NULL;
++	
++	DBGPRINT(RT_DEBUG_TRACE, ("80211> CFG80211_LostGoInform ==> \n"));
++
++	pAd->cfg80211_ctrl.FlgCfg80211Connecting = FALSE;
++	if ((pAd->cfg80211_ctrl.Cfg80211VifDevSet.vifDevList.size > 0) &&        
++	((pNetDev = RTMP_CFG80211_FindVifEntry_ByType(pAd, RT_CMD_80211_IFTYPE_P2P_CLIENT)) != NULL))
++	{
++	        if (pNetDev->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTING)
++       	 	{
++                   cfg80211_connect_result(pNetDev, NULL, NULL, 0, NULL, 0,
++                                                                   WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL);
++        	}
++        	else if (pNetDev->ieee80211_ptr->sme_state == CFG80211_SME_CONNECTED)
++        	{
++                   cfg80211_disconnected(pNetDev, 0, NULL, 0, GFP_KERNEL);
++        	}
++	}
++	else
++		DBGPRINT(RT_DEBUG_ERROR, ("80211> BUG CFG80211_LostGoInform, BUT NetDevice not exist.\n"));
++		
++	Set_ApCli_Enable_Proc(pAd, "0");	
++}
++#endif /* RT_CFG80211_P2P_CONCURRENT_DEVICE */
++#endif /* RT_CFG80211_P2P_SUPPORT */
++#endif /* RT_CFG80211_SUPPORT */
+ 
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/rt_profile.c b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/rt_profile.c
+index 38ca78054ee2..29f532ee0ed0 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/rt_profile.c
++++ b/package/feeds/custom/mt7615d/src/mt_wifi/os/linux/rt_profile.c
+@@ -758,14 +758,14 @@ NDIS_STATUS	RTMPReadParametersHook(RTMP_ADAPTER *pAd)
+ 					buf_size = srcf.fsize  + 1;
+ 				}
+ #endif /* OS_ABL_SUPPORT */
+-					retval =os_file_read(srcf, buffer, buf_size - 1);
+-					if (retval > 0)
+-					{
+-						RTMPSetProfileParameters(pAd, buffer);
+-						retval = NDIS_STATUS_SUCCESS;
+-					}
+-					else
+-						MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
++				retval =os_file_read(srcf, buffer, buf_size - 1);
++				if (retval > 0)
++				{
++					RTMPSetProfileParameters(pAd, buffer);
++					retval = NDIS_STATUS_SUCCESS;
++				}
++				else
++					MTWF_LOG(DBG_CAT_CFG, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("Read file \"%s\" failed(errCode=%d)!\n", src, retval));
+ 
+ 				if (os_file_close(srcf) != 0)
+ 				{
+diff --git a/package/feeds/custom/mt7615d/src/mt_wifi_ap/Makefile b/package/feeds/custom/mt7615d/src/mt_wifi_ap/Makefile
+index 2a1578ff4880..a01f788cd3ac 100644
+--- a/package/feeds/custom/mt7615d/src/mt_wifi_ap/Makefile
++++ b/package/feeds/custom/mt7615d/src/mt_wifi_ap/Makefile
+@@ -8,7 +8,7 @@ WIFI_DRV_PATH = drivers/net/wireless/mtk/mt7615e
+ endif
+ endif
+ 
+-EXTRA_CFLAGS = -I$(WIFI_DRV_PATH)/mt_wifi/include \
++EXTRA_CFLAGS += -I$(WIFI_DRV_PATH)/mt_wifi/include \
+ 				-I$(WIFI_DRV_PATH)/mt_wifi/embedded/include \
+ 				-I$(WIFI_DRV_PATH)/mt_wifi/ate/include \
+ 				-I$(WIFI_DRV_PATH)/mt_wifi/include/mcu
+@@ -487,7 +487,8 @@ ifeq ($(CONFIG_HOSTAPD_MAP_SUPPORT),y)
+ endif
+ 
+ #ENTERPRISE_AP
+-ifeq ($(CONFIG_ENTERPRISE_AP_SUPPORT),y)
++ifeq ($(CONFIG_CFG80211_SUPPORT),y)
++ifneq ($(CONFIG_HOSTAPD_MAP_SUPPORT),y)
+ 	EXTRA_CFLAGS += -DHOSTAPD_11R_SUPPORT
+ 	EXTRA_CFLAGS += -DMBSS_DTIM_SUPPORT
+ 	ifeq ($(CONFIG_VLAN_SUPPORT),y)
+@@ -501,6 +502,7 @@ ifeq ($(CONFIG_ENTERPRISE_AP_SUPPORT),y)
+ 	endif
+ 
+ endif
++endif
+ 
+ #CFG
+ ifeq ($(CONFIG_CFG80211_SUPPORT),y)
+@@ -803,7 +805,7 @@ ifeq ($(CONFIG_AIR_MONITOR),y)
+ endif
+ 
+ ifeq ($(CONFIG_EASY_SETUP_SUPPORT),y)
+-$(DRV_NAME)-objs += $(SRC_EMBEDDED_DIR)/easy_setup/ez_cmm.o
++$(DRV_NAME)-y += $(SRC_EMBEDDED_DIR)/easy_setup/ez_cmm.o
+ endif
+ 
+ ifeq ($(CONFIG_MWDS),y)
+@@ -1297,23 +1299,23 @@ endif
+ # Root
+ #
+ 
+-$(DRV_NAME)-objs += $(ap_objs) $(cmm_objs) $(asic_objs) $(chip_objs) $(rate_objs)\
++$(DRV_NAME)-y += $(ap_objs) $(cmm_objs) $(asic_objs) $(chip_objs) $(rate_objs)\
+                     $(spec_objs) $(func_objs) $(os_objs) $(dot11_ft_objs)
+ 
+-$(DRV_NAME)-objs += $(SRC_EMBEDDED_DIR)/common/eeprom.o\
++$(DRV_NAME)-y += $(SRC_EMBEDDED_DIR)/common/eeprom.o\
+ 					$(SRC_EMBEDDED_DIR)/common/ee_flash.o\
+ 					$(SRC_EMBEDDED_DIR)/common/ee_efuse.o
+ 
+-$(DRV_NAME)-objs += $(SRC_EMBEDDED_DIR)/common/cmm_mac_pci.o
+-$(DRV_NAME)-objs += $(SRC_EMBEDDED_DIR)/common/hif_pci.o
++$(DRV_NAME)-y += $(SRC_EMBEDDED_DIR)/common/cmm_mac_pci.o
++$(DRV_NAME)-y += $(SRC_EMBEDDED_DIR)/common/hif_pci.o
+ 
+-$(DRV_NAME)-objs += $(SRC_DIR)/os/linux/rt_pci_rbus.o\
++$(DRV_NAME)-y += $(SRC_DIR)/os/linux/rt_pci_rbus.o\
+                     $(SRC_DIR)/os/linux/rt_rbus_pci_drv.o\
+                     $(SRC_DIR)/os/linux/rt_rbus_pci_util.o\
+                     #$(SRC_DIR)/os/linux/rbus_main_dev.o
+ 
+ ifeq ($(CONFIG_ATE_SUPPORT),y)
+-$(DRV_NAME)-objs += $(SRC_DIR)/ate/ate_agent.o\
++$(DRV_NAME)-y += $(SRC_DIR)/ate/ate_agent.o\
+                     $(SRC_DIR)/ate/testmode_ioctl.o\
+ 		    $(SRC_DIR)/ate/mt_mac/mt_testmode.o\
+  		    $(SRC_DIR)/ate/LoopBack.o
+@@ -1321,7 +1323,7 @@ endif
+ 
+ 
+ ifeq ($(CONFIG_TCP_RACK_SUPPORT),y)
+-$(DRV_NAME)-objs += $(SRC_EMBEDDED_DIR)/common/cmm_tcprack.o
++$(DRV_NAME)-y += $(SRC_EMBEDDED_DIR)/common/cmm_tcprack.o
+ endif
+ 
+ ifeq ($(CONFIG_LED_CONTROL_SUPPORT),y)
+@@ -1433,4 +1435,6 @@ endif
+ 
+ MODULE_FLAGS=$(EXTRA_CFLAGS)
+ export MODULE_FLAGS
++ifeq ($(CONFIG_WHNAT_SUPPORT),y)
+ obj-m+=$(SRC_EMBEDDED_DIR)/plug_in/
++endif

+ 1 - 4
devices/k2p-32m-usb/diy.sh

@@ -2,14 +2,11 @@ rm -Rf target/linux/{ramips,generic}
 svn co https://github.com/coolsnowwolf/lede/trunk/target/linux/ramips target/linux/ramips
 svn co https://github.com/coolsnowwolf/lede/trunk/target/linux/generic target/linux/generic
 
-rm -rf feeds/custom/mt-drivers
-svn co https://github.com/immortalwrt/immortalwrt/branches/master/package/kernel/mt-drivers package/feeds/custom/mt-drivers
+sed -i 's/kmod-mt7615d_dbdc/kmod-mt7615d luci-app-mtwifi/g' target/linux/ramips/image/mt7621.mk
 
 rm -rf include/kernel-version.mk
 wget -O include/kernel-version.mk https://raw.githubusercontent.com/coolsnowwolf/lede/master/include/kernel-version.mk
 
-sed -i 's/kmod-mt7615d_dbdc/kmod-mt7615d luci-app-mtwifi/g' target/linux/ramips/image/mt7621.mk
-
 sed -i 's?admin/status/channel_analysis??' package/feeds/luci/luci-mod-status/root/usr/share/luci/menu.d/luci-mod-status.json
 
 sed -i 's/PKG_VERSION:=1/PKG_VERSION:=2/' package/feeds/custom/luci-app-bypass/Makefile

+ 0 - 3
devices/phicomm-k2p/diy.sh

@@ -2,9 +2,6 @@ rm -Rf target/linux/{ramips,generic}
 svn co https://github.com/coolsnowwolf/lede/trunk/target/linux/ramips target/linux/ramips
 svn co https://github.com/coolsnowwolf/lede/trunk/target/linux/generic target/linux/generic
 
-rm -rf feeds/custom/mt-drivers
-svn co https://github.com/immortalwrt/immortalwrt/branches/master/package/kernel/mt-drivers package/feeds/custom/mt-drivers
-
 rm -rf include/kernel-version.mk
 wget -O include/kernel-version.mk https://raw.githubusercontent.com/coolsnowwolf/lede/master/include/kernel-version.mk
 

+ 2 - 2
onekey/compile.sh

@@ -148,10 +148,10 @@ if [ -f "devices/$firmware/default-settings" ]; then
 	cat -f devices/$firmware/default-settings >> package/*/*/default-settings/files/uci.defaults
 fi
 if [ -n "$(ls -A "devices/common/patches" 2>/dev/null)" ]; then
-          find "devices/common/patches" -type f -name '*.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
+          find "devices/common/patches" -type f -name '*.patch' ! -name '*.revert.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
 fi
 if [ -n "$(ls -A "devices/$firmware/patches" 2>/dev/null)" ]; then
-          find "devices/$firmware/patches" -type f -name '*.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
+          find "devices/$firmware/patches" -type f -name '*.patch' ! -name '*.revert.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
 fi
 cp devices/common/.config .config
 echo >> .config

+ 2 - 2
onekey/recompile.sh

@@ -78,10 +78,10 @@ if [ -f "devices/$firmware/default-settings" ]; then
 	cat devices/$firmware/default-settings >> package/*/*/default-settings/files/uci.defaults
 fi
 if [ -n "$(ls -A "devices/common/patches" 2>/dev/null)" ]; then
-          find "devices/common/patches" -type f -name '*.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
+          find "devices/common/patches" -type f -name '*.patch' ! -name '*.revert.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
 fi
 if [ -n "$(ls -A "devices/$firmware/patches" 2>/dev/null)" ]; then
-          find "devices/$firmware/patches" -type f -name '*.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
+          find "devices/$firmware/patches" -type f -name '*.patch' ! -name '*.revert.patch' -print0 | sort -z | xargs -I % -t -0 -n 1 sh -c "cat '%'  | patch -d './' -p1 --forward"
 fi
 [ -f ".config.bak" ] && cp -f .config.bak .config || {
 cp -f devices/common/.config .config