aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h6
-rw-r--r--net/mac80211/cfg.c7
-rw-r--r--net/mac80211/driver-ops.h16
-rw-r--r--net/mac80211/mlme.c9
-rw-r--r--net/mac80211/trace.h6
5 files changed, 43 insertions, 1 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 19e4159ce3a3..7861ed875c4d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2836,6 +2836,9 @@ enum ieee80211_roc_type {
2836 * before a channel switch procedure is started (ie. when a STA 2836 * before a channel switch procedure is started (ie. when a STA
2837 * gets a CSA or an userspace initiated channel-switch), allowing 2837 * gets a CSA or an userspace initiated channel-switch), allowing
2838 * the driver to prepare for the channel switch. 2838 * the driver to prepare for the channel switch.
2839 * @post_channel_switch: This is an optional callback that is called
2840 * after a channel switch procedure is completed, allowing the
2841 * driver to go back to a normal configuration.
2839 * 2842 *
2840 * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all 2843 * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all
2841 * information in bss_conf is set up and the beacon can be retrieved. A 2844 * information in bss_conf is set up and the beacon can be retrieved. A
@@ -3046,6 +3049,9 @@ struct ieee80211_ops {
3046 struct ieee80211_vif *vif, 3049 struct ieee80211_vif *vif,
3047 struct ieee80211_channel_switch *ch_switch); 3050 struct ieee80211_channel_switch *ch_switch);
3048 3051
3052 int (*post_channel_switch)(struct ieee80211_hw *hw,
3053 struct ieee80211_vif *vif);
3054
3049 int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 3055 int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
3050 void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 3056 void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
3051 u32 (*get_expected_throughput)(struct ieee80211_sta *sta); 3057 u32 (*get_expected_throughput)(struct ieee80211_sta *sta);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 647a2f6eb7dc..9d58b30b096a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2919,7 +2919,6 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2919 return err; 2919 return err;
2920 2920
2921 ieee80211_bss_info_change_notify(sdata, changed); 2921 ieee80211_bss_info_change_notify(sdata, changed);
2922 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2923 2922
2924 if (sdata->csa_block_tx) { 2923 if (sdata->csa_block_tx) {
2925 ieee80211_wake_vif_queues(local, sdata, 2924 ieee80211_wake_vif_queues(local, sdata,
@@ -2927,6 +2926,12 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
2927 sdata->csa_block_tx = false; 2926 sdata->csa_block_tx = false;
2928 } 2927 }
2929 2928
2929 err = drv_post_channel_switch(sdata);
2930 if (err)
2931 return err;
2932
2933 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
2934
2930 return 0; 2935 return 0;
2931} 2936}
2932 2937
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 5522672129ce..0a6090644769 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1214,6 +1214,22 @@ drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
1214 return ret; 1214 return ret;
1215} 1215}
1216 1216
1217static inline int
1218drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1219{
1220 struct ieee80211_local *local = sdata->local;
1221 int ret = 0;
1222
1223 if (!check_sdata_in_driver(sdata))
1224 return -EIO;
1225
1226 trace_drv_post_channel_switch(local, sdata);
1227 if (local->ops->post_channel_switch)
1228 ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1229 trace_drv_return_int(local, ret);
1230 return ret;
1231}
1232
1217static inline int drv_join_ibss(struct ieee80211_local *local, 1233static inline int drv_join_ibss(struct ieee80211_local *local,
1218 struct ieee80211_sub_if_data *sdata) 1234 struct ieee80211_sub_if_data *sdata)
1219{ 1235{
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d23d6d97e453..cb1a8c3bc73f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1010,6 +1010,15 @@ static void ieee80211_chswitch_work(struct work_struct *work)
1010 sdata->csa_block_tx = false; 1010 sdata->csa_block_tx = false;
1011 } 1011 }
1012 1012
1013 ret = drv_post_channel_switch(sdata);
1014 if (ret) {
1015 sdata_info(sdata,
1016 "driver post channel switch failed, disconnecting\n");
1017 ieee80211_queue_work(&local->hw,
1018 &ifmgd->csa_connection_drop_work);
1019 goto out;
1020 }
1021
1013 ieee80211_sta_reset_beacon_monitor(sdata); 1022 ieee80211_sta_reset_beacon_monitor(sdata);
1014 ieee80211_sta_reset_conn_monitor(sdata); 1023 ieee80211_sta_reset_conn_monitor(sdata);
1015 1024
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 30476d2c7302..ca0e12dd23c0 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2141,6 +2141,12 @@ TRACE_EVENT(drv_pre_channel_switch,
2141 ) 2141 )
2142); 2142);
2143 2143
2144DEFINE_EVENT(local_sdata_evt, drv_post_channel_switch,
2145 TP_PROTO(struct ieee80211_local *local,
2146 struct ieee80211_sub_if_data *sdata),
2147 TP_ARGS(local, sdata)
2148);
2149
2144 2150
2145#ifdef CONFIG_MAC80211_MESSAGE_TRACING 2151#ifdef CONFIG_MAC80211_MESSAGE_TRACING
2146#undef TRACE_SYSTEM 2152#undef TRACE_SYSTEM