blob: de63b5e2fa878547680d8597ccb2151e2f50b084 [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 68822b5e5ef48ad096a57a2366b231b7ee9af9c6 Mon Sep 17 00:00:00 2001
2From: Peter Chiu <chui-hao.chiu@mediatek.com>
3Date: Thu, 18 Jul 2024 10:29:22 +0800
4Subject: [PATCH 184/199] mtk: mt76: mt7996: leave ps when 4 address is
5 established
6
7Because the 4 address non-amsdu packet does not have bssid field, the
8hardware cannot get the bssid. Without bssid, the station's are not able
9leave PS mode due to HW design. Wake up non-setup link when receiving
104 address null data to prevent this issue.
11
12Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
13---
14 mt76_connac_mcu.h | 1 +
15 mt7996/main.c | 3 +++
16 mt7996/mcu.c | 18 ++++++++++++++++++
17 mt7996/mcu.h | 6 ++++++
18 mt7996/mt7996.h | 2 ++
19 5 files changed, 30 insertions(+)
20
21diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
22index 01dbe0e5..eb738f4f 100644
23--- a/mt76_connac_mcu.h
24+++ b/mt76_connac_mcu.h
25@@ -838,6 +838,7 @@ enum {
26 STA_REC_EML_OP = 0x29,
27 STA_REC_HDR_TRANS = 0x2B,
28 STA_REC_TX_CAP = 0x2f,
29+ STA_REC_PS_LEAVE = 0x45,
30 STA_REC_MAX_NUM
31 };
32
33diff --git a/mt7996/main.c b/mt7996/main.c
34index 0e5e9a51..8398151d 100644
35--- a/mt7996/main.c
36+++ b/mt7996/main.c
37@@ -2077,6 +2077,9 @@ static void mt7996_sta_set_4addr(struct ieee80211_hw *hw,
38 clear_bit(MT_WCID_FLAG_4ADDR, &mlink->wcid.flags);
39
40 mt7996_mcu_wtbl_update_hdr_trans(dev, vif, mconf, mlink);
41+
42+ if (msta->pri_link != link_id && is_mt7996(&dev->mt76))
43+ mt7996_mcu_ps_leave(dev, mconf, mlink);
44 }
45 mutex_unlock(&dev->mt76.mutex);
46 }
47diff --git a/mt7996/mcu.c b/mt7996/mcu.c
48index ce2168e8..0af0ca82 100644
49--- a/mt7996/mcu.c
50+++ b/mt7996/mcu.c
51@@ -6247,6 +6247,24 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
52 MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
53 }
54
55+int mt7996_mcu_ps_leave(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf,
56+ struct mt7996_link_sta *mlink)
57+{
58+ struct sk_buff *skb;
59+
60+ skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mconf->mt76,
61+ &mlink->wcid,
62+ MT7996_STA_UPDATE_MAX_SIZE);
63+ if (IS_ERR(skb))
64+ return PTR_ERR(skb);
65+
66+ mt76_connac_mcu_add_tlv(skb, STA_REC_PS_LEAVE,
67+ sizeof(struct sta_rec_ps_leave));
68+
69+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
70+ MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
71+}
72+
73 int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
74 u16 rate_idx, bool beacon)
75 {
76diff --git a/mt7996/mcu.h b/mt7996/mcu.h
77index 0f2695eb..ffa574b8 100644
78--- a/mt7996/mcu.h
79+++ b/mt7996/mcu.h
80@@ -775,6 +775,12 @@ struct sta_rec_hdr_trans {
81 u8 mesh;
82 } __packed;
83
84+struct sta_rec_ps_leave {
85+ __le16 tag;
86+ __le16 len;
87+ u8 __rsv[4];
88+} __packed;
89+
90 struct sta_rec_mld_setup {
91 __le16 tag;
92 __le16 len;
93diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
94index 2ee46583..c1823759 100644
95--- a/mt7996/mt7996.h
96+++ b/mt7996/mt7996.h
97@@ -1277,6 +1277,8 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
98 struct ieee80211_vif *vif,
99 struct mt7996_bss_conf *mconf,
100 struct mt7996_link_sta *mlink);
101+int mt7996_mcu_ps_leave(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf,
102+ struct mt7996_link_sta *mlink);
103 int mt7996_mcu_cp_support(struct mt7996_dev *dev, u8 mode);
104 int mt7996_mcu_set_pp_en(struct mt7996_phy *phy, u8 mode, u16 bitmap);
105 int mt7996_mcu_set_pp_sta_dscb(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef,
106--
1072.18.0
108