mac80211: notify driver on subsequent CSA beacons

Some drivers may want to track further the CSA beacons, for example
to compensate for buggy APs that change the beacon count or quiet
mode during CSA flow.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Sara Sharon
2019-02-06 13:17:15 +02:00
committed by Johannes Berg
parent c15353be91
commit fafd2bce5a
4 changed files with 77 additions and 16 deletions

View File

@@ -2,7 +2,7 @@
/*
* Portions of this file
* Copyright(c) 2016 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018 - 2019 Intel Corporation
*/
#ifndef __MAC80211_DRIVER_OPS
@@ -1066,6 +1066,21 @@ drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata)
local->ops->abort_channel_switch(&local->hw, &sdata->vif);
}
static inline void
drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_switch *ch_switch)
{
struct ieee80211_local *local = sdata->local;
if (!check_sdata_in_driver(sdata))
return;
trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
if (local->ops->channel_switch_rx_beacon)
local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,
ch_switch);
}
static inline int drv_join_ibss(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
{

View File

@@ -7,7 +7,7 @@
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright (C) 2018 - 2019 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -1312,15 +1312,27 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
ifmgd->flags,
ifmgd->associated->bssid, &csa_ie);
if (!res) {
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;
ch_switch.delay = csa_ie.max_switch_time;
}
if (res < 0) {
ieee80211_queue_work(&local->hw,
&ifmgd->csa_connection_drop_work);
return;
}
if (res && beacon && sdata->vif.csa_active &&
!ifmgd->csa_waiting_bcn) {
ieee80211_sta_abort_chanswitch(sdata);
if (beacon && sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) {
if (res)
ieee80211_sta_abort_chanswitch(sdata);
else
drv_channel_switch_rx_beacon(sdata, &ch_switch);
return;
} else if (sdata->vif.csa_active || res) {
/* disregard subsequent announcements if already processing */
@@ -1378,13 +1390,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
goto drop_connection;
}
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;
ch_switch.delay = csa_ie.max_switch_time;
if (drv_pre_channel_switch(sdata, &ch_switch)) {
sdata_info(sdata,
"preparing for channel switch failed, disconnecting\n");

View File

@@ -1,8 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Portions of this file
* Copyright(c) 2016 Intel Deutschland GmbH
* Copyright (C) 2018 Intel Corporation
* Copyright(c) 2016-2017 Intel Deutschland GmbH
* Copyright (C) 2018 - 2019 Intel Corporation
*/
#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -2458,6 +2458,42 @@ DEFINE_EVENT(local_sdata_evt, drv_abort_channel_switch,
TP_ARGS(local, sdata)
);
TRACE_EVENT(drv_channel_switch_rx_beacon,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_switch *ch_switch),
TP_ARGS(local, sdata, ch_switch),
TP_STRUCT__entry(
LOCAL_ENTRY
VIF_ENTRY
CHANDEF_ENTRY
__field(u64, timestamp)
__field(u32, device_timestamp)
__field(bool, block_tx)
__field(u8, count)
),
TP_fast_assign(
LOCAL_ASSIGN;
VIF_ASSIGN;
CHANDEF_ASSIGN(&ch_switch->chandef)
__entry->timestamp = ch_switch->timestamp;
__entry->device_timestamp = ch_switch->device_timestamp;
__entry->block_tx = ch_switch->block_tx;
__entry->count = ch_switch->count;
),
TP_printk(
LOCAL_PR_FMT VIF_PR_FMT
" received a channel switch beacon to "
CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu",
LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count,
__entry->block_tx, __entry->timestamp
)
);
TRACE_EVENT(drv_get_txpower,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,