hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/mac80211/offchannel.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Off-channel operation helpers
34 *
....@@ -7,10 +8,7 @@
78 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
89 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
910 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
10
- *
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
13
- * published by the Free Software Foundation.
11
+ * Copyright (C) 2019 Intel Corporation
1412 */
1513 #include <linux/export.h>
1614 #include <net/mac80211.h>
....@@ -28,8 +26,7 @@
2826 {
2927 struct ieee80211_local *local = sdata->local;
3028 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
31
-
32
- local->offchannel_ps_enabled = false;
29
+ bool offchannel_ps_enabled = false;
3330
3431 /* FIXME: what to do when local->pspolling is true? */
3532
....@@ -40,12 +37,12 @@
4037 cancel_work_sync(&local->dynamic_ps_enable_work);
4138
4239 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
43
- local->offchannel_ps_enabled = true;
40
+ offchannel_ps_enabled = true;
4441 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
4542 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
4643 }
4744
48
- if (!local->offchannel_ps_enabled ||
45
+ if (!offchannel_ps_enabled ||
4946 !ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
5047 /*
5148 * If power save was enabled, no need to send a nullfunc
....@@ -60,38 +57,19 @@
6057 ieee80211_send_nullfunc(local, sdata, true);
6158 }
6259
63
-/* inform AP that we are awake again, unless power save is enabled */
60
+/* inform AP that we are awake again */
6461 static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
6562 {
6663 struct ieee80211_local *local = sdata->local;
6764
6865 if (!local->ps_sdata)
6966 ieee80211_send_nullfunc(local, sdata, false);
70
- else if (local->offchannel_ps_enabled) {
67
+ else if (local->hw.conf.dynamic_ps_timeout > 0) {
7168 /*
72
- * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
73
- * will send a nullfunc frame with the powersave bit set
74
- * even though the AP already knows that we are sleeping.
75
- * This could be avoided by sending a null frame with power
76
- * save bit disabled before enabling the power save, but
77
- * this doesn't gain anything.
78
- *
79
- * When IEEE80211_HW_PS_NULLFUNC_STACK is enabled, no need
80
- * to send a nullfunc frame because AP already knows that
81
- * we are sleeping, let's just enable power save mode in
82
- * hardware.
83
- */
84
- /* TODO: Only set hardware if CONF_PS changed?
85
- * TODO: Should we set offchannel_ps_enabled to false?
86
- */
87
- local->hw.conf.flags |= IEEE80211_CONF_PS;
88
- ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
89
- } else if (local->hw.conf.dynamic_ps_timeout > 0) {
90
- /*
91
- * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
92
- * had been running before leaving the operating channel,
93
- * restart the timer now and send a nullfunc frame to inform
94
- * the AP that we are awake.
69
+ * the dynamic_ps_timer had been running before leaving the
70
+ * operating channel, restart the timer now and send a nullfunc
71
+ * frame to inform the AP that we are awake so that AP sends
72
+ * the buffered packets (if any).
9573 */
9674 ieee80211_send_nullfunc(local, sdata, false);
9775 mod_timer(&local->dynamic_ps_timer, jiffies +
....@@ -202,6 +180,10 @@
202180 cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
203181 roc->cookie, roc->chan,
204182 GFP_KERNEL);
183
+ else
184
+ cfg80211_tx_mgmt_expired(&roc->sdata->wdev,
185
+ roc->mgmt_tx_cookie,
186
+ roc->chan, GFP_KERNEL);
205187
206188 list_del(&roc->list);
207189 kfree(roc);
....@@ -262,7 +244,7 @@
262244 if (roc->mgmt_tx_cookie) {
263245 if (!WARN_ON(!roc->frame)) {
264246 ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7,
265
- roc->chan->band, 0);
247
+ roc->chan->band);
266248 roc->frame = NULL;
267249 }
268250 } else {
....@@ -555,6 +537,10 @@
555537
556538 lockdep_assert_held(&local->mtx);
557539
540
+ if (channel->freq_offset)
541
+ /* this may work, but is untested */
542
+ return -EOPNOTSUPP;
543
+
558544 if (local->use_chanctx && !local->ops->remain_on_channel)
559545 return -EOPNOTSUPP;
560546
....@@ -731,7 +717,7 @@
731717 }
732718
733719 if (local->ops->remain_on_channel) {
734
- ret = drv_cancel_remain_on_channel(local);
720
+ ret = drv_cancel_remain_on_channel(local, roc->sdata);
735721 if (WARN_ON_ONCE(ret)) {
736722 mutex_unlock(&local->mtx);
737723 return ret;
....@@ -802,13 +788,13 @@
802788 if (!sdata->vif.bss_conf.ibss_joined)
803789 need_offchan = true;
804790 #ifdef CONFIG_MAC80211_MESH
805
- /* fall through */
791
+ fallthrough;
806792 case NL80211_IFTYPE_MESH_POINT:
807793 if (ieee80211_vif_is_mesh(&sdata->vif) &&
808794 !sdata->u.mesh.mesh_id_len)
809795 need_offchan = true;
810796 #endif
811
- /* fall through */
797
+ fallthrough;
812798 case NL80211_IFTYPE_AP:
813799 case NL80211_IFTYPE_AP_VLAN:
814800 case NL80211_IFTYPE_P2P_GO:
....@@ -910,7 +896,7 @@
910896 if (beacon)
911897 for (i = 0; i < params->n_csa_offsets; i++)
912898 data[params->csa_offsets[i]] =
913
- beacon->csa_current_counter;
899
+ beacon->cntdwn_current_counter;
914900
915901 rcu_read_unlock();
916902 }
....@@ -990,7 +976,7 @@
990976 if (roc->started) {
991977 if (local->ops->remain_on_channel) {
992978 /* can race, so ignore return value */
993
- drv_cancel_remain_on_channel(local);
979
+ drv_cancel_remain_on_channel(local, sdata);
994980 ieee80211_roc_notify_destroy(roc);
995981 } else {
996982 roc->abort = true;