diff options
-rw-r--r-- | drivers/net/wireless/ath/ath10k/core.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath10k/mac.c | 161 |
2 files changed, 72 insertions, 93 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index abb32037c3f7..a47b41dd966f 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
@@ -285,10 +285,8 @@ struct ath10k_vif { | |||
285 | u32 aid; | 285 | u32 aid; |
286 | u8 bssid[ETH_ALEN]; | 286 | u8 bssid[ETH_ALEN]; |
287 | 287 | ||
288 | struct work_struct wep_key_work; | ||
289 | struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1]; | 288 | struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1]; |
290 | u8 def_wep_key_idx; | 289 | s8 def_wep_key_idx; |
291 | u8 def_wep_key_newidx; | ||
292 | 290 | ||
293 | u16 tx_seq_no; | 291 | u16 tx_seq_no; |
294 | 292 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index f9440deffa26..d3fe1a378e8b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -37,7 +37,7 @@ | |||
37 | static int ath10k_send_key(struct ath10k_vif *arvif, | 37 | static int ath10k_send_key(struct ath10k_vif *arvif, |
38 | struct ieee80211_key_conf *key, | 38 | struct ieee80211_key_conf *key, |
39 | enum set_key_cmd cmd, | 39 | enum set_key_cmd cmd, |
40 | const u8 *macaddr) | 40 | const u8 *macaddr, bool def_idx) |
41 | { | 41 | { |
42 | struct ath10k *ar = arvif->ar; | 42 | struct ath10k *ar = arvif->ar; |
43 | struct wmi_vdev_install_key_arg arg = { | 43 | struct wmi_vdev_install_key_arg arg = { |
@@ -72,6 +72,9 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
72 | * Otherwise pairwise key must be set */ | 72 | * Otherwise pairwise key must be set */ |
73 | if (memcmp(macaddr, arvif->vif->addr, ETH_ALEN)) | 73 | if (memcmp(macaddr, arvif->vif->addr, ETH_ALEN)) |
74 | arg.key_flags = WMI_KEY_PAIRWISE; | 74 | arg.key_flags = WMI_KEY_PAIRWISE; |
75 | |||
76 | if (def_idx) | ||
77 | arg.key_flags |= WMI_KEY_TX_USAGE; | ||
75 | break; | 78 | break; |
76 | default: | 79 | default: |
77 | ath10k_warn(ar, "cipher %d is not supported\n", key->cipher); | 80 | ath10k_warn(ar, "cipher %d is not supported\n", key->cipher); |
@@ -89,7 +92,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif, | |||
89 | static int ath10k_install_key(struct ath10k_vif *arvif, | 92 | static int ath10k_install_key(struct ath10k_vif *arvif, |
90 | struct ieee80211_key_conf *key, | 93 | struct ieee80211_key_conf *key, |
91 | enum set_key_cmd cmd, | 94 | enum set_key_cmd cmd, |
92 | const u8 *macaddr) | 95 | const u8 *macaddr, bool def_idx) |
93 | { | 96 | { |
94 | struct ath10k *ar = arvif->ar; | 97 | struct ath10k *ar = arvif->ar; |
95 | int ret; | 98 | int ret; |
@@ -98,7 +101,7 @@ static int ath10k_install_key(struct ath10k_vif *arvif, | |||
98 | 101 | ||
99 | reinit_completion(&ar->install_key_done); | 102 | reinit_completion(&ar->install_key_done); |
100 | 103 | ||
101 | ret = ath10k_send_key(arvif, key, cmd, macaddr); | 104 | ret = ath10k_send_key(arvif, key, cmd, macaddr, def_idx); |
102 | if (ret) | 105 | if (ret) |
103 | return ret; | 106 | return ret; |
104 | 107 | ||
@@ -116,6 +119,7 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif, | |||
116 | struct ath10k_peer *peer; | 119 | struct ath10k_peer *peer; |
117 | int ret; | 120 | int ret; |
118 | int i; | 121 | int i; |
122 | bool def_idx; | ||
119 | 123 | ||
120 | lockdep_assert_held(&ar->conf_mutex); | 124 | lockdep_assert_held(&ar->conf_mutex); |
121 | 125 | ||
@@ -129,9 +133,14 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif, | |||
129 | for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) { | 133 | for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) { |
130 | if (arvif->wep_keys[i] == NULL) | 134 | if (arvif->wep_keys[i] == NULL) |
131 | continue; | 135 | continue; |
136 | /* set TX_USAGE flag for default key id */ | ||
137 | if (arvif->def_wep_key_idx == i) | ||
138 | def_idx = true; | ||
139 | else | ||
140 | def_idx = false; | ||
132 | 141 | ||
133 | ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY, | 142 | ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY, |
134 | addr); | 143 | addr, def_idx); |
135 | if (ret) | 144 | if (ret) |
136 | return ret; | 145 | return ret; |
137 | 146 | ||
@@ -165,8 +174,9 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif, | |||
165 | if (peer->keys[i] == NULL) | 174 | if (peer->keys[i] == NULL) |
166 | continue; | 175 | continue; |
167 | 176 | ||
177 | /* key flags are not required to delete the key */ | ||
168 | ret = ath10k_install_key(arvif, peer->keys[i], | 178 | ret = ath10k_install_key(arvif, peer->keys[i], |
169 | DISABLE_KEY, addr); | 179 | DISABLE_KEY, addr, false); |
170 | if (ret && first_errno == 0) | 180 | if (ret && first_errno == 0) |
171 | first_errno = ret; | 181 | first_errno = ret; |
172 | 182 | ||
@@ -240,8 +250,8 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, | |||
240 | 250 | ||
241 | if (i == ARRAY_SIZE(peer->keys)) | 251 | if (i == ARRAY_SIZE(peer->keys)) |
242 | break; | 252 | break; |
243 | 253 | /* key flags are not required to delete the key */ | |
244 | ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr); | 254 | ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, false); |
245 | if (ret && first_errno == 0) | 255 | if (ret && first_errno == 0) |
246 | first_errno = ret; | 256 | first_errno = ret; |
247 | 257 | ||
@@ -1855,7 +1865,8 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, | |||
1855 | ath10k_warn(ar, "faield to down vdev %i: %d\n", | 1865 | ath10k_warn(ar, "faield to down vdev %i: %d\n", |
1856 | arvif->vdev_id, ret); | 1866 | arvif->vdev_id, ret); |
1857 | 1867 | ||
1858 | arvif->def_wep_key_idx = 0; | 1868 | arvif->def_wep_key_idx = -1; |
1869 | |||
1859 | arvif->is_up = false; | 1870 | arvif->is_up = false; |
1860 | } | 1871 | } |
1861 | 1872 | ||
@@ -1914,11 +1925,14 @@ static int ath10k_station_assoc(struct ath10k *ar, | |||
1914 | } | 1925 | } |
1915 | } | 1926 | } |
1916 | 1927 | ||
1917 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); | 1928 | /* Plumb cached keys only for static WEP */ |
1918 | if (ret) { | 1929 | if (arvif->def_wep_key_idx != -1) { |
1919 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", | 1930 | ret = ath10k_install_peer_wep_keys(arvif, sta->addr); |
1920 | arvif->vdev_id, ret); | 1931 | if (ret) { |
1921 | return ret; | 1932 | ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", |
1933 | arvif->vdev_id, ret); | ||
1934 | return ret; | ||
1935 | } | ||
1922 | } | 1936 | } |
1923 | } | 1937 | } |
1924 | 1938 | ||
@@ -2190,69 +2204,6 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2190 | } | 2204 | } |
2191 | } | 2205 | } |
2192 | 2206 | ||
2193 | static void ath10k_tx_wep_key_work(struct work_struct *work) | ||
2194 | { | ||
2195 | struct ath10k_vif *arvif = container_of(work, struct ath10k_vif, | ||
2196 | wep_key_work); | ||
2197 | struct ath10k *ar = arvif->ar; | ||
2198 | int ret, keyidx = arvif->def_wep_key_newidx; | ||
2199 | |||
2200 | mutex_lock(&arvif->ar->conf_mutex); | ||
2201 | |||
2202 | if (arvif->ar->state != ATH10K_STATE_ON) | ||
2203 | goto unlock; | ||
2204 | |||
2205 | if (arvif->def_wep_key_idx == keyidx) | ||
2206 | goto unlock; | ||
2207 | |||
2208 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", | ||
2209 | arvif->vdev_id, keyidx); | ||
2210 | |||
2211 | ret = ath10k_wmi_vdev_set_param(arvif->ar, | ||
2212 | arvif->vdev_id, | ||
2213 | arvif->ar->wmi.vdev_param->def_keyid, | ||
2214 | keyidx); | ||
2215 | if (ret) { | ||
2216 | ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n", | ||
2217 | arvif->vdev_id, | ||
2218 | ret); | ||
2219 | goto unlock; | ||
2220 | } | ||
2221 | |||
2222 | arvif->def_wep_key_idx = keyidx; | ||
2223 | |||
2224 | unlock: | ||
2225 | mutex_unlock(&arvif->ar->conf_mutex); | ||
2226 | } | ||
2227 | |||
2228 | static void ath10k_tx_h_update_wep_key(struct ieee80211_vif *vif, | ||
2229 | struct ieee80211_key_conf *key, | ||
2230 | struct sk_buff *skb) | ||
2231 | { | ||
2232 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | ||
2233 | struct ath10k *ar = arvif->ar; | ||
2234 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
2235 | |||
2236 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
2237 | return; | ||
2238 | |||
2239 | if (!key) | ||
2240 | return; | ||
2241 | |||
2242 | if (key->cipher != WLAN_CIPHER_SUITE_WEP40 && | ||
2243 | key->cipher != WLAN_CIPHER_SUITE_WEP104) | ||
2244 | return; | ||
2245 | |||
2246 | if (key->keyidx == arvif->def_wep_key_idx) | ||
2247 | return; | ||
2248 | |||
2249 | /* FIXME: Most likely a few frames will be TXed with an old key. Simply | ||
2250 | * queueing frames until key index is updated is not an option because | ||
2251 | * sk_buff may need more processing to be done, e.g. offchannel */ | ||
2252 | arvif->def_wep_key_newidx = key->keyidx; | ||
2253 | ieee80211_queue_work(ar->hw, &arvif->wep_key_work); | ||
2254 | } | ||
2255 | |||
2256 | static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, | 2207 | static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, |
2257 | struct ieee80211_vif *vif, | 2208 | struct ieee80211_vif *vif, |
2258 | struct sk_buff *skb) | 2209 | struct sk_buff *skb) |
@@ -2613,7 +2564,6 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
2613 | struct ath10k *ar = hw->priv; | 2564 | struct ath10k *ar = hw->priv; |
2614 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 2565 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2615 | struct ieee80211_vif *vif = info->control.vif; | 2566 | struct ieee80211_vif *vif = info->control.vif; |
2616 | struct ieee80211_key_conf *key = info->control.hw_key; | ||
2617 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 2567 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
2618 | 2568 | ||
2619 | /* We should disable CCK RATE due to P2P */ | 2569 | /* We should disable CCK RATE due to P2P */ |
@@ -2627,7 +2577,6 @@ static void ath10k_tx(struct ieee80211_hw *hw, | |||
2627 | /* it makes no sense to process injected frames like that */ | 2577 | /* it makes no sense to process injected frames like that */ |
2628 | if (vif && vif->type != NL80211_IFTYPE_MONITOR) { | 2578 | if (vif && vif->type != NL80211_IFTYPE_MONITOR) { |
2629 | ath10k_tx_h_nwifi(hw, skb); | 2579 | ath10k_tx_h_nwifi(hw, skb); |
2630 | ath10k_tx_h_update_wep_key(vif, key, skb); | ||
2631 | ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb); | 2580 | ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb); |
2632 | ath10k_tx_h_seq_no(vif, skb); | 2581 | ath10k_tx_h_seq_no(vif, skb); |
2633 | } | 2582 | } |
@@ -3132,7 +3081,6 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
3132 | arvif->ar = ar; | 3081 | arvif->ar = ar; |
3133 | arvif->vif = vif; | 3082 | arvif->vif = vif; |
3134 | 3083 | ||
3135 | INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); | ||
3136 | INIT_LIST_HEAD(&arvif->list); | 3084 | INIT_LIST_HEAD(&arvif->list); |
3137 | 3085 | ||
3138 | if (ar->free_vdev_map == 0) { | 3086 | if (ar->free_vdev_map == 0) { |
@@ -3231,14 +3179,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, | |||
3231 | goto err_vdev_delete; | 3179 | goto err_vdev_delete; |
3232 | } | 3180 | } |
3233 | 3181 | ||
3234 | vdev_param = ar->wmi.vdev_param->def_keyid; | 3182 | arvif->def_wep_key_idx = -1; |
3235 | ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param, | ||
3236 | arvif->def_wep_key_idx); | ||
3237 | if (ret) { | ||
3238 | ath10k_warn(ar, "failed to set vdev %i default key id: %d\n", | ||
3239 | arvif->vdev_id, ret); | ||
3240 | goto err_vdev_delete; | ||
3241 | } | ||
3242 | 3183 | ||
3243 | vdev_param = ar->wmi.vdev_param->tx_encap_type; | 3184 | vdev_param = ar->wmi.vdev_param->tx_encap_type; |
3244 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, | 3185 | ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, |
@@ -3358,8 +3299,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, | |||
3358 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | 3299 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); |
3359 | int ret; | 3300 | int ret; |
3360 | 3301 | ||
3361 | cancel_work_sync(&arvif->wep_key_work); | ||
3362 | |||
3363 | mutex_lock(&ar->conf_mutex); | 3302 | mutex_lock(&ar->conf_mutex); |
3364 | 3303 | ||
3365 | spin_lock_bh(&ar->data_lock); | 3304 | spin_lock_bh(&ar->data_lock); |
@@ -3731,6 +3670,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3731 | const u8 *peer_addr; | 3670 | const u8 *peer_addr; |
3732 | bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 || | 3671 | bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 || |
3733 | key->cipher == WLAN_CIPHER_SUITE_WEP104; | 3672 | key->cipher == WLAN_CIPHER_SUITE_WEP104; |
3673 | bool def_idx = false; | ||
3734 | int ret = 0; | 3674 | int ret = 0; |
3735 | 3675 | ||
3736 | if (key->keyidx > WMI_MAX_KEY_INDEX) | 3676 | if (key->keyidx > WMI_MAX_KEY_INDEX) |
@@ -3776,7 +3716,14 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3776 | ath10k_clear_vdev_key(arvif, key); | 3716 | ath10k_clear_vdev_key(arvif, key); |
3777 | } | 3717 | } |
3778 | 3718 | ||
3779 | ret = ath10k_install_key(arvif, key, cmd, peer_addr); | 3719 | /* set TX_USAGE flag for all the keys incase of dot1x-WEP. For |
3720 | * static WEP, do not set this flag for the keys whose key id | ||
3721 | * is greater than default key id. | ||
3722 | */ | ||
3723 | if (arvif->def_wep_key_idx == -1) | ||
3724 | def_idx = true; | ||
3725 | |||
3726 | ret = ath10k_install_key(arvif, key, cmd, peer_addr, def_idx); | ||
3780 | if (ret) { | 3727 | if (ret) { |
3781 | ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n", | 3728 | ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n", |
3782 | arvif->vdev_id, peer_addr, ret); | 3729 | arvif->vdev_id, peer_addr, ret); |
@@ -3801,6 +3748,39 @@ exit: | |||
3801 | return ret; | 3748 | return ret; |
3802 | } | 3749 | } |
3803 | 3750 | ||
3751 | static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw, | ||
3752 | struct ieee80211_vif *vif, | ||
3753 | int keyidx) | ||
3754 | { | ||
3755 | struct ath10k *ar = hw->priv; | ||
3756 | struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); | ||
3757 | int ret; | ||
3758 | |||
3759 | mutex_lock(&arvif->ar->conf_mutex); | ||
3760 | |||
3761 | if (arvif->ar->state != ATH10K_STATE_ON) | ||
3762 | goto unlock; | ||
3763 | |||
3764 | ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", | ||
3765 | arvif->vdev_id, keyidx); | ||
3766 | |||
3767 | ret = ath10k_wmi_vdev_set_param(arvif->ar, | ||
3768 | arvif->vdev_id, | ||
3769 | arvif->ar->wmi.vdev_param->def_keyid, | ||
3770 | keyidx); | ||
3771 | |||
3772 | if (ret) { | ||
3773 | ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n", | ||
3774 | arvif->vdev_id, | ||
3775 | ret); | ||
3776 | goto unlock; | ||
3777 | } | ||
3778 | |||
3779 | arvif->def_wep_key_idx = keyidx; | ||
3780 | unlock: | ||
3781 | mutex_unlock(&arvif->ar->conf_mutex); | ||
3782 | } | ||
3783 | |||
3804 | static void ath10k_sta_rc_update_wk(struct work_struct *wk) | 3784 | static void ath10k_sta_rc_update_wk(struct work_struct *wk) |
3805 | { | 3785 | { |
3806 | struct ath10k *ar; | 3786 | struct ath10k *ar; |
@@ -4966,6 +4946,7 @@ static const struct ieee80211_ops ath10k_ops = { | |||
4966 | .hw_scan = ath10k_hw_scan, | 4946 | .hw_scan = ath10k_hw_scan, |
4967 | .cancel_hw_scan = ath10k_cancel_hw_scan, | 4947 | .cancel_hw_scan = ath10k_cancel_hw_scan, |
4968 | .set_key = ath10k_set_key, | 4948 | .set_key = ath10k_set_key, |
4949 | .set_default_unicast_key = ath10k_set_default_unicast_key, | ||
4969 | .sta_state = ath10k_sta_state, | 4950 | .sta_state = ath10k_sta_state, |
4970 | .conf_tx = ath10k_conf_tx, | 4951 | .conf_tx = ath10k_conf_tx, |
4971 | .remain_on_channel = ath10k_remain_on_channel, | 4952 | .remain_on_channel = ath10k_remain_on_channel, |