Skip to content

Commit

Permalink
ath5k: Use common ath key management functions
Browse files Browse the repository at this point in the history
Use common ath key management functions in ath5k. This fixes problems with HW
encryption in AP mode, which was broken in the ath5k implementation.

Before (with the ath5k implementation) only one client could connect to the AP
using HW encryption and WPA. When a second client connected, the first client
was not able to send/receive any more packets. Because of the problems with HW
encryption, software encryption was always used in AP mode, which resulted in a
high CPU load (and/or low thruput) on embedded devices. Instead of trying to
fix the implementation in ath5k it makes more sense to share the code with
ath9k.

This also enables HW encryption for AP mode again.

Signed-off-by: Bruno Randolf <br1@einfach.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Bruno Randolf authored and John W. Linville committed Sep 16, 2010
1 parent 1bba5b7 commit e0f8c2a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 19 deletions.
3 changes: 3 additions & 0 deletions drivers/net/wireless/ath/ath5k/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
}

/* Crypto settings */
common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);

ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 &&
(ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
!AR5K_EEPROM_AES_DIS(ee->ee_misc5));
Expand Down
33 changes: 14 additions & 19 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2570,6 +2570,7 @@ static int
ath5k_init(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
struct ath_common *common = ath5k_hw_common(ah);
int ret, i;

mutex_lock(&sc->lock);
Expand Down Expand Up @@ -2605,8 +2606,8 @@ ath5k_init(struct ath5k_softc *sc)
* Reset the key cache since some parts do not reset the
* contents on initial power up or resume from suspend.
*/
for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
ath5k_hw_reset_key(ah, i);
for (i = 0; i < common->keymax; i++)
ath_hw_keyreset(common, (u16)i);

ath5k_hw_set_ack_bitrate_high(ah, true);
ret = 0;
Expand Down Expand Up @@ -3287,9 +3288,6 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (modparam_nohwcrypt)
return -EOPNOTSUPP;

if (sc->opmode == NL80211_IFTYPE_AP)
return -EOPNOTSUPP;

switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
Expand All @@ -3298,7 +3296,6 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
case WLAN_CIPHER_SUITE_CCMP:
if (sc->ah->ah_aes_support)
break;

return -EOPNOTSUPP;
default:
WARN_ON(1);
Expand All @@ -3309,27 +3306,25 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,

switch (cmd) {
case SET_KEY:
ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
sta ? sta->addr : NULL);
if (ret) {
ATH5K_ERR(sc, "can't set the key\n");
goto unlock;
ret = ath_key_config(common, vif, sta, key);
if (ret >= 0) {
key->hw_key_idx = ret;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
if (key->cipher == WLAN_CIPHER_SUITE_CCMP)
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
ret = 0;
}
__set_bit(key->keyidx, common->keymap);
key->hw_key_idx = key->keyidx;
key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
IEEE80211_KEY_FLAG_GENERATE_MMIC);
break;
case DISABLE_KEY:
ath5k_hw_reset_key(sc->ah, key->keyidx);
__clear_bit(key->keyidx, common->keymap);
ath_key_delete(common, key);
break;
default:
ret = -EINVAL;
goto unlock;
}

unlock:
mmiowb();
mutex_unlock(&sc->lock);
return ret;
Expand Down

0 comments on commit e0f8c2a

Please sign in to comment.