From efca885412b8f3de4f375513d1e3315482377295 Mon Sep 17 00:00:00 2001 From: Nagarajan Maran Date: Mon, 7 Nov 2022 10:12:30 +0530 Subject: [PATCH] hostapd: Radar bitmap support during radar detection Currently when radar is detected the whole configured frequency is moved to unavailable state. These changes adds support to parse a new NL attribute "NL80211_ATTR_RADAR_BITMAP" which gets the radar bitmap.This radar bitmap indicates the sub-channels where radar is detected. In the radar bitmap, the lowest bit denotes the lowest 20MHz based on the center frequency configured. With this radar bitmap, the affected sub-channels alone will be moved to unavailable state. Signed-off-by: Nagarajan Maran --- src/ap/dfs.c | 37 +++++++++++++------ src/ap/dfs.h | 2 +- src/ap/drv_callbacks.c | 2 +- src/drivers/driver.h | 1 + src/drivers/driver_nl80211_event.c | 14 ++++--- src/drivers/nl80211_copy.h | 6 +++ wpa_supplicant/ap.c | 3 +- 8 files changed, 46 insertions(+), 21 deletions(-) --- a/src/ap/dfs.c +++ b/src/ap/dfs.c @@ -764,7 +764,7 @@ static int set_dfs_state_freq(struct hos static int set_dfs_state(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, - int cf2, u32 state) + int cf2, u32 state, u16 radar_bitmap) { int n_chans = 1, i; struct hostapd_hw_modes *mode; @@ -819,12 +819,25 @@ static int set_dfs_state(struct hostapd_ wpa_printf(MSG_DEBUG, "DFS freq: %dMHz, n_chans: %d", frequency, n_chans); for (i = 0; i < n_chans; i++) { - ret += set_dfs_state_freq(iface, frequency, state); - frequency = frequency + 20; - if (chan_width == CHAN_WIDTH_80P80) { - ret += set_dfs_state_freq(iface, frequency2, state); - frequency2 = frequency2 + 20; + if (radar_bitmap && state == HOSTAPD_CHAN_DFS_UNAVAILABLE) + { + if (radar_bitmap & 1<bss[0]->msg_ctx, MSG_INFO, DFS_EVENT_RADAR_DETECTED "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", @@ -1651,13 +1664,13 @@ int hostapd_dfs_radar_detected(struct ho /* mark radar frequency as invalid */ if (!set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width, - cf1, cf2, HOSTAPD_CHAN_DFS_UNAVAILABLE)) + cf1, cf2, HOSTAPD_CHAN_DFS_UNAVAILABLE, radar_bitmap)) return 0; if (iface->conf->dfs_test_mode) { set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width, cf1, cf2, - HOSTAPD_CHAN_DFS_AVAILABLE); + HOSTAPD_CHAN_DFS_AVAILABLE, radar_bitmap); } if (!hostapd_dfs_is_background_event(iface, freq)) { @@ -1697,7 +1710,7 @@ int hostapd_dfs_nop_finished(struct host /* TODO add correct implementation here */ set_dfs_state(iface, freq, ht_enabled, chan_offset, chan_width, - cf1, cf2, HOSTAPD_CHAN_DFS_USABLE); + cf1, cf2, HOSTAPD_CHAN_DFS_USABLE,0); if (iface->state == HAPD_IFACE_DFS && !iface->cac_started) { /* Handle cases where all channels were initially unavailable */ --- a/src/ap/dfs.h +++ b/src/ap/dfs.h @@ -27,7 +27,7 @@ int hostapd_dfs_pre_cac_expired(struct h int hostapd_dfs_radar_detected(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, - int cf1, int cf2); + int cf1, int cf2, u16 radar_bitmap); int hostapd_dfs_nop_finished(struct hostapd_iface *iface, int freq, int ht_enabled, int chan_offset, int chan_width, int cf1, int cf2); --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -1856,7 +1856,7 @@ static void hostapd_event_dfs_radar_dete wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq); hostapd_dfs_radar_detected(hapd->iface, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, - radar->cf1, radar->cf2); + radar->cf1, radar->cf2, radar->radar_bitmap); } static void hostapd_event_awgn_detected(struct hostapd_data *hapd, --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -6573,6 +6573,7 @@ union wpa_event_data { enum chan_width chan_width; int cf1; int cf2; + u16 radar_bitmap; } dfs_event; /** --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -2431,11 +2431,13 @@ static void nl80211_radar_event(struct w data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]); if (tb[NL80211_ATTR_CENTER_FREQ2]) data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]); + if (tb[NL80211_ATTR_RADAR_BITMAP]) + data.dfs_event.radar_bitmap = nla_get_u16(tb[NL80211_ATTR_RADAR_BITMAP]); - wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz", - data.dfs_event.freq, data.dfs_event.ht_enabled, + wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz" + "radar_bitmap: %0x ", data.dfs_event.freq, data.dfs_event.ht_enabled, data.dfs_event.chan_offset, data.dfs_event.chan_width, - data.dfs_event.cf1, data.dfs_event.cf2); + data.dfs_event.cf1, data.dfs_event.cf2, data.dfs_event.radar_bitmap); switch (event_type) { case NL80211_RADAR_DETECTED: @@ -2831,12 +2833,14 @@ static void qca_nl80211_dfs_offload_rada data.dfs_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]); if (tb[NL80211_ATTR_CENTER_FREQ2]) data.dfs_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]); + if (tb[NL80211_ATTR_RADAR_BITMAP]) + data.dfs_event.radar_bitmap = nla_get_u16(tb[NL80211_ATTR_RADAR_BITMAP]); wpa_printf(MSG_DEBUG, "nl80211: DFS event on freq %d MHz, ht: %d, " - "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz", + "offset: %d, width: %d, cf1: %dMHz, cf2: %dMHz radar bitmap: %0x", data.dfs_event.freq, data.dfs_event.ht_enabled, data.dfs_event.chan_offset, data.dfs_event.chan_width, - data.dfs_event.cf1, data.dfs_event.cf2); + data.dfs_event.cf1, data.dfs_event.cf2, data.dfs_event.radar_bitmap); switch (subcmd) { case QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED: --- a/src/drivers/nl80211_copy.h +++ b/src/drivers/nl80211_copy.h @@ -2835,6 +2835,11 @@ enum nl80211_commands { * This attribute type is u8 and valid range is 0 to 1. * 0 for disable AP power save mode. * 1 for enable AP power save mode. + * @NL80211_ATTR_RADAR_BITMAP: (u16) RADAR bitmap where the lowest bit + * corresponds to the lowest 20MHZ channel. Each bit set to 1 + * indicates that radar is detected in that sub-channel. + * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3386,6 +3391,8 @@ enum nl80211_attrs { NL80211_ATTR_RU_PUNCT_BITMAP, NL80211_ATTR_AP_PS, + NL80211_ATTR_MULTI_HW_MACS, + NL80211_ATTR_RADAR_BITMAP, /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -2128,7 +2128,8 @@ void wpas_ap_event_dfs_radar_detected(st hostapd_dfs_radar_detected(iface, radar->freq, radar->ht_enabled, radar->chan_offset, radar->chan_width, - radar->cf1, radar->cf2); + radar->cf1, radar->cf2, + radar->radar_bitmap); }