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