When max virtual ap interfaces are configured in all the bands with ACS and hostapd restart is done every 60s, a crash is observed at random times. In this certain scenario, a fragmented packet is received for self peer, for which rx_tid and rx_frags are not initialized in datapath. While handling this fragment, crash is observed as the rx_frag list is uninitialised and when we walk in ath11k_dp_rx_h_sort_frags, skb null leads to exception. To address this, before processing received fragments we check dp_setup_done flag is set to ensure that peer has completed its dp peer setup for fragment queue, else ignore processing the fragments. Call trace: ath11k_dp_process_rx_err+0x550/0x1084 [ath11k] ath11k_dp_service_srng+0x70/0x370 [ath11k] 0xffffffc009693a04 __napi_poll+0x30/0xa4 net_rx_action+0x118/0x270 __do_softirq+0x10c/0x244 irq_exit+0x64/0xb4 __handle_domain_irq+0x88/0xac gic_handle_irq+0x74/0xbc el1_irq+0xf0/0x1c0 arch_cpu_idle+0x10/0x18 do_idle+0x104/0x248 cpu_startup_entry+0x20/0x64 rest_init+0xd0/0xdc arch_call_rest_init+0xc/0x14 start_kernel+0x480/0x4b8 Code: f9400281 f94066a2 91405021 b94a0023 (f9406401) Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 Signed-off-by: Harshitha Prem <quic_hprem@quicinc.com> Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com> Link: https://lore.kernel.org/r/20230403184155.8670-2-quic_nmaran@quicinc.com
61 lines
2.0 KiB
C
61 lines
2.0 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause-Clear */
|
|
/*
|
|
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
|
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
|
|
#ifndef ATH11K_PEER_H
|
|
#define ATH11K_PEER_H
|
|
|
|
struct ath11k_peer {
|
|
struct list_head list;
|
|
struct ieee80211_sta *sta;
|
|
int vdev_id;
|
|
u8 addr[ETH_ALEN];
|
|
int peer_id;
|
|
u16 ast_hash;
|
|
u8 pdev_idx;
|
|
u16 hw_peer_id;
|
|
|
|
/* protected by ab->data_lock */
|
|
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
|
|
struct dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
|
|
|
|
/* peer id based rhashtable list pointer */
|
|
struct rhash_head rhash_id;
|
|
/* peer addr based rhashtable list pointer */
|
|
struct rhash_head rhash_addr;
|
|
|
|
/* Info used in MMIC verification of
|
|
* RX fragments
|
|
*/
|
|
struct crypto_shash *tfm_mmic;
|
|
u8 mcast_keyidx;
|
|
u8 ucast_keyidx;
|
|
u16 sec_type;
|
|
u16 sec_type_grp;
|
|
bool is_authorized;
|
|
bool dp_setup_done;
|
|
};
|
|
|
|
void ath11k_peer_unmap_event(struct ath11k_base *ab, u16 peer_id);
|
|
void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id,
|
|
u8 *mac_addr, u16 ast_hash, u16 hw_peer_id);
|
|
struct ath11k_peer *ath11k_peer_find(struct ath11k_base *ab, int vdev_id,
|
|
const u8 *addr);
|
|
struct ath11k_peer *ath11k_peer_find_by_addr(struct ath11k_base *ab,
|
|
const u8 *addr);
|
|
struct ath11k_peer *ath11k_peer_find_by_id(struct ath11k_base *ab, int peer_id);
|
|
void ath11k_peer_cleanup(struct ath11k *ar, u32 vdev_id);
|
|
int ath11k_peer_delete(struct ath11k *ar, u32 vdev_id, u8 *addr);
|
|
int ath11k_peer_create(struct ath11k *ar, struct ath11k_vif *arvif,
|
|
struct ieee80211_sta *sta, struct peer_create_params *param);
|
|
int ath11k_wait_for_peer_delete_done(struct ath11k *ar, u32 vdev_id,
|
|
const u8 *addr);
|
|
struct ath11k_peer *ath11k_peer_find_by_vdev_id(struct ath11k_base *ab,
|
|
int vdev_id);
|
|
int ath11k_peer_rhash_tbl_init(struct ath11k_base *ab);
|
|
void ath11k_peer_rhash_tbl_destroy(struct ath11k_base *ab);
|
|
int ath11k_peer_rhash_delete(struct ath11k_base *ab, struct ath11k_peer *peer);
|
|
#endif /* _PEER_H_ */
|