diff options
author | Luciano Coelho <luciano.coelho@intel.com> | 2014-10-08 02:48:40 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-10-09 05:30:09 -0400 |
commit | 0f791eb47f8222fd594e6f8a090632344ef23924 (patch) | |
tree | ec3771ef78ebd391e7c4e90472b5e8246f083703 | |
parent | 0c21e6320f6ea7c4bd2fc0a8c1d8577b372f92d2 (diff) |
mac80211: allow channel switch with multiple channel contexts
Channel switch with multiple channel contexts should now work fine.
Remove check that disallows switches when multiple contexts are in
use.
Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-mac.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 23 | ||||
-rw-r--r-- | include/net/mac80211.h | 1 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 7 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 26 | ||||
-rw-r--r-- | net/mac80211/trace.h | 9 |
8 files changed, 34 insertions, 40 deletions
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 26fec54dcd03..2748fde4b90c 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -6063,7 +6063,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
6063 | } | 6063 | } |
6064 | 6064 | ||
6065 | void | 6065 | void |
6066 | il4965_mac_channel_switch(struct ieee80211_hw *hw, | 6066 | il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
6067 | struct ieee80211_channel_switch *ch_switch) | 6067 | struct ieee80211_channel_switch *ch_switch) |
6068 | { | 6068 | { |
6069 | struct il_priv *il = hw->priv; | 6069 | struct il_priv *il = hw->priv; |
diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 337dfcf3bbde..3a57f71b8ed5 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h | |||
@@ -187,8 +187,9 @@ int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
187 | u8 buf_size); | 187 | u8 buf_size); |
188 | int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 188 | int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
189 | struct ieee80211_sta *sta); | 189 | struct ieee80211_sta *sta); |
190 | void il4965_mac_channel_switch(struct ieee80211_hw *hw, | 190 | void |
191 | struct ieee80211_channel_switch *ch_switch); | 191 | il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
192 | struct ieee80211_channel_switch *ch_switch); | ||
192 | 193 | ||
193 | void il4965_led_enable(struct il_priv *il); | 194 | void il4965_led_enable(struct il_priv *il); |
194 | 195 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 2364a3c09b9e..a967bf893a89 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -941,6 +941,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, | |||
941 | } | 941 | } |
942 | 942 | ||
943 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | 943 | static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, |
944 | struct ieee80211_vif *vif, | ||
944 | struct ieee80211_channel_switch *ch_switch) | 945 | struct ieee80211_channel_switch *ch_switch) |
945 | { | 946 | { |
946 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 947 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 575c8f6d4009..6ad3fcedab9b 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -5177,10 +5177,11 @@ out: | |||
5177 | } | 5177 | } |
5178 | 5178 | ||
5179 | static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, | 5179 | static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, |
5180 | struct ieee80211_vif *vif, | ||
5180 | struct ieee80211_channel_switch *ch_switch) | 5181 | struct ieee80211_channel_switch *ch_switch) |
5181 | { | 5182 | { |
5182 | struct wl1271 *wl = hw->priv; | 5183 | struct wl1271 *wl = hw->priv; |
5183 | struct wl12xx_vif *wlvif; | 5184 | struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); |
5184 | int ret; | 5185 | int ret; |
5185 | 5186 | ||
5186 | wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); | 5187 | wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch"); |
@@ -5190,14 +5191,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, | |||
5190 | mutex_lock(&wl->mutex); | 5191 | mutex_lock(&wl->mutex); |
5191 | 5192 | ||
5192 | if (unlikely(wl->state == WLCORE_STATE_OFF)) { | 5193 | if (unlikely(wl->state == WLCORE_STATE_OFF)) { |
5193 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | 5194 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) |
5194 | struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); | ||
5195 | |||
5196 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | ||
5197 | continue; | ||
5198 | |||
5199 | ieee80211_chswitch_done(vif, false); | 5195 | ieee80211_chswitch_done(vif, false); |
5200 | } | ||
5201 | goto out; | 5196 | goto out; |
5202 | } else if (unlikely(wl->state != WLCORE_STATE_ON)) { | 5197 | } else if (unlikely(wl->state != WLCORE_STATE_ON)) { |
5203 | goto out; | 5198 | goto out; |
@@ -5208,11 +5203,9 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, | |||
5208 | goto out; | 5203 | goto out; |
5209 | 5204 | ||
5210 | /* TODO: change mac80211 to pass vif as param */ | 5205 | /* TODO: change mac80211 to pass vif as param */ |
5211 | wl12xx_for_each_wlvif_sta(wl, wlvif) { | ||
5212 | unsigned long delay_usec; | ||
5213 | 5206 | ||
5214 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | 5207 | if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { |
5215 | continue; | 5208 | unsigned long delay_usec; |
5216 | 5209 | ||
5217 | ret = wl->ops->channel_switch(wl, wlvif, ch_switch); | 5210 | ret = wl->ops->channel_switch(wl, wlvif, ch_switch); |
5218 | if (ret) | 5211 | if (ret) |
@@ -5222,10 +5215,10 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, | |||
5222 | 5215 | ||
5223 | /* indicate failure 5 seconds after channel switch time */ | 5216 | /* indicate failure 5 seconds after channel switch time */ |
5224 | delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) * | 5217 | delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) * |
5225 | ch_switch->count; | 5218 | ch_switch->count; |
5226 | ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work, | 5219 | ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work, |
5227 | usecs_to_jiffies(delay_usec) + | 5220 | usecs_to_jiffies(delay_usec) + |
5228 | msecs_to_jiffies(5000)); | 5221 | msecs_to_jiffies(5000)); |
5229 | } | 5222 | } |
5230 | 5223 | ||
5231 | out_sleep: | 5224 | out_sleep: |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 7861ed875c4d..9bb2fc73aeaa 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2969,6 +2969,7 @@ struct ieee80211_ops { | |||
2969 | void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2969 | void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2970 | u32 queues, bool drop); | 2970 | u32 queues, bool drop); |
2971 | void (*channel_switch)(struct ieee80211_hw *hw, | 2971 | void (*channel_switch)(struct ieee80211_hw *hw, |
2972 | struct ieee80211_vif *vif, | ||
2972 | struct ieee80211_channel_switch *ch_switch); | 2973 | struct ieee80211_channel_switch *ch_switch); |
2973 | int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); | 2974 | int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); |
2974 | int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); | 2975 | int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 0a6090644769..1bbb0790264f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -764,12 +764,13 @@ static inline void drv_flush(struct ieee80211_local *local, | |||
764 | } | 764 | } |
765 | 765 | ||
766 | static inline void drv_channel_switch(struct ieee80211_local *local, | 766 | static inline void drv_channel_switch(struct ieee80211_local *local, |
767 | struct ieee80211_channel_switch *ch_switch) | 767 | struct ieee80211_sub_if_data *sdata, |
768 | struct ieee80211_channel_switch *ch_switch) | ||
768 | { | 769 | { |
769 | might_sleep(); | 770 | might_sleep(); |
770 | 771 | ||
771 | trace_drv_channel_switch(local, ch_switch); | 772 | trace_drv_channel_switch(local, sdata, ch_switch); |
772 | local->ops->channel_switch(&local->hw, ch_switch); | 773 | local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); |
773 | trace_drv_return_void(local); | 774 | trace_drv_return_void(local); |
774 | } | 775 | } |
775 | 776 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 148253c1bd78..fb6561509caf 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1134,21 +1134,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1134 | 1134 | ||
1135 | chanctx = container_of(conf, struct ieee80211_chanctx, conf); | 1135 | chanctx = container_of(conf, struct ieee80211_chanctx, conf); |
1136 | 1136 | ||
1137 | if (local->use_chanctx) { | 1137 | if (local->use_chanctx && |
1138 | u32 num_chanctx = 0; | 1138 | !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { |
1139 | list_for_each_entry(chanctx, &local->chanctx_list, list) | 1139 | sdata_info(sdata, |
1140 | num_chanctx++; | 1140 | "driver doesn't support chan-switch with channel contexts\n"); |
1141 | 1141 | ieee80211_queue_work(&local->hw, | |
1142 | if (num_chanctx > 1 || | 1142 | &ifmgd->csa_connection_drop_work); |
1143 | !(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) { | 1143 | mutex_unlock(&local->chanctx_mtx); |
1144 | sdata_info(sdata, | 1144 | mutex_unlock(&local->mtx); |
1145 | "not handling chan-switch with channel contexts\n"); | 1145 | return; |
1146 | ieee80211_queue_work(&local->hw, | ||
1147 | &ifmgd->csa_connection_drop_work); | ||
1148 | mutex_unlock(&local->chanctx_mtx); | ||
1149 | mutex_unlock(&local->mtx); | ||
1150 | return; | ||
1151 | } | ||
1152 | } | 1146 | } |
1153 | 1147 | ||
1154 | ch_switch.timestamp = timestamp; | 1148 | ch_switch.timestamp = timestamp; |
@@ -1192,7 +1186,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1192 | 1186 | ||
1193 | if (local->ops->channel_switch) { | 1187 | if (local->ops->channel_switch) { |
1194 | /* use driver's channel switch callback */ | 1188 | /* use driver's channel switch callback */ |
1195 | drv_channel_switch(local, &ch_switch); | 1189 | drv_channel_switch(local, sdata, &ch_switch); |
1196 | return; | 1190 | return; |
1197 | } | 1191 | } |
1198 | 1192 | ||
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index ca0e12dd23c0..976606aebac9 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -987,12 +987,14 @@ TRACE_EVENT(drv_flush, | |||
987 | 987 | ||
988 | TRACE_EVENT(drv_channel_switch, | 988 | TRACE_EVENT(drv_channel_switch, |
989 | TP_PROTO(struct ieee80211_local *local, | 989 | TP_PROTO(struct ieee80211_local *local, |
990 | struct ieee80211_sub_if_data *sdata, | ||
990 | struct ieee80211_channel_switch *ch_switch), | 991 | struct ieee80211_channel_switch *ch_switch), |
991 | 992 | ||
992 | TP_ARGS(local, ch_switch), | 993 | TP_ARGS(local, sdata, ch_switch), |
993 | 994 | ||
994 | TP_STRUCT__entry( | 995 | TP_STRUCT__entry( |
995 | LOCAL_ENTRY | 996 | LOCAL_ENTRY |
997 | VIF_ENTRY | ||
996 | CHANDEF_ENTRY | 998 | CHANDEF_ENTRY |
997 | __field(u64, timestamp) | 999 | __field(u64, timestamp) |
998 | __field(u32, device_timestamp) | 1000 | __field(u32, device_timestamp) |
@@ -1002,6 +1004,7 @@ TRACE_EVENT(drv_channel_switch, | |||
1002 | 1004 | ||
1003 | TP_fast_assign( | 1005 | TP_fast_assign( |
1004 | LOCAL_ASSIGN; | 1006 | LOCAL_ASSIGN; |
1007 | VIF_ASSIGN; | ||
1005 | CHANDEF_ASSIGN(&ch_switch->chandef) | 1008 | CHANDEF_ASSIGN(&ch_switch->chandef) |
1006 | __entry->timestamp = ch_switch->timestamp; | 1009 | __entry->timestamp = ch_switch->timestamp; |
1007 | __entry->device_timestamp = ch_switch->device_timestamp; | 1010 | __entry->device_timestamp = ch_switch->device_timestamp; |
@@ -1010,8 +1013,8 @@ TRACE_EVENT(drv_channel_switch, | |||
1010 | ), | 1013 | ), |
1011 | 1014 | ||
1012 | TP_printk( | 1015 | TP_printk( |
1013 | LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d", | 1016 | LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d", |
1014 | LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count | 1017 | LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count |
1015 | ) | 1018 | ) |
1016 | ); | 1019 | ); |
1017 | 1020 | ||