nl80211 recently gained the ability to accept a KHz offset to a frequency otherwise specified in MHz. Since the internal hostap units are now KHz, we can support this by supplying the KHz frequency modulo 1000. Signed-off-by: Thomas Pedersen <thomas@xxxxxxxxxxxx> --- src/drivers/driver_nl80211.c | 10 ++++++++++ src/drivers/driver_nl80211_capa.c | 3 +++ src/drivers/driver_nl80211_event.c | 22 ++++++++++++++-------- src/drivers/driver_nl80211_scan.c | 3 +++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 7329e60403d5..7873654369f7 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3667,6 +3667,9 @@ retry: wpa_printf(MSG_DEBUG, " * freq=%g", PR_KHZ(params->freq)); if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, MHZ(params->freq))) goto fail; + if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, + params->freq % 1000)) + goto fail; } if (params->ssid) { wpa_printf(MSG_DEBUG, " * SSID=%s", @@ -4550,6 +4553,8 @@ static int nl80211_put_freq_params(struct nl_msg *msg, const u64 flags, wpa_printf(MSG_DEBUG, " * freq=%g", PR_KHZ(freq->freq)); if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, MHZ(freq->freq))) return -ENOBUFS; + if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq->freq % 1000)) + return -ENOBUFS; wpa_printf(MSG_DEBUG, " * he_enabled=%d", freq->he_enabled); wpa_printf(MSG_DEBUG, " * vht_enabled=%d", freq->vht_enabled); @@ -5742,6 +5747,9 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv, if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, MHZ(params->freq.freq))) return -1; + if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, + params->freq.freq % 1000)) + return -1; drv->assoc_freq = params->freq.freq; } else drv->assoc_freq = 0; @@ -7733,6 +7741,8 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss, if (!(msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_FRAME)) || (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, MHZ(freq))) || + (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, + freq % 1000)) || (wait && nla_put_u32(msg, NL80211_ATTR_DURATION, wait)) || (offchanok && ((drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) || drv->test_use_roc_tx) && diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c index f26bd45df6f9..f84a9988623d 100644 --- a/src/drivers/driver_nl80211_capa.c +++ b/src/drivers/driver_nl80211_capa.c @@ -1506,6 +1506,9 @@ static void phy_info_freq(struct hostapd_hw_modes *mode, chan->allowed_bw = ~0; chan->dfs_cac_ms = 0; + if (tb_freq[NL80211_FREQUENCY_ATTR_OFFSET]) + chan->freq += nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_OFFSET]); + if (ieee80211_freq_to_chan(chan->freq, &channel) != NUM_HOSTAPD_MODES) chan->chan = channel; else diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 430bf7ddbb79..e02533fe8107 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -635,8 +635,7 @@ static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv, } -static void mlme_event_mgmt(struct i802_bss *bss, - struct nlattr *freq, struct nlattr *sig, +static void mlme_event_mgmt(struct i802_bss *bss, u32 freq, struct nlattr *sig, const u8 *frame, size_t len) { struct wpa_driver_nl80211_data *drv = bss->drv; @@ -660,10 +659,8 @@ static void mlme_event_mgmt(struct i802_bss *bss, ssi_signal = (s32) nla_get_u32(sig); os_memset(&event, 0, sizeof(event)); - if (freq) { - event.rx_mgmt.freq = KHZ(nla_get_u32(freq)); - rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq; - } + event.rx_mgmt.freq = freq; + rx_freq = drv->last_mgmt_freq = event.rx_mgmt.freq; wpa_printf(MSG_DEBUG, "nl80211: RX frame da=" MACSTR " sa=" MACSTR " bssid=" MACSTR " freq=%g ssi_signal=%d fc=0x%x seq_ctrl=0x%x stype=%u (%s) len=%u", @@ -914,11 +911,13 @@ static void mlme_event_unprot_beacon(struct wpa_driver_nl80211_data *drv, static void mlme_event(struct i802_bss *bss, enum nl80211_commands cmd, struct nlattr *frame, struct nlattr *addr, struct nlattr *timed_out, - struct nlattr *freq, struct nlattr *ack, + struct nlattr *freq, struct nlattr *freq_offset, + struct nlattr *ack, struct nlattr *cookie, struct nlattr *sig, struct nlattr *wmm, struct nlattr *req_ie) { struct wpa_driver_nl80211_data *drv = bss->drv; + u32 frequency = 0; const u8 *data; size_t len; @@ -934,6 +933,11 @@ static void mlme_event(struct i802_bss *bss, return; } + if (freq) + frequency = KHZ(nla_get_u32(freq)); + if (freq_offset) + frequency += nla_get_u32(freq_offset); + data = nla_data(frame); len = nla_len(frame); if (len < 4 + 2 * ETH_ALEN) { @@ -977,7 +981,7 @@ static void mlme_event(struct i802_bss *bss, nla_data(frame), nla_len(frame)); break; case NL80211_CMD_FRAME: - mlme_event_mgmt(bss, freq, sig, nla_data(frame), + mlme_event_mgmt(bss, frequency, sig, nla_data(frame), nla_len(frame)); break; case NL80211_CMD_FRAME_TX_STATUS: @@ -2661,6 +2665,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, mlme_event(bss, cmd, tb[NL80211_ATTR_FRAME], tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT], tb[NL80211_ATTR_WIPHY_FREQ], + tb[NL80211_ATTR_WIPHY_FREQ_OFFSET], tb[NL80211_ATTR_ACK], tb[NL80211_ATTR_COOKIE], tb[NL80211_ATTR_RX_SIGNAL_DBM], @@ -2856,6 +2861,7 @@ int process_bss_event(struct nl_msg *msg, void *arg) mlme_event(bss, gnlh->cmd, tb[NL80211_ATTR_FRAME], tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT], tb[NL80211_ATTR_WIPHY_FREQ], + tb[NL80211_ATTR_WIPHY_FREQ_OFFSET], tb[NL80211_ATTR_ACK], tb[NL80211_ATTR_COOKIE], tb[NL80211_ATTR_RX_SIGNAL_DBM], diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index 44c6a8ef312e..fad5234b7c6b 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -703,6 +703,7 @@ nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv, static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { [NL80211_BSS_BSSID] = { .type = NLA_UNSPEC }, [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, + [NL80211_BSS_FREQUENCY_OFFSET] = { .type = NLA_U32 }, [NL80211_BSS_TSF] = { .type = NLA_U64 }, [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, @@ -755,6 +756,8 @@ nl80211_parse_bss_info(struct wpa_driver_nl80211_data *drv, ETH_ALEN); if (bss[NL80211_BSS_FREQUENCY]) r->freq = KHZ(nla_get_u32(bss[NL80211_BSS_FREQUENCY])); + if (bss[NL80211_BSS_FREQUENCY_OFFSET]) + r->freq += nla_get_u32(bss[NL80211_BSS_FREQUENCY_OFFSET]); if (bss[NL80211_BSS_BEACON_INTERVAL]) r->beacon_int = nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL]); if (bss[NL80211_BSS_CAPABILITY]) -- 2.20.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap