aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h4
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c161
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 @@
37static int ath10k_send_key(struct ath10k_vif *arvif, 37static 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,
89static int ath10k_install_key(struct ath10k_vif *arvif, 92static 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
2193static 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
2224unlock:
2225 mutex_unlock(&arvif->ar->conf_mutex);
2226}
2227
2228static 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
2256static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, 2207static 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
3751static 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;
3780unlock:
3781 mutex_unlock(&arvif->ar->conf_mutex);
3782}
3783
3804static void ath10k_sta_rc_update_wk(struct work_struct *wk) 3784static 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,