aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-04-17 17:28:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-19 15:38:06 -0400
commit93ae2dd2230393566738a5f211ffbaa33b056d56 (patch)
tree7dc59fdc6e07d2919b16e2def11258c2caa5d615 /drivers/net/wireless/ath/ath9k/main.c
parent5519541d5a5f19893546883547e2f0f2e5934df7 (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.c22
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
1745static 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
1741static int ath9k_sta_remove(struct ieee80211_hw *hw, 1759static 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;