From b88f5c6473aa92469a5be7a1fdf521b711ed40ba Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Thu, 28 Jan 2021 03:33:48 +0800 Subject: [PATCH] mt76: mt7921: introduce beacon_loss mcu event If device has enabled beacon hw filter rx beacons are not reported to the host. Introduce beacon_loss mcu event to trigger mac80211 mlme connection state machine in this configuration. IEEE80211_VIF_BEACON_FILTER has not set in vif flags since hw beacon filter is not enabled yet Co-developed-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi Co-developed-by: Soul Huang Signed-off-by: Soul Huang Signed-off-by: Sean Wang Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 35 +++++++++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt7921/mcu.h | 6 +++++ 2 files changed, 41 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 768456c7aa7f..02fde1c63ecf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -544,6 +544,40 @@ mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb) } static void +mt7921_mcu_beacon_loss_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_beacon_loss_event *event = priv; + + if (mvif->mt76.idx != event->bss_idx) + return; + + if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER)) + return; + + ieee80211_beacon_loss(vif); +} + +static void +mt7921_mcu_beacon_loss_event(struct mt7921_dev *dev, struct sk_buff *skb) +{ + struct mt7921_beacon_loss_event *event; + struct mt76_phy *mphy; + u8 band_idx = 0; /* DBDC support */ + + skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + event = (struct mt7921_beacon_loss_event *)skb->data; + if (band_idx && dev->mt76.phy2) + mphy = dev->mt76.phy2; + else + mphy = &dev->mt76.phy; + + ieee80211_iterate_active_interfaces_atomic(mphy->hw, + IEEE80211_IFACE_ITER_RESUME_ALL, + mt7921_mcu_beacon_loss_iter, event); +} + +static void mt7921_mcu_bss_event(struct mt7921_dev *dev, struct sk_buff *skb) { struct mt76_phy *mphy = &dev->mt76.phy; @@ -593,6 +627,7 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) switch (rxd->eid) { case MCU_EVENT_BSS_BEACON_LOSS: + mt7921_mcu_beacon_loss_event(dev, skb); break; case MCU_EVENT_SCHED_SCAN_DONE: case MCU_EVENT_SCAN_DONE: diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h index de3a9aabec04..bf2e643cd870 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h @@ -784,6 +784,12 @@ struct mt7921_bss_qos_tlv { u8 pad[3]; } __packed; +struct mt7921_beacon_loss_event { + u8 bss_idx; + u8 reason; + u8 pad[2]; +} __packed; + struct mt7921_mcu_scan_ssid { __le32 ssid_len; u8 ssid[IEEE80211_MAX_SSID_LEN]; -- 2.11.0