Merge "[[OSBNB00182981][RDKB]enable/disable WPS,  WPS clients are not able to connect]"
diff --git a/src/logan_wifi/wifi_hal.c b/src/logan_wifi/wifi_hal.c
index 398aed3..80be0dc 100644
--- a/src/logan_wifi/wifi_hal.c
+++ b/src/logan_wifi/wifi_hal.c
@@ -99,7 +99,6 @@
 #define VLAN_FILE "/nvram/hostapd.vlan"
 #define PSK_FILE "/nvram/hostapd"
 #define MCS_FILE "/tmp/MCS"
-#define POWER_PERCENTAGE "/tmp/POWER"
 #define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
 /*LOGAN_DAT_FILE: may be different on customer's platform.*/
 #ifdef WIFI_7992
@@ -3434,16 +3433,16 @@
 	}
 }
 
-static void wifi_power_percentage_file_check()
+static void wifi_mcs_file_check()
 {
 	char ret_buf[MAX_BUF_SIZE] = {0};
 	int res;
-	unsigned char band = 0;
+	unsigned char i = 0;
 	char file[MAX_SUB_CMD_SIZE] = {0};
 	FILE *f = NULL;
 
-	for (band = band_2_4; band <= band_6; band++) {
-		res = snprintf(file, sizeof(file), "%s%d.txt", POWER_PERCENTAGE, band);
+	for (i = 0; i < get_runtime_max_radio(); i++) {
+		res = snprintf(file, sizeof(file), "%s%d.txt", MCS_FILE, i);
 		if (os_snprintf_error(sizeof(file), res)) {
 			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		}
@@ -3457,13 +3456,12 @@
 		f = fopen(file, "w");
 		if (f == NULL)
 			return;
-		fprintf(f, "%s", "100");
+		fprintf(f, "%s", "11");
 		if (fclose(f) == EOF)
 			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
 	}
 }
-
-static void wifi_mcs_file_check()
+static void wifi_mgmt_pwr_file_check()
 {
 	char ret_buf[MAX_BUF_SIZE] = {0};
 	int res;
@@ -3472,11 +3470,10 @@
 	FILE *f = NULL;
 
 	for (i = 0; i < get_runtime_max_radio(); i++) {
-		res = snprintf(file, sizeof(file), "%s%d.txt", MCS_FILE, i);
+		res = snprintf(file, sizeof(file), "%s%d.txt", MGMT_POWER_CTRL, i);
 		if (os_snprintf_error(sizeof(file), res)) {
 			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		}
-		wifi_debug(DEBUG_INFO, "%s:file %s", __func__, file);
 		if (access(file, F_OK) != 0) {
 			res =  _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
 			if (res) {
@@ -3486,12 +3483,11 @@
 		f = fopen(file, "w");
 		if (f == NULL)
 			return;
-		fprintf(f, "%s", "11");
+		fprintf(f, "%s", "0");
 		if (fclose(f) == EOF)
 			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
 	}
 }
-
 #ifdef WIFI_AGENT_TDK_TEST
 static void wifi_upload_reset()
 {
@@ -3550,8 +3546,8 @@
 		CallOnce = 0;
 		mld_info_display();
 		wifi_guard_interval_file_check();
-		wifi_power_percentage_file_check();
 		wifi_mcs_file_check();
+		wifi_mgmt_pwr_file_check();
 #ifdef WIFI_AGENT_TDK_TEST
 		/* for wifiagent TDK test */
 		wifi_upload_reset();
@@ -7789,35 +7785,21 @@
 //The transmite power level is in units of full power for this radio.
 INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong)	//RDKB
 {
-	char interface_name[16] = {0};
-	char buf[16]={0};
-	char pwr_file[128]={0};
+	char config_dat_file[MAX_BUF_SIZE] = {0};
+	char buf[64]={'\0'};
 	int res;
-	int main_vap_idx;
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
 	if(output_ulong == NULL)
 		return RETURN_ERR;
 
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radio_index_to_band(radioIndex));
-	if (os_snprintf_error(sizeof(pwr_file), res)) {
+	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_index_to_band(radioIndex));
+	if (os_snprintf_error(sizeof(config_dat_file), res)) {
 		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		return RETURN_ERR;
 	}
-
-	res = _syscmd_secure(buf, sizeof(buf),"cat %s 2> /dev/null", pwr_file);
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
+	wifi_datfileRead(config_dat_file, "TxPower", buf, sizeof(buf));
 	if (strlen(buf) > 0) {
 		if (hal_strtoul(buf, 10, output_ulong) < 0) {
 			wifi_debug(DEBUG_ERROR, "strtol fail\n");
@@ -7836,8 +7818,6 @@
 	char *support;
 	char buf[128]={0};
 	char txpower_str[64] = {0};
-	char pwr_file[128]={0};
-	FILE *f = NULL;
 	int if_idx, ret = 0;
 	struct nl_msg *msg  = NULL;
 	struct nlattr * msg_data = NULL;
@@ -7845,6 +7825,8 @@
 	struct unl unl_ins;
 	int res;
 	int main_vap_idx;
+	char config_dat_file[MAX_BUF_SIZE] = {0};
+	struct params dat={0};
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
@@ -7908,20 +7890,14 @@
 	mtk_nl80211_deint(&unl_ins);
 	wifi_debug(DEBUG_INFO, "set cmd success.\n");
 
-	res = snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radio_index_to_band(radioIndex));
-	if (os_snprintf_error(sizeof(pwr_file), res)) {
+	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_index_to_band(radioIndex));
+	if (os_snprintf_error(sizeof(config_dat_file), res)) {
 		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		return RETURN_ERR;
 	}
-
-	f = fopen(pwr_file, "w");
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR, "%s: fopen failed\n", __func__);
-		return RETURN_ERR;
-	}
-	fprintf(f, "%lu", TransmitPower);
-	if (fclose(f) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
+	dat.name = "TxPower";
+	dat.value = txpower_str;
+	wifi_datfileWrite(config_dat_file, &dat, 1);
 	return RETURN_OK;
 err:
 	mtk_nl80211_deint(&unl_ins);
@@ -17526,7 +17502,76 @@
     wifi_debug(DEBUG_ERROR,"send cmd fails\n");
     return RETURN_ERR;
 }
+int get_mgmt_real_pwr_handler(struct nl_msg *msg, void *data)
+{
+	struct nlattr *tb[NL80211_ATTR_MAX + 1];
+	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_TXPWR_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	unsigned char *mgmt_pwr = (unsigned char *)data;
+	int err = 0;
+
+	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+			  genlmsg_attrlen(gnlh, 0), NULL);
+	if (err < 0)
+		return err;
+
+	if (tb[NL80211_ATTR_VENDOR_DATA]) {
+		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_TXPWR_ATTR_MAX,
+			tb[NL80211_ATTR_VENDOR_DATA], NULL);
+		if (err < 0)
+			return err;
+
+		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_TXPWR_GET_MGMT]) {
+			*mgmt_pwr = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_TXPWR_GET_MGMT]);
+		}
+	}
+	wifi_debug(DEBUG_INFO, "get_mgmt_real_pwr_handler--\n");
+
+	return 0;
+}
 
+INT mtk_wifi_get_mgmt_real_pwr(
+	int if_idx, INT vendor_data_attr, mtk_nl80211_cb call_back, void *output)
+{
+	int ret = -1;
+	struct unl unl_ins;
+	struct nl_msg *msg	= NULL;
+	struct nlattr * msg_data = NULL;
+	struct mtk_nl80211_param param;
+
+	/*init mtk nl80211 vendor cmd*/
+	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
+	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_u8(msg, vendor_data_attr, 1)) {
+		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
+		nlmsg_free(msg);
+		goto err;
+	}
+
+	/*send mtk nl80211 vendor msg*/
+	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, 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.\n");
+
+	return RETURN_OK;
+err:
+	mtk_nl80211_deint(&unl_ins);
+	wifi_debug(DEBUG_ERROR,"send cmd fails,%d\n", ret);
+	return RETURN_ERR;
+}
 INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
 {
 	char mgmtpwr_file[32] = {0};
@@ -17553,7 +17598,7 @@
 		}
 		*output_dBm = tmp;
 	} else
- 		*output_dBm = 23;
+ 		*output_dBm = 0;/*Agent range:-20 ~ 0*/
 	return RETURN_OK;
 }
 
@@ -17569,6 +17614,7 @@
 	struct unl unl_ins;
 	char power[16] = {0};
 	int res;
+	unsigned char mgmt_real_pwr = 0;
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
@@ -17586,9 +17632,19 @@
 		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
 		return RETURN_ERR;
 	}
-
+	if (dBm > 0)
+		dBm = 0;
+	if (dBm < -20)
+		dBm = -20;
+	/*Generally, management tx power is 23dBm, the input dBm is not a target power, it's range is -20 ~ 0,
+	it may be delta power.*/
+	mtk_wifi_get_mgmt_real_pwr(if_idx, MTK_NL80211_VENDOR_ATTR_TXPWR_GET_MGMT, get_mgmt_real_pwr_handler, &mgmt_real_pwr);
+	wifi_debug(DEBUG_INFO, "mgmt_real_pwr = %d\n", mgmt_real_pwr);
 	/*add mtk vendor cmd data*/
-	res = snprintf(power, sizeof(power), "%d", dBm);
+	if (mgmt_real_pwr != 0)
+		res = snprintf(power, sizeof(power), "%d", (mgmt_real_pwr + dBm));
+	else
+		res = snprintf(power, sizeof(power), "%d", (23 + dBm));
 	if (os_snprintf_error(sizeof(power), res)) {
 		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		return RETURN_ERR;
@@ -19620,6 +19676,11 @@
 	char dat_file[64] = {'\0'};
 	struct params params[3];
 	int res;
+	char *str_zro = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 16bss per band.*/
+	char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
+	UCHAR bss_cnt = 0;
+	UCHAR val_cnt = 0;
+	char valbuf[64] = {0};
 
 	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
 
@@ -19679,18 +19740,29 @@
 		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
 		return RETURN_ERR;
 	}
+	get_bssnum_byindex(radio_index, &bss_cnt);
+	if (bss_cnt <= 0)
+	{
+		wifi_debug(DEBUG_ERROR, "Unexpected bss_cnt\n");
+		return RETURN_ERR;
+	}
+	if (bss_cnt > LOGAN_MAX_NUM_VAP_PER_RADIO)
+		bss_cnt = LOGAN_MAX_NUM_VAP_PER_RADIO;
+	val_cnt = 2*bss_cnt - 1;
 	if (guard_interval == wifi_guard_interval_400) {
+		strncpy(valbuf, str_one, val_cnt);
 		params[0].name = "HT_GI";
-		params[0].value = "1";
+		params[0].value = valbuf;
 		params[1].name = "VHT_SGI";
-		params[1].value = "1";
+		params[1].value = valbuf;
 		wifi_datfileWrite(dat_file, params, 2);
 		memcpy(GI, "0.4", 3);
 	} else {
+		strncpy(valbuf, str_zro, val_cnt);
 		params[0].name = "HT_GI";
-		params[0].value = "0";
+		params[0].value = valbuf;
 		params[1].name = "VHT_SGI";
-		params[1].value = "0";
+		params[1].value = valbuf;
 		/*should enable FIXED_HE_GI_SUPPORT in driver*/
 		params[2].name = "FgiFltf";
 		if (guard_interval == wifi_guard_interval_800) {
@@ -22710,6 +22782,10 @@
 		if (ret != RETURN_OK) {
 			wifi_debug(DEBUG_ERROR, "wifi_setApIsolationEnable return error\n");
 		}
+		ret = wifi_setApManagementFramePowerControl(vap_info->vap_index, vap_info->u.bss_info.mgmtPowerControl);
+		if (ret != RETURN_OK) {
+			wifi_debug(DEBUG_ERROR, "wifi_setApManagementFramePowerControl return error\n");
+		}
 		// TODO mgmtPowerControl, interworking, wps
 	}
 
diff --git a/src/wifi/wifi_hal.c b/src/wifi/wifi_hal.c
index 62b986f..a965254 100644
--- a/src/wifi/wifi_hal.c
+++ b/src/wifi/wifi_hal.c
@@ -6258,7 +6258,11 @@
         if (!(apIndex/max_radio_num)) {
 	        sprintf(cmd, "iw %s del", interface_name);
 	        _syscmd(cmd, buf, sizeof(buf));
+#ifdef SINGLE_WIPHY_SUPPORT
+	        sprintf(cmd, "iw phy phy0 interface add %s type __ap", interface_name);
+#else
 	        sprintf(cmd, "iw phy phy%d interface add %s type __ap", phyId, interface_name);
+#endif
 	        _syscmd(cmd, buf, sizeof(buf));
         }
         sprintf(cmd, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);