aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c10
-rw-r--r--drivers/net/wireless/ath/key.c6
4 files changed, 36 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index a2ddabf0ca2f..a6b538802251 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -256,6 +256,8 @@ struct ath_node {
256#endif 256#endif
257 struct ath_atx_tid tid[WME_NUM_TID]; 257 struct ath_atx_tid tid[WME_NUM_TID];
258 struct ath_atx_ac ac[WME_NUM_AC]; 258 struct ath_atx_ac ac[WME_NUM_AC];
259 int ps_key;
260
259 u16 maxampdu; 261 u16 maxampdu;
260 u8 mpdudensity; 262 u8 mpdudensity;
261 263
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;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 48ff8c22ba1f..65d46c6ebced 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1526,7 +1526,7 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1526 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; 1526 struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
1527 struct ieee80211_hdr *hdr; 1527 struct ieee80211_hdr *hdr;
1528 struct ath_frame_info *fi = get_frame_info(skb); 1528 struct ath_frame_info *fi = get_frame_info(skb);
1529 struct ath_node *an; 1529 struct ath_node *an = NULL;
1530 struct ath_atx_tid *tid; 1530 struct ath_atx_tid *tid;
1531 enum ath9k_key_type keytype; 1531 enum ath9k_key_type keytype;
1532 u16 seqno = 0; 1532 u16 seqno = 0;
@@ -1534,11 +1534,13 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1534 1534
1535 keytype = ath9k_cmn_get_hw_crypto_keytype(skb); 1535 keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
1536 1536
1537 if (sta)
1538 an = (struct ath_node *) sta->drv_priv;
1539
1537 hdr = (struct ieee80211_hdr *)skb->data; 1540 hdr = (struct ieee80211_hdr *)skb->data;
1538 if (sta && ieee80211_is_data_qos(hdr->frame_control) && 1541 if (an && ieee80211_is_data_qos(hdr->frame_control) &&
1539 conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { 1542 conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
1540 1543
1541 an = (struct ath_node *) sta->drv_priv;
1542 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; 1544 tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
1543 1545
1544 /* 1546 /*
@@ -1554,6 +1556,8 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
1554 memset(fi, 0, sizeof(*fi)); 1556 memset(fi, 0, sizeof(*fi));
1555 if (hw_key) 1557 if (hw_key)
1556 fi->keyix = hw_key->hw_key_idx; 1558 fi->keyix = hw_key->hw_key_idx;
1559 else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
1560 fi->keyix = an->ps_key;
1557 else 1561 else
1558 fi->keyix = ATH9K_TXKEYIX_INVALID; 1562 fi->keyix = ATH9K_TXKEYIX_INVALID;
1559 fi->keytype = keytype; 1563 fi->keytype = keytype;
diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c
index 0d4f39cbdcab..a61ef3d6d89c 100644
--- a/drivers/net/wireless/ath/key.c
+++ b/drivers/net/wireless/ath/key.c
@@ -483,6 +483,9 @@ int ath_key_config(struct ath_common *common,
483 memset(&hk, 0, sizeof(hk)); 483 memset(&hk, 0, sizeof(hk));
484 484
485 switch (key->cipher) { 485 switch (key->cipher) {
486 case 0:
487 hk.kv_type = ATH_CIPHER_CLR;
488 break;
486 case WLAN_CIPHER_SUITE_WEP40: 489 case WLAN_CIPHER_SUITE_WEP40:
487 case WLAN_CIPHER_SUITE_WEP104: 490 case WLAN_CIPHER_SUITE_WEP104:
488 hk.kv_type = ATH_CIPHER_WEP; 491 hk.kv_type = ATH_CIPHER_WEP;
@@ -498,7 +501,8 @@ int ath_key_config(struct ath_common *common,
498 } 501 }
499 502
500 hk.kv_len = key->keylen; 503 hk.kv_len = key->keylen;
501 memcpy(hk.kv_val, key->key, key->keylen); 504 if (key->keylen)
505 memcpy(hk.kv_val, key->key, key->keylen);
502 506
503 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { 507 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
504 switch (vif->type) { 508 switch (vif->type) {