1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 */ 5 6 #include "core.h" 7 #include "peer.h" 8 #include "debug.h" 9 10 struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id, 11 const u8 *addr) 12 { 13 struct ath11k_peer *peer; 14 15 lockdep_assert_held(&ab->base_lock); 16 17 list_for_each_entry(peer, &ab->peers, list) { 18 if (peer->vdev_id != vdev_id) 19 continue; 20 if (!ether_addr_equal(peer->addr, addr)) 21 continue; 22 23 return peer; 24 } 25 26 return NULL; 27 } 28 29 static struct ath11k_peer *ath11k_peer_find_by_pdev_idx(struct ath11k_base *ab, 30 u8 pdev_idx, const u8 *addr) 31 { 32 struct ath11k_peer *peer; 33 34 lockdep_assert_held(&ab->base_lock); 35 36 list_for_each_entry(peer, &ab->peers, list) { 37 if (peer->pdev_idx != pdev_idx) 38 continue; 39 if (!ether_addr_equal(peer->addr, addr)) 40 continue; 41 42 return peer; 43 } 44 45 return NULL; 46 } 47 48 struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab, 49 const u8 *addr) 50 { 51 struct ath11k_peer *peer; 52 53 lockdep_assert_held(&ab->base_lock); 54 55 list_for_each_entry(peer, &ab->peers, list) { 56 if (!ether_addr_equal(peer->addr, addr)) 57 continue; 58 59 return peer; 60 } 61 62 return NULL; 63 } 64 65 struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, 66 int peer_id) 67 { 68 struct ath11k_peer *peer; 69 70 lockdep_assert_held(&ab->base_lock); 71 72 list_for_each_entry(peer, &ab->peers, list) 73 if (peer_id == peer->peer_id) 74 return peer; 75 76 return NULL; 77 } 78 79 void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id) 80 { 81 struct ath11k_peer *peer; 82 83 spin_lock_bh(&ab->base_lock); 84 85 peer = ath11k_peer_find_by_id(ab, peer_id); 86 if (!peer) { 87 ath11k_warn(ab, "peer-unmap-event: unknown peer id %d\n", 88 peer_id); 89 goto exit; 90 } 91 92 ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer unmap vdev %d peer %pM id %d\n", 93 peer->vdev_id, peer->addr, peer_id); 94 95 list_del(&peer->list); 96 kfree(peer); 97 wake_up(&ab->peer_mapping_wq); 98 99 exit: 100 spin_unlock_bh(&ab->base_lock); 101 } 102 103 void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, 104 u8 *mac_addr, u16 ast_hash) 105 { 106 struct ath11k_peer *peer; 107 108 spin_lock_bh(&ab->base_lock); 109 peer = ath11k_peer_find(ab, vdev_id, mac_addr); 110 if (!peer) { 111 peer = kzalloc(sizeof(*peer), GFP_ATOMIC); 112 if (!peer) 113 goto exit; 114 115 peer->vdev_id = vdev_id; 116 peer->peer_id = peer_id; 117 peer->ast_hash = ast_hash; 118 ether_addr_copy(peer->addr, mac_addr); 119 list_add(&peer->list, &ab->peers); 120 wake_up(&ab->peer_mapping_wq); 121 } 122 123 ath11k_dbg(ab, ATH11K_DBG_DP_HTT, "htt peer map vdev %d peer %pM id %d\n", 124 vdev_id, mac_addr, peer_id); 125 126 exit: 127 spin_unlock_bh(&ab->base_lock); 128 } 129 130 static int ath11k_wait_for_peer_common(struct ath11k_base *ab, int vdev_id, 131 const u8 *addr, bool expect_mapped) 132 { 133 int ret; 134 135 ret = wait_event_timeout(ab->peer_mapping_wq, ({ 136 bool mapped; 137 138 spin_lock_bh(&ab->base_lock); 139 mapped = !!ath11k_peer_find(ab, vdev_id, addr); 140 spin_unlock_bh(&ab->base_lock); 141 142 (mapped == expect_mapped || 143 test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)); 144 }), 3 * HZ); 145 146 if (ret <= 0) 147 return -ETIMEDOUT; 148 149 return 0; 150 } 151 152 void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id) 153 { 154 struct ath11k_peer *peer, *tmp; 155 struct ath11k_base *ab = ar->ab; 156 157 lockdep_assert_held(&ar->conf_mutex); 158 159 spin_lock_bh(&ab->base_lock); 160 list_for_each_entry_safe(peer, tmp, &ab->peers, list) { 161 if (peer->vdev_id != vdev_id) 162 continue; 163 164 ath11k_warn(ab, "removing stale peer %pM from vdev_id %d\n", 165 peer->addr, vdev_id); 166 167 list_del(&peer->list); 168 kfree(peer); 169 ar->num_peers--; 170 } 171 172 spin_unlock_bh(&ab->base_lock); 173 } 174 175 static int ath11k_wait_for_peer_deleted(struct ath11k *ar, int vdev_id, const u8 *addr) 176 { 177 return ath11k_wait_for_peer_common(ar->ab, vdev_id, addr, false); 178 } 179 180 int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id, 181 const u8 *addr) 182 { 183 int ret; 184 unsigned long time_left; 185 186 ret = ath11k_wait_for_peer_deleted(ar, vdev_id, addr); 187 if (ret) { 188 ath11k_warn(ar->ab, "failed wait for peer deleted"); 189 return ret; 190 } 191 192 time_left = wait_for_completion_timeout(&ar->peer_delete_done, 193 3 * HZ); 194 if (time_left == 0) { 195 ath11k_warn(ar->ab, "Timeout in receiving peer delete response\n"); 196 return -ETIMEDOUT; 197 } 198 199 return 0; 200 } 201 202 int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr) 203 { 204 int ret; 205 206 lockdep_assert_held(&ar->conf_mutex); 207 208 reinit_completion(&ar->peer_delete_done); 209 210 ret = ath11k_wmi_send_peer_delete_cmd(ar, addr, vdev_id); 211 if (ret) { 212 ath11k_warn(ar->ab, 213 "failed to delete peer vdev_id %d addr %pM ret %d\n", 214 vdev_id, addr, ret); 215 return ret; 216 } 217 218 ret = ath11k_wait_for_peer_delete_done(ar, vdev_id, addr); 219 if (ret) 220 return ret; 221 222 ar->num_peers--; 223 224 return 0; 225 } 226 227 static int ath11k_wait_for_peer_created(struct ath11k *ar, int vdev_id, const u8 *addr) 228 { 229 return ath11k_wait_for_peer_common(ar->ab, vdev_id, addr, true); 230 } 231 232 int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif, 233 struct ieee80211_sta *sta, struct peer_create_params *param) 234 { 235 struct ath11k_peer *peer; 236 int ret; 237 238 lockdep_assert_held(&ar->conf_mutex); 239 240 if (ar->num_peers > (ar->max_num_peers - 1)) { 241 ath11k_warn(ar->ab, 242 "failed to create peer due to insufficient peer entry resource in firmware\n"); 243 return -ENOBUFS; 244 } 245 246 spin_lock_bh(&ar->ab->base_lock); 247 peer = ath11k_peer_find_by_pdev_idx(ar->ab, ar->pdev_idx, param->peer_addr); 248 if (peer) { 249 spin_unlock_bh(&ar->ab->base_lock); 250 return -EINVAL; 251 } 252 spin_unlock_bh(&ar->ab->base_lock); 253 254 ret = ath11k_wmi_send_peer_create_cmd(ar, param); 255 if (ret) { 256 ath11k_warn(ar->ab, 257 "failed to send peer create vdev_id %d ret %d\n", 258 param->vdev_id, ret); 259 return ret; 260 } 261 262 ret = ath11k_wait_for_peer_created(ar, param->vdev_id, 263 param->peer_addr); 264 if (ret) 265 return ret; 266 267 spin_lock_bh(&ar->ab->base_lock); 268 269 peer = ath11k_peer_find(ar->ab, param->vdev_id, param->peer_addr); 270 if (!peer) { 271 spin_unlock_bh(&ar->ab->base_lock); 272 ath11k_warn(ar->ab, "failed to find peer %pM on vdev %i after creation\n", 273 param->peer_addr, param->vdev_id); 274 275 reinit_completion(&ar->peer_delete_done); 276 277 ret = ath11k_wmi_send_peer_delete_cmd(ar, param->peer_addr, 278 param->vdev_id); 279 if (ret) { 280 ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", 281 param->vdev_id, param->peer_addr); 282 return ret; 283 } 284 285 ret = ath11k_wait_for_peer_delete_done(ar, param->vdev_id, 286 param->peer_addr); 287 if (ret) 288 return ret; 289 290 return -ENOENT; 291 } 292 293 peer->pdev_idx = ar->pdev_idx; 294 peer->sta = sta; 295 arvif->ast_hash = peer->ast_hash; 296 297 peer->sec_type = HAL_ENCRYPT_TYPE_OPEN; 298 peer->sec_type_grp = HAL_ENCRYPT_TYPE_OPEN; 299 300 ar->num_peers++; 301 302 spin_unlock_bh(&ar->ab->base_lock); 303 304 return 0; 305 } 306