| From 68822b5e5ef48ad096a57a2366b231b7ee9af9c6 Mon Sep 17 00:00:00 2001 |
| From: Peter Chiu <chui-hao.chiu@mediatek.com> |
| Date: Thu, 18 Jul 2024 10:29:22 +0800 |
| Subject: [PATCH 184/199] mtk: mt76: mt7996: leave ps when 4 address is |
| established |
| |
| Because the 4 address non-amsdu packet does not have bssid field, the |
| hardware cannot get the bssid. Without bssid, the station's are not able |
| leave PS mode due to HW design. Wake up non-setup link when receiving |
| 4 address null data to prevent this issue. |
| |
| Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com> |
| --- |
| mt76_connac_mcu.h | 1 + |
| mt7996/main.c | 3 +++ |
| mt7996/mcu.c | 18 ++++++++++++++++++ |
| mt7996/mcu.h | 6 ++++++ |
| mt7996/mt7996.h | 2 ++ |
| 5 files changed, 30 insertions(+) |
| |
| diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| index 01dbe0e5..eb738f4f 100644 |
| --- a/mt76_connac_mcu.h |
| +++ b/mt76_connac_mcu.h |
| @@ -838,6 +838,7 @@ enum { |
| STA_REC_EML_OP = 0x29, |
| STA_REC_HDR_TRANS = 0x2B, |
| STA_REC_TX_CAP = 0x2f, |
| + STA_REC_PS_LEAVE = 0x45, |
| STA_REC_MAX_NUM |
| }; |
| |
| diff --git a/mt7996/main.c b/mt7996/main.c |
| index 0e5e9a51..8398151d 100644 |
| --- a/mt7996/main.c |
| +++ b/mt7996/main.c |
| @@ -2077,6 +2077,9 @@ static void mt7996_sta_set_4addr(struct ieee80211_hw *hw, |
| clear_bit(MT_WCID_FLAG_4ADDR, &mlink->wcid.flags); |
| |
| mt7996_mcu_wtbl_update_hdr_trans(dev, vif, mconf, mlink); |
| + |
| + if (msta->pri_link != link_id && is_mt7996(&dev->mt76)) |
| + mt7996_mcu_ps_leave(dev, mconf, mlink); |
| } |
| mutex_unlock(&dev->mt76.mutex); |
| } |
| diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| index ce2168e8..0af0ca82 100644 |
| --- a/mt7996/mcu.c |
| +++ b/mt7996/mcu.c |
| @@ -6247,6 +6247,24 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, |
| MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true); |
| } |
| |
| +int mt7996_mcu_ps_leave(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf, |
| + struct mt7996_link_sta *mlink) |
| +{ |
| + struct sk_buff *skb; |
| + |
| + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mconf->mt76, |
| + &mlink->wcid, |
| + MT7996_STA_UPDATE_MAX_SIZE); |
| + if (IS_ERR(skb)) |
| + return PTR_ERR(skb); |
| + |
| + mt76_connac_mcu_add_tlv(skb, STA_REC_PS_LEAVE, |
| + sizeof(struct sta_rec_ps_leave)); |
| + |
| + return mt76_mcu_skb_send_msg(&dev->mt76, skb, |
| + MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true); |
| +} |
| + |
| int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx, |
| u16 rate_idx, bool beacon) |
| { |
| diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| index 0f2695eb..ffa574b8 100644 |
| --- a/mt7996/mcu.h |
| +++ b/mt7996/mcu.h |
| @@ -775,6 +775,12 @@ struct sta_rec_hdr_trans { |
| u8 mesh; |
| } __packed; |
| |
| +struct sta_rec_ps_leave { |
| + __le16 tag; |
| + __le16 len; |
| + u8 __rsv[4]; |
| +} __packed; |
| + |
| struct sta_rec_mld_setup { |
| __le16 tag; |
| __le16 len; |
| diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| index 2ee46583..c1823759 100644 |
| --- a/mt7996/mt7996.h |
| +++ b/mt7996/mt7996.h |
| @@ -1277,6 +1277,8 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, |
| struct ieee80211_vif *vif, |
| struct mt7996_bss_conf *mconf, |
| struct mt7996_link_sta *mlink); |
| +int mt7996_mcu_ps_leave(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf, |
| + struct mt7996_link_sta *mlink); |
| int mt7996_mcu_cp_support(struct mt7996_dev *dev, u8 mode); |
| int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, u8 mode, u16 bitmap); |
| int mt7996_mcu_set_pp_sta_dscb(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef, |
| -- |
| 2.18.0 |
| |