[PATCH] wifi: mt76: mt7925: add MT7928 debugfs txpower_sku with power table selection
JB Tsai <[email protected]>
| Newsgroups | org.infradead.lists.linux-mediatek,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
From: Charlie-cy Wu <[email protected]> Add MT7928-specific debugfs interface for txpower_sku that supports multiple power table selection. MT7928 extends the power structure with additional OFDM bandwidth variants (OFDM20/40/80/160) compared to MT7925. Key changes: - Add struct mt7928_txpwr with OFDM20/40/80/160 support - Implement mt7928_txpwr() handler for MT7928-specific power display - Add txpower_tbl debugfs control for selecting power tables: * 0: STA_SISO * 1: STA_CDD * 2: STA_MIMO * 3: P2P_SISO * 4: P2P_CDD * 5: P2P_MIMO - Extend mt7925_txpwr_req with power_tbl field for FW communication - Add mt7928_txpwr_event structure for handling FW responses - Store txpwr_tbl in mt792x_dev for per-device power table tracking Usage: echo 0 > /sys/kernel/debug/ieee80211/phy0/mt76/txpower_tbl cat /sys/kernel/debug/ieee80211/phy0/mt76/txpower_sku Signed-off-by: Charlie-cy Wu <[email protected]> --- .../wireless/mediatek/mt76/mt7925/debugfs.c | 151 +++++++++++++++++- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 27 ++++ .../net/wireless/mediatek/mt76/mt7925/mcu.h | 20 ++- .../wireless/mediatek/mt76/mt7925/mt7925.h | 39 +++++ drivers/net/wireless/mediatek/mt76/mt792x.h | 1 + 5 files changed, 235 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c index e2498659c884..3db564d63c15 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/debugfs.c @@ -178,6 +178,147 @@ mt7925_txpwr(struct seq_file *s, void *data) return ret; } +static inline void +mt7928_eht_txpwr(struct seq_file *s, struct mt7928_txpwr *txpwr, u8 band_idx) +{ + seq_printf(s, "%-22s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7", "mcs8", "mcs9", "mcs10", "mcs11", + "mcs12", "mcs13", "mcs14", "mcs15"); + mt7925_print_txpwr_entry(EHT26, eht26, band_idx); + mt7925_print_txpwr_entry(EHT52, eht52, band_idx); + mt7925_print_txpwr_entry(EHT106, eht106, band_idx); + mt7925_print_txpwr_entry(EHT242, eht242, band_idx); + mt7925_print_txpwr_entry(EHT484, eht484, band_idx); + + mt7925_print_txpwr_entry(EHT996, eht996, band_idx); + mt7925_print_txpwr_entry(EHT996x2, eht996x2, band_idx); + mt7925_print_txpwr_entry(EHT996x4, eht996x4, band_idx); + mt7925_print_txpwr_entry(EHT26_52, eht26_52, band_idx); + mt7925_print_txpwr_entry(EHT26_106, eht26_106, band_idx); + mt7925_print_txpwr_entry(EHT484_242, eht484_242, band_idx); + mt7925_print_txpwr_entry(EHT996_484, eht996_484, band_idx); + mt7925_print_txpwr_entry(EHT996_484_242, eht996_484_242, band_idx); + mt7925_print_txpwr_entry(EHT996x2_484, eht996x2_484, band_idx); + mt7925_print_txpwr_entry(EHT996x3, eht996x3, band_idx); + mt7925_print_txpwr_entry(EHT996x3_484, eht996x3_484, band_idx); +} + +static int +mt7928_txpwr(struct seq_file *s, void *data) +{ + struct mt792x_dev *dev = dev_get_drvdata(s->private); + struct mt7928_txpwr *txpwr = NULL; + u8 band_idx = dev->mphy.band_idx; + int ret = 0; + + txpwr = devm_kmalloc(dev->mt76.dev, sizeof(*txpwr), GFP_KERNEL); + + if (!txpwr) + return -ENOMEM; + + mt792x_mutex_acquire(dev); + ret = mt7928_get_txpwr_info(dev, band_idx, dev->txpwr_tbl, txpwr); + mt792x_mutex_release(dev); + + if (ret) + goto out; + + /* Display power table name based on the index */ + switch (dev->txpwr_tbl) { + case 0: + seq_printf(s, "Power Table: %d (STA_SISO)\n", dev->txpwr_tbl); + break; + case 1: + seq_printf(s, "Power Table: %d (STA_CDD)\n", dev->txpwr_tbl); + break; + case 2: + seq_printf(s, "Power Table: %d (STA_MIMO)\n", dev->txpwr_tbl); + break; + case 3: + seq_printf(s, "Power Table: %d (P2P_SISO)\n", dev->txpwr_tbl); + break; + case 4: + seq_printf(s, "Power Table: %d (P2P_CDD)\n", dev->txpwr_tbl); + break; + case 5: + seq_printf(s, "Power Table: %d (P2P_MIMO)\n", dev->txpwr_tbl); + break; + default: + seq_printf(s, "Power Table: %d (Unknown)\n", dev->txpwr_tbl); + break; + } + + seq_printf(s, "%-22s %6s %6s %6s %6s\n", + " ", "1m", "2m", "5m", "11m"); + mt7925_print_txpwr_entry(CCK, cck, band_idx); + + seq_printf(s, "%-22s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "6m", "9m", "12m", "18m", "24m", "36m", + "48m", "54m"); + mt7925_print_txpwr_entry(OFDM20, ofdm20, band_idx); + mt7925_print_txpwr_entry(OFDM40, ofdm40, band_idx); + mt7925_print_txpwr_entry(OFDM80, ofdm80, band_idx); + mt7925_print_txpwr_entry(OFDM160, ofdm160, band_idx); + + seq_printf(s, "%-22s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7"); + mt7925_print_txpwr_entry(HT20, ht20, band_idx); + + seq_printf(s, "%-22s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7", "mcs32"); + mt7925_print_txpwr_entry(HT40, ht40, band_idx); + + seq_printf(s, "%-22s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s\n", + " ", "mcs0", "mcs1", "mcs2", "mcs3", "mcs4", "mcs5", + "mcs6", "mcs7", "mcs8", "mcs9", "mcs10", "mcs11"); + mt7925_print_txpwr_entry(VHT20, vht20, band_idx); + mt7925_print_txpwr_entry(VHT40, vht40, band_idx); + + mt7925_print_txpwr_entry(VHT80, vht80, band_idx); + mt7925_print_txpwr_entry(VHT160, vht160, band_idx); + + mt7925_print_txpwr_entry(HE26, he26, band_idx); + mt7925_print_txpwr_entry(HE52, he52, band_idx); + mt7925_print_txpwr_entry(HE106, he106, band_idx); + mt7925_print_txpwr_entry(HE242, he242, band_idx); + mt7925_print_txpwr_entry(HE484, he484, band_idx); + + mt7925_print_txpwr_entry(HE996, he996, band_idx); + mt7925_print_txpwr_entry(HE996x2, he996x2, band_idx); + + mt7928_eht_txpwr(s, txpwr, band_idx); + +out: + devm_kfree(dev->mt76.dev, txpwr); + return ret; +} + +static int +mt7928_txpwr_tbl_set(void *data, u64 val) +{ + struct mt792x_dev *dev = data; + + dev->txpwr_tbl = (u8)val; + + return 0; +} + +static int +mt7928_txpwr_tbl_get(void *data, u64 *val) +{ + struct mt792x_dev *dev = data; + + *val = dev->txpwr_tbl; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(fops_txpwr_tbl, mt7928_txpwr_tbl_get, + mt7928_txpwr_tbl_set, "%lld\n"); + static int mt7925_pm_set(void *data, u64 val) { @@ -303,8 +444,14 @@ int mt7925_init_debugfs(struct mt792x_dev *dev) debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir, mt792x_queues_acq); - debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir, - mt7925_txpwr); + if (is_mt7928(&dev->mt76)) { + debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir, + mt7928_txpwr); + debugfs_create_file("txpower_tbl", 0600, dir, dev, &fops_txpwr_tbl); + } else { + debugfs_create_devm_seqfile(dev->mt76.dev, "txpower_sku", dir, + mt7925_txpwr); + } debugfs_create_file("tx_stats", 0400, dir, dev, &mt792x_tx_stats_fops); debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug); debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index 37502d8a0e7d..7162eca8e23e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -2211,6 +2211,33 @@ int mt7925_get_txpwr_info(struct mt792x_dev *dev, u8 band_idx, struct mt7925_txp return 0; } +int mt7928_get_txpwr_info(struct mt792x_dev *dev, u8 band_idx, u8 power_tbl, + struct mt7928_txpwr *txpwr) +{ + struct mt7928_txpwr_event *event; + struct mt7925_txpwr_req req = { + .tag = cpu_to_le16(TX_POWER_SHOW_INFO), + .len = cpu_to_le16(sizeof(req) - 4), + .catg = TXPOWER_ALL_RATE_POWER_INFO, + .band_idx = band_idx, + .power_tbl = power_tbl, + }; + struct sk_buff *skb; + int ret; + + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_UNI_CMD(TXPOWER), + &req, sizeof(req), true, &skb); + if (ret) + return ret; + + event = (struct mt7928_txpwr_event *)skb->data; + memcpy(txpwr, &event->txpwr, sizeof(*txpwr)); + + dev_kfree_skb(skb); + + return 0; +} + int mt7925_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h index 1613c4765186..754db84200d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h @@ -69,7 +69,7 @@ struct mt7925_txpwr_req { u8 format_id; u8 catg; u8 band_idx; - u8 _rsv1; + u8 power_tbl; } __packed; struct mt7925_txpwr_event { @@ -90,6 +90,24 @@ struct mt7925_txpwr_event { u8 rsv1; } __packed; +struct mt7928_txpwr_event { + u8 rsv[4]; + __le16 tag; + __le16 len; + + u8 catg; + u8 band_idx; + u8 ch_band; + u8 format; /* 0:Legacy, 1:HE */ + + /* Rate power info */ + struct mt7928_txpwr txpwr; + + s8 pwr_max; + s8 pwr_min; + u8 rsv1; +} __packed; + enum { TM_SWITCH_MODE, TM_SET_AT_CMD, diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h index e3fef41cbb33..b06f17b2fd8c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h @@ -260,6 +260,43 @@ struct mt7925_txpwr { s8 eht996x3_484[16][2]; }; +struct mt7928_txpwr { + s8 cck[4][2]; + s8 ofdm20[8][2]; + s8 ofdm40[8][2]; + s8 ofdm80[8][2]; + s8 ofdm160[8][2]; + s8 ht20[8][2]; + s8 ht40[9][2]; + s8 vht20[12][2]; + s8 vht40[12][2]; + s8 vht80[12][2]; + s8 vht160[12][2]; + s8 he26[12][2]; + s8 he52[12][2]; + s8 he106[12][2]; + s8 he242[12][2]; + s8 he484[12][2]; + s8 he996[12][2]; + s8 he996x2[12][2]; + s8 eht26[16][2]; + s8 eht52[16][2]; + s8 eht106[16][2]; + s8 eht242[16][2]; + s8 eht484[16][2]; + s8 eht996[16][2]; + s8 eht996x2[16][2]; + s8 eht996x4[16][2]; + s8 eht26_52[16][2]; + s8 eht26_106[16][2]; + s8 eht484_242[16][2]; + s8 eht996_484[16][2]; + s8 eht996_484_242[16][2]; + s8 eht996x2_484[16][2]; + s8 eht996x3[16][2]; + s8 eht996x3_484[16][2]; +}; + static inline u8 mt7927_band_idx(enum nl80211_band band) { switch (band) { @@ -339,6 +376,8 @@ int mt7925_mcu_uni_bss_ps(struct mt792x_dev *dev, void mt7925_coredump_work(struct work_struct *work); int mt7925_get_txpwr_info(struct mt792x_dev *dev, u8 band_idx, struct mt7925_txpwr *txpwr); +int mt7928_get_txpwr_info(struct mt792x_dev *dev, u8 band_idx, u8 power_tbl, + struct mt7928_txpwr *txpwr); void mt7925_mac_set_fixed_rate_table(struct mt792x_dev *dev, u8 tbl_idx, u16 rate_idx); void mt7925_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index 5a1ba1cfc5a3..fbe1793e5598 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -281,6 +281,7 @@ struct mt792x_dev { u8 fw_debug; u8 fw_features; + u8 txpwr_tbl; struct mt76_connac_pm pm; struct mt76_connac_coredump coredump; -- 2.18.0