blob: d4d3d2e8298235d5c7b297c11c9482faf31e65fb [file] [log] [blame]
developerdad89a32024-04-29 14:17:17 +08001From 9c6e5082d5552ac2cefe5b4857da4b29b0c76685 Mon Sep 17 00:00:00 2001
2From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
3Date: Thu, 25 Apr 2024 17:17:13 +0800
4Subject: [PATCH] wifi: mt76: mt7915: fix inconsistent QoS mapping between SW
5 and HW
6
7The mapping from IP DSCP to IEEE 802.11 user priority may be customized.
8Therefore, 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.
9
10Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
11---
12 mt76_connac_mcu.h | 1 +
13 mt7915/main.c | 3 +++
14 mt7915/mcu.c | 37 +++++++++++++++++++++++++++++++++++++
15 mt7915/mt7915.h | 1 +
16 4 files changed, 42 insertions(+)
17
18diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
19index 1dd8244..0936c1c 100644
20--- a/mt76_connac_mcu.h
21+++ b/mt76_connac_mcu.h
22@@ -1236,6 +1236,7 @@ enum {
23 MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
24 MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
25 MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
26+ MCU_EXT_CMD_SET_QOS_MAP = 0xb4,
27 };
28
29 enum {
30diff --git a/mt7915/main.c b/mt7915/main.c
31index 5ed84bc..26f9a5a 100644
32--- a/mt7915/main.c
33+++ b/mt7915/main.c
34@@ -646,6 +646,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
35 }
36 }
37
38+ if (changed & BSS_CHANGED_QOS)
39+ mt7915_mcu_set_qos_map(dev, vif);
40+
41 /* ensure that enable txcmd_mode after bss_info */
42 if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
43 mt7915_mcu_set_tx(dev, vif);
44diff --git a/mt7915/mcu.c b/mt7915/mcu.c
45index 446c512..3d7fc6d 100644
46--- a/mt7915/mcu.c
47+++ b/mt7915/mcu.c
48@@ -4212,3 +4212,40 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
49
50 return 0;
51 }
52+
53+int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif)
54+{
55+#define IP_DSCP_NUM 64
56+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
57+ struct {
58+ u8 bss_idx;
59+ u8 qos_map_enable;
60+ u8 __rsv[2];
61+ s8 qos_map[IP_DSCP_NUM];
62+ } __packed req = {
63+ .bss_idx = mvif->mt76.idx,
64+ .qos_map_enable = false,
65+ };
66+ struct cfg80211_qos_map *qos_map;
67+
68+ rcu_read_lock();
69+ qos_map = ieee80211_get_qos_map(vif);
70+ if (qos_map) {
71+ struct cfg80211_dscp_range *dscp_range = qos_map->up;
72+ s8 up;
73+
74+ req.qos_map_enable = true;
75+ for (up = 0; up < IEEE80211_NUM_UPS; ++up) {
76+ u8 low = dscp_range[up].low, high = dscp_range[up].high;
77+
78+ if (low >= IP_DSCP_NUM || high >= IP_DSCP_NUM || low > high)
79+ continue;
80+
81+ memset(req.qos_map + low, up, high - low + 1);
82+ }
83+ }
84+ rcu_read_unlock();
85+
86+ return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(SET_QOS_MAP), &req,
87+ sizeof(req), true);
88+}
89diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
90index 74cd8ca..66d87d7 100644
91--- a/mt7915/mt7915.h
92+++ b/mt7915/mt7915.h
93@@ -521,6 +521,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
94 void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
95 void mt7915_mcu_exit(struct mt7915_dev *dev);
96 void mt7915_mcu_wmm_pbc_work(struct work_struct *work);
97+int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif);
98
99 static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
100 {
101--
1022.18.0
103