diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 2cc322308..b4123b812 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -721,6 +721,8 @@ int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq, int hostapd_start_dfs_cac(struct hostapd_data *hapd, int freq, int flags) { + struct hostapd_freq_params data; + if (!hapd->driver || !hapd->driver->start_dfs_cac) return 0; @@ -742,5 +744,11 @@ int hostapd_start_dfs_cac(struct hostapd_data *hapd, int freq, int flags) return -1; } - return hapd->driver->start_dfs_cac(hapd->drv_priv, freq); + if (hostapd_set_freq_params(&data, hapd->iconf->hw_mode, freq, + hapd->iconf->channel, + hapd->iconf->ieee80211n, + 0, 0, 0, 0, 0)) + return -1; + + return hapd->driver->start_dfs_cac(hapd->drv_priv, &data); } diff --git a/src/drivers/driver.h b/src/drivers/driver.h index ad62c477f..37e27ba51 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -2735,10 +2735,10 @@ struct wpa_driver_ops { /** * start_dfs_cac - Listen for radar interference on the channel * @priv: Private driver interface data - * @freq: Frequency (in MHz) of the channel + * @freq: Channel parameters * Returns: 0 on success, -1 on failure */ - int (*start_dfs_cac)(void *priv, int freq); + int (*start_dfs_cac)(void *priv, struct hostapd_freq_params *freq); /** * stop_ap - Removes beacon from AP diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index df3df0997..8decec5a0 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -10330,14 +10330,18 @@ static int nl80211_set_p2p_powersave(void *priv, int legacy_ps, int opp_ps, } -static int nl80211_start_radar_detection(void *priv, int freq) +static int nl80211_start_radar_detection(void *priv, + struct hostapd_freq_params *freq) { struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; struct nl_msg *msg; int ret; - wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC)"); + wpa_printf(MSG_DEBUG, "nl80211: Start radar detection (CAC) %d MHz (ht_enabled=%d, vht_enabled=%d, bandwidth=%d MHz, cf1=%d MHz, cf2=%d MHz)", + freq->freq, freq->ht_enabled, freq->vht_enabled, + freq->bandwidth, freq->center_freq1, freq->center_freq2); + if (!(drv->capa.flags & WPA_DRIVER_FLAGS_RADAR)) { wpa_printf(MSG_DEBUG, "nl80211: Driver does not support radar " "detection"); @@ -10350,10 +10354,53 @@ static int nl80211_start_radar_detection(void *priv, int freq) nl80211_cmd(bss->drv, msg, 0, NL80211_CMD_RADAR_DETECT); NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); - NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq->freq); - /* only HT20 is supported at this point */ - NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, NL80211_CHAN_HT20); + if (freq->vht_enabled) { + switch (freq->bandwidth) { + case 20: + NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, + NL80211_CHAN_WIDTH_20); + break; + case 40: + NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, + NL80211_CHAN_WIDTH_40); + break; + case 80: + if (freq->center_freq2) + NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, + NL80211_CHAN_WIDTH_80P80); + else + NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, + NL80211_CHAN_WIDTH_80); + break; + case 160: + NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, + NL80211_CHAN_WIDTH_160); + break; + default: + return -1; + } + NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq->center_freq1); + if (freq->center_freq2) + NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2, + freq->center_freq2); + } else if (freq->ht_enabled) { + switch (freq->sec_channel_offset) { + case -1: + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, + NL80211_CHAN_HT40MINUS); + break; + case 1: + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, + NL80211_CHAN_HT40PLUS); + break; + default: + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, + NL80211_CHAN_HT20); + break; + } + } ret = send_and_recv_msgs(drv, msg, NULL, NULL); if (ret == 0)