Add a debugfs knob to override the firmware hybrid-MLO link plan for validation. Writing "-----" to /sys/kernel/debug/ieee80211/phyN/mt76/hm_alg_ctrl sends the UNI_CMD_HM ALG_CTRL TLV to the firmware. Signed-off-by: Emery Hsin --- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 + .../wireless/mediatek/mt76/mt7925/debugfs.c | 41 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7925/mcu.c | 30 ++++++++++++++ .../net/wireless/mediatek/mt76/mt7925/mcu.h | 16 ++++++++ 4 files changed, 88 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 5c27285542ab..233da1b0162d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -1364,6 +1364,7 @@ enum { MCU_UNI_CMD_ASSERT_DUMP = 0x6f, MCU_UNI_CMD_EXT_EEPROM_CTRL = 0x74, MCU_UNI_CMD_FACT_CAL = 0x7c, + MCU_UNI_CMD_HM = 0x7d, MCU_UNI_CMD_RADIO_STATUS = 0x80, MCU_UNI_CMD_MLD = 0x82, MCU_UNI_CMD_PEER_MLD = 0x83, diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c index d01ff49de47a..52e9bf437c8e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c @@ -286,6 +286,46 @@ static int mt7925_chip_reset(void *data, u64 val) DEFINE_DEBUGFS_ATTRIBUTE(fops_reset, NULL, mt7925_chip_reset, "%lld\n"); +/* Hybrid-MLO link-plan control. + * + * Usage: + * echo ----- \ + * > /sys/kernel/debug/ieee80211/phyX/mt76/hm_alg_ctrl + */ +static ssize_t +mt7925_hm_alg_ctrl_set(struct file *file, const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct mt792x_dev *dev = file->private_data; + struct mt7925_hm_alg_ctrl ctrl = {}; + char buf[32]; + int ret; + + if (count >= sizeof(buf)) + return -EINVAL; + if (copy_from_user(buf, user_buf, count)) + return -EFAULT; + buf[count] = '\0'; + + if (sscanf(buf, "%hhu-%hhu-%hhu-%hhu-%hhu-%hhu", + &ctrl.manual_mode_en, &ctrl.force_obss, &ctrl.force_bt, + &ctrl.force_plan, &ctrl.obss_time_pct, &ctrl.bt_pct) != 6) + return -EINVAL; + + mt792x_mutex_acquire(dev); + ret = mt7925_mcu_set_hm_alg_ctrl(dev, &ctrl); + mt792x_mutex_release(dev); + + return ret ? ret : count; +} + +static const struct file_operations fops_hm_alg_ctrl = { + .write = mt7925_hm_alg_ctrl_set, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + int mt7925_init_debugfs(struct mt792x_dev *dev) { struct dentry *dir; @@ -312,6 +352,7 @@ int mt7925_init_debugfs(struct mt792x_dev *dev) debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir, mt792x_pm_stats); debugfs_create_file("deep-sleep", 0600, dir, dev, &fops_ds); + debugfs_create_file("hm_alg_ctrl", 0200, dir, dev, &fops_hm_alg_ctrl); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 588328a01dc8..d02ab03fe7ee 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -4606,3 +4606,33 @@ int mt7925_mcu_set_rssimonitor(struct mt792x_dev *dev, struct ieee80211_vif *vif return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(RSSI_MONITOR), &req, sizeof(req), false); } + +int mt7925_mcu_set_hm_alg_ctrl(struct mt792x_dev *dev, + struct mt7925_hm_alg_ctrl *ctrl) +{ + struct { + u8 rsv[4]; /* struct UNI_CMD_HM fixed field */ + __le16 tag; + __le16 len; + u8 manual_mode_en; + u8 force_obss; + u8 force_bt; + u8 force_plan; + u8 obss_time_pct; + u8 bt_pct; + u8 rsv2[6]; + } __packed req = { + .tag = cpu_to_le16(UNI_CMD_HM_TAG_ALG_CTRL), + .len = cpu_to_le16(sizeof(req) - + offsetof(typeof(req), tag)), + .manual_mode_en = ctrl->manual_mode_en, + .force_obss = ctrl->force_obss, + .force_bt = ctrl->force_bt, + .force_plan = ctrl->force_plan, + .obss_time_pct = ctrl->obss_time_pct, + .bt_pct = ctrl->bt_pct, + }; + + return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(HM), &req, + sizeof(req), true); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h index ae403c04e436..1f42a48e522d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h @@ -764,4 +764,20 @@ int mt7925_mcu_update_arp_filter(struct mt76_dev *dev, int mt7925_mcu_uni_bss_bcnft(struct mt792x_dev *dev, struct ieee80211_bss_conf *link_conf, bool enable); +/* Hybrid-MLO algorithm control. Lets the host override the firmware's + * MLO link-plan decision for validation. + */ +#define UNI_CMD_HM_TAG_ALG_CTRL 0 + +struct mt7925_hm_alg_ctrl { + u8 manual_mode_en; + u8 force_obss; + u8 force_bt; + u8 force_plan; + u8 obss_time_pct; + u8 bt_pct; +}; + +int mt7925_mcu_set_hm_alg_ctrl(struct mt792x_dev *dev, + struct mt7925_hm_alg_ctrl *ctrl); #endif -- 2.45.2