1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
11 static struct ath11k_peer
*ath11k_peer_find_list_by_id(struct ath11k_base
*ab
,
14 struct ath11k_peer
*peer
;
16 lockdep_assert_held(&ab
->base_lock
);
18 list_for_each_entry(peer
, &ab
->peers
, list
) {
19 if (peer
->peer_id
!= peer_id
)
28 struct ath11k_peer
*ath11k_peer_find(struct ath11k_base
*ab
, int vdev_id
,
31 struct ath11k_peer
*peer
;
33 lockdep_assert_held(&ab
->base_lock
);
35 list_for_each_entry(peer
, &ab
->peers
, list
) {
36 if (peer
->vdev_id
!= vdev_id
)
38 if (!ether_addr_equal(peer
->addr
, addr
))
47 struct ath11k_peer
*ath11k_peer_find_by_addr(struct ath11k_base
*ab
,
50 struct ath11k_peer
*peer
;
52 lockdep_assert_held(&ab
->base_lock
);
54 if (!ab
->rhead_peer_addr
)
57 peer
= rhashtable_lookup_fast(ab
->rhead_peer_addr
, addr
,
58 ab
->rhash_peer_addr_param
);
63 struct ath11k_peer
*ath11k_peer_find_by_id(struct ath11k_base
*ab
,
66 struct ath11k_peer
*peer
;
68 lockdep_assert_held(&ab
->base_lock
);
70 if (!ab
->rhead_peer_id
)
73 peer
= rhashtable_lookup_fast(ab
->rhead_peer_id
, &peer_id
,
74 ab
->rhash_peer_id_param
);
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_list_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
, "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
, u16 hw_peer_id
)
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 peer
->hw_peer_id
= hw_peer_id
;
136 ether_addr_copy(peer
->addr
, mac_addr
);
137 list_add(&peer
->list
, &ab
->peers
);
138 wake_up(&ab
->peer_mapping_wq
);
141 ath11k_dbg(ab
, ATH11K_DBG_DP_HTT
, "peer map vdev %d peer %pM id %d\n",
142 vdev_id
, mac_addr
, peer_id
);
145 spin_unlock_bh(&ab
->base_lock
);
148 static int ath11k_wait_for_peer_common(struct ath11k_base
*ab
, int vdev_id
,
149 const u8
*addr
, bool expect_mapped
)
153 ret
= wait_event_timeout(ab
->peer_mapping_wq
, ({
156 spin_lock_bh(&ab
->base_lock
);
157 mapped
= !!ath11k_peer_find(ab
, vdev_id
, addr
);
158 spin_unlock_bh(&ab
->base_lock
);
160 (mapped
== expect_mapped
||
161 test_bit(ATH11K_FLAG_CRASH_FLUSH
, &ab
->dev_flags
));
170 static inline int ath11k_peer_rhash_insert(struct ath11k_base
*ab
,
171 struct rhashtable
*rtbl
,
172 struct rhash_head
*rhead
,
173 struct rhashtable_params
*params
,
176 struct ath11k_peer
*tmp
;
178 lockdep_assert_held(&ab
->tbl_mtx_lock
);
180 tmp
= rhashtable_lookup_get_insert_fast(rtbl
, rhead
, *params
);
184 else if (IS_ERR(tmp
))
190 static inline int ath11k_peer_rhash_remove(struct ath11k_base
*ab
,
191 struct rhashtable
*rtbl
,
192 struct rhash_head
*rhead
,
193 struct rhashtable_params
*params
)
197 lockdep_assert_held(&ab
->tbl_mtx_lock
);
199 ret
= rhashtable_remove_fast(rtbl
, rhead
, *params
);
200 if (ret
&& ret
!= -ENOENT
)
206 static int ath11k_peer_rhash_add(struct ath11k_base
*ab
, struct ath11k_peer
*peer
)
210 lockdep_assert_held(&ab
->base_lock
);
211 lockdep_assert_held(&ab
->tbl_mtx_lock
);
213 if (!ab
->rhead_peer_id
|| !ab
->rhead_peer_addr
)
216 ret
= ath11k_peer_rhash_insert(ab
, ab
->rhead_peer_id
, &peer
->rhash_id
,
217 &ab
->rhash_peer_id_param
, &peer
->peer_id
);
219 ath11k_warn(ab
, "failed to add peer %pM with id %d in rhash_id ret %d\n",
220 peer
->addr
, peer
->peer_id
, ret
);
224 ret
= ath11k_peer_rhash_insert(ab
, ab
->rhead_peer_addr
, &peer
->rhash_addr
,
225 &ab
->rhash_peer_addr_param
, &peer
->addr
);
227 ath11k_warn(ab
, "failed to add peer %pM with id %d in rhash_addr ret %d\n",
228 peer
->addr
, peer
->peer_id
, ret
);
235 ath11k_peer_rhash_remove(ab
, ab
->rhead_peer_id
, &peer
->rhash_id
,
236 &ab
->rhash_peer_id_param
);
240 void ath11k_peer_cleanup(struct ath11k
*ar
, u32 vdev_id
)
242 struct ath11k_peer
*peer
, *tmp
;
243 struct ath11k_base
*ab
= ar
->ab
;
245 lockdep_assert_held(&ar
->conf_mutex
);
247 mutex_lock(&ab
->tbl_mtx_lock
);
248 spin_lock_bh(&ab
->base_lock
);
249 list_for_each_entry_safe(peer
, tmp
, &ab
->peers
, list
) {
250 if (peer
->vdev_id
!= vdev_id
)
253 ath11k_warn(ab
, "removing stale peer %pM from vdev_id %d\n",
254 peer
->addr
, vdev_id
);
256 ath11k_peer_rhash_delete(ab
, peer
);
257 list_del(&peer
->list
);
262 spin_unlock_bh(&ab
->base_lock
);
263 mutex_unlock(&ab
->tbl_mtx_lock
);
266 static int ath11k_wait_for_peer_deleted(struct ath11k
*ar
, int vdev_id
, const u8
*addr
)
268 return ath11k_wait_for_peer_common(ar
->ab
, vdev_id
, addr
, false);
271 int ath11k_wait_for_peer_delete_done(struct ath11k
*ar
, u32 vdev_id
,
275 unsigned long time_left
;
277 ret
= ath11k_wait_for_peer_deleted(ar
, vdev_id
, addr
);
279 ath11k_warn(ar
->ab
, "failed wait for peer deleted");
283 time_left
= wait_for_completion_timeout(&ar
->peer_delete_done
,
285 if (time_left
== 0) {
286 ath11k_warn(ar
->ab
, "Timeout in receiving peer delete response\n");
293 static int __ath11k_peer_delete(struct ath11k
*ar
, u32 vdev_id
, const u8
*addr
)
296 struct ath11k_peer
*peer
;
297 struct ath11k_base
*ab
= ar
->ab
;
299 lockdep_assert_held(&ar
->conf_mutex
);
301 mutex_lock(&ab
->tbl_mtx_lock
);
302 spin_lock_bh(&ab
->base_lock
);
304 peer
= ath11k_peer_find_by_addr(ab
, addr
);
305 /* Check if the found peer is what we want to remove.
306 * While the sta is transitioning to another band we may
307 * have 2 peer with the same addr assigned to different
308 * vdev_id. Make sure we are deleting the correct peer.
310 if (peer
&& peer
->vdev_id
== vdev_id
)
311 ath11k_peer_rhash_delete(ab
, peer
);
313 /* Fallback to peer list search if the correct peer can't be found.
314 * Skip the deletion of the peer from the rhash since it has already
315 * been deleted in peer add.
318 peer
= ath11k_peer_find(ab
, vdev_id
, addr
);
321 spin_unlock_bh(&ab
->base_lock
);
322 mutex_unlock(&ab
->tbl_mtx_lock
);
325 "failed to find peer vdev_id %d addr %pM in delete\n",
330 spin_unlock_bh(&ab
->base_lock
);
331 mutex_unlock(&ab
->tbl_mtx_lock
);
333 reinit_completion(&ar
->peer_delete_done
);
335 ret
= ath11k_wmi_send_peer_delete_cmd(ar
, addr
, vdev_id
);
338 "failed to delete peer vdev_id %d addr %pM ret %d\n",
343 ret
= ath11k_wait_for_peer_delete_done(ar
, vdev_id
, addr
);
350 int ath11k_peer_delete(struct ath11k
*ar
, u32 vdev_id
, u8
*addr
)
354 lockdep_assert_held(&ar
->conf_mutex
);
356 ret
= __ath11k_peer_delete(ar
, vdev_id
, addr
);
365 static int ath11k_wait_for_peer_created(struct ath11k
*ar
, int vdev_id
, const u8
*addr
)
367 return ath11k_wait_for_peer_common(ar
->ab
, vdev_id
, addr
, true);
370 int ath11k_peer_create(struct ath11k
*ar
, struct ath11k_vif
*arvif
,
371 struct ieee80211_sta
*sta
, struct peer_create_params
*param
)
373 struct ath11k_peer
*peer
;
374 struct ath11k_sta
*arsta
;
377 lockdep_assert_held(&ar
->conf_mutex
);
379 if (ar
->num_peers
> (ar
->max_num_peers
- 1)) {
381 "failed to create peer due to insufficient peer entry resource in firmware\n");
385 mutex_lock(&ar
->ab
->tbl_mtx_lock
);
386 spin_lock_bh(&ar
->ab
->base_lock
);
387 peer
= ath11k_peer_find_by_addr(ar
->ab
, param
->peer_addr
);
389 if (peer
->vdev_id
== param
->vdev_id
) {
390 spin_unlock_bh(&ar
->ab
->base_lock
);
391 mutex_unlock(&ar
->ab
->tbl_mtx_lock
);
395 /* Assume sta is transitioning to another band.
396 * Remove here the peer from rhash.
398 ath11k_peer_rhash_delete(ar
->ab
, peer
);
400 spin_unlock_bh(&ar
->ab
->base_lock
);
401 mutex_unlock(&ar
->ab
->tbl_mtx_lock
);
403 ret
= ath11k_wmi_send_peer_create_cmd(ar
, param
);
406 "failed to send peer create vdev_id %d ret %d\n",
407 param
->vdev_id
, ret
);
411 ret
= ath11k_wait_for_peer_created(ar
, param
->vdev_id
,
416 mutex_lock(&ar
->ab
->tbl_mtx_lock
);
417 spin_lock_bh(&ar
->ab
->base_lock
);
419 peer
= ath11k_peer_find(ar
->ab
, param
->vdev_id
, param
->peer_addr
);
421 spin_unlock_bh(&ar
->ab
->base_lock
);
422 mutex_unlock(&ar
->ab
->tbl_mtx_lock
);
423 ath11k_warn(ar
->ab
, "failed to find peer %pM on vdev %i after creation\n",
424 param
->peer_addr
, param
->vdev_id
);
430 ret
= ath11k_peer_rhash_add(ar
->ab
, peer
);
432 spin_unlock_bh(&ar
->ab
->base_lock
);
433 mutex_unlock(&ar
->ab
->tbl_mtx_lock
);
437 peer
->pdev_idx
= ar
->pdev_idx
;
440 if (arvif
->vif
->type
== NL80211_IFTYPE_STATION
) {
441 arvif
->ast_hash
= peer
->ast_hash
;
442 arvif
->ast_idx
= peer
->hw_peer_id
;
445 peer
->sec_type
= HAL_ENCRYPT_TYPE_OPEN
;
446 peer
->sec_type_grp
= HAL_ENCRYPT_TYPE_OPEN
;
449 arsta
= ath11k_sta_to_arsta(sta
);
450 arsta
->tcl_metadata
|= FIELD_PREP(HTT_TCL_META_DATA_TYPE
, 0) |
451 FIELD_PREP(HTT_TCL_META_DATA_PEER_ID
,
454 /* set HTT extension valid bit to 0 by default */
455 arsta
->tcl_metadata
&= ~HTT_TCL_META_DATA_VALID_HTT
;
460 spin_unlock_bh(&ar
->ab
->base_lock
);
461 mutex_unlock(&ar
->ab
->tbl_mtx_lock
);
466 fbret
= __ath11k_peer_delete(ar
, param
->vdev_id
, param
->peer_addr
);
468 ath11k_warn(ar
->ab
, "failed peer %pM delete vdev_id %d fallback ret %d\n",
469 param
->peer_addr
, param
->vdev_id
, fbret
);
474 int ath11k_peer_rhash_delete(struct ath11k_base
*ab
, struct ath11k_peer
*peer
)
478 lockdep_assert_held(&ab
->base_lock
);
479 lockdep_assert_held(&ab
->tbl_mtx_lock
);
481 if (!ab
->rhead_peer_id
|| !ab
->rhead_peer_addr
)
484 ret
= ath11k_peer_rhash_remove(ab
, ab
->rhead_peer_addr
, &peer
->rhash_addr
,
485 &ab
->rhash_peer_addr_param
);
487 ath11k_warn(ab
, "failed to remove peer %pM id %d in rhash_addr ret %d\n",
488 peer
->addr
, peer
->peer_id
, ret
);
492 ret
= ath11k_peer_rhash_remove(ab
, ab
->rhead_peer_id
, &peer
->rhash_id
,
493 &ab
->rhash_peer_id_param
);
495 ath11k_warn(ab
, "failed to remove peer %pM id %d in rhash_id ret %d\n",
496 peer
->addr
, peer
->peer_id
, ret
);
503 static int ath11k_peer_rhash_id_tbl_init(struct ath11k_base
*ab
)
505 struct rhashtable_params
*param
;
506 struct rhashtable
*rhash_id_tbl
;
510 lockdep_assert_held(&ab
->tbl_mtx_lock
);
512 if (ab
->rhead_peer_id
)
515 size
= sizeof(*ab
->rhead_peer_id
);
516 rhash_id_tbl
= kzalloc(size
, GFP_KERNEL
);
518 ath11k_warn(ab
, "failed to init rhash id table due to no mem (size %zu)\n",
523 param
= &ab
->rhash_peer_id_param
;
525 param
->key_offset
= offsetof(struct ath11k_peer
, peer_id
);
526 param
->head_offset
= offsetof(struct ath11k_peer
, rhash_id
);
527 param
->key_len
= sizeof_field(struct ath11k_peer
, peer_id
);
528 param
->automatic_shrinking
= true;
529 param
->nelem_hint
= ab
->num_radios
* TARGET_NUM_PEERS_PDEV(ab
);
531 ret
= rhashtable_init(rhash_id_tbl
, param
);
533 ath11k_warn(ab
, "failed to init peer id rhash table %d\n", ret
);
537 spin_lock_bh(&ab
->base_lock
);
539 if (!ab
->rhead_peer_id
) {
540 ab
->rhead_peer_id
= rhash_id_tbl
;
542 spin_unlock_bh(&ab
->base_lock
);
546 spin_unlock_bh(&ab
->base_lock
);
551 rhashtable_destroy(rhash_id_tbl
);
558 static int ath11k_peer_rhash_addr_tbl_init(struct ath11k_base
*ab
)
560 struct rhashtable_params
*param
;
561 struct rhashtable
*rhash_addr_tbl
;
565 lockdep_assert_held(&ab
->tbl_mtx_lock
);
567 if (ab
->rhead_peer_addr
)
570 size
= sizeof(*ab
->rhead_peer_addr
);
571 rhash_addr_tbl
= kzalloc(size
, GFP_KERNEL
);
572 if (!rhash_addr_tbl
) {
573 ath11k_warn(ab
, "failed to init rhash addr table due to no mem (size %zu)\n",
578 param
= &ab
->rhash_peer_addr_param
;
580 param
->key_offset
= offsetof(struct ath11k_peer
, addr
);
581 param
->head_offset
= offsetof(struct ath11k_peer
, rhash_addr
);
582 param
->key_len
= sizeof_field(struct ath11k_peer
, addr
);
583 param
->automatic_shrinking
= true;
584 param
->nelem_hint
= ab
->num_radios
* TARGET_NUM_PEERS_PDEV(ab
);
586 ret
= rhashtable_init(rhash_addr_tbl
, param
);
588 ath11k_warn(ab
, "failed to init peer addr rhash table %d\n", ret
);
592 spin_lock_bh(&ab
->base_lock
);
594 if (!ab
->rhead_peer_addr
) {
595 ab
->rhead_peer_addr
= rhash_addr_tbl
;
597 spin_unlock_bh(&ab
->base_lock
);
601 spin_unlock_bh(&ab
->base_lock
);
606 rhashtable_destroy(rhash_addr_tbl
);
608 kfree(rhash_addr_tbl
);
613 static inline void ath11k_peer_rhash_id_tbl_destroy(struct ath11k_base
*ab
)
615 lockdep_assert_held(&ab
->tbl_mtx_lock
);
617 if (!ab
->rhead_peer_id
)
620 rhashtable_destroy(ab
->rhead_peer_id
);
621 kfree(ab
->rhead_peer_id
);
622 ab
->rhead_peer_id
= NULL
;
625 static inline void ath11k_peer_rhash_addr_tbl_destroy(struct ath11k_base
*ab
)
627 lockdep_assert_held(&ab
->tbl_mtx_lock
);
629 if (!ab
->rhead_peer_addr
)
632 rhashtable_destroy(ab
->rhead_peer_addr
);
633 kfree(ab
->rhead_peer_addr
);
634 ab
->rhead_peer_addr
= NULL
;
637 int ath11k_peer_rhash_tbl_init(struct ath11k_base
*ab
)
641 mutex_lock(&ab
->tbl_mtx_lock
);
643 ret
= ath11k_peer_rhash_id_tbl_init(ab
);
647 ret
= ath11k_peer_rhash_addr_tbl_init(ab
);
651 mutex_unlock(&ab
->tbl_mtx_lock
);
656 ath11k_peer_rhash_id_tbl_destroy(ab
);
658 mutex_unlock(&ab
->tbl_mtx_lock
);
662 void ath11k_peer_rhash_tbl_destroy(struct ath11k_base
*ab
)
664 mutex_lock(&ab
->tbl_mtx_lock
);
666 ath11k_peer_rhash_addr_tbl_destroy(ab
);
667 ath11k_peer_rhash_id_tbl_destroy(ab
);
669 mutex_unlock(&ab
->tbl_mtx_lock
);