blob: 5f25fc542e8f58d4560629045d28781f2dbef52a [file] [log] [blame]
From 605a40dad37c685a49f2c7985e3a05806d7ac1fc 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 | 59 ++++++++++++++++++++++++++++++++++++++++++++++-
mt7915/mt7915.h | 4 ++++
3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
index 46dcd1c..e0255a2 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 f40a900..71f3ad1 100644
--- a/mt7915/main.c
+++ b/mt7915/main.c
@@ -209,7 +209,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt76_txq *mtxq;
bool ext_phy = phy != &dev->phy;
- int idx, ret = 0;
+ int idx, i, ret = 0;
mutex_lock(&dev->mt76.mutex);
@@ -255,6 +255,12 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;
mt76_wcid_init(&mvif->sta.wcid);
+ /* init Default QoS map, defined in section 2.3 of RFC8325.
+ * Three most significant bits of DSCP are used as UP.
+ */
+ for (i = 0; i < IP_DSCP_NUM; ++i)
+ mvif->qos_map[i] = i >> 3;
+
mt7915_mac_wtbl_update(dev, idx,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
@@ -1619,6 +1625,56 @@ 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 *usr_qos_map)
+{
+ 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 = usr_qos_map ? true : false,
+ };
+
+ /* Prevent access to members of mt7915_vif before its initialization. */
+ if (!mvif->phy)
+ return -EPERM;
+
+ if (usr_qos_map) {
+ struct cfg80211_dscp_exception *exception = usr_qos_map->dscp_exception;
+ struct cfg80211_dscp_range *range = usr_qos_map->up;
+ s8 i;
+
+ /* Default QoS map, defined in section 2.3 of RFC8325.
+ * Three most significant bits of DSCP are used as UP.
+ */
+ for (i = 0; i < IP_DSCP_NUM; ++i)
+ req.qos_map[i] = i >> 3;
+
+ /* User-defined QoS map */
+ 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 < usr_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;
+ }
+ memcpy(mvif->qos_map, req.qos_map, IP_DSCP_NUM);
+ }
+
+ 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)
@@ -1751,6 +1807,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
diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
index 74cd8ca..bfac851 100644
--- a/mt7915/mt7915.h
+++ b/mt7915/mt7915.h
@@ -83,6 +83,8 @@
#define MT7915_CRIT_TEMP 110
#define MT7915_MAX_TEMP 120
+#define IP_DSCP_NUM 64
+
struct mt7915_vif;
struct mt7915_sta;
struct mt7915_dfs_pulse;
@@ -175,6 +177,8 @@ struct mt7915_vif {
struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
struct cfg80211_bitrate_mask bitrate_mask;
+ /* QoS map support */
+ u8 qos_map[IP_DSCP_NUM];
};
/* crash-dump */
--
2.45.2