Extend the shared ath key cache code to support Extended Key ID. The key cache code has to accept unicast keys to use key idx 1 and allow drivers to enable/disable hardware Rx decryption for a key independent from Tx. Signed-off-by: Alexander Wetzel <alexander@xxxxxxxxxxxxxx> --- I know this is the wrong audience to discuss ath drivers. It's only included here as an example and POC that the Compatibility Extended Key ID means for drivers. This has so far only got the minimal attention needed to get it working for my AP used for tests. The idea is, to discuss that with the proper audience once we know what mac80211 Extended Key ID support will look like. drivers/net/wireless/ath/ath.h | 7 ++++++- drivers/net/wireless/ath/key.c | 35 +++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index cc45ccfea5af..465629448fdf 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -202,8 +202,13 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); int ath_key_config(struct ath_common *common, struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); + struct ieee80211_key_conf *key, + bool rx_accel); bool ath_hw_keyreset(struct ath_common *common, u16 entry); +bool ath_hw_rx_crypt(struct ath_common *common, + struct ieee80211_key_conf *key, + struct ieee80211_sta *sta, + bool rx_accel); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 689fab9acf10..ced1c89102ad 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -126,6 +126,23 @@ static bool ath_hw_keysetmac(struct ath_common *common, return true; } +bool ath_hw_rx_crypt(struct ath_common *common, + struct ieee80211_key_conf *key, + struct ieee80211_sta *sta, + bool rx_accel) +{ + const u8 *mac = NULL; + + if (!sta || !test_bit(key->hw_key_idx, common->keymap)) + return false; + + if (rx_accel) + mac = sta->addr; + + return ath_hw_keysetmac(common, key->hw_key_idx, mac); +} +EXPORT_SYMBOL(ath_hw_rx_crypt); + static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, const struct ath_keyval *k, const u8 *mac) @@ -473,7 +490,8 @@ static int ath_reserve_key_cache_slot(struct ath_common *common, int ath_key_config(struct ath_common *common, struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) + struct ieee80211_key_conf *key, + bool rx_accel) { struct ath_keyval hk; const u8 *mac = NULL; @@ -527,21 +545,28 @@ int ath_key_config(struct ath_common *common, idx = key->keyidx; break; } - } else if (key->keyidx) { + } else if (key->keyidx > 1) { if (WARN_ON(!sta)) return -EOPNOTSUPP; mac = sta->addr; if (vif->type != NL80211_IFTYPE_AP) { - /* Only keyidx 0 should be used with unicast key, but - * allow this for client mode for now. */ + /* Only keyidx 0 and when using Extended Key ID 1 should + * be used with a unicast key. But allow this for client + * mode for now. + */ idx = key->keyidx; } else return -EIO; } else { if (WARN_ON(!sta)) return -EOPNOTSUPP; - mac = sta->addr; + + /* Handle sta Tx only keys like GTK keys for now */ + if (rx_accel) + mac = sta->addr; + else + mac = NULL; idx = ath_reserve_key_cache_slot(common, key->cipher); } -- 2.20.1