summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorLuciano Coelho <luciano.coelho@intel.com>2014-10-08 08:48:37 +0200
committerJohannes Berg <johannes.berg@intel.com>2014-10-09 11:30:08 +0200
commit6d027bcc8a4e2518ae825b0ff3dd069ab1abfe96 (patch)
tree798d3bfaf90f5f653905da6cb3be864f2a7a0443 /net/mac80211/mlme.c
parentmac80211: add extended channel switching capability if the driver supports CSA (diff)
downloadlinux-6d027bcc8a4e2518ae825b0ff3dd069ab1abfe96.tar.xz
linux-6d027bcc8a4e2518ae825b0ff3dd069ab1abfe96.zip
mac80211: add pre_channel_switch driver operation
Some drivers may need to prepare for a channel switch also when it is initiated from the remote side (eg. station, P2P client). To make this possible, add a generic callback that can be called for all interface types. Signed-off-by: Luciano Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f2e048fa250c..d23d6d97e453 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1057,6 +1057,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct ieee80211_chanctx *chanctx;
enum ieee80211_band current_band;
struct ieee80211_csa_ie csa_ie;
+ struct ieee80211_channel_switch ch_switch;
int res;
sdata_assert_lock(sdata);
@@ -1128,6 +1129,22 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
}
}
+ ch_switch.timestamp = timestamp;
+ ch_switch.device_timestamp = device_timestamp;
+ ch_switch.block_tx = csa_ie.mode;
+ ch_switch.chandef = csa_ie.chandef;
+ ch_switch.count = csa_ie.count;
+
+ if (drv_pre_channel_switch(sdata, &ch_switch)) {
+ sdata_info(sdata,
+ "preparing for channel switch failed, disconnecting\n");
+ ieee80211_queue_work(&local->hw,
+ &ifmgd->csa_connection_drop_work);
+ mutex_unlock(&local->chanctx_mtx);
+ mutex_unlock(&local->mtx);
+ return;
+ }
+
res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
chanctx->mode, false);
if (res) {
@@ -1153,14 +1170,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
if (local->ops->channel_switch) {
/* use driver's channel switch callback */
- struct ieee80211_channel_switch ch_switch = {
- .timestamp = timestamp,
- .device_timestamp = device_timestamp,
- .block_tx = csa_ie.mode,
- .chandef = csa_ie.chandef,
- .count = csa_ie.count,
- };
-
drv_channel_switch(local, &ch_switch);
return;
}