mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 10:51:27 +00:00
261 lines
7.9 KiB
Diff
261 lines
7.9 KiB
Diff
From 19cb10a62d2cd4507cbe28bf36a1522fd8d5870a Mon Sep 17 00:00:00 2001
|
|
From: Karthik M <quic_karm@quicinc.com>
|
|
Date: Fri, 24 Jun 2022 10:28:31 +0530
|
|
Subject: [PATCH] hostapd: Add ACS and DFS support for 5GHz BW240MHZ
|
|
|
|
ACS dynamically punctures the channels based on the
|
|
noise levels. Incase of 5G 240MHZ bandwidth, we need
|
|
to use static punturing bitmap.
|
|
|
|
In case of radar, We have only one channel in 240MHz.
|
|
The bandwidth should downgrade to 160MHz
|
|
and choose a channel.
|
|
|
|
Signed-off-by: Karthik M <quic_karm@quicinc.com>
|
|
---
|
|
src/ap/acs.c | 19 +++++++++++++++----
|
|
src/ap/dfs.c | 34 ++++++++++++++++++++++++++++++----
|
|
2 files changed, 45 insertions(+), 8 deletions(-)
|
|
|
|
Index: b/src/ap/acs.c
|
|
===================================================================
|
|
--- a/src/ap/acs.c 2022-09-19 10:33:57.084303028 +0530
|
|
+++ b/src/ap/acs.c 2022-09-19 10:33:57.076303097 +0530
|
|
@@ -420,7 +420,7 @@ static int acs_usable_bw160_chan(const s
|
|
static int acs_usable_bw320_chan(const struct hostapd_channel_data *chan)
|
|
{
|
|
/* Allow start of overlapping 320MHz channels */
|
|
- const int allowed[] = { 5955, 6115, 6275, 6435, 6595, 6755 };
|
|
+ const int allowed[] = { 5500, 5955, 6115, 6275, 6435, 6595, 6755 };
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < ARRAY_SIZE(allowed); i++)
|
|
@@ -657,6 +657,8 @@ static int is_common_24ghz_chan(int chan
|
|
#define ACS_24GHZ_PREFER_1_6_11 0.8
|
|
#endif /* ACS_24GHZ_PREFER_1_6_11 */
|
|
|
|
+#define PUNCTURING_PATTERN_5G_320MHZ 0XF000
|
|
+
|
|
static void acs_update_puncturing_bitmap(struct hostapd_iface *iface,
|
|
struct hostapd_hw_modes *mode, u32 bw,
|
|
int n_chans,
|
|
@@ -669,14 +671,32 @@ static void acs_update_puncturing_bitmap
|
|
struct hostapd_config *conf = iface->conf;
|
|
long double threshold = factor * conf->ru_punct_acs_threshold / 100;
|
|
|
|
+ if (is_24ghz_mode(mode->mode) || (bw < 80))
|
|
+ return;
|
|
+
|
|
+ /*
|
|
+ * 5GHz 320Mhz operates with static punturing bitmap. Overiding the dynammic
|
|
+ * bitmap calculation
|
|
+ */
|
|
+
|
|
+ if (!is_6ghz_op_class(iface->conf->op_class) && bw == 320) {
|
|
+ if ((conf->ru_punct_bitmap & PUNCTURING_PATTERN_5G_320MHZ) ==
|
|
+ PUNCTURING_PATTERN_5G_320MHZ) {
|
|
+ chan->ru_punct_bitmap = conf->ru_punct_bitmap;
|
|
+ goto bitmap_selected;
|
|
+ } else {
|
|
+ wpa_printf(MSG_DEBUG, "ACS : Invalid ru_punct_bitmap for 5G %X",
|
|
+ conf->ru_punct_bitmap);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
/*
|
|
* If threshold is 0 or user configured puncturing pattern is
|
|
* available then don't add additional puncturing.
|
|
*/
|
|
- if (!conf->ru_punct_acs_threshold || conf->ru_punct_bitmap)
|
|
- return;
|
|
|
|
- if (is_24ghz_mode(mode->mode) || (bw < 80))
|
|
+ if (!conf->ru_punct_acs_threshold || conf->ru_punct_bitmap)
|
|
return;
|
|
|
|
for (i = 0; i < n_chans; i++) {
|
|
@@ -701,6 +721,11 @@ static void acs_update_puncturing_bitmap
|
|
chan->ru_punct_bitmap |= BIT(i);
|
|
}
|
|
|
|
+bitmap_selected:
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "ACS: Calculated ru_punct_bitmap is %X and ru_punct_ofdma is %X",
|
|
+ chan->ru_punct_bitmap,conf->ru_punct_ofdma);
|
|
+
|
|
if (!is_ru_punct_bitmap_valid(bw,
|
|
(chan->freq - first_chan->freq) / 20,
|
|
chan->ru_punct_bitmap,
|
|
@@ -919,6 +944,11 @@ acs_find_ideal_chan_mode(struct hostapd_
|
|
factor = chan->interference_factor;
|
|
total_weight = 1;
|
|
|
|
+ /* 5GHz is supported for 240Mhz and so reducing number of channels*/
|
|
+ if(!is_6ghz_op_class(iface->conf->op_class) &&
|
|
+ hostapd_get_oper_chwidth(iface->conf) == CHANWIDTH_320MHZ)
|
|
+ n_chans = n_chans - 4;
|
|
+
|
|
for (j = 1; j < n_chans; j++) {
|
|
adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
|
|
if (!adj_chan)
|
|
@@ -1018,7 +1048,7 @@ acs_find_ideal_chan_mode(struct hostapd_
|
|
*ideal_factor = factor;
|
|
*ideal_chan = chan;
|
|
|
|
- if (iface->conf->ieee80211ax)
|
|
+ if (iface->conf->ieee80211ax || iface->conf->ieee80211be)
|
|
acs_update_puncturing_bitmap(iface, mode, bw,
|
|
n_chans, chan,
|
|
factor, 0);
|
|
@@ -1075,7 +1105,9 @@ acs_find_ideal_chan(struct hostapd_iface
|
|
case CHANWIDTH_160MHZ:
|
|
n_chans = 8;
|
|
break;
|
|
- /* 320 is supported only in 6GHz 11be mode */
|
|
+ case CHANWIDTH_320MHZ:
|
|
+ n_chans = 16;
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
Index: b/src/ap/dfs.c
|
|
===================================================================
|
|
--- a/src/ap/dfs.c 2022-09-19 10:33:57.084303028 +0530
|
|
+++ b/src/ap/dfs.c 2022-09-19 10:42:06.192255486 +0530
|
|
@@ -20,7 +20,6 @@
|
|
#include "beacon.h"
|
|
#include "eloop.h"
|
|
|
|
-
|
|
static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
|
|
{
|
|
int n_chans = 1;
|
|
@@ -30,7 +29,8 @@ static int dfs_get_used_n_chans(struct h
|
|
if (iface->conf->ieee80211n && iface->conf->secondary_channel)
|
|
n_chans = 2;
|
|
|
|
- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
|
|
+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
|
|
+ iface->conf->ieee80211be) {
|
|
switch (hostapd_get_oper_chwidth(iface->conf)) {
|
|
case CHANWIDTH_USE_HT:
|
|
break;
|
|
@@ -44,6 +44,9 @@ static int dfs_get_used_n_chans(struct h
|
|
n_chans = 4;
|
|
*seg1 = 4;
|
|
break;
|
|
+ case CHANWIDTH_320MHZ:
|
|
+ n_chans = 12;
|
|
+ break;
|
|
default:
|
|
break;
|
|
}
|
|
@@ -94,6 +97,12 @@ static int dfs_is_chan_allowed(struct ho
|
|
* 50, 114, 163
|
|
*/
|
|
int allowed_160[] = { 36, 100, 149 };
|
|
+ /*
|
|
+ * EHT320 valid channels based on center frequency:
|
|
+ * 100
|
|
+ */
|
|
+ int allowed_320[] = {100};
|
|
+
|
|
int *allowed = allowed_40;
|
|
unsigned int i, allowed_no = 0;
|
|
|
|
@@ -110,6 +119,10 @@ static int dfs_is_chan_allowed(struct ho
|
|
allowed = allowed_160;
|
|
allowed_no = ARRAY_SIZE(allowed_160);
|
|
break;
|
|
+ case 16:
|
|
+ allowed = allowed_320;
|
|
+ allowed_no = ARRAY_SIZE(allowed_320);
|
|
+ break;
|
|
default:
|
|
wpa_printf(MSG_DEBUG, "Unknown width for %d channels", n_chans);
|
|
break;
|
|
@@ -337,7 +350,8 @@ static void dfs_adjust_center_freq(struc
|
|
u8 *oper_centr_freq_seg0_idx,
|
|
u8 *oper_centr_freq_seg1_idx)
|
|
{
|
|
- if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax)
|
|
+ if (!iface->conf->ieee80211ac && !iface->conf->ieee80211ax &&
|
|
+ !iface->conf->ieee80211be)
|
|
return;
|
|
|
|
if (!chan)
|
|
@@ -364,6 +378,9 @@ static void dfs_adjust_center_freq(struc
|
|
*oper_centr_freq_seg0_idx = chan->chan + 6;
|
|
*oper_centr_freq_seg1_idx = sec_chan_idx_80p80 + 6;
|
|
break;
|
|
+ case CHANWIDTH_320MHZ:
|
|
+ *oper_centr_freq_seg0_idx = chan->chan + 30;
|
|
+ break;
|
|
|
|
default:
|
|
wpa_printf(MSG_INFO,
|
|
@@ -711,7 +728,7 @@ static int set_dfs_state(struct hostapd_
|
|
frequency = cf1 - 70;
|
|
break;
|
|
case CHAN_WIDTH_320:
|
|
- n_chans = 16;
|
|
+ n_chans = 12;
|
|
frequency = cf1 - 150;
|
|
break;
|
|
default:
|
|
@@ -775,6 +792,10 @@ static int dfs_are_channels_overlapped(s
|
|
radar_n_chans = 8;
|
|
frequency = cf1 - 70;
|
|
break;
|
|
+ case CHAN_WIDTH_320:
|
|
+ radar_n_chans = 12;
|
|
+ frequency = cf1 - 150;
|
|
+ break;
|
|
default:
|
|
wpa_printf(MSG_INFO, "DFS chan_width %d not supported",
|
|
chan_width);
|
|
@@ -1021,6 +1042,7 @@ dfs_downgrade_bandwidth(struct hostapd_i
|
|
u8 *oper_centr_freq_seg1_idx, int *skip_radar)
|
|
{
|
|
struct hostapd_channel_data *channel;
|
|
+ int oper_chwidth;
|
|
|
|
for (;;) {
|
|
channel = dfs_get_valid_channel(iface, secondary_channel,
|
|
@@ -1036,7 +1058,6 @@ dfs_downgrade_bandwidth(struct hostapd_i
|
|
if (*skip_radar) {
|
|
*skip_radar = 0;
|
|
} else {
|
|
- int oper_chwidth;
|
|
|
|
oper_chwidth = hostapd_get_oper_chwidth(iface->conf);
|
|
if (oper_chwidth == CHANWIDTH_USE_HT) {
|
|
@@ -1047,9 +1068,13 @@ dfs_downgrade_bandwidth(struct hostapd_i
|
|
iface->conf->secondary_channel = 0;
|
|
*skip_radar = 1;
|
|
continue;
|
|
+ } else if (oper_chwidth == CHANWIDTH_320MHZ) {
|
|
+ oper_chwidth = oper_chwidth - 7;
|
|
+ } else {
|
|
+ oper_chwidth = oper_chwidth - 1;
|
|
}
|
|
*skip_radar = 1;
|
|
- hostapd_set_oper_chwidth(iface->conf, oper_chwidth - 1);
|
|
+ hostapd_set_oper_chwidth(iface->conf, oper_chwidth);
|
|
}
|
|
}
|
|
|
|
Index: b/src/common/hw_features_common.c
|
|
===================================================================
|
|
--- a/src/common/hw_features_common.c 2022-09-19 10:33:57.084303028 +0530
|
|
+++ b/src/common/hw_features_common.c 2022-09-19 10:33:57.080303063 +0530
|
|
@@ -794,6 +794,7 @@ u32 num_chan_to_bw(int num_chans)
|
|
case 2:
|
|
case 4:
|
|
case 8:
|
|
+ case 16:
|
|
return num_chans * 20;
|
|
default:
|
|
return 20;
|