Merge "[Fix wifi_getRadioVapInfoMap error handling issue]"
diff --git a/src/logan_wifi/wifi_hal.c b/src/logan_wifi/wifi_hal.c
index eae5dfb..9192a2e 100644
--- a/src/logan_wifi/wifi_hal.c
+++ b/src/logan_wifi/wifi_hal.c
@@ -1193,9 +1193,6 @@
 	for (i=0; i<item_count; i++, list++) {
 		fp = v_secure_popen("r", "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
 
-
-
-
 		if (fp == NULL) {
 			perror("v_secure_popen failed");
 			return -1;
@@ -1219,12 +1216,12 @@
 	if (multiple_set == TRUE)
 		return RETURN_OK;
 
+
 	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
 		return RETURN_ERR;
 
 	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s reload", interface_name);
-
-if (res) {
+	if (res) {
 		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
 		return RETURN_ERR;
  	}
@@ -3674,7 +3671,7 @@
 	struct nlattr * msg_data = NULL;
 	struct mtk_nl80211_param param;
 
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
+	WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s:%d_%d\n", __func__, channelMode, pureMode, __LINE__);
 
 	wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
 
@@ -5866,8 +5863,10 @@
 	char config_file[MAX_BUF_SIZE] = {0};
 	wifi_band band = wifi_index_to_band(radioIndex);
 	int res;
+	bool temp_multiple_set = multiple_set;
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
+
 	if(NULL == TransmitRates)
 		return RETURN_ERR;
 	if (strlen(TransmitRates) >= sizeof(sub_set))
@@ -5973,6 +5972,11 @@
 	}
 
 	wifi_hostapdWrite(config_file,&params,1);
+	multiple_set = false;
+	wifi_hostapdProcessUpdate(radioIndex, &params, 1);
+	wifi_quick_reload_ap(radioIndex);
+	multiple_set = temp_multiple_set;
+
 	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
 	return RETURN_OK;
 }
@@ -7462,80 +7466,132 @@
 	return RETURN_OK;
 }
 
+int mtk_get_ap_amsdu_callback(struct nl_msg *msg, void *data) {
+    struct nlattr *tb[NL80211_ATTR_MAX + 1];
+    struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX + 1];
+    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+    unsigned char status;
+    unsigned char *out_status = data;
+    int err = 0;
+
+    err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+              genlmsg_attrlen(gnlh, 0), NULL);
+    if (err < 0){
+        wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
+        return err;
+    }
+
+    if (tb[NL80211_ATTR_VENDOR_DATA]) {
+        err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX,
+            tb[NL80211_ATTR_VENDOR_DATA], NULL);
+        if (err < 0){
+            wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
+            return err;
+        }
+
+        if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN]) {
+            status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN]);
+            if (status == 0) {
+                wifi_debug(DEBUG_INFO, "disabled\n");
+            } else {
+                wifi_debug(DEBUG_INFO, "enabled\n");
+            }
+            *out_status = status;
+        }
+    }
+    return 0;
+}
+
 // outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
 INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
 {
-	char dat_file[128] = {0};
-	wifi_band band;
-	char amdus_buff[8] = {'\0'};
-	int res;
+	char inf_name[IF_NAME_SIZE] = {0};
+	unsigned int if_idx = 0;
+	int ret = -1;
+	struct unl unl_ins;
+	struct nl_msg *msg	= NULL;
+	struct nlattr * msg_data = NULL;
+	struct mtk_nl80211_param param;
 
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
+	if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
+		return RETURN_ERR;
+	if_idx = if_nametoindex(inf_name);
+	/*init mtk nl80211 vendor cmd*/
+	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
+	param.if_type = NL80211_ATTR_IFINDEX;
+	param.if_idx = if_idx;
 
-	band = wifi_index_to_band(radioIndex);
-	if (band == band_invalid) {
-		printf("%s:Band Error\n", __func__);
+	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;
 	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
+	/*add mtk vendor cmd data*/
+	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN, 0xf)) {
+		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
+		nlmsg_free(msg);
+		goto err;
 	}
 
-	wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
-	if (strncmp(amdus_buff, "1", 1) == 0)
-		*output_bool = TRUE;
-	else
-		*output_bool = FALSE;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
+	/*send mtk nl80211 vendor msg*/
+	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_amsdu_callback, output_bool);
+	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_INFO,"send cmd success, get output_bool:%d\n", *output_bool);
 	return RETURN_OK;
+err:
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
+	return RETURN_ERR;
 }
 
 // enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
 INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
 {
-	char dat_file[128] = {0};
-	BOOL enable;
-	wifi_band band;
-	char amdus_buff[8] = {'\0'};
-	struct params params = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
+	char inf_name[IF_NAME_SIZE] = {0};
+	unsigned int if_idx = 0;
+	struct unl unl_ins;
+	struct nl_msg *msg	= NULL;
+	struct nlattr * msg_data = NULL;
+	struct mtk_nl80211_param param;
+	int ret = -1;
 
-	band = wifi_index_to_band(radioIndex);
-	if (band == band_invalid) {
-		printf("%s:Band Error\n", __func__);
+	if (wifi_GetInterfaceName(radioIndex, inf_name) != RETURN_OK)
 		return RETURN_ERR;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
+	if_idx = if_nametoindex(inf_name);
+	/*init mtk nl80211 vendor cmd*/
+	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
+	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;
 	}
-
-	wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
-	if (strncmp(amdus_buff, "1", 1) == 0)
-		enable = TRUE;
-	else
-		enable = FALSE;
-	if (amsduEnable == enable)
-		return RETURN_OK;
-
-	params.name = "HT_AMSDU";
-	if (amsduEnable)
-		params.value = "1";
-	else
-		params.value = "0";
-	wifi_datfileWrite(dat_file, &params, 1);
-	wifi_reloadAp(radioIndex);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
+	/*add mtk vendor cmd data*/
+	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN, amsduEnable)) {
+		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
+		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);
 	return RETURN_OK;
+err:
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
+	return RETURN_ERR;
 }
 
 //P2  // outputs the number of Tx streams
@@ -12622,6 +12678,7 @@
 	struct params params;
 	char config_file[MAX_BUF_SIZE] = {0};
 	int res;
+	bool temp_multiple_set = multiple_set;
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 	if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
@@ -12646,6 +12703,11 @@
 	}
 
 	wifi_hostapdWrite(config_file, &params, 1);
+	multiple_set = false;
+	wifi_hostapdProcessUpdate(apIndex, &params, 1);
+	wifi_quick_reload_ap(apIndex);
+	multiple_set = temp_multiple_set;
+
 	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
 	return RETURN_OK;
 }
@@ -12816,6 +12878,7 @@
 	wifi_band band = wifi_index_to_band(wlanIndex);
 	unsigned long len;
 	int res;
+	bool temp_multiple_set = multiple_set;
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 	if(NULL == output)
@@ -12898,7 +12961,13 @@
 		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		return RETURN_ERR;
 	}
+
 	wifi_hostapdWrite(config_file,&params,1);
+	multiple_set = false;
+	wifi_hostapdProcessUpdate(wlanIndex, &params, 1);
+	wifi_quick_reload_ap(wlanIndex);
+	multiple_set = temp_multiple_set;
+
 	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
 
 	return RETURN_OK;
@@ -14161,56 +14230,134 @@
 	return RETURN_OK;
 }
 
+int mtk_get_ap_isolation_callback(struct nl_msg *msg, void *data) {
+    struct nlattr *tb[NL80211_ATTR_MAX + 1];
+    struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX + 1];
+    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+    unsigned char status;
+    unsigned char *out_status = data;
+    int err = 0;
+
+    err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+              genlmsg_attrlen(gnlh, 0), NULL);
+    if (err < 0){
+        wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
+        return err;
+    }
+
+    if (tb[NL80211_ATTR_VENDOR_DATA]) {
+        err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX,
+            tb[NL80211_ATTR_VENDOR_DATA], NULL);
+        if (err < 0){
+            wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
+            return err;
+        }
+
+        if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_ISOLATION]) {
+            status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_ISOLATION]);
+            if (status == 0) {
+                wifi_debug(DEBUG_INFO, "disabled\n");
+            } else {
+                wifi_debug(DEBUG_INFO, "enabled\n");
+            }
+            *out_status = status;
+        }
+    }
+    return 0;
+
+}
+
 //Enables or disables device isolation. A value of true means that the devices connected to the Access Point are isolated from all other devices within the home network (as is typically the case for a Wireless Hotspot).
 INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
 {
-	char output_val[16]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
+    char inf_name[IF_NAME_SIZE] = {0};
+    unsigned int if_idx = 0;
+    int ret = -1;
+    struct unl unl_ins;
+    struct nl_msg *msg  = NULL;
+    struct nlattr * msg_data = NULL;
+    struct mtk_nl80211_param param;
 
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (!output)
-		return RETURN_ERR;
+    if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
+        return RETURN_ERR;
+    if_idx = if_nametoindex(inf_name);
 
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
+    /*init mtk nl80211 vendor cmd*/
+    param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
+    param.if_type = NL80211_ATTR_IFINDEX;
+    param.if_idx = if_idx;
 
-	if( strcmp(output_val,"1") == 0 )
-		*output = TRUE;
-	else
-		*output = FALSE;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
+    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_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_ISOLATION, 0xf)) {
+        wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
+        nlmsg_free(msg);
+        goto err;
+    }
 
-	return RETURN_OK;
+    /*send mtk nl80211 vendor msg*/
+    ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_isolation_callback, output);
+    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_INFO,"send cmd success, get output_bool:%d\n", *output);
+    return RETURN_OK;
+err:
+    mtk_nl80211_deint(&unl_ins);
+    wifi_debug(DEBUG_ERROR,"send cmd fails\n");
+    return RETURN_ERR;
 }
 
 INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
 {
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	char string[MAX_BUF_SIZE]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params params;
-	int res;
-
-	string[0] = enable == TRUE ? '1' : '0';
+    char inf_name[IF_NAME_SIZE] = {0};
+    unsigned int if_idx = 0;
+    int ret = -1;
+    struct unl unl_ins;
+    struct nl_msg *msg  = NULL;
+    struct nlattr * msg_data = NULL;
+    struct mtk_nl80211_param nl_param;
 
-	params.name = "ap_isolate";
-	params.value = string;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
+    if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
+        return RETURN_ERR;
+    if_idx = if_nametoindex(inf_name);
 
-	wifi_hostapdWrite(config_file,&params,1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
+    nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
+    nl_param.if_type = NL80211_ATTR_IFINDEX;
+    nl_param.if_idx = if_idx;
+    /*init mtk nl80211 vendor cmd*/
+    ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_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_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_ISOLATION, enable)) {
+        wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_ISOLATION);
+        nlmsg_free(msg);
+        goto err;
+    }
 
-	return RETURN_OK;
+    /*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);
+    return RETURN_OK;
+err:
+    mtk_nl80211_deint(&unl_ins);
+    wifi_debug(DEBUG_ERROR,"send cmd fails\n");
+    return RETURN_ERR;
 }
 
 INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
@@ -14334,11 +14481,13 @@
 {
 	return RETURN_OK;
 }
+
 INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
 {
 	char config_file[MAX_BUF_SIZE] = {0};
 	struct params list;
 	int res;
+	bool temp_multiple_set = multiple_set;
 
 	list.name = "bss_transition";
 	list.value = activate?"1":"0";
@@ -14348,9 +14497,15 @@
 		return RETURN_ERR;
 	}
 	wifi_hostapdWrite(config_file, &list, 1);
+	multiple_set = false;
+	wifi_hostapdProcessUpdate(apIndex, &list, 1);
+	wifi_quick_reload_ap(apIndex);
+	multiple_set = temp_multiple_set;
 
 	return RETURN_OK;
 }
+
+
 wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
 
 void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
@@ -14980,6 +15135,7 @@
 	char config_file[MAX_BUF_SIZE] = {0};
 	struct params list;
 	int res;
+	bool temp_multiple_set = multiple_set;
 
 	list.name = "rrm_neighbor_report";
 	list.value = activate?"1":"0";
@@ -14988,11 +15144,18 @@
 		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		return RETURN_ERR;
 	}
+
 	wifi_hostapdWrite(config_file, &list, 1);
 
+	multiple_set = false;
+	wifi_hostapdProcessUpdate(apIndex, &list, 1);
+	wifi_quick_reload_ap(apIndex);
+	multiple_set = temp_multiple_set;
+
 	return RETURN_OK;
 }
 
+
 INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
 {
 	char buf[32] = {0};
@@ -16046,7 +16209,7 @@
 		wifi_debug(DEBUG_ERROR, "strtol fail\n");
 	}
 
-	WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
+	WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%ld,mimo=%ld\n", __func__, ofdma, mimo);
 	if ((ofdma == 1) && (mimo == 1))
 		*mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
 	else if ((ofdma == 0) && (mimo == 1))
@@ -16792,16 +16955,48 @@
 		printf("extchannel is %s \n",buf);
 		return 0;
 	}
+	if (strstr(argv[1], "wifi_setRadioAMSDUEnable")!=NULL) {
+		unsigned char enable = atoi(argv[3]);
+		BOOL out_put;
+		if (enable)
+			wifi_setRadioAMSDUEnable(index, TRUE);
+		else
+			wifi_setRadioAMSDUEnable(index, FALSE);
+		wifi_getRadioAMSDUEnable(index, &out_put);
+		printf("amsdu = %d\n", out_put);
+	}
+	if (strstr(argv[1], "wifi_setApIsolationEnable")!=NULL) {
+		unsigned char enable = atoi(argv[3]);
+		BOOL out_put;
+		if (enable)
+			wifi_setApIsolationEnable(index, TRUE);
+		else
+			wifi_setApIsolationEnable(index, FALSE);
+		wifi_getApIsolationEnable(index, &out_put);
+		printf("isolation input=%d, output=%d\n", enable, out_put);
+	}
 	if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
 	{
-		UINT pureMode = atoi(argv[3]);
+		UINT pureMode;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
 
+		pureMode = atoi(argv[3]);
 		wifi_setRadioMode(index, NULL, pureMode);
 		printf("Ap SET Radio mode 0x%x\n", pureMode);
 		return 0;
 	}
 	if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
-		unsigned char enable = atoi(argv[3]);
+		unsigned char enable;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		enable = atoi(argv[3]);
 		if (enable)
 			wifi_setRadioAutoBlockAckEnable(index, TRUE);
 		else
@@ -16824,26 +17019,40 @@
 	}
 	if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
 	{
-		ULONG TransmitPower = atoi(argv[3]);
-
+		ULONG TransmitPower;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		TransmitPower = atoi(argv[3]);
 		wifi_setRadioTransmitPower(index, TransmitPower);
 		printf("Ap SET TransmitPower %lu\n", TransmitPower);
 		return 0;
 	}
 	if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
 	{
-		INT TransmitPower = atoi(argv[3]);
-
+		INT TransmitPower;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		TransmitPower = atoi(argv[3]);
 		wifi_setApManagementFramePowerControl(index, TransmitPower);
 		printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
 		return 0;
 	}
 	if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
 	{
-		CHAR *bandwith = argv[3];
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
 
-		wifi_setRadioOperatingChannelBandwidth(index, bandwith);
-		printf("Ap SET bw %s\n", bandwith);
+		wifi_setRadioOperatingChannelBandwidth(index, argv[3]);
+		printf("Ap SET bw %s\n", argv[3]);
 		return 0;
 	}
 	if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
@@ -16939,7 +17148,7 @@
 		wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
 		return 0;
 	}
-	if (strncmp(argv[1], "wifi_setRadioDCSEnable(", strlen(argv[1])) == 0) {
+	if (strncmp(argv[1], "wifi_setRadioDCSEnable", strlen(argv[1])) == 0) {
 		int enable = 0;
 		if(argc <= 3 )
 		{
@@ -16951,30 +17160,38 @@
 		wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
 		return 0;
 	}
-	if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod(", strlen(argv[1])) == 0) {
+	if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod", strlen(argv[1])) == 0) {
 		ULONG period = 0;
 
 		wifi_getRadioAutoChannelRefreshPeriod(index, &period);
 		wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
 		return 0;
 	}
-	if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod(", strlen(argv[1])) == 0) {
+	if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod", strlen(argv[1])) == 0) {
 		ULONG period = 0;
-
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
 		period = (ULONG)atoi(argv[3]);
 		wifi_setRadioDfsRefreshPeriod(index, period);
 		wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
 		return 0;
 	}
-	if (strncmp(argv[1], "wifi_setRadioDCSChannelPool(", strlen(argv[1])) == 0) {
+	if (strncmp(argv[1], "wifi_setRadioDCSChannelPool", strlen(argv[1])) == 0) {
 		char pool[256] = {'\0'};
-
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
 		strncpy(pool, argv[3], strlen(argv[3]));
 		wifi_setRadioDCSChannelPool(index, pool);
 		wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
 		return 0;
 	}
-	if (strncmp(argv[1], "wifi_getRadioDCSChannelPool(", strlen(argv[1])) == 0) {
+	if (strncmp(argv[1], "wifi_getRadioDCSChannelPool", strlen(argv[1])) == 0) {
 		char pool[256] = {'\0'};
 
 		wifi_getRadioDCSChannelPool(index, pool);
@@ -17101,7 +17318,13 @@
 		printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
 	}
 	else if(strstr(argv[1], "setApEnable")!=NULL) {
-		BOOL enable = atoi(argv[3]);
+		BOOL enable;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		enable = atoi(argv[3]);
 		ret=wifi_setApEnable(index, enable);
 		printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
 	}
@@ -17370,12 +17593,23 @@
 	}
 	if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
 	{
-		int enable = atoi(argv[3]);
+		int enable;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		enable = atoi(argv[3]);
 		wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
 		printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
 	}
 	if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
 	{
+		if(argc <= 5)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
 		wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
 		printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
 	}
@@ -17427,7 +17661,13 @@
 	}
 	if (strstr(argv[1],"setGF")!=NULL)
 	{
-		BOOL enable = atoi(argv[3]);
+		BOOL enable;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		enable = atoi(argv[3]);
 		if((ret=wifi_setRadio11nGreenfieldEnable(index, enable))==RETURN_OK)
 			printf("wifi_setRadio11nGreenfieldEnable success\n");
 		else
@@ -17435,7 +17675,13 @@
 	}
 	if (strstr(argv[1],"setVID")!=NULL)
 	{
-		INT vid = atoi(argv[3]);
+		INT vid;
+		if(argc <= 3)
+		{
+			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
+			exit(-1);
+		}
+		vid = atoi(argv[3]);
 		if((ret=wifi_setApVlanID(index, vid))==RETURN_OK)
 			printf("wifi_setApVlanID success.\n");
 		else
diff --git a/src/wifi/wifi_hal.c b/src/wifi/wifi_hal.c
index f0bda1b..5535304 100644
--- a/src/wifi/wifi_hal.c
+++ b/src/wifi/wifi_hal.c
@@ -3137,35 +3137,74 @@
 {
         if (NULL == output_list)
                 return RETURN_ERR;
-        snprintf(output_list, 64,"0,25,50,75,100");
+        snprintf(output_list, 64,"0,12,25,50,75,100");
         return RETURN_OK;
 }
 
-//Get current Transmit Power in dBm units.
-//The transmite power level is in units of full power for this radio.
+// Get current Transmit Power in percent
 INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong)	//RDKB
 {
-    char interface_name[16] = {0};
-    char cmd[128]={0};
-    char buf[16]={0};
+    char cmd[128]={'\0'};
+    char buf[128]={'\0'};
+    int phyIndex = -1;
+    bool enabled = false;
+    int cur_tx_dbm = 0;
+
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
     if(output_ulong == NULL)
         return RETURN_ERR;
 
-    if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
-        return RETURN_ERR;
-    snprintf(cmd, sizeof(cmd),  "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
+    phyIndex = radio_index_to_phy(radioIndex);
+
+    // Get the maximum tx power of the device
+    snprintf(cmd, sizeof(cmd),  "cat /sys/kernel/debug/ieee80211/phy%d/mt76/txpower_info | "
+                                "grep 'Percentage Control:' | awk '{print $3}' | tr -d '\\n'", phyIndex);
     _syscmd(cmd, buf, sizeof(buf));
+    if (strcmp(buf, "enable") == 0)
+        enabled = true;
 
-    *output_ulong = strtol(buf, NULL, 10);
+    if (!enabled) {
+        *output_ulong = 100;
+        return RETURN_OK;
+    }
 
-    WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
+    memset(cmd, 0, sizeof(cmd));
+    memset(buf, 0, sizeof(buf));
+    snprintf(cmd, sizeof(cmd),  "cat /sys/kernel/debug/ieee80211/phy%d/mt76/txpower_info | "
+                                "grep 'Power Drop:' | awk '{print $3}' | tr -d '\\n'", phyIndex);
+    _syscmd(cmd, buf, sizeof(buf));
+    cur_tx_dbm = strtol(buf, NULL, 10);
+
+    switch (cur_tx_dbm) {
+        case 0:
+            *output_ulong = 100; // range 91-100
+            break;
+        case 1:
+            *output_ulong = 75;  // range 61-90
+            break;
+        case 3:
+            *output_ulong = 50;  // range 31-60
+            break;
+        case 6:
+            *output_ulong = 25;  // range 16-30
+            break;
+        case 9:
+            *output_ulong = 12; // range 10-15
+            break;
+        case 12:
+            *output_ulong = 6;  // range 1-9
+            break;
+        default:
+            *output_ulong = 100; // 0
+    }
+
     return RETURN_OK;
 }
 
-//Set Transmit Power
-//The transmite power level is in units of full power for this radio.
+// TransmitPower: the the percentage relative to the maximum power,
+// only support 0,12,25,50,75,100, But 0 means disable Power limit,
+// so the power is 100%
 INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower)	//RDKB
 {
     char interface_name[16] = {0};
@@ -3173,17 +3212,12 @@
     char cmd[128]={0};
     char buf[128]={0};
     char txpower_str[64] = {0};
-    int txpower = 0;
-    int maximum_tx = 0;
     int phyId = 0;
 
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
     if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
         return RETURN_ERR;
-    snprintf(cmd, sizeof(cmd),  "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
-    _syscmd(cmd, buf, sizeof(buf));
-    maximum_tx = strtol(buf, NULL, 10);
 
     // Get the Tx power supported list and check that is the input in the list
     snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
@@ -3200,10 +3234,12 @@
         }
         support = strtok(NULL, ",");
     }
-    txpower = TransmitPower*maximum_tx/100;
+
     phyId = radio_index_to_phy(radioIndex);
-    snprintf(cmd, sizeof(cmd),  "iw phy phy%d set txpower fixed %d00", phyId, txpower);
+    snprintf(cmd, sizeof(cmd),  "echo %lu > /sys/kernel/debug/ieee80211/phy%d/mt76/txpower_level",
+                                TransmitPower, phyId);
     _syscmd(cmd, buf, sizeof(buf));
+
     WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
 
     return RETURN_OK;
@@ -11100,52 +11136,68 @@
     return RETURN_ERR;
 }
 
+
 INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
 {
-    char interface_name[16] = {0};
     char cmd[128]={'\0'};
     char buf[128]={'\0'};
-    char *support;
-    int maximum_tx = 0, current_tx = 0;
+    int radioIndex = -1;
+    int phyIndex = -1;
+    bool enabled = false;
+    int cur_tx_dbm = 0;
 
     WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
+
     if(txpwr_pcntg == NULL)
         return RETURN_ERR;
 
-    if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-        return RETURN_ERR;
+    // The API name as getRadioXXX, I think the input index should be radioIndex,
+    // but current we not change the name, but use it as radioIndex
+    radioIndex = apIndex;
+    phyIndex = radio_index_to_phy(radioIndex);
 
     // Get the maximum tx power of the device
-    snprintf(cmd, sizeof(cmd),  "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
+    snprintf(cmd, sizeof(cmd),  "cat /sys/kernel/debug/ieee80211/phy%d/mt76/txpower_info | "
+                                "grep 'Percentage Control:' | awk '{print $3}' | tr -d '\\n'", phyIndex);
     _syscmd(cmd, buf, sizeof(buf));
-    maximum_tx = strtol(buf, NULL, 10);
+    if (strcmp(buf, "enable") == 0)
+        enabled = true;
 
-    // Get the current tx power
+    if (!enabled) {
+        *txpwr_pcntg = 100;
+        return RETURN_OK;
+    }
+
     memset(cmd, 0, sizeof(cmd));
     memset(buf, 0, sizeof(buf));
-    snprintf(cmd, sizeof(cmd),  "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
+    snprintf(cmd, sizeof(cmd),  "cat /sys/kernel/debug/ieee80211/phy%d/mt76/txpower_info | "
+                                "grep 'Power Drop:' | awk '{print $3}' | tr -d '\\n'", phyIndex);
     _syscmd(cmd, buf, sizeof(buf));
-    current_tx = strtol(buf, NULL, 10);
+    cur_tx_dbm = strtol(buf, NULL, 10);
 
-    // Get the power supported list and find the current power percentage in supported list
-    memset(buf, 0, sizeof(buf));
-    wifi_getRadioTransmitPowerSupported(apIndex, buf);
-    support = strtok(buf, ",");
-    while(true)
-    {
-        if(support == NULL) {       // current power is not in supported list, this should not happen if the power is set by hal.
-            *txpwr_pcntg = 100;
-            wifi_dbg_printf("current power is not in supported list\n");
-            return RETURN_OK;
-        }
-        int tmp = maximum_tx*strtol(support, NULL, 10)/100;
-        if (tmp == current_tx) {
-            *txpwr_pcntg = strtol(support, NULL, 10);
+    switch (cur_tx_dbm) {
+        case 0:
+            *txpwr_pcntg = 100; // range 91-100
             break;
-        }
-        support = strtok(NULL, ",");
+        case 1:
+            *txpwr_pcntg = 75;  // range 61-90
+            break;
+        case 3:
+            *txpwr_pcntg = 50;  // range 31-60
+            break;
+        case 6:
+            *txpwr_pcntg = 25;  // range 16-30
+            break;
+        case 9:
+            *txpwr_pcntg = 12; // range 10-15
+            break;
+        case 12:
+            *txpwr_pcntg = 6;  // range 1-9
+            break;
+        default:
+            *txpwr_pcntg = 100; // 0
     }
-    WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
+
     return RETURN_OK;
 }