From 18425d7d74c5be88b13b970a21e52e2498abf4ba Mon Sep 17 00:00:00 2001 From: Wang Yufen Date: Fri, 25 Nov 2022 17:06:07 +0800 Subject: [PATCH 01/27] wifi: mt76: mt7915: add missing of_node_put() Add missing of_node_put() after of_reserved_mem_lookup() Fixes: 99ad32a4ca3a ("mt76: mt7915: add support for MT7986") Signed-off-by: Wang Yufen Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/soc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c index c06c56a0270d..686c9bbd5929 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/soc.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/soc.c @@ -278,6 +278,7 @@ static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev) return -EINVAL; rmem = of_reserved_mem_lookup(np); + of_node_put(np); if (!rmem) return -EINVAL; From aec4cf2ea0797e28f18f8dbe01943a56d987fe56 Mon Sep 17 00:00:00 2001 From: Deren Wu Date: Thu, 1 Dec 2022 23:53:37 +0800 Subject: [PATCH 02/27] wifi: mt76: mt7921s: fix slab-out-of-bounds access in sdio host SDIO may need addtional 511 bytes to align bus operation. If the tailroom of this skb is not big enough, we would access invalid memory region. For low level operation, increase skb size to keep valid memory access in SDIO host. Error message: [69.951] BUG: KASAN: slab-out-of-bounds in sg_copy_buffer+0xe9/0x1a0 [69.951] Read of size 64 at addr ffff88811c9cf000 by task kworker/u16:7/451 [69.951] CPU: 4 PID: 451 Comm: kworker/u16:7 Tainted: G W OE 6.1.0-rc5 #1 [69.951] Workqueue: kvub300c vub300_cmndwork_thread [vub300] [69.951] Call Trace: [69.951] [69.952] dump_stack_lvl+0x49/0x63 [69.952] print_report+0x171/0x4a8 [69.952] kasan_report+0xb4/0x130 [69.952] kasan_check_range+0x149/0x1e0 [69.952] memcpy+0x24/0x70 [69.952] sg_copy_buffer+0xe9/0x1a0 [69.952] sg_copy_to_buffer+0x12/0x20 [69.952] __command_write_data.isra.0+0x23c/0xbf0 [vub300] [69.952] vub300_cmndwork_thread+0x17f3/0x58b0 [vub300] [69.952] process_one_work+0x7ee/0x1320 [69.952] worker_thread+0x53c/0x1240 [69.952] kthread+0x2b8/0x370 [69.952] ret_from_fork+0x1f/0x30 [69.952] [69.952] Allocated by task 854: [69.952] kasan_save_stack+0x26/0x50 [69.952] kasan_set_track+0x25/0x30 [69.952] kasan_save_alloc_info+0x1b/0x30 [69.952] __kasan_kmalloc+0x87/0xa0 [69.952] __kmalloc_node_track_caller+0x63/0x150 [69.952] kmalloc_reserve+0x31/0xd0 [69.952] __alloc_skb+0xfc/0x2b0 [69.952] __mt76_mcu_msg_alloc+0xbf/0x230 [mt76] [69.952] mt76_mcu_send_and_get_msg+0xab/0x110 [mt76] [69.952] __mt76_mcu_send_firmware.cold+0x94/0x15d [mt76] [69.952] mt76_connac_mcu_send_ram_firmware+0x415/0x54d [mt76_connac_lib] [69.952] mt76_connac2_load_ram.cold+0x118/0x4bc [mt76_connac_lib] [69.952] mt7921_run_firmware.cold+0x2e9/0x405 [mt7921_common] [69.952] mt7921s_mcu_init+0x45/0x80 [mt7921s] [69.953] mt7921_init_work+0xe1/0x2a0 [mt7921_common] [69.953] process_one_work+0x7ee/0x1320 [69.953] worker_thread+0x53c/0x1240 [69.953] kthread+0x2b8/0x370 [69.953] ret_from_fork+0x1f/0x30 [69.953] The buggy address belongs to the object at ffff88811c9ce800 which belongs to the cache kmalloc-2k of size 2048 [69.953] The buggy address is located 0 bytes to the right of 2048-byte region [ffff88811c9ce800, ffff88811c9cf000) [69.953] Memory state around the buggy address: [69.953] ffff88811c9cef00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [69.953] ffff88811c9cef80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [69.953] >ffff88811c9cf000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [69.953] ^ [69.953] ffff88811c9cf080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [69.953] ffff88811c9cf100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc Fixes: 764dee47e2c1 ("mt76: sdio: move common code in mt76_sdio module") Suggested-by: Lorenzo Bianconi Tested-by: YN Chen Signed-off-by: Deren Wu Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/sdio_txrx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c index bfc4de50a4d2..ddd8c0cc744d 100644 --- a/drivers/net/wireless/mediatek/mt76/sdio_txrx.c +++ b/drivers/net/wireless/mediatek/mt76/sdio_txrx.c @@ -254,6 +254,10 @@ static int mt76s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q) if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->phy.state)) { __skb_put_zero(e->skb, 4); + err = __skb_grow(e->skb, roundup(e->skb->len, + sdio->func->cur_blksize)); + if (err) + return err; err = __mt76s_xmit_queue(dev, e->skb->data, e->skb->len); if (err) From 8b25301af01566f4b5a301fc1ad7c5d2b1788d7f Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sat, 3 Dec 2022 11:22:22 +0800 Subject: [PATCH 03/27] wifi: mt76: mt7915: fix mt7915_rate_txpower_get() resource leaks Coverity message: variable "buf" going out of scope leaks the storage. Reported-by: coverity-bot Addresses-Coverity-ID: 1527799 ("Resource leaks") Fixes: e3296759f347 ("wifi: mt76: mt7915: enable per bandwidth power limit support") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index fb46c2c1784f..a7fdcd1f3d98 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -996,7 +996,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf, ret = mt7915_mcu_get_txpower_sku(phy, txpwr, sizeof(txpwr)); if (ret) - return ret; + goto out; /* Txpower propagation path: TMAC -> TXV -> BBP */ len += scnprintf(buf + len, sz - len, @@ -1047,6 +1047,8 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf, mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER)); ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); + +out: kfree(buf); return ret; } From 5202b983f9894d31110e49c4ec6b57955b5eaa1a Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sat, 3 Dec 2022 11:22:23 +0800 Subject: [PATCH 04/27] wifi: mt76: mt7996: fix insecure data handling of mt7996_mcu_ie_countdown() Coverity message: using tainted "hdr->band" variable as an index into an array "(*dev).mt76.phys". Reported-by: coverity-bot Addresses-Coverity-ID: 1527797 ("Insecure data handling") Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 04e1d10bbd21..a90b7ca2df63 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -412,6 +412,9 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb) struct header *hdr = (struct header *)data; struct tlv *tlv = (struct tlv *)(data + 4); + if (hdr->band >= ARRAY_SIZE(dev->mt76.phys)) + return; + if (hdr->band && dev->mt76.phys[hdr->band]) mphy = dev->mt76.phys[hdr->band]; From f37c6e5c75029443bc72c45acf92b2f2de2945be Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sat, 3 Dec 2022 11:22:24 +0800 Subject: [PATCH 05/27] wifi: mt76: mt7996: fix insecure data handling of mt7996_mcu_rx_radar_detected() Coverity message: using tainted "r->band_idx" variable as an index into an array "(*dev).mt76.phys". Reported-by: coverity-bot Addresses-Coverity-ID: 1527812 ("Insecure data handling") Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index a90b7ca2df63..efb245c8ac84 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -335,6 +335,9 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb) r = (struct mt7996_mcu_rdd_report *)skb->data; + if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys)) + return; + mphy = dev->mt76.phys[r->band_idx]; if (!mphy) return; From aab169ad3a7aa8678aed90d7fdbc243e3d4b32a6 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sat, 3 Dec 2022 11:22:25 +0800 Subject: [PATCH 06/27] wifi: mt76: mt7996: fix integer handling issue of mt7996_rf_regval_set() This code is supposed to set a u32 value, but casting will not work on big endian systems. Reported-by: coverity-bot Addresses-Coverity-ID: 1527816 ("Integer handling issues") Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c index 2e4a8909b9e8..99b23aef53a5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c @@ -653,8 +653,9 @@ static int mt7996_rf_regval_set(void *data, u64 val) { struct mt7996_dev *dev = data; + u32 val32 = val; - return mt7996_mcu_rf_regval(dev, dev->mt76.debugfs_reg, (u32 *)&val, true); + return mt7996_mcu_rf_regval(dev, dev->mt76.debugfs_reg, &val32, true); } DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7996_rf_regval_get, From 3fc36de8212bda168eb859cf83a7f44babdcf806 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sat, 3 Dec 2022 15:37:54 +0800 Subject: [PATCH 07/27] wifi: mt76: mt7915: split mcu chan_mib array up The current flow confuses coverity check that leads to false reporting, so split the offs[] into two pieces according to chipset revision to silence coverity tool. Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index b2652de082ba..ca315af3905b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2974,38 +2974,42 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy) int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch) { - /* strict order */ - static const u32 offs[] = { - MIB_NON_WIFI_TIME, - MIB_TX_TIME, - MIB_RX_TIME, - MIB_OBSS_AIRTIME, - MIB_TXOP_INIT_COUNT, - /* v2 */ - MIB_NON_WIFI_TIME_V2, - MIB_TX_TIME_V2, - MIB_RX_TIME_V2, - MIB_OBSS_AIRTIME_V2 - }; struct mt76_channel_state *state = phy->mt76->chan_state; struct mt76_channel_state *state_ts = &phy->state_ts; struct mt7915_dev *dev = phy->dev; struct mt7915_mcu_mib *res, req[5]; struct sk_buff *skb; - int i, ret, start = 0, ofs = 20; + static const u32 *offs; + int i, ret, len, offs_cc; u64 cc_tx; - if (!is_mt7915(&dev->mt76)) { - start = 5; - ofs = 0; + /* strict order */ + if (is_mt7915(&dev->mt76)) { + static const u32 chip_offs[] = { + MIB_NON_WIFI_TIME, + MIB_TX_TIME, + MIB_RX_TIME, + MIB_OBSS_AIRTIME, + MIB_TXOP_INIT_COUNT, + }; + len = ARRAY_SIZE(chip_offs); + offs = chip_offs; + offs_cc = 20; + } else { + static const u32 chip_offs[] = { + MIB_NON_WIFI_TIME_V2, + MIB_TX_TIME_V2, + MIB_RX_TIME_V2, + MIB_OBSS_AIRTIME_V2 + }; + len = ARRAY_SIZE(chip_offs); + offs = chip_offs; + offs_cc = 0; } - for (i = 0; i < 5; i++) { + for (i = 0; i < len; i++) { req[i].band = cpu_to_le32(phy->mt76->band_idx); - req[i].offs = cpu_to_le32(offs[i + start]); - - if (!is_mt7915(&dev->mt76) && i == 3) - break; + req[i].offs = cpu_to_le32(offs[i]); } ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO), @@ -3013,7 +3017,7 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch) if (ret) return ret; - res = (struct mt7915_mcu_mib *)(skb->data + ofs); + res = (struct mt7915_mcu_mib *)(skb->data + offs_cc); #define __res_u64(s) le64_to_cpu(res[s].data) /* subtract Tx backoff time from Tx duration */ From 59b27a7d472f100ac8998e15a63c47a03cced12a Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sun, 4 Dec 2022 05:33:17 +0800 Subject: [PATCH 08/27] wifi: mt76: mt7915: check return value before accessing free_block_num Check return value of mt7915_mcu_get_eeprom_free_block() first before accessing free_block_num. Fixes: bbc1d4154ec1 ("mt76: mt7915: add default calibrated data support") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7915/eeprom.c | 19 ++++++++++++------- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 10 ++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c index 59069fb86414..24efa280dd86 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c @@ -110,18 +110,23 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev) } else { u8 free_block_num; u32 block_num, i; + u32 eeprom_blk_size = MT7915_EEPROM_BLOCK_SIZE; - mt7915_mcu_get_eeprom_free_block(dev, &free_block_num); - /* efuse info not enough */ + ret = mt7915_mcu_get_eeprom_free_block(dev, &free_block_num); + if (ret < 0) + return ret; + + /* efuse info isn't enough */ if (free_block_num >= 29) return -EINVAL; /* read eeprom data from efuse */ - block_num = DIV_ROUND_UP(eeprom_size, - MT7915_EEPROM_BLOCK_SIZE); - for (i = 0; i < block_num; i++) - mt7915_mcu_get_eeprom(dev, - i * MT7915_EEPROM_BLOCK_SIZE); + block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size); + for (i = 0; i < block_num; i++) { + ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size); + if (ret < 0) + return ret; + } } return mt7915_check_eeprom(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index ca315af3905b..86ec767266cc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2792,8 +2792,9 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset) int ret; u8 *buf; - ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS), &req, - sizeof(req), true, &skb); + ret = mt76_mcu_send_and_get_msg(&dev->mt76, + MCU_EXT_QUERY(EFUSE_ACCESS), + &req, sizeof(req), true, &skb); if (ret) return ret; @@ -2818,8 +2819,9 @@ int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num) struct sk_buff *skb; int ret; - ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_FREE_BLOCK), &req, - sizeof(req), true, &skb); + ret = mt76_mcu_send_and_get_msg(&dev->mt76, + MCU_EXT_QUERY(EFUSE_FREE_BLOCK), + &req, sizeof(req), true, &skb); if (ret) return ret; From 783ef7da7a53c7ab98471f47fbabab6cf6f45c8f Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sun, 4 Dec 2022 05:33:18 +0800 Subject: [PATCH 09/27] wifi: mt76: mt7996: check return value before accessing free_block_num Check return value of mt7996_mcu_get_eeprom_free_block() first before accessing free_block_num. Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7996/eeprom.c | 18 ++++++++++++------ .../net/wireless/mediatek/mt76/mt7996/mcu.c | 5 +++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c index b9f62bedbc48..5d8e0353627e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/eeprom.c @@ -65,17 +65,23 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev) } else { u8 free_block_num; u32 block_num, i; + u32 eeprom_blk_size = MT7996_EEPROM_BLOCK_SIZE; - /* TODO: check free block event */ - mt7996_mcu_get_eeprom_free_block(dev, &free_block_num); - /* efuse info not enough */ + ret = mt7996_mcu_get_eeprom_free_block(dev, &free_block_num); + if (ret < 0) + return ret; + + /* efuse info isn't enough */ if (free_block_num >= 59) return -EINVAL; /* read eeprom data from efuse */ - block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, MT7996_EEPROM_BLOCK_SIZE); - for (i = 0; i < block_num; i++) - mt7996_mcu_get_eeprom(dev, i * MT7996_EEPROM_BLOCK_SIZE); + block_num = DIV_ROUND_UP(MT7996_EEPROM_SIZE, eeprom_blk_size); + for (i = 0; i < block_num; i++) { + ret = mt7996_mcu_get_eeprom(dev, i * eeprom_blk_size); + if (ret < 0) + return ret; + } } return mt7996_check_eeprom(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index efb245c8ac84..da72684e4308 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -2927,8 +2927,9 @@ int mt7996_mcu_get_eeprom(struct mt7996_dev *dev, u32 offset) bool valid; int ret; - ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL), &req, - sizeof(req), true, &skb); + ret = mt76_mcu_send_and_get_msg(&dev->mt76, + MCU_WM_UNI_CMD_QUERY(EFUSE_CTRL), + &req, sizeof(req), true, &skb); if (ret) return ret; From 7a53eecd5c877c445e10c32a4b4d671cd36c6558 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sun, 4 Dec 2022 05:33:19 +0800 Subject: [PATCH 10/27] wifi: mt76: mt7915: check the correctness of event data The mcu event might not be reliable, so check the correctness of data before handling it. Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7915/mcu.c | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index 86ec767266cc..37a3c1f082d9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -232,8 +232,11 @@ mt7915_mcu_rx_csa_notify(struct mt7915_dev *dev, struct sk_buff *skb) c = (struct mt7915_mcu_csa_notify *)skb->data; + if (c->band_idx > MT_BAND1) + return; + if ((c->band_idx && !dev->phy.mt76->band_idx) && - dev->mt76.phys[MT_BAND1]) + dev->mt76.phys[MT_BAND1]) mphy = dev->mt76.phys[MT_BAND1]; ieee80211_iterate_active_interfaces_atomic(mphy->hw, @@ -252,8 +255,11 @@ mt7915_mcu_rx_thermal_notify(struct mt7915_dev *dev, struct sk_buff *skb) if (t->ctrl.ctrl_id != THERMAL_PROTECT_ENABLE) return; + if (t->ctrl.band_idx > MT_BAND1) + return; + if ((t->ctrl.band_idx && !dev->phy.mt76->band_idx) && - dev->mt76.phys[MT_BAND1]) + dev->mt76.phys[MT_BAND1]) mphy = dev->mt76.phys[MT_BAND1]; phy = (struct mt7915_phy *)mphy->priv; @@ -268,8 +274,11 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb) r = (struct mt7915_mcu_rdd_report *)skb->data; + if (r->band_idx > MT_BAND1) + return; + if ((r->band_idx && !dev->phy.mt76->band_idx) && - dev->mt76.phys[MT_BAND1]) + dev->mt76.phys[MT_BAND1]) mphy = dev->mt76.phys[MT_BAND1]; if (r->band_idx == MT_RX_SEL2) @@ -326,7 +335,11 @@ mt7915_mcu_rx_bcc_notify(struct mt7915_dev *dev, struct sk_buff *skb) b = (struct mt7915_mcu_bcc_notify *)skb->data; - if ((b->band_idx && !dev->phy.mt76->band_idx) && dev->mt76.phys[MT_BAND1]) + if (b->band_idx > MT_BAND1) + return; + + if ((b->band_idx && !dev->phy.mt76->band_idx) && + dev->mt76.phys[MT_BAND1]) mphy = dev->mt76.phys[MT_BAND1]; ieee80211_iterate_active_interfaces_atomic(mphy->hw, From b0f7b9563358493dfe70d3e4c3ebeffc92d4b494 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sun, 4 Dec 2022 15:18:14 +0800 Subject: [PATCH 11/27] wifi: mt76: mt7915: drop always true condition of __mt7915_reg_addr() smatch warnings: addr <= MT_CBTOP2_PHY_END(0xffffffff) is always true (<= u32max), so drop it. Fixes: cd4c314a65d3 ("mt76: mt7915: refine register definition") Reported-by: kernel test robot Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/regs.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 0a95c3da241b..52be55dff947 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -495,7 +495,7 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) if (dev_is_pci(dev->mt76.dev) && ((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) || - (addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END))) + addr >= MT_CBTOP2_PHY_START)) return mt7915_reg_map_l1(dev, addr); /* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index aca1b2f1e9e3..7e0d86366c77 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -803,7 +803,6 @@ enum offs_rev { #define MT_CBTOP1_PHY_START 0x70000000 #define MT_CBTOP1_PHY_END __REG(CBTOP1_PHY_END) #define MT_CBTOP2_PHY_START 0xf0000000 -#define MT_CBTOP2_PHY_END 0xffffffff #define MT_INFRA_MCU_START 0x7c000000 #define MT_INFRA_MCU_END __REG(INFRA_MCU_ADDR_END) #define MT_CONN_INFRA_OFFSET(p) ((p) - MT_INFRA_BASE) From ef1ea24cb0ecfd42c1ff266d92613163792aec77 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Sun, 4 Dec 2022 15:18:15 +0800 Subject: [PATCH 12/27] wifi: mt76: mt7996: drop always true condition of __mt7996_reg_addr() addr <= MT_CBTOP2_PHY_END(0xffffffff) is always true (<= u32max), so drop it. Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/mmio.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7996/regs.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c index 521769eb6b0e..60781d046216 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c @@ -149,7 +149,7 @@ static u32 __mt7996_reg_addr(struct mt7996_dev *dev, u32 addr) if (dev_is_pci(dev->mt76.dev) && ((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) || - (addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END))) + addr >= MT_CBTOP2_PHY_START)) return mt7996_reg_map_l1(dev, addr); /* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */ diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h index 794f61b93a46..42980b97b4d4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/regs.h @@ -463,7 +463,6 @@ enum base_rev { #define MT_CBTOP1_PHY_START 0x70000000 #define MT_CBTOP1_PHY_END 0x77ffffff #define MT_CBTOP2_PHY_START 0xf0000000 -#define MT_CBTOP2_PHY_END 0xffffffff #define MT_INFRA_MCU_START 0x7c000000 #define MT_INFRA_MCU_END 0x7c3fffff From 54ccb836ffb28eacba51b674cbe94cb5613f8441 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 4 Dec 2022 23:01:37 +0100 Subject: [PATCH 13/27] wifi: mt76: mt7996: fix endianness warning in mt7996_mcu_sta_he_tlv Fix the following sparse warnings in mt7996_mcu_sta_he_tlv routine: warning: incorrect type in assignment (different base types) expected unsigned char got restricted __le16 [usertype] warning: incorrect type in assignment (different base types) expected unsigned char got restricted __le16 [usertype] Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index da72684e4308..a88fc7680b1a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -909,8 +909,8 @@ mt7996_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) he = (struct sta_rec_he_v2 *)tlv; for (i = 0; i < 11; i++) { if (i < 6) - he->he_mac_cap[i] = cpu_to_le16(elem->mac_cap_info[i]); - he->he_phy_cap[i] = cpu_to_le16(elem->phy_cap_info[i]); + he->he_mac_cap[i] = elem->mac_cap_info[i]; + he->he_phy_cap[i] = elem->phy_cap_info[i]; } mcs_map = sta->deflink.he_cap.he_mcs_nss_supp; From 6e1abc51c945663bddebfa1beb9590ff5b250eb7 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 5 Dec 2022 17:59:04 +0100 Subject: [PATCH 14/27] wifi: mt76: mt76x0: fix oob access in mt76x0_phy_get_target_power After 'commit ba45841ca5eb ("wifi: mt76: mt76x02: simplify struct mt76x02_rate_power")', mt76x02 relies on ht[0-7] rate_power data for vht mcs{0,7}, while it uses vth[0-1] rate_power for vht mcs {8,9}. Fix a possible out-of-bound access in mt76x0_phy_get_target_power routine. Fixes: ba45841ca5eb ("wifi: mt76: mt76x02: simplify struct mt76x02_rate_power") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index 6c6c8ada7943..d543ef3de65b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -642,7 +642,12 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode, if (tx_rate > 9) return -EINVAL; - *target_power = cur_power + dev->rate_power.vht[tx_rate]; + *target_power = cur_power; + if (tx_rate > 7) + *target_power += dev->rate_power.vht[tx_rate - 8]; + else + *target_power += dev->rate_power.ht[tx_rate]; + *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate); break; default: From 7176fe656f1b5cf5aa6d5d306d0710c4e5d7a6b5 Mon Sep 17 00:00:00 2001 From: Quan Zhou Date: Wed, 7 Dec 2022 13:03:41 +0800 Subject: [PATCH 15/27] wifi: mt76: mt7921: add support to update fw capability with MTFG table In ACPI enabled devices, mt7921 should read MTFG table from platform hardware. Apply necessary settings for firmware capabilities through CLC command. Co-developed-by: Deren Wu Signed-off-by: Deren Wu Signed-off-by: Quan Zhou Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7921/acpi_sar.c | 55 +++++++++++++++++++ .../wireless/mediatek/mt76/mt7921/acpi_sar.h | 12 ++++ .../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +- .../wireless/mediatek/mt76/mt7921/mt7921.h | 7 +++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c index 47e034a9b003..a98d0fb42d0a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c @@ -135,6 +135,22 @@ mt7921_asar_acpi_read_mtgs(struct mt7921_dev *dev, u8 **table, u8 version) return ret; } +/* MTFG : Flag Table */ +static int +mt7921_asar_acpi_read_mtfg(struct mt7921_dev *dev, u8 **table) +{ + int len, ret; + + ret = mt7921_acpi_read(dev, MT7921_ACPI_MTFG, table, &len); + if (ret) + return ret; + + if (len < MT7921_ASAR_MIN_FG) + ret = -EINVAL; + + return ret; +} + int mt7921_init_acpi_sar(struct mt7921_dev *dev) { struct mt7921_acpi_sar *asar; @@ -162,6 +178,12 @@ int mt7921_init_acpi_sar(struct mt7921_dev *dev) asar->geo = NULL; } + /* MTFG is optional */ + ret = mt7921_asar_acpi_read_mtfg(dev, (u8 **)&asar->fg); + if (ret) { + devm_kfree(dev->mt76.dev, asar->fg); + asar->fg = NULL; + } dev->phy.acpisar = asar; return 0; @@ -280,3 +302,36 @@ int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) return 0; } + +u8 mt7921_acpi_get_flags(struct mt7921_phy *phy) +{ + struct mt7921_asar_fg *fg; + struct { + u8 acpi_idx; + u8 chip_idx; + } map[] = { + {1, 1}, + {4, 2}, + }; + u8 flags = BIT(0); + int i, j; + + if (!phy->acpisar) + return 0; + + fg = phy->acpisar->fg; + if (!fg) + return flags; + + /* pickup necessary settings per device and + * translate the index of bitmap for chip command. + */ + for (i = 0; i < fg->nr_flag; i++) + for (j = 0; j < ARRAY_SIZE(map); j++) + if (fg->flag[i] == map[j].acpi_idx) { + flags |= BIT(map[j].chip_idx); + break; + } + + return flags; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h index 23f86bfae0c0..35268b0890ad 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h @@ -8,10 +8,12 @@ #define MT7921_ASAR_MAX_DYN 8 #define MT7921_ASAR_MIN_GEO 3 #define MT7921_ASAR_MAX_GEO 8 +#define MT7921_ASAR_MIN_FG 8 #define MT7921_ACPI_MTCL "MTCL" #define MT7921_ACPI_MTDS "MTDS" #define MT7921_ACPI_MTGS "MTGS" +#define MT7921_ACPI_MTFG "MTFG" struct mt7921_asar_dyn_limit { u8 idx; @@ -77,6 +79,15 @@ struct mt7921_asar_cl { u8 cl6g[6]; } __packed; +struct mt7921_asar_fg { + u8 names[4]; + u8 version; + u8 rsvd; + u8 nr_flag; + u8 rsvd1; + u8 flag[0]; +} __packed; + struct mt7921_acpi_sar { u8 ver; union { @@ -88,6 +99,7 @@ struct mt7921_acpi_sar { struct mt7921_asar_geo_v2 *geo_v2; }; struct mt7921_asar_cl *countrylist; + struct mt7921_asar_fg *fg; }; #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index fb9c0f66cb27..8930b5a4467c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1184,13 +1184,15 @@ int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2, __le16 len; u8 idx; u8 env; - u8 pad1[2]; + u8 acpi_conf; + u8 pad1; u8 alpha2[2]; u8 type[2]; u8 rsvd[64]; } __packed req = { .idx = idx, .env = env_cap, + .acpi_conf = mt7921_acpi_get_flags(&dev->phy), }; int ret, valid_cnt = 0; u8 i, *pos; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 15d6b7fe1c6c..efff4d43d796 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -554,6 +554,7 @@ int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, #ifdef CONFIG_ACPI int mt7921_init_acpi_sar(struct mt7921_dev *dev); int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default); +u8 mt7921_acpi_get_flags(struct mt7921_phy *phy); #else static inline int mt7921_init_acpi_sar(struct mt7921_dev *dev) @@ -566,6 +567,12 @@ mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) { return 0; } + +static inline u8 +mt7921_acpi_get_flags(struct mt7921_phy *phy) +{ + return 0; +} #endif int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar); From 063cca0252b46970e7e9ca423d5e930be3179aa1 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Wed, 7 Dec 2022 15:30:04 +0800 Subject: [PATCH 16/27] wifi: mt76: mt7996: fix unintended sign extension of mt7996_hw_queue_read() In the expression "map[i].qid << 24" starts as u8, but is promoted to "signed int", then sign-extended to type "unsigned long", which is not intended. Cast to u32 to avoid the sign extension. Reported-by: coverity-bot Addresses-Coverity-ID: 1527813 ("Integer handling issues") Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c index 99b23aef53a5..3d4fbbbcc206 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c @@ -457,7 +457,7 @@ mt7996_hw_queue_read(struct seq_file *s, u32 size, if (val & BIT(map[i].index)) continue; - ctrl = BIT(31) | (map[i].pid << 10) | (map[i].qid << 24); + ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24); mt76_wr(dev, MT_FL_Q0_CTRL, ctrl); head = mt76_get_field(dev, MT_FL_Q2_CTRL, From edb0406bda4629ef496f52eb11cbea7e92ed301b Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Wed, 7 Dec 2022 15:30:05 +0800 Subject: [PATCH 17/27] wifi: mt76: mt7915: fix unintended sign extension of mt7915_hw_queue_read() In the expression "map[i].qid << 24" starts as u8, but is promoted to "signed int", then sign-extended to type "unsigned long", which is not intended. Cast to u32 to avoid the sign extension. Fixes: 776ec4e77aa6 ("mt76: mt7915: rework debugfs queue info") Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index a7fdcd1f3d98..5a46813a59ea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -811,7 +811,7 @@ mt7915_hw_queue_read(struct seq_file *s, u32 size, if (val & BIT(map[i].index)) continue; - ctrl = BIT(31) | (map[i].pid << 10) | (map[i].qid << 24); + ctrl = BIT(31) | (map[i].pid << 10) | ((u32)map[i].qid << 24); mt76_wr(dev, MT_FL_Q0_CTRL, ctrl); head = mt76_get_field(dev, MT_FL_Q2_CTRL, From 0ffcb2a68b15bd63d5555a923ae7dfe8bfdb14a7 Mon Sep 17 00:00:00 2001 From: Deren Wu Date: Thu, 8 Dec 2022 00:03:10 +0800 Subject: [PATCH 18/27] wifi: mt76: fix coverity uninit_use_in_call in mt76_connac2_reverse_frag0_hdr_trans() The default case for frame_contorl is invalid. We should always assign addr3 of this frame properly. Coverity error message: if (ieee80211_has_a4(hdr.frame_control)) (19) Event uninit_use_in_call: Using uninitialized value "hdr". Field "hdr.addr3" is uninitialized when calling "memcpy". memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr)); else memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6); Fixes: 0880d40871d1 ("mt76: connac: move mt76_connac2_reverse_frag0_hdr_trans in mt76-connac module") Signed-off-by: Deren Wu Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c index fd60123fb284..c8d0c84e688b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -930,7 +930,7 @@ int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif, ether_addr_copy(hdr.addr4, eth_hdr->h_source); break; default: - break; + return -EINVAL; } skb_pull(skb, hdr_offset + sizeof(struct ethhdr) - 2); From a00b791026920c3dd2ddcf4fb730ccf6db961627 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 7 Dec 2022 17:19:42 +0100 Subject: [PATCH 19/27] wifi: mt76: move leds field in leds struct This is a preliminary patch to support per-phy leds. Tested-by: Frank Wunderlich Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/debugfs.c | 2 +- drivers/net/wireless/mediatek/mt76/mac80211.c | 18 ++++++++--------- drivers/net/wireless/mediatek/mt76/mt76.h | 12 ++++++----- .../net/wireless/mediatek/mt76/mt7603/init.c | 20 +++++++++---------- .../wireless/mediatek/mt76/mt7615/pci_init.c | 18 ++++++++--------- .../net/wireless/mediatek/mt76/mt76x02_util.c | 20 +++++++++---------- .../net/wireless/mediatek/mt76/mt7915/init.c | 10 +++++----- .../net/wireless/mediatek/mt76/mt7996/init.c | 10 +++++----- 8 files changed, 56 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index 11b0b3d62f29..5579b67d686c 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -112,7 +112,7 @@ mt76_register_debugfs_fops(struct mt76_phy *phy, if (!dir) return NULL; - debugfs_create_u8("led_pin", 0600, dir, &dev->led_pin); + debugfs_create_u8("led_pin", 0600, dir, &dev->leds.pin); debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg); debugfs_create_file_unsafe("regval", 0600, dir, dev, fops); debugfs_create_file_unsafe("napi_threaded", 0600, dir, dev, diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index fc608b369b3c..96ce7811b630 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -198,14 +198,14 @@ static int mt76_led_init(struct mt76_dev *dev) struct ieee80211_hw *hw = dev->hw; int led_pin; - if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set) + if (!dev->leds.cdev.brightness_set && !dev->leds.cdev.blink_set) return 0; - snprintf(dev->led_name, sizeof(dev->led_name), + snprintf(dev->leds.name, sizeof(dev->leds.name), "mt76-%s", wiphy_name(hw->wiphy)); - dev->led_cdev.name = dev->led_name; - dev->led_cdev.default_trigger = + dev->leds.cdev.name = dev->leds.name; + dev->leds.cdev.default_trigger = ieee80211_create_tpt_led_trigger(hw, IEEE80211_TPT_LEDTRIG_FL_RADIO, mt76_tpt_blink, @@ -214,20 +214,20 @@ static int mt76_led_init(struct mt76_dev *dev) np = of_get_child_by_name(np, "led"); if (np) { if (!of_property_read_u32(np, "led-sources", &led_pin)) - dev->led_pin = led_pin; - dev->led_al = of_property_read_bool(np, "led-active-low"); + dev->leds.pin = led_pin; + dev->leds.al = of_property_read_bool(np, "led-active-low"); of_node_put(np); } - return led_classdev_register(dev->dev, &dev->led_cdev); + return led_classdev_register(dev->dev, &dev->leds.cdev); } static void mt76_led_cleanup(struct mt76_dev *dev) { - if (!dev->led_cdev.brightness_set && !dev->led_cdev.blink_set) + if (!dev->leds.cdev.brightness_set && !dev->leds.cdev.blink_set) return; - led_classdev_unregister(&dev->led_cdev); + led_classdev_unregister(&dev->leds.cdev); } static void mt76_init_stream_cap(struct mt76_phy *phy, diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 32a77a0ae9da..8c34b1f8acc0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -812,11 +812,6 @@ struct mt76_dev { u32 debugfs_reg; - struct led_classdev led_cdev; - char led_name[32]; - bool led_al; - u8 led_pin; - u8 csa_complete; u32 rxfilter; @@ -835,6 +830,13 @@ struct mt76_dev { struct mt76_usb usb; struct mt76_sdio sdio; }; + + struct { + struct led_classdev cdev; + char name[32]; + bool al; + u8 pin; + } leds; }; struct mt76_power_limits { diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c index 031d39a48a55..a44c7b3a6e02 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c @@ -341,15 +341,15 @@ static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on, FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | FIELD_PREP(MT_LED_STATUS_ON, delay_on); - addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin)); + addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mt76->leds.pin)); mt76_wr(dev, addr, val); - addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin)); + addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mt76->leds.pin)); mt76_wr(dev, addr, val); - val = MT_LED_CTRL_REPLAY(mt76->led_pin) | - MT_LED_CTRL_KICK(mt76->led_pin); - if (mt76->led_al) - val |= MT_LED_CTRL_POLARITY(mt76->led_pin); + val = MT_LED_CTRL_REPLAY(mt76->leds.pin) | + MT_LED_CTRL_KICK(mt76->leds.pin); + if (mt76->leds.al) + val |= MT_LED_CTRL_POLARITY(mt76->leds.pin); addr = mt7603_reg_map(dev, MT_LED_CTRL); mt76_wr(dev, addr, val); } @@ -359,7 +359,7 @@ static int mt7603_led_set_blink(struct led_classdev *led_cdev, unsigned long *delay_off) { struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev, - led_cdev); + leds.cdev); u8 delta_on, delta_off; delta_off = max_t(u8, *delay_off / 10, 1); @@ -373,7 +373,7 @@ static void mt7603_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev, - led_cdev); + leds.cdev); if (!brightness) mt7603_led_set_config(mt76, 0, 0xff); @@ -535,8 +535,8 @@ int mt7603_register_device(struct mt7603_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.led_cdev.brightness_set = mt7603_led_set_brightness; - dev->mt76.led_cdev.blink_set = mt7603_led_set_blink; + dev->mt76.leds.cdev.brightness_set = mt7603_led_set_brightness; + dev->mt76.leds.cdev.blink_set = mt7603_led_set_blink; } wiphy->reg_notifier = mt7603_regd_notifier; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c index 87b4aa52ee0f..944bae068dab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c @@ -74,7 +74,7 @@ mt7615_led_set_config(struct led_classdev *led_cdev, struct mt76_dev *mt76; u32 val, addr; - mt76 = container_of(led_cdev, struct mt76_dev, led_cdev); + mt76 = container_of(led_cdev, struct mt76_dev, leds.cdev); dev = container_of(mt76, struct mt7615_dev, mt76); if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) @@ -84,15 +84,15 @@ mt7615_led_set_config(struct led_classdev *led_cdev, FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | FIELD_PREP(MT_LED_STATUS_ON, delay_on); - addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin)); + addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mt76->leds.pin)); mt76_wr(dev, addr, val); - addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin)); + addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mt76->leds.pin)); mt76_wr(dev, addr, val); - val = MT_LED_CTRL_REPLAY(mt76->led_pin) | - MT_LED_CTRL_KICK(mt76->led_pin); - if (mt76->led_al) - val |= MT_LED_CTRL_POLARITY(mt76->led_pin); + val = MT_LED_CTRL_REPLAY(mt76->leds.pin) | + MT_LED_CTRL_KICK(mt76->leds.pin); + if (mt76->leds.al) + val |= MT_LED_CTRL_POLARITY(mt76->leds.pin); addr = mt7615_reg_map(dev, MT_LED_CTRL); mt76_wr(dev, addr, val); @@ -133,8 +133,8 @@ int mt7615_register_device(struct mt7615_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.led_cdev.brightness_set = mt7615_led_set_brightness; - dev->mt76.led_cdev.blink_set = mt7615_led_set_blink; + dev->mt76.leds.cdev.brightness_set = mt7615_led_set_brightness; + dev->mt76.leds.cdev.blink_set = mt7615_led_set_blink; } ret = mt7622_wmac_init(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 604ddcc21123..56abc1bdb9fb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -98,13 +98,13 @@ mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on, FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | FIELD_PREP(MT_LED_STATUS_ON, delay_on); - mt76_wr(dev, MT_LED_S0(mdev->led_pin), val); - mt76_wr(dev, MT_LED_S1(mdev->led_pin), val); + mt76_wr(dev, MT_LED_S0(mdev->leds.pin), val); + mt76_wr(dev, MT_LED_S1(mdev->leds.pin), val); - val = MT_LED_CTRL_REPLAY(mdev->led_pin) | - MT_LED_CTRL_KICK(mdev->led_pin); - if (mdev->led_al) - val |= MT_LED_CTRL_POLARITY(mdev->led_pin); + val = MT_LED_CTRL_REPLAY(mdev->leds.pin) | + MT_LED_CTRL_KICK(mdev->leds.pin); + if (mdev->leds.al) + val |= MT_LED_CTRL_POLARITY(mdev->leds.pin); mt76_wr(dev, MT_LED_CTRL, val); } @@ -114,7 +114,7 @@ mt76x02_led_set_blink(struct led_classdev *led_cdev, unsigned long *delay_off) { struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev, - led_cdev); + leds.cdev); u8 delta_on, delta_off; delta_off = max_t(u8, *delay_off / 10, 1); @@ -130,7 +130,7 @@ mt76x02_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev, - led_cdev); + leds.cdev); if (!brightness) mt76x02_led_set_config(mdev, 0, 0xff); @@ -167,9 +167,9 @@ int mt76x02_init_device(struct mt76x02_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.led_cdev.brightness_set = + dev->mt76.leds.cdev.brightness_set = mt76x02_led_set_brightness; - dev->mt76.led_cdev.blink_set = mt76x02_led_set_blink; + dev->mt76.leds.cdev.blink_set = mt76x02_led_set_blink; } } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index c810c31fbd6e..bae6c2701323 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -212,7 +212,7 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev, struct mt76_dev *mt76; u32 val; - mt76 = container_of(led_cdev, struct mt76_dev, led_cdev); + mt76 = container_of(led_cdev, struct mt76_dev, leds.cdev); dev = container_of(mt76, struct mt7915_dev, mt76); /* select TX blink mode, 2: only data frames */ @@ -228,7 +228,7 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev, /* control LED */ val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK; - if (dev->mt76.led_al) + if (dev->mt76.leds.al) val |= MT_LED_CTRL_POLARITY; mt76_wr(dev, MT_LED_CTRL(0), val); @@ -498,7 +498,7 @@ void mt7915_mac_init(struct mt7915_dev *dev) mt7915_mac_init_band(dev, i); if (IS_ENABLED(CONFIG_MT76_LEDS)) { - i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; + i = dev->mt76.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4); } } @@ -1141,8 +1141,8 @@ int mt7915_register_device(struct mt7915_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.led_cdev.brightness_set = mt7915_led_set_brightness; - dev->mt76.led_cdev.blink_set = mt7915_led_set_blink; + dev->mt76.leds.cdev.brightness_set = mt7915_led_set_brightness; + dev->mt76.leds.cdev.blink_set = mt7915_led_set_blink; } ret = mt76_register_device(&dev->mt76, true, mt76_rates, diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 46b290526092..2923606d5f5e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -49,7 +49,7 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev, struct mt76_dev *mt76; u32 val; - mt76 = container_of(led_cdev, struct mt76_dev, led_cdev); + mt76 = container_of(led_cdev, struct mt76_dev, leds.cdev); dev = container_of(mt76, struct mt7996_dev, mt76); /* select TX blink mode, 2: only data frames */ @@ -65,7 +65,7 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev, /* control LED */ val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK; - if (dev->mt76.led_al) + if (dev->mt76.leds.al) val |= MT_LED_CTRL_POLARITY; mt76_wr(dev, MT_LED_CTRL(0), val); @@ -261,7 +261,7 @@ static void mt7996_mac_init(struct mt7996_dev *dev) MT_WTBL_UPDATE_ADM_COUNT_CLEAR); if (IS_ENABLED(CONFIG_MT76_LEDS)) { - i = dev->mt76.led_pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; + i = dev->mt76.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4); } @@ -787,8 +787,8 @@ int mt7996_register_device(struct mt7996_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.led_cdev.brightness_set = mt7996_led_set_brightness; - dev->mt76.led_cdev.blink_set = mt7996_led_set_blink; + dev->mt76.leds.cdev.brightness_set = mt7996_led_set_brightness; + dev->mt76.leds.cdev.blink_set = mt7996_led_set_blink; } ret = mt76_register_device(&dev->mt76, true, mt76_rates, From 3abd46ddf80a4f1bbe22372b9b808f12dfe2602b Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 7 Dec 2022 17:19:43 +0100 Subject: [PATCH 20/27] wifi: mt76: move leds struct in mt76_phy Move leds struct in mt76_phy in order to have leds associated to phy (e.g. in dbdc mode) instead of per device. Tested-by: Frank Wunderlich Co-developed-by: Ryder Lee Signed-off-by: Ryder Lee Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/debugfs.c | 2 +- drivers/net/wireless/mediatek/mt76/mac80211.c | 48 +++++++++++-------- drivers/net/wireless/mediatek/mt76/mt76.h | 14 +++--- .../net/wireless/mediatek/mt76/mt7603/init.c | 30 ++++++------ .../wireless/mediatek/mt76/mt7615/pci_init.c | 26 +++++----- .../net/wireless/mediatek/mt76/mt76x02_util.c | 31 ++++++------ .../net/wireless/mediatek/mt76/mt7915/init.c | 14 +++--- .../net/wireless/mediatek/mt76/mt7996/init.c | 14 +++--- 8 files changed, 92 insertions(+), 87 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index 5579b67d686c..57fbcc83e074 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -112,7 +112,7 @@ mt76_register_debugfs_fops(struct mt76_phy *phy, if (!dir) return NULL; - debugfs_create_u8("led_pin", 0600, dir, &dev->leds.pin); + debugfs_create_u8("led_pin", 0600, dir, &phy->leds.pin); debugfs_create_u32("regidx", 0600, dir, &dev->debugfs_reg); debugfs_create_file_unsafe("regval", 0600, dir, dev, fops); debugfs_create_file_unsafe("napi_threaded", 0600, dir, dev, diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 96ce7811b630..ad7274de5694 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -192,42 +192,48 @@ static const struct cfg80211_sar_capa mt76_sar_capa = { .freq_ranges = &mt76_sar_freq_ranges[0], }; -static int mt76_led_init(struct mt76_dev *dev) +static int mt76_led_init(struct mt76_phy *phy) { - struct device_node *np = dev->dev->of_node; - struct ieee80211_hw *hw = dev->hw; - int led_pin; + struct mt76_dev *dev = phy->dev; + struct ieee80211_hw *hw = phy->hw; - if (!dev->leds.cdev.brightness_set && !dev->leds.cdev.blink_set) + if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set) return 0; - snprintf(dev->leds.name, sizeof(dev->leds.name), - "mt76-%s", wiphy_name(hw->wiphy)); + snprintf(phy->leds.name, sizeof(phy->leds.name), "mt76-%s", + wiphy_name(hw->wiphy)); - dev->leds.cdev.name = dev->leds.name; - dev->leds.cdev.default_trigger = + phy->leds.cdev.name = phy->leds.name; + phy->leds.cdev.default_trigger = ieee80211_create_tpt_led_trigger(hw, IEEE80211_TPT_LEDTRIG_FL_RADIO, mt76_tpt_blink, ARRAY_SIZE(mt76_tpt_blink)); - np = of_get_child_by_name(np, "led"); - if (np) { - if (!of_property_read_u32(np, "led-sources", &led_pin)) - dev->leds.pin = led_pin; - dev->leds.al = of_property_read_bool(np, "led-active-low"); - of_node_put(np); + if (phy == &dev->phy) { + struct device_node *np = dev->dev->of_node; + + np = of_get_child_by_name(np, "led"); + if (np) { + int led_pin; + + if (!of_property_read_u32(np, "led-sources", &led_pin)) + phy->leds.pin = led_pin; + phy->leds.al = of_property_read_bool(np, + "led-active-low"); + of_node_put(np); + } } - return led_classdev_register(dev->dev, &dev->leds.cdev); + return led_classdev_register(dev->dev, &phy->leds.cdev); } -static void mt76_led_cleanup(struct mt76_dev *dev) +static void mt76_led_cleanup(struct mt76_phy *phy) { - if (!dev->leds.cdev.brightness_set && !dev->leds.cdev.blink_set) + if (!phy->leds.cdev.brightness_set && !phy->leds.cdev.blink_set) return; - led_classdev_unregister(&dev->leds.cdev); + led_classdev_unregister(&phy->leds.cdev); } static void mt76_init_stream_cap(struct mt76_phy *phy, @@ -653,7 +659,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, mt76_check_sband(&dev->phy, &phy->sband_6g, NL80211_BAND_6GHZ); if (IS_ENABLED(CONFIG_MT76_LEDS)) { - ret = mt76_led_init(dev); + ret = mt76_led_init(phy); if (ret) return ret; } @@ -674,7 +680,7 @@ void mt76_unregister_device(struct mt76_dev *dev) struct ieee80211_hw *hw = dev->hw; if (IS_ENABLED(CONFIG_MT76_LEDS)) - mt76_led_cleanup(dev); + mt76_led_cleanup(&dev->phy); mt76_tx_status_check(dev, true); ieee80211_unregister_hw(hw); } diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 8c34b1f8acc0..1037d23bc4d0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -731,6 +731,13 @@ struct mt76_phy { } rx_amsdu[__MT_RXQ_MAX]; struct mt76_freq_range_power *frp; + + struct { + struct led_classdev cdev; + char name[32]; + bool al; + u8 pin; + } leds; }; struct mt76_dev { @@ -830,13 +837,6 @@ struct mt76_dev { struct mt76_usb usb; struct mt76_sdio sdio; }; - - struct { - struct led_classdev cdev; - char name[32]; - bool al; - u8 pin; - } leds; }; struct mt76_power_limits { diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c index a44c7b3a6e02..9a2e632d577a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c @@ -330,10 +330,10 @@ static const struct ieee80211_iface_combination if_comb[] = { } }; -static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on, +static void mt7603_led_set_config(struct mt76_phy *mphy, u8 delay_on, u8 delay_off) { - struct mt7603_dev *dev = container_of(mt76, struct mt7603_dev, + struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev, mt76); u32 val, addr; @@ -341,15 +341,15 @@ static void mt7603_led_set_config(struct mt76_dev *mt76, u8 delay_on, FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | FIELD_PREP(MT_LED_STATUS_ON, delay_on); - addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mt76->leds.pin)); + addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mphy->leds.pin)); mt76_wr(dev, addr, val); - addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mt76->leds.pin)); + addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mphy->leds.pin)); mt76_wr(dev, addr, val); - val = MT_LED_CTRL_REPLAY(mt76->leds.pin) | - MT_LED_CTRL_KICK(mt76->leds.pin); - if (mt76->leds.al) - val |= MT_LED_CTRL_POLARITY(mt76->leds.pin); + val = MT_LED_CTRL_REPLAY(mphy->leds.pin) | + MT_LED_CTRL_KICK(mphy->leds.pin); + if (mphy->leds.al) + val |= MT_LED_CTRL_POLARITY(mphy->leds.pin); addr = mt7603_reg_map(dev, MT_LED_CTRL); mt76_wr(dev, addr, val); } @@ -358,27 +358,27 @@ static int mt7603_led_set_blink(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { - struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev, + struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); u8 delta_on, delta_off; delta_off = max_t(u8, *delay_off / 10, 1); delta_on = max_t(u8, *delay_on / 10, 1); - mt7603_led_set_config(mt76, delta_on, delta_off); + mt7603_led_set_config(mphy, delta_on, delta_off); return 0; } static void mt7603_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev, + struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); if (!brightness) - mt7603_led_set_config(mt76, 0, 0xff); + mt7603_led_set_config(mphy, 0, 0xff); else - mt7603_led_set_config(mt76, 0xff, 0); + mt7603_led_set_config(mphy, 0xff, 0); } static u32 __mt7603_reg_addr(struct mt7603_dev *dev, u32 addr) @@ -535,8 +535,8 @@ int mt7603_register_device(struct mt7603_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.leds.cdev.brightness_set = mt7603_led_set_brightness; - dev->mt76.leds.cdev.blink_set = mt7603_led_set_blink; + dev->mphy.leds.cdev.brightness_set = mt7603_led_set_brightness; + dev->mphy.leds.cdev.blink_set = mt7603_led_set_blink; } wiphy->reg_notifier = mt7603_regd_notifier; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c index 944bae068dab..506a3b561d4a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c @@ -71,32 +71,32 @@ mt7615_led_set_config(struct led_classdev *led_cdev, u8 delay_on, u8 delay_off) { struct mt7615_dev *dev; - struct mt76_dev *mt76; + struct mt76_phy *mphy; u32 val, addr; - mt76 = container_of(led_cdev, struct mt76_dev, leds.cdev); - dev = container_of(mt76, struct mt7615_dev, mt76); + mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); + dev = container_of(mphy->dev, struct mt7615_dev, mt76); - if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm)) + if (!mt76_connac_pm_ref(mphy, &dev->pm)) return; val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) | FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | FIELD_PREP(MT_LED_STATUS_ON, delay_on); - addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mt76->leds.pin)); + addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mphy->leds.pin)); mt76_wr(dev, addr, val); - addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mt76->leds.pin)); + addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mphy->leds.pin)); mt76_wr(dev, addr, val); - val = MT_LED_CTRL_REPLAY(mt76->leds.pin) | - MT_LED_CTRL_KICK(mt76->leds.pin); - if (mt76->leds.al) - val |= MT_LED_CTRL_POLARITY(mt76->leds.pin); + val = MT_LED_CTRL_REPLAY(mphy->leds.pin) | + MT_LED_CTRL_KICK(mphy->leds.pin); + if (mphy->leds.al) + val |= MT_LED_CTRL_POLARITY(mphy->leds.pin); addr = mt7615_reg_map(dev, MT_LED_CTRL); mt76_wr(dev, addr, val); - mt76_connac_pm_unref(&dev->mphy, &dev->pm); + mt76_connac_pm_unref(mphy, &dev->pm); } static int @@ -133,8 +133,8 @@ int mt7615_register_device(struct mt7615_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.leds.cdev.brightness_set = mt7615_led_set_brightness; - dev->mt76.leds.cdev.blink_set = mt7615_led_set_blink; + dev->mphy.leds.cdev.brightness_set = mt7615_led_set_brightness; + dev->mphy.leds.cdev.blink_set = mt7615_led_set_blink; } ret = mt7622_wmac_init(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 56abc1bdb9fb..7451a63206a5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -87,10 +87,9 @@ static const struct ieee80211_iface_combination mt76x02u_if_comb[] = { }; static void -mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on, - u8 delay_off) +mt76x02_led_set_config(struct mt76_phy *mphy, u8 delay_on, u8 delay_off) { - struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, + struct mt76x02_dev *dev = container_of(mphy->dev, struct mt76x02_dev, mt76); u32 val; @@ -98,13 +97,13 @@ mt76x02_led_set_config(struct mt76_dev *mdev, u8 delay_on, FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | FIELD_PREP(MT_LED_STATUS_ON, delay_on); - mt76_wr(dev, MT_LED_S0(mdev->leds.pin), val); - mt76_wr(dev, MT_LED_S1(mdev->leds.pin), val); + mt76_wr(dev, MT_LED_S0(mphy->leds.pin), val); + mt76_wr(dev, MT_LED_S1(mphy->leds.pin), val); - val = MT_LED_CTRL_REPLAY(mdev->leds.pin) | - MT_LED_CTRL_KICK(mdev->leds.pin); - if (mdev->leds.al) - val |= MT_LED_CTRL_POLARITY(mdev->leds.pin); + val = MT_LED_CTRL_REPLAY(mphy->leds.pin) | + MT_LED_CTRL_KICK(mphy->leds.pin); + if (mphy->leds.al) + val |= MT_LED_CTRL_POLARITY(mphy->leds.pin); mt76_wr(dev, MT_LED_CTRL, val); } @@ -113,14 +112,14 @@ mt76x02_led_set_blink(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { - struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev, + struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); u8 delta_on, delta_off; delta_off = max_t(u8, *delay_off / 10, 1); delta_on = max_t(u8, *delay_on / 10, 1); - mt76x02_led_set_config(mdev, delta_on, delta_off); + mt76x02_led_set_config(mphy, delta_on, delta_off); return 0; } @@ -129,13 +128,13 @@ static void mt76x02_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - struct mt76_dev *mdev = container_of(led_cdev, struct mt76_dev, + struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); if (!brightness) - mt76x02_led_set_config(mdev, 0, 0xff); + mt76x02_led_set_config(mphy, 0, 0xff); else - mt76x02_led_set_config(mdev, 0xff, 0); + mt76x02_led_set_config(mphy, 0xff, 0); } int mt76x02_init_device(struct mt76x02_dev *dev) @@ -167,9 +166,9 @@ int mt76x02_init_device(struct mt76x02_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.leds.cdev.brightness_set = + dev->mphy.leds.cdev.brightness_set = mt76x02_led_set_brightness; - dev->mt76.leds.cdev.blink_set = mt76x02_led_set_blink; + dev->mphy.leds.cdev.blink_set = mt76x02_led_set_blink; } } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index bae6c2701323..f7b8675e940c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -209,11 +209,11 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev, u8 delay_on, u8 delay_off) { struct mt7915_dev *dev; - struct mt76_dev *mt76; + struct mt76_phy *mphy; u32 val; - mt76 = container_of(led_cdev, struct mt76_dev, leds.cdev); - dev = container_of(mt76, struct mt7915_dev, mt76); + mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); + dev = container_of(mphy->dev, struct mt7915_dev, mt76); /* select TX blink mode, 2: only data frames */ mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2); @@ -228,7 +228,7 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev, /* control LED */ val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK; - if (dev->mt76.leds.al) + if (mphy->leds.al) val |= MT_LED_CTRL_POLARITY; mt76_wr(dev, MT_LED_CTRL(0), val); @@ -498,7 +498,7 @@ void mt7915_mac_init(struct mt7915_dev *dev) mt7915_mac_init_band(dev, i); if (IS_ENABLED(CONFIG_MT76_LEDS)) { - i = dev->mt76.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; + i = dev->mphy.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4); } } @@ -1141,8 +1141,8 @@ int mt7915_register_device(struct mt7915_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.leds.cdev.brightness_set = mt7915_led_set_brightness; - dev->mt76.leds.cdev.blink_set = mt7915_led_set_blink; + dev->mphy.leds.cdev.brightness_set = mt7915_led_set_brightness; + dev->mphy.leds.cdev.blink_set = mt7915_led_set_blink; } ret = mt76_register_device(&dev->mt76, true, mt76_rates, diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 2923606d5f5e..64e8dfd06e9f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -46,11 +46,11 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev, u8 delay_on, u8 delay_off) { struct mt7996_dev *dev; - struct mt76_dev *mt76; + struct mt76_phy *mphy; u32 val; - mt76 = container_of(led_cdev, struct mt76_dev, leds.cdev); - dev = container_of(mt76, struct mt7996_dev, mt76); + mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); + dev = container_of(mphy->dev, struct mt7996_dev, mt76); /* select TX blink mode, 2: only data frames */ mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2); @@ -65,7 +65,7 @@ static void mt7996_led_set_config(struct led_classdev *led_cdev, /* control LED */ val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK; - if (dev->mt76.leds.al) + if (mphy->leds.al) val |= MT_LED_CTRL_POLARITY; mt76_wr(dev, MT_LED_CTRL(0), val); @@ -261,7 +261,7 @@ static void mt7996_mac_init(struct mt7996_dev *dev) MT_WTBL_UPDATE_ADM_COUNT_CLEAR); if (IS_ENABLED(CONFIG_MT76_LEDS)) { - i = dev->mt76.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; + i = dev->mphy.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4); } @@ -787,8 +787,8 @@ int mt7996_register_device(struct mt7996_dev *dev) /* init led callbacks */ if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mt76.leds.cdev.brightness_set = mt7996_led_set_brightness; - dev->mt76.leds.cdev.blink_set = mt7996_led_set_blink; + dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness; + dev->mphy.leds.cdev.blink_set = mt7996_led_set_blink; } ret = mt76_register_device(&dev->mt76, true, mt76_rates, From 9e81c2c7b9af6a5f160e0a9a7f009c37910402ee Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 7 Dec 2022 17:19:44 +0100 Subject: [PATCH 21/27] wifi: mt76: mt7915: enable per-phy led support Introduce the capability to support per-phy led blinking. This is needed for devices supporting dbdc. Tested-by: Frank Wunderlich Co-developed-by: Ryder Lee Signed-off-by: Ryder Lee Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 8 ++ .../net/wireless/mediatek/mt76/mt7915/init.c | 118 ++++++++++++++---- .../net/wireless/mediatek/mt76/mt7915/regs.h | 12 +- 3 files changed, 109 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index ad7274de5694..7fe7f68acc24 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -523,6 +523,12 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht, return ret; } + if (IS_ENABLED(CONFIG_MT76_LEDS)) { + ret = mt76_led_init(phy); + if (ret) + return ret; + } + wiphy_read_of_freq_limits(phy->hw->wiphy); mt76_check_sband(phy, &phy->sband_2g, NL80211_BAND_2GHZ); mt76_check_sband(phy, &phy->sband_5g, NL80211_BAND_5GHZ); @@ -542,6 +548,8 @@ void mt76_unregister_phy(struct mt76_phy *phy) { struct mt76_dev *dev = phy->dev; + if (IS_ENABLED(CONFIG_MT76_LEDS)) + mt76_led_cleanup(phy); mt76_tx_status_check(dev, true); ieee80211_unregister_hw(phy->hw); dev->phys[phy->band_idx] = NULL; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index f7b8675e940c..571c94835942 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -215,24 +215,25 @@ static void mt7915_led_set_config(struct led_classdev *led_cdev, mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); dev = container_of(mphy->dev, struct mt7915_dev, mt76); - /* select TX blink mode, 2: only data frames */ - mt76_rmw_field(dev, MT_TMAC_TCR0(0), MT_TMAC_TCR0_TX_BLINK, 2); + /* set PWM mode */ + val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) | + FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | + FIELD_PREP(MT_LED_STATUS_ON, delay_on); + mt76_wr(dev, MT_LED_STATUS_0(mphy->band_idx), val); + mt76_wr(dev, MT_LED_STATUS_1(mphy->band_idx), val); /* enable LED */ - mt76_wr(dev, MT_LED_EN(0), 1); - - /* set LED Tx blink on/off time */ - val = FIELD_PREP(MT_LED_TX_BLINK_ON_MASK, delay_on) | - FIELD_PREP(MT_LED_TX_BLINK_OFF_MASK, delay_off); - mt76_wr(dev, MT_LED_TX_BLINK(0), val); + mt76_wr(dev, MT_LED_EN(mphy->band_idx), 1); /* control LED */ - val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK; - if (mphy->leds.al) + val = MT_LED_CTRL_KICK; + if (dev->mphy.leds.al) val |= MT_LED_CTRL_POLARITY; + if (mphy->band_idx) + val |= MT_LED_CTRL_BAND; - mt76_wr(dev, MT_LED_CTRL(0), val); - mt76_clear(dev, MT_LED_CTRL(0), MT_LED_CTRL_KICK); + mt76_wr(dev, MT_LED_CTRL(mphy->band_idx), val); + mt76_clear(dev, MT_LED_CTRL(mphy->band_idx), MT_LED_CTRL_KICK); } static int mt7915_led_set_blink(struct led_classdev *led_cdev, @@ -319,9 +320,10 @@ mt7915_regd_notifier(struct wiphy *wiphy, } static void -mt7915_init_wiphy(struct ieee80211_hw *hw) +mt7915_init_wiphy(struct mt7915_phy *phy) { - struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt76_phy *mphy = phy->mt76; + struct ieee80211_hw *hw = mphy->hw; struct mt76_dev *mdev = &phy->dev->mt76; struct wiphy *wiphy = hw->wiphy; struct mt7915_dev *dev = phy->dev; @@ -415,6 +417,12 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) wiphy->available_antennas_rx = phy->mt76->antenna_mask; wiphy->available_antennas_tx = phy->mt76->antenna_mask; + + /* init led callbacks */ + if (IS_ENABLED(CONFIG_MT76_LEDS)) { + mphy->leds.cdev.brightness_set = mt7915_led_set_brightness; + mphy->leds.cdev.blink_set = mt7915_led_set_blink; + } } static void @@ -473,6 +481,72 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set); } +static void +mt7915_init_led_mux(struct mt7915_dev *dev) +{ + if (!IS_ENABLED(CONFIG_MT76_LEDS)) + return; + + if (dev->dbdc_support) { + switch (mt76_chip(&dev->mt76)) { + case 0x7915: + mt76_rmw_field(dev, MT_LED_GPIO_MUX2, + GENMASK(11, 8), 4); + mt76_rmw_field(dev, MT_LED_GPIO_MUX3, + GENMASK(11, 8), 4); + break; + case 0x7986: + mt76_rmw_field(dev, MT_LED_GPIO_MUX0, + GENMASK(7, 4), 1); + mt76_rmw_field(dev, MT_LED_GPIO_MUX0, + GENMASK(11, 8), 1); + break; + case 0x7916: + mt76_rmw_field(dev, MT_LED_GPIO_MUX1, + GENMASK(27, 24), 3); + mt76_rmw_field(dev, MT_LED_GPIO_MUX1, + GENMASK(31, 28), 3); + break; + default: + break; + } + } else if (dev->mphy.leds.pin) { + switch (mt76_chip(&dev->mt76)) { + case 0x7915: + mt76_rmw_field(dev, MT_LED_GPIO_MUX3, + GENMASK(11, 8), 4); + break; + case 0x7986: + mt76_rmw_field(dev, MT_LED_GPIO_MUX0, + GENMASK(11, 8), 1); + break; + case 0x7916: + mt76_rmw_field(dev, MT_LED_GPIO_MUX1, + GENMASK(31, 28), 3); + break; + default: + break; + } + } else { + switch (mt76_chip(&dev->mt76)) { + case 0x7915: + mt76_rmw_field(dev, MT_LED_GPIO_MUX2, + GENMASK(11, 8), 4); + break; + case 0x7986: + mt76_rmw_field(dev, MT_LED_GPIO_MUX0, + GENMASK(7, 4), 1); + break; + case 0x7916: + mt76_rmw_field(dev, MT_LED_GPIO_MUX1, + GENMASK(27, 24), 3); + break; + default: + break; + } + } +} + void mt7915_mac_init(struct mt7915_dev *dev) { int i; @@ -497,10 +571,7 @@ void mt7915_mac_init(struct mt7915_dev *dev) for (i = 0; i < 2; i++) mt7915_mac_init_band(dev, i); - if (IS_ENABLED(CONFIG_MT76_LEDS)) { - i = dev->mphy.leds.pin ? MT_LED_GPIO_MUX3 : MT_LED_GPIO_MUX2; - mt76_rmw_field(dev, i, MT_LED_GPIO_SEL_MASK, 4); - } + mt7915_init_led_mux(dev); } int mt7915_txbf_init(struct mt7915_dev *dev) @@ -569,7 +640,7 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy) mt76_eeprom_override(mphy); /* init wiphy according to mphy and phy */ - mt7915_init_wiphy(mphy->hw); + mt7915_init_wiphy(phy); ret = mt76_register_phy(mphy, true, mt76_rates, ARRAY_SIZE(mt76_rates)); @@ -1104,7 +1175,6 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev) int mt7915_register_device(struct mt7915_dev *dev) { - struct ieee80211_hw *hw = mt76_hw(dev); struct mt7915_phy *phy2; int ret; @@ -1133,18 +1203,12 @@ int mt7915_register_device(struct mt7915_dev *dev) if (ret) goto free_phy2; - mt7915_init_wiphy(hw); + mt7915_init_wiphy(&dev->phy); #ifdef CONFIG_NL80211_TESTMODE dev->mt76.test_ops = &mt7915_testmode_ops; #endif - /* init led callbacks */ - if (IS_ENABLED(CONFIG_MT76_LEDS)) { - dev->mphy.leds.cdev.brightness_set = mt7915_led_set_brightness; - dev->mphy.leds.cdev.blink_set = mt7915_led_set_blink; - } - ret = mt76_register_device(&dev->mt76, true, mt76_rates, ARRAY_SIZE(mt76_rates)); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index 7e0d86366c77..c8e478a55081 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -1054,6 +1054,7 @@ enum offs_rev { #define MT_LED_CTRL(_n) MT_LED_PHYS(0x00 + ((_n) * 4)) #define MT_LED_CTRL_KICK BIT(7) +#define MT_LED_CTRL_BAND BIT(4) #define MT_LED_CTRL_BLINK_MODE BIT(2) #define MT_LED_CTRL_POLARITY BIT(1) @@ -1061,11 +1062,18 @@ enum offs_rev { #define MT_LED_TX_BLINK_ON_MASK GENMASK(7, 0) #define MT_LED_TX_BLINK_OFF_MASK GENMASK(15, 8) +#define MT_LED_STATUS_0(_n) MT_LED_PHYS(0x20 + ((_n) * 8)) +#define MT_LED_STATUS_1(_n) MT_LED_PHYS(0x24 + ((_n) * 8)) +#define MT_LED_STATUS_OFF GENMASK(31, 24) +#define MT_LED_STATUS_ON GENMASK(23, 16) +#define MT_LED_STATUS_DURATION GENMASK(15, 0) + #define MT_LED_EN(_n) MT_LED_PHYS(0x40 + ((_n) * 4)) +#define MT_LED_GPIO_MUX0 0x70005050 /* GPIO 1 and GPIO 2 */ +#define MT_LED_GPIO_MUX1 0x70005054 /* GPIO 14 and 15 */ #define MT_LED_GPIO_MUX2 0x70005058 /* GPIO 18 */ -#define MT_LED_GPIO_MUX3 0x7000505C /* GPIO 26 */ -#define MT_LED_GPIO_SEL_MASK GENMASK(11, 8) +#define MT_LED_GPIO_MUX3 0x7000505c /* GPIO 26 */ /* MT TOP */ #define MT_TOP_BASE 0x18060000 From 12a88d4d307e227b9ada9377ea49ce2b79f165f5 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 7 Dec 2022 17:19:45 +0100 Subject: [PATCH 22/27] wifi: mt76: mt7615: enable per-phy led support Introduce the capability to support per-phy led blinking. This is needed for devices supporting dbdc. Co-developed-by: Ryder Lee Signed-off-by: Ryder Lee Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7615/init.c | 85 +++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7615/mmio.c | 16 ---- .../wireless/mediatek/mt76/mt7615/mt7615.h | 6 ++ .../wireless/mediatek/mt76/mt7615/pci_init.c | 58 ------------- .../net/wireless/mediatek/mt76/mt7615/regs.h | 1 + 5 files changed, 92 insertions(+), 74 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c index 07a1fea94f66..5fa6f097ec30 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c @@ -443,6 +443,85 @@ mt7615_cap_dbdc_disable(struct mt7615_dev *dev) mt76_set_stream_caps(&dev->mphy, true); } +u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr) +{ + u32 base, offset; + + if (is_mt7663(&dev->mt76)) { + base = addr & MT7663_MCU_PCIE_REMAP_2_BASE; + offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET; + } else { + base = addr & MT_MCU_PCIE_REMAP_2_BASE; + offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET; + } + mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base); + + return MT_PCIE_REMAP_BASE_2 + offset; +} +EXPORT_SYMBOL_GPL(mt7615_reg_map); + +static void +mt7615_led_set_config(struct led_classdev *led_cdev, + u8 delay_on, u8 delay_off) +{ + struct mt7615_dev *dev; + struct mt76_phy *mphy; + u32 val, addr; + u8 index; + + mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); + dev = container_of(mphy->dev, struct mt7615_dev, mt76); + + if (!mt76_connac_pm_ref(mphy, &dev->pm)) + return; + + val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) | + FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | + FIELD_PREP(MT_LED_STATUS_ON, delay_on); + + index = dev->dbdc_support ? mphy->band_idx : mphy->leds.pin; + addr = mt7615_reg_map(dev, MT_LED_STATUS_0(index)); + mt76_wr(dev, addr, val); + addr = mt7615_reg_map(dev, MT_LED_STATUS_1(index)); + mt76_wr(dev, addr, val); + + val = MT_LED_CTRL_REPLAY(index) | MT_LED_CTRL_KICK(index); + if (dev->mphy.leds.al) + val |= MT_LED_CTRL_POLARITY(index); + if (mphy->band_idx) + val |= MT_LED_CTRL_BAND(index); + + addr = mt7615_reg_map(dev, MT_LED_CTRL); + mt76_wr(dev, addr, val); + + mt76_connac_pm_unref(mphy, &dev->pm); +} + +int mt7615_led_set_blink(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off) +{ + u8 delta_on, delta_off; + + delta_off = max_t(u8, *delay_off / 10, 1); + delta_on = max_t(u8, *delay_on / 10, 1); + + mt7615_led_set_config(led_cdev, delta_on, delta_off); + + return 0; +} +EXPORT_SYMBOL_GPL(mt7615_led_set_blink); + +void mt7615_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + if (!brightness) + mt7615_led_set_config(led_cdev, 0, 0xff); + else + mt7615_led_set_config(led_cdev, 0xff, 0); +} +EXPORT_SYMBOL_GPL(mt7615_led_set_brightness); + int mt7615_register_ext_phy(struct mt7615_dev *dev) { struct mt7615_phy *phy = mt7615_ext_phy(dev); @@ -497,6 +576,12 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev) for (i = 0; i <= MT_TXQ_PSD ; i++) mphy->q_tx[i] = dev->mphy.q_tx[i]; + /* init led callbacks */ + if (IS_ENABLED(CONFIG_MT76_LEDS)) { + mphy->leds.cdev.brightness_set = mt7615_led_set_brightness; + mphy->leds.cdev.blink_set = mt7615_led_set_blink; + } + ret = mt76_register_phy(mphy, true, mt76_rates, ARRAY_SIZE(mt76_rates)); if (ret) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c index a784f9d9e935..83173efb56dc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c @@ -63,22 +63,6 @@ const u32 mt7663e_reg_map[] = { [MT_EFUSE_ADDR_BASE] = 0x78011000, }; -u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr) -{ - u32 base, offset; - - if (is_mt7663(&dev->mt76)) { - base = addr & MT7663_MCU_PCIE_REMAP_2_BASE; - offset = addr & MT7663_MCU_PCIE_REMAP_2_OFFSET; - } else { - base = addr & MT_MCU_PCIE_REMAP_2_BASE; - offset = addr & MT_MCU_PCIE_REMAP_2_OFFSET; - } - mt76_wr(dev, MT_MCU_PCIE_REMAP_2, base); - - return MT_PCIE_REMAP_BASE_2 + offset; -} - static void mt7615_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 087d4886162e..43591b4c1d9a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -376,6 +376,12 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base, int irq, const u32 *map); u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr); +u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr); +int mt7615_led_set_blink(struct led_classdev *led_cdev, + unsigned long *delay_on, + unsigned long *delay_off); +void mt7615_led_set_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness); void mt7615_init_device(struct mt7615_dev *dev); int mt7615_register_device(struct mt7615_dev *dev); void mt7615_unregister_device(struct mt7615_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c index 506a3b561d4a..0680e002b981 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c @@ -66,64 +66,6 @@ static int mt7615_init_hardware(struct mt7615_dev *dev) return 0; } -static void -mt7615_led_set_config(struct led_classdev *led_cdev, - u8 delay_on, u8 delay_off) -{ - struct mt7615_dev *dev; - struct mt76_phy *mphy; - u32 val, addr; - - mphy = container_of(led_cdev, struct mt76_phy, leds.cdev); - dev = container_of(mphy->dev, struct mt7615_dev, mt76); - - if (!mt76_connac_pm_ref(mphy, &dev->pm)) - return; - - val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) | - FIELD_PREP(MT_LED_STATUS_OFF, delay_off) | - FIELD_PREP(MT_LED_STATUS_ON, delay_on); - - addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mphy->leds.pin)); - mt76_wr(dev, addr, val); - addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mphy->leds.pin)); - mt76_wr(dev, addr, val); - - val = MT_LED_CTRL_REPLAY(mphy->leds.pin) | - MT_LED_CTRL_KICK(mphy->leds.pin); - if (mphy->leds.al) - val |= MT_LED_CTRL_POLARITY(mphy->leds.pin); - addr = mt7615_reg_map(dev, MT_LED_CTRL); - mt76_wr(dev, addr, val); - - mt76_connac_pm_unref(mphy, &dev->pm); -} - -static int -mt7615_led_set_blink(struct led_classdev *led_cdev, - unsigned long *delay_on, - unsigned long *delay_off) -{ - u8 delta_on, delta_off; - - delta_off = max_t(u8, *delay_off / 10, 1); - delta_on = max_t(u8, *delay_on / 10, 1); - - mt7615_led_set_config(led_cdev, delta_on, delta_off); - - return 0; -} - -static void -mt7615_led_set_brightness(struct led_classdev *led_cdev, - enum led_brightness brightness) -{ - if (!brightness) - mt7615_led_set_config(led_cdev, 0, 0xff); - else - mt7615_led_set_config(led_cdev, 0xff, 0); -} - int mt7615_register_device(struct mt7615_dev *dev) { int ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h index fa1b9b26b399..7cecb22c569e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h @@ -544,6 +544,7 @@ enum mt7615_reg_base { #define MT_LED_CTRL_POLARITY(_n) BIT(1 + (8 * (_n))) #define MT_LED_CTRL_TX_BLINK_MODE(_n) BIT(2 + (8 * (_n))) #define MT_LED_CTRL_TX_MANUAL_BLINK(_n) BIT(3 + (8 * (_n))) +#define MT_LED_CTRL_BAND(_n) BIT(4 + (8 * (_n))) #define MT_LED_CTRL_TX_OVER_BLINK(_n) BIT(5 + (8 * (_n))) #define MT_LED_CTRL_KICK(_n) BIT(7 + (8 * (_n))) From fe13dad8992be0b26c1be390bcd111acf9892c17 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Wed, 7 Dec 2022 22:49:31 +0100 Subject: [PATCH 23/27] wifi: mt76: dma: do not increment queue head if mt76_dma_add_buf fails Do not increment queue head if mt76_dma_add_buf fails for Wireless Ethernet Dispatcher rx queues. Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 3f8c0845fcca..983ca346b18b 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -212,14 +212,14 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, { struct mt76_queue_entry *entry; struct mt76_desc *desc; - u32 ctrl; int i, idx = -1; + u32 ctrl, next; for (i = 0; i < nbufs; i += 2, buf += 2) { u32 buf0 = buf[0].addr, buf1 = 0; idx = q->head; - q->head = (q->head + 1) % q->ndesc; + next = (q->head + 1) % q->ndesc; desc = &q->desc[idx]; entry = &q->entry[idx]; @@ -239,8 +239,8 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, MT_DMA_CTL_TO_HOST; } else { if (txwi) { - q->entry[q->head].txwi = DMA_DUMMY_DATA; - q->entry[q->head].skip_buf0 = true; + q->entry[next].txwi = DMA_DUMMY_DATA; + q->entry[next].skip_buf0 = true; } if (buf[0].skip_unmap) @@ -271,6 +271,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, WRITE_ONCE(desc->info, cpu_to_le32(info)); WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); + q->head = next; q->queued++; } From 96f134dc19645be4994e89a2f68fa89309becbee Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 8 Dec 2022 11:46:40 +0100 Subject: [PATCH 24/27] wifi: mt76: handle possible mt76_rx_token_consume failures Take into account possible error conditions of mt76_rx_token_consume routine in mt7915_mmio_wed_init_rx_buf() and mt76_dma_add_buf() Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.c | 10 +++++++++- drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 7 +++++++ drivers/net/wireless/mediatek/mt76/tx.c | 7 ++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 983ca346b18b..931e58cd9cd1 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -234,6 +234,9 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, rx_token = mt76_rx_token_consume(dev, (void *)skb, t, buf[0].addr); + if (rx_token < 0) + return -ENOMEM; + buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) | MT_DMA_CTL_TO_HOST; @@ -602,7 +605,12 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) qbuf.addr = addr + offset; qbuf.len = len - offset; qbuf.skip_unmap = false; - mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t); + if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) { + dma_unmap_single(dev->dma_dev, addr, len, + DMA_FROM_DEVICE); + skb_free_frag(buf); + break; + } frames++; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 52be55dff947..afa558c9a930 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -653,6 +653,13 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) desc->buf0 = cpu_to_le32(phy_addr); token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr); + if (token < 0) { + dma_unmap_single(dev->mt76.dma_dev, phy_addr, + wed->wlan.rx_size, DMA_TO_DEVICE); + skb_free_frag(ptr); + goto unmap; + } + desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN, token)); desc++; diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 24568b98ed9d..1f309d05380a 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -764,11 +764,12 @@ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, spin_lock_bh(&dev->rx_token_lock); token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size, GFP_ATOMIC); + if (token >= 0) { + t->ptr = ptr; + t->dma_addr = phys; + } spin_unlock_bh(&dev->rx_token_lock); - t->ptr = ptr; - t->dma_addr = phys; - return token; } EXPORT_SYMBOL_GPL(mt76_rx_token_consume); From 4493acad5b334ed0b45e374135acc6d6aaa9755c Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 8 Dec 2022 12:36:10 +0100 Subject: [PATCH 25/27] wifi: mt76: dma: rely on queue page_frag_cache for wed rx queues Since mt76_dma_rx_fill() acquires mt76_queue spinlock, rely on mt76_queue page_frag_cache in mt76_dma_rx_fill() instead of wed rx_buf_ring page_frag_cache. Get rid of mt76_dma_rx_get_frag_cache since it is no longer used. Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/dma.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 931e58cd9cd1..fad5fe19fe18 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -554,23 +554,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, return ret; } -static struct page_frag_cache * -mt76_dma_rx_get_frag_cache(struct mt76_dev *dev, struct mt76_queue *q) -{ - struct page_frag_cache *rx_page = &q->rx_page; - -#ifdef CONFIG_NET_MEDIATEK_SOC_WED - if ((q->flags & MT_QFLAG_WED) && - FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) - rx_page = &dev->mmio.wed.rx_buf_ring.rx_page; -#endif - return rx_page; -} - static int mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) { - struct page_frag_cache *rx_page = mt76_dma_rx_get_frag_cache(dev, q); int len = SKB_WITH_OVERHEAD(q->buf_size); int frames = 0, offset = q->buf_offset; dma_addr_t addr; @@ -592,7 +578,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) break; } - buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC); + buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC); if (!buf) break; From 47180ecf4541146836c5307c1d5526f8ac6a5a6d Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Fri, 9 Dec 2022 07:01:57 +0800 Subject: [PATCH 26/27] wifi: mt76: mt7921: resource leaks at mt7921_check_offload_capability() Fixed coverity issue with resource leaks at variable "fw" going out of scope leaks the storage it points to mt7921_check_offload_capability(). Reported-by: coverity-bot Addresses-Coverity-ID: 1527806 ("Resource leaks") Fixes: 034ae28b56f1 ("wifi: mt76: mt7921: introduce remain_on_channel support") Signed-off-by: Sean Wang Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7921/init.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 542dfd425129..d4b681d7e1d2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -175,7 +175,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm) if (!fw || !fw->data || fw->size < sizeof(*hdr)) { dev_err(dev, "Invalid firmware\n"); - return -EINVAL; + goto out; } data = fw->data; @@ -206,6 +206,7 @@ u8 mt7921_check_offload_capability(struct device *dev, const char *fw_wm) data += le16_to_cpu(rel_info->len) + rel_info->pad_len; } +out: release_firmware(fw); return features ? features->data : 0; From d878d3dc126db05b075147456644bd2d2ab1fb5e Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 9 Dec 2022 16:07:22 +0100 Subject: [PATCH 27/27] wifi: mt76: mt7915: get rid of wed rx_buf_ring page_frag_cache Since wed rx_buf_ring page_frag_cache is no longer used in a hot path, remove it and rely on page allocation APIs in mt7915_mmio_wed_init_rx_buf() and mt7915_mmio_wed_release_rx_buf() Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7915/mmio.c | 25 ++++++++----------- include/linux/soc/mediatek/mtk_wed.h | 1 - 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index afa558c9a930..1a2e4df8d1b5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -594,10 +594,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed) static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed) { struct mt7915_dev *dev; - struct page *page; + u32 length; int i; dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); + length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size + + sizeof(struct skb_shared_info)); + for (i = 0; i < dev->mt76.rx_token_size; i++) { struct mt76_txwi_cache *t; @@ -607,18 +610,11 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed) dma_unmap_single(dev->mt76.dma_dev, t->dma_addr, wed->wlan.rx_size, DMA_FROM_DEVICE); - skb_free_frag(t->ptr); + __free_pages(virt_to_page(t->ptr), get_order(length)); t->ptr = NULL; mt76_put_rxwi(&dev->mt76, t); } - - if (!wed->rx_buf_ring.rx_page.va) - return; - - page = virt_to_page(wed->rx_buf_ring.rx_page.va); - __page_frag_cache_drain(page, wed->rx_buf_ring.rx_page.pagecnt_bias); - memset(&wed->rx_buf_ring.rx_page, 0, sizeof(wed->rx_buf_ring.rx_page)); } static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) @@ -635,19 +631,20 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) for (i = 0; i < size; i++) { struct mt76_txwi_cache *t = mt76_get_rxwi(&dev->mt76); dma_addr_t phy_addr; + struct page *page; int token; void *ptr; - ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length, - GFP_KERNEL); - if (!ptr) + page = __dev_alloc_pages(GFP_KERNEL, get_order(length)); + if (!page) goto unmap; + ptr = page_address(page); phy_addr = dma_map_single(dev->mt76.dma_dev, ptr, wed->wlan.rx_size, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) { - skb_free_frag(ptr); + __free_pages(page, get_order(length)); goto unmap; } @@ -656,7 +653,7 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) if (token < 0) { dma_unmap_single(dev->mt76.dma_dev, phy_addr, wed->wlan.rx_size, DMA_TO_DEVICE); - skb_free_frag(ptr); + __free_pages(page, get_order(length)); goto unmap; } diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h index beb190449704..7293259dc1f8 100644 --- a/include/linux/soc/mediatek/mtk_wed.h +++ b/include/linux/soc/mediatek/mtk_wed.h @@ -103,7 +103,6 @@ struct mtk_wed_device { struct { int size; - struct page_frag_cache rx_page; struct mtk_rxbm_desc *desc; dma_addr_t desc_phys; } rx_buf_ring;