| 1 | // SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 2 | /* | 
|---|
| 3 | * Copyright 2002-2005, Instant802 Networks, Inc. | 
|---|
| 4 | * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz> | 
|---|
| 5 | * Copyright 2013-2014  Intel Mobile Communications GmbH | 
|---|
| 6 | * Copyright (C) 2015 - 2017 Intel Deutschland GmbH | 
|---|
| 7 | * Copyright (C) 2018-2025 Intel Corporation | 
|---|
| 8 | */ | 
|---|
| 9 |  | 
|---|
| 10 | #include <linux/module.h> | 
|---|
| 11 | #include <linux/init.h> | 
|---|
| 12 | #include <linux/etherdevice.h> | 
|---|
| 13 | #include <linux/netdevice.h> | 
|---|
| 14 | #include <linux/types.h> | 
|---|
| 15 | #include <linux/slab.h> | 
|---|
| 16 | #include <linux/skbuff.h> | 
|---|
| 17 | #include <linux/if_arp.h> | 
|---|
| 18 | #include <linux/timer.h> | 
|---|
| 19 | #include <linux/rtnetlink.h> | 
|---|
| 20 |  | 
|---|
| 21 | #include <net/mac80211.h> | 
|---|
| 22 | #include "ieee80211_i.h" | 
|---|
| 23 | #include "driver-ops.h" | 
|---|
| 24 | #include "rate.h" | 
|---|
| 25 | #include "sta_info.h" | 
|---|
| 26 | #include "debugfs_sta.h" | 
|---|
| 27 | #include "mesh.h" | 
|---|
| 28 | #include "wme.h" | 
|---|
| 29 |  | 
|---|
| 30 | /** | 
|---|
| 31 | * DOC: STA information lifetime rules | 
|---|
| 32 | * | 
|---|
| 33 | * STA info structures (&struct sta_info) are managed in a hash table | 
|---|
| 34 | * for faster lookup and a list for iteration. They are managed using | 
|---|
| 35 | * RCU, i.e. access to the list and hash table is protected by RCU. | 
|---|
| 36 | * | 
|---|
| 37 | * Upon allocating a STA info structure with sta_info_alloc(), the caller | 
|---|
| 38 | * owns that structure. It must then insert it into the hash table using | 
|---|
| 39 | * either sta_info_insert() or sta_info_insert_rcu(); only in the latter | 
|---|
| 40 | * case (which acquires an rcu read section but must not be called from | 
|---|
| 41 | * within one) will the pointer still be valid after the call. Note that | 
|---|
| 42 | * the caller may not do much with the STA info before inserting it; in | 
|---|
| 43 | * particular, it may not start any mesh peer link management or add | 
|---|
| 44 | * encryption keys. | 
|---|
| 45 | * | 
|---|
| 46 | * When the insertion fails (sta_info_insert()) returns non-zero), the | 
|---|
| 47 | * structure will have been freed by sta_info_insert()! | 
|---|
| 48 | * | 
|---|
| 49 | * Station entries are added by mac80211 when you establish a link with a | 
|---|
| 50 | * peer. This means different things for the different type of interfaces | 
|---|
| 51 | * we support. For a regular station this mean we add the AP sta when we | 
|---|
| 52 | * receive an association response from the AP. For IBSS this occurs when | 
|---|
| 53 | * get to know about a peer on the same IBSS. For WDS we add the sta for | 
|---|
| 54 | * the peer immediately upon device open. When using AP mode we add stations | 
|---|
| 55 | * for each respective station upon request from userspace through nl80211. | 
|---|
| 56 | * | 
|---|
| 57 | * In order to remove a STA info structure, various sta_info_destroy_*() | 
|---|
| 58 | * calls are available. | 
|---|
| 59 | * | 
|---|
| 60 | * There is no concept of ownership on a STA entry; each structure is | 
|---|
| 61 | * owned by the global hash table/list until it is removed. All users of | 
|---|
| 62 | * the structure need to be RCU protected so that the structure won't be | 
|---|
| 63 | * freed before they are done using it. | 
|---|
| 64 | */ | 
|---|
| 65 |  | 
|---|
| 66 | struct sta_link_alloc { | 
|---|
| 67 | struct link_sta_info info; | 
|---|
| 68 | struct ieee80211_link_sta sta; | 
|---|
| 69 | struct rcu_head rcu_head; | 
|---|
| 70 | }; | 
|---|
| 71 |  | 
|---|
| 72 | static const struct rhashtable_params sta_rht_params = { | 
|---|
| 73 | .nelem_hint = 3, /* start small */ | 
|---|
| 74 | .automatic_shrinking = true, | 
|---|
| 75 | .head_offset = offsetof(struct sta_info, hash_node), | 
|---|
| 76 | .key_offset = offsetof(struct sta_info, addr), | 
|---|
| 77 | .key_len = ETH_ALEN, | 
|---|
| 78 | .max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE, | 
|---|
| 79 | }; | 
|---|
| 80 |  | 
|---|
| 81 | static const struct rhashtable_params link_sta_rht_params = { | 
|---|
| 82 | .nelem_hint = 3, /* start small */ | 
|---|
| 83 | .automatic_shrinking = true, | 
|---|
| 84 | .head_offset = offsetof(struct link_sta_info, link_hash_node), | 
|---|
| 85 | .key_offset = offsetof(struct link_sta_info, addr), | 
|---|
| 86 | .key_len = ETH_ALEN, | 
|---|
| 87 | .max_size = CONFIG_MAC80211_STA_HASH_MAX_SIZE, | 
|---|
| 88 | }; | 
|---|
| 89 |  | 
|---|
| 90 | static int sta_info_hash_del(struct ieee80211_local *local, | 
|---|
| 91 | struct sta_info *sta) | 
|---|
| 92 | { | 
|---|
| 93 | return rhltable_remove(hlt: &local->sta_hash, list: &sta->hash_node, | 
|---|
| 94 | params: sta_rht_params); | 
|---|
| 95 | } | 
|---|
| 96 |  | 
|---|
| 97 | static int link_sta_info_hash_add(struct ieee80211_local *local, | 
|---|
| 98 | struct link_sta_info *link_sta) | 
|---|
| 99 | { | 
|---|
| 100 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 101 |  | 
|---|
| 102 | return rhltable_insert(hlt: &local->link_sta_hash, | 
|---|
| 103 | list: &link_sta->link_hash_node, params: link_sta_rht_params); | 
|---|
| 104 | } | 
|---|
| 105 |  | 
|---|
| 106 | static int link_sta_info_hash_del(struct ieee80211_local *local, | 
|---|
| 107 | struct link_sta_info *link_sta) | 
|---|
| 108 | { | 
|---|
| 109 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 110 |  | 
|---|
| 111 | return rhltable_remove(hlt: &local->link_sta_hash, | 
|---|
| 112 | list: &link_sta->link_hash_node, params: link_sta_rht_params); | 
|---|
| 113 | } | 
|---|
| 114 |  | 
|---|
| 115 | void ieee80211_purge_sta_txqs(struct sta_info *sta) | 
|---|
| 116 | { | 
|---|
| 117 | struct ieee80211_local *local = sta->sdata->local; | 
|---|
| 118 | int i; | 
|---|
| 119 |  | 
|---|
| 120 | for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { | 
|---|
| 121 | struct txq_info *txqi; | 
|---|
| 122 |  | 
|---|
| 123 | if (!sta->sta.txq[i]) | 
|---|
| 124 | continue; | 
|---|
| 125 |  | 
|---|
| 126 | txqi = to_txq_info(txq: sta->sta.txq[i]); | 
|---|
| 127 |  | 
|---|
| 128 | ieee80211_txq_purge(local, txqi); | 
|---|
| 129 | } | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | static void __cleanup_single_sta(struct sta_info *sta) | 
|---|
| 133 | { | 
|---|
| 134 | int ac, i; | 
|---|
| 135 | struct tid_ampdu_tx *tid_tx; | 
|---|
| 136 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 137 | struct ieee80211_local *local = sdata->local; | 
|---|
| 138 | struct ps_data *ps; | 
|---|
| 139 |  | 
|---|
| 140 | if (test_sta_flag(sta, flag: WLAN_STA_PS_STA) || | 
|---|
| 141 | test_sta_flag(sta, flag: WLAN_STA_PS_DRIVER) || | 
|---|
| 142 | test_sta_flag(sta, flag: WLAN_STA_PS_DELIVER)) { | 
|---|
| 143 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || | 
|---|
| 144 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 
|---|
| 145 | ps = &sdata->bss->ps; | 
|---|
| 146 | else if (ieee80211_vif_is_mesh(vif: &sdata->vif)) | 
|---|
| 147 | ps = &sdata->u.mesh.ps; | 
|---|
| 148 | else | 
|---|
| 149 | return; | 
|---|
| 150 |  | 
|---|
| 151 | clear_sta_flag(sta, flag: WLAN_STA_PS_STA); | 
|---|
| 152 | clear_sta_flag(sta, flag: WLAN_STA_PS_DRIVER); | 
|---|
| 153 | clear_sta_flag(sta, flag: WLAN_STA_PS_DELIVER); | 
|---|
| 154 |  | 
|---|
| 155 | atomic_dec(v: &ps->num_sta_ps); | 
|---|
| 156 | } | 
|---|
| 157 |  | 
|---|
| 158 | ieee80211_purge_sta_txqs(sta); | 
|---|
| 159 |  | 
|---|
| 160 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 
|---|
| 161 | local->total_ps_buffered -= skb_queue_len(list_: &sta->ps_tx_buf[ac]); | 
|---|
| 162 | ieee80211_purge_tx_queue(hw: &local->hw, skbs: &sta->ps_tx_buf[ac]); | 
|---|
| 163 | ieee80211_purge_tx_queue(hw: &local->hw, skbs: &sta->tx_filtered[ac]); | 
|---|
| 164 | } | 
|---|
| 165 |  | 
|---|
| 166 | if (ieee80211_vif_is_mesh(vif: &sdata->vif)) | 
|---|
| 167 | mesh_sta_cleanup(sta); | 
|---|
| 168 |  | 
|---|
| 169 | cancel_work_sync(work: &sta->drv_deliver_wk); | 
|---|
| 170 |  | 
|---|
| 171 | /* | 
|---|
| 172 | * Destroy aggregation state here. It would be nice to wait for the | 
|---|
| 173 | * driver to finish aggregation stop and then clean up, but for now | 
|---|
| 174 | * drivers have to handle aggregation stop being requested, followed | 
|---|
| 175 | * directly by station destruction. | 
|---|
| 176 | */ | 
|---|
| 177 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 
|---|
| 178 | kfree(objp: sta->ampdu_mlme.tid_start_tx[i]); | 
|---|
| 179 | tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); | 
|---|
| 180 | if (!tid_tx) | 
|---|
| 181 | continue; | 
|---|
| 182 | ieee80211_purge_tx_queue(hw: &local->hw, skbs: &tid_tx->pending); | 
|---|
| 183 | kfree(objp: tid_tx); | 
|---|
| 184 | } | 
|---|
| 185 | } | 
|---|
| 186 |  | 
|---|
| 187 | static void cleanup_single_sta(struct sta_info *sta) | 
|---|
| 188 | { | 
|---|
| 189 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 190 | struct ieee80211_local *local = sdata->local; | 
|---|
| 191 |  | 
|---|
| 192 | __cleanup_single_sta(sta); | 
|---|
| 193 | sta_info_free(local, sta); | 
|---|
| 194 | } | 
|---|
| 195 |  | 
|---|
| 196 | struct rhlist_head *sta_info_hash_lookup(struct ieee80211_local *local, | 
|---|
| 197 | const u8 *addr) | 
|---|
| 198 | { | 
|---|
| 199 | return rhltable_lookup(hlt: &local->sta_hash, key: addr, params: sta_rht_params); | 
|---|
| 200 | } | 
|---|
| 201 |  | 
|---|
| 202 | /* protected by RCU */ | 
|---|
| 203 | struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | 
|---|
| 204 | const u8 *addr) | 
|---|
| 205 | { | 
|---|
| 206 | struct ieee80211_local *local = sdata->local; | 
|---|
| 207 | struct rhlist_head *tmp; | 
|---|
| 208 | struct sta_info *sta; | 
|---|
| 209 |  | 
|---|
| 210 | rcu_read_lock(); | 
|---|
| 211 | for_each_sta_info(local, addr, sta, tmp) { | 
|---|
| 212 | if (sta->sdata == sdata) { | 
|---|
| 213 | rcu_read_unlock(); | 
|---|
| 214 | /* this is safe as the caller must already hold | 
|---|
| 215 | * another rcu read section or the mutex | 
|---|
| 216 | */ | 
|---|
| 217 | return sta; | 
|---|
| 218 | } | 
|---|
| 219 | } | 
|---|
| 220 | rcu_read_unlock(); | 
|---|
| 221 | return NULL; | 
|---|
| 222 | } | 
|---|
| 223 |  | 
|---|
| 224 | /* | 
|---|
| 225 | * Get sta info either from the specified interface | 
|---|
| 226 | * or from one of its vlans | 
|---|
| 227 | */ | 
|---|
| 228 | struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | 
|---|
| 229 | const u8 *addr) | 
|---|
| 230 | { | 
|---|
| 231 | struct ieee80211_local *local = sdata->local; | 
|---|
| 232 | struct rhlist_head *tmp; | 
|---|
| 233 | struct sta_info *sta; | 
|---|
| 234 |  | 
|---|
| 235 | rcu_read_lock(); | 
|---|
| 236 | for_each_sta_info(local, addr, sta, tmp) { | 
|---|
| 237 | if (sta->sdata == sdata || | 
|---|
| 238 | (sta->sdata->bss && sta->sdata->bss == sdata->bss)) { | 
|---|
| 239 | rcu_read_unlock(); | 
|---|
| 240 | /* this is safe as the caller must already hold | 
|---|
| 241 | * another rcu read section or the mutex | 
|---|
| 242 | */ | 
|---|
| 243 | return sta; | 
|---|
| 244 | } | 
|---|
| 245 | } | 
|---|
| 246 | rcu_read_unlock(); | 
|---|
| 247 | return NULL; | 
|---|
| 248 | } | 
|---|
| 249 |  | 
|---|
| 250 | struct rhlist_head *link_sta_info_hash_lookup(struct ieee80211_local *local, | 
|---|
| 251 | const u8 *addr) | 
|---|
| 252 | { | 
|---|
| 253 | return rhltable_lookup(hlt: &local->link_sta_hash, key: addr, | 
|---|
| 254 | params: link_sta_rht_params); | 
|---|
| 255 | } | 
|---|
| 256 |  | 
|---|
| 257 | struct link_sta_info * | 
|---|
| 258 | link_sta_info_get_bss(struct ieee80211_sub_if_data *sdata, const u8 *addr) | 
|---|
| 259 | { | 
|---|
| 260 | struct ieee80211_local *local = sdata->local; | 
|---|
| 261 | struct rhlist_head *tmp; | 
|---|
| 262 | struct link_sta_info *link_sta; | 
|---|
| 263 |  | 
|---|
| 264 | rcu_read_lock(); | 
|---|
| 265 | for_each_link_sta_info(local, addr, link_sta, tmp) { | 
|---|
| 266 | struct sta_info *sta = link_sta->sta; | 
|---|
| 267 |  | 
|---|
| 268 | if (sta->sdata == sdata || | 
|---|
| 269 | (sta->sdata->bss && sta->sdata->bss == sdata->bss)) { | 
|---|
| 270 | rcu_read_unlock(); | 
|---|
| 271 | /* this is safe as the caller must already hold | 
|---|
| 272 | * another rcu read section or the mutex | 
|---|
| 273 | */ | 
|---|
| 274 | return link_sta; | 
|---|
| 275 | } | 
|---|
| 276 | } | 
|---|
| 277 | rcu_read_unlock(); | 
|---|
| 278 | return NULL; | 
|---|
| 279 | } | 
|---|
| 280 |  | 
|---|
| 281 | struct ieee80211_sta * | 
|---|
| 282 | ieee80211_find_sta_by_link_addrs(struct ieee80211_hw *hw, | 
|---|
| 283 | const u8 *addr, | 
|---|
| 284 | const u8 *localaddr, | 
|---|
| 285 | unsigned int *link_id) | 
|---|
| 286 | { | 
|---|
| 287 | struct ieee80211_local *local = hw_to_local(hw); | 
|---|
| 288 | struct link_sta_info *link_sta; | 
|---|
| 289 | struct rhlist_head *tmp; | 
|---|
| 290 |  | 
|---|
| 291 | for_each_link_sta_info(local, addr, link_sta, tmp) { | 
|---|
| 292 | struct sta_info *sta = link_sta->sta; | 
|---|
| 293 | struct ieee80211_link_data *link; | 
|---|
| 294 | u8 _link_id = link_sta->link_id; | 
|---|
| 295 |  | 
|---|
| 296 | if (!localaddr) { | 
|---|
| 297 | if (link_id) | 
|---|
| 298 | *link_id = _link_id; | 
|---|
| 299 | return &sta->sta; | 
|---|
| 300 | } | 
|---|
| 301 |  | 
|---|
| 302 | link = rcu_dereference(sta->sdata->link[_link_id]); | 
|---|
| 303 | if (!link) | 
|---|
| 304 | continue; | 
|---|
| 305 |  | 
|---|
| 306 | if (memcmp(link->conf->addr, localaddr, ETH_ALEN)) | 
|---|
| 307 | continue; | 
|---|
| 308 |  | 
|---|
| 309 | if (link_id) | 
|---|
| 310 | *link_id = _link_id; | 
|---|
| 311 | return &sta->sta; | 
|---|
| 312 | } | 
|---|
| 313 |  | 
|---|
| 314 | return NULL; | 
|---|
| 315 | } | 
|---|
| 316 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_link_addrs); | 
|---|
| 317 |  | 
|---|
| 318 | struct sta_info *sta_info_get_by_addrs(struct ieee80211_local *local, | 
|---|
| 319 | const u8 *sta_addr, const u8 *vif_addr) | 
|---|
| 320 | { | 
|---|
| 321 | struct rhlist_head *tmp; | 
|---|
| 322 | struct sta_info *sta; | 
|---|
| 323 |  | 
|---|
| 324 | for_each_sta_info(local, sta_addr, sta, tmp) { | 
|---|
| 325 | if (ether_addr_equal(addr1: vif_addr, addr2: sta->sdata->vif.addr)) | 
|---|
| 326 | return sta; | 
|---|
| 327 | } | 
|---|
| 328 |  | 
|---|
| 329 | return NULL; | 
|---|
| 330 | } | 
|---|
| 331 |  | 
|---|
| 332 | struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata, | 
|---|
| 333 | int idx) | 
|---|
| 334 | { | 
|---|
| 335 | struct ieee80211_local *local = sdata->local; | 
|---|
| 336 | struct sta_info *sta; | 
|---|
| 337 | int i = 0; | 
|---|
| 338 |  | 
|---|
| 339 | list_for_each_entry_rcu(sta, &local->sta_list, list, | 
|---|
| 340 | lockdep_is_held(&local->hw.wiphy->mtx)) { | 
|---|
| 341 | if (sdata != sta->sdata) | 
|---|
| 342 | continue; | 
|---|
| 343 | if (i < idx) { | 
|---|
| 344 | ++i; | 
|---|
| 345 | continue; | 
|---|
| 346 | } | 
|---|
| 347 | return sta; | 
|---|
| 348 | } | 
|---|
| 349 |  | 
|---|
| 350 | return NULL; | 
|---|
| 351 | } | 
|---|
| 352 |  | 
|---|
| 353 | static void sta_info_free_link(struct link_sta_info *link_sta) | 
|---|
| 354 | { | 
|---|
| 355 | free_percpu(pdata: link_sta->pcpu_rx_stats); | 
|---|
| 356 | } | 
|---|
| 357 |  | 
|---|
| 358 | static void sta_accumulate_removed_link_stats(struct sta_info *sta, int link_id) | 
|---|
| 359 | { | 
|---|
| 360 | struct link_sta_info *link_sta = wiphy_dereference(sta->local->hw.wiphy, | 
|---|
| 361 | sta->link[link_id]); | 
|---|
| 362 | struct ieee80211_link_data *link; | 
|---|
| 363 | int ac, tid; | 
|---|
| 364 | u32 thr; | 
|---|
| 365 |  | 
|---|
| 366 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 
|---|
| 367 | sta->rem_link_stats.tx_packets += | 
|---|
| 368 | link_sta->tx_stats.packets[ac]; | 
|---|
| 369 | sta->rem_link_stats.tx_bytes += link_sta->tx_stats.bytes[ac]; | 
|---|
| 370 | } | 
|---|
| 371 |  | 
|---|
| 372 | sta->rem_link_stats.rx_packets += link_sta->rx_stats.packets; | 
|---|
| 373 | sta->rem_link_stats.rx_bytes += link_sta->rx_stats.bytes; | 
|---|
| 374 | sta->rem_link_stats.tx_retries += link_sta->status_stats.retry_count; | 
|---|
| 375 | sta->rem_link_stats.tx_failed += link_sta->status_stats.retry_failed; | 
|---|
| 376 | sta->rem_link_stats.rx_dropped_misc += link_sta->rx_stats.dropped; | 
|---|
| 377 |  | 
|---|
| 378 | thr = sta_get_expected_throughput(sta); | 
|---|
| 379 | if (thr != 0) | 
|---|
| 380 | sta->rem_link_stats.expected_throughput += thr; | 
|---|
| 381 |  | 
|---|
| 382 | for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { | 
|---|
| 383 | sta->rem_link_stats.pertid_stats.rx_msdu += | 
|---|
| 384 | link_sta->rx_stats.msdu[tid]; | 
|---|
| 385 | sta->rem_link_stats.pertid_stats.tx_msdu += | 
|---|
| 386 | link_sta->tx_stats.msdu[tid]; | 
|---|
| 387 | sta->rem_link_stats.pertid_stats.tx_msdu_retries += | 
|---|
| 388 | link_sta->status_stats.msdu_retries[tid]; | 
|---|
| 389 | sta->rem_link_stats.pertid_stats.tx_msdu_failed += | 
|---|
| 390 | link_sta->status_stats.msdu_failed[tid]; | 
|---|
| 391 | } | 
|---|
| 392 |  | 
|---|
| 393 | if (sta->sdata->vif.type == NL80211_IFTYPE_STATION) { | 
|---|
| 394 | link = wiphy_dereference(sta->sdata->local->hw.wiphy, | 
|---|
| 395 | sta->sdata->link[link_id]); | 
|---|
| 396 | if (link) | 
|---|
| 397 | sta->rem_link_stats.beacon_loss_count += | 
|---|
| 398 | link->u.mgd.beacon_loss_count; | 
|---|
| 399 | } | 
|---|
| 400 | } | 
|---|
| 401 |  | 
|---|
| 402 | static void sta_remove_link(struct sta_info *sta, unsigned int link_id, | 
|---|
| 403 | bool unhash) | 
|---|
| 404 | { | 
|---|
| 405 | struct sta_link_alloc *alloc = NULL; | 
|---|
| 406 | struct link_sta_info *link_sta; | 
|---|
| 407 |  | 
|---|
| 408 | lockdep_assert_wiphy(sta->local->hw.wiphy); | 
|---|
| 409 |  | 
|---|
| 410 | link_sta = rcu_access_pointer(sta->link[link_id]); | 
|---|
| 411 | if (WARN_ON(!link_sta)) | 
|---|
| 412 | return; | 
|---|
| 413 |  | 
|---|
| 414 | if (unhash) | 
|---|
| 415 | link_sta_info_hash_del(local: sta->local, link_sta); | 
|---|
| 416 |  | 
|---|
| 417 | if (test_sta_flag(sta, flag: WLAN_STA_INSERTED)) | 
|---|
| 418 | ieee80211_link_sta_debugfs_remove(link_sta); | 
|---|
| 419 |  | 
|---|
| 420 | if (link_sta != &sta->deflink) | 
|---|
| 421 | alloc = container_of(link_sta, typeof(*alloc), info); | 
|---|
| 422 |  | 
|---|
| 423 | sta->sta.valid_links &= ~BIT(link_id); | 
|---|
| 424 |  | 
|---|
| 425 | /* store removed link info for accumulated stats consistency */ | 
|---|
| 426 | sta_accumulate_removed_link_stats(sta, link_id); | 
|---|
| 427 |  | 
|---|
| 428 | RCU_INIT_POINTER(sta->link[link_id], NULL); | 
|---|
| 429 | RCU_INIT_POINTER(sta->sta.link[link_id], NULL); | 
|---|
| 430 | if (alloc) { | 
|---|
| 431 | sta_info_free_link(link_sta: &alloc->info); | 
|---|
| 432 | kfree_rcu(alloc, rcu_head); | 
|---|
| 433 | } | 
|---|
| 434 |  | 
|---|
| 435 | ieee80211_sta_recalc_aggregates(pubsta: &sta->sta); | 
|---|
| 436 | } | 
|---|
| 437 |  | 
|---|
| 438 | /** | 
|---|
| 439 | * sta_info_free - free STA | 
|---|
| 440 | * | 
|---|
| 441 | * @local: pointer to the global information | 
|---|
| 442 | * @sta: STA info to free | 
|---|
| 443 | * | 
|---|
| 444 | * This function must undo everything done by sta_info_alloc() | 
|---|
| 445 | * that may happen before sta_info_insert(). It may only be | 
|---|
| 446 | * called when sta_info_insert() has not been attempted (and | 
|---|
| 447 | * if that fails, the station is freed anyway.) | 
|---|
| 448 | */ | 
|---|
| 449 | void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) | 
|---|
| 450 | { | 
|---|
| 451 | int i; | 
|---|
| 452 |  | 
|---|
| 453 | for (i = 0; i < ARRAY_SIZE(sta->link); i++) { | 
|---|
| 454 | struct link_sta_info *link_sta; | 
|---|
| 455 |  | 
|---|
| 456 | link_sta = rcu_access_pointer(sta->link[i]); | 
|---|
| 457 | if (!link_sta) | 
|---|
| 458 | continue; | 
|---|
| 459 |  | 
|---|
| 460 | sta_remove_link(sta, link_id: i, unhash: false); | 
|---|
| 461 | } | 
|---|
| 462 |  | 
|---|
| 463 | /* | 
|---|
| 464 | * If we had used sta_info_pre_move_state() then we might not | 
|---|
| 465 | * have gone through the state transitions down again, so do | 
|---|
| 466 | * it here now (and warn if it's inserted). | 
|---|
| 467 | * | 
|---|
| 468 | * This will clear state such as fast TX/RX that may have been | 
|---|
| 469 | * allocated during state transitions. | 
|---|
| 470 | */ | 
|---|
| 471 | while (sta->sta_state > IEEE80211_STA_NONE) { | 
|---|
| 472 | int ret; | 
|---|
| 473 |  | 
|---|
| 474 | WARN_ON_ONCE(test_sta_flag(sta, WLAN_STA_INSERTED)); | 
|---|
| 475 |  | 
|---|
| 476 | ret = sta_info_move_state(sta, new_state: sta->sta_state - 1); | 
|---|
| 477 | if (WARN_ONCE(ret, "sta_info_move_state() returned %d\n", ret)) | 
|---|
| 478 | break; | 
|---|
| 479 | } | 
|---|
| 480 |  | 
|---|
| 481 | if (sta->rate_ctrl) | 
|---|
| 482 | rate_control_free_sta(sta); | 
|---|
| 483 |  | 
|---|
| 484 | sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); | 
|---|
| 485 |  | 
|---|
| 486 | kfree(objp: to_txq_info(txq: sta->sta.txq[0])); | 
|---|
| 487 | kfree(rcu_dereference_raw(sta->sta.rates)); | 
|---|
| 488 | #ifdef CONFIG_MAC80211_MESH | 
|---|
| 489 | kfree(sta->mesh); | 
|---|
| 490 | #endif | 
|---|
| 491 |  | 
|---|
| 492 | sta_info_free_link(link_sta: &sta->deflink); | 
|---|
| 493 | kfree(objp: sta); | 
|---|
| 494 | } | 
|---|
| 495 |  | 
|---|
| 496 | static int sta_info_hash_add(struct ieee80211_local *local, | 
|---|
| 497 | struct sta_info *sta) | 
|---|
| 498 | { | 
|---|
| 499 | return rhltable_insert(hlt: &local->sta_hash, list: &sta->hash_node, | 
|---|
| 500 | params: sta_rht_params); | 
|---|
| 501 | } | 
|---|
| 502 |  | 
|---|
| 503 | static void sta_deliver_ps_frames(struct work_struct *wk) | 
|---|
| 504 | { | 
|---|
| 505 | struct sta_info *sta; | 
|---|
| 506 |  | 
|---|
| 507 | sta = container_of(wk, struct sta_info, drv_deliver_wk); | 
|---|
| 508 |  | 
|---|
| 509 | if (sta->dead) | 
|---|
| 510 | return; | 
|---|
| 511 |  | 
|---|
| 512 | local_bh_disable(); | 
|---|
| 513 | if (!test_sta_flag(sta, flag: WLAN_STA_PS_STA)) | 
|---|
| 514 | ieee80211_sta_ps_deliver_wakeup(sta); | 
|---|
| 515 | else if (test_and_clear_sta_flag(sta, flag: WLAN_STA_PSPOLL)) | 
|---|
| 516 | ieee80211_sta_ps_deliver_poll_response(sta); | 
|---|
| 517 | else if (test_and_clear_sta_flag(sta, flag: WLAN_STA_UAPSD)) | 
|---|
| 518 | ieee80211_sta_ps_deliver_uapsd(sta); | 
|---|
| 519 | local_bh_enable(); | 
|---|
| 520 | } | 
|---|
| 521 |  | 
|---|
| 522 | static int sta_prepare_rate_control(struct ieee80211_local *local, | 
|---|
| 523 | struct sta_info *sta, gfp_t gfp) | 
|---|
| 524 | { | 
|---|
| 525 | if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) | 
|---|
| 526 | return 0; | 
|---|
| 527 |  | 
|---|
| 528 | sta->rate_ctrl = local->rate_ctrl; | 
|---|
| 529 | sta->rate_ctrl_priv = rate_control_alloc_sta(ref: sta->rate_ctrl, | 
|---|
| 530 | sta, gfp); | 
|---|
| 531 | if (!sta->rate_ctrl_priv) | 
|---|
| 532 | return -ENOMEM; | 
|---|
| 533 |  | 
|---|
| 534 | return 0; | 
|---|
| 535 | } | 
|---|
| 536 |  | 
|---|
| 537 | static int sta_info_alloc_link(struct ieee80211_local *local, | 
|---|
| 538 | struct link_sta_info *link_info, | 
|---|
| 539 | gfp_t gfp) | 
|---|
| 540 | { | 
|---|
| 541 | struct ieee80211_hw *hw = &local->hw; | 
|---|
| 542 | int i; | 
|---|
| 543 |  | 
|---|
| 544 | if (ieee80211_hw_check(hw, USES_RSS)) { | 
|---|
| 545 | link_info->pcpu_rx_stats = | 
|---|
| 546 | alloc_percpu_gfp(struct ieee80211_sta_rx_stats, gfp); | 
|---|
| 547 | if (!link_info->pcpu_rx_stats) | 
|---|
| 548 | return -ENOMEM; | 
|---|
| 549 | } | 
|---|
| 550 |  | 
|---|
| 551 | link_info->rx_stats.last_rx = jiffies; | 
|---|
| 552 | u64_stats_init(syncp: &link_info->rx_stats.syncp); | 
|---|
| 553 |  | 
|---|
| 554 | ewma_signal_init(e: &link_info->rx_stats_avg.signal); | 
|---|
| 555 | ewma_avg_signal_init(e: &link_info->status_stats.avg_ack_signal); | 
|---|
| 556 | for (i = 0; i < ARRAY_SIZE(link_info->rx_stats_avg.chain_signal); i++) | 
|---|
| 557 | ewma_signal_init(e: &link_info->rx_stats_avg.chain_signal[i]); | 
|---|
| 558 |  | 
|---|
| 559 | link_info->rx_omi_bw_rx = IEEE80211_STA_RX_BW_MAX; | 
|---|
| 560 | link_info->rx_omi_bw_tx = IEEE80211_STA_RX_BW_MAX; | 
|---|
| 561 | link_info->rx_omi_bw_staging = IEEE80211_STA_RX_BW_MAX; | 
|---|
| 562 |  | 
|---|
| 563 | /* | 
|---|
| 564 | * Cause (a) warning(s) if IEEE80211_STA_RX_BW_MAX != 320 | 
|---|
| 565 | * or if new values are added to the enum. | 
|---|
| 566 | */ | 
|---|
| 567 | switch (link_info->cur_max_bandwidth) { | 
|---|
| 568 | case IEEE80211_STA_RX_BW_20: | 
|---|
| 569 | case IEEE80211_STA_RX_BW_40: | 
|---|
| 570 | case IEEE80211_STA_RX_BW_80: | 
|---|
| 571 | case IEEE80211_STA_RX_BW_160: | 
|---|
| 572 | case IEEE80211_STA_RX_BW_MAX: | 
|---|
| 573 | /* intentionally nothing */ | 
|---|
| 574 | break; | 
|---|
| 575 | } | 
|---|
| 576 |  | 
|---|
| 577 | return 0; | 
|---|
| 578 | } | 
|---|
| 579 |  | 
|---|
| 580 | static void sta_info_add_link(struct sta_info *sta, | 
|---|
| 581 | unsigned int link_id, | 
|---|
| 582 | struct link_sta_info *link_info, | 
|---|
| 583 | struct ieee80211_link_sta *link_sta) | 
|---|
| 584 | { | 
|---|
| 585 | link_info->sta = sta; | 
|---|
| 586 | link_info->link_id = link_id; | 
|---|
| 587 | link_info->pub = link_sta; | 
|---|
| 588 | link_info->pub->sta = &sta->sta; | 
|---|
| 589 | link_sta->link_id = link_id; | 
|---|
| 590 | rcu_assign_pointer(sta->link[link_id], link_info); | 
|---|
| 591 | rcu_assign_pointer(sta->sta.link[link_id], link_sta); | 
|---|
| 592 |  | 
|---|
| 593 | link_sta->smps_mode = IEEE80211_SMPS_OFF; | 
|---|
| 594 | link_sta->agg.max_rc_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA; | 
|---|
| 595 | } | 
|---|
| 596 |  | 
|---|
| 597 | static struct sta_info * | 
|---|
| 598 | __sta_info_alloc(struct ieee80211_sub_if_data *sdata, | 
|---|
| 599 | const u8 *addr, int link_id, const u8 *link_addr, | 
|---|
| 600 | gfp_t gfp) | 
|---|
| 601 | { | 
|---|
| 602 | struct ieee80211_local *local = sdata->local; | 
|---|
| 603 | struct ieee80211_hw *hw = &local->hw; | 
|---|
| 604 | struct sta_info *sta; | 
|---|
| 605 | void *txq_data; | 
|---|
| 606 | int size; | 
|---|
| 607 | int i; | 
|---|
| 608 |  | 
|---|
| 609 | sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); | 
|---|
| 610 | if (!sta) | 
|---|
| 611 | return NULL; | 
|---|
| 612 |  | 
|---|
| 613 | sta->local = local; | 
|---|
| 614 | sta->sdata = sdata; | 
|---|
| 615 |  | 
|---|
| 616 | if (sta_info_alloc_link(local, link_info: &sta->deflink, gfp)) | 
|---|
| 617 | goto free; | 
|---|
| 618 |  | 
|---|
| 619 | if (link_id >= 0) { | 
|---|
| 620 | sta_info_add_link(sta, link_id, link_info: &sta->deflink, | 
|---|
| 621 | link_sta: &sta->sta.deflink); | 
|---|
| 622 | sta->sta.valid_links = BIT(link_id); | 
|---|
| 623 | } else { | 
|---|
| 624 | sta_info_add_link(sta, link_id: 0, link_info: &sta->deflink, link_sta: &sta->sta.deflink); | 
|---|
| 625 | } | 
|---|
| 626 |  | 
|---|
| 627 | sta->sta.cur = &sta->sta.deflink.agg; | 
|---|
| 628 |  | 
|---|
| 629 | spin_lock_init(&sta->lock); | 
|---|
| 630 | spin_lock_init(&sta->ps_lock); | 
|---|
| 631 | INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); | 
|---|
| 632 | wiphy_work_init(work: &sta->ampdu_mlme.work, func: ieee80211_ba_session_work); | 
|---|
| 633 | #ifdef CONFIG_MAC80211_MESH | 
|---|
| 634 | if (ieee80211_vif_is_mesh(&sdata->vif)) { | 
|---|
| 635 | sta->mesh = kzalloc(sizeof(*sta->mesh), gfp); | 
|---|
| 636 | if (!sta->mesh) | 
|---|
| 637 | goto free; | 
|---|
| 638 | sta->mesh->plink_sta = sta; | 
|---|
| 639 | spin_lock_init(&sta->mesh->plink_lock); | 
|---|
| 640 | if (!sdata->u.mesh.user_mpm) | 
|---|
| 641 | timer_setup(&sta->mesh->plink_timer, mesh_plink_timer, | 
|---|
| 642 | 0); | 
|---|
| 643 | sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE; | 
|---|
| 644 | } | 
|---|
| 645 | #endif | 
|---|
| 646 |  | 
|---|
| 647 | memcpy(to: sta->addr, from: addr, ETH_ALEN); | 
|---|
| 648 | memcpy(to: sta->sta.addr, from: addr, ETH_ALEN); | 
|---|
| 649 | memcpy(to: sta->deflink.addr, from: link_addr, ETH_ALEN); | 
|---|
| 650 | memcpy(to: sta->sta.deflink.addr, from: link_addr, ETH_ALEN); | 
|---|
| 651 | sta->sta.max_rx_aggregation_subframes = | 
|---|
| 652 | local->hw.max_rx_aggregation_subframes; | 
|---|
| 653 |  | 
|---|
| 654 | /* TODO link specific alloc and assignments for MLO Link STA */ | 
|---|
| 655 |  | 
|---|
| 656 | /* Extended Key ID needs to install keys for keyid 0 and 1 Rx-only. | 
|---|
| 657 | * The Tx path starts to use a key as soon as the key slot ptk_idx | 
|---|
| 658 | * references to is not NULL. To not use the initial Rx-only key | 
|---|
| 659 | * prematurely for Tx initialize ptk_idx to an impossible PTK keyid | 
|---|
| 660 | * which always will refer to a NULL key. | 
|---|
| 661 | */ | 
|---|
| 662 | BUILD_BUG_ON(ARRAY_SIZE(sta->ptk) <= INVALID_PTK_KEYIDX); | 
|---|
| 663 | sta->ptk_idx = INVALID_PTK_KEYIDX; | 
|---|
| 664 |  | 
|---|
| 665 |  | 
|---|
| 666 | ieee80211_init_frag_cache(cache: &sta->frags); | 
|---|
| 667 |  | 
|---|
| 668 | sta->sta_state = IEEE80211_STA_NONE; | 
|---|
| 669 |  | 
|---|
| 670 | if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) | 
|---|
| 671 | sta->amsdu_mesh_control = -1; | 
|---|
| 672 |  | 
|---|
| 673 | /* Mark TID as unreserved */ | 
|---|
| 674 | sta->reserved_tid = IEEE80211_TID_UNRESERVED; | 
|---|
| 675 |  | 
|---|
| 676 | sta->last_connected = ktime_get_seconds(); | 
|---|
| 677 |  | 
|---|
| 678 | size = sizeof(struct txq_info) + | 
|---|
| 679 | ALIGN(hw->txq_data_size, sizeof(void *)); | 
|---|
| 680 |  | 
|---|
| 681 | txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp); | 
|---|
| 682 | if (!txq_data) | 
|---|
| 683 | goto free; | 
|---|
| 684 |  | 
|---|
| 685 | for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { | 
|---|
| 686 | struct txq_info *txq = txq_data + i * size; | 
|---|
| 687 |  | 
|---|
| 688 | /* might not do anything for the (bufferable) MMPDU TXQ */ | 
|---|
| 689 | ieee80211_txq_init(sdata, sta, txq, tid: i); | 
|---|
| 690 | } | 
|---|
| 691 |  | 
|---|
| 692 | if (sta_prepare_rate_control(local, sta, gfp)) | 
|---|
| 693 | goto free_txq; | 
|---|
| 694 |  | 
|---|
| 695 | sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT; | 
|---|
| 696 |  | 
|---|
| 697 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { | 
|---|
| 698 | skb_queue_head_init(list: &sta->ps_tx_buf[i]); | 
|---|
| 699 | skb_queue_head_init(list: &sta->tx_filtered[i]); | 
|---|
| 700 | sta->airtime[i].deficit = sta->airtime_weight; | 
|---|
| 701 | atomic_set(v: &sta->airtime[i].aql_tx_pending, i: 0); | 
|---|
| 702 | sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i]; | 
|---|
| 703 | sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i]; | 
|---|
| 704 | } | 
|---|
| 705 |  | 
|---|
| 706 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | 
|---|
| 707 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 
|---|
| 708 |  | 
|---|
| 709 | for (i = 0; i < NUM_NL80211_BANDS; i++) { | 
|---|
| 710 | u32 mandatory = 0; | 
|---|
| 711 | int r; | 
|---|
| 712 |  | 
|---|
| 713 | if (!hw->wiphy->bands[i]) | 
|---|
| 714 | continue; | 
|---|
| 715 |  | 
|---|
| 716 | switch (i) { | 
|---|
| 717 | case NL80211_BAND_2GHZ: | 
|---|
| 718 | case NL80211_BAND_LC: | 
|---|
| 719 | /* | 
|---|
| 720 | * We use both here, even if we cannot really know for | 
|---|
| 721 | * sure the station will support both, but the only use | 
|---|
| 722 | * for this is when we don't know anything yet and send | 
|---|
| 723 | * management frames, and then we'll pick the lowest | 
|---|
| 724 | * possible rate anyway. | 
|---|
| 725 | * If we don't include _G here, we cannot find a rate | 
|---|
| 726 | * in P2P, and thus trigger the WARN_ONCE() in rate.c | 
|---|
| 727 | */ | 
|---|
| 728 | mandatory = IEEE80211_RATE_MANDATORY_B | | 
|---|
| 729 | IEEE80211_RATE_MANDATORY_G; | 
|---|
| 730 | break; | 
|---|
| 731 | case NL80211_BAND_5GHZ: | 
|---|
| 732 | case NL80211_BAND_6GHZ: | 
|---|
| 733 | mandatory = IEEE80211_RATE_MANDATORY_A; | 
|---|
| 734 | break; | 
|---|
| 735 | case NL80211_BAND_60GHZ: | 
|---|
| 736 | WARN_ON(1); | 
|---|
| 737 | mandatory = 0; | 
|---|
| 738 | break; | 
|---|
| 739 | } | 
|---|
| 740 |  | 
|---|
| 741 | for (r = 0; r < hw->wiphy->bands[i]->n_bitrates; r++) { | 
|---|
| 742 | struct ieee80211_rate *rate; | 
|---|
| 743 |  | 
|---|
| 744 | rate = &hw->wiphy->bands[i]->bitrates[r]; | 
|---|
| 745 |  | 
|---|
| 746 | if (!(rate->flags & mandatory)) | 
|---|
| 747 | continue; | 
|---|
| 748 | sta->sta.deflink.supp_rates[i] |= BIT(r); | 
|---|
| 749 | } | 
|---|
| 750 | } | 
|---|
| 751 |  | 
|---|
| 752 |  | 
|---|
| 753 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); | 
|---|
| 754 |  | 
|---|
| 755 | return sta; | 
|---|
| 756 |  | 
|---|
| 757 | free_txq: | 
|---|
| 758 | kfree(objp: to_txq_info(txq: sta->sta.txq[0])); | 
|---|
| 759 | free: | 
|---|
| 760 | sta_info_free_link(link_sta: &sta->deflink); | 
|---|
| 761 | #ifdef CONFIG_MAC80211_MESH | 
|---|
| 762 | kfree(sta->mesh); | 
|---|
| 763 | #endif | 
|---|
| 764 | kfree(objp: sta); | 
|---|
| 765 | return NULL; | 
|---|
| 766 | } | 
|---|
| 767 |  | 
|---|
| 768 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | 
|---|
| 769 | const u8 *addr, gfp_t gfp) | 
|---|
| 770 | { | 
|---|
| 771 | return __sta_info_alloc(sdata, addr, link_id: -1, link_addr: addr, gfp); | 
|---|
| 772 | } | 
|---|
| 773 |  | 
|---|
| 774 | struct sta_info *sta_info_alloc_with_link(struct ieee80211_sub_if_data *sdata, | 
|---|
| 775 | const u8 *mld_addr, | 
|---|
| 776 | unsigned int link_id, | 
|---|
| 777 | const u8 *link_addr, | 
|---|
| 778 | gfp_t gfp) | 
|---|
| 779 | { | 
|---|
| 780 | return __sta_info_alloc(sdata, addr: mld_addr, link_id, link_addr, gfp); | 
|---|
| 781 | } | 
|---|
| 782 |  | 
|---|
| 783 | static int sta_info_insert_check(struct sta_info *sta) | 
|---|
| 784 | { | 
|---|
| 785 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 786 |  | 
|---|
| 787 | lockdep_assert_wiphy(sdata->local->hw.wiphy); | 
|---|
| 788 |  | 
|---|
| 789 | /* | 
|---|
| 790 | * Can't be a WARN_ON because it can be triggered through a race: | 
|---|
| 791 | * something inserts a STA (on one CPU) without holding the RTNL | 
|---|
| 792 | * and another CPU turns off the net device. | 
|---|
| 793 | */ | 
|---|
| 794 | if (unlikely(!ieee80211_sdata_running(sdata))) | 
|---|
| 795 | return -ENETDOWN; | 
|---|
| 796 |  | 
|---|
| 797 | if (WARN_ON(ether_addr_equal(sta->sta.addr, sdata->vif.addr) || | 
|---|
| 798 | !is_valid_ether_addr(sta->sta.addr))) | 
|---|
| 799 | return -EINVAL; | 
|---|
| 800 |  | 
|---|
| 801 | /* The RCU read lock is required by rhashtable due to | 
|---|
| 802 | * asynchronous resize/rehash.  We also require the mutex | 
|---|
| 803 | * for correctness. | 
|---|
| 804 | */ | 
|---|
| 805 | rcu_read_lock(); | 
|---|
| 806 | if (ieee80211_hw_check(&sdata->local->hw, NEEDS_UNIQUE_STA_ADDR) && | 
|---|
| 807 | ieee80211_find_sta_by_ifaddr(hw: &sdata->local->hw, addr: sta->addr, NULL)) { | 
|---|
| 808 | rcu_read_unlock(); | 
|---|
| 809 | return -ENOTUNIQ; | 
|---|
| 810 | } | 
|---|
| 811 | rcu_read_unlock(); | 
|---|
| 812 |  | 
|---|
| 813 | return 0; | 
|---|
| 814 | } | 
|---|
| 815 |  | 
|---|
| 816 | static int sta_info_insert_drv_state(struct ieee80211_local *local, | 
|---|
| 817 | struct ieee80211_sub_if_data *sdata, | 
|---|
| 818 | struct sta_info *sta) | 
|---|
| 819 | { | 
|---|
| 820 | enum ieee80211_sta_state state; | 
|---|
| 821 | int err = 0; | 
|---|
| 822 |  | 
|---|
| 823 | for (state = IEEE80211_STA_NOTEXIST; state < sta->sta_state; state++) { | 
|---|
| 824 | err = drv_sta_state(local, sdata, sta, old_state: state, new_state: state + 1); | 
|---|
| 825 | if (err) | 
|---|
| 826 | break; | 
|---|
| 827 | } | 
|---|
| 828 |  | 
|---|
| 829 | if (!err) { | 
|---|
| 830 | /* | 
|---|
| 831 | * Drivers using legacy sta_add/sta_remove callbacks only | 
|---|
| 832 | * get uploaded set to true after sta_add is called. | 
|---|
| 833 | */ | 
|---|
| 834 | if (!local->ops->sta_add) | 
|---|
| 835 | sta->uploaded = true; | 
|---|
| 836 | return 0; | 
|---|
| 837 | } | 
|---|
| 838 |  | 
|---|
| 839 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 
|---|
| 840 | sdata_info(sdata, | 
|---|
| 841 | "failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", | 
|---|
| 842 | sta->sta.addr, state + 1, err); | 
|---|
| 843 | err = 0; | 
|---|
| 844 | } | 
|---|
| 845 |  | 
|---|
| 846 | /* unwind on error */ | 
|---|
| 847 | for (; state > IEEE80211_STA_NOTEXIST; state--) | 
|---|
| 848 | WARN_ON(drv_sta_state(local, sdata, sta, state, state - 1)); | 
|---|
| 849 |  | 
|---|
| 850 | return err; | 
|---|
| 851 | } | 
|---|
| 852 |  | 
|---|
| 853 | static void | 
|---|
| 854 | ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata) | 
|---|
| 855 | { | 
|---|
| 856 | struct ieee80211_local *local = sdata->local; | 
|---|
| 857 | bool allow_p2p_go_ps = sdata->vif.p2p; | 
|---|
| 858 | struct sta_info *sta; | 
|---|
| 859 |  | 
|---|
| 860 | rcu_read_lock(); | 
|---|
| 861 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | 
|---|
| 862 | if (sdata != sta->sdata || | 
|---|
| 863 | !test_sta_flag(sta, flag: WLAN_STA_ASSOC)) | 
|---|
| 864 | continue; | 
|---|
| 865 | if (!sta->sta.support_p2p_ps) { | 
|---|
| 866 | allow_p2p_go_ps = false; | 
|---|
| 867 | break; | 
|---|
| 868 | } | 
|---|
| 869 | } | 
|---|
| 870 | rcu_read_unlock(); | 
|---|
| 871 |  | 
|---|
| 872 | if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) { | 
|---|
| 873 | sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps; | 
|---|
| 874 | ieee80211_link_info_change_notify(sdata, link: &sdata->deflink, | 
|---|
| 875 | changed: BSS_CHANGED_P2P_PS); | 
|---|
| 876 | } | 
|---|
| 877 | } | 
|---|
| 878 |  | 
|---|
| 879 | static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | 
|---|
| 880 | { | 
|---|
| 881 | struct ieee80211_local *local = sta->local; | 
|---|
| 882 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 883 | struct station_info *sinfo = NULL; | 
|---|
| 884 | int err = 0; | 
|---|
| 885 |  | 
|---|
| 886 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 887 |  | 
|---|
| 888 | /* check if STA exists already */ | 
|---|
| 889 | if (sta_info_get_bss(sdata, addr: sta->sta.addr)) { | 
|---|
| 890 | err = -EEXIST; | 
|---|
| 891 | goto out_cleanup; | 
|---|
| 892 | } | 
|---|
| 893 |  | 
|---|
| 894 | sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL); | 
|---|
| 895 | if (!sinfo) { | 
|---|
| 896 | err = -ENOMEM; | 
|---|
| 897 | goto out_cleanup; | 
|---|
| 898 | } | 
|---|
| 899 |  | 
|---|
| 900 | local->num_sta++; | 
|---|
| 901 | local->sta_generation++; | 
|---|
| 902 | smp_mb(); | 
|---|
| 903 |  | 
|---|
| 904 | /* simplify things and don't accept BA sessions yet */ | 
|---|
| 905 | set_sta_flag(sta, flag: WLAN_STA_BLOCK_BA); | 
|---|
| 906 |  | 
|---|
| 907 | /* make the station visible */ | 
|---|
| 908 | err = sta_info_hash_add(local, sta); | 
|---|
| 909 | if (err) | 
|---|
| 910 | goto out_drop_sta; | 
|---|
| 911 |  | 
|---|
| 912 | if (sta->sta.valid_links) { | 
|---|
| 913 | err = link_sta_info_hash_add(local, link_sta: &sta->deflink); | 
|---|
| 914 | if (err) { | 
|---|
| 915 | sta_info_hash_del(local, sta); | 
|---|
| 916 | goto out_drop_sta; | 
|---|
| 917 | } | 
|---|
| 918 | } | 
|---|
| 919 |  | 
|---|
| 920 | list_add_tail_rcu(new: &sta->list, head: &local->sta_list); | 
|---|
| 921 |  | 
|---|
| 922 | /* update channel context before notifying the driver about state | 
|---|
| 923 | * change, this enables driver using the updated channel context right away. | 
|---|
| 924 | */ | 
|---|
| 925 | if (sta->sta_state >= IEEE80211_STA_ASSOC) { | 
|---|
| 926 | ieee80211_recalc_min_chandef(sdata: sta->sdata, link_id: -1); | 
|---|
| 927 | if (!sta->sta.support_p2p_ps) | 
|---|
| 928 | ieee80211_recalc_p2p_go_ps_allowed(sdata: sta->sdata); | 
|---|
| 929 | } | 
|---|
| 930 |  | 
|---|
| 931 | /* notify driver */ | 
|---|
| 932 | err = sta_info_insert_drv_state(local, sdata, sta); | 
|---|
| 933 | if (err) | 
|---|
| 934 | goto out_remove; | 
|---|
| 935 |  | 
|---|
| 936 | set_sta_flag(sta, flag: WLAN_STA_INSERTED); | 
|---|
| 937 |  | 
|---|
| 938 | /* accept BA sessions now */ | 
|---|
| 939 | clear_sta_flag(sta, flag: WLAN_STA_BLOCK_BA); | 
|---|
| 940 |  | 
|---|
| 941 | ieee80211_sta_debugfs_add(sta); | 
|---|
| 942 | rate_control_add_sta_debugfs(sta); | 
|---|
| 943 | if (sta->sta.valid_links) { | 
|---|
| 944 | int i; | 
|---|
| 945 |  | 
|---|
| 946 | for (i = 0; i < ARRAY_SIZE(sta->link); i++) { | 
|---|
| 947 | struct link_sta_info *link_sta; | 
|---|
| 948 |  | 
|---|
| 949 | link_sta = rcu_dereference_protected(sta->link[i], | 
|---|
| 950 | lockdep_is_held(&local->hw.wiphy->mtx)); | 
|---|
| 951 |  | 
|---|
| 952 | if (!link_sta) | 
|---|
| 953 | continue; | 
|---|
| 954 |  | 
|---|
| 955 | ieee80211_link_sta_debugfs_add(link_sta); | 
|---|
| 956 | if (sdata->vif.active_links & BIT(i)) | 
|---|
| 957 | ieee80211_link_sta_debugfs_drv_add(link_sta); | 
|---|
| 958 | } | 
|---|
| 959 | } else { | 
|---|
| 960 | ieee80211_link_sta_debugfs_add(link_sta: &sta->deflink); | 
|---|
| 961 | ieee80211_link_sta_debugfs_drv_add(link_sta: &sta->deflink); | 
|---|
| 962 | } | 
|---|
| 963 |  | 
|---|
| 964 | sinfo->generation = local->sta_generation; | 
|---|
| 965 | cfg80211_new_sta(dev: sdata->dev, mac_addr: sta->sta.addr, sinfo, GFP_KERNEL); | 
|---|
| 966 | kfree(objp: sinfo); | 
|---|
| 967 |  | 
|---|
| 968 | sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr); | 
|---|
| 969 |  | 
|---|
| 970 | /* move reference to rcu-protected */ | 
|---|
| 971 | rcu_read_lock(); | 
|---|
| 972 |  | 
|---|
| 973 | if (ieee80211_vif_is_mesh(vif: &sdata->vif)) | 
|---|
| 974 | mesh_accept_plinks_update(sdata); | 
|---|
| 975 |  | 
|---|
| 976 | ieee80211_check_fast_xmit(sta); | 
|---|
| 977 |  | 
|---|
| 978 | return 0; | 
|---|
| 979 | out_remove: | 
|---|
| 980 | if (sta->sta.valid_links) | 
|---|
| 981 | link_sta_info_hash_del(local, link_sta: &sta->deflink); | 
|---|
| 982 | sta_info_hash_del(local, sta); | 
|---|
| 983 | list_del_rcu(entry: &sta->list); | 
|---|
| 984 | out_drop_sta: | 
|---|
| 985 | local->num_sta--; | 
|---|
| 986 | synchronize_net(); | 
|---|
| 987 | out_cleanup: | 
|---|
| 988 | cleanup_single_sta(sta); | 
|---|
| 989 | kfree(objp: sinfo); | 
|---|
| 990 | rcu_read_lock(); | 
|---|
| 991 | return err; | 
|---|
| 992 | } | 
|---|
| 993 |  | 
|---|
| 994 | int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) | 
|---|
| 995 | { | 
|---|
| 996 | struct ieee80211_local *local = sta->local; | 
|---|
| 997 | int err; | 
|---|
| 998 |  | 
|---|
| 999 | might_sleep(); | 
|---|
| 1000 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 1001 |  | 
|---|
| 1002 | err = sta_info_insert_check(sta); | 
|---|
| 1003 | if (err) { | 
|---|
| 1004 | sta_info_free(local, sta); | 
|---|
| 1005 | rcu_read_lock(); | 
|---|
| 1006 | return err; | 
|---|
| 1007 | } | 
|---|
| 1008 |  | 
|---|
| 1009 | return sta_info_insert_finish(sta); | 
|---|
| 1010 | } | 
|---|
| 1011 |  | 
|---|
| 1012 | int sta_info_insert(struct sta_info *sta) | 
|---|
| 1013 | { | 
|---|
| 1014 | int err = sta_info_insert_rcu(sta); | 
|---|
| 1015 |  | 
|---|
| 1016 | rcu_read_unlock(); | 
|---|
| 1017 |  | 
|---|
| 1018 | return err; | 
|---|
| 1019 | } | 
|---|
| 1020 |  | 
|---|
| 1021 | static inline void __bss_tim_set(u8 *tim, u16 id) | 
|---|
| 1022 | { | 
|---|
| 1023 | /* | 
|---|
| 1024 | * This format has been mandated by the IEEE specifications, | 
|---|
| 1025 | * so this line may not be changed to use the __set_bit() format. | 
|---|
| 1026 | */ | 
|---|
| 1027 | tim[id / 8] |= (1 << (id % 8)); | 
|---|
| 1028 | } | 
|---|
| 1029 |  | 
|---|
| 1030 | static inline void __bss_tim_clear(u8 *tim, u16 id) | 
|---|
| 1031 | { | 
|---|
| 1032 | /* | 
|---|
| 1033 | * This format has been mandated by the IEEE specifications, | 
|---|
| 1034 | * so this line may not be changed to use the __clear_bit() format. | 
|---|
| 1035 | */ | 
|---|
| 1036 | tim[id / 8] &= ~(1 << (id % 8)); | 
|---|
| 1037 | } | 
|---|
| 1038 |  | 
|---|
| 1039 | static inline bool __bss_tim_get(u8 *tim, u16 id) | 
|---|
| 1040 | { | 
|---|
| 1041 | /* | 
|---|
| 1042 | * This format has been mandated by the IEEE specifications, | 
|---|
| 1043 | * so this line may not be changed to use the test_bit() format. | 
|---|
| 1044 | */ | 
|---|
| 1045 | return tim[id / 8] & (1 << (id % 8)); | 
|---|
| 1046 | } | 
|---|
| 1047 |  | 
|---|
| 1048 | static unsigned long ieee80211_tids_for_ac(int ac) | 
|---|
| 1049 | { | 
|---|
| 1050 | /* If we ever support TIDs > 7, this obviously needs to be adjusted */ | 
|---|
| 1051 | switch (ac) { | 
|---|
| 1052 | case IEEE80211_AC_VO: | 
|---|
| 1053 | return BIT(6) | BIT(7); | 
|---|
| 1054 | case IEEE80211_AC_VI: | 
|---|
| 1055 | return BIT(4) | BIT(5); | 
|---|
| 1056 | case IEEE80211_AC_BE: | 
|---|
| 1057 | return BIT(0) | BIT(3); | 
|---|
| 1058 | case IEEE80211_AC_BK: | 
|---|
| 1059 | return BIT(1) | BIT(2); | 
|---|
| 1060 | default: | 
|---|
| 1061 | WARN_ON(1); | 
|---|
| 1062 | return 0; | 
|---|
| 1063 | } | 
|---|
| 1064 | } | 
|---|
| 1065 |  | 
|---|
| 1066 | static void __sta_info_recalc_tim(struct sta_info *sta, bool ignore_pending) | 
|---|
| 1067 | { | 
|---|
| 1068 | struct ieee80211_local *local = sta->local; | 
|---|
| 1069 | struct ps_data *ps; | 
|---|
| 1070 | bool indicate_tim = false; | 
|---|
| 1071 | u8 ignore_for_tim = sta->sta.uapsd_queues; | 
|---|
| 1072 | int ac; | 
|---|
| 1073 | u16 id = sta->sta.aid; | 
|---|
| 1074 |  | 
|---|
| 1075 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || | 
|---|
| 1076 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | 
|---|
| 1077 | if (WARN_ON_ONCE(!sta->sdata->bss)) | 
|---|
| 1078 | return; | 
|---|
| 1079 |  | 
|---|
| 1080 | ps = &sta->sdata->bss->ps; | 
|---|
| 1081 | #ifdef CONFIG_MAC80211_MESH | 
|---|
| 1082 | } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) { | 
|---|
| 1083 | ps = &sta->sdata->u.mesh.ps; | 
|---|
| 1084 | #endif | 
|---|
| 1085 | } else { | 
|---|
| 1086 | return; | 
|---|
| 1087 | } | 
|---|
| 1088 |  | 
|---|
| 1089 | /* No need to do anything if the driver does all */ | 
|---|
| 1090 | if (ieee80211_hw_check(&local->hw, AP_LINK_PS) && !local->ops->set_tim) | 
|---|
| 1091 | return; | 
|---|
| 1092 |  | 
|---|
| 1093 | if (sta->dead) | 
|---|
| 1094 | goto done; | 
|---|
| 1095 |  | 
|---|
| 1096 | /* | 
|---|
| 1097 | * If all ACs are delivery-enabled then we should build | 
|---|
| 1098 | * the TIM bit for all ACs anyway; if only some are then | 
|---|
| 1099 | * we ignore those and build the TIM bit using only the | 
|---|
| 1100 | * non-enabled ones. | 
|---|
| 1101 | */ | 
|---|
| 1102 | if (ignore_for_tim == BIT(IEEE80211_NUM_ACS) - 1) | 
|---|
| 1103 | ignore_for_tim = 0; | 
|---|
| 1104 |  | 
|---|
| 1105 | if (ignore_pending) | 
|---|
| 1106 | ignore_for_tim = BIT(IEEE80211_NUM_ACS) - 1; | 
|---|
| 1107 |  | 
|---|
| 1108 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 
|---|
| 1109 | unsigned long tids; | 
|---|
| 1110 |  | 
|---|
| 1111 | if (ignore_for_tim & ieee80211_ac_to_qos_mask[ac]) | 
|---|
| 1112 | continue; | 
|---|
| 1113 |  | 
|---|
| 1114 | indicate_tim |= !skb_queue_empty(list: &sta->tx_filtered[ac]) || | 
|---|
| 1115 | !skb_queue_empty(list: &sta->ps_tx_buf[ac]); | 
|---|
| 1116 | if (indicate_tim) | 
|---|
| 1117 | break; | 
|---|
| 1118 |  | 
|---|
| 1119 | tids = ieee80211_tids_for_ac(ac); | 
|---|
| 1120 |  | 
|---|
| 1121 | indicate_tim |= | 
|---|
| 1122 | sta->driver_buffered_tids & tids; | 
|---|
| 1123 | indicate_tim |= | 
|---|
| 1124 | sta->txq_buffered_tids & tids; | 
|---|
| 1125 | } | 
|---|
| 1126 |  | 
|---|
| 1127 | done: | 
|---|
| 1128 | spin_lock_bh(lock: &local->tim_lock); | 
|---|
| 1129 |  | 
|---|
| 1130 | if (indicate_tim == __bss_tim_get(tim: ps->tim, id)) | 
|---|
| 1131 | goto out_unlock; | 
|---|
| 1132 |  | 
|---|
| 1133 | if (indicate_tim) | 
|---|
| 1134 | __bss_tim_set(tim: ps->tim, id); | 
|---|
| 1135 | else | 
|---|
| 1136 | __bss_tim_clear(tim: ps->tim, id); | 
|---|
| 1137 |  | 
|---|
| 1138 | if (local->ops->set_tim && !WARN_ON(sta->dead)) { | 
|---|
| 1139 | local->tim_in_locked_section = true; | 
|---|
| 1140 | drv_set_tim(local, sta: &sta->sta, set: indicate_tim); | 
|---|
| 1141 | local->tim_in_locked_section = false; | 
|---|
| 1142 | } | 
|---|
| 1143 |  | 
|---|
| 1144 | out_unlock: | 
|---|
| 1145 | spin_unlock_bh(lock: &local->tim_lock); | 
|---|
| 1146 | } | 
|---|
| 1147 |  | 
|---|
| 1148 | void sta_info_recalc_tim(struct sta_info *sta) | 
|---|
| 1149 | { | 
|---|
| 1150 | __sta_info_recalc_tim(sta, ignore_pending: false); | 
|---|
| 1151 | } | 
|---|
| 1152 |  | 
|---|
| 1153 | static bool sta_info_buffer_expired(struct sta_info *sta, struct sk_buff *skb) | 
|---|
| 1154 | { | 
|---|
| 1155 | struct ieee80211_tx_info *info; | 
|---|
| 1156 | int timeout; | 
|---|
| 1157 |  | 
|---|
| 1158 | if (!skb) | 
|---|
| 1159 | return false; | 
|---|
| 1160 |  | 
|---|
| 1161 | info = IEEE80211_SKB_CB(skb); | 
|---|
| 1162 |  | 
|---|
| 1163 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ | 
|---|
| 1164 | timeout = (sta->listen_interval * | 
|---|
| 1165 | sta->sdata->vif.bss_conf.beacon_int * | 
|---|
| 1166 | 32 / 15625) * HZ; | 
|---|
| 1167 | if (timeout < STA_TX_BUFFER_EXPIRE) | 
|---|
| 1168 | timeout = STA_TX_BUFFER_EXPIRE; | 
|---|
| 1169 | return time_after(jiffies, info->control.jiffies + timeout); | 
|---|
| 1170 | } | 
|---|
| 1171 |  | 
|---|
| 1172 |  | 
|---|
| 1173 | static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | 
|---|
| 1174 | struct sta_info *sta, int ac) | 
|---|
| 1175 | { | 
|---|
| 1176 | unsigned long flags; | 
|---|
| 1177 | struct sk_buff *skb; | 
|---|
| 1178 |  | 
|---|
| 1179 | /* | 
|---|
| 1180 | * First check for frames that should expire on the filtered | 
|---|
| 1181 | * queue. Frames here were rejected by the driver and are on | 
|---|
| 1182 | * a separate queue to avoid reordering with normal PS-buffered | 
|---|
| 1183 | * frames. They also aren't accounted for right now in the | 
|---|
| 1184 | * total_ps_buffered counter. | 
|---|
| 1185 | */ | 
|---|
| 1186 | for (;;) { | 
|---|
| 1187 | spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); | 
|---|
| 1188 | skb = skb_peek(list_: &sta->tx_filtered[ac]); | 
|---|
| 1189 | if (sta_info_buffer_expired(sta, skb)) | 
|---|
| 1190 | skb = __skb_dequeue(list: &sta->tx_filtered[ac]); | 
|---|
| 1191 | else | 
|---|
| 1192 | skb = NULL; | 
|---|
| 1193 | spin_unlock_irqrestore(lock: &sta->tx_filtered[ac].lock, flags); | 
|---|
| 1194 |  | 
|---|
| 1195 | /* | 
|---|
| 1196 | * Frames are queued in order, so if this one | 
|---|
| 1197 | * hasn't expired yet we can stop testing. If | 
|---|
| 1198 | * we actually reached the end of the queue we | 
|---|
| 1199 | * also need to stop, of course. | 
|---|
| 1200 | */ | 
|---|
| 1201 | if (!skb) | 
|---|
| 1202 | break; | 
|---|
| 1203 | ieee80211_free_txskb(hw: &local->hw, skb); | 
|---|
| 1204 | } | 
|---|
| 1205 |  | 
|---|
| 1206 | /* | 
|---|
| 1207 | * Now also check the normal PS-buffered queue, this will | 
|---|
| 1208 | * only find something if the filtered queue was emptied | 
|---|
| 1209 | * since the filtered frames are all before the normal PS | 
|---|
| 1210 | * buffered frames. | 
|---|
| 1211 | */ | 
|---|
| 1212 | for (;;) { | 
|---|
| 1213 | spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); | 
|---|
| 1214 | skb = skb_peek(list_: &sta->ps_tx_buf[ac]); | 
|---|
| 1215 | if (sta_info_buffer_expired(sta, skb)) | 
|---|
| 1216 | skb = __skb_dequeue(list: &sta->ps_tx_buf[ac]); | 
|---|
| 1217 | else | 
|---|
| 1218 | skb = NULL; | 
|---|
| 1219 | spin_unlock_irqrestore(lock: &sta->ps_tx_buf[ac].lock, flags); | 
|---|
| 1220 |  | 
|---|
| 1221 | /* | 
|---|
| 1222 | * frames are queued in order, so if this one | 
|---|
| 1223 | * hasn't expired yet (or we reached the end of | 
|---|
| 1224 | * the queue) we can stop testing | 
|---|
| 1225 | */ | 
|---|
| 1226 | if (!skb) | 
|---|
| 1227 | break; | 
|---|
| 1228 |  | 
|---|
| 1229 | local->total_ps_buffered--; | 
|---|
| 1230 | ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", | 
|---|
| 1231 | sta->sta.addr); | 
|---|
| 1232 | ieee80211_free_txskb(hw: &local->hw, skb); | 
|---|
| 1233 | } | 
|---|
| 1234 |  | 
|---|
| 1235 | /* | 
|---|
| 1236 | * Finally, recalculate the TIM bit for this station -- it might | 
|---|
| 1237 | * now be clear because the station was too slow to retrieve its | 
|---|
| 1238 | * frames. | 
|---|
| 1239 | */ | 
|---|
| 1240 | sta_info_recalc_tim(sta); | 
|---|
| 1241 |  | 
|---|
| 1242 | /* | 
|---|
| 1243 | * Return whether there are any frames still buffered, this is | 
|---|
| 1244 | * used to check whether the cleanup timer still needs to run, | 
|---|
| 1245 | * if there are no frames we don't need to rearm the timer. | 
|---|
| 1246 | */ | 
|---|
| 1247 | return !(skb_queue_empty(list: &sta->ps_tx_buf[ac]) && | 
|---|
| 1248 | skb_queue_empty(list: &sta->tx_filtered[ac])); | 
|---|
| 1249 | } | 
|---|
| 1250 |  | 
|---|
| 1251 | static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | 
|---|
| 1252 | struct sta_info *sta) | 
|---|
| 1253 | { | 
|---|
| 1254 | bool have_buffered = false; | 
|---|
| 1255 | int ac; | 
|---|
| 1256 |  | 
|---|
| 1257 | /* This is only necessary for stations on BSS/MBSS interfaces */ | 
|---|
| 1258 | if (!sta->sdata->bss && | 
|---|
| 1259 | !ieee80211_vif_is_mesh(vif: &sta->sdata->vif)) | 
|---|
| 1260 | return false; | 
|---|
| 1261 |  | 
|---|
| 1262 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 1263 | have_buffered |= | 
|---|
| 1264 | sta_info_cleanup_expire_buffered_ac(local, sta, ac); | 
|---|
| 1265 |  | 
|---|
| 1266 | return have_buffered; | 
|---|
| 1267 | } | 
|---|
| 1268 |  | 
|---|
| 1269 | static int __must_check __sta_info_destroy_part1(struct sta_info *sta) | 
|---|
| 1270 | { | 
|---|
| 1271 | struct ieee80211_local *local; | 
|---|
| 1272 | struct ieee80211_sub_if_data *sdata; | 
|---|
| 1273 | int ret, i; | 
|---|
| 1274 |  | 
|---|
| 1275 | might_sleep(); | 
|---|
| 1276 |  | 
|---|
| 1277 | if (!sta) | 
|---|
| 1278 | return -ENOENT; | 
|---|
| 1279 |  | 
|---|
| 1280 | local = sta->local; | 
|---|
| 1281 | sdata = sta->sdata; | 
|---|
| 1282 |  | 
|---|
| 1283 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 1284 |  | 
|---|
| 1285 | /* | 
|---|
| 1286 | * Before removing the station from the driver and | 
|---|
| 1287 | * rate control, it might still start new aggregation | 
|---|
| 1288 | * sessions -- block that to make sure the tear-down | 
|---|
| 1289 | * will be sufficient. | 
|---|
| 1290 | */ | 
|---|
| 1291 | set_sta_flag(sta, flag: WLAN_STA_BLOCK_BA); | 
|---|
| 1292 | ieee80211_sta_tear_down_BA_sessions(sta, reason: AGG_STOP_DESTROY_STA); | 
|---|
| 1293 |  | 
|---|
| 1294 | /* | 
|---|
| 1295 | * Before removing the station from the driver there might be pending | 
|---|
| 1296 | * rx frames on RSS queues sent prior to the disassociation - wait for | 
|---|
| 1297 | * all such frames to be processed. | 
|---|
| 1298 | */ | 
|---|
| 1299 | drv_sync_rx_queues(local, sta); | 
|---|
| 1300 |  | 
|---|
| 1301 | for (i = 0; i < ARRAY_SIZE(sta->link); i++) { | 
|---|
| 1302 | struct link_sta_info *link_sta; | 
|---|
| 1303 |  | 
|---|
| 1304 | if (!(sta->sta.valid_links & BIT(i))) | 
|---|
| 1305 | continue; | 
|---|
| 1306 |  | 
|---|
| 1307 | link_sta = rcu_dereference_protected(sta->link[i], | 
|---|
| 1308 | lockdep_is_held(&local->hw.wiphy->mtx)); | 
|---|
| 1309 |  | 
|---|
| 1310 | link_sta_info_hash_del(local, link_sta); | 
|---|
| 1311 | } | 
|---|
| 1312 |  | 
|---|
| 1313 | ret = sta_info_hash_del(local, sta); | 
|---|
| 1314 | if (WARN_ON(ret)) | 
|---|
| 1315 | return ret; | 
|---|
| 1316 |  | 
|---|
| 1317 | /* | 
|---|
| 1318 | * for TDLS peers, make sure to return to the base channel before | 
|---|
| 1319 | * removal. | 
|---|
| 1320 | */ | 
|---|
| 1321 | if (test_sta_flag(sta, flag: WLAN_STA_TDLS_OFF_CHANNEL)) { | 
|---|
| 1322 | drv_tdls_cancel_channel_switch(local, sdata, sta: &sta->sta); | 
|---|
| 1323 | clear_sta_flag(sta, flag: WLAN_STA_TDLS_OFF_CHANNEL); | 
|---|
| 1324 | } | 
|---|
| 1325 |  | 
|---|
| 1326 | list_del_rcu(entry: &sta->list); | 
|---|
| 1327 | sta->removed = true; | 
|---|
| 1328 |  | 
|---|
| 1329 | if (sta->uploaded) | 
|---|
| 1330 | drv_sta_pre_rcu_remove(local, sdata: sta->sdata, sta); | 
|---|
| 1331 |  | 
|---|
| 1332 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && | 
|---|
| 1333 | rcu_access_pointer(sdata->u.vlan.sta) == sta) | 
|---|
| 1334 | RCU_INIT_POINTER(sdata->u.vlan.sta, NULL); | 
|---|
| 1335 |  | 
|---|
| 1336 | return 0; | 
|---|
| 1337 | } | 
|---|
| 1338 |  | 
|---|
| 1339 | static int _sta_info_move_state(struct sta_info *sta, | 
|---|
| 1340 | enum ieee80211_sta_state new_state, | 
|---|
| 1341 | bool recalc) | 
|---|
| 1342 | { | 
|---|
| 1343 | struct ieee80211_local *local = sta->local; | 
|---|
| 1344 |  | 
|---|
| 1345 | might_sleep(); | 
|---|
| 1346 |  | 
|---|
| 1347 | if (sta->sta_state == new_state) | 
|---|
| 1348 | return 0; | 
|---|
| 1349 |  | 
|---|
| 1350 | /* check allowed transitions first */ | 
|---|
| 1351 |  | 
|---|
| 1352 | switch (new_state) { | 
|---|
| 1353 | case IEEE80211_STA_NONE: | 
|---|
| 1354 | if (sta->sta_state != IEEE80211_STA_AUTH) | 
|---|
| 1355 | return -EINVAL; | 
|---|
| 1356 | break; | 
|---|
| 1357 | case IEEE80211_STA_AUTH: | 
|---|
| 1358 | if (sta->sta_state != IEEE80211_STA_NONE && | 
|---|
| 1359 | sta->sta_state != IEEE80211_STA_ASSOC) | 
|---|
| 1360 | return -EINVAL; | 
|---|
| 1361 | break; | 
|---|
| 1362 | case IEEE80211_STA_ASSOC: | 
|---|
| 1363 | if (sta->sta_state != IEEE80211_STA_AUTH && | 
|---|
| 1364 | sta->sta_state != IEEE80211_STA_AUTHORIZED) | 
|---|
| 1365 | return -EINVAL; | 
|---|
| 1366 | break; | 
|---|
| 1367 | case IEEE80211_STA_AUTHORIZED: | 
|---|
| 1368 | if (sta->sta_state != IEEE80211_STA_ASSOC) | 
|---|
| 1369 | return -EINVAL; | 
|---|
| 1370 | break; | 
|---|
| 1371 | default: | 
|---|
| 1372 | WARN(1, "invalid state %d", new_state); | 
|---|
| 1373 | return -EINVAL; | 
|---|
| 1374 | } | 
|---|
| 1375 |  | 
|---|
| 1376 | sta_dbg(sta->sdata, "moving STA %pM to state %d\n", | 
|---|
| 1377 | sta->sta.addr, new_state); | 
|---|
| 1378 |  | 
|---|
| 1379 | /* notify the driver before the actual changes so it can | 
|---|
| 1380 | * fail the transition if the state is increasing. | 
|---|
| 1381 | * The driver is required not to fail when the transition | 
|---|
| 1382 | * is decreasing the state, so first, do all the preparation | 
|---|
| 1383 | * work and only then, notify the driver. | 
|---|
| 1384 | */ | 
|---|
| 1385 | if (new_state > sta->sta_state && | 
|---|
| 1386 | test_sta_flag(sta, flag: WLAN_STA_INSERTED)) { | 
|---|
| 1387 | int err = drv_sta_state(local: sta->local, sdata: sta->sdata, sta, | 
|---|
| 1388 | old_state: sta->sta_state, new_state); | 
|---|
| 1389 | if (err) | 
|---|
| 1390 | return err; | 
|---|
| 1391 | } | 
|---|
| 1392 |  | 
|---|
| 1393 | /* reflect the change in all state variables */ | 
|---|
| 1394 |  | 
|---|
| 1395 | switch (new_state) { | 
|---|
| 1396 | case IEEE80211_STA_NONE: | 
|---|
| 1397 | if (sta->sta_state == IEEE80211_STA_AUTH) | 
|---|
| 1398 | clear_bit(nr: WLAN_STA_AUTH, addr: &sta->_flags); | 
|---|
| 1399 | break; | 
|---|
| 1400 | case IEEE80211_STA_AUTH: | 
|---|
| 1401 | if (sta->sta_state == IEEE80211_STA_NONE) { | 
|---|
| 1402 | set_bit(nr: WLAN_STA_AUTH, addr: &sta->_flags); | 
|---|
| 1403 | } else if (sta->sta_state == IEEE80211_STA_ASSOC) { | 
|---|
| 1404 | clear_bit(nr: WLAN_STA_ASSOC, addr: &sta->_flags); | 
|---|
| 1405 | if (recalc) { | 
|---|
| 1406 | ieee80211_recalc_min_chandef(sdata: sta->sdata, link_id: -1); | 
|---|
| 1407 | if (!sta->sta.support_p2p_ps) | 
|---|
| 1408 | ieee80211_recalc_p2p_go_ps_allowed(sdata: sta->sdata); | 
|---|
| 1409 | } | 
|---|
| 1410 | } | 
|---|
| 1411 | break; | 
|---|
| 1412 | case IEEE80211_STA_ASSOC: | 
|---|
| 1413 | if (sta->sta_state == IEEE80211_STA_AUTH) { | 
|---|
| 1414 | set_bit(nr: WLAN_STA_ASSOC, addr: &sta->_flags); | 
|---|
| 1415 | sta->assoc_at = ktime_get_boottime_ns(); | 
|---|
| 1416 | if (recalc) { | 
|---|
| 1417 | ieee80211_recalc_min_chandef(sdata: sta->sdata, link_id: -1); | 
|---|
| 1418 | if (!sta->sta.support_p2p_ps) | 
|---|
| 1419 | ieee80211_recalc_p2p_go_ps_allowed(sdata: sta->sdata); | 
|---|
| 1420 | } | 
|---|
| 1421 | } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) { | 
|---|
| 1422 | ieee80211_vif_dec_num_mcast(sdata: sta->sdata); | 
|---|
| 1423 | clear_bit(nr: WLAN_STA_AUTHORIZED, addr: &sta->_flags); | 
|---|
| 1424 |  | 
|---|
| 1425 | /* | 
|---|
| 1426 | * If we have encryption offload, flush (station) queues | 
|---|
| 1427 | * (after ensuring concurrent TX completed) so we won't | 
|---|
| 1428 | * transmit anything later unencrypted if/when keys are | 
|---|
| 1429 | * also removed, which might otherwise happen depending | 
|---|
| 1430 | * on how the hardware offload works. | 
|---|
| 1431 | */ | 
|---|
| 1432 | if (local->ops->set_key) { | 
|---|
| 1433 | synchronize_net(); | 
|---|
| 1434 | if (local->ops->flush_sta) | 
|---|
| 1435 | drv_flush_sta(local, sdata: sta->sdata, sta); | 
|---|
| 1436 | else | 
|---|
| 1437 | ieee80211_flush_queues(local, | 
|---|
| 1438 | sdata: sta->sdata, | 
|---|
| 1439 | drop: false); | 
|---|
| 1440 | } | 
|---|
| 1441 |  | 
|---|
| 1442 | ieee80211_clear_fast_xmit(sta); | 
|---|
| 1443 | ieee80211_clear_fast_rx(sta); | 
|---|
| 1444 | } | 
|---|
| 1445 | break; | 
|---|
| 1446 | case IEEE80211_STA_AUTHORIZED: | 
|---|
| 1447 | if (sta->sta_state == IEEE80211_STA_ASSOC) { | 
|---|
| 1448 | ieee80211_vif_inc_num_mcast(sdata: sta->sdata); | 
|---|
| 1449 | set_bit(nr: WLAN_STA_AUTHORIZED, addr: &sta->_flags); | 
|---|
| 1450 | ieee80211_check_fast_xmit(sta); | 
|---|
| 1451 | ieee80211_check_fast_rx(sta); | 
|---|
| 1452 | } | 
|---|
| 1453 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | 
|---|
| 1454 | sta->sdata->vif.type == NL80211_IFTYPE_AP) | 
|---|
| 1455 | cfg80211_send_layer2_update(dev: sta->sdata->dev, | 
|---|
| 1456 | addr: sta->sta.addr); | 
|---|
| 1457 | break; | 
|---|
| 1458 | default: | 
|---|
| 1459 | break; | 
|---|
| 1460 | } | 
|---|
| 1461 |  | 
|---|
| 1462 | if (new_state < sta->sta_state && | 
|---|
| 1463 | test_sta_flag(sta, flag: WLAN_STA_INSERTED)) { | 
|---|
| 1464 | int err = drv_sta_state(local: sta->local, sdata: sta->sdata, sta, | 
|---|
| 1465 | old_state: sta->sta_state, new_state); | 
|---|
| 1466 |  | 
|---|
| 1467 | WARN_ONCE(err, | 
|---|
| 1468 | "Driver is not allowed to fail if the sta_state is transitioning down the list: %d\n", | 
|---|
| 1469 | err); | 
|---|
| 1470 | } | 
|---|
| 1471 |  | 
|---|
| 1472 | sta->sta_state = new_state; | 
|---|
| 1473 |  | 
|---|
| 1474 | return 0; | 
|---|
| 1475 | } | 
|---|
| 1476 |  | 
|---|
| 1477 | int sta_info_move_state(struct sta_info *sta, | 
|---|
| 1478 | enum ieee80211_sta_state new_state) | 
|---|
| 1479 | { | 
|---|
| 1480 | return _sta_info_move_state(sta, new_state, recalc: true); | 
|---|
| 1481 | } | 
|---|
| 1482 |  | 
|---|
| 1483 | static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc) | 
|---|
| 1484 | { | 
|---|
| 1485 | struct ieee80211_local *local = sta->local; | 
|---|
| 1486 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 1487 | struct station_info *sinfo; | 
|---|
| 1488 | int ret; | 
|---|
| 1489 |  | 
|---|
| 1490 | /* | 
|---|
| 1491 | * NOTE: This assumes at least synchronize_net() was done | 
|---|
| 1492 | *	 after _part1 and before _part2! | 
|---|
| 1493 | */ | 
|---|
| 1494 |  | 
|---|
| 1495 | /* | 
|---|
| 1496 | * There's a potential race in _part1 where we set WLAN_STA_BLOCK_BA | 
|---|
| 1497 | * but someone might have just gotten past a check, and not yet into | 
|---|
| 1498 | * queuing the work/creating the data/etc. | 
|---|
| 1499 | * | 
|---|
| 1500 | * Do another round of destruction so that the worker is certainly | 
|---|
| 1501 | * canceled before we later free the station. | 
|---|
| 1502 | * | 
|---|
| 1503 | * Since this is after synchronize_rcu()/synchronize_net() we're now | 
|---|
| 1504 | * certain that nobody can actually hold a reference to the STA and | 
|---|
| 1505 | * be calling e.g. ieee80211_start_tx_ba_session(). | 
|---|
| 1506 | */ | 
|---|
| 1507 | ieee80211_sta_tear_down_BA_sessions(sta, reason: AGG_STOP_DESTROY_STA); | 
|---|
| 1508 |  | 
|---|
| 1509 | might_sleep(); | 
|---|
| 1510 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 1511 |  | 
|---|
| 1512 | if (sta->sta_state == IEEE80211_STA_AUTHORIZED) { | 
|---|
| 1513 | ret = _sta_info_move_state(sta, new_state: IEEE80211_STA_ASSOC, recalc); | 
|---|
| 1514 | WARN_ON_ONCE(ret); | 
|---|
| 1515 | } | 
|---|
| 1516 |  | 
|---|
| 1517 | /* now keys can no longer be reached */ | 
|---|
| 1518 | ieee80211_free_sta_keys(local, sta); | 
|---|
| 1519 |  | 
|---|
| 1520 | /* disable TIM bit - last chance to tell driver */ | 
|---|
| 1521 | __sta_info_recalc_tim(sta, ignore_pending: true); | 
|---|
| 1522 |  | 
|---|
| 1523 | sta->dead = true; | 
|---|
| 1524 |  | 
|---|
| 1525 | local->num_sta--; | 
|---|
| 1526 | local->sta_generation++; | 
|---|
| 1527 |  | 
|---|
| 1528 | while (sta->sta_state > IEEE80211_STA_NONE) { | 
|---|
| 1529 | ret = _sta_info_move_state(sta, new_state: sta->sta_state - 1, recalc); | 
|---|
| 1530 | if (ret) { | 
|---|
| 1531 | WARN_ON_ONCE(1); | 
|---|
| 1532 | break; | 
|---|
| 1533 | } | 
|---|
| 1534 | } | 
|---|
| 1535 |  | 
|---|
| 1536 | if (sta->uploaded) { | 
|---|
| 1537 | ret = drv_sta_state(local, sdata, sta, old_state: IEEE80211_STA_NONE, | 
|---|
| 1538 | new_state: IEEE80211_STA_NOTEXIST); | 
|---|
| 1539 | WARN_ON_ONCE(ret != 0); | 
|---|
| 1540 | } | 
|---|
| 1541 |  | 
|---|
| 1542 | sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); | 
|---|
| 1543 |  | 
|---|
| 1544 | sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); | 
|---|
| 1545 | if (sinfo) | 
|---|
| 1546 | sta_set_sinfo(sta, sinfo, tidstats: true); | 
|---|
| 1547 | cfg80211_del_sta_sinfo(dev: sdata->dev, mac_addr: sta->sta.addr, sinfo, GFP_KERNEL); | 
|---|
| 1548 | kfree(objp: sinfo); | 
|---|
| 1549 |  | 
|---|
| 1550 | ieee80211_sta_debugfs_remove(sta); | 
|---|
| 1551 |  | 
|---|
| 1552 | ieee80211_destroy_frag_cache(cache: &sta->frags); | 
|---|
| 1553 |  | 
|---|
| 1554 | cleanup_single_sta(sta); | 
|---|
| 1555 | } | 
|---|
| 1556 |  | 
|---|
| 1557 | int __must_check __sta_info_destroy(struct sta_info *sta) | 
|---|
| 1558 | { | 
|---|
| 1559 | int err = __sta_info_destroy_part1(sta); | 
|---|
| 1560 |  | 
|---|
| 1561 | if (err) | 
|---|
| 1562 | return err; | 
|---|
| 1563 |  | 
|---|
| 1564 | synchronize_net(); | 
|---|
| 1565 |  | 
|---|
| 1566 | __sta_info_destroy_part2(sta, recalc: true); | 
|---|
| 1567 |  | 
|---|
| 1568 | return 0; | 
|---|
| 1569 | } | 
|---|
| 1570 |  | 
|---|
| 1571 | int sta_info_destroy_addr(struct ieee80211_sub_if_data *sdata, const u8 *addr) | 
|---|
| 1572 | { | 
|---|
| 1573 | struct sta_info *sta; | 
|---|
| 1574 |  | 
|---|
| 1575 | lockdep_assert_wiphy(sdata->local->hw.wiphy); | 
|---|
| 1576 |  | 
|---|
| 1577 | sta = sta_info_get(sdata, addr); | 
|---|
| 1578 | return __sta_info_destroy(sta); | 
|---|
| 1579 | } | 
|---|
| 1580 |  | 
|---|
| 1581 | int sta_info_destroy_addr_bss(struct ieee80211_sub_if_data *sdata, | 
|---|
| 1582 | const u8 *addr) | 
|---|
| 1583 | { | 
|---|
| 1584 | struct sta_info *sta; | 
|---|
| 1585 |  | 
|---|
| 1586 | lockdep_assert_wiphy(sdata->local->hw.wiphy); | 
|---|
| 1587 |  | 
|---|
| 1588 | sta = sta_info_get_bss(sdata, addr); | 
|---|
| 1589 | return __sta_info_destroy(sta); | 
|---|
| 1590 | } | 
|---|
| 1591 |  | 
|---|
| 1592 | static void sta_info_cleanup(struct timer_list *t) | 
|---|
| 1593 | { | 
|---|
| 1594 | struct ieee80211_local *local = timer_container_of(local, t, | 
|---|
| 1595 | sta_cleanup); | 
|---|
| 1596 | struct sta_info *sta; | 
|---|
| 1597 | bool timer_needed = false; | 
|---|
| 1598 |  | 
|---|
| 1599 | rcu_read_lock(); | 
|---|
| 1600 | list_for_each_entry_rcu(sta, &local->sta_list, list) | 
|---|
| 1601 | if (sta_info_cleanup_expire_buffered(local, sta)) | 
|---|
| 1602 | timer_needed = true; | 
|---|
| 1603 | rcu_read_unlock(); | 
|---|
| 1604 |  | 
|---|
| 1605 | if (local->quiescing) | 
|---|
| 1606 | return; | 
|---|
| 1607 |  | 
|---|
| 1608 | if (!timer_needed) | 
|---|
| 1609 | return; | 
|---|
| 1610 |  | 
|---|
| 1611 | mod_timer(timer: &local->sta_cleanup, | 
|---|
| 1612 | expires: round_jiffies(j: jiffies + STA_INFO_CLEANUP_INTERVAL)); | 
|---|
| 1613 | } | 
|---|
| 1614 |  | 
|---|
| 1615 | int sta_info_init(struct ieee80211_local *local) | 
|---|
| 1616 | { | 
|---|
| 1617 | int err; | 
|---|
| 1618 |  | 
|---|
| 1619 | err = rhltable_init(&local->sta_hash, &sta_rht_params); | 
|---|
| 1620 | if (err) | 
|---|
| 1621 | return err; | 
|---|
| 1622 |  | 
|---|
| 1623 | err = rhltable_init(&local->link_sta_hash, &link_sta_rht_params); | 
|---|
| 1624 | if (err) { | 
|---|
| 1625 | rhltable_destroy(hlt: &local->sta_hash); | 
|---|
| 1626 | return err; | 
|---|
| 1627 | } | 
|---|
| 1628 |  | 
|---|
| 1629 | spin_lock_init(&local->tim_lock); | 
|---|
| 1630 | INIT_LIST_HEAD(list: &local->sta_list); | 
|---|
| 1631 |  | 
|---|
| 1632 | timer_setup(&local->sta_cleanup, sta_info_cleanup, 0); | 
|---|
| 1633 | return 0; | 
|---|
| 1634 | } | 
|---|
| 1635 |  | 
|---|
| 1636 | void sta_info_stop(struct ieee80211_local *local) | 
|---|
| 1637 | { | 
|---|
| 1638 | timer_delete_sync(timer: &local->sta_cleanup); | 
|---|
| 1639 | rhltable_destroy(hlt: &local->sta_hash); | 
|---|
| 1640 | rhltable_destroy(hlt: &local->link_sta_hash); | 
|---|
| 1641 | } | 
|---|
| 1642 |  | 
|---|
| 1643 |  | 
|---|
| 1644 | int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans, | 
|---|
| 1645 | int link_id, struct sta_info *do_not_flush_sta) | 
|---|
| 1646 | { | 
|---|
| 1647 | struct ieee80211_local *local = sdata->local; | 
|---|
| 1648 | struct sta_info *sta, *tmp; | 
|---|
| 1649 | LIST_HEAD(free_list); | 
|---|
| 1650 | int ret = 0; | 
|---|
| 1651 |  | 
|---|
| 1652 | might_sleep(); | 
|---|
| 1653 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 1654 |  | 
|---|
| 1655 | WARN_ON(vlans && sdata->vif.type != NL80211_IFTYPE_AP); | 
|---|
| 1656 | WARN_ON(vlans && !sdata->bss); | 
|---|
| 1657 |  | 
|---|
| 1658 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { | 
|---|
| 1659 | if (sdata != sta->sdata && | 
|---|
| 1660 | (!vlans || sdata->bss != sta->sdata->bss)) | 
|---|
| 1661 | continue; | 
|---|
| 1662 |  | 
|---|
| 1663 | if (sta == do_not_flush_sta) | 
|---|
| 1664 | continue; | 
|---|
| 1665 |  | 
|---|
| 1666 | if (link_id >= 0 && sta->sta.valid_links && | 
|---|
| 1667 | !(sta->sta.valid_links & BIT(link_id))) | 
|---|
| 1668 | continue; | 
|---|
| 1669 |  | 
|---|
| 1670 | if (!WARN_ON(__sta_info_destroy_part1(sta))) | 
|---|
| 1671 | list_add(new: &sta->free_list, head: &free_list); | 
|---|
| 1672 |  | 
|---|
| 1673 | ret++; | 
|---|
| 1674 | } | 
|---|
| 1675 |  | 
|---|
| 1676 | if (!list_empty(head: &free_list)) { | 
|---|
| 1677 | bool support_p2p_ps = true; | 
|---|
| 1678 |  | 
|---|
| 1679 | synchronize_net(); | 
|---|
| 1680 | list_for_each_entry_safe(sta, tmp, &free_list, free_list) { | 
|---|
| 1681 | if (!sta->sta.support_p2p_ps) | 
|---|
| 1682 | support_p2p_ps = false; | 
|---|
| 1683 | __sta_info_destroy_part2(sta, recalc: false); | 
|---|
| 1684 | } | 
|---|
| 1685 |  | 
|---|
| 1686 | ieee80211_recalc_min_chandef(sdata, link_id: -1); | 
|---|
| 1687 | if (!support_p2p_ps) | 
|---|
| 1688 | ieee80211_recalc_p2p_go_ps_allowed(sdata); | 
|---|
| 1689 | } | 
|---|
| 1690 |  | 
|---|
| 1691 | return ret; | 
|---|
| 1692 | } | 
|---|
| 1693 |  | 
|---|
| 1694 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | 
|---|
| 1695 | unsigned long exp_time) | 
|---|
| 1696 | { | 
|---|
| 1697 | struct ieee80211_local *local = sdata->local; | 
|---|
| 1698 | struct sta_info *sta, *tmp; | 
|---|
| 1699 |  | 
|---|
| 1700 | lockdep_assert_wiphy(local->hw.wiphy); | 
|---|
| 1701 |  | 
|---|
| 1702 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) { | 
|---|
| 1703 | unsigned long last_active = ieee80211_sta_last_active(sta, link_id: -1); | 
|---|
| 1704 |  | 
|---|
| 1705 | if (sdata != sta->sdata) | 
|---|
| 1706 | continue; | 
|---|
| 1707 |  | 
|---|
| 1708 | if (time_is_before_jiffies(last_active + exp_time)) { | 
|---|
| 1709 | sta_dbg(sta->sdata, "expiring inactive STA %pM\n", | 
|---|
| 1710 | sta->sta.addr); | 
|---|
| 1711 |  | 
|---|
| 1712 | if (ieee80211_vif_is_mesh(vif: &sdata->vif) && | 
|---|
| 1713 | test_sta_flag(sta, flag: WLAN_STA_PS_STA)) | 
|---|
| 1714 | atomic_dec(v: &sdata->u.mesh.ps.num_sta_ps); | 
|---|
| 1715 |  | 
|---|
| 1716 | WARN_ON(__sta_info_destroy(sta)); | 
|---|
| 1717 | } | 
|---|
| 1718 | } | 
|---|
| 1719 | } | 
|---|
| 1720 |  | 
|---|
| 1721 | struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, | 
|---|
| 1722 | const u8 *addr, | 
|---|
| 1723 | const u8 *localaddr) | 
|---|
| 1724 | { | 
|---|
| 1725 | struct ieee80211_local *local = hw_to_local(hw); | 
|---|
| 1726 | struct rhlist_head *tmp; | 
|---|
| 1727 | struct sta_info *sta; | 
|---|
| 1728 |  | 
|---|
| 1729 | /* | 
|---|
| 1730 | * Just return a random station if localaddr is NULL | 
|---|
| 1731 | * ... first in list. | 
|---|
| 1732 | */ | 
|---|
| 1733 | for_each_sta_info(local, addr, sta, tmp) { | 
|---|
| 1734 | if (localaddr && | 
|---|
| 1735 | !ether_addr_equal(addr1: sta->sdata->vif.addr, addr2: localaddr)) | 
|---|
| 1736 | continue; | 
|---|
| 1737 | if (!sta->uploaded) | 
|---|
| 1738 | return NULL; | 
|---|
| 1739 | return &sta->sta; | 
|---|
| 1740 | } | 
|---|
| 1741 |  | 
|---|
| 1742 | return NULL; | 
|---|
| 1743 | } | 
|---|
| 1744 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr); | 
|---|
| 1745 |  | 
|---|
| 1746 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | 
|---|
| 1747 | const u8 *addr) | 
|---|
| 1748 | { | 
|---|
| 1749 | struct sta_info *sta; | 
|---|
| 1750 |  | 
|---|
| 1751 | if (!vif) | 
|---|
| 1752 | return NULL; | 
|---|
| 1753 |  | 
|---|
| 1754 | sta = sta_info_get_bss(sdata: vif_to_sdata(p: vif), addr); | 
|---|
| 1755 | if (!sta) | 
|---|
| 1756 | return NULL; | 
|---|
| 1757 |  | 
|---|
| 1758 | if (!sta->uploaded) | 
|---|
| 1759 | return NULL; | 
|---|
| 1760 |  | 
|---|
| 1761 | return &sta->sta; | 
|---|
| 1762 | } | 
|---|
| 1763 | EXPORT_SYMBOL(ieee80211_find_sta); | 
|---|
| 1764 |  | 
|---|
| 1765 | /* powersave support code */ | 
|---|
| 1766 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | 
|---|
| 1767 | { | 
|---|
| 1768 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 1769 | struct ieee80211_local *local = sdata->local; | 
|---|
| 1770 | struct sk_buff_head pending; | 
|---|
| 1771 | int filtered = 0, buffered = 0, ac, i; | 
|---|
| 1772 | unsigned long flags; | 
|---|
| 1773 | struct ps_data *ps; | 
|---|
| 1774 |  | 
|---|
| 1775 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 
|---|
| 1776 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, | 
|---|
| 1777 | u.ap); | 
|---|
| 1778 |  | 
|---|
| 1779 | if (sdata->vif.type == NL80211_IFTYPE_AP) | 
|---|
| 1780 | ps = &sdata->bss->ps; | 
|---|
| 1781 | else if (ieee80211_vif_is_mesh(vif: &sdata->vif)) | 
|---|
| 1782 | ps = &sdata->u.mesh.ps; | 
|---|
| 1783 | else | 
|---|
| 1784 | return; | 
|---|
| 1785 |  | 
|---|
| 1786 | clear_sta_flag(sta, flag: WLAN_STA_SP); | 
|---|
| 1787 |  | 
|---|
| 1788 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); | 
|---|
| 1789 | sta->driver_buffered_tids = 0; | 
|---|
| 1790 | sta->txq_buffered_tids = 0; | 
|---|
| 1791 |  | 
|---|
| 1792 | if (!ieee80211_hw_check(&local->hw, AP_LINK_PS)) | 
|---|
| 1793 | drv_sta_notify(local, sdata, cmd: STA_NOTIFY_AWAKE, sta: &sta->sta); | 
|---|
| 1794 |  | 
|---|
| 1795 | for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { | 
|---|
| 1796 | if (!sta->sta.txq[i] || !txq_has_queue(txq: sta->sta.txq[i])) | 
|---|
| 1797 | continue; | 
|---|
| 1798 |  | 
|---|
| 1799 | schedule_and_wake_txq(local, txqi: to_txq_info(txq: sta->sta.txq[i])); | 
|---|
| 1800 | } | 
|---|
| 1801 |  | 
|---|
| 1802 | skb_queue_head_init(list: &pending); | 
|---|
| 1803 |  | 
|---|
| 1804 | /* sync with ieee80211_tx_h_unicast_ps_buf */ | 
|---|
| 1805 | spin_lock_bh(lock: &sta->ps_lock); | 
|---|
| 1806 | /* Send all buffered frames to the station */ | 
|---|
| 1807 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 
|---|
| 1808 | int count = skb_queue_len(list_: &pending), tmp; | 
|---|
| 1809 |  | 
|---|
| 1810 | spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); | 
|---|
| 1811 | skb_queue_splice_tail_init(list: &sta->tx_filtered[ac], head: &pending); | 
|---|
| 1812 | spin_unlock_irqrestore(lock: &sta->tx_filtered[ac].lock, flags); | 
|---|
| 1813 | tmp = skb_queue_len(list_: &pending); | 
|---|
| 1814 | filtered += tmp - count; | 
|---|
| 1815 | count = tmp; | 
|---|
| 1816 |  | 
|---|
| 1817 | spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); | 
|---|
| 1818 | skb_queue_splice_tail_init(list: &sta->ps_tx_buf[ac], head: &pending); | 
|---|
| 1819 | spin_unlock_irqrestore(lock: &sta->ps_tx_buf[ac].lock, flags); | 
|---|
| 1820 | tmp = skb_queue_len(list_: &pending); | 
|---|
| 1821 | buffered += tmp - count; | 
|---|
| 1822 | } | 
|---|
| 1823 |  | 
|---|
| 1824 | ieee80211_add_pending_skbs(local, skbs: &pending); | 
|---|
| 1825 |  | 
|---|
| 1826 | /* now we're no longer in the deliver code */ | 
|---|
| 1827 | clear_sta_flag(sta, flag: WLAN_STA_PS_DELIVER); | 
|---|
| 1828 |  | 
|---|
| 1829 | /* The station might have polled and then woken up before we responded, | 
|---|
| 1830 | * so clear these flags now to avoid them sticking around. | 
|---|
| 1831 | */ | 
|---|
| 1832 | clear_sta_flag(sta, flag: WLAN_STA_PSPOLL); | 
|---|
| 1833 | clear_sta_flag(sta, flag: WLAN_STA_UAPSD); | 
|---|
| 1834 | spin_unlock_bh(lock: &sta->ps_lock); | 
|---|
| 1835 |  | 
|---|
| 1836 | atomic_dec(v: &ps->num_sta_ps); | 
|---|
| 1837 |  | 
|---|
| 1838 | local->total_ps_buffered -= buffered; | 
|---|
| 1839 |  | 
|---|
| 1840 | sta_info_recalc_tim(sta); | 
|---|
| 1841 |  | 
|---|
| 1842 | ps_dbg(sdata, | 
|---|
| 1843 | "STA %pM aid %d sending %d filtered/%d PS frames since STA woke up\n", | 
|---|
| 1844 | sta->sta.addr, sta->sta.aid, filtered, buffered); | 
|---|
| 1845 |  | 
|---|
| 1846 | ieee80211_check_fast_xmit(sta); | 
|---|
| 1847 | } | 
|---|
| 1848 |  | 
|---|
| 1849 | static void ieee80211_send_null_response(struct sta_info *sta, int tid, | 
|---|
| 1850 | enum ieee80211_frame_release_type reason, | 
|---|
| 1851 | bool call_driver, bool more_data) | 
|---|
| 1852 | { | 
|---|
| 1853 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 1854 | struct ieee80211_local *local = sdata->local; | 
|---|
| 1855 | struct ieee80211_qos_hdr *nullfunc; | 
|---|
| 1856 | struct sk_buff *skb; | 
|---|
| 1857 | int size = sizeof(*nullfunc); | 
|---|
| 1858 | __le16 fc; | 
|---|
| 1859 | bool qos = sta->sta.wme; | 
|---|
| 1860 | struct ieee80211_tx_info *info; | 
|---|
| 1861 | struct ieee80211_chanctx_conf *chanctx_conf; | 
|---|
| 1862 |  | 
|---|
| 1863 | if (qos) { | 
|---|
| 1864 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | 
|---|
| 1865 | IEEE80211_STYPE_QOS_NULLFUNC | | 
|---|
| 1866 | IEEE80211_FCTL_FROMDS); | 
|---|
| 1867 | } else { | 
|---|
| 1868 | size -= 2; | 
|---|
| 1869 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | | 
|---|
| 1870 | IEEE80211_STYPE_NULLFUNC | | 
|---|
| 1871 | IEEE80211_FCTL_FROMDS); | 
|---|
| 1872 | } | 
|---|
| 1873 |  | 
|---|
| 1874 | skb = dev_alloc_skb(length: local->hw.extra_tx_headroom + size); | 
|---|
| 1875 | if (!skb) | 
|---|
| 1876 | return; | 
|---|
| 1877 |  | 
|---|
| 1878 | skb_reserve(skb, len: local->hw.extra_tx_headroom); | 
|---|
| 1879 |  | 
|---|
| 1880 | nullfunc = skb_put(skb, len: size); | 
|---|
| 1881 | nullfunc->frame_control = fc; | 
|---|
| 1882 | nullfunc->duration_id = 0; | 
|---|
| 1883 | memcpy(to: nullfunc->addr1, from: sta->sta.addr, ETH_ALEN); | 
|---|
| 1884 | memcpy(to: nullfunc->addr2, from: sdata->vif.addr, ETH_ALEN); | 
|---|
| 1885 | memcpy(to: nullfunc->addr3, from: sdata->vif.addr, ETH_ALEN); | 
|---|
| 1886 | nullfunc->seq_ctrl = 0; | 
|---|
| 1887 |  | 
|---|
| 1888 | skb->priority = tid; | 
|---|
| 1889 | skb_set_queue_mapping(skb, queue_mapping: ieee802_1d_to_ac[tid]); | 
|---|
| 1890 | if (qos) { | 
|---|
| 1891 | nullfunc->qos_ctrl = cpu_to_le16(tid); | 
|---|
| 1892 |  | 
|---|
| 1893 | if (reason == IEEE80211_FRAME_RELEASE_UAPSD) { | 
|---|
| 1894 | nullfunc->qos_ctrl |= | 
|---|
| 1895 | cpu_to_le16(IEEE80211_QOS_CTL_EOSP); | 
|---|
| 1896 | if (more_data) | 
|---|
| 1897 | nullfunc->frame_control |= | 
|---|
| 1898 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 
|---|
| 1899 | } | 
|---|
| 1900 | } | 
|---|
| 1901 |  | 
|---|
| 1902 | info = IEEE80211_SKB_CB(skb); | 
|---|
| 1903 |  | 
|---|
| 1904 | /* | 
|---|
| 1905 | * Tell TX path to send this frame even though the | 
|---|
| 1906 | * STA may still remain is PS mode after this frame | 
|---|
| 1907 | * exchange. Also set EOSP to indicate this packet | 
|---|
| 1908 | * ends the poll/service period. | 
|---|
| 1909 | */ | 
|---|
| 1910 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | | 
|---|
| 1911 | IEEE80211_TX_STATUS_EOSP | | 
|---|
| 1912 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 
|---|
| 1913 |  | 
|---|
| 1914 | info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE; | 
|---|
| 1915 |  | 
|---|
| 1916 | if (call_driver) | 
|---|
| 1917 | drv_allow_buffered_frames(local, sta, BIT(tid), num_frames: 1, | 
|---|
| 1918 | reason, more_data: false); | 
|---|
| 1919 |  | 
|---|
| 1920 | skb->dev = sdata->dev; | 
|---|
| 1921 |  | 
|---|
| 1922 | rcu_read_lock(); | 
|---|
| 1923 | chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); | 
|---|
| 1924 | if (WARN_ON(!chanctx_conf)) { | 
|---|
| 1925 | rcu_read_unlock(); | 
|---|
| 1926 | kfree_skb(skb); | 
|---|
| 1927 | return; | 
|---|
| 1928 | } | 
|---|
| 1929 |  | 
|---|
| 1930 | info->band = chanctx_conf->def.chan->band; | 
|---|
| 1931 | ieee80211_xmit(sdata, sta, skb); | 
|---|
| 1932 | rcu_read_unlock(); | 
|---|
| 1933 | } | 
|---|
| 1934 |  | 
|---|
| 1935 | static int find_highest_prio_tid(unsigned long tids) | 
|---|
| 1936 | { | 
|---|
| 1937 | /* lower 3 TIDs aren't ordered perfectly */ | 
|---|
| 1938 | if (tids & 0xF8) | 
|---|
| 1939 | return fls(x: tids) - 1; | 
|---|
| 1940 | /* TID 0 is BE just like TID 3 */ | 
|---|
| 1941 | if (tids & BIT(0)) | 
|---|
| 1942 | return 0; | 
|---|
| 1943 | return fls(x: tids) - 1; | 
|---|
| 1944 | } | 
|---|
| 1945 |  | 
|---|
| 1946 | /* Indicates if the MORE_DATA bit should be set in the last | 
|---|
| 1947 | * frame obtained by ieee80211_sta_ps_get_frames. | 
|---|
| 1948 | * Note that driver_release_tids is relevant only if | 
|---|
| 1949 | * reason = IEEE80211_FRAME_RELEASE_PSPOLL | 
|---|
| 1950 | */ | 
|---|
| 1951 | static bool | 
|---|
| 1952 | ieee80211_sta_ps_more_data(struct sta_info *sta, u8 ignored_acs, | 
|---|
| 1953 | enum ieee80211_frame_release_type reason, | 
|---|
| 1954 | unsigned long driver_release_tids) | 
|---|
| 1955 | { | 
|---|
| 1956 | int ac; | 
|---|
| 1957 |  | 
|---|
| 1958 | /* If the driver has data on more than one TID then | 
|---|
| 1959 | * certainly there's more data if we release just a | 
|---|
| 1960 | * single frame now (from a single TID). This will | 
|---|
| 1961 | * only happen for PS-Poll. | 
|---|
| 1962 | */ | 
|---|
| 1963 | if (reason == IEEE80211_FRAME_RELEASE_PSPOLL && | 
|---|
| 1964 | hweight16(driver_release_tids) > 1) | 
|---|
| 1965 | return true; | 
|---|
| 1966 |  | 
|---|
| 1967 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 
|---|
| 1968 | if (ignored_acs & ieee80211_ac_to_qos_mask[ac]) | 
|---|
| 1969 | continue; | 
|---|
| 1970 |  | 
|---|
| 1971 | if (!skb_queue_empty(list: &sta->tx_filtered[ac]) || | 
|---|
| 1972 | !skb_queue_empty(list: &sta->ps_tx_buf[ac])) | 
|---|
| 1973 | return true; | 
|---|
| 1974 | } | 
|---|
| 1975 |  | 
|---|
| 1976 | return false; | 
|---|
| 1977 | } | 
|---|
| 1978 |  | 
|---|
| 1979 | static void | 
|---|
| 1980 | ieee80211_sta_ps_get_frames(struct sta_info *sta, int n_frames, u8 ignored_acs, | 
|---|
| 1981 | enum ieee80211_frame_release_type reason, | 
|---|
| 1982 | struct sk_buff_head *frames, | 
|---|
| 1983 | unsigned long *driver_release_tids) | 
|---|
| 1984 | { | 
|---|
| 1985 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 1986 | struct ieee80211_local *local = sdata->local; | 
|---|
| 1987 | int ac; | 
|---|
| 1988 |  | 
|---|
| 1989 | /* Get response frame(s) and more data bit for the last one. */ | 
|---|
| 1990 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 
|---|
| 1991 | unsigned long tids; | 
|---|
| 1992 |  | 
|---|
| 1993 | if (ignored_acs & ieee80211_ac_to_qos_mask[ac]) | 
|---|
| 1994 | continue; | 
|---|
| 1995 |  | 
|---|
| 1996 | tids = ieee80211_tids_for_ac(ac); | 
|---|
| 1997 |  | 
|---|
| 1998 | /* if we already have frames from software, then we can't also | 
|---|
| 1999 | * release from hardware queues | 
|---|
| 2000 | */ | 
|---|
| 2001 | if (skb_queue_empty(list: frames)) { | 
|---|
| 2002 | *driver_release_tids |= | 
|---|
| 2003 | sta->driver_buffered_tids & tids; | 
|---|
| 2004 | *driver_release_tids |= sta->txq_buffered_tids & tids; | 
|---|
| 2005 | } | 
|---|
| 2006 |  | 
|---|
| 2007 | if (!*driver_release_tids) { | 
|---|
| 2008 | struct sk_buff *skb; | 
|---|
| 2009 |  | 
|---|
| 2010 | while (n_frames > 0) { | 
|---|
| 2011 | skb = skb_dequeue(list: &sta->tx_filtered[ac]); | 
|---|
| 2012 | if (!skb) { | 
|---|
| 2013 | skb = skb_dequeue( | 
|---|
| 2014 | list: &sta->ps_tx_buf[ac]); | 
|---|
| 2015 | if (skb) | 
|---|
| 2016 | local->total_ps_buffered--; | 
|---|
| 2017 | } | 
|---|
| 2018 | if (!skb) | 
|---|
| 2019 | break; | 
|---|
| 2020 | n_frames--; | 
|---|
| 2021 | __skb_queue_tail(list: frames, newsk: skb); | 
|---|
| 2022 | } | 
|---|
| 2023 | } | 
|---|
| 2024 |  | 
|---|
| 2025 | /* If we have more frames buffered on this AC, then abort the | 
|---|
| 2026 | * loop since we can't send more data from other ACs before | 
|---|
| 2027 | * the buffered frames from this. | 
|---|
| 2028 | */ | 
|---|
| 2029 | if (!skb_queue_empty(list: &sta->tx_filtered[ac]) || | 
|---|
| 2030 | !skb_queue_empty(list: &sta->ps_tx_buf[ac])) | 
|---|
| 2031 | break; | 
|---|
| 2032 | } | 
|---|
| 2033 | } | 
|---|
| 2034 |  | 
|---|
| 2035 | static void | 
|---|
| 2036 | ieee80211_sta_ps_deliver_response(struct sta_info *sta, | 
|---|
| 2037 | int n_frames, u8 ignored_acs, | 
|---|
| 2038 | enum ieee80211_frame_release_type reason) | 
|---|
| 2039 | { | 
|---|
| 2040 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 2041 | struct ieee80211_local *local = sdata->local; | 
|---|
| 2042 | unsigned long driver_release_tids = 0; | 
|---|
| 2043 | struct sk_buff_head frames; | 
|---|
| 2044 | bool more_data; | 
|---|
| 2045 |  | 
|---|
| 2046 | /* Service or PS-Poll period starts */ | 
|---|
| 2047 | set_sta_flag(sta, flag: WLAN_STA_SP); | 
|---|
| 2048 |  | 
|---|
| 2049 | __skb_queue_head_init(list: &frames); | 
|---|
| 2050 |  | 
|---|
| 2051 | ieee80211_sta_ps_get_frames(sta, n_frames, ignored_acs, reason, | 
|---|
| 2052 | frames: &frames, driver_release_tids: &driver_release_tids); | 
|---|
| 2053 |  | 
|---|
| 2054 | more_data = ieee80211_sta_ps_more_data(sta, ignored_acs, reason, driver_release_tids); | 
|---|
| 2055 |  | 
|---|
| 2056 | if (driver_release_tids && reason == IEEE80211_FRAME_RELEASE_PSPOLL) | 
|---|
| 2057 | driver_release_tids = | 
|---|
| 2058 | BIT(find_highest_prio_tid(driver_release_tids)); | 
|---|
| 2059 |  | 
|---|
| 2060 | if (skb_queue_empty(list: &frames) && !driver_release_tids) { | 
|---|
| 2061 | int tid, ac; | 
|---|
| 2062 |  | 
|---|
| 2063 | /* | 
|---|
| 2064 | * For PS-Poll, this can only happen due to a race condition | 
|---|
| 2065 | * when we set the TIM bit and the station notices it, but | 
|---|
| 2066 | * before it can poll for the frame we expire it. | 
|---|
| 2067 | * | 
|---|
| 2068 | * For uAPSD, this is said in the standard (11.2.1.5 h): | 
|---|
| 2069 | *	At each unscheduled SP for a non-AP STA, the AP shall | 
|---|
| 2070 | *	attempt to transmit at least one MSDU or MMPDU, but no | 
|---|
| 2071 | *	more than the value specified in the Max SP Length field | 
|---|
| 2072 | *	in the QoS Capability element from delivery-enabled ACs, | 
|---|
| 2073 | *	that are destined for the non-AP STA. | 
|---|
| 2074 | * | 
|---|
| 2075 | * Since we have no other MSDU/MMPDU, transmit a QoS null frame. | 
|---|
| 2076 | */ | 
|---|
| 2077 |  | 
|---|
| 2078 | /* This will evaluate to 1, 3, 5 or 7. */ | 
|---|
| 2079 | for (ac = IEEE80211_AC_VO; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 2080 | if (!(ignored_acs & ieee80211_ac_to_qos_mask[ac])) | 
|---|
| 2081 | break; | 
|---|
| 2082 | tid = 7 - 2 * ac; | 
|---|
| 2083 |  | 
|---|
| 2084 | ieee80211_send_null_response(sta, tid, reason, call_driver: true, more_data: false); | 
|---|
| 2085 | } else if (!driver_release_tids) { | 
|---|
| 2086 | struct sk_buff_head pending; | 
|---|
| 2087 | struct sk_buff *skb; | 
|---|
| 2088 | int num = 0; | 
|---|
| 2089 | u16 tids = 0; | 
|---|
| 2090 | bool need_null = false; | 
|---|
| 2091 |  | 
|---|
| 2092 | skb_queue_head_init(list: &pending); | 
|---|
| 2093 |  | 
|---|
| 2094 | while ((skb = __skb_dequeue(list: &frames))) { | 
|---|
| 2095 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 
|---|
| 2096 | struct ieee80211_hdr *hdr = (void *) skb->data; | 
|---|
| 2097 | u8 *qoshdr = NULL; | 
|---|
| 2098 |  | 
|---|
| 2099 | num++; | 
|---|
| 2100 |  | 
|---|
| 2101 | /* | 
|---|
| 2102 | * Tell TX path to send this frame even though the | 
|---|
| 2103 | * STA may still remain is PS mode after this frame | 
|---|
| 2104 | * exchange. | 
|---|
| 2105 | */ | 
|---|
| 2106 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; | 
|---|
| 2107 | info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE; | 
|---|
| 2108 |  | 
|---|
| 2109 | /* | 
|---|
| 2110 | * Use MoreData flag to indicate whether there are | 
|---|
| 2111 | * more buffered frames for this STA | 
|---|
| 2112 | */ | 
|---|
| 2113 | if (more_data || !skb_queue_empty(list: &frames)) | 
|---|
| 2114 | hdr->frame_control |= | 
|---|
| 2115 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 
|---|
| 2116 | else | 
|---|
| 2117 | hdr->frame_control &= | 
|---|
| 2118 | cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | 
|---|
| 2119 |  | 
|---|
| 2120 | if (ieee80211_is_data_qos(fc: hdr->frame_control) || | 
|---|
| 2121 | ieee80211_is_qos_nullfunc(fc: hdr->frame_control)) | 
|---|
| 2122 | qoshdr = ieee80211_get_qos_ctl(hdr); | 
|---|
| 2123 |  | 
|---|
| 2124 | tids |= BIT(skb->priority); | 
|---|
| 2125 |  | 
|---|
| 2126 | __skb_queue_tail(list: &pending, newsk: skb); | 
|---|
| 2127 |  | 
|---|
| 2128 | /* end service period after last frame or add one */ | 
|---|
| 2129 | if (!skb_queue_empty(list: &frames)) | 
|---|
| 2130 | continue; | 
|---|
| 2131 |  | 
|---|
| 2132 | if (reason != IEEE80211_FRAME_RELEASE_UAPSD) { | 
|---|
| 2133 | /* for PS-Poll, there's only one frame */ | 
|---|
| 2134 | info->flags |= IEEE80211_TX_STATUS_EOSP | | 
|---|
| 2135 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 
|---|
| 2136 | break; | 
|---|
| 2137 | } | 
|---|
| 2138 |  | 
|---|
| 2139 | /* For uAPSD, things are a bit more complicated. If the | 
|---|
| 2140 | * last frame has a QoS header (i.e. is a QoS-data or | 
|---|
| 2141 | * QoS-nulldata frame) then just set the EOSP bit there | 
|---|
| 2142 | * and be done. | 
|---|
| 2143 | * If the frame doesn't have a QoS header (which means | 
|---|
| 2144 | * it should be a bufferable MMPDU) then we can't set | 
|---|
| 2145 | * the EOSP bit in the QoS header; add a QoS-nulldata | 
|---|
| 2146 | * frame to the list to send it after the MMPDU. | 
|---|
| 2147 | * | 
|---|
| 2148 | * Note that this code is only in the mac80211-release | 
|---|
| 2149 | * code path, we assume that the driver will not buffer | 
|---|
| 2150 | * anything but QoS-data frames, or if it does, will | 
|---|
| 2151 | * create the QoS-nulldata frame by itself if needed. | 
|---|
| 2152 | * | 
|---|
| 2153 | * Cf. 802.11-2012 10.2.1.10 (c). | 
|---|
| 2154 | */ | 
|---|
| 2155 | if (qoshdr) { | 
|---|
| 2156 | *qoshdr |= IEEE80211_QOS_CTL_EOSP; | 
|---|
| 2157 |  | 
|---|
| 2158 | info->flags |= IEEE80211_TX_STATUS_EOSP | | 
|---|
| 2159 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 
|---|
| 2160 | } else { | 
|---|
| 2161 | /* The standard isn't completely clear on this | 
|---|
| 2162 | * as it says the more-data bit should be set | 
|---|
| 2163 | * if there are more BUs. The QoS-Null frame | 
|---|
| 2164 | * we're about to send isn't buffered yet, we | 
|---|
| 2165 | * only create it below, but let's pretend it | 
|---|
| 2166 | * was buffered just in case some clients only | 
|---|
| 2167 | * expect more-data=0 when eosp=1. | 
|---|
| 2168 | */ | 
|---|
| 2169 | hdr->frame_control |= | 
|---|
| 2170 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 
|---|
| 2171 | need_null = true; | 
|---|
| 2172 | num++; | 
|---|
| 2173 | } | 
|---|
| 2174 | break; | 
|---|
| 2175 | } | 
|---|
| 2176 |  | 
|---|
| 2177 | drv_allow_buffered_frames(local, sta, tids, num_frames: num, | 
|---|
| 2178 | reason, more_data); | 
|---|
| 2179 |  | 
|---|
| 2180 | ieee80211_add_pending_skbs(local, skbs: &pending); | 
|---|
| 2181 |  | 
|---|
| 2182 | if (need_null) | 
|---|
| 2183 | ieee80211_send_null_response( | 
|---|
| 2184 | sta, tid: find_highest_prio_tid(tids), | 
|---|
| 2185 | reason, call_driver: false, more_data: false); | 
|---|
| 2186 |  | 
|---|
| 2187 | sta_info_recalc_tim(sta); | 
|---|
| 2188 | } else { | 
|---|
| 2189 | int tid; | 
|---|
| 2190 |  | 
|---|
| 2191 | /* | 
|---|
| 2192 | * We need to release a frame that is buffered somewhere in the | 
|---|
| 2193 | * driver ... it'll have to handle that. | 
|---|
| 2194 | * Note that the driver also has to check the number of frames | 
|---|
| 2195 | * on the TIDs we're releasing from - if there are more than | 
|---|
| 2196 | * n_frames it has to set the more-data bit (if we didn't ask | 
|---|
| 2197 | * it to set it anyway due to other buffered frames); if there | 
|---|
| 2198 | * are fewer than n_frames it has to make sure to adjust that | 
|---|
| 2199 | * to allow the service period to end properly. | 
|---|
| 2200 | */ | 
|---|
| 2201 | drv_release_buffered_frames(local, sta, tids: driver_release_tids, | 
|---|
| 2202 | num_frames: n_frames, reason, more_data); | 
|---|
| 2203 |  | 
|---|
| 2204 | /* | 
|---|
| 2205 | * Note that we don't recalculate the TIM bit here as it would | 
|---|
| 2206 | * most likely have no effect at all unless the driver told us | 
|---|
| 2207 | * that the TID(s) became empty before returning here from the | 
|---|
| 2208 | * release function. | 
|---|
| 2209 | * Either way, however, when the driver tells us that the TID(s) | 
|---|
| 2210 | * became empty or we find that a txq became empty, we'll do the | 
|---|
| 2211 | * TIM recalculation. | 
|---|
| 2212 | */ | 
|---|
| 2213 |  | 
|---|
| 2214 | for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { | 
|---|
| 2215 | if (!sta->sta.txq[tid] || | 
|---|
| 2216 | !(driver_release_tids & BIT(tid)) || | 
|---|
| 2217 | txq_has_queue(txq: sta->sta.txq[tid])) | 
|---|
| 2218 | continue; | 
|---|
| 2219 |  | 
|---|
| 2220 | sta_info_recalc_tim(sta); | 
|---|
| 2221 | break; | 
|---|
| 2222 | } | 
|---|
| 2223 | } | 
|---|
| 2224 | } | 
|---|
| 2225 |  | 
|---|
| 2226 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) | 
|---|
| 2227 | { | 
|---|
| 2228 | u8 ignore_for_response = sta->sta.uapsd_queues; | 
|---|
| 2229 |  | 
|---|
| 2230 | /* | 
|---|
| 2231 | * If all ACs are delivery-enabled then we should reply | 
|---|
| 2232 | * from any of them, if only some are enabled we reply | 
|---|
| 2233 | * only from the non-enabled ones. | 
|---|
| 2234 | */ | 
|---|
| 2235 | if (ignore_for_response == BIT(IEEE80211_NUM_ACS) - 1) | 
|---|
| 2236 | ignore_for_response = 0; | 
|---|
| 2237 |  | 
|---|
| 2238 | ieee80211_sta_ps_deliver_response(sta, n_frames: 1, ignored_acs: ignore_for_response, | 
|---|
| 2239 | reason: IEEE80211_FRAME_RELEASE_PSPOLL); | 
|---|
| 2240 | } | 
|---|
| 2241 |  | 
|---|
| 2242 | void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta) | 
|---|
| 2243 | { | 
|---|
| 2244 | int n_frames = sta->sta.max_sp; | 
|---|
| 2245 | u8 delivery_enabled = sta->sta.uapsd_queues; | 
|---|
| 2246 |  | 
|---|
| 2247 | /* | 
|---|
| 2248 | * If we ever grow support for TSPEC this might happen if | 
|---|
| 2249 | * the TSPEC update from hostapd comes in between a trigger | 
|---|
| 2250 | * frame setting WLAN_STA_UAPSD in the RX path and this | 
|---|
| 2251 | * actually getting called. | 
|---|
| 2252 | */ | 
|---|
| 2253 | if (!delivery_enabled) | 
|---|
| 2254 | return; | 
|---|
| 2255 |  | 
|---|
| 2256 | switch (sta->sta.max_sp) { | 
|---|
| 2257 | case 1: | 
|---|
| 2258 | n_frames = 2; | 
|---|
| 2259 | break; | 
|---|
| 2260 | case 2: | 
|---|
| 2261 | n_frames = 4; | 
|---|
| 2262 | break; | 
|---|
| 2263 | case 3: | 
|---|
| 2264 | n_frames = 6; | 
|---|
| 2265 | break; | 
|---|
| 2266 | case 0: | 
|---|
| 2267 | /* XXX: what is a good value? */ | 
|---|
| 2268 | n_frames = 128; | 
|---|
| 2269 | break; | 
|---|
| 2270 | } | 
|---|
| 2271 |  | 
|---|
| 2272 | ieee80211_sta_ps_deliver_response(sta, n_frames, ignored_acs: ~delivery_enabled, | 
|---|
| 2273 | reason: IEEE80211_FRAME_RELEASE_UAPSD); | 
|---|
| 2274 | } | 
|---|
| 2275 |  | 
|---|
| 2276 | void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | 
|---|
| 2277 | struct ieee80211_sta *pubsta, bool block) | 
|---|
| 2278 | { | 
|---|
| 2279 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 2280 |  | 
|---|
| 2281 | trace_api_sta_block_awake(local: sta->local, sta: pubsta, block); | 
|---|
| 2282 |  | 
|---|
| 2283 | if (block) { | 
|---|
| 2284 | set_sta_flag(sta, flag: WLAN_STA_PS_DRIVER); | 
|---|
| 2285 | ieee80211_clear_fast_xmit(sta); | 
|---|
| 2286 | return; | 
|---|
| 2287 | } | 
|---|
| 2288 |  | 
|---|
| 2289 | if (!test_sta_flag(sta, flag: WLAN_STA_PS_DRIVER)) | 
|---|
| 2290 | return; | 
|---|
| 2291 |  | 
|---|
| 2292 | if (!test_sta_flag(sta, flag: WLAN_STA_PS_STA)) { | 
|---|
| 2293 | set_sta_flag(sta, flag: WLAN_STA_PS_DELIVER); | 
|---|
| 2294 | clear_sta_flag(sta, flag: WLAN_STA_PS_DRIVER); | 
|---|
| 2295 | ieee80211_queue_work(hw, work: &sta->drv_deliver_wk); | 
|---|
| 2296 | } else if (test_sta_flag(sta, flag: WLAN_STA_PSPOLL) || | 
|---|
| 2297 | test_sta_flag(sta, flag: WLAN_STA_UAPSD)) { | 
|---|
| 2298 | /* must be asleep in this case */ | 
|---|
| 2299 | clear_sta_flag(sta, flag: WLAN_STA_PS_DRIVER); | 
|---|
| 2300 | ieee80211_queue_work(hw, work: &sta->drv_deliver_wk); | 
|---|
| 2301 | } else { | 
|---|
| 2302 | clear_sta_flag(sta, flag: WLAN_STA_PS_DRIVER); | 
|---|
| 2303 | ieee80211_check_fast_xmit(sta); | 
|---|
| 2304 | } | 
|---|
| 2305 | } | 
|---|
| 2306 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | 
|---|
| 2307 |  | 
|---|
| 2308 | void ieee80211_sta_eosp(struct ieee80211_sta *pubsta) | 
|---|
| 2309 | { | 
|---|
| 2310 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 2311 | struct ieee80211_local *local = sta->local; | 
|---|
| 2312 |  | 
|---|
| 2313 | trace_api_eosp(local, sta: pubsta); | 
|---|
| 2314 |  | 
|---|
| 2315 | clear_sta_flag(sta, flag: WLAN_STA_SP); | 
|---|
| 2316 | } | 
|---|
| 2317 | EXPORT_SYMBOL(ieee80211_sta_eosp); | 
|---|
| 2318 |  | 
|---|
| 2319 | void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid) | 
|---|
| 2320 | { | 
|---|
| 2321 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 2322 | enum ieee80211_frame_release_type reason; | 
|---|
| 2323 | bool more_data; | 
|---|
| 2324 |  | 
|---|
| 2325 | trace_api_send_eosp_nullfunc(local: sta->local, sta: pubsta, tid); | 
|---|
| 2326 |  | 
|---|
| 2327 | reason = IEEE80211_FRAME_RELEASE_UAPSD; | 
|---|
| 2328 | more_data = ieee80211_sta_ps_more_data(sta, ignored_acs: ~sta->sta.uapsd_queues, | 
|---|
| 2329 | reason, driver_release_tids: 0); | 
|---|
| 2330 |  | 
|---|
| 2331 | ieee80211_send_null_response(sta, tid, reason, call_driver: false, more_data); | 
|---|
| 2332 | } | 
|---|
| 2333 | EXPORT_SYMBOL(ieee80211_send_eosp_nullfunc); | 
|---|
| 2334 |  | 
|---|
| 2335 | void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, | 
|---|
| 2336 | u8 tid, bool buffered) | 
|---|
| 2337 | { | 
|---|
| 2338 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 2339 |  | 
|---|
| 2340 | if (WARN_ON(tid >= IEEE80211_NUM_TIDS)) | 
|---|
| 2341 | return; | 
|---|
| 2342 |  | 
|---|
| 2343 | trace_api_sta_set_buffered(local: sta->local, sta: pubsta, tid, buffered); | 
|---|
| 2344 |  | 
|---|
| 2345 | if (buffered) | 
|---|
| 2346 | set_bit(nr: tid, addr: &sta->driver_buffered_tids); | 
|---|
| 2347 | else | 
|---|
| 2348 | clear_bit(nr: tid, addr: &sta->driver_buffered_tids); | 
|---|
| 2349 |  | 
|---|
| 2350 | sta_info_recalc_tim(sta); | 
|---|
| 2351 | } | 
|---|
| 2352 | EXPORT_SYMBOL(ieee80211_sta_set_buffered); | 
|---|
| 2353 |  | 
|---|
| 2354 | void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, | 
|---|
| 2355 | u32 tx_airtime, u32 rx_airtime) | 
|---|
| 2356 | { | 
|---|
| 2357 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 2358 | struct ieee80211_local *local = sta->sdata->local; | 
|---|
| 2359 | u8 ac = ieee80211_ac_from_tid(tid); | 
|---|
| 2360 | u32 airtime = 0; | 
|---|
| 2361 |  | 
|---|
| 2362 | if (sta->local->airtime_flags & AIRTIME_USE_TX) | 
|---|
| 2363 | airtime += tx_airtime; | 
|---|
| 2364 | if (sta->local->airtime_flags & AIRTIME_USE_RX) | 
|---|
| 2365 | airtime += rx_airtime; | 
|---|
| 2366 |  | 
|---|
| 2367 | spin_lock_bh(lock: &local->active_txq_lock[ac]); | 
|---|
| 2368 | sta->airtime[ac].tx_airtime += tx_airtime; | 
|---|
| 2369 | sta->airtime[ac].rx_airtime += rx_airtime; | 
|---|
| 2370 |  | 
|---|
| 2371 | if (ieee80211_sta_keep_active(sta, ac)) | 
|---|
| 2372 | sta->airtime[ac].deficit -= airtime; | 
|---|
| 2373 |  | 
|---|
| 2374 | spin_unlock_bh(lock: &local->active_txq_lock[ac]); | 
|---|
| 2375 | } | 
|---|
| 2376 | EXPORT_SYMBOL(ieee80211_sta_register_airtime); | 
|---|
| 2377 |  | 
|---|
| 2378 | void __ieee80211_sta_recalc_aggregates(struct sta_info *sta, u16 active_links) | 
|---|
| 2379 | { | 
|---|
| 2380 | bool first = true; | 
|---|
| 2381 | int link_id; | 
|---|
| 2382 |  | 
|---|
| 2383 | if (!sta->sta.valid_links || !sta->sta.mlo) { | 
|---|
| 2384 | sta->sta.cur = &sta->sta.deflink.agg; | 
|---|
| 2385 | return; | 
|---|
| 2386 | } | 
|---|
| 2387 |  | 
|---|
| 2388 | rcu_read_lock(); | 
|---|
| 2389 | for (link_id = 0; link_id < ARRAY_SIZE((sta)->link); link_id++) { | 
|---|
| 2390 | struct ieee80211_link_sta *link_sta; | 
|---|
| 2391 | int i; | 
|---|
| 2392 |  | 
|---|
| 2393 | if (!(active_links & BIT(link_id))) | 
|---|
| 2394 | continue; | 
|---|
| 2395 |  | 
|---|
| 2396 | link_sta = rcu_dereference(sta->sta.link[link_id]); | 
|---|
| 2397 | if (!link_sta) | 
|---|
| 2398 | continue; | 
|---|
| 2399 |  | 
|---|
| 2400 | if (first) { | 
|---|
| 2401 | sta->cur = sta->sta.deflink.agg; | 
|---|
| 2402 | first = false; | 
|---|
| 2403 | continue; | 
|---|
| 2404 | } | 
|---|
| 2405 |  | 
|---|
| 2406 | sta->cur.max_amsdu_len = | 
|---|
| 2407 | min(sta->cur.max_amsdu_len, | 
|---|
| 2408 | link_sta->agg.max_amsdu_len); | 
|---|
| 2409 | sta->cur.max_rc_amsdu_len = | 
|---|
| 2410 | min(sta->cur.max_rc_amsdu_len, | 
|---|
| 2411 | link_sta->agg.max_rc_amsdu_len); | 
|---|
| 2412 |  | 
|---|
| 2413 | for (i = 0; i < ARRAY_SIZE(sta->cur.max_tid_amsdu_len); i++) | 
|---|
| 2414 | sta->cur.max_tid_amsdu_len[i] = | 
|---|
| 2415 | min(sta->cur.max_tid_amsdu_len[i], | 
|---|
| 2416 | link_sta->agg.max_tid_amsdu_len[i]); | 
|---|
| 2417 | } | 
|---|
| 2418 | rcu_read_unlock(); | 
|---|
| 2419 |  | 
|---|
| 2420 | sta->sta.cur = &sta->cur; | 
|---|
| 2421 | } | 
|---|
| 2422 |  | 
|---|
| 2423 | void ieee80211_sta_recalc_aggregates(struct ieee80211_sta *pubsta) | 
|---|
| 2424 | { | 
|---|
| 2425 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 2426 |  | 
|---|
| 2427 | __ieee80211_sta_recalc_aggregates(sta, active_links: sta->sdata->vif.active_links); | 
|---|
| 2428 | } | 
|---|
| 2429 | EXPORT_SYMBOL(ieee80211_sta_recalc_aggregates); | 
|---|
| 2430 |  | 
|---|
| 2431 | void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, | 
|---|
| 2432 | struct sta_info *sta, u8 ac, | 
|---|
| 2433 | u16 tx_airtime, bool tx_completed) | 
|---|
| 2434 | { | 
|---|
| 2435 | int tx_pending; | 
|---|
| 2436 |  | 
|---|
| 2437 | if (!wiphy_ext_feature_isset(wiphy: local->hw.wiphy, ftidx: NL80211_EXT_FEATURE_AQL)) | 
|---|
| 2438 | return; | 
|---|
| 2439 |  | 
|---|
| 2440 | if (!tx_completed) { | 
|---|
| 2441 | if (sta) | 
|---|
| 2442 | atomic_add(i: tx_airtime, | 
|---|
| 2443 | v: &sta->airtime[ac].aql_tx_pending); | 
|---|
| 2444 |  | 
|---|
| 2445 | atomic_add(i: tx_airtime, v: &local->aql_total_pending_airtime); | 
|---|
| 2446 | atomic_add(i: tx_airtime, v: &local->aql_ac_pending_airtime[ac]); | 
|---|
| 2447 | return; | 
|---|
| 2448 | } | 
|---|
| 2449 |  | 
|---|
| 2450 | if (sta) { | 
|---|
| 2451 | tx_pending = atomic_sub_return(i: tx_airtime, | 
|---|
| 2452 | v: &sta->airtime[ac].aql_tx_pending); | 
|---|
| 2453 | if (tx_pending < 0) | 
|---|
| 2454 | atomic_cmpxchg(v: &sta->airtime[ac].aql_tx_pending, | 
|---|
| 2455 | old: tx_pending, new: 0); | 
|---|
| 2456 | } | 
|---|
| 2457 |  | 
|---|
| 2458 | atomic_sub(i: tx_airtime, v: &local->aql_total_pending_airtime); | 
|---|
| 2459 | tx_pending = atomic_sub_return(i: tx_airtime, | 
|---|
| 2460 | v: &local->aql_ac_pending_airtime[ac]); | 
|---|
| 2461 | if (WARN_ONCE(tx_pending < 0, | 
|---|
| 2462 | "Device %s AC %d pending airtime underflow: %u, %u", | 
|---|
| 2463 | wiphy_name(local->hw.wiphy), ac, tx_pending, | 
|---|
| 2464 | tx_airtime)) { | 
|---|
| 2465 | atomic_cmpxchg(v: &local->aql_ac_pending_airtime[ac], | 
|---|
| 2466 | old: tx_pending, new: 0); | 
|---|
| 2467 | atomic_sub(i: tx_pending, v: &local->aql_total_pending_airtime); | 
|---|
| 2468 | } | 
|---|
| 2469 | } | 
|---|
| 2470 |  | 
|---|
| 2471 | static struct ieee80211_sta_rx_stats * | 
|---|
| 2472 | sta_get_last_rx_stats(struct sta_info *sta, int link_id) | 
|---|
| 2473 | { | 
|---|
| 2474 | struct ieee80211_sta_rx_stats *stats; | 
|---|
| 2475 | struct link_sta_info *link_sta_info; | 
|---|
| 2476 | int cpu; | 
|---|
| 2477 |  | 
|---|
| 2478 | if (link_id < 0) | 
|---|
| 2479 | link_sta_info = &sta->deflink; | 
|---|
| 2480 | else | 
|---|
| 2481 | link_sta_info = wiphy_dereference(sta->local->hw.wiphy, | 
|---|
| 2482 | sta->link[link_id]); | 
|---|
| 2483 |  | 
|---|
| 2484 | stats = &link_sta_info->rx_stats; | 
|---|
| 2485 |  | 
|---|
| 2486 | if (!link_sta_info->pcpu_rx_stats) | 
|---|
| 2487 | return stats; | 
|---|
| 2488 |  | 
|---|
| 2489 | for_each_possible_cpu(cpu) { | 
|---|
| 2490 | struct ieee80211_sta_rx_stats *cpustats; | 
|---|
| 2491 |  | 
|---|
| 2492 | cpustats = per_cpu_ptr(link_sta_info->pcpu_rx_stats, cpu); | 
|---|
| 2493 |  | 
|---|
| 2494 | if (time_after(cpustats->last_rx, stats->last_rx)) | 
|---|
| 2495 | stats = cpustats; | 
|---|
| 2496 | } | 
|---|
| 2497 |  | 
|---|
| 2498 | return stats; | 
|---|
| 2499 | } | 
|---|
| 2500 |  | 
|---|
| 2501 | static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate, | 
|---|
| 2502 | struct rate_info *rinfo) | 
|---|
| 2503 | { | 
|---|
| 2504 | rinfo->bw = STA_STATS_GET(BW, rate); | 
|---|
| 2505 |  | 
|---|
| 2506 | switch (STA_STATS_GET(TYPE, rate)) { | 
|---|
| 2507 | case STA_STATS_RATE_TYPE_VHT: | 
|---|
| 2508 | rinfo->flags = RATE_INFO_FLAGS_VHT_MCS; | 
|---|
| 2509 | rinfo->mcs = STA_STATS_GET(VHT_MCS, rate); | 
|---|
| 2510 | rinfo->nss = STA_STATS_GET(VHT_NSS, rate); | 
|---|
| 2511 | if (STA_STATS_GET(SGI, rate)) | 
|---|
| 2512 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | 
|---|
| 2513 | break; | 
|---|
| 2514 | case STA_STATS_RATE_TYPE_HT: | 
|---|
| 2515 | rinfo->flags = RATE_INFO_FLAGS_MCS; | 
|---|
| 2516 | rinfo->mcs = STA_STATS_GET(HT_MCS, rate); | 
|---|
| 2517 | if (STA_STATS_GET(SGI, rate)) | 
|---|
| 2518 | rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; | 
|---|
| 2519 | break; | 
|---|
| 2520 | case STA_STATS_RATE_TYPE_LEGACY: { | 
|---|
| 2521 | struct ieee80211_supported_band *sband; | 
|---|
| 2522 | u16 brate; | 
|---|
| 2523 | unsigned int shift; | 
|---|
| 2524 | int band = STA_STATS_GET(LEGACY_BAND, rate); | 
|---|
| 2525 | int rate_idx = STA_STATS_GET(LEGACY_IDX, rate); | 
|---|
| 2526 |  | 
|---|
| 2527 | sband = local->hw.wiphy->bands[band]; | 
|---|
| 2528 |  | 
|---|
| 2529 | if (WARN_ON_ONCE(!sband->bitrates)) | 
|---|
| 2530 | break; | 
|---|
| 2531 |  | 
|---|
| 2532 | brate = sband->bitrates[rate_idx].bitrate; | 
|---|
| 2533 | if (rinfo->bw == RATE_INFO_BW_5) | 
|---|
| 2534 | shift = 2; | 
|---|
| 2535 | else if (rinfo->bw == RATE_INFO_BW_10) | 
|---|
| 2536 | shift = 1; | 
|---|
| 2537 | else | 
|---|
| 2538 | shift = 0; | 
|---|
| 2539 | rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift); | 
|---|
| 2540 | break; | 
|---|
| 2541 | } | 
|---|
| 2542 | case STA_STATS_RATE_TYPE_HE: | 
|---|
| 2543 | rinfo->flags = RATE_INFO_FLAGS_HE_MCS; | 
|---|
| 2544 | rinfo->mcs = STA_STATS_GET(HE_MCS, rate); | 
|---|
| 2545 | rinfo->nss = STA_STATS_GET(HE_NSS, rate); | 
|---|
| 2546 | rinfo->he_gi = STA_STATS_GET(HE_GI, rate); | 
|---|
| 2547 | rinfo->he_ru_alloc = STA_STATS_GET(HE_RU, rate); | 
|---|
| 2548 | rinfo->he_dcm = STA_STATS_GET(HE_DCM, rate); | 
|---|
| 2549 | break; | 
|---|
| 2550 | case STA_STATS_RATE_TYPE_EHT: | 
|---|
| 2551 | rinfo->flags = RATE_INFO_FLAGS_EHT_MCS; | 
|---|
| 2552 | rinfo->mcs = STA_STATS_GET(EHT_MCS, rate); | 
|---|
| 2553 | rinfo->nss = STA_STATS_GET(EHT_NSS, rate); | 
|---|
| 2554 | rinfo->eht_gi = STA_STATS_GET(EHT_GI, rate); | 
|---|
| 2555 | rinfo->eht_ru_alloc = STA_STATS_GET(EHT_RU, rate); | 
|---|
| 2556 | break; | 
|---|
| 2557 | } | 
|---|
| 2558 | } | 
|---|
| 2559 |  | 
|---|
| 2560 | static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo, | 
|---|
| 2561 | int link_id) | 
|---|
| 2562 | { | 
|---|
| 2563 | u32 rate = READ_ONCE(sta_get_last_rx_stats(sta, link_id)->last_rate); | 
|---|
| 2564 |  | 
|---|
| 2565 | if (rate == STA_STATS_RATE_INVALID) | 
|---|
| 2566 | return -EINVAL; | 
|---|
| 2567 |  | 
|---|
| 2568 | sta_stats_decode_rate(local: sta->local, rate, rinfo); | 
|---|
| 2569 | return 0; | 
|---|
| 2570 | } | 
|---|
| 2571 |  | 
|---|
| 2572 | static inline u64 sta_get_tidstats_msdu(struct ieee80211_sta_rx_stats *rxstats, | 
|---|
| 2573 | int tid) | 
|---|
| 2574 | { | 
|---|
| 2575 | unsigned int start; | 
|---|
| 2576 | u64 value; | 
|---|
| 2577 |  | 
|---|
| 2578 | do { | 
|---|
| 2579 | start = u64_stats_fetch_begin(syncp: &rxstats->syncp); | 
|---|
| 2580 | value = rxstats->msdu[tid]; | 
|---|
| 2581 | } while (u64_stats_fetch_retry(syncp: &rxstats->syncp, start)); | 
|---|
| 2582 |  | 
|---|
| 2583 | return value; | 
|---|
| 2584 | } | 
|---|
| 2585 |  | 
|---|
| 2586 | static void sta_set_tidstats(struct sta_info *sta, | 
|---|
| 2587 | struct cfg80211_tid_stats *tidstats, | 
|---|
| 2588 | int tid, int link_id) | 
|---|
| 2589 | { | 
|---|
| 2590 | struct ieee80211_local *local = sta->local; | 
|---|
| 2591 | struct link_sta_info *link_sta_info; | 
|---|
| 2592 | int cpu; | 
|---|
| 2593 |  | 
|---|
| 2594 | if (link_id < 0) | 
|---|
| 2595 | link_sta_info = &sta->deflink; | 
|---|
| 2596 | else | 
|---|
| 2597 | link_sta_info = wiphy_dereference(sta->local->hw.wiphy, | 
|---|
| 2598 | sta->link[link_id]); | 
|---|
| 2599 |  | 
|---|
| 2600 | if (!(tidstats->filled & BIT(NL80211_TID_STATS_RX_MSDU))) { | 
|---|
| 2601 | tidstats->rx_msdu += | 
|---|
| 2602 | sta_get_tidstats_msdu(rxstats: &link_sta_info->rx_stats, | 
|---|
| 2603 | tid); | 
|---|
| 2604 |  | 
|---|
| 2605 | if (link_sta_info->pcpu_rx_stats) { | 
|---|
| 2606 | for_each_possible_cpu(cpu) { | 
|---|
| 2607 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 2608 |  | 
|---|
| 2609 | cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, | 
|---|
| 2610 | cpu); | 
|---|
| 2611 | tidstats->rx_msdu += | 
|---|
| 2612 | sta_get_tidstats_msdu(rxstats: cpurxs, tid); | 
|---|
| 2613 | } | 
|---|
| 2614 | } | 
|---|
| 2615 |  | 
|---|
| 2616 | tidstats->filled |= BIT(NL80211_TID_STATS_RX_MSDU); | 
|---|
| 2617 | } | 
|---|
| 2618 |  | 
|---|
| 2619 | if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU))) { | 
|---|
| 2620 | tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU); | 
|---|
| 2621 | tidstats->tx_msdu = link_sta_info->tx_stats.msdu[tid]; | 
|---|
| 2622 | } | 
|---|
| 2623 |  | 
|---|
| 2624 | if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_RETRIES)) && | 
|---|
| 2625 | ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { | 
|---|
| 2626 | tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_RETRIES); | 
|---|
| 2627 | tidstats->tx_msdu_retries = | 
|---|
| 2628 | link_sta_info->status_stats.msdu_retries[tid]; | 
|---|
| 2629 | } | 
|---|
| 2630 |  | 
|---|
| 2631 | if (!(tidstats->filled & BIT(NL80211_TID_STATS_TX_MSDU_FAILED)) && | 
|---|
| 2632 | ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { | 
|---|
| 2633 | tidstats->filled |= BIT(NL80211_TID_STATS_TX_MSDU_FAILED); | 
|---|
| 2634 | tidstats->tx_msdu_failed = | 
|---|
| 2635 | link_sta_info->status_stats.msdu_failed[tid]; | 
|---|
| 2636 | } | 
|---|
| 2637 |  | 
|---|
| 2638 | if (link_id < 0 && tid < IEEE80211_NUM_TIDS) { | 
|---|
| 2639 | spin_lock_bh(lock: &local->fq.lock); | 
|---|
| 2640 |  | 
|---|
| 2641 | tidstats->filled |= BIT(NL80211_TID_STATS_TXQ_STATS); | 
|---|
| 2642 | ieee80211_fill_txq_stats(txqstats: &tidstats->txq_stats, | 
|---|
| 2643 | txqi: to_txq_info(txq: sta->sta.txq[tid])); | 
|---|
| 2644 |  | 
|---|
| 2645 | spin_unlock_bh(lock: &local->fq.lock); | 
|---|
| 2646 | } | 
|---|
| 2647 | } | 
|---|
| 2648 |  | 
|---|
| 2649 | static inline u64 sta_get_stats_bytes(struct ieee80211_sta_rx_stats *rxstats) | 
|---|
| 2650 | { | 
|---|
| 2651 | unsigned int start; | 
|---|
| 2652 | u64 value; | 
|---|
| 2653 |  | 
|---|
| 2654 | do { | 
|---|
| 2655 | start = u64_stats_fetch_begin(syncp: &rxstats->syncp); | 
|---|
| 2656 | value = rxstats->bytes; | 
|---|
| 2657 | } while (u64_stats_fetch_retry(syncp: &rxstats->syncp, start)); | 
|---|
| 2658 |  | 
|---|
| 2659 | return value; | 
|---|
| 2660 | } | 
|---|
| 2661 |  | 
|---|
| 2662 | #ifdef CONFIG_MAC80211_MESH | 
|---|
| 2663 | static void sta_set_mesh_sinfo(struct sta_info *sta, | 
|---|
| 2664 | struct station_info *sinfo) | 
|---|
| 2665 | { | 
|---|
| 2666 | struct ieee80211_local *local = sta->sdata->local; | 
|---|
| 2667 |  | 
|---|
| 2668 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_LLID) | | 
|---|
| 2669 | BIT_ULL(NL80211_STA_INFO_PLID) | | 
|---|
| 2670 | BIT_ULL(NL80211_STA_INFO_PLINK_STATE) | | 
|---|
| 2671 | BIT_ULL(NL80211_STA_INFO_LOCAL_PM) | | 
|---|
| 2672 | BIT_ULL(NL80211_STA_INFO_PEER_PM) | | 
|---|
| 2673 | BIT_ULL(NL80211_STA_INFO_NONPEER_PM) | | 
|---|
| 2674 | BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_GATE) | | 
|---|
| 2675 | BIT_ULL(NL80211_STA_INFO_CONNECTED_TO_AS); | 
|---|
| 2676 |  | 
|---|
| 2677 | sinfo->llid = sta->mesh->llid; | 
|---|
| 2678 | sinfo->plid = sta->mesh->plid; | 
|---|
| 2679 | sinfo->plink_state = sta->mesh->plink_state; | 
|---|
| 2680 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { | 
|---|
| 2681 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_T_OFFSET); | 
|---|
| 2682 | sinfo->t_offset = sta->mesh->t_offset; | 
|---|
| 2683 | } | 
|---|
| 2684 | sinfo->local_pm = sta->mesh->local_pm; | 
|---|
| 2685 | sinfo->peer_pm = sta->mesh->peer_pm; | 
|---|
| 2686 | sinfo->nonpeer_pm = sta->mesh->nonpeer_pm; | 
|---|
| 2687 | sinfo->connected_to_gate = sta->mesh->connected_to_gate; | 
|---|
| 2688 | sinfo->connected_to_as = sta->mesh->connected_to_as; | 
|---|
| 2689 |  | 
|---|
| 2690 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_LINK_METRIC); | 
|---|
| 2691 | sinfo->airtime_link_metric = airtime_link_metric_get(local, sta); | 
|---|
| 2692 | } | 
|---|
| 2693 | #endif | 
|---|
| 2694 |  | 
|---|
| 2695 | void sta_set_accumulated_removed_links_sinfo(struct sta_info *sta, | 
|---|
| 2696 | struct station_info *sinfo) | 
|---|
| 2697 | { | 
|---|
| 2698 | /* Accumulating the removed link statistics. */ | 
|---|
| 2699 | sinfo->tx_packets = sta->rem_link_stats.tx_packets; | 
|---|
| 2700 | sinfo->rx_packets = sta->rem_link_stats.rx_packets; | 
|---|
| 2701 | sinfo->tx_bytes = sta->rem_link_stats.tx_bytes; | 
|---|
| 2702 | sinfo->rx_bytes = sta->rem_link_stats.rx_bytes; | 
|---|
| 2703 | sinfo->tx_retries = sta->rem_link_stats.tx_retries; | 
|---|
| 2704 | sinfo->tx_failed = sta->rem_link_stats.tx_failed; | 
|---|
| 2705 | sinfo->rx_dropped_misc = sta->rem_link_stats.rx_dropped_misc; | 
|---|
| 2706 | sinfo->beacon_loss_count = sta->rem_link_stats.beacon_loss_count; | 
|---|
| 2707 | sinfo->expected_throughput = sta->rem_link_stats.expected_throughput; | 
|---|
| 2708 |  | 
|---|
| 2709 | if (sinfo->pertid) { | 
|---|
| 2710 | sinfo->pertid->rx_msdu = | 
|---|
| 2711 | sta->rem_link_stats.pertid_stats.rx_msdu; | 
|---|
| 2712 | sinfo->pertid->tx_msdu = | 
|---|
| 2713 | sta->rem_link_stats.pertid_stats.tx_msdu; | 
|---|
| 2714 | sinfo->pertid->tx_msdu_retries = | 
|---|
| 2715 | sta->rem_link_stats.pertid_stats.tx_msdu_retries; | 
|---|
| 2716 | sinfo->pertid->tx_msdu_failed = | 
|---|
| 2717 | sta->rem_link_stats.pertid_stats.tx_msdu_failed; | 
|---|
| 2718 | } | 
|---|
| 2719 | } | 
|---|
| 2720 |  | 
|---|
| 2721 | static void sta_set_link_sinfo(struct sta_info *sta, | 
|---|
| 2722 | struct link_station_info *link_sinfo, | 
|---|
| 2723 | struct ieee80211_link_data *link, | 
|---|
| 2724 | bool tidstats) | 
|---|
| 2725 | { | 
|---|
| 2726 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 2727 | struct ieee80211_sta_rx_stats *last_rxstats; | 
|---|
| 2728 | int i, ac, cpu, link_id = link->link_id; | 
|---|
| 2729 | struct link_sta_info *link_sta_info; | 
|---|
| 2730 | u32 thr = 0; | 
|---|
| 2731 |  | 
|---|
| 2732 | last_rxstats = sta_get_last_rx_stats(sta, link_id); | 
|---|
| 2733 |  | 
|---|
| 2734 | link_sta_info = wiphy_dereference(sta->local->hw.wiphy, | 
|---|
| 2735 | sta->link[link_id]); | 
|---|
| 2736 |  | 
|---|
| 2737 | /* do before driver, so beacon filtering drivers have a | 
|---|
| 2738 | * chance to e.g. just add the number of filtered beacons | 
|---|
| 2739 | * (or just modify the value entirely, of course) | 
|---|
| 2740 | */ | 
|---|
| 2741 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 
|---|
| 2742 | link_sinfo->rx_beacon = link->u.mgd.count_beacon_signal; | 
|---|
| 2743 |  | 
|---|
| 2744 | ether_addr_copy(dst: link_sinfo->addr, src: link_sta_info->addr); | 
|---|
| 2745 |  | 
|---|
| 2746 | drv_link_sta_statistics(local: sta->local, sdata, | 
|---|
| 2747 | link_sta: link_sta_info->pub, | 
|---|
| 2748 | link_sinfo); | 
|---|
| 2749 |  | 
|---|
| 2750 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | | 
|---|
| 2751 | BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | | 
|---|
| 2752 | BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); | 
|---|
| 2753 |  | 
|---|
| 2754 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 
|---|
| 2755 | link_sinfo->beacon_loss_count = | 
|---|
| 2756 | link->u.mgd.beacon_loss_count; | 
|---|
| 2757 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS); | 
|---|
| 2758 | } | 
|---|
| 2759 |  | 
|---|
| 2760 | link_sinfo->inactive_time = | 
|---|
| 2761 | jiffies_to_msecs(j: jiffies - ieee80211_sta_last_active(sta, link_id)); | 
|---|
| 2762 |  | 
|---|
| 2763 | if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | | 
|---|
| 2764 | BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { | 
|---|
| 2765 | link_sinfo->tx_bytes = 0; | 
|---|
| 2766 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 2767 | link_sinfo->tx_bytes += | 
|---|
| 2768 | link_sta_info->tx_stats.bytes[ac]; | 
|---|
| 2769 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); | 
|---|
| 2770 | } | 
|---|
| 2771 |  | 
|---|
| 2772 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { | 
|---|
| 2773 | link_sinfo->tx_packets = 0; | 
|---|
| 2774 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 2775 | link_sinfo->tx_packets += | 
|---|
| 2776 | link_sta_info->tx_stats.packets[ac]; | 
|---|
| 2777 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); | 
|---|
| 2778 | } | 
|---|
| 2779 |  | 
|---|
| 2780 | if (!(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) | | 
|---|
| 2781 | BIT_ULL(NL80211_STA_INFO_RX_BYTES)))) { | 
|---|
| 2782 | link_sinfo->rx_bytes += | 
|---|
| 2783 | sta_get_stats_bytes(rxstats: &link_sta_info->rx_stats); | 
|---|
| 2784 |  | 
|---|
| 2785 | if (link_sta_info->pcpu_rx_stats) { | 
|---|
| 2786 | for_each_possible_cpu(cpu) { | 
|---|
| 2787 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 2788 |  | 
|---|
| 2789 | cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, | 
|---|
| 2790 | cpu); | 
|---|
| 2791 | link_sinfo->rx_bytes += | 
|---|
| 2792 | sta_get_stats_bytes(rxstats: cpurxs); | 
|---|
| 2793 | } | 
|---|
| 2794 | } | 
|---|
| 2795 |  | 
|---|
| 2796 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); | 
|---|
| 2797 | } | 
|---|
| 2798 |  | 
|---|
| 2799 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { | 
|---|
| 2800 | link_sinfo->rx_packets = link_sta_info->rx_stats.packets; | 
|---|
| 2801 | if (link_sta_info->pcpu_rx_stats) { | 
|---|
| 2802 | for_each_possible_cpu(cpu) { | 
|---|
| 2803 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 2804 |  | 
|---|
| 2805 | cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, | 
|---|
| 2806 | cpu); | 
|---|
| 2807 | link_sinfo->rx_packets += cpurxs->packets; | 
|---|
| 2808 | } | 
|---|
| 2809 | } | 
|---|
| 2810 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); | 
|---|
| 2811 | } | 
|---|
| 2812 |  | 
|---|
| 2813 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES))) { | 
|---|
| 2814 | link_sinfo->tx_retries = | 
|---|
| 2815 | link_sta_info->status_stats.retry_count; | 
|---|
| 2816 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); | 
|---|
| 2817 | } | 
|---|
| 2818 |  | 
|---|
| 2819 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))) { | 
|---|
| 2820 | link_sinfo->tx_failed = | 
|---|
| 2821 | link_sta_info->status_stats.retry_failed; | 
|---|
| 2822 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); | 
|---|
| 2823 | } | 
|---|
| 2824 |  | 
|---|
| 2825 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) { | 
|---|
| 2826 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 2827 | link_sinfo->rx_duration += sta->airtime[ac].rx_airtime; | 
|---|
| 2828 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); | 
|---|
| 2829 | } | 
|---|
| 2830 |  | 
|---|
| 2831 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) { | 
|---|
| 2832 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 2833 | link_sinfo->tx_duration += sta->airtime[ac].tx_airtime; | 
|---|
| 2834 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); | 
|---|
| 2835 | } | 
|---|
| 2836 |  | 
|---|
| 2837 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { | 
|---|
| 2838 | link_sinfo->airtime_weight = sta->airtime_weight; | 
|---|
| 2839 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); | 
|---|
| 2840 | } | 
|---|
| 2841 |  | 
|---|
| 2842 | link_sinfo->rx_dropped_misc = link_sta_info->rx_stats.dropped; | 
|---|
| 2843 | if (link_sta_info->pcpu_rx_stats) { | 
|---|
| 2844 | for_each_possible_cpu(cpu) { | 
|---|
| 2845 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 2846 |  | 
|---|
| 2847 | cpurxs = per_cpu_ptr(link_sta_info->pcpu_rx_stats, | 
|---|
| 2848 | cpu); | 
|---|
| 2849 | link_sinfo->rx_dropped_misc += cpurxs->dropped; | 
|---|
| 2850 | } | 
|---|
| 2851 | } | 
|---|
| 2852 |  | 
|---|
| 2853 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 
|---|
| 2854 | !(sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)) { | 
|---|
| 2855 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | | 
|---|
| 2856 | BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); | 
|---|
| 2857 | link_sinfo->rx_beacon_signal_avg = | 
|---|
| 2858 | ieee80211_ave_rssi(vif: &sdata->vif, link_id: -1); | 
|---|
| 2859 | } | 
|---|
| 2860 |  | 
|---|
| 2861 | if (ieee80211_hw_check(&sta->local->hw, SIGNAL_DBM) || | 
|---|
| 2862 | ieee80211_hw_check(&sta->local->hw, SIGNAL_UNSPEC)) { | 
|---|
| 2863 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL))) { | 
|---|
| 2864 | link_sinfo->signal = (s8)last_rxstats->last_signal; | 
|---|
| 2865 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); | 
|---|
| 2866 | } | 
|---|
| 2867 |  | 
|---|
| 2868 | if (!link_sta_info->pcpu_rx_stats && | 
|---|
| 2869 | !(link_sinfo->filled & | 
|---|
| 2870 | BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))) { | 
|---|
| 2871 | link_sinfo->signal_avg = | 
|---|
| 2872 | -ewma_signal_read(e: &link_sta_info->rx_stats_avg.signal); | 
|---|
| 2873 | link_sinfo->filled |= | 
|---|
| 2874 | BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); | 
|---|
| 2875 | } | 
|---|
| 2876 | } | 
|---|
| 2877 |  | 
|---|
| 2878 | /* for the average - if pcpu_rx_stats isn't set - rxstats must point to | 
|---|
| 2879 | * the sta->rx_stats struct, so the check here is fine with and without | 
|---|
| 2880 | * pcpu statistics | 
|---|
| 2881 | */ | 
|---|
| 2882 | if (last_rxstats->chains && | 
|---|
| 2883 | !(link_sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | | 
|---|
| 2884 | BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { | 
|---|
| 2885 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); | 
|---|
| 2886 | if (!link_sta_info->pcpu_rx_stats) | 
|---|
| 2887 | link_sinfo->filled |= | 
|---|
| 2888 | BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); | 
|---|
| 2889 |  | 
|---|
| 2890 | link_sinfo->chains = last_rxstats->chains; | 
|---|
| 2891 |  | 
|---|
| 2892 | for (i = 0; i < ARRAY_SIZE(link_sinfo->chain_signal); i++) { | 
|---|
| 2893 | link_sinfo->chain_signal[i] = | 
|---|
| 2894 | last_rxstats->chain_signal_last[i]; | 
|---|
| 2895 | link_sinfo->chain_signal_avg[i] = | 
|---|
| 2896 | -ewma_signal_read( | 
|---|
| 2897 | e: &link_sta_info->rx_stats_avg.chain_signal[i]); | 
|---|
| 2898 | } | 
|---|
| 2899 | } | 
|---|
| 2900 |  | 
|---|
| 2901 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && | 
|---|
| 2902 | ieee80211_rate_valid(rate: &link_sta_info->tx_stats.last_rate)) { | 
|---|
| 2903 | sta_set_rate_info_tx(sta, rate: &link_sta_info->tx_stats.last_rate, | 
|---|
| 2904 | rinfo: &link_sinfo->txrate); | 
|---|
| 2905 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); | 
|---|
| 2906 | } | 
|---|
| 2907 |  | 
|---|
| 2908 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE))) { | 
|---|
| 2909 | if (sta_set_rate_info_rx(sta, rinfo: &link_sinfo->rxrate, | 
|---|
| 2910 | link_id) == 0) | 
|---|
| 2911 | link_sinfo->filled |= | 
|---|
| 2912 | BIT_ULL(NL80211_STA_INFO_RX_BITRATE); | 
|---|
| 2913 | } | 
|---|
| 2914 |  | 
|---|
| 2915 | if (tidstats && !cfg80211_link_sinfo_alloc_tid_stats(link_sinfo, | 
|---|
| 2916 | GFP_KERNEL)) { | 
|---|
| 2917 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) | 
|---|
| 2918 | sta_set_tidstats(sta, tidstats: &link_sinfo->pertid[i], tid: i, | 
|---|
| 2919 | link_id); | 
|---|
| 2920 | } | 
|---|
| 2921 |  | 
|---|
| 2922 | link_sinfo->bss_param.flags = 0; | 
|---|
| 2923 | if (sdata->vif.bss_conf.use_cts_prot) | 
|---|
| 2924 | link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; | 
|---|
| 2925 | if (sdata->vif.bss_conf.use_short_preamble) | 
|---|
| 2926 | link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; | 
|---|
| 2927 | if (sdata->vif.bss_conf.use_short_slot) | 
|---|
| 2928 | link_sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; | 
|---|
| 2929 | link_sinfo->bss_param.dtim_period = link->conf->dtim_period; | 
|---|
| 2930 | link_sinfo->bss_param.beacon_interval = link->conf->beacon_int; | 
|---|
| 2931 |  | 
|---|
| 2932 | thr = sta_get_expected_throughput(sta); | 
|---|
| 2933 |  | 
|---|
| 2934 | if (thr != 0) { | 
|---|
| 2935 | link_sinfo->filled |= | 
|---|
| 2936 | BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT); | 
|---|
| 2937 | link_sinfo->expected_throughput = thr; | 
|---|
| 2938 | } | 
|---|
| 2939 |  | 
|---|
| 2940 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) && | 
|---|
| 2941 | link_sta_info->status_stats.ack_signal_filled) { | 
|---|
| 2942 | link_sinfo->ack_signal = | 
|---|
| 2943 | link_sta_info->status_stats.last_ack_signal; | 
|---|
| 2944 | link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); | 
|---|
| 2945 | } | 
|---|
| 2946 |  | 
|---|
| 2947 | if (!(link_sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) && | 
|---|
| 2948 | link_sta_info->status_stats.ack_signal_filled) { | 
|---|
| 2949 | link_sinfo->avg_ack_signal = | 
|---|
| 2950 | -(s8)ewma_avg_signal_read( | 
|---|
| 2951 | e: &link_sta_info->status_stats.avg_ack_signal); | 
|---|
| 2952 | link_sinfo->filled |= | 
|---|
| 2953 | BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); | 
|---|
| 2954 | } | 
|---|
| 2955 | } | 
|---|
| 2956 |  | 
|---|
| 2957 | void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo, | 
|---|
| 2958 | bool tidstats) | 
|---|
| 2959 | { | 
|---|
| 2960 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 2961 | struct ieee80211_local *local = sdata->local; | 
|---|
| 2962 | u32 thr = 0; | 
|---|
| 2963 | int i, ac, cpu; | 
|---|
| 2964 | struct ieee80211_sta_rx_stats *last_rxstats; | 
|---|
| 2965 |  | 
|---|
| 2966 | last_rxstats = sta_get_last_rx_stats(sta, link_id: -1); | 
|---|
| 2967 |  | 
|---|
| 2968 | sinfo->generation = sdata->local->sta_generation; | 
|---|
| 2969 |  | 
|---|
| 2970 | /* do before driver, so beacon filtering drivers have a | 
|---|
| 2971 | * chance to e.g. just add the number of filtered beacons | 
|---|
| 2972 | * (or just modify the value entirely, of course) | 
|---|
| 2973 | */ | 
|---|
| 2974 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | 
|---|
| 2975 | sinfo->rx_beacon = sdata->deflink.u.mgd.count_beacon_signal; | 
|---|
| 2976 |  | 
|---|
| 2977 | drv_sta_statistics(local, sdata, sta: &sta->sta, sinfo); | 
|---|
| 2978 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME) | | 
|---|
| 2979 | BIT_ULL(NL80211_STA_INFO_STA_FLAGS) | | 
|---|
| 2980 | BIT_ULL(NL80211_STA_INFO_BSS_PARAM) | | 
|---|
| 2981 | BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME) | | 
|---|
| 2982 | BIT_ULL(NL80211_STA_INFO_ASSOC_AT_BOOTTIME) | | 
|---|
| 2983 | BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC); | 
|---|
| 2984 |  | 
|---|
| 2985 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 
|---|
| 2986 | sinfo->beacon_loss_count = | 
|---|
| 2987 | sdata->deflink.u.mgd.beacon_loss_count; | 
|---|
| 2988 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_LOSS); | 
|---|
| 2989 | } | 
|---|
| 2990 |  | 
|---|
| 2991 | sinfo->connected_time = ktime_get_seconds() - sta->last_connected; | 
|---|
| 2992 | sinfo->assoc_at = sta->assoc_at; | 
|---|
| 2993 | sinfo->inactive_time = | 
|---|
| 2994 | jiffies_to_msecs(j: jiffies - ieee80211_sta_last_active(sta, link_id: -1)); | 
|---|
| 2995 |  | 
|---|
| 2996 | if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES64) | | 
|---|
| 2997 | BIT_ULL(NL80211_STA_INFO_TX_BYTES)))) { | 
|---|
| 2998 | sinfo->tx_bytes = 0; | 
|---|
| 2999 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 3000 | sinfo->tx_bytes += sta->deflink.tx_stats.bytes[ac]; | 
|---|
| 3001 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); | 
|---|
| 3002 | } | 
|---|
| 3003 |  | 
|---|
| 3004 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_PACKETS))) { | 
|---|
| 3005 | sinfo->tx_packets = 0; | 
|---|
| 3006 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 3007 | sinfo->tx_packets += sta->deflink.tx_stats.packets[ac]; | 
|---|
| 3008 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); | 
|---|
| 3009 | } | 
|---|
| 3010 |  | 
|---|
| 3011 | if (!(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES64) | | 
|---|
| 3012 | BIT_ULL(NL80211_STA_INFO_RX_BYTES)))) { | 
|---|
| 3013 | sinfo->rx_bytes += sta_get_stats_bytes(rxstats: &sta->deflink.rx_stats); | 
|---|
| 3014 |  | 
|---|
| 3015 | if (sta->deflink.pcpu_rx_stats) { | 
|---|
| 3016 | for_each_possible_cpu(cpu) { | 
|---|
| 3017 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 3018 |  | 
|---|
| 3019 | cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, | 
|---|
| 3020 | cpu); | 
|---|
| 3021 | sinfo->rx_bytes += sta_get_stats_bytes(rxstats: cpurxs); | 
|---|
| 3022 | } | 
|---|
| 3023 | } | 
|---|
| 3024 |  | 
|---|
| 3025 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES64); | 
|---|
| 3026 | } | 
|---|
| 3027 |  | 
|---|
| 3028 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_PACKETS))) { | 
|---|
| 3029 | sinfo->rx_packets = sta->deflink.rx_stats.packets; | 
|---|
| 3030 | if (sta->deflink.pcpu_rx_stats) { | 
|---|
| 3031 | for_each_possible_cpu(cpu) { | 
|---|
| 3032 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 3033 |  | 
|---|
| 3034 | cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, | 
|---|
| 3035 | cpu); | 
|---|
| 3036 | sinfo->rx_packets += cpurxs->packets; | 
|---|
| 3037 | } | 
|---|
| 3038 | } | 
|---|
| 3039 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS); | 
|---|
| 3040 | } | 
|---|
| 3041 |  | 
|---|
| 3042 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_RETRIES))) { | 
|---|
| 3043 | sinfo->tx_retries = sta->deflink.status_stats.retry_count; | 
|---|
| 3044 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); | 
|---|
| 3045 | } | 
|---|
| 3046 |  | 
|---|
| 3047 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_FAILED))) { | 
|---|
| 3048 | sinfo->tx_failed = sta->deflink.status_stats.retry_failed; | 
|---|
| 3049 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); | 
|---|
| 3050 | } | 
|---|
| 3051 |  | 
|---|
| 3052 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) { | 
|---|
| 3053 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 3054 | sinfo->rx_duration += sta->airtime[ac].rx_airtime; | 
|---|
| 3055 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); | 
|---|
| 3056 | } | 
|---|
| 3057 |  | 
|---|
| 3058 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) { | 
|---|
| 3059 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | 
|---|
| 3060 | sinfo->tx_duration += sta->airtime[ac].tx_airtime; | 
|---|
| 3061 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); | 
|---|
| 3062 | } | 
|---|
| 3063 |  | 
|---|
| 3064 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { | 
|---|
| 3065 | sinfo->airtime_weight = sta->airtime_weight; | 
|---|
| 3066 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); | 
|---|
| 3067 | } | 
|---|
| 3068 |  | 
|---|
| 3069 | sinfo->rx_dropped_misc = sta->deflink.rx_stats.dropped; | 
|---|
| 3070 | if (sta->deflink.pcpu_rx_stats) { | 
|---|
| 3071 | for_each_possible_cpu(cpu) { | 
|---|
| 3072 | struct ieee80211_sta_rx_stats *cpurxs; | 
|---|
| 3073 |  | 
|---|
| 3074 | cpurxs = per_cpu_ptr(sta->deflink.pcpu_rx_stats, cpu); | 
|---|
| 3075 | sinfo->rx_dropped_misc += cpurxs->dropped; | 
|---|
| 3076 | } | 
|---|
| 3077 | } | 
|---|
| 3078 |  | 
|---|
| 3079 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 
|---|
| 3080 | !(sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)) { | 
|---|
| 3081 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_BEACON_RX) | | 
|---|
| 3082 | BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG); | 
|---|
| 3083 | sinfo->rx_beacon_signal_avg = | 
|---|
| 3084 | ieee80211_ave_rssi(vif: &sdata->vif, link_id: -1); | 
|---|
| 3085 | } | 
|---|
| 3086 |  | 
|---|
| 3087 | if (ieee80211_hw_check(&sta->local->hw, SIGNAL_DBM) || | 
|---|
| 3088 | ieee80211_hw_check(&sta->local->hw, SIGNAL_UNSPEC)) { | 
|---|
| 3089 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL))) { | 
|---|
| 3090 | sinfo->signal = (s8)last_rxstats->last_signal; | 
|---|
| 3091 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); | 
|---|
| 3092 | } | 
|---|
| 3093 |  | 
|---|
| 3094 | if (!sta->deflink.pcpu_rx_stats && | 
|---|
| 3095 | !(sinfo->filled & BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG))) { | 
|---|
| 3096 | sinfo->signal_avg = | 
|---|
| 3097 | -ewma_signal_read(e: &sta->deflink.rx_stats_avg.signal); | 
|---|
| 3098 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); | 
|---|
| 3099 | } | 
|---|
| 3100 | } | 
|---|
| 3101 |  | 
|---|
| 3102 | /* for the average - if pcpu_rx_stats isn't set - rxstats must point to | 
|---|
| 3103 | * the sta->rx_stats struct, so the check here is fine with and without | 
|---|
| 3104 | * pcpu statistics | 
|---|
| 3105 | */ | 
|---|
| 3106 | if (last_rxstats->chains && | 
|---|
| 3107 | !(sinfo->filled & (BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL) | | 
|---|
| 3108 | BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)))) { | 
|---|
| 3109 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); | 
|---|
| 3110 | if (!sta->deflink.pcpu_rx_stats) | 
|---|
| 3111 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); | 
|---|
| 3112 |  | 
|---|
| 3113 | sinfo->chains = last_rxstats->chains; | 
|---|
| 3114 |  | 
|---|
| 3115 | for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { | 
|---|
| 3116 | sinfo->chain_signal[i] = | 
|---|
| 3117 | last_rxstats->chain_signal_last[i]; | 
|---|
| 3118 | sinfo->chain_signal_avg[i] = | 
|---|
| 3119 | -ewma_signal_read(e: &sta->deflink.rx_stats_avg.chain_signal[i]); | 
|---|
| 3120 | } | 
|---|
| 3121 | } | 
|---|
| 3122 |  | 
|---|
| 3123 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) && | 
|---|
| 3124 | !sta->sta.valid_links && | 
|---|
| 3125 | ieee80211_rate_valid(rate: &sta->deflink.tx_stats.last_rate)) { | 
|---|
| 3126 | sta_set_rate_info_tx(sta, rate: &sta->deflink.tx_stats.last_rate, | 
|---|
| 3127 | rinfo: &sinfo->txrate); | 
|---|
| 3128 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); | 
|---|
| 3129 | } | 
|---|
| 3130 |  | 
|---|
| 3131 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) && | 
|---|
| 3132 | !sta->sta.valid_links) { | 
|---|
| 3133 | if (sta_set_rate_info_rx(sta, rinfo: &sinfo->rxrate, link_id: -1) == 0) | 
|---|
| 3134 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE); | 
|---|
| 3135 | } | 
|---|
| 3136 |  | 
|---|
| 3137 | if (tidstats && !cfg80211_sinfo_alloc_tid_stats(sinfo, GFP_KERNEL)) { | 
|---|
| 3138 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) | 
|---|
| 3139 | sta_set_tidstats(sta, tidstats: &sinfo->pertid[i], tid: i, link_id: -1); | 
|---|
| 3140 | } | 
|---|
| 3141 |  | 
|---|
| 3142 | #ifdef CONFIG_MAC80211_MESH | 
|---|
| 3143 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 
|---|
| 3144 | sta_set_mesh_sinfo(sta, sinfo); | 
|---|
| 3145 | #endif | 
|---|
| 3146 |  | 
|---|
| 3147 | sinfo->bss_param.flags = 0; | 
|---|
| 3148 | if (sdata->vif.bss_conf.use_cts_prot) | 
|---|
| 3149 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; | 
|---|
| 3150 | if (sdata->vif.bss_conf.use_short_preamble) | 
|---|
| 3151 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; | 
|---|
| 3152 | if (sdata->vif.bss_conf.use_short_slot) | 
|---|
| 3153 | sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; | 
|---|
| 3154 | sinfo->bss_param.dtim_period = sdata->vif.bss_conf.dtim_period; | 
|---|
| 3155 | sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int; | 
|---|
| 3156 |  | 
|---|
| 3157 | sinfo->sta_flags.set = 0; | 
|---|
| 3158 | sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | | 
|---|
| 3159 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | 
|---|
| 3160 | BIT(NL80211_STA_FLAG_WME) | | 
|---|
| 3161 | BIT(NL80211_STA_FLAG_MFP) | | 
|---|
| 3162 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 
|---|
| 3163 | BIT(NL80211_STA_FLAG_ASSOCIATED) | | 
|---|
| 3164 | BIT(NL80211_STA_FLAG_TDLS_PEER); | 
|---|
| 3165 | if (test_sta_flag(sta, flag: WLAN_STA_AUTHORIZED)) | 
|---|
| 3166 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); | 
|---|
| 3167 | if (test_sta_flag(sta, flag: WLAN_STA_SHORT_PREAMBLE)) | 
|---|
| 3168 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); | 
|---|
| 3169 | if (sta->sta.wme) | 
|---|
| 3170 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); | 
|---|
| 3171 | if (test_sta_flag(sta, flag: WLAN_STA_MFP)) | 
|---|
| 3172 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); | 
|---|
| 3173 | if (test_sta_flag(sta, flag: WLAN_STA_AUTH)) | 
|---|
| 3174 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); | 
|---|
| 3175 | if (test_sta_flag(sta, flag: WLAN_STA_ASSOC)) | 
|---|
| 3176 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); | 
|---|
| 3177 | if (test_sta_flag(sta, flag: WLAN_STA_TDLS_PEER)) | 
|---|
| 3178 | sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); | 
|---|
| 3179 |  | 
|---|
| 3180 | thr = sta_get_expected_throughput(sta); | 
|---|
| 3181 |  | 
|---|
| 3182 | if (thr != 0) { | 
|---|
| 3183 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_EXPECTED_THROUGHPUT); | 
|---|
| 3184 | sinfo->expected_throughput = thr; | 
|---|
| 3185 | } | 
|---|
| 3186 |  | 
|---|
| 3187 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL)) && | 
|---|
| 3188 | sta->deflink.status_stats.ack_signal_filled) { | 
|---|
| 3189 | sinfo->ack_signal = sta->deflink.status_stats.last_ack_signal; | 
|---|
| 3190 | sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL); | 
|---|
| 3191 | } | 
|---|
| 3192 |  | 
|---|
| 3193 | if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG)) && | 
|---|
| 3194 | sta->deflink.status_stats.ack_signal_filled) { | 
|---|
| 3195 | sinfo->avg_ack_signal = | 
|---|
| 3196 | -(s8)ewma_avg_signal_read( | 
|---|
| 3197 | e: &sta->deflink.status_stats.avg_ack_signal); | 
|---|
| 3198 | sinfo->filled |= | 
|---|
| 3199 | BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL_AVG); | 
|---|
| 3200 | } | 
|---|
| 3201 |  | 
|---|
| 3202 | if (sta->sta.valid_links) { | 
|---|
| 3203 | struct ieee80211_link_data *link; | 
|---|
| 3204 | struct link_sta_info *link_sta; | 
|---|
| 3205 | int link_id; | 
|---|
| 3206 |  | 
|---|
| 3207 | ether_addr_copy(dst: sinfo->mld_addr, src: sta->addr); | 
|---|
| 3208 |  | 
|---|
| 3209 | /* assign valid links first for iteration */ | 
|---|
| 3210 | sinfo->valid_links = sta->sta.valid_links; | 
|---|
| 3211 |  | 
|---|
| 3212 | for_each_valid_link(sinfo, link_id) { | 
|---|
| 3213 | link_sta = wiphy_dereference(sta->local->hw.wiphy, | 
|---|
| 3214 | sta->link[link_id]); | 
|---|
| 3215 | link = wiphy_dereference(sdata->local->hw.wiphy, | 
|---|
| 3216 | sdata->link[link_id]); | 
|---|
| 3217 |  | 
|---|
| 3218 | if (!link_sta || !sinfo->links[link_id] || !link) { | 
|---|
| 3219 | sinfo->valid_links &= ~BIT(link_id); | 
|---|
| 3220 | continue; | 
|---|
| 3221 | } | 
|---|
| 3222 | sta_set_link_sinfo(sta, link_sinfo: sinfo->links[link_id], | 
|---|
| 3223 | link, tidstats); | 
|---|
| 3224 | } | 
|---|
| 3225 | } | 
|---|
| 3226 | } | 
|---|
| 3227 |  | 
|---|
| 3228 | u32 sta_get_expected_throughput(struct sta_info *sta) | 
|---|
| 3229 | { | 
|---|
| 3230 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 3231 | struct ieee80211_local *local = sdata->local; | 
|---|
| 3232 | struct rate_control_ref *ref = NULL; | 
|---|
| 3233 | u32 thr = 0; | 
|---|
| 3234 |  | 
|---|
| 3235 | if (test_sta_flag(sta, flag: WLAN_STA_RATE_CONTROL)) | 
|---|
| 3236 | ref = local->rate_ctrl; | 
|---|
| 3237 |  | 
|---|
| 3238 | /* check if the driver has a SW RC implementation */ | 
|---|
| 3239 | if (ref && ref->ops->get_expected_throughput) | 
|---|
| 3240 | thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv); | 
|---|
| 3241 | else | 
|---|
| 3242 | thr = drv_get_expected_throughput(local, sta); | 
|---|
| 3243 |  | 
|---|
| 3244 | return thr; | 
|---|
| 3245 | } | 
|---|
| 3246 |  | 
|---|
| 3247 | unsigned long ieee80211_sta_last_active(struct sta_info *sta, int link_id) | 
|---|
| 3248 | { | 
|---|
| 3249 | struct ieee80211_sta_rx_stats *stats; | 
|---|
| 3250 | struct link_sta_info *link_sta_info; | 
|---|
| 3251 |  | 
|---|
| 3252 | stats = sta_get_last_rx_stats(sta, link_id); | 
|---|
| 3253 |  | 
|---|
| 3254 | if (link_id < 0) | 
|---|
| 3255 | link_sta_info = &sta->deflink; | 
|---|
| 3256 | else | 
|---|
| 3257 | link_sta_info = wiphy_dereference(sta->local->hw.wiphy, | 
|---|
| 3258 | sta->link[link_id]); | 
|---|
| 3259 |  | 
|---|
| 3260 | if (!link_sta_info->status_stats.last_ack || | 
|---|
| 3261 | time_after(stats->last_rx, link_sta_info->status_stats.last_ack)) | 
|---|
| 3262 | return stats->last_rx; | 
|---|
| 3263 |  | 
|---|
| 3264 | return link_sta_info->status_stats.last_ack; | 
|---|
| 3265 | } | 
|---|
| 3266 |  | 
|---|
| 3267 | int ieee80211_sta_allocate_link(struct sta_info *sta, unsigned int link_id) | 
|---|
| 3268 | { | 
|---|
| 3269 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 3270 | struct sta_link_alloc *alloc; | 
|---|
| 3271 | int ret; | 
|---|
| 3272 |  | 
|---|
| 3273 | lockdep_assert_wiphy(sdata->local->hw.wiphy); | 
|---|
| 3274 |  | 
|---|
| 3275 | WARN_ON(!test_sta_flag(sta, WLAN_STA_INSERTED)); | 
|---|
| 3276 |  | 
|---|
| 3277 | /* must represent an MLD from the start */ | 
|---|
| 3278 | if (WARN_ON(!sta->sta.valid_links)) | 
|---|
| 3279 | return -EINVAL; | 
|---|
| 3280 |  | 
|---|
| 3281 | if (WARN_ON(sta->sta.valid_links & BIT(link_id) || | 
|---|
| 3282 | sta->link[link_id])) | 
|---|
| 3283 | return -EBUSY; | 
|---|
| 3284 |  | 
|---|
| 3285 | alloc = kzalloc(sizeof(*alloc), GFP_KERNEL); | 
|---|
| 3286 | if (!alloc) | 
|---|
| 3287 | return -ENOMEM; | 
|---|
| 3288 |  | 
|---|
| 3289 | ret = sta_info_alloc_link(local: sdata->local, link_info: &alloc->info, GFP_KERNEL); | 
|---|
| 3290 | if (ret) { | 
|---|
| 3291 | kfree(objp: alloc); | 
|---|
| 3292 | return ret; | 
|---|
| 3293 | } | 
|---|
| 3294 |  | 
|---|
| 3295 | sta_info_add_link(sta, link_id, link_info: &alloc->info, link_sta: &alloc->sta); | 
|---|
| 3296 |  | 
|---|
| 3297 | ieee80211_link_sta_debugfs_add(link_sta: &alloc->info); | 
|---|
| 3298 |  | 
|---|
| 3299 | return 0; | 
|---|
| 3300 | } | 
|---|
| 3301 |  | 
|---|
| 3302 | void ieee80211_sta_free_link(struct sta_info *sta, unsigned int link_id) | 
|---|
| 3303 | { | 
|---|
| 3304 | lockdep_assert_wiphy(sta->sdata->local->hw.wiphy); | 
|---|
| 3305 |  | 
|---|
| 3306 | WARN_ON(!test_sta_flag(sta, WLAN_STA_INSERTED)); | 
|---|
| 3307 |  | 
|---|
| 3308 | sta_remove_link(sta, link_id, unhash: false); | 
|---|
| 3309 | } | 
|---|
| 3310 |  | 
|---|
| 3311 | int ieee80211_sta_activate_link(struct sta_info *sta, unsigned int link_id) | 
|---|
| 3312 | { | 
|---|
| 3313 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 3314 | struct link_sta_info *link_sta; | 
|---|
| 3315 | u16 old_links = sta->sta.valid_links; | 
|---|
| 3316 | u16 new_links = old_links | BIT(link_id); | 
|---|
| 3317 | int ret; | 
|---|
| 3318 |  | 
|---|
| 3319 | link_sta = rcu_dereference_protected(sta->link[link_id], | 
|---|
| 3320 | lockdep_is_held(&sdata->local->hw.wiphy->mtx)); | 
|---|
| 3321 |  | 
|---|
| 3322 | if (WARN_ON(old_links == new_links || !link_sta)) | 
|---|
| 3323 | return -EINVAL; | 
|---|
| 3324 |  | 
|---|
| 3325 | rcu_read_lock(); | 
|---|
| 3326 | if (link_sta_info_hash_lookup(local: sdata->local, addr: link_sta->addr)) { | 
|---|
| 3327 | rcu_read_unlock(); | 
|---|
| 3328 | return -EALREADY; | 
|---|
| 3329 | } | 
|---|
| 3330 | /* we only modify under the mutex so this is fine */ | 
|---|
| 3331 | rcu_read_unlock(); | 
|---|
| 3332 |  | 
|---|
| 3333 | sta->sta.valid_links = new_links; | 
|---|
| 3334 |  | 
|---|
| 3335 | if (WARN_ON(!test_sta_flag(sta, WLAN_STA_INSERTED))) | 
|---|
| 3336 | goto hash; | 
|---|
| 3337 |  | 
|---|
| 3338 | ieee80211_recalc_min_chandef(sdata, link_id); | 
|---|
| 3339 |  | 
|---|
| 3340 | /* Ensure the values are updated for the driver, | 
|---|
| 3341 | * redone by sta_remove_link on failure. | 
|---|
| 3342 | */ | 
|---|
| 3343 | ieee80211_sta_recalc_aggregates(&sta->sta); | 
|---|
| 3344 |  | 
|---|
| 3345 | ret = drv_change_sta_links(local: sdata->local, sdata, sta: &sta->sta, | 
|---|
| 3346 | old_links, new_links); | 
|---|
| 3347 | if (ret) { | 
|---|
| 3348 | sta->sta.valid_links = old_links; | 
|---|
| 3349 | sta_remove_link(sta, link_id, unhash: false); | 
|---|
| 3350 | return ret; | 
|---|
| 3351 | } | 
|---|
| 3352 |  | 
|---|
| 3353 | hash: | 
|---|
| 3354 | ret = link_sta_info_hash_add(local: sdata->local, link_sta); | 
|---|
| 3355 | WARN_ON(ret); | 
|---|
| 3356 | return 0; | 
|---|
| 3357 | } | 
|---|
| 3358 |  | 
|---|
| 3359 | void ieee80211_sta_remove_link(struct sta_info *sta, unsigned int link_id) | 
|---|
| 3360 | { | 
|---|
| 3361 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 
|---|
| 3362 | u16 old_links = sta->sta.valid_links; | 
|---|
| 3363 |  | 
|---|
| 3364 | lockdep_assert_wiphy(sdata->local->hw.wiphy); | 
|---|
| 3365 |  | 
|---|
| 3366 | sta->sta.valid_links &= ~BIT(link_id); | 
|---|
| 3367 |  | 
|---|
| 3368 | if (!WARN_ON(!test_sta_flag(sta, WLAN_STA_INSERTED))) | 
|---|
| 3369 | drv_change_sta_links(local: sdata->local, sdata, sta: &sta->sta, | 
|---|
| 3370 | old_links, new_links: sta->sta.valid_links); | 
|---|
| 3371 |  | 
|---|
| 3372 | sta_remove_link(sta, link_id, unhash: true); | 
|---|
| 3373 | } | 
|---|
| 3374 |  | 
|---|
| 3375 | void ieee80211_sta_set_max_amsdu_subframes(struct sta_info *sta, | 
|---|
| 3376 | const u8 *ext_capab, | 
|---|
| 3377 | unsigned int ext_capab_len) | 
|---|
| 3378 | { | 
|---|
| 3379 | u8 val; | 
|---|
| 3380 |  | 
|---|
| 3381 | sta->sta.max_amsdu_subframes = 0; | 
|---|
| 3382 |  | 
|---|
| 3383 | if (ext_capab_len < 8) | 
|---|
| 3384 | return; | 
|---|
| 3385 |  | 
|---|
| 3386 | /* The sender might not have sent the last bit, consider it to be 0 */ | 
|---|
| 3387 | val = u8_get_bits(v: ext_capab[7], WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB); | 
|---|
| 3388 |  | 
|---|
| 3389 | /* we did get all the bits, take the MSB as well */ | 
|---|
| 3390 | if (ext_capab_len >= 9) | 
|---|
| 3391 | val |= u8_get_bits(v: ext_capab[8], | 
|---|
| 3392 | WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB) << 1; | 
|---|
| 3393 |  | 
|---|
| 3394 | if (val) | 
|---|
| 3395 | sta->sta.max_amsdu_subframes = 4 << (4 - val); | 
|---|
| 3396 | } | 
|---|
| 3397 |  | 
|---|
| 3398 | #ifdef CONFIG_LOCKDEP | 
|---|
| 3399 | bool lockdep_sta_mutex_held(struct ieee80211_sta *pubsta) | 
|---|
| 3400 | { | 
|---|
| 3401 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | 
|---|
| 3402 |  | 
|---|
| 3403 | return lockdep_is_held(&sta->local->hw.wiphy->mtx); | 
|---|
| 3404 | } | 
|---|
| 3405 | EXPORT_SYMBOL(lockdep_sta_mutex_held); | 
|---|
| 3406 | #endif | 
|---|
| 3407 |  | 
|---|