mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
wifi: ath12k: Extend beacon miss handling for MLO non-AP STA
Currently, ath12k_mac_handle_beacon_miss() does not handle the beacon miss for the MLO case. In MLO scenarios, the host fails to process the beacon miss because the vdev_id comparison in ath12k_mac_handle_beacon_miss_iter() does not match. This mismatch occurs since arvif always points to ahvif->deflink, which may not correspond to the actual vdev_id associated with the event. Fix this by retrieving arvif from vdev_id instead of ahvif->deflink which will work for both MLO and Non-MLO case. Also refactor the ath12k_mac_handle_beacon_miss(), by passing arvif directly instead of vdev_id and remove ath12k_mac_handle_beacon_miss_iter() which is no longer needed. ath12k_mac_handle_beacon_miss() is called from ath12k_roam_event() for WCN chipsets and ath12k_peer_sta_kickout_event() for QCN chipsets. So, refactor the ath12k_roam_event() to pass arvif instead vdev_id to the ath12k_mac_handle_beacon_miss() function to align with the ath12k_peer_sta_kickout_event() and change the rcu_read_lock() to guard(rcu)() in the same function ath12k_roam_event(). Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1 Co-developed-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com> Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com> Signed-off-by: Maharaja Kennadyrajan <maharaja.kennadyrajan@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20250812111708.3686-4-maharaja.kennadyrajan@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
9891fbd9d8
commit
dcdb05a43d
|
|
@ -1822,22 +1822,16 @@ void ath12k_mac_handle_beacon(struct ath12k *ar, struct sk_buff *skb)
|
|||
skb);
|
||||
}
|
||||
|
||||
static void ath12k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
void ath12k_mac_handle_beacon_miss(struct ath12k *ar,
|
||||
struct ath12k_link_vif *arvif)
|
||||
{
|
||||
u32 *vdev_id = data;
|
||||
struct ath12k_vif *ahvif = ath12k_vif_to_ahvif(vif);
|
||||
struct ath12k_link_vif *arvif = &ahvif->deflink;
|
||||
struct ieee80211_hw *hw;
|
||||
struct ieee80211_hw *hw = ath12k_ar_to_hw(ar);
|
||||
struct ieee80211_vif *vif = ath12k_ahvif_to_vif(arvif->ahvif);
|
||||
|
||||
if (!arvif->is_created || arvif->vdev_id != *vdev_id)
|
||||
return;
|
||||
|
||||
if (!arvif->is_up)
|
||||
if (!(arvif->is_created && arvif->is_up))
|
||||
return;
|
||||
|
||||
ieee80211_beacon_loss(vif);
|
||||
hw = ath12k_ar_to_hw(arvif->ar);
|
||||
|
||||
/* Firmware doesn't report beacon loss events repeatedly. If AP probe
|
||||
* (done by mac80211) succeeds but beacons do not resume then it
|
||||
|
|
@ -1848,14 +1842,6 @@ static void ath12k_mac_handle_beacon_miss_iter(void *data, u8 *mac,
|
|||
ATH12K_CONNECTION_LOSS_HZ);
|
||||
}
|
||||
|
||||
void ath12k_mac_handle_beacon_miss(struct ath12k *ar, u32 vdev_id)
|
||||
{
|
||||
ieee80211_iterate_active_interfaces_atomic(ath12k_ar_to_hw(ar),
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
ath12k_mac_handle_beacon_miss_iter,
|
||||
&vdev_id);
|
||||
}
|
||||
|
||||
static void ath12k_mac_vif_sta_connection_loss_work(struct work_struct *work)
|
||||
{
|
||||
struct ath12k_link_vif *arvif = container_of(work, struct ath12k_link_vif,
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ int ath12k_mac_rfkill_enable_radio(struct ath12k *ar, bool enable);
|
|||
int ath12k_mac_rfkill_config(struct ath12k *ar);
|
||||
int ath12k_mac_wait_tx_complete(struct ath12k *ar);
|
||||
void ath12k_mac_handle_beacon(struct ath12k *ar, struct sk_buff *skb);
|
||||
void ath12k_mac_handle_beacon_miss(struct ath12k *ar, u32 vdev_id);
|
||||
void ath12k_mac_handle_beacon_miss(struct ath12k *ar,
|
||||
struct ath12k_link_vif *arvif);
|
||||
int ath12k_mac_vif_set_keepalive(struct ath12k_link_vif *arvif,
|
||||
enum wmi_sta_keepalive_method method,
|
||||
u32 interval);
|
||||
|
|
|
|||
|
|
@ -7308,6 +7308,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff
|
|||
struct ath12k_link_vif *arvif;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ath12k_peer *peer;
|
||||
unsigned int link_id;
|
||||
struct ath12k *ar;
|
||||
|
||||
if (ath12k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) {
|
||||
|
|
@ -7336,11 +7337,23 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff
|
|||
|
||||
ar = arvif->ar;
|
||||
|
||||
sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar),
|
||||
arg.mac_addr, NULL);
|
||||
if (peer->mlo) {
|
||||
sta = ieee80211_find_sta_by_link_addrs(ath12k_ar_to_hw(ar),
|
||||
arg.mac_addr,
|
||||
NULL, &link_id);
|
||||
if (peer->link_id != link_id) {
|
||||
ath12k_warn(ab,
|
||||
"Spurious quick kickout for MLO STA %pM with invalid link_id, peer: %d, sta: %d\n",
|
||||
arg.mac_addr, peer->link_id, link_id);
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar),
|
||||
arg.mac_addr, NULL);
|
||||
}
|
||||
if (!sta) {
|
||||
ath12k_warn(ab, "Spurious quick kickout for STA %pM\n",
|
||||
arg.mac_addr);
|
||||
ath12k_warn(ab, "Spurious quick kickout for %sSTA %pM\n",
|
||||
peer->mlo ? "MLO " : "", arg.mac_addr);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
|
@ -7351,7 +7364,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff
|
|||
switch (arg.reason) {
|
||||
case WMI_PEER_STA_KICKOUT_REASON_INACTIVITY:
|
||||
if (arvif->ahvif->vif->type == NL80211_IFTYPE_STATION) {
|
||||
ath12k_mac_handle_beacon_miss(ar, peer->vdev_id);
|
||||
ath12k_mac_handle_beacon_miss(ar, arvif);
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
|
|
@ -7366,6 +7379,7 @@ static void ath12k_peer_sta_kickout_event(struct ath12k_base *ab, struct sk_buff
|
|||
|
||||
static void ath12k_roam_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct ath12k_link_vif *arvif;
|
||||
struct wmi_roam_event roam_ev = {};
|
||||
struct ath12k *ar;
|
||||
u32 vdev_id;
|
||||
|
|
@ -7384,21 +7398,22 @@ static void ath12k_roam_event(struct ath12k_base *ab, struct sk_buff *skb)
|
|||
"wmi roam event vdev %u reason %d rssi %d\n",
|
||||
vdev_id, roam_reason, roam_ev.rssi);
|
||||
|
||||
rcu_read_lock();
|
||||
ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id);
|
||||
if (!ar) {
|
||||
guard(rcu)();
|
||||
arvif = ath12k_mac_get_arvif_by_vdev_id(ab, vdev_id);
|
||||
if (!arvif) {
|
||||
ath12k_warn(ab, "invalid vdev id in roam ev %d", vdev_id);
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
ar = arvif->ar;
|
||||
|
||||
if (roam_reason >= WMI_ROAM_REASON_MAX)
|
||||
ath12k_warn(ab, "ignoring unknown roam event reason %d on vdev %i\n",
|
||||
roam_reason, vdev_id);
|
||||
|
||||
switch (roam_reason) {
|
||||
case WMI_ROAM_REASON_BEACON_MISS:
|
||||
ath12k_mac_handle_beacon_miss(ar, vdev_id);
|
||||
ath12k_mac_handle_beacon_miss(ar, arvif);
|
||||
break;
|
||||
case WMI_ROAM_REASON_BETTER_AP:
|
||||
case WMI_ROAM_REASON_LOW_RSSI:
|
||||
|
|
@ -7408,8 +7423,6 @@ static void ath12k_roam_event(struct ath12k_base *ab, struct sk_buff *skb)
|
|||
roam_reason, vdev_id);
|
||||
break;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void ath12k_chan_info_event(struct ath12k_base *ab, struct sk_buff *skb)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user