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>
This commit is contained in:
parent
0c21e6320f
commit
0f791eb47f
|
@ -6063,7 +6063,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
void
|
||||
il4965_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
{
|
||||
struct il_priv *il = hw->priv;
|
||||
|
|
|
@ -187,8 +187,9 @@ int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
u8 buf_size);
|
||||
int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void il4965_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_channel_switch *ch_switch);
|
||||
void
|
||||
il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *ch_switch);
|
||||
|
||||
void il4965_led_enable(struct il_priv *il);
|
||||
|
||||
|
|
|
@ -941,6 +941,7 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
{
|
||||
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
||||
|
|
|
@ -5177,10 +5177,11 @@ out:
|
|||
}
|
||||
|
||||
static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
{
|
||||
struct wl1271 *wl = hw->priv;
|
||||
struct wl12xx_vif *wlvif;
|
||||
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
||||
int ret;
|
||||
|
||||
wl1271_debug(DEBUG_MAC80211, "mac80211 channel switch");
|
||||
|
@ -5190,14 +5191,8 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
|
|||
mutex_lock(&wl->mutex);
|
||||
|
||||
if (unlikely(wl->state == WLCORE_STATE_OFF)) {
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
|
||||
|
||||
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
|
||||
continue;
|
||||
|
||||
if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
|
||||
ieee80211_chswitch_done(vif, false);
|
||||
}
|
||||
goto out;
|
||||
} else if (unlikely(wl->state != WLCORE_STATE_ON)) {
|
||||
goto out;
|
||||
|
@ -5208,11 +5203,9 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
|
|||
goto out;
|
||||
|
||||
/* TODO: change mac80211 to pass vif as param */
|
||||
wl12xx_for_each_wlvif_sta(wl, wlvif) {
|
||||
unsigned long delay_usec;
|
||||
|
||||
if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
|
||||
continue;
|
||||
if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) {
|
||||
unsigned long delay_usec;
|
||||
|
||||
ret = wl->ops->channel_switch(wl, wlvif, ch_switch);
|
||||
if (ret)
|
||||
|
@ -5222,10 +5215,10 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw,
|
|||
|
||||
/* indicate failure 5 seconds after channel switch time */
|
||||
delay_usec = ieee80211_tu_to_usec(wlvif->beacon_int) *
|
||||
ch_switch->count;
|
||||
ch_switch->count;
|
||||
ieee80211_queue_delayed_work(hw, &wlvif->channel_switch_work,
|
||||
usecs_to_jiffies(delay_usec) +
|
||||
msecs_to_jiffies(5000));
|
||||
usecs_to_jiffies(delay_usec) +
|
||||
msecs_to_jiffies(5000));
|
||||
}
|
||||
|
||||
out_sleep:
|
||||
|
|
|
@ -2969,6 +2969,7 @@ struct ieee80211_ops {
|
|||
void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u32 queues, bool drop);
|
||||
void (*channel_switch)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_channel_switch *ch_switch);
|
||||
int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
|
||||
int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
|
||||
|
|
|
@ -764,12 +764,13 @@ static inline void drv_flush(struct ieee80211_local *local,
|
|||
}
|
||||
|
||||
static inline void drv_channel_switch(struct ieee80211_local *local,
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel_switch *ch_switch)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
trace_drv_channel_switch(local, ch_switch);
|
||||
local->ops->channel_switch(&local->hw, ch_switch);
|
||||
trace_drv_channel_switch(local, sdata, ch_switch);
|
||||
local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
|
|
|
@ -1134,21 +1134,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
chanctx = container_of(conf, struct ieee80211_chanctx, conf);
|
||||
|
||||
if (local->use_chanctx) {
|
||||
u32 num_chanctx = 0;
|
||||
list_for_each_entry(chanctx, &local->chanctx_list, list)
|
||||
num_chanctx++;
|
||||
|
||||
if (num_chanctx > 1 ||
|
||||
!(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
|
||||
sdata_info(sdata,
|
||||
"not handling chan-switch with channel contexts\n");
|
||||
ieee80211_queue_work(&local->hw,
|
||||
&ifmgd->csa_connection_drop_work);
|
||||
mutex_unlock(&local->chanctx_mtx);
|
||||
mutex_unlock(&local->mtx);
|
||||
return;
|
||||
}
|
||||
if (local->use_chanctx &&
|
||||
!(local->hw.flags & IEEE80211_HW_CHANCTX_STA_CSA)) {
|
||||
sdata_info(sdata,
|
||||
"driver doesn't support chan-switch with channel contexts\n");
|
||||
ieee80211_queue_work(&local->hw,
|
||||
&ifmgd->csa_connection_drop_work);
|
||||
mutex_unlock(&local->chanctx_mtx);
|
||||
mutex_unlock(&local->mtx);
|
||||
return;
|
||||
}
|
||||
|
||||
ch_switch.timestamp = timestamp;
|
||||
|
@ -1192,7 +1186,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
if (local->ops->channel_switch) {
|
||||
/* use driver's channel switch callback */
|
||||
drv_channel_switch(local, &ch_switch);
|
||||
drv_channel_switch(local, sdata, &ch_switch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -987,12 +987,14 @@ TRACE_EVENT(drv_flush,
|
|||
|
||||
TRACE_EVENT(drv_channel_switch,
|
||||
TP_PROTO(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel_switch *ch_switch),
|
||||
|
||||
TP_ARGS(local, ch_switch),
|
||||
TP_ARGS(local, sdata, ch_switch),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
LOCAL_ENTRY
|
||||
VIF_ENTRY
|
||||
CHANDEF_ENTRY
|
||||
__field(u64, timestamp)
|
||||
__field(u32, device_timestamp)
|
||||
|
@ -1002,6 +1004,7 @@ TRACE_EVENT(drv_channel_switch,
|
|||
|
||||
TP_fast_assign(
|
||||
LOCAL_ASSIGN;
|
||||
VIF_ASSIGN;
|
||||
CHANDEF_ASSIGN(&ch_switch->chandef)
|
||||
__entry->timestamp = ch_switch->timestamp;
|
||||
__entry->device_timestamp = ch_switch->device_timestamp;
|
||||
|
@ -1010,8 +1013,8 @@ TRACE_EVENT(drv_channel_switch,
|
|||
),
|
||||
|
||||
TP_printk(
|
||||
LOCAL_PR_FMT " new " CHANDEF_PR_FMT " count:%d",
|
||||
LOCAL_PR_ARG, CHANDEF_PR_ARG, __entry->count
|
||||
LOCAL_PR_FMT VIF_PR_FMT " new " CHANDEF_PR_FMT " count:%d",
|
||||
LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count
|
||||
)
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue