blob: c871c6091323f358341383c110b9a9cfcfa9d3a1 [file] [log] [blame]
From 5fd6278fa4d62c140f40fe2d7ae0bd86074b2d36 Mon Sep 17 00:00:00 2001
From: Benjamin Lin <benjamin-jw.lin@mediatek.com>
Date: Thu, 25 Apr 2024 17:17:13 +0800
Subject: [PATCH] wifi: mt76: mt7915: fix inconsistent QoS mapping between SW
and HW
The mapping from IP DSCP to IEEE 802.11 user priority may be customized.
Therefore, the mapping needs to be passed to HW, so that the QoS type of traffic can be mapped in a consistent manner for both SW and HW paths.
Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com>
---
mt76_connac_mcu.h | 1 +
mt7915/main.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+)
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
index 8899eea..5c25f1a 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
@@ -1238,6 +1238,7 @@ enum {
MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
+ MCU_EXT_CMD_SET_QOS_MAP = 0xb4,
};
enum {
diff --git a/mt7915/main.c b/mt7915/main.c
index 5ed84bc..be11e4f 100644
--- a/mt7915/main.c
+++ b/mt7915/main.c
@@ -1619,6 +1619,49 @@ mt7915_set_frag_threshold(struct ieee80211_hw *hw, u32 val)
return 0;
}
+static int
+mt7915_set_qos_map(struct ieee80211_vif *vif, struct cfg80211_qos_map *qos_map)
+{
+#define IP_DSCP_NUM 64
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct {
+ u8 bss_idx;
+ u8 qos_map_enable;
+ u8 __rsv[2];
+ s8 qos_map[IP_DSCP_NUM];
+ } __packed req = {
+ .bss_idx = mvif->mt76.idx,
+ .qos_map_enable = qos_map ? true : false,
+ };
+
+ /* Prevent access to members of mt7915_vif before its initialization. */
+ if (!mvif->phy)
+ return -EPERM;
+
+ if (qos_map) {
+ struct cfg80211_dscp_exception *exception = qos_map->dscp_exception;
+ struct cfg80211_dscp_range *range = qos_map->up;
+ s8 i;
+
+ for (i = 0; i < IEEE80211_NUM_UPS; ++i) {
+ u8 low = range[i].low, high = range[i].high;
+
+ if (low < IP_DSCP_NUM && high < IP_DSCP_NUM && low <= high)
+ memset(req.qos_map + low, i, high - low + 1);
+ }
+
+ for (i = 0; i < qos_map->num_des; ++i) {
+ u8 dscp = exception[i].dscp, up = exception[i].up;
+
+ if (dscp < IP_DSCP_NUM && up < IEEE80211_NUM_UPS)
+ req.qos_map[dscp] = up;
+ }
+ }
+
+ return mt76_mcu_send_msg(&mvif->phy->dev->mt76, MCU_WA_EXT_CMD(SET_QOS_MAP),
+ &req, sizeof(req), true);
+}
+
static int
mt7915_set_radar_background(struct ieee80211_hw *hw,
struct cfg80211_chan_def *chandef)
@@ -1747,6 +1790,7 @@ const struct ieee80211_ops mt7915_ops = {
.add_twt_setup = mt7915_mac_add_twt_setup,
.twt_teardown_request = mt7915_twt_teardown_request,
.set_frag_threshold = mt7915_set_frag_threshold,
+ .set_qos_map = mt7915_set_qos_map,
CFG80211_TESTMODE_CMD(mt76_testmode_cmd)
CFG80211_TESTMODE_DUMP(mt76_testmode_dump)
#ifdef CONFIG_MAC80211_DEBUGFS
--
2.18.0