| From 6e6fb69bc4f57d622fae76d8d5a3102b8e98e10f 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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++ |
| 2 files changed, 52 insertions(+) |
| |
| 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..f82d0b1 100644 |
| --- a/mt7915/main.c |
| +++ b/mt7915/main.c |
| @@ -1619,6 +1619,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) |
| +{ |
| +#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 = 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; |
| + } |
| + } |
| + |
| + 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 +1801,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.45.2 |
| |