aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers
diff options
context:
space:
mode:
authorThomas Pedersen <c_tpeder@qca.qualcomm.com>2012-06-25 14:45:14 +0300
committerJouni Malinen <j@w1.fi>2012-06-25 14:45:14 +0300
commit1b487b8b1e95e1fbd9e00d52d883ba0ac4c2e4bf (patch)
tree9b8ebae95234d64e861736aec269b67abafa28e2 /src/drivers
parente7381b8473e7fb43c0e13f45c1c61e64d64072c2 (diff)
downloadexternal_wpa_supplicant_8_ti-1b487b8b1e95e1fbd9e00d52d883ba0ac4c2e4bf.zip
external_wpa_supplicant_8_ti-1b487b8b1e95e1fbd9e00d52d883ba0ac4c2e4bf.tar.gz
external_wpa_supplicant_8_ti-1b487b8b1e95e1fbd9e00d52d883ba0ac4c2e4bf.tar.bz2
nl80211: Handle CH_SWITCH event
Some drivers may independently decide to switch channels. Handle this by updating the hostapd and wpa_supplicant AP and GO configuration. Signed-hostap: Thomas Pedersen <c_tpeder@qca.qualcomm.com>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/driver.h21
-rw-r--r--src/drivers/driver_common.c1
-rw-r--r--src/drivers/driver_nl80211.c38
3 files changed, 59 insertions, 1 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 102ea46..9ed52ea 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -2978,7 +2978,14 @@ enum wpa_event_type {
/**
* EVENT_EAPOL_TX_STATUS - notify of EAPOL TX status
*/
- EVENT_EAPOL_TX_STATUS
+ EVENT_EAPOL_TX_STATUS,
+
+ /**
+ * EVENT_CH_SWITCH - AP or GO decided to switch channels
+ *
+ * Described in wpa_event_data.ch_switch
+ * */
+ EVENT_CH_SWITCH
};
@@ -3573,6 +3580,18 @@ union wpa_event_data {
int data_len;
int ack;
} eapol_tx_status;
+
+ /**
+ * struct ch_switch
+ * @freq: Frequency of new channel in MHz
+ * @ht_enabled: Whether this is an HT channel
+ * @ch_offset: Secondary channel offset
+ */
+ struct ch_switch {
+ int freq;
+ int ht_enabled;
+ int ch_offset;
+ } ch_switch;
};
/**
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index 345e851..81856aa 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -77,6 +77,7 @@ const char * event_to_string(enum wpa_event_type event)
E2S(SCHED_SCAN_STOPPED);
E2S(DRIVER_CLIENT_POLL_OK);
E2S(EAPOL_TX_STATUS);
+ E2S(CH_SWITCH);
}
return "UNKNOWN";
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b403792..376f363 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1196,6 +1196,40 @@ static void mlme_event_disconnect(struct wpa_driver_nl80211_data *drv,
}
+static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
+ struct nlattr *freq, struct nlattr *type)
+{
+ union wpa_event_data data;
+ int ht_enabled = 1;
+ int chan_offset = 0;
+
+ wpa_printf(MSG_DEBUG, "nl80211: Channel switch event");
+
+ if (!freq || !type)
+ return;
+
+ switch (nla_get_u32(type)) {
+ case NL80211_CHAN_NO_HT:
+ ht_enabled = 0;
+ break;
+ case NL80211_CHAN_HT20:
+ break;
+ case NL80211_CHAN_HT40PLUS:
+ chan_offset = 1;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ chan_offset = -1;
+ break;
+ }
+
+ data.ch_switch.freq = nla_get_u32(freq);
+ data.ch_switch.ht_enabled = ht_enabled;
+ data.ch_switch.ch_offset = chan_offset;
+
+ wpa_supplicant_event(drv->ctx, EVENT_CH_SWITCH, &data);
+}
+
+
static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
enum nl80211_commands cmd, struct nlattr *addr)
{
@@ -2116,6 +2150,10 @@ static void do_process_drv_event(struct wpa_driver_nl80211_data *drv,
tb[NL80211_ATTR_REQ_IE],
tb[NL80211_ATTR_RESP_IE]);
break;
+ case NL80211_CMD_CH_SWITCH_NOTIFY:
+ mlme_event_ch_switch(drv, tb[NL80211_ATTR_WIPHY_FREQ],
+ tb[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+ break;
case NL80211_CMD_DISCONNECT:
mlme_event_disconnect(drv, tb[NL80211_ATTR_REASON_CODE],
tb[NL80211_ATTR_MAC],