[][MAC80211][hostapd][Add DFS detect mode command in hostapd]

[Description]
Add the DFS detect mode command in hostapd, which disables channel switch
(including AP and background chain) when receiving radar detection.

[Release-log]
N/A

Change-Id: I4b580f0f10a51e8bce6edd4e39c06e31a745437a
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/6590830
Build: srv_hbgsm110
diff --git a/autobuild_mac80211_release/package/network/services/hostapd/patches/99917-master-Add-DFS-disable-channel-switch-when-receive-radar.patch b/autobuild_mac80211_release/package/network/services/hostapd/patches/99917-master-Add-DFS-disable-channel-switch-when-receive-radar.patch
new file mode 100644
index 0000000..6ad519f
--- /dev/null
+++ b/autobuild_mac80211_release/package/network/services/hostapd/patches/99917-master-Add-DFS-disable-channel-switch-when-receive-radar.patch
@@ -0,0 +1,130 @@
+From a9c16aec415de2f4550c0bf25eb690e9025c5dbf Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 22 Sep 2022 19:12:18 +0800
+Subject: [PATCH] Add DFS disable channel switch when receive radar
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ hostapd/config_file.c |  4 ++++
+ hostapd/ctrl_iface.c  | 22 ++++++++++++++++++++++
+ src/ap/ap_config.h    | 13 +++++++++++++
+ src/ap/dfs.c          | 10 ++++++++++
+ 4 files changed, 49 insertions(+)
+
+diff --git a/hostapd/config_file.c b/hostapd/config_file.c
+index 9b79be1..5fa0e37 100644
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -4789,6 +4789,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
+ 	} else if (os_strcmp(buf, "ibf_enable") == 0) { /*ibf setting is per device*/
+ 		int val = atoi(pos);
+ 		conf->ibf_enable = !!val;
++	} else if (os_strcmp(buf, "dfs_detect_mode") == 0) { /*bypass channel switch*/
++		u8 en = strtol(pos, NULL, 10);
++
++		conf->dfs_detect_mode = en;
+ 	} else {
+ 		wpa_printf(MSG_ERROR,
+ 			   "Line %d: unknown configuration item '%s'",
+diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
+index a010e7f..6ed8965 100644
+--- a/hostapd/ctrl_iface.c
++++ b/hostapd/ctrl_iface.c
+@@ -3494,6 +3494,25 @@ hostapd_ctrl_iface_get_ibf(struct hostapd_data *hapd, char *buf,
+ 	return ret;
+ }
+ 
++static int
++hostapd_ctrl_iface_set_dfs_detect_mode(struct hostapd_data *hapd, char *value,
++				       char *buf, size_t buflen)
++{
++	u8 dfs_detect_mode;
++
++	if (!value)
++		return -1;
++
++	dfs_detect_mode = strtol(value, NULL, 10);
++	if (dfs_detect_mode > DFS_DETECT_MODE_MAX) {
++		wpa_printf(MSG_ERROR, "Invalid value for dfs detect mode");
++		return -1;
++	}
++	hapd->iconf->dfs_detect_mode = dfs_detect_mode;
++
++	return 0;
++}
++
+ 
+ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 					      char *buf, char *reply,
+@@ -4055,6 +4074,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
+ 		reply_len = hostapd_ctrl_iface_get_hemu(hapd, reply, reply_size);
+ 	} else if (os_strncmp(buf, "GET_IBF", 7) == 0) {
+ 		reply_len = hostapd_ctrl_iface_get_ibf(hapd, reply, reply_size);
++	} else if (os_strncmp(buf, "DFS_DETECT_MODE ", 16) == 0) {
++		reply_len = hostapd_ctrl_iface_set_dfs_detect_mode(hapd, buf + 16,
++								   reply, reply_size);
+ 	} else {
+ 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ 		reply_len = 16;
+diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
+index 2a74e09..97f5e33 100644
+--- a/src/ap/ap_config.h
++++ b/src/ap/ap_config.h
+@@ -1158,6 +1158,7 @@ struct hostapd_config {
+ 	s8 edcca_compensation;
+ 	u8 three_wire_enable;
+ 	u8 ibf_enable;
++	u8 dfs_detect_mode;
+ };
+ 
+ enum three_wire_mode {
+@@ -1172,6 +1173,18 @@ enum three_wire_mode {
+ 		NUM_THREE_WIRE_MODE - 1
+ };
+ 
++enum dfs_mode {
++	DFS_DETECT_MODE_DISABLE,
++	DFS_DETECT_MODE_AP_ENABLE,
++	DFS_DETECT_MODE_BACKGROUND_ENABLE,
++	DFS_DETECT_MODE_ALL_ENABLE,
++
++	/* keep last */
++	NUM_DFS_DETECT_MODE,
++	DFS_DETECT_MODE_MAX =
++		NUM_DFS_DETECT_MODE - 1
++};
++
+ enum edcca_mode {
+ 	EDCCA_MODE_FORCE_DISABLE = 0,
+ 	EDCCA_MODE_AUTO = 1,
+diff --git a/src/ap/dfs.c b/src/ap/dfs.c
+index b5d105d..5cb7799 100644
+--- a/src/ap/dfs.c
++++ b/src/ap/dfs.c
+@@ -1317,6 +1317,11 @@ hostapd_dfs_background_start_channel_switch(struct hostapd_iface *iface,
+ 		   __func__, iface->radar_background.cac_started ? "yes" : "no",
+ 		   hostapd_csa_in_progress(iface) ? "yes" : "no");
+ 
++	/* Skip channel switch when background dfs detect mode is on */
++	if (iface->conf->dfs_detect_mode == DFS_DETECT_MODE_BACKGROUND_ENABLE ||
++	    iface->conf->dfs_detect_mode == DFS_DETECT_MODE_ALL_ENABLE)
++		return 0;
++
+ 	/* Check if CSA in progress */
+ 	if (hostapd_csa_in_progress(iface))
+ 		return 0;
+@@ -1365,6 +1370,11 @@ static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
+ 		   __func__, iface->cac_started ? "yes" : "no",
+ 		   hostapd_csa_in_progress(iface) ? "yes" : "no");
+ 
++	/* Skip channel switch when dfs detect mode is on */
++	if (iface->conf->dfs_detect_mode == DFS_DETECT_MODE_AP_ENABLE ||
++	    iface->conf->dfs_detect_mode == DFS_DETECT_MODE_ALL_ENABLE)
++		return 0;
++
+ 	/* Check if CSA in progress */
+ 	if (hostapd_csa_in_progress(iface))
+ 		return 0;
+-- 
+2.18.0
+