aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSenthilKumar Jegadeesan <sjegadee@qti.qualcomm.com>2015-01-29 06:50:38 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2015-02-04 02:14:43 -0500
commit627613f8f081928efe2e82100f54c67e17bea72c (patch)
tree193f982dc9b61a133df8b21711caa9c9cb3f40a2
parent6c3d7d785966f89bda1be17aef59ad14ce321f38 (diff)
ath10k: prevent setting wrong key idx for station
Ath10k driver sets wrong default key idx that results in sending unicast frames with multicast key. The reason for this behavior is that cached broadcast key is installed for station MAC address on association. After dot1x completes, unicast key is installed for station MAC address. Default key idx is set to broadcast key id when driver tries to send broadcast frame. This causes firmware to use broadcast key id to transmit unicast frames to stations. Used TX_USAGE flag to set default key for stations. Added callback for setting unicast default idx which will be invoked on every default key idx configuration. Signed-off-by: SenthilKumar Jegadeesan <sjegadee@qti.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-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,