diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath/key.c | 6 |
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 | ||
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; |
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) { |