.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2002-2005, Instant802 Networks, Inc. |
---|
3 | 4 | * Copyright 2005-2006, Devicescape Software, Inc. |
---|
.. | .. |
---|
5 | 6 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> |
---|
6 | 7 | * Copyright 2013-2014 Intel Mobile Communications GmbH |
---|
7 | 8 | * Copyright 2015-2017 Intel Deutschland GmbH |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify |
---|
10 | | - * it under the terms of the GNU General Public License version 2 as |
---|
11 | | - * published by the Free Software Foundation. |
---|
| 9 | + * Copyright 2018-2020 Intel Corporation |
---|
12 | 10 | */ |
---|
13 | 11 | |
---|
14 | 12 | #include <linux/if_ether.h> |
---|
.. | .. |
---|
140 | 138 | * so clear that flag now to avoid trying to remove |
---|
141 | 139 | * it again later. |
---|
142 | 140 | */ |
---|
| 141 | + if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
---|
| 142 | + !(key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
| 143 | + IEEE80211_KEY_FLAG_PUT_MIC_SPACE | |
---|
| 144 | + IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
| 145 | + increment_tailroom_need_count(sdata); |
---|
| 146 | + |
---|
143 | 147 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
---|
144 | 148 | return -EINVAL; |
---|
145 | 149 | } |
---|
.. | .. |
---|
179 | 183 | if (!ret) { |
---|
180 | 184 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
---|
181 | 185 | |
---|
182 | | - if (!((key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
183 | | - IEEE80211_KEY_FLAG_PUT_MIC_SPACE)) || |
---|
184 | | - (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
| 186 | + if (!(key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
| 187 | + IEEE80211_KEY_FLAG_PUT_MIC_SPACE | |
---|
| 188 | + IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
185 | 189 | decrease_tailroom_need_count(sdata, 1); |
---|
186 | 190 | |
---|
187 | 191 | WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && |
---|
.. | .. |
---|
206 | 210 | case WLAN_CIPHER_SUITE_TKIP: |
---|
207 | 211 | case WLAN_CIPHER_SUITE_CCMP: |
---|
208 | 212 | case WLAN_CIPHER_SUITE_CCMP_256: |
---|
| 213 | + case WLAN_CIPHER_SUITE_GCMP: |
---|
| 214 | + case WLAN_CIPHER_SUITE_GCMP_256: |
---|
209 | 215 | case WLAN_CIPHER_SUITE_AES_CMAC: |
---|
210 | 216 | case WLAN_CIPHER_SUITE_BIP_CMAC_256: |
---|
211 | 217 | case WLAN_CIPHER_SUITE_BIP_GMAC_128: |
---|
212 | 218 | case WLAN_CIPHER_SUITE_BIP_GMAC_256: |
---|
213 | | - case WLAN_CIPHER_SUITE_GCMP: |
---|
214 | | - case WLAN_CIPHER_SUITE_GCMP_256: |
---|
215 | 219 | /* all of these we can do in software - if driver can */ |
---|
216 | 220 | if (ret == 1) |
---|
217 | 221 | return 0; |
---|
.. | .. |
---|
242 | 246 | sta = key->sta; |
---|
243 | 247 | sdata = key->sdata; |
---|
244 | 248 | |
---|
245 | | - if (!((key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
246 | | - IEEE80211_KEY_FLAG_PUT_MIC_SPACE)) || |
---|
247 | | - (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
| 249 | + if (!(key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
| 250 | + IEEE80211_KEY_FLAG_PUT_MIC_SPACE | |
---|
| 251 | + IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
248 | 252 | increment_tailroom_need_count(sdata); |
---|
249 | 253 | |
---|
| 254 | + key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
---|
250 | 255 | ret = drv_set_key(key->local, DISABLE_KEY, sdata, |
---|
251 | 256 | sta ? &sta->sta : NULL, &key->conf); |
---|
252 | 257 | |
---|
.. | .. |
---|
255 | 260 | "failed to remove key (%d, %pM) from hardware (%d)\n", |
---|
256 | 261 | key->conf.keyidx, |
---|
257 | 262 | sta ? sta->sta.addr : bcast_addr, ret); |
---|
| 263 | +} |
---|
258 | 264 | |
---|
259 | | - key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
---|
| 265 | +static int _ieee80211_set_tx_key(struct ieee80211_key *key, bool force) |
---|
| 266 | +{ |
---|
| 267 | + struct sta_info *sta = key->sta; |
---|
| 268 | + struct ieee80211_local *local = key->local; |
---|
| 269 | + |
---|
| 270 | + assert_key_lock(local); |
---|
| 271 | + |
---|
| 272 | + set_sta_flag(sta, WLAN_STA_USES_ENCRYPTION); |
---|
| 273 | + |
---|
| 274 | + sta->ptk_idx = key->conf.keyidx; |
---|
| 275 | + |
---|
| 276 | + if (force || !ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT)) |
---|
| 277 | + clear_sta_flag(sta, WLAN_STA_BLOCK_BA); |
---|
| 278 | + ieee80211_check_fast_xmit(sta); |
---|
| 279 | + |
---|
| 280 | + return 0; |
---|
| 281 | +} |
---|
| 282 | + |
---|
| 283 | +int ieee80211_set_tx_key(struct ieee80211_key *key) |
---|
| 284 | +{ |
---|
| 285 | + return _ieee80211_set_tx_key(key, false); |
---|
| 286 | +} |
---|
| 287 | + |
---|
| 288 | +static void ieee80211_pairwise_rekey(struct ieee80211_key *old, |
---|
| 289 | + struct ieee80211_key *new) |
---|
| 290 | +{ |
---|
| 291 | + struct ieee80211_local *local = new->local; |
---|
| 292 | + struct sta_info *sta = new->sta; |
---|
| 293 | + int i; |
---|
| 294 | + |
---|
| 295 | + assert_key_lock(local); |
---|
| 296 | + |
---|
| 297 | + if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) { |
---|
| 298 | + /* Extended Key ID key install, initial one or rekey */ |
---|
| 299 | + |
---|
| 300 | + if (sta->ptk_idx != INVALID_PTK_KEYIDX && |
---|
| 301 | + !ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT)) { |
---|
| 302 | + /* Aggregation Sessions with Extended Key ID must not |
---|
| 303 | + * mix MPDUs with different keyIDs within one A-MPDU. |
---|
| 304 | + * Tear down running Tx aggregation sessions and block |
---|
| 305 | + * new Rx/Tx aggregation requests during rekey to |
---|
| 306 | + * ensure there are no A-MPDUs when the driver is not |
---|
| 307 | + * supporting A-MPDU key borders. (Blocking Tx only |
---|
| 308 | + * would be sufficient but WLAN_STA_BLOCK_BA gets the |
---|
| 309 | + * job done for the few ms we need it.) |
---|
| 310 | + */ |
---|
| 311 | + set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
---|
| 312 | + mutex_lock(&sta->ampdu_mlme.mtx); |
---|
| 313 | + for (i = 0; i < IEEE80211_NUM_TIDS; i++) |
---|
| 314 | + ___ieee80211_stop_tx_ba_session(sta, i, |
---|
| 315 | + AGG_STOP_LOCAL_REQUEST); |
---|
| 316 | + mutex_unlock(&sta->ampdu_mlme.mtx); |
---|
| 317 | + } |
---|
| 318 | + } else if (old) { |
---|
| 319 | + /* Rekey without Extended Key ID. |
---|
| 320 | + * Aggregation sessions are OK when running on SW crypto. |
---|
| 321 | + * A broken remote STA may cause issues not observed with HW |
---|
| 322 | + * crypto, though. |
---|
| 323 | + */ |
---|
| 324 | + if (!(old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
---|
| 325 | + return; |
---|
| 326 | + |
---|
| 327 | + /* Stop Tx till we are on the new key */ |
---|
| 328 | + old->flags |= KEY_FLAG_TAINTED; |
---|
| 329 | + ieee80211_clear_fast_xmit(sta); |
---|
| 330 | + if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION)) { |
---|
| 331 | + set_sta_flag(sta, WLAN_STA_BLOCK_BA); |
---|
| 332 | + ieee80211_sta_tear_down_BA_sessions(sta, |
---|
| 333 | + AGG_STOP_LOCAL_REQUEST); |
---|
| 334 | + } |
---|
| 335 | + if (!wiphy_ext_feature_isset(local->hw.wiphy, |
---|
| 336 | + NL80211_EXT_FEATURE_CAN_REPLACE_PTK0)) { |
---|
| 337 | + pr_warn_ratelimited("Rekeying PTK for STA %pM but driver can't safely do that.", |
---|
| 338 | + sta->sta.addr); |
---|
| 339 | + /* Flushing the driver queues *may* help prevent |
---|
| 340 | + * the clear text leaks and freezes. |
---|
| 341 | + */ |
---|
| 342 | + ieee80211_flush_queues(local, old->sdata, false); |
---|
| 343 | + } |
---|
| 344 | + } |
---|
260 | 345 | } |
---|
261 | 346 | |
---|
262 | 347 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, |
---|
.. | .. |
---|
314 | 399 | mutex_unlock(&sdata->local->key_mtx); |
---|
315 | 400 | } |
---|
316 | 401 | |
---|
| 402 | +static void |
---|
| 403 | +__ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata, int idx) |
---|
| 404 | +{ |
---|
| 405 | + struct ieee80211_key *key = NULL; |
---|
317 | 406 | |
---|
318 | | -static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, |
---|
| 407 | + assert_key_lock(sdata->local); |
---|
| 408 | + |
---|
| 409 | + if (idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS && |
---|
| 410 | + idx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + |
---|
| 411 | + NUM_DEFAULT_BEACON_KEYS) |
---|
| 412 | + key = key_mtx_dereference(sdata->local, sdata->keys[idx]); |
---|
| 413 | + |
---|
| 414 | + rcu_assign_pointer(sdata->default_beacon_key, key); |
---|
| 415 | + |
---|
| 416 | + ieee80211_debugfs_key_update_default(sdata); |
---|
| 417 | +} |
---|
| 418 | + |
---|
| 419 | +void ieee80211_set_default_beacon_key(struct ieee80211_sub_if_data *sdata, |
---|
| 420 | + int idx) |
---|
| 421 | +{ |
---|
| 422 | + mutex_lock(&sdata->local->key_mtx); |
---|
| 423 | + __ieee80211_set_default_beacon_key(sdata, idx); |
---|
| 424 | + mutex_unlock(&sdata->local->key_mtx); |
---|
| 425 | +} |
---|
| 426 | + |
---|
| 427 | +static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, |
---|
319 | 428 | struct sta_info *sta, |
---|
320 | 429 | bool pairwise, |
---|
321 | 430 | struct ieee80211_key *old, |
---|
322 | 431 | struct ieee80211_key *new) |
---|
323 | 432 | { |
---|
324 | 433 | int idx; |
---|
325 | | - bool defunikey, defmultikey, defmgmtkey; |
---|
| 434 | + int ret = 0; |
---|
| 435 | + bool defunikey, defmultikey, defmgmtkey, defbeaconkey; |
---|
326 | 436 | |
---|
327 | 437 | /* caller must provide at least one old/new */ |
---|
328 | 438 | if (WARN_ON(!new && !old)) |
---|
329 | | - return; |
---|
| 439 | + return 0; |
---|
330 | 440 | |
---|
331 | 441 | if (new) |
---|
332 | 442 | list_add_tail_rcu(&new->list, &sdata->key_list); |
---|
333 | 443 | |
---|
334 | 444 | WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); |
---|
335 | 445 | |
---|
336 | | - if (old) |
---|
| 446 | + if (new && sta && pairwise) { |
---|
| 447 | + /* Unicast rekey needs special handling. With Extended Key ID |
---|
| 448 | + * old is still NULL for the first rekey. |
---|
| 449 | + */ |
---|
| 450 | + ieee80211_pairwise_rekey(old, new); |
---|
| 451 | + } |
---|
| 452 | + |
---|
| 453 | + if (old) { |
---|
337 | 454 | idx = old->conf.keyidx; |
---|
338 | | - else |
---|
| 455 | + |
---|
| 456 | + if (old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
---|
| 457 | + ieee80211_key_disable_hw_accel(old); |
---|
| 458 | + |
---|
| 459 | + if (new) |
---|
| 460 | + ret = ieee80211_key_enable_hw_accel(new); |
---|
| 461 | + } |
---|
| 462 | + } else { |
---|
| 463 | + /* new must be provided in case old is not */ |
---|
339 | 464 | idx = new->conf.keyidx; |
---|
| 465 | + if (!new->local->wowlan) |
---|
| 466 | + ret = ieee80211_key_enable_hw_accel(new); |
---|
| 467 | + } |
---|
| 468 | + |
---|
| 469 | + if (ret) |
---|
| 470 | + return ret; |
---|
340 | 471 | |
---|
341 | 472 | if (sta) { |
---|
342 | 473 | if (pairwise) { |
---|
343 | 474 | rcu_assign_pointer(sta->ptk[idx], new); |
---|
344 | | - set_sta_flag(sta, WLAN_STA_USES_ENCRYPTION); |
---|
345 | | - sta->ptk_idx = idx; |
---|
346 | | - ieee80211_check_fast_xmit(sta); |
---|
| 475 | + if (new && |
---|
| 476 | + !(new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX)) |
---|
| 477 | + _ieee80211_set_tx_key(new, true); |
---|
347 | 478 | } else { |
---|
348 | 479 | rcu_assign_pointer(sta->gtk[idx], new); |
---|
349 | 480 | } |
---|
350 | | - ieee80211_check_fast_rx(sta); |
---|
| 481 | + /* Only needed for transition from no key -> key. |
---|
| 482 | + * Still triggers unnecessary when using Extended Key ID |
---|
| 483 | + * and installing the second key ID the first time. |
---|
| 484 | + */ |
---|
| 485 | + if (new && !old) |
---|
| 486 | + ieee80211_check_fast_rx(sta); |
---|
351 | 487 | } else { |
---|
352 | 488 | defunikey = old && |
---|
353 | 489 | old == key_mtx_dereference(sdata->local, |
---|
.. | .. |
---|
358 | 494 | defmgmtkey = old && |
---|
359 | 495 | old == key_mtx_dereference(sdata->local, |
---|
360 | 496 | sdata->default_mgmt_key); |
---|
| 497 | + defbeaconkey = old && |
---|
| 498 | + old == key_mtx_dereference(sdata->local, |
---|
| 499 | + sdata->default_beacon_key); |
---|
361 | 500 | |
---|
362 | 501 | if (defunikey && !new) |
---|
363 | 502 | __ieee80211_set_default_key(sdata, -1, true, false); |
---|
.. | .. |
---|
365 | 504 | __ieee80211_set_default_key(sdata, -1, false, true); |
---|
366 | 505 | if (defmgmtkey && !new) |
---|
367 | 506 | __ieee80211_set_default_mgmt_key(sdata, -1); |
---|
| 507 | + if (defbeaconkey && !new) |
---|
| 508 | + __ieee80211_set_default_beacon_key(sdata, -1); |
---|
368 | 509 | |
---|
369 | 510 | rcu_assign_pointer(sdata->keys[idx], new); |
---|
370 | 511 | if (defunikey && new) |
---|
.. | .. |
---|
376 | 517 | if (defmgmtkey && new) |
---|
377 | 518 | __ieee80211_set_default_mgmt_key(sdata, |
---|
378 | 519 | new->conf.keyidx); |
---|
| 520 | + if (defbeaconkey && new) |
---|
| 521 | + __ieee80211_set_default_beacon_key(sdata, |
---|
| 522 | + new->conf.keyidx); |
---|
379 | 523 | } |
---|
380 | 524 | |
---|
381 | 525 | if (old) |
---|
382 | 526 | list_del_rcu(&old->list); |
---|
| 527 | + |
---|
| 528 | + return 0; |
---|
383 | 529 | } |
---|
384 | 530 | |
---|
385 | 531 | struct ieee80211_key * |
---|
.. | .. |
---|
391 | 537 | struct ieee80211_key *key; |
---|
392 | 538 | int i, j, err; |
---|
393 | 539 | |
---|
394 | | - if (WARN_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)) |
---|
| 540 | + if (WARN_ON(idx < 0 || |
---|
| 541 | + idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + |
---|
| 542 | + NUM_DEFAULT_BEACON_KEYS)) |
---|
395 | 543 | return ERR_PTR(-EINVAL); |
---|
396 | 544 | |
---|
397 | 545 | key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); |
---|
.. | .. |
---|
569 | 717 | ieee80211_aes_gcm_key_free(key->u.gcmp.tfm); |
---|
570 | 718 | break; |
---|
571 | 719 | } |
---|
572 | | - kzfree(key); |
---|
| 720 | + kfree_sensitive(key); |
---|
573 | 721 | } |
---|
574 | 722 | |
---|
575 | 723 | static void __ieee80211_key_destroy(struct ieee80211_key *key, |
---|
576 | 724 | bool delay_tailroom) |
---|
577 | 725 | { |
---|
578 | | - if (key->local) |
---|
579 | | - ieee80211_key_disable_hw_accel(key); |
---|
580 | | - |
---|
581 | 726 | if (key->local) { |
---|
582 | 727 | struct ieee80211_sub_if_data *sdata = key->sdata; |
---|
583 | 728 | |
---|
.. | .. |
---|
655 | 800 | struct sta_info *sta) |
---|
656 | 801 | { |
---|
657 | 802 | static atomic_t key_color = ATOMIC_INIT(0); |
---|
658 | | - struct ieee80211_local *local = sdata->local; |
---|
659 | 803 | struct ieee80211_key *old_key; |
---|
660 | 804 | int idx = key->conf.keyidx; |
---|
661 | 805 | bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; |
---|
.. | .. |
---|
665 | 809 | * can cause warnings to appear. |
---|
666 | 810 | */ |
---|
667 | 811 | bool delay_tailroom = sdata->vif.type == NL80211_IFTYPE_STATION; |
---|
668 | | - int ret; |
---|
| 812 | + int ret = -EOPNOTSUPP; |
---|
669 | 813 | |
---|
670 | 814 | mutex_lock(&sdata->local->key_mtx); |
---|
671 | 815 | |
---|
672 | | - if (sta && pairwise) |
---|
| 816 | + if (sta && pairwise) { |
---|
| 817 | + struct ieee80211_key *alt_key; |
---|
| 818 | + |
---|
673 | 819 | old_key = key_mtx_dereference(sdata->local, sta->ptk[idx]); |
---|
674 | | - else if (sta) |
---|
| 820 | + alt_key = key_mtx_dereference(sdata->local, sta->ptk[idx ^ 1]); |
---|
| 821 | + |
---|
| 822 | + /* The rekey code assumes that the old and new key are using |
---|
| 823 | + * the same cipher. Enforce the assumption for pairwise keys. |
---|
| 824 | + */ |
---|
| 825 | + if ((alt_key && alt_key->conf.cipher != key->conf.cipher) || |
---|
| 826 | + (old_key && old_key->conf.cipher != key->conf.cipher)) |
---|
| 827 | + goto out; |
---|
| 828 | + } else if (sta) { |
---|
675 | 829 | old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]); |
---|
676 | | - else |
---|
| 830 | + } else { |
---|
677 | 831 | old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); |
---|
| 832 | + } |
---|
| 833 | + |
---|
| 834 | + /* Non-pairwise keys must also not switch the cipher on rekey */ |
---|
| 835 | + if (!pairwise) { |
---|
| 836 | + if (old_key && old_key->conf.cipher != key->conf.cipher) |
---|
| 837 | + goto out; |
---|
| 838 | + } |
---|
678 | 839 | |
---|
679 | 840 | /* |
---|
680 | 841 | * Silently accept key re-installation without really installing the |
---|
.. | .. |
---|
698 | 859 | |
---|
699 | 860 | increment_tailroom_need_count(sdata); |
---|
700 | 861 | |
---|
701 | | - ieee80211_key_replace(sdata, sta, pairwise, old_key, key); |
---|
702 | | - ieee80211_key_destroy(old_key, delay_tailroom); |
---|
| 862 | + ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key); |
---|
703 | 863 | |
---|
704 | | - ieee80211_debugfs_key_add(key); |
---|
705 | | - |
---|
706 | | - if (!local->wowlan) { |
---|
707 | | - ret = ieee80211_key_enable_hw_accel(key); |
---|
708 | | - if (ret) |
---|
709 | | - ieee80211_key_free(key, delay_tailroom); |
---|
| 864 | + if (!ret) { |
---|
| 865 | + ieee80211_debugfs_key_add(key); |
---|
| 866 | + ieee80211_key_destroy(old_key, delay_tailroom); |
---|
710 | 867 | } else { |
---|
711 | | - ret = 0; |
---|
| 868 | + ieee80211_key_free(key, delay_tailroom); |
---|
712 | 869 | } |
---|
713 | 870 | |
---|
714 | 871 | out: |
---|
.. | .. |
---|
732 | 889 | ieee80211_key_destroy(key, delay_tailroom); |
---|
733 | 890 | } |
---|
734 | 891 | |
---|
735 | | -void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) |
---|
| 892 | +void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata) |
---|
736 | 893 | { |
---|
737 | 894 | struct ieee80211_key *key; |
---|
738 | 895 | struct ieee80211_sub_if_data *vlan; |
---|
739 | 896 | |
---|
740 | 897 | ASSERT_RTNL(); |
---|
741 | 898 | |
---|
742 | | - if (WARN_ON(!ieee80211_sdata_running(sdata))) |
---|
743 | | - return; |
---|
744 | | - |
---|
745 | | - mutex_lock(&sdata->local->key_mtx); |
---|
746 | | - |
---|
747 | | - WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt || |
---|
748 | | - sdata->crypto_tx_tailroom_pending_dec); |
---|
749 | | - |
---|
750 | | - if (sdata->vif.type == NL80211_IFTYPE_AP) { |
---|
751 | | - list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
---|
752 | | - WARN_ON_ONCE(vlan->crypto_tx_tailroom_needed_cnt || |
---|
753 | | - vlan->crypto_tx_tailroom_pending_dec); |
---|
754 | | - } |
---|
755 | | - |
---|
756 | | - list_for_each_entry(key, &sdata->key_list, list) { |
---|
757 | | - increment_tailroom_need_count(sdata); |
---|
758 | | - ieee80211_key_enable_hw_accel(key); |
---|
759 | | - } |
---|
760 | | - |
---|
761 | | - mutex_unlock(&sdata->local->key_mtx); |
---|
762 | | -} |
---|
763 | | - |
---|
764 | | -void ieee80211_reset_crypto_tx_tailroom(struct ieee80211_sub_if_data *sdata) |
---|
765 | | -{ |
---|
766 | | - struct ieee80211_sub_if_data *vlan; |
---|
767 | | - |
---|
768 | 899 | mutex_lock(&sdata->local->key_mtx); |
---|
769 | 900 | |
---|
770 | 901 | sdata->crypto_tx_tailroom_needed_cnt = 0; |
---|
| 902 | + sdata->crypto_tx_tailroom_pending_dec = 0; |
---|
771 | 903 | |
---|
772 | 904 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
---|
773 | | - list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) |
---|
| 905 | + list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { |
---|
774 | 906 | vlan->crypto_tx_tailroom_needed_cnt = 0; |
---|
| 907 | + vlan->crypto_tx_tailroom_pending_dec = 0; |
---|
| 908 | + } |
---|
| 909 | + } |
---|
| 910 | + |
---|
| 911 | + if (ieee80211_sdata_running(sdata)) { |
---|
| 912 | + list_for_each_entry(key, &sdata->key_list, list) { |
---|
| 913 | + increment_tailroom_need_count(sdata); |
---|
| 914 | + ieee80211_key_enable_hw_accel(key); |
---|
| 915 | + } |
---|
775 | 916 | } |
---|
776 | 917 | |
---|
777 | 918 | mutex_unlock(&sdata->local->key_mtx); |
---|
.. | .. |
---|
868 | 1009 | sdata->crypto_tx_tailroom_pending_dec = 0; |
---|
869 | 1010 | |
---|
870 | 1011 | ieee80211_debugfs_key_remove_mgmt_default(sdata); |
---|
| 1012 | + ieee80211_debugfs_key_remove_beacon_default(sdata); |
---|
871 | 1013 | |
---|
872 | 1014 | list_for_each_entry_safe(key, tmp, &sdata->key_list, list) { |
---|
873 | 1015 | ieee80211_key_replace(key->sdata, key->sta, |
---|
.. | .. |
---|
1124 | 1266 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
---|
1125 | 1267 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
---|
1126 | 1268 | |
---|
1127 | | - if (!((key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
1128 | | - IEEE80211_KEY_FLAG_PUT_MIC_SPACE)) || |
---|
1129 | | - (key->conf.flags & IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
| 1269 | + if (!(key->conf.flags & (IEEE80211_KEY_FLAG_GENERATE_MMIC | |
---|
| 1270 | + IEEE80211_KEY_FLAG_PUT_MIC_SPACE | |
---|
| 1271 | + IEEE80211_KEY_FLAG_RESERVE_TAILROOM))) |
---|
1130 | 1272 | increment_tailroom_need_count(key->sdata); |
---|
1131 | 1273 | } |
---|
1132 | 1274 | |
---|