Avoid a not needed warning and queue flush from mac80211 when deleting PTK keys. The flush is only needed when queued MPDUs depend on the key table instead carrying the needed key material directly in the MPDU info. Set NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 and flush the queues only when needed. Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- .../net/wireless/intel/iwlwifi/dvm/mac80211.c | 1 + .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 18 ++++++++++++++++++ drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 6 ------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 423d3c396b2d..8846203526d2 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -201,6 +201,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_EXT_KEY_ID); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); ret = ieee80211_register_hw(priv->hw); if (ret) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 9374c85c5caf..40003de28556 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -83,6 +83,9 @@ #include "iwl-prph.h" #include "iwl-nvm-parse.h" +static void iwl_mvm_mac_flush(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, u32 queues, bool drop); + static const struct ieee80211_iface_limit iwl_mvm_limits[] = { { .max = 1, @@ -543,6 +546,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS); + wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); /* The new Tx API does not allow to pass the key or keyid of a MPDU to * the hw, preventing us to control which key(id) to use per MPDU. @@ -3540,6 +3544,20 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, break; } + /* GCMP and 256 bit CCMP keys the key can't be copied into the + * MPDU struct ieee80211_tx_info. We therefore must flush the + * queues to ensure there are no MPDUs left which are referring + * to the outgoing key. + */ + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE && + (key->cipher == WLAN_CIPHER_SUITE_GCMP || + key->cipher == WLAN_CIPHER_SUITE_GCMP_256 || + key->cipher == WLAN_CIPHER_SUITE_CCMP_256)) { + ieee80211_stop_queues(hw); + iwl_mvm_mac_flush(hw, vif, 0, true); + ieee80211_wake_queues(hw); + } + if (sta && iwl_mvm_has_new_rx_api(mvm) && key->flags & IEEE80211_KEY_FLAG_PAIRWISE && (key->cipher == WLAN_CIPHER_SUITE_CCMP || diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 2f6484e0d726..9e0c55b75478 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -472,12 +472,6 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, type = TX_CMD_SEC_GCMP; /* Fall through */ case WLAN_CIPHER_SUITE_CCMP_256: - /* TODO: Taking the key from the table might introduce a race - * when PTK rekeying is done, having an old packets with a PN - * based on the old key but the message encrypted with a new - * one. - * Need to handle this. - */ tx_cmd->sec_ctl |= type | TX_CMD_SEC_KEY_FROM_TABLE; tx_cmd->key[0] = keyconf->hw_key_idx; iwl_mvm_set_tx_cmd_pn(info, crypto_hdr); -- 2.28.0