diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-04-17 17:28:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-19 15:38:06 -0400 |
commit | 93ae2dd2230393566738a5f211ffbaa33b056d56 (patch) | |
tree | 7dc59fdc6e07d2919b16e2def11258c2caa5d615 /drivers/net/wireless/ath/ath9k/main.c | |
parent | 5519541d5a5f19893546883547e2f0f2e5934df7 (diff) |
ath9k: assign keycache slots to unencrypted stations
Frame filtering relies on having a valid destination index (keycache slot),
to keep track of the destination. Assigning a keycache slot (configured
to unencrypted, with no key data attached) improves powersave handling in
AP mode with no encryption.
The dummy keycache entry for a station is cleared, when a real key gets
added.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 01df5876fda1..e7d6d98ed1cc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1732,18 +1732,37 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, | |||
1732 | struct ieee80211_sta *sta) | 1732 | struct ieee80211_sta *sta) |
1733 | { | 1733 | { |
1734 | struct ath_softc *sc = hw->priv; | 1734 | struct ath_softc *sc = hw->priv; |
1735 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1736 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1737 | struct ieee80211_key_conf ps_key = { }; | ||
1735 | 1738 | ||
1736 | ath_node_attach(sc, sta); | 1739 | ath_node_attach(sc, sta); |
1740 | an->ps_key = ath_key_config(common, vif, sta, &ps_key); | ||
1737 | 1741 | ||
1738 | return 0; | 1742 | return 0; |
1739 | } | 1743 | } |
1740 | 1744 | ||
1745 | static void ath9k_del_ps_key(struct ath_softc *sc, | ||
1746 | struct ieee80211_vif *vif, | ||
1747 | struct ieee80211_sta *sta) | ||
1748 | { | ||
1749 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
1750 | struct ath_node *an = (struct ath_node *) sta->drv_priv; | ||
1751 | struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; | ||
1752 | |||
1753 | if (!an->ps_key) | ||
1754 | return; | ||
1755 | |||
1756 | ath_key_delete(common, &ps_key); | ||
1757 | } | ||
1758 | |||
1741 | static int ath9k_sta_remove(struct ieee80211_hw *hw, | 1759 | static int ath9k_sta_remove(struct ieee80211_hw *hw, |
1742 | struct ieee80211_vif *vif, | 1760 | struct ieee80211_vif *vif, |
1743 | struct ieee80211_sta *sta) | 1761 | struct ieee80211_sta *sta) |
1744 | { | 1762 | { |
1745 | struct ath_softc *sc = hw->priv; | 1763 | struct ath_softc *sc = hw->priv; |
1746 | 1764 | ||
1765 | ath9k_del_ps_key(sc, vif, sta); | ||
1747 | ath_node_detach(sc, sta); | 1766 | ath_node_detach(sc, sta); |
1748 | 1767 | ||
1749 | return 0; | 1768 | return 0; |
@@ -1844,6 +1863,9 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1844 | 1863 | ||
1845 | switch (cmd) { | 1864 | switch (cmd) { |
1846 | case SET_KEY: | 1865 | case SET_KEY: |
1866 | if (sta) | ||
1867 | ath9k_del_ps_key(sc, vif, sta); | ||
1868 | |||
1847 | ret = ath_key_config(common, vif, sta, key); | 1869 | ret = ath_key_config(common, vif, sta, key); |
1848 | if (ret >= 0) { | 1870 | if (ret >= 0) { |
1849 | key->hw_key_idx = ret; | 1871 | key->hw_key_idx = ret; |