2020-10-12 02:17:50

by Ryder Lee

[permalink] [raw]
Subject: [PATCH] mt76: mt7915: initialize firmware DRR settings correctly

Driver uses mac80211 airtime fairness instead of hardware solution,
so initialize corresponding MCU settings to adapt it.

Signed-off-by: Ryder Lee <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7915/main.c | 7 +++
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 44 ++++++++++++++-----
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 5 +++
.../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +
4 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 77f7226e655d..650dcad432de 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -47,6 +47,11 @@ static int mt7915_start(struct ieee80211_hw *hw)
mt7915_mcu_set_sku_en(phy, true);
mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);

+ /* use mac80211 airtime fairness instead of hardware solution,
+ * hence set max deficit to 256us to force STAs round-robin.
+ */
+ mt7915_mcu_set_drr(dev, NULL, NULL, DRR_CTRL_AIRTIME_DEFICIT_BOUND);
+
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);

ieee80211_queue_delayed_work(hw, &phy->mac_work,
@@ -201,6 +206,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
vif->offload_flags = 0;
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;

+ ret = mt7915_mcu_set_drr(dev, vif, NULL, DRR_CTRL_STA_BSS_GROUP);
+
out:
mutex_unlock(&dev->mt76.mutex);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 94a3ccf63d0e..614d7af7cd1b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -2217,13 +2217,11 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
MCU_EXT_CMD_STA_REC_UPDATE, true);
}

-static int
-mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+int mt7915_mcu_set_drr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, int cmd)
{
-#define MT_STA_BSS_GROUP 1
- struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
- struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct mt7915_vif *mvif = NULL;
+ struct mt7915_sta *msta = NULL;
struct {
__le32 action;
u8 wlan_idx_lo;
@@ -2233,12 +2231,36 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
__le32 val;
u8 rsv1[8];
} __packed req = {
- .action = cpu_to_le32(MT_STA_BSS_GROUP),
- .wlan_idx_lo = to_wcid_lo(msta->wcid.idx),
- .wlan_idx_hi = to_wcid_hi(msta->wcid.idx),
- .val = cpu_to_le32(mvif->idx % 16),
+ .action = cpu_to_le32(cmd),
};

+ if (vif && vif->type != NL80211_IFTYPE_AP)
+ return 0;
+
+ if (vif) {
+ mvif = (struct mt7915_vif *)vif->drv_priv;
+ msta = &mvif->sta;
+ }
+
+ if (sta)
+ msta = (struct mt7915_sta *)sta->drv_priv;
+
+ if (msta) {
+ req.wlan_idx_lo = to_wcid_lo(msta->wcid.idx);
+ req.wlan_idx_hi = to_wcid_hi(msta->wcid.idx);
+ }
+
+ switch (cmd) {
+ case DRR_CTRL_STA_BSS_GROUP:
+ req.val = cpu_to_le32(mvif->idx % 16);
+ break;
+ case DRR_CTRL_AIRTIME_DEFICIT_BOUND:
+ req.val = cpu_to_le32(1); /* 256us */
+ break;
+ default:
+ return -EINVAL;
+ }
+
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_DRR_CTRL, &req,
sizeof(req), true);
}
@@ -2252,7 +2274,7 @@ int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
return 0;

/* must keep the order */
- ret = mt7915_mcu_add_group(dev, vif, sta);
+ ret = mt7915_mcu_set_drr(dev, vif, sta, DRR_CTRL_STA_BSS_GROUP);
if (ret)
return ret;

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 5f23f27f9f6c..6a0765960d7e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -995,6 +995,11 @@ enum {
THERMAL_SENSOR_TASK_CTRL,
};

+enum {
+ DRR_CTRL_STA_BSS_GROUP = 0x01,
+ DRR_CTRL_AIRTIME_DEFICIT_BOUND = 0x10,
+};
+
enum {
MT_EBF = BIT(0), /* explicit beamforming */
MT_IBF = BIT(1) /* implicit beamforming */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index aee45cce35db..8f58424014b7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -301,6 +301,8 @@ int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd);
int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif);
+int mt7915_mcu_set_drr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, int cmd);
int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
struct ieee80211_sta *sta, u32 rate);
int mt7915_mcu_set_eeprom(struct mt7915_dev *dev);
--
2.18.0