1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
10 struct ath11k_peer
*ath11k_peer_find(struct ath11k_base
*ab
, int vdev_id
,
13 struct ath11k_peer
*peer
;
15 lockdep_assert_held(&ab
->base_lock
);
17 list_for_each_entry(peer
, &ab
->peers
, list
) {
18 if (peer
->vdev_id
!= vdev_id
)
20 if (!ether_addr_equal(peer
->addr
, addr
))
29 static struct ath11k_peer
*ath11k_peer_find_by_pdev_idx(struct ath11k_base
*ab
,
30 u8 pdev_idx
, const u8
*addr
)
32 struct ath11k_peer
*peer
;
34 lockdep_assert_held(&ab
->base_lock
);
36 list_for_each_entry(peer
, &ab
->peers
, list
) {
37 if (peer
->pdev_idx
!= pdev_idx
)
39 if (!ether_addr_equal(peer
->addr
, addr
))
48 struct ath11k_peer
*ath11k_peer_find_by_addr(struct ath11k_base
*ab
,
51 struct ath11k_peer
*peer
;
53 lockdep_assert_held(&ab
->base_lock
);
55 list_for_each_entry(peer
, &ab
->peers
, list
) {
56 if (!ether_addr_equal(peer
->addr
, addr
))
65 struct ath11k_peer
*ath11k_peer_find_by_id(struct ath11k_base
*ab
,
68 struct ath11k_peer
*peer
;
70 lockdep_assert_held(&ab
->base_lock
);
72 list_for_each_entry(peer
, &ab
->peers
, list
)
73 if (peer_id
== peer
->peer_id
)
79 struct ath11k_peer
*ath11k_peer_find_by_vdev_id(struct ath11k_base
*ab
,
82 struct ath11k_peer
*peer
;
84 spin_lock_bh(&ab
->base_lock
);
86 list_for_each_entry(peer
, &ab
->peers
, list
) {
87 if (vdev_id
== peer
->vdev_id
) {
88 spin_unlock_bh(&ab
->base_lock
);
92 spin_unlock_bh(&ab
->base_lock
);
96 void ath11k_peer_unmap_event(struct ath11k_base
*ab
, u16 peer_id
)
98 struct ath11k_peer
*peer
;
100 spin_lock_bh(&ab
->base_lock
);
102 peer
= ath11k_peer_find_by_id(ab
, peer_id
);
104 ath11k_warn(ab
, "peer-unmap-event: unknown peer id %d\n",
109 ath11k_dbg(ab
, ATH11K_DBG_DP_HTT
, "htt peer unmap vdev %d peer %pM id %d\n",
110 peer
->vdev_id
, peer
->addr
, peer_id
);
112 list_del(&peer
->list
);
114 wake_up(&ab
->peer_mapping_wq
);
117 spin_unlock_bh(&ab
->base_lock
);
120 void ath11k_peer_map_event(struct ath11k_base
*ab
, u8 vdev_id
, u16 peer_id
,
121 u8
*mac_addr
, u16 ast_hash
)
123 struct ath11k_peer
*peer
;
125 spin_lock_bh(&ab
->base_lock
);
126 peer
= ath11k_peer_find(ab
, vdev_id
, mac_addr
);
128 peer
= kzalloc(sizeof(*peer
), GFP_ATOMIC
);
132 peer
->vdev_id
= vdev_id
;
133 peer
->peer_id
= peer_id
;
134 peer
->ast_hash
= ast_hash
;
135 ether_addr_copy(peer
->addr
, mac_addr
);
136 list_add(&peer
->list
, &ab
->peers
);
137 wake_up(&ab
->peer_mapping_wq
);
140 ath11k_dbg(ab
, ATH11K_DBG_DP_HTT
, "htt peer map vdev %d peer %pM id %d\n",
141 vdev_id
, mac_addr
, peer_id
);
144 spin_unlock_bh(&ab
->base_lock
);
147 static int ath11k_wait_for_peer_common(struct ath11k_base
*ab
, int vdev_id
,
148 const u8
*addr
, bool expect_mapped
)
152 ret
= wait_event_timeout(ab
->peer_mapping_wq
, ({
155 spin_lock_bh(&ab
->base_lock
);
156 mapped
= !!ath11k_peer_find(ab
, vdev_id
, addr
);
157 spin_unlock_bh(&ab
->base_lock
);
159 (mapped
== expect_mapped
||
160 test_bit(ATH11K_FLAG_CRASH_FLUSH
, &ab
->dev_flags
));
169 void ath11k_peer_cleanup(struct ath11k
*ar
, u32 vdev_id
)
171 struct ath11k_peer
*peer
, *tmp
;
172 struct ath11k_base
*ab
= ar
->ab
;
174 lockdep_assert_held(&ar
->conf_mutex
);
176 spin_lock_bh(&ab
->base_lock
);
177 list_for_each_entry_safe(peer
, tmp
, &ab
->peers
, list
) {
178 if (peer
->vdev_id
!= vdev_id
)
181 ath11k_warn(ab
, "removing stale peer %pM from vdev_id %d\n",
182 peer
->addr
, vdev_id
);
184 list_del(&peer
->list
);
189 spin_unlock_bh(&ab
->base_lock
);
192 static int ath11k_wait_for_peer_deleted(struct ath11k
*ar
, int vdev_id
, const u8
*addr
)
194 return ath11k_wait_for_peer_common(ar
->ab
, vdev_id
, addr
, false);
197 int ath11k_wait_for_peer_delete_done(struct ath11k
*ar
, u32 vdev_id
,
201 unsigned long time_left
;
203 ret
= ath11k_wait_for_peer_deleted(ar
, vdev_id
, addr
);
205 ath11k_warn(ar
->ab
, "failed wait for peer deleted");
209 time_left
= wait_for_completion_timeout(&ar
->peer_delete_done
,
211 if (time_left
== 0) {
212 ath11k_warn(ar
->ab
, "Timeout in receiving peer delete response\n");
219 int ath11k_peer_delete(struct ath11k
*ar
, u32 vdev_id
, u8
*addr
)
223 lockdep_assert_held(&ar
->conf_mutex
);
225 reinit_completion(&ar
->peer_delete_done
);
227 ret
= ath11k_wmi_send_peer_delete_cmd(ar
, addr
, vdev_id
);
230 "failed to delete peer vdev_id %d addr %pM ret %d\n",
235 ret
= ath11k_wait_for_peer_delete_done(ar
, vdev_id
, addr
);
244 static int ath11k_wait_for_peer_created(struct ath11k
*ar
, int vdev_id
, const u8
*addr
)
246 return ath11k_wait_for_peer_common(ar
->ab
, vdev_id
, addr
, true);
249 int ath11k_peer_create(struct ath11k
*ar
, struct ath11k_vif
*arvif
,
250 struct ieee80211_sta
*sta
, struct peer_create_params
*param
)
252 struct ath11k_peer
*peer
;
255 lockdep_assert_held(&ar
->conf_mutex
);
257 if (ar
->num_peers
> (ar
->max_num_peers
- 1)) {
259 "failed to create peer due to insufficient peer entry resource in firmware\n");
263 spin_lock_bh(&ar
->ab
->base_lock
);
264 peer
= ath11k_peer_find_by_pdev_idx(ar
->ab
, ar
->pdev_idx
, param
->peer_addr
);
266 spin_unlock_bh(&ar
->ab
->base_lock
);
269 spin_unlock_bh(&ar
->ab
->base_lock
);
271 ret
= ath11k_wmi_send_peer_create_cmd(ar
, param
);
274 "failed to send peer create vdev_id %d ret %d\n",
275 param
->vdev_id
, ret
);
279 ret
= ath11k_wait_for_peer_created(ar
, param
->vdev_id
,
284 spin_lock_bh(&ar
->ab
->base_lock
);
286 peer
= ath11k_peer_find(ar
->ab
, param
->vdev_id
, param
->peer_addr
);
288 spin_unlock_bh(&ar
->ab
->base_lock
);
289 ath11k_warn(ar
->ab
, "failed to find peer %pM on vdev %i after creation\n",
290 param
->peer_addr
, param
->vdev_id
);
292 reinit_completion(&ar
->peer_delete_done
);
294 ret
= ath11k_wmi_send_peer_delete_cmd(ar
, param
->peer_addr
,
297 ath11k_warn(ar
->ab
, "failed to delete peer vdev_id %d addr %pM\n",
298 param
->vdev_id
, param
->peer_addr
);
302 ret
= ath11k_wait_for_peer_delete_done(ar
, param
->vdev_id
,
310 peer
->pdev_idx
= ar
->pdev_idx
;
312 arvif
->ast_hash
= peer
->ast_hash
;
314 peer
->sec_type
= HAL_ENCRYPT_TYPE_OPEN
;
315 peer
->sec_type_grp
= HAL_ENCRYPT_TYPE_OPEN
;
319 spin_unlock_bh(&ar
->ab
->base_lock
);