blob: 8a8f4b105468af3e57b07d7bcc558687be1ced09 [file] [log] [blame]
developer1a173672023-12-21 14:49:33 +08001From 488e67b3592e6e36622e12a212739d4d74710a56 Mon Sep 17 00:00:00 2001
2From: "fancy.liu" <fancy.liu@mediatek.com>
3Date: Thu, 30 Nov 2023 16:42:59 +0800
4Subject: [PATCH 37/37] mtk: mac80211: Add CSA action frame tx when channel
5 switch on AP
6
7Description:
8To meet spec requirement.
9
10802.11-2020
1111.8.8.2 Selecting and advertising a new channel in a non-DMG infrastructure BSS
1211.8.8.6 Selecting and advertising a new channel in a DMG BSS
13-
14An AP shall inform associated STAs that the AP is moving to a new channel and shall maintain the association by advertising the switch using Channel Switch Announcement elements in Beacon frames, Probe Response frames, and Channel Switch Announcement frames until the intended channel switch time.
15
16Signed-off-by: fancy.liu <fancy.liu@mediatek.com>
17---
18 net/mac80211/cfg.c | 28 ++++++++++++++--------------
19 net/mac80211/util.c | 10 +++++++---
20 2 files changed, 21 insertions(+), 17 deletions(-)
21
22diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
23index 2072a7a..1554849 100644
24--- a/net/mac80211/cfg.c
25+++ b/net/mac80211/cfg.c
26@@ -3790,15 +3790,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
27 * immediately too. If we would delay the switch
28 * until the next TBTT, we would have to set the probe
29 * response here.
30- *
31- * TODO: A channel switch with count <= 1 without
32- * sending a CSA action frame is kind of useless,
33- * because the clients won't know we're changing
34- * channels. The action frame must be implemented
35- * either here or in the userspace.
36 */
37- if (params->count <= 1)
38- break;
39
40 if ((params->n_counter_offsets_beacon >
41 IEEE80211_MAX_CNTDWN_COUNTERS_NUM) ||
42@@ -3814,14 +3806,20 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
43 csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
44 csa.count = params->count;
45
46- err = ieee80211_assign_beacon(sdata, &sdata->deflink,
47- &params->beacon_csa, &csa,
48- NULL, changed);
49- if (err < 0) {
50- ieee80211_free_next_beacon(&sdata->deflink);
51- return err;
52+ /* see comments in the NL80211_IFTYPE_AP block */
53+ if (params->count > 1) {
54+ err = ieee80211_assign_beacon(sdata, &sdata->deflink,
55+ &params->beacon_csa, &csa,
56+ NULL, changed);
57+
58+ if (err < 0) {
59+ ieee80211_free_next_beacon(&sdata->deflink);
60+ return err;
61+ }
62 }
63
64+ ieee80211_send_action_csa(sdata, params);
65+
66 break;
67 case NL80211_IFTYPE_ADHOC:
68 if (!sdata->vif.cfg.ibss_joined)
69@@ -3893,6 +3891,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
70 }
71 #endif
72 default:
73+ sdata_info(sdata, "Won't send CSA for vif.type:%d.\n", sdata->vif.type);
74 return -EOPNOTSUPP;
75 }
76
77@@ -3982,6 +3981,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
78
79 err = ieee80211_set_csa_beacon(sdata, params, &changed);
80 if (err) {
81+ sdata_info(sdata, "failed to set csa in beacon.\n");
82 ieee80211_link_unreserve_chanctx(&sdata->deflink);
83 goto out;
84 }
85diff --git a/net/mac80211/util.c b/net/mac80211/util.c
86index 5bd40c6..f36a5c0 100644
87--- a/net/mac80211/util.c
88+++ b/net/mac80211/util.c
89@@ -4515,8 +4515,11 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
90 u8 *pos;
91
92 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
93- sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
94+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
95+ sdata->vif.type != NL80211_IFTYPE_AP) {
96+ sdata_info(sdata, "Not allow csa action on vif.type:%d.\n", sdata->vif.type);
97 return -EOPNOTSUPP;
98+ }
99
100 skb = dev_alloc_skb(local->tx_headroom + hdr_len +
101 5 + /* channel switch announcement element */
102@@ -4533,9 +4536,10 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
103
104 eth_broadcast_addr(mgmt->da);
105 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
106- if (ieee80211_vif_is_mesh(&sdata->vif)) {
107+ if (sdata->vif.type == NL80211_IFTYPE_AP ||
108+ sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
109 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
110- } else {
111+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
112 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
113 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
114 }
115--
1162.18.0
117