Merge "[[RDKB][mt7990]rdkb development]"
diff --git a/src/logan_wifi/wifi_hal.c b/src/logan_wifi/wifi_hal.c
index 8966d84..f6d9b7b 100644
--- a/src/logan_wifi/wifi_hal.c
+++ b/src/logan_wifi/wifi_hal.c
@@ -133,7 +133,7 @@
 {	\
 	if (level <= wifi_debug_level)	\
 	{ \
-		printf("[%s][%d]"fmt"\n", __func__, __LINE__, ##args);	\
+		printf("[%s][%d]"fmt"", __func__, __LINE__, ##args);	\
 	} \
 }
 
@@ -258,6 +258,7 @@
 static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
 static void wifi_PrepareDefaultHostapdConfigs(void);
 static void wifi_psk_file_reset();
+static int util_get_sec_chan_offset(int channel, const char* ht_mode);
 
 /*type define the nl80211 call back func*/
 typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
@@ -348,7 +349,6 @@
 
 	return 0;
 err:
-
 	nlmsg_free(*msg);
 	unl_free(nl);
 	return -1;
@@ -391,10 +391,10 @@
 
 /**
 *mtk_nl80211_deint
-* deinit the netlink and the nl80211 vendor msg.
+* deinit the netlink.
 * @nl: netlink.
 *
-*free deinit the netlink and the nl80211 vendor msg.
+*free deinit the netlink.
 *
 *return:
 *	0: success
@@ -3294,9 +3294,9 @@
     CHAR cmd[150] = {0};
 
     wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
-    if (strncmp(buf, "0", 1) == 0)  //bewlow
+    if (strncmp(buf, "Below", 5) == 0)  //below
         strcpy(Value,"BelowControlChannel");
-    if(strncmp(buf, "1", 1) == 0)      //above
+    if(strncmp(buf, "Above", 5) == 0)      //above
         strcpy(Value,"AboveControlChannel");
     return RETURN_OK;
 }
@@ -3779,7 +3779,6 @@
     char buf[16] = {0};
     FILE *f = NULL;
     char config_file_dat[128] = {0};
-    char dfs_key[16] = "DfsEnable";
     wifi_band band = band_invalid;
 
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
@@ -3790,7 +3789,7 @@
     band = wifi_index_to_band(radioIndex);
     snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
 
-    wifi_datfileRead(config_file_dat, dfs_key, buf, sizeof(buf));
+    wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
 
     if (strncmp(buf, "0", 1) == 0)
         *output_bool = FALSE;
@@ -3818,7 +3817,7 @@
     wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
 
     dat.name = "DfsEnable";
-    dat.value = enable?"0":"1";
+    dat.value = enable?"1":"0";
     band = wifi_index_to_band(radioIndex);
     snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
     wifi_datfileWrite(config_dat_file, &dat, 1);
@@ -3910,6 +3909,9 @@
     char eht_value[16];
     struct params dat[3];
     wifi_band band = band_invalid;
+    char cmd[MAX_CMD_SIZE] = {0};
+    char buf[MAX_BUF_SIZE] = {0};
+    int bw = 20;
 
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
@@ -3921,22 +3923,27 @@
         snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
         snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
         snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
+        bw = 320;
     } else if(strstr(bandwidth,"160") != NULL) {
         snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
         snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
         snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
+        bw = 160;
     } else if(strstr(bandwidth,"80") != NULL) {
         snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
         snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
         snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
+        bw = 80;
     } else if(strstr(bandwidth,"40") != NULL) {
         snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
         snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
         snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
+         bw = 40;
     } else if(strstr(bandwidth,"20") != NULL) {
         snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
         snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
         snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
+        bw = 20;
     } else {
         fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
         return RETURN_ERR;
@@ -3950,6 +3957,8 @@
     dat[2].name = "EHT_ApBw";
     dat[2].value = eht_value;
     wifi_datfileWrite(config_file, dat, 3);
+    snprintf(cmd, sizeof(cmd),	"mwctl phy phy%d set channel bw=%d\n", band, bw);
+    _syscmd(cmd, buf, sizeof(buf));
 
     WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
     return RETURN_OK;
@@ -4040,6 +4049,7 @@
         return RETURN_ERR;
     bandwidth = strtol(buf, NULL, 10);
     // TDK expected to get error with 20MHz
+    // we handle 20MHz in function wifi_RemoveRadioExtChannel().
     if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
         return RETURN_ERR;
 
@@ -4050,24 +4060,23 @@
     if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
         return RETURN_ERR;
 
-    if (band == band_5) {
-        snprintf(buf, sizeof(buf), "HT%d", bandwidth);
-        centr_channel = util_unii_5g_centerfreq(buf, channel);
-        if (centr_channel == 0)
-            return RETURN_ERR;
-    }
+    snprintf(buf, sizeof(buf), "HT%d", bandwidth);
+    ret = util_get_sec_chan_offset(channel, buf);
+    if (ret == -EINVAL)
+        return RETURN_ERR;
 
     if(NULL!= strstr(string,"Above")) {
-        if ((band == band_2_4 && channel > 9) || (band == band_5 && channel > centr_channel))
-            return RETURN_ERR;
-        snprintf(ext_channel, sizeof(ext_channel), "Above");
+        if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
+            return RETURN_OK;
+	strcpy(ext_channel, "Above");
     } else if(NULL!= strstr(string,"Below")) {
-        if ((band == band_2_4 && channel < 5) || (band == band_5 && channel < centr_channel))
-            return RETURN_ERR;
-        snprintf(ext_channel, sizeof(ext_channel), "Above");
-    } else
+        if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
+            return RETURN_OK;
+        strcpy(ext_channel, "Below");
+    } else {
         printf("%s: invalid EXT_CHA:%s\n", __func__, string);
-
+	return RETURN_ERR;
+    }
     params.name = "HT_EXTCHA";
     params.value = ext_channel;
 
@@ -5837,7 +5846,7 @@
     snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
     snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
     wifi_hostapdWrite(config_file, &list, 1);
-    wifi_datfileWrite(config_dat_file, &list, 1);
+    wifi_datfileWrite(config_dat_file, &dat, 1);
     wifi_hostapdProcessUpdate(apIndex, &list, 1);
 
     WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
@@ -6915,22 +6924,19 @@
 	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
 	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
 	char *show_str = NULL;
-	int err = 0, skip_len = 0;
+	int err = 0;
 	unsigned short acl_result_len = 0;
 	struct mtk_nl80211_cb_data *cb_data = cb;
-
 	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.", msg, cb_data);
+		wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data);
 		return NL_SKIP;
 	}
-
 	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
 			  genlmsg_attrlen(gnlh, 0), NULL);
 	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.");
+		wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
 		return NL_SKIP;
 	}
-
 	if (tb[NL80211_ATTR_VENDOR_DATA]) {
 		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
 			tb[NL80211_ATTR_VENDOR_DATA], NULL);
@@ -6947,16 +6953,15 @@
 				*(show_str + acl_result_len - 1) = '\0';
 			}
 			wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
-			/*skip the first line: 'policy=1\n' len check*/
-			skip_len = (strchr(show_str, '\n')+1 - show_str);
-			if (cb_data->out_len < acl_result_len-skip_len) {
-				wifi_debug(DEBUG_ERROR, "output buffer is not enough! error.\n");
-				return NL_SKIP;
+
+			if (cb_data->out_len >= acl_result_len) {
+				memset(cb_data->out_buf, 0, cb_data->out_len);
+				/*skip the first line: 'policy=1\n' to find the acl mac addrs*/
+				memmove(cb_data->out_buf, show_str, acl_result_len);
+				wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
+			} else {
+				memset(cb_data->out_buf, 0, cb_data->out_len);
 			}
-			memset(cb_data->out_buf, 0, cb_data->out_len);
-			/*skip the first line: 'policy=1\n' to find the acl mac addrs*/
-			memmove(cb_data->out_buf, strchr(show_str, '\n')+1, acl_result_len-skip_len);
-			wifi_debug(DEBUG_INFO, "out buff:%s", cb_data->out_buf);
 		} else
 			wifi_debug(DEBUG_ERROR, "no acl result attr\n");
 	} else
@@ -6964,7 +6969,7 @@
 	return NL_OK;
 }
 // Get the ACL MAC list per AP
-INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
+INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
 {
 	char inf_name[IF_NAME_SIZE] = {0};
 	struct mtk_nl80211_param params;
@@ -6975,13 +6980,11 @@
 	struct nlattr * msg_data = NULL;
 	struct mtk_nl80211_param param;
 	struct mtk_nl80211_cb_data cb_data;
-
 	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
 		return RETURN_ERR;
-
 	if_idx = if_nametoindex(inf_name);
 	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR", inf_name);
+		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
 		return RETURN_ERR;
 	}
 	/*init mtk nl80211 vendor cmd*/
@@ -6994,10 +6997,9 @@
 		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
 		return RETURN_ERR;
 	}
-
 	/*add mtk vendor cmd data*/
 	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
-		printf("Nla put ACL_SHOW_ALL attribute error\n");
+		wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
 		nlmsg_free(msg);
 		goto err;
 	}
@@ -7013,14 +7015,51 @@
 	}
 	/*deinit mtk nl80211 vendor msg*/
 	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_NOTICE,"send cmd success, get macArray:%s", macArray);
+	wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
     return RETURN_OK;
 err:
 	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails");
+	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
 	return RETURN_ERR;
 }
 
+INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
+{
+	char *mac_arry_buf = NULL;
+
+	mac_arry_buf =  malloc(buf_size);
+	if (!mac_arry_buf) {
+		wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
+		return RETURN_ERR;
+	}
+	memset(mac_arry_buf, 0, buf_size);
+	if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
+		wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
+		free(mac_arry_buf);
+		mac_arry_buf = NULL;
+		return RETURN_ERR;
+	}
+	/*
+	mtk format to wifi hal format:
+	"policy=1
+	 00:11:22:33:44:55
+	 00:11:22:33:44:66
+	"
+	-->
+	"00:11:22:33:44:55
+	00:11:22:33:44:66
+	"
+	*/
+	memset(macArray, 0, buf_size);
+	if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
+		memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
+		wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
+	}
+	free(mac_arry_buf);
+	mac_arry_buf = NULL;
+	return RETURN_OK;
+}
+
 INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
 {
 
@@ -7091,8 +7130,6 @@
 //DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
 INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
 {
-	char cmd[MAX_CMD_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
 	char inf_name[IF_NAME_SIZE] = {0};
 	int if_idx, ret = 0;
 	struct nl_msg *msg  = NULL;
@@ -7105,11 +7142,14 @@
 	if (!DeviceMacAddress)
 		return RETURN_ERR;
 	if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
-		printf("error device mac address=%s\n", DeviceMacAddress);
+		wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
 		return RETURN_ERR;
 	}
-
 	if_idx = if_nametoindex(inf_name);
+	if (!if_idx) {
+		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
+		return RETURN_ERR;
+	}
 	/*init mtk nl80211 vendor cmd*/
 	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
 	param.if_type = NL80211_ATTR_IFINDEX;
@@ -7121,11 +7161,10 @@
 	}
 	/*add mtk vendor cmd data*/
 	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
-		printf("Nla put attribute error\n");
+		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
 		nlmsg_free(msg);
 		goto err;
 	}
-
 	/*send mtk nl80211 vendor msg*/
 	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
 	if (ret) {
@@ -7146,9 +7185,13 @@
 //DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
 INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
 {
-	char cmd[MAX_CMD_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
+	struct unl unl_ins;
+	int if_idx = 0, ret = 0;
+	struct nl_msg *msg  = NULL;
+	struct nlattr * msg_data = NULL;
+	struct mtk_nl80211_param param;
 	char inf_name[IF_NAME_SIZE] = {0};
+	unsigned char mac[ETH_ALEN] = {0};
 
 	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
 		return RETURN_ERR;
@@ -7156,39 +7199,91 @@
 	if (!DeviceMacAddress)
 		return RETURN_ERR;
 
-	/* mwctl acl del sta */
-	snprintf(cmd, sizeof(cmd), "mwctl %s acl del=%s", inf_name, DeviceMacAddress);
-	_syscmd(cmd, buf, sizeof(buf));
+	if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
+		wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
+		return RETURN_ERR;
+	}
 
-    return RETURN_OK;
+	if_idx = if_nametoindex(inf_name);
+	if (!if_idx) {
+		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
+		return RETURN_ERR;
+	}
+	/*init mtk nl80211 vendor cmd*/
+	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
+	param.if_type = NL80211_ATTR_IFINDEX;
+	param.if_idx = if_idx;
+	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
+	if (ret) {
+		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
+		return RETURN_ERR;
+	}
+	/*add mtk vendor cmd data*/
+	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
+		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
+		nlmsg_free(msg);
+		goto err;
+	}
+	/*send mtk nl80211 vendor msg*/
+	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
+	if (ret) {
+		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
+		goto err;
+	}
+	/*deinit mtk nl80211 vendor msg*/
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
+	return RETURN_OK;
+err:
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
+	return RETURN_ERR;
 }
 
 // outputs the number of devices in the filter list
 INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
 {
-	char cmd[MAX_CMD_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
 	char inf_name[IF_NAME_SIZE] = {0};
-	char sta_num = 0;
-
+	char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
+	UINT buf_size = 1024;
+	UINT sta_num = 0;
+	unsigned char mac[ETH_ALEN] = {0};
     if(output_uint == NULL)
         return RETURN_ERR;
 
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
+	mac_arry = (char *)malloc(buf_size);
+	if (mac_arry == NULL) {
+		wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
 		return RETURN_ERR;
-
-	/* mwctl acl get sta num */
-	snprintf(cmd, sizeof(cmd), "mwctl %s acl show_all | wc -l | tr -d '\\n'", inf_name);
-	_syscmd(cmd, buf, sizeof(buf));
-
-	if (atoi(buf) > 1)
-		*output_uint = atoi(buf) - 1; /*except the line of acl_policy*/
-	else {
-		*output_uint = 0;
-		printf("%s: acl get wrong return content!!!\n", __func__);
-	 }
+	}
+	memset(mac_arry, buf_size, 0);
+	/*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
+	if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
+		wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
+		return RETURN_ERR;
+	}
+	/*count the acl str nums:*/
+	wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
 
+	/*mac addr string format:
+	exp1: 00:11:22:33:44:55\0
+	exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
+	*/
+	ptr = mac_arry;
+	while (sscanf(ptr, "%17s", mac_str) == 1) {
+		if (hwaddr_aton2(mac_str, mac) >= 0)
+			sta_num++;
+		ptr = strstr(ptr, mac_str) + strlen(mac_str);
+	}
+	*output_uint = sta_num;
+	wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
+	free(mac_arry);
+	mac_arry = NULL;
 	return RETURN_OK;
+err:
+	free(mac_arry);
+	mac_arry = NULL;
+	return RETURN_ERR;
 }
 
 INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
@@ -7251,18 +7346,61 @@
 // sets the mac address filter control mode.  0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
 INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
 {
+	int if_idx = 0, ret = 0;
+	struct unl unl_ins;
+	struct nl_msg *msg  = NULL;
+	struct nlattr * msg_data = NULL;
+	struct mtk_nl80211_param param;
+	int acl_policy = -1;
 	char inf_name[IF_NAME_SIZE] = {0};
-	char cmd[MAX_CMD_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
 
 	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
 		return RETURN_ERR;
-
-	/*mwctl set acl policy*/
-    snprintf(cmd, sizeof(cmd), "mwctl %s acl policy=%d", inf_name, filterMode);
-    _syscmd(cmd, buf, sizeof(buf));
-
+	if_idx = if_nametoindex(inf_name);
+	if (!if_idx) {
+		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
+		return RETURN_ERR;
+	}
+	/*init mtk nl80211 vendor cmd*/
+	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
+	param.if_type = NL80211_ATTR_IFINDEX;
+	param.if_idx = if_idx;
+	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
+	if (ret) {
+		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
+		return RETURN_ERR;
+	}
+	/*add mtk vendor cmd data*/
+	if (filterMode == 0) {
+		acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
+	} else if (filterMode == 1) {
+		acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
+	} else if (filterMode == 2) {
+		acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
+	} else {
+		wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
+		nlmsg_free(msg);
+		goto err;
+	}
+	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
+		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
+		nlmsg_free(msg);
+		goto err;
+	}
+	/*send mtk nl80211 vendor msg*/
+	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
+	if (ret) {
+		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
+		goto err;
+	}
+	/*deinit mtk nl80211 vendor msg*/
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
 	return RETURN_OK;
+err:
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
+	return RETURN_ERR;
 }
 
 // enables internal gateway VLAN mode.  In this mode a Vlan tag is added to upstream (received) data packets before exiting the Wifi driver.  VLAN tags in downstream data are stripped from data packets before transmission.  Default is FALSE.
@@ -9763,9 +9901,18 @@
 
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
     snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
-    wifi_datfileRead(config_file, "Channel" , output, sizeof(output));
+    wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
 
-    *output_bool = (strncmp(output, "0", 1)==0) ?  TRUE : FALSE;
+    if (output == NULL)
+        *output_bool = FALSE;
+    else if (strncmp(output, "1", 1) == 0)
+        *output_bool = TRUE;
+    else if (strncmp(output, "2", 1) == 0)
+        *output_bool = TRUE;
+    else if (strncmp(output, "3", 1) == 0)
+        *output_bool = TRUE;
+    else
+        *output_bool = FALSE;
     WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
 
     return RETURN_OK;
@@ -10309,8 +10456,10 @@
             return RETURN_ERR;
         }
 
-        if (sec_chan_offset == 1) ext_str = "Above";
-        else if (sec_chan_offset == -1) ext_str = "Below";
+        if (sec_chan_offset == 1)
+            ext_str = "Above";
+        else if (sec_chan_offset == -1)
+            ext_str = "Below";
 
         /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
 
@@ -10625,35 +10774,48 @@
 
 INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
 {
-    char cmd[MAX_CMD_SIZE] = {0};
-    char buf[MAX_BUF_SIZE] = {0};
-	char inf_name[IF_NAME_SIZE] = {0};
-	char policy = 0;
-
-    if (!output_filterMode)
-        return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	/* mwctl get acl policy */
-	snprintf(cmd, sizeof(cmd), "mwctl %s acl show_all | grep policy | cut -d '=' -f2 | tr -d '\\n'", inf_name);
-	_syscmd(cmd, buf, sizeof(buf));
-
-
-	policy = atoi(buf);
+	char *mac_arry_buf = NULL;
+	INT policy = -1;
+	INT buf_size = 1024;
 
-	if (policy < 0 || policy > 2) {
-		printf("%s:get wrong acl policy!!!\n", __func__);
-		*output_filterMode = 0;
+	mac_arry_buf =	malloc(buf_size);
+	if (!mac_arry_buf) {
+		wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
 		return RETURN_ERR;
-	} else
-		*output_filterMode = policy;
-
-
-    return RETURN_OK;
+	}
+	memset(mac_arry_buf, 0, buf_size);
+	if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
+		wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
+		goto err;
+	}
+	/*
+	mtk format to get policy:
+	"policy=1
+	 00:11:22:33:44:55
+	 00:11:22:33:44:66
+	"
+	*/
+	if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
+		wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
+		goto err;
+	}
+	if (!(policy >=0 && policy <= 2)){
+		wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
+		goto err;
+	}
+	*output_filterMode = policy;
+	wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
+	free(mac_arry_buf);
+	mac_arry_buf = NULL;
+	return RETURN_OK;
+err:
+	free(mac_arry_buf);
+	mac_arry_buf = NULL;
+	wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
+	return RETURN_ERR;
 }
 
+
 INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
 {
     FILE *fp = NULL;
@@ -11329,16 +11491,49 @@
 
 INT wifi_delApAclDevices(INT apIndex)
 {
-	char cmd[MAX_CMD_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
 	char inf_name[IF_NAME_SIZE] = {0};
+	struct unl unl_ins;
+	int if_idx = 0, ret = 0;
+	struct nl_msg *msg  = NULL;
+	struct nlattr * msg_data = NULL;
+	struct mtk_nl80211_param param;
 
 	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
 		return RETURN_ERR;
-
-	/* mwctl acl clear all stas */
-	snprintf(cmd, sizeof(cmd), "mwctl %s acl clear_all", inf_name);
-	_syscmd(cmd, buf, sizeof(buf));
+	if_idx = if_nametoindex(inf_name);
+	if (!if_idx) {
+		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
+		return RETURN_ERR;
+	}
+	/*init mtk nl80211 vendor cmd*/
+	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
+	param.if_type = NL80211_ATTR_IFINDEX;
+	param.if_idx = if_idx;
+	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
+	if (ret) {
+		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
+		return RETURN_ERR;
+	}
+	/*add mtk vendor cmd data*/
+	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
+		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
+		nlmsg_free(msg);
+		goto err;
+	}
+	/*send mtk nl80211 vendor msg*/
+	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
+	if (ret) {
+		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
+		goto err;
+	}
+	/*deinit mtk nl80211 vendor msg*/
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
+	return RETURN_OK;
+err:
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
+	return RETURN_ERR;
 
     return RETURN_OK;
 }
@@ -13153,20 +13348,62 @@
         printf("Ap name is %s \n",buf);
         return 0;
     }
-	if (strstr(argv[1], "wifi_setApAclDevice")!=NULL) {
+	if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
 		if(argc <= 3 )
         {
-            printf("Insufficient arguments \n");
+            wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
             exit(-1);
         }
 		wifi_addApAclDevice(index, argv[3]);
 		return 0;
 	}
+	if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
+		wifi_getApAclDevices(index, buf, 1024);
+		wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
+		return 0;
+	}
+	if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
+		if(argc <= 3 )
+        {
+           wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+            exit(-1);
+        }
+		wifi_delApAclDevice(index, argv[3]);
+		return 0;
+	}
+	if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
+		wifi_delApAclDevices(index);
+		return 0;
+	}
+	if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
+		int acl_num = 0;
+		wifi_getApAclDeviceNum(index, &acl_num);
+		wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
+		return 0;
+	}
-	if (strstr(argv[1], "wifi_getApAclDevices")!=NULL) {
-		wifi_getApAclDevices(index, buf, MAX_BUF_SIZE);
+	if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
+		wifi_getApDenyAclDevices(index, buf, 1024);
+		wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
 		return 0;
 	}
+	if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
+		int filter_mode = 0;
+		if(argc <= 3 )
+        {
+            wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+            exit(-1);
+        }
+		filter_mode = atoi(argv[3]);
+		wifi_setApMacAddressControlMode(index,filter_mode);
+		return 0;
+	}
 
+	if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
+		int filter_mode = 0;
+		wifi_getApMacAddressControlMode(index, &filter_mode);
+		wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
+		return 0;
+	}
 	if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
     {
     	int mode = 0;