| From 0a59757ea8e0ea066053cb6b58da3570a4092c09 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, 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. |
| |
| Signed-off-by: Benjamin Lin <benjamin-jw.lin@mediatek.com> |
| --- |
| mt76_connac_mcu.h | 1 + |
| mt7915/main.c | 5 +++++ |
| mt7915/mcu.c | 37 +++++++++++++++++++++++++++++++++++++ |
| mt7915/mt7915.h | 3 +++ |
| 4 files changed, 46 insertions(+) |
| |
| diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| index 1dd8244..0936c1c 100644 |
| --- a/mt76_connac_mcu.h |
| +++ b/mt76_connac_mcu.h |
| @@ -1236,6 +1236,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..c6880ca 100644 |
| --- a/mt7915/main.c |
| +++ b/mt7915/main.c |
| @@ -1697,6 +1697,11 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, |
| |
| ctx->dev = NULL; |
| |
| + if (!mvif->qos_map_enabled) { |
| + mt7915_mcu_set_qos_map(dev, vif); |
| + mvif->qos_map_enabled = true; |
| + } |
| + |
| return 0; |
| } |
| #endif |
| diff --git a/mt7915/mcu.c b/mt7915/mcu.c |
| index 446c512..64d2710 100644 |
| --- a/mt7915/mcu.c |
| +++ b/mt7915/mcu.c |
| @@ -4212,3 +4212,40 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) |
| |
| return 0; |
| } |
| + |
| +int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) |
| +{ |
| +#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 = false, |
| + }; |
| + struct cfg80211_qos_map *qos_map; |
| + |
| + rcu_read_lock(); |
| + qos_map = ieee80211_get_qos_map(vif); |
| + if (qos_map) { |
| + struct cfg80211_dscp_range *dscp_range = qos_map->up; |
| + s8 up; |
| + |
| + req.qos_map_enable = true; |
| + for (up = 0; up < IEEE80211_NUM_UPS; ++up) { |
| + u8 low = dscp_range[up].low, high = dscp_range[up].high; |
| + |
| + if (low >= IP_DSCP_NUM || high >= IP_DSCP_NUM || low > high) |
| + continue; |
| + |
| + memset(req.qos_map + low, up, high - low + 1); |
| + } |
| + } |
| + rcu_read_unlock(); |
| + |
| + return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(SET_QOS_MAP), &req, |
| + sizeof(req), false); |
| +} |
| diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h |
| index 74cd8ca..c813433 100644 |
| --- a/mt7915/mt7915.h |
| +++ b/mt7915/mt7915.h |
| @@ -175,6 +175,8 @@ struct mt7915_vif { |
| |
| struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; |
| struct cfg80211_bitrate_mask bitrate_mask; |
| + |
| + bool qos_map_enabled; |
| }; |
| |
| /* crash-dump */ |
| @@ -521,6 +523,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); |
| void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); |
| void mt7915_mcu_exit(struct mt7915_dev *dev); |
| void mt7915_mcu_wmm_pbc_work(struct work_struct *work); |
| +int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif); |
| |
| static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev) |
| { |
| -- |
| 2.18.0 |
| |