hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/mac80211/ibss.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * IBSS mode implementation
34 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
....@@ -8,10 +9,7 @@
89 * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
910 * Copyright 2013-2014 Intel Mobile Communications GmbH
1011 * Copyright(c) 2016 Intel Deutschland GmbH
11
- *
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
14
- * published by the Free Software Foundation.
12
+ * Copyright(c) 2018-2020 Intel Corporation
1513 */
1614
1715 #include <linux/delay.h>
....@@ -147,9 +145,9 @@
147145 *pos++ = csa_settings->block_tx ? 1 : 0;
148146 *pos++ = ieee80211_frequency_to_channel(
149147 csa_settings->chandef.chan->center_freq);
150
- presp->csa_counter_offsets[0] = (pos - presp->head);
148
+ presp->cntdwn_counter_offsets[0] = (pos - presp->head);
151149 *pos++ = csa_settings->count;
152
- presp->csa_current_counter = csa_settings->count;
150
+ presp->cntdwn_current_counter = csa_settings->count;
153151 }
154152
155153 /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */
....@@ -540,9 +538,12 @@
540538 {
541539 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
542540 struct cfg80211_bss *cbss;
543
- int err, changed = 0;
544541
545542 sdata_assert_lock(sdata);
543
+
544
+ /* When not connected/joined, sending CSA doesn't make sense. */
545
+ if (ifibss->state != IEEE80211_IBSS_MLME_JOINED)
546
+ return -ENOLINK;
546547
547548 /* update cfg80211 bss information with the new channel */
548549 if (!is_zero_ether_addr(ifibss->bssid)) {
....@@ -562,13 +563,7 @@
562563 ifibss->chandef = sdata->csa_chandef;
563564
564565 /* generate the beacon */
565
- err = ieee80211_ibss_csa_beacon(sdata, NULL);
566
- if (err < 0)
567
- return err;
568
-
569
- changed |= err;
570
-
571
- return changed;
566
+ return ieee80211_ibss_csa_beacon(sdata, NULL);
572567 }
573568
574569 void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata)
....@@ -790,6 +785,7 @@
790785 enum nl80211_channel_type ch_type;
791786 int err;
792787 u32 sta_flags;
788
+ u32 vht_cap_info = 0;
793789
794790 sdata_assert_lock(sdata);
795791
....@@ -799,7 +795,7 @@
799795 case NL80211_CHAN_WIDTH_10:
800796 case NL80211_CHAN_WIDTH_20_NOHT:
801797 sta_flags |= IEEE80211_STA_DISABLE_HT;
802
- /* fall through */
798
+ fallthrough;
803799 case NL80211_CHAN_WIDTH_20:
804800 sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
805801 break;
....@@ -807,9 +803,13 @@
807803 break;
808804 }
809805
806
+ if (elems->vht_cap_elem)
807
+ vht_cap_info = le32_to_cpu(elems->vht_cap_elem->vht_cap_info);
808
+
810809 memset(&params, 0, sizeof(params));
811810 err = ieee80211_parse_ch_switch_ie(sdata, elems,
812811 ifibss->chandef.chan->band,
812
+ vht_cap_info,
813813 sta_flags, ifibss->bssid, &csa_ie);
814814 /* can't switch to destination channel, fail */
815815 if (err < 0)
....@@ -1041,7 +1041,8 @@
10411041 }
10421042
10431043 if (sta && !sta->sta.wme &&
1044
- elems->wmm_info && local->hw.queues >= IEEE80211_NUM_ACS) {
1044
+ (elems->wmm_info || elems->s1g_capab) &&
1045
+ local->hw.queues >= IEEE80211_NUM_ACS) {
10451046 sta->sta.wme = true;
10461047 ieee80211_check_fast_xmit(sta);
10471048 }
....@@ -1069,8 +1070,12 @@
10691070 /* we both use VHT */
10701071 struct ieee80211_vht_cap cap_ie;
10711072 struct ieee80211_sta_vht_cap cap = sta->sta.vht_cap;
1073
+ u32 vht_cap_info =
1074
+ le32_to_cpu(elems->vht_cap_elem->vht_cap_info);
10721075
1073
- ieee80211_chandef_vht_oper(elems->vht_operation,
1076
+ ieee80211_chandef_vht_oper(&local->hw, vht_cap_info,
1077
+ elems->vht_operation,
1078
+ elems->ht_operation,
10741079 &chandef);
10751080 memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie));
10761081 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
....@@ -1122,8 +1127,7 @@
11221127
11231128 ieee80211_update_sta_info(sdata, mgmt, len, rx_status, elems, channel);
11241129
1125
- bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1126
- channel);
1130
+ bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, channel);
11271131 if (!bss)
11281132 return;
11291133
....@@ -1253,6 +1257,7 @@
12531257
12541258 static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
12551259 {
1260
+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
12561261 struct ieee80211_local *local = sdata->local;
12571262 struct sta_info *sta, *tmp;
12581263 unsigned long exp_time = IEEE80211_IBSS_INACTIVITY_LIMIT;
....@@ -1269,10 +1274,17 @@
12691274 if (time_is_before_jiffies(last_active + exp_time) ||
12701275 (time_is_before_jiffies(last_active + exp_rsn) &&
12711276 sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
1277
+ u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
1278
+
12721279 sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
12731280 sta->sta_state != IEEE80211_STA_AUTHORIZED ?
12741281 "not authorized " : "", sta->sta.addr);
12751282
1283
+ ieee80211_send_deauth_disassoc(sdata, sta->sta.addr,
1284
+ ifibss->bssid,
1285
+ IEEE80211_STYPE_DEAUTH,
1286
+ WLAN_REASON_DEAUTH_LEAVING,
1287
+ true, frame_buf);
12761288 WARN_ON(__sta_info_destroy(sta));
12771289 }
12781290 }
....@@ -1394,7 +1406,7 @@
13941406 break;
13951407 case NL80211_CHAN_WIDTH_80P80:
13961408 cf2 = chandef->center_freq2;
1397
- /* fall through */
1409
+ fallthrough;
13981410 case NL80211_CHAN_WIDTH_80:
13991411 width = 80;
14001412 break;
....@@ -1602,7 +1614,7 @@
16021614 return;
16031615
16041616 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
1605
- false, &elems);
1617
+ false, &elems, mgmt->bssid, NULL);
16061618
16071619 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
16081620 }
....@@ -1652,7 +1664,7 @@
16521664
16531665 ieee802_11_parse_elems(
16541666 mgmt->u.action.u.chan_switch.variable,
1655
- ies_len, true, &elems);
1667
+ ies_len, true, &elems, mgmt->bssid, NULL);
16561668
16571669 if (elems.parse_error)
16581670 break;
....@@ -1758,6 +1770,11 @@
17581770 int i;
17591771 int ret;
17601772
1773
+ if (params->chandef.chan->freq_offset) {
1774
+ /* this may work, but is untested */
1775
+ return -EOPNOTSUPP;
1776
+ }
1777
+
17611778 ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
17621779 &params->chandef,
17631780 sdata->wdev.iftype);