aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2019-02-06 06:17:15 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-02-22 07:45:51 -0500
commitfafd2bce5a5821b8902b11ab24dffa47dfdbd2d0 (patch)
tree7355d98f723f9edfd6099d62ef566acdc47adfc0
parentc15353be91902fa6cde08d4bf325d089895d65e8 (diff)
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>
-rw-r--r--include/net/mac80211.h9
-rw-r--r--net/mac80211/driver-ops.h17
-rw-r--r--net/mac80211/mlme.c27
-rw-r--r--net/mac80211/trace.h40
4 files changed, 77 insertions, 16 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index aef7174a7c65..ac2ed8ec662b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6,7 +6,7 @@
6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 * Copyright 2013-2014 Intel Mobile Communications GmbH
8 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 8 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
9 * Copyright (C) 2018 Intel Corporation 9 * Copyright (C) 2018 - 2019 Intel Corporation
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as 12 * it under the terms of the GNU General Public License version 2 as
@@ -3646,7 +3646,9 @@ enum ieee80211_reconfig_type {
3646 * @abort_channel_switch: This is an optional callback that is called 3646 * @abort_channel_switch: This is an optional callback that is called
3647 * when channel switch procedure was completed, allowing the 3647 * when channel switch procedure was completed, allowing the
3648 * driver to go back to a normal configuration. 3648 * driver to go back to a normal configuration.
3649 * 3649 * @channel_switch_rx_beacon: This is an optional callback that is called
3650 * when channel switch procedure is in progress and additional beacon with
3651 * CSA IE was received, allowing driver to track changes in count.
3650 * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all 3652 * @join_ibss: Join an IBSS (on an IBSS interface); this is called after all
3651 * information in bss_conf is set up and the beacon can be retrieved. A 3653 * information in bss_conf is set up and the beacon can be retrieved. A
3652 * channel context is bound before this is called. 3654 * channel context is bound before this is called.
@@ -3951,6 +3953,9 @@ struct ieee80211_ops {
3951 struct ieee80211_vif *vif); 3953 struct ieee80211_vif *vif);
3952 void (*abort_channel_switch)(struct ieee80211_hw *hw, 3954 void (*abort_channel_switch)(struct ieee80211_hw *hw,
3953 struct ieee80211_vif *vif); 3955 struct ieee80211_vif *vif);
3956 void (*channel_switch_rx_beacon)(struct ieee80211_hw *hw,
3957 struct ieee80211_vif *vif,
3958 struct ieee80211_channel_switch *ch_switch);
3954 3959
3955 int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 3960 int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
3956 void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); 3961 void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index e069122595d0..28d022a3eee3 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -2,7 +2,7 @@
2/* 2/*
3* Portions of this file 3* Portions of this file
4* Copyright(c) 2016 Intel Deutschland GmbH 4* Copyright(c) 2016 Intel Deutschland GmbH
5* Copyright (C) 2018 Intel Corporation 5* Copyright (C) 2018 - 2019 Intel Corporation
6*/ 6*/
7 7
8#ifndef __MAC80211_DRIVER_OPS 8#ifndef __MAC80211_DRIVER_OPS
@@ -1066,6 +1066,21 @@ drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata)
1066 local->ops->abort_channel_switch(&local->hw, &sdata->vif); 1066 local->ops->abort_channel_switch(&local->hw, &sdata->vif);
1067} 1067}
1068 1068
1069static inline void
1070drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
1071 struct ieee80211_channel_switch *ch_switch)
1072{
1073 struct ieee80211_local *local = sdata->local;
1074
1075 if (!check_sdata_in_driver(sdata))
1076 return;
1077
1078 trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
1079 if (local->ops->channel_switch_rx_beacon)
1080 local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,
1081 ch_switch);
1082}
1083
1069static inline int drv_join_ibss(struct ieee80211_local *local, 1084static inline int drv_join_ibss(struct ieee80211_local *local,
1070 struct ieee80211_sub_if_data *sdata) 1085 struct ieee80211_sub_if_data *sdata)
1071{ 1086{
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 28a275ec6700..411656614e9a 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -7,7 +7,7 @@
7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 7 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
8 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 * Copyright 2013-2014 Intel Mobile Communications GmbH
9 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH 9 * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
10 * Copyright (C) 2018 Intel Corporation 10 * Copyright (C) 2018 - 2019 Intel Corporation
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as 13 * 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,
1312 res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, 1312 res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
1313 ifmgd->flags, 1313 ifmgd->flags,
1314 ifmgd->associated->bssid, &csa_ie); 1314 ifmgd->associated->bssid, &csa_ie);
1315
1316 if (!res) {
1317 ch_switch.timestamp = timestamp;
1318 ch_switch.device_timestamp = device_timestamp;
1319 ch_switch.block_tx = csa_ie.mode;
1320 ch_switch.chandef = csa_ie.chandef;
1321 ch_switch.count = csa_ie.count;
1322 ch_switch.delay = csa_ie.max_switch_time;
1323 }
1324
1315 if (res < 0) { 1325 if (res < 0) {
1316 ieee80211_queue_work(&local->hw, 1326 ieee80211_queue_work(&local->hw,
1317 &ifmgd->csa_connection_drop_work); 1327 &ifmgd->csa_connection_drop_work);
1318 return; 1328 return;
1319 } 1329 }
1320 1330
1321 if (res && beacon && sdata->vif.csa_active && 1331 if (beacon && sdata->vif.csa_active && !ifmgd->csa_waiting_bcn) {
1322 !ifmgd->csa_waiting_bcn) { 1332 if (res)
1323 ieee80211_sta_abort_chanswitch(sdata); 1333 ieee80211_sta_abort_chanswitch(sdata);
1334 else
1335 drv_channel_switch_rx_beacon(sdata, &ch_switch);
1324 return; 1336 return;
1325 } else if (sdata->vif.csa_active || res) { 1337 } else if (sdata->vif.csa_active || res) {
1326 /* disregard subsequent announcements if already processing */ 1338 /* disregard subsequent announcements if already processing */
@@ -1378,13 +1390,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1378 goto drop_connection; 1390 goto drop_connection;
1379 } 1391 }
1380 1392
1381 ch_switch.timestamp = timestamp;
1382 ch_switch.device_timestamp = device_timestamp;
1383 ch_switch.block_tx = csa_ie.mode;
1384 ch_switch.chandef = csa_ie.chandef;
1385 ch_switch.count = csa_ie.count;
1386 ch_switch.delay = csa_ie.max_switch_time;
1387
1388 if (drv_pre_channel_switch(sdata, &ch_switch)) { 1393 if (drv_pre_channel_switch(sdata, &ch_switch)) {
1389 sdata_info(sdata, 1394 sdata_info(sdata,
1390 "preparing for channel switch failed, disconnecting\n"); 1395 "preparing for channel switch failed, disconnecting\n");
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index c1e203fe281e..8ba70d26b82e 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1,8 +1,8 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2/* 2/*
3* Portions of this file 3* Portions of this file
4* Copyright(c) 2016 Intel Deutschland GmbH 4* Copyright(c) 2016-2017 Intel Deutschland GmbH
5* Copyright (C) 2018 Intel Corporation 5* Copyright (C) 2018 - 2019 Intel Corporation
6*/ 6*/
7 7
8#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) 8#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -2458,6 +2458,42 @@ DEFINE_EVENT(local_sdata_evt, drv_abort_channel_switch,
2458 TP_ARGS(local, sdata) 2458 TP_ARGS(local, sdata)
2459); 2459);
2460 2460
2461TRACE_EVENT(drv_channel_switch_rx_beacon,
2462 TP_PROTO(struct ieee80211_local *local,
2463 struct ieee80211_sub_if_data *sdata,
2464 struct ieee80211_channel_switch *ch_switch),
2465
2466 TP_ARGS(local, sdata, ch_switch),
2467
2468 TP_STRUCT__entry(
2469 LOCAL_ENTRY
2470 VIF_ENTRY
2471 CHANDEF_ENTRY
2472 __field(u64, timestamp)
2473 __field(u32, device_timestamp)
2474 __field(bool, block_tx)
2475 __field(u8, count)
2476 ),
2477
2478 TP_fast_assign(
2479 LOCAL_ASSIGN;
2480 VIF_ASSIGN;
2481 CHANDEF_ASSIGN(&ch_switch->chandef)
2482 __entry->timestamp = ch_switch->timestamp;
2483 __entry->device_timestamp = ch_switch->device_timestamp;
2484 __entry->block_tx = ch_switch->block_tx;
2485 __entry->count = ch_switch->count;
2486 ),
2487
2488 TP_printk(
2489 LOCAL_PR_FMT VIF_PR_FMT
2490 " received a channel switch beacon to "
2491 CHANDEF_PR_FMT " count:%d block_tx:%d timestamp:%llu",
2492 LOCAL_PR_ARG, VIF_PR_ARG, CHANDEF_PR_ARG, __entry->count,
2493 __entry->block_tx, __entry->timestamp
2494 )
2495);
2496
2461TRACE_EVENT(drv_get_txpower, 2497TRACE_EVENT(drv_get_txpower,
2462 TP_PROTO(struct ieee80211_local *local, 2498 TP_PROTO(struct ieee80211_local *local,
2463 struct ieee80211_sub_if_data *sdata, 2499 struct ieee80211_sub_if_data *sdata,