mac80211: AMPDU handling for rekeys with Extended Key ID
Extended Key ID allows A-MPDU sessions while rekeying as long as each A-MPDU aggregates only MPDUs with one keyid together. Drivers able to segregate MPDUs accordingly can tell mac80211 to not stop A-MPDU sessions when rekeying by setting the new flag IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT. Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> Link: https://lore.kernel.org/r/20190629195015.19680-3-alexander@wetzel-home.de Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Родитель
3e47bf1ca4
Коммит
dc3998ec5c
|
@ -2268,6 +2268,10 @@ struct ieee80211_txq {
|
||||||
* @IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID: Hardware supports multi BSSID
|
* @IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID: Hardware supports multi BSSID
|
||||||
* only for HE APs. Applies if @IEEE80211_HW_SUPPORTS_MULTI_BSSID is set.
|
* only for HE APs. Applies if @IEEE80211_HW_SUPPORTS_MULTI_BSSID is set.
|
||||||
*
|
*
|
||||||
|
* @IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT: The card and driver is only
|
||||||
|
* aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx
|
||||||
|
* A-MPDU sessions active while rekeying with Extended Key ID.
|
||||||
|
*
|
||||||
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
||||||
*/
|
*/
|
||||||
enum ieee80211_hw_flags {
|
enum ieee80211_hw_flags {
|
||||||
|
@ -2319,6 +2323,7 @@ enum ieee80211_hw_flags {
|
||||||
IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
|
IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
|
||||||
IEEE80211_HW_SUPPORTS_MULTI_BSSID,
|
IEEE80211_HW_SUPPORTS_MULTI_BSSID,
|
||||||
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
|
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
|
||||||
|
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
|
||||||
|
|
||||||
/* keep last, obviously */
|
/* keep last, obviously */
|
||||||
NUM_IEEE80211_HW_FLAGS
|
NUM_IEEE80211_HW_FLAGS
|
||||||
|
|
|
@ -271,6 +271,7 @@ static const char *hw_flag_names[] = {
|
||||||
FLAG(TX_STATUS_NO_AMPDU_LEN),
|
FLAG(TX_STATUS_NO_AMPDU_LEN),
|
||||||
FLAG(SUPPORTS_MULTI_BSSID),
|
FLAG(SUPPORTS_MULTI_BSSID),
|
||||||
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
|
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
|
||||||
|
FLAG(AMPDU_KEYBORDER_SUPPORT),
|
||||||
#undef FLAG
|
#undef FLAG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -270,6 +270,7 @@ int ieee80211_set_tx_key(struct ieee80211_key *key)
|
||||||
|
|
||||||
sta->ptk_idx = key->conf.keyidx;
|
sta->ptk_idx = key->conf.keyidx;
|
||||||
|
|
||||||
|
if (!ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
|
||||||
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||||
ieee80211_check_fast_xmit(sta);
|
ieee80211_check_fast_xmit(sta);
|
||||||
|
|
||||||
|
@ -288,15 +289,16 @@ static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
|
||||||
if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) {
|
if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) {
|
||||||
/* Extended Key ID key install, initial one or rekey */
|
/* Extended Key ID key install, initial one or rekey */
|
||||||
|
|
||||||
if (sta->ptk_idx != INVALID_PTK_KEYIDX) {
|
if (sta->ptk_idx != INVALID_PTK_KEYIDX &&
|
||||||
|
!ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT)) {
|
||||||
/* Aggregation Sessions with Extended Key ID must not
|
/* Aggregation Sessions with Extended Key ID must not
|
||||||
* mix MPDUs with different keyIDs within one A-MPDU.
|
* mix MPDUs with different keyIDs within one A-MPDU.
|
||||||
* Tear down running Tx aggregation sessions and block
|
* Tear down running Tx aggregation sessions and block
|
||||||
* new Rx/Tx aggregation requests during rekey to
|
* new Rx/Tx aggregation requests during rekey to
|
||||||
* ensure there are no A-MPDUs for the driver to
|
* ensure there are no A-MPDUs when the driver is not
|
||||||
* aggregate. (Blocking Tx only would be sufficient but
|
* supporting A-MPDU key borders. (Blocking Tx only
|
||||||
* WLAN_STA_BLOCK_BA gets the job done for the few ms
|
* would be sufficient but WLAN_STA_BLOCK_BA gets the
|
||||||
* we need it.)
|
* job done for the few ms we need it.)
|
||||||
*/
|
*/
|
||||||
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||||
mutex_lock(&sta->ampdu_mlme.mtx);
|
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче