blob: 64030e79dc3fc6d204dc4550d98c081f00f7e049 [file] [log] [blame]
developerd0c89452024-10-11 16:53:27 +08001From 0f060bd8db3e101c30617548032f00adabcd9ffa Mon Sep 17 00:00:00 2001
developer05f3b2b2024-08-19 19:17:34 +08002From: Rex Lu <rex.lu@mediatek.com>
3Date: Fri, 7 Jun 2024 13:51:25 +0800
developerd0c89452024-10-11 16:53:27 +08004Subject: [PATCH 138/223] mtk: mt76: mt7996: Fix inconsistent QoS mapping
developer05f3b2b2024-08-19 19:17:34 +08005 between SW and HW
6
7Fix inconsistent QoS mapping between SW and HW.
8Specifically, the mapping from IP DSCP to IEEE 802.11 user priority may be customized.
9Therefore, driver needs to pass the mapping to HW, so that the QoS type of traffic can be mapped in a consistent manner for both SW and HW paths.
10
11Refactor mt7996_mcu_set_qos_map function.
121. According to fw logic, it will fill the dscp value 0~63 correspond tid.
13for example:
14The last set is 48-56 in the default qos map from hostapd.
15And it will set tid 7. but 57-63 in original function will not fill any value,
16so it will set zero to fw. Once the value of dscp is 57. mac80211 will correspond to tid 7.
17and fw will correspond to tid 0.
18
developerd0c89452024-10-11 16:53:27 +080019Change-Id: Ied5b9caab869985cbbca55b401805af6787afef3
20Change-Id: I6d9066c6afdfc7bb1c4523e9bc8dec40111abd25
developer05f3b2b2024-08-19 19:17:34 +080021Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
22Signed-off-by: Rex Lu <rex.lu@mediatek.com>
23---
24 mt76_connac_mcu.h | 1 +
25 mt7996/main.c | 31 ++++++++++++++++++++++++++
26 mt7996/mcu.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++
27 mt7996/mt7996.h | 8 ++++++-
28 4 files changed, 94 insertions(+), 1 deletion(-)
29
30diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
developerd0c89452024-10-11 16:53:27 +080031index 73cf311a..1971c7bf 100644
developer05f3b2b2024-08-19 19:17:34 +080032--- a/mt76_connac_mcu.h
33+++ b/mt76_connac_mcu.h
developerd0c89452024-10-11 16:53:27 +080034@@ -1267,6 +1267,7 @@ enum {
developer05f3b2b2024-08-19 19:17:34 +080035 MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
36 MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
37 MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
38+ MCU_EXT_CMD_SET_QOS_MAP = 0xb4,
39 };
40
41 enum {
42diff --git a/mt7996/main.c b/mt7996/main.c
developerd0c89452024-10-11 16:53:27 +080043index 9ad4a9d6..c1c62d32 100644
developer05f3b2b2024-08-19 19:17:34 +080044--- a/mt7996/main.c
45+++ b/mt7996/main.c
developerd0c89452024-10-11 16:53:27 +080046@@ -2369,6 +2369,9 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
developer05f3b2b2024-08-19 19:17:34 +080047
48 ctx->dev = NULL;
49
50+ if (path->mtk_wdma.amsdu)
51+ path->mtk_wdma.tid = mvif->qos_map[path->mtk_wdma.tid >> 2];
52+
53 return 0;
54 }
55
developerd0c89452024-10-11 16:53:27 +080056@@ -2798,6 +2801,33 @@ mt7996_event_callback(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
developer05f3b2b2024-08-19 19:17:34 +080057 }
58 }
59
60+static int
61+mt7996_set_qos_map(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
62+ struct cfg80211_qos_map *qos_map)
63+{
64+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
65+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
66+ unsigned long valid_links = vif->valid_links ?: BIT(0);
67+ unsigned int link_id;
68+ int ret = 0;
69+
70+ mutex_lock(&dev->mt76.mutex);
71+ for_each_set_bit(link_id, &valid_links, IEEE80211_MLD_MAX_NUM_LINKS) {
72+ struct mt7996_bss_conf *mconf =
73+ mconf_dereference_protected(mvif, link_id);
74+
75+ if (!mconf)
76+ continue;
77+
78+ ret = mt7996_mcu_set_qos_map(dev, mconf, qos_map);
79+ if(ret)
80+ break;
81+ }
82+ mutex_unlock(&dev->mt76.mutex);
83+
84+ return ret;
85+}
86+
87 const struct ieee80211_ops mt7996_ops = {
88 .add_chanctx = ieee80211_emulate_add_chanctx,
89 .remove_chanctx = ieee80211_emulate_remove_chanctx,
developerd0c89452024-10-11 16:53:27 +080090@@ -2865,4 +2895,5 @@ const struct ieee80211_ops mt7996_ops = {
developer05f3b2b2024-08-19 19:17:34 +080091 .switch_vif_chanctx = mt7996_switch_vif_chanctx,
92 .change_vif_links = mt7996_change_vif_links,
93 .change_sta_links = mt7996_change_sta_links,
94+ .set_qos_map = mt7996_set_qos_map,
95 };
96diff --git a/mt7996/mcu.c b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +080097index 043f8d5c..edbe9cbe 100644
developer05f3b2b2024-08-19 19:17:34 +080098--- a/mt7996/mcu.c
99+++ b/mt7996/mcu.c
developerd0c89452024-10-11 16:53:27 +0800100@@ -6693,4 +6693,59 @@ int mt7996_mcu_set_csi(struct mt7996_phy *phy, u8 mode,
developer05f3b2b2024-08-19 19:17:34 +0800101 return -EINVAL;
102 }
103 }
104+
105+int mt7996_mcu_set_qos_map(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf,
106+ struct cfg80211_qos_map *usr_qos_map)
107+{
108+ struct {
109+ u8 bss_idx;
110+ u8 qos_map_enable;
111+ u8 __rsv[2];
112+ s8 qos_map[IP_DSCP_NUM];
113+ } __packed req = {
114+ .bss_idx = mconf->mt76.idx,
115+ .qos_map_enable = true,
116+ };
117+ s8 i;
118+
119+ /* Default QoS map, defined in section 2.3 of RFC8325.
120+ * Three most significant bits of DSCP are used as UP.
121+ */
122+ for (i = 0; i < IP_DSCP_NUM; ++i)
123+ req.qos_map[i] = i >> 3;
124+
125+ /* Recommended QoS map, defined in section 4 of RFC8325.
126+ * Used in cfg80211_classify8021d since kernel v6.8.
127+ */
128+ req.qos_map[10] = req.qos_map[12] = req.qos_map[14] = req.qos_map[16] = 0;
129+ req.qos_map[18] = req.qos_map[20] = req.qos_map[22] = 3;
130+ req.qos_map[24] = 4;
131+ req.qos_map[40] = 5;
132+ req.qos_map[44] = req.qos_map[46] = 6;
133+ req.qos_map[48] = 7;
134+
135+ /* User-defined QoS map */
136+ if (usr_qos_map) {
137+ for (i = 0; i < IEEE80211_NUM_UPS; ++i) {
138+ u8 low = usr_qos_map->up[i].low;
139+ u8 high = usr_qos_map->up[i].high;
140+
141+ if (low < IP_DSCP_NUM && high < IP_DSCP_NUM && low <= high)
142+ memset(req.qos_map + low, i, high - low + 1);
143+ }
144+
145+ for (i = 0; i < usr_qos_map->num_des; ++i) {
146+ u8 dscp = usr_qos_map->dscp_exception[i].dscp;
147+ u8 up = usr_qos_map->dscp_exception[i].up;
148+
149+ if (dscp < IP_DSCP_NUM && up < IEEE80211_NUM_UPS)
150+ req.qos_map[dscp] = up;
151+ }
152+ }
153+
154+ memcpy(mconf->vif->qos_map, req.qos_map, IP_DSCP_NUM);
155+
156+ return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(SET_QOS_MAP), &req,
157+ sizeof(req), false);
158+}
159 #endif
160diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800161index 3ff9cb68..d97df22f 100644
developer05f3b2b2024-08-19 19:17:34 +0800162--- a/mt7996/mt7996.h
163+++ b/mt7996/mt7996.h
developerd0c89452024-10-11 16:53:27 +0800164@@ -136,6 +136,8 @@
developer05f3b2b2024-08-19 19:17:34 +0800165 #define MT7996_MAX_PROBE_TIMEOUT 500
166 #define MT7996_MAX_PROBE_TRIES 2
167
168+#define IP_DSCP_NUM 64
169+
170 struct mt7996_vif;
171 struct mt7996_sta;
172 struct mt7996_dfs_pulse;
developerd0c89452024-10-11 16:53:27 +0800173@@ -377,6 +379,9 @@ struct mt7996_vif {
developer05f3b2b2024-08-19 19:17:34 +0800174 void *probe[__MT_MAX_BAND];
175 unsigned long probe_send_time[__MT_MAX_BAND];
176 int probe_send_count[__MT_MAX_BAND];
177+
178+ /* QoS map support */
179+ u8 qos_map[IP_DSCP_NUM];
180 };
181
182 /* crash-dump */
developerd0c89452024-10-11 16:53:27 +0800183@@ -1337,5 +1342,6 @@ int mt7996_mcu_mlo_agc(struct mt7996_dev *dev, const void *data, int len);
developer05f3b2b2024-08-19 19:17:34 +0800184 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
185 int mt7996_dma_rro_init(struct mt7996_dev *dev);
186 #endif /* CONFIG_NET_MEDIATEK_SOC_WED */
187-
188+int mt7996_mcu_set_qos_map(struct mt7996_dev *dev, struct mt7996_bss_conf *mconf,
189+ struct cfg80211_qos_map *usr_qos_map);
190 #endif
191--
developerd0c89452024-10-11 16:53:27 +08001922.45.2
developer05f3b2b2024-08-19 19:17:34 +0800193