@@ -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) &&
@@ -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
@@ -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],
@@ -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])
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@adapt-ip.com> --- 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(-)