mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
197 lines
6.1 KiB
Diff
197 lines
6.1 KiB
Diff
From d873d195bcb481b7b82be195cb17e3fc7f7ecf58 Mon Sep 17 00:00:00 2001
|
|
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
|
|
Date: Wed, 11 Dec 2024 13:21:21 +0800
|
|
Subject: [PATCH] mac80211: mtk: add dfs relax flag for scanning without dfs
|
|
restrictions
|
|
|
|
Add dfs relax flag for scanning without dfs restrictions.
|
|
If user turn on the dfs relax flag by entering the following command:
|
|
echo 1 > /sys/kernel/debug/ieee80211/phyX/scan_dfs_relax
|
|
Then, allow AP/STA to scan while operating on a DFS channel.
|
|
|
|
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
|
|
---
|
|
include/net/cfg80211.h | 4 +++
|
|
net/mac80211/offchannel.c | 4 +--
|
|
net/mac80211/scan.c | 3 ++-
|
|
net/wireless/debugfs.c | 53 +++++++++++++++++++++++++++++++++++++++
|
|
net/wireless/nl80211.c | 14 ++++++++---
|
|
5 files changed, 71 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
|
|
index 67b0e6c..f159340 100644
|
|
--- a/include/net/cfg80211.h
|
|
+++ b/include/net/cfg80211.h
|
|
@@ -5047,6 +5047,8 @@ struct wiphy_iftype_akm_suites {
|
|
* @mbssid_max_ema_profile_periodicity: maximum profile periodicity supported by
|
|
* the driver. Setting this field to a non-zero value indicates that the
|
|
* driver supports enhanced multi-BSSID advertisements (EMA AP).
|
|
+ *
|
|
+ * @dfs_relax: a flag to relax the DFS restrictions during scanning
|
|
*/
|
|
struct wiphy {
|
|
struct mutex mtx;
|
|
@@ -5197,6 +5199,8 @@ struct wiphy {
|
|
u8 mbssid_max_interfaces;
|
|
u8 ema_max_profile_periodicity;
|
|
|
|
+ bool dfs_relax;
|
|
+
|
|
char priv[] __aligned(NETDEV_ALIGN);
|
|
};
|
|
|
|
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
|
|
index 042b6fb..2cd8454 100644
|
|
--- a/net/mac80211/offchannel.c
|
|
+++ b/net/mac80211/offchannel.c
|
|
@@ -579,8 +579,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|
}
|
|
|
|
/* if there's no need to queue, handle it immediately */
|
|
- if (list_empty(&local->roc_list) &&
|
|
- !local->scanning && !ieee80211_is_radar_required(local)) {
|
|
+ if (list_empty(&local->roc_list) && !local->scanning &&
|
|
+ (local->hw.wiphy->dfs_relax || !ieee80211_is_radar_required(local))) {
|
|
/* if not HW assist, just queue & schedule work */
|
|
if (!local->ops->remain_on_channel) {
|
|
list_add_tail(&roc->list, &local->roc_list);
|
|
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
|
|
index 9d53f1a..9ef5179 100644
|
|
--- a/net/mac80211/scan.c
|
|
+++ b/net/mac80211/scan.c
|
|
@@ -572,7 +572,8 @@ static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata)
|
|
if (!ieee80211_is_radar_required(local))
|
|
return true;
|
|
|
|
- if (!regulatory_pre_cac_allowed(local->hw.wiphy))
|
|
+ if (!local->hw.wiphy->dfs_relax &&
|
|
+ !regulatory_pre_cac_allowed(local->hw.wiphy))
|
|
return false;
|
|
|
|
mutex_lock(&local->iflist_mtx);
|
|
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
|
|
index 0637ed4..9fecbef 100644
|
|
--- a/net/wireless/debugfs.c
|
|
+++ b/net/wireless/debugfs.c
|
|
@@ -388,6 +388,58 @@ dfs_available_reset(void *data, u64 val)
|
|
DEFINE_DEBUGFS_ATTRIBUTE(dfs_available_reset_ops, NULL,
|
|
dfs_available_reset, "0x%08llx\n");
|
|
|
|
+
|
|
+static ssize_t scan_dfs_relax_write(struct file *file,
|
|
+ const char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct wiphy *wiphy = file->private_data;
|
|
+ char buf[16];
|
|
+
|
|
+ if (count >= sizeof(buf))
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (copy_from_user(buf, user_buf, count))
|
|
+ return -EFAULT;
|
|
+
|
|
+ if (count && buf[count - 1] == '\n')
|
|
+ buf[count - 1] = '\0';
|
|
+ else
|
|
+ buf[count] = '\0';
|
|
+
|
|
+ if (kstrtobool(buf, &wiphy->dfs_relax))
|
|
+ return -EINVAL;
|
|
+
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static ssize_t scan_dfs_relax_read(struct file *file, char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct wiphy *wiphy = file->private_data;
|
|
+ unsigned int r, offset, buf_size = PAGE_SIZE;
|
|
+ char *buf;
|
|
+
|
|
+ buf = kzalloc(buf_size, GFP_KERNEL);
|
|
+ if (!buf)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ offset = scnprintf(buf, buf_size, "dfs relax: %u\n", wiphy->dfs_relax);
|
|
+
|
|
+ r = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
|
|
+
|
|
+ kfree(buf);
|
|
+
|
|
+ return r;
|
|
+}
|
|
+
|
|
+static const struct file_operations scan_dfs_relax_ops = {
|
|
+ .write = scan_dfs_relax_write,
|
|
+ .read = scan_dfs_relax_read,
|
|
+ .open = simple_open,
|
|
+ .llseek = default_llseek,
|
|
+};
|
|
+
|
|
#define DEBUGFS_ADD(name, chmod) \
|
|
debugfs_create_file(#name, chmod, phyd, &rdev->wiphy, &name## _ops)
|
|
|
|
@@ -404,4 +456,5 @@ void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev)
|
|
DEBUGFS_ADD(dfs_skip_nop, 0600);
|
|
DEBUGFS_ADD(dfs_skip_cac, 0600);
|
|
DEBUGFS_ADD(dfs_available_reset, 0600);
|
|
+ DEBUGFS_ADD(scan_dfs_relax, 0644);
|
|
}
|
|
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
|
|
index 4883b1f..3d22429 100644
|
|
--- a/net/wireless/nl80211.c
|
|
+++ b/net/wireless/nl80211.c
|
|
@@ -8400,13 +8400,16 @@ int nl80211_parse_random_mac(struct nlattr **attrs,
|
|
return 0;
|
|
}
|
|
|
|
-static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
|
|
+static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev, bool dfs_relax)
|
|
{
|
|
ASSERT_WDEV_LOCK(wdev);
|
|
|
|
if (!cfg80211_beaconing_iface_active(wdev))
|
|
return true;
|
|
|
|
+ if (dfs_relax)
|
|
+ return true;
|
|
+
|
|
if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
|
|
return true;
|
|
|
|
@@ -8627,7 +8630,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|
request->n_channels = i;
|
|
|
|
wdev_lock(wdev);
|
|
- if (!cfg80211_off_channel_oper_allowed(wdev)) {
|
|
+ if (!cfg80211_off_channel_oper_allowed(wdev, wiphy->dfs_relax)) {
|
|
struct ieee80211_channel *chan;
|
|
|
|
if (request->n_channels != 1) {
|
|
@@ -11549,8 +11552,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
|
|
if (err)
|
|
return err;
|
|
|
|
+ if (wdev->cac_started)
|
|
+ return -EBUSY;
|
|
+
|
|
wdev_lock(wdev);
|
|
- if (!cfg80211_off_channel_oper_allowed(wdev) &&
|
|
+ if (!cfg80211_off_channel_oper_allowed(wdev, rdev->wiphy.dfs_relax) &&
|
|
!cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
|
|
compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
|
|
&chandef);
|
|
@@ -11755,7 +11761,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
|
|
return -EINVAL;
|
|
|
|
wdev_lock(wdev);
|
|
- if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
|
|
+ if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev, false)) {
|
|
wdev_unlock(wdev);
|
|
return -EBUSY;
|
|
}
|
|
--
|
|
2.45.2
|
|
|