Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Aug 2023 01:36:52 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: cbb3ec25236b - main - mt76: update driver from upstream
Message-ID:  <202308210136.37L1aqXB038414@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=cbb3ec25236ba72f91cbdf23f8b78b9d1af0cedf

commit cbb3ec25236ba72f91cbdf23f8b78b9d1af0cedf
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2023-05-23 23:03:09 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2023-08-21 01:34:03 +0000

    mt76: update driver from upstream
    
    This is a set of updates of the mt76 driver based on wireless-testing
    (wt-2023-05-11) 711dca0ca3d77414f8f346e564e9c8640147f40d (after v6.4-rc1),
      This adds support for mt7996 as well.
    (wt-2023-06-09) 7bd20e011626ccc3ad53e57873452b1716fcfaaa (after v6.4-rc5),
    (wt-2023-07-24) 62e409149b62a285e89018e49b2e115757fb9022 (after v6.5-rc3),
    (wt-2023-08-06) 2a220a15be657a24868368892e3e2caba2115283 (after v6.5-rc4).
    
    The current version of LinuxKPI lacks support for "page pool" which
    needs enhancing and updating a decade or so old shortcut mapping
    struct page directly to struct vm_page.
    
    MFC after:      20 days
---
 .../common/include/linux/soc/mediatek/mtk_wed.h    |   16 +-
 sys/contrib/dev/mediatek/mt76/debugfs.c            |   21 +-
 sys/contrib/dev/mediatek/mt76/dma.c                |  300 +-
 sys/contrib/dev/mediatek/mt76/dma.h                |   10 +
 sys/contrib/dev/mediatek/mt76/eeprom.c             |   95 +-
 sys/contrib/dev/mediatek/mt76/mac80211.c           |  197 +-
 sys/contrib/dev/mediatek/mt76/mt76.h               |  248 +-
 sys/contrib/dev/mediatek/mt76/mt7603/beacon.c      |    3 +-
 sys/contrib/dev/mediatek/mt76/mt7603/debugfs.c     |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7603/dma.c         |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7603/init.c        |   36 +-
 sys/contrib/dev/mediatek/mt76/mt7603/mac.c         |   54 +-
 sys/contrib/dev/mediatek/mt76/mt7603/main.c        |   35 +-
 sys/contrib/dev/mediatek/mt76/mt7603/mcu.c         |    3 +-
 sys/contrib/dev/mediatek/mt76/mt7603/mt7603.h      |    8 +-
 sys/contrib/dev/mediatek/mt76/mt7603/regs.h        |    7 +
 sys/contrib/dev/mediatek/mt76/mt7615/debugfs.c     |    6 +-
 sys/contrib/dev/mediatek/mt76/mt7615/dma.c         |    5 +-
 sys/contrib/dev/mediatek/mt76/mt7615/eeprom.c      |   13 +-
 sys/contrib/dev/mediatek/mt76/mt7615/eeprom.h      |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7615/init.c        |   90 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mac.c         |  152 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mac.h         |   12 -
 sys/contrib/dev/mediatek/mt76/mt7615/main.c        |   71 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mcu.c         |   16 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mcu.h         |   11 -
 sys/contrib/dev/mediatek/mt76/mt7615/mmio.c        |   27 +-
 sys/contrib/dev/mediatek/mt76/mt7615/mt7615.h      |   33 +-
 .../dev/mediatek/mt76/mt7615/mt7615_trace.h        |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7615/pci.c         |    2 +-
 sys/contrib/dev/mediatek/mt76/mt7615/pci_init.c    |   64 +-
 sys/contrib/dev/mediatek/mt76/mt7615/regs.h        |   12 +
 sys/contrib/dev/mediatek/mt76/mt7615/sdio.c        |    1 -
 sys/contrib/dev/mediatek/mt76/mt7615/usb.c         |    1 -
 sys/contrib/dev/mediatek/mt76/mt76_connac.h        |   62 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac2_mac.h   |   24 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac3_mac.c   |  182 +
 sys/contrib/dev/mediatek/mt76/mt76_connac3_mac.h   |  339 ++
 sys/contrib/dev/mediatek/mt76/mt76_connac_mac.c    |  213 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.c    |  284 +-
 sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.h    |  134 +-
 sys/contrib/dev/mediatek/mt76/mt76x0/usb_mcu.c     |    1 +
 sys/contrib/dev/mediatek/mt76/mt76x02.h            |   16 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_debugfs.c    |   19 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_eeprom.h     |    2 -
 sys/contrib/dev/mediatek/mt76/mt76x02_mac.c        |   14 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_phy.c        |   22 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_phy.h        |    6 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_trace.h      |    2 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_txrx.c       |   14 +-
 sys/contrib/dev/mediatek/mt76/mt76x02_util.c       |   53 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/eeprom.c      |   16 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/eeprom.h      |    2 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/init.c        |    2 +-
 sys/contrib/dev/mediatek/mt76/mt76x2/phy.c         |    6 +-
 sys/contrib/dev/mediatek/mt76/mt7915/Kconfig       |    7 +-
 sys/contrib/dev/mediatek/mt76/mt7915/Makefile      |    3 +-
 sys/contrib/dev/mediatek/mt76/mt7915/coredump.c    |  411 +++
 sys/contrib/dev/mediatek/mt76/mt7915/coredump.h    |  139 +
 sys/contrib/dev/mediatek/mt76/mt7915/debugfs.c     |  439 ++-
 sys/contrib/dev/mediatek/mt76/mt7915/dma.c         |  370 +-
 sys/contrib/dev/mediatek/mt76/mt7915/eeprom.c      |   95 +-
 sys/contrib/dev/mediatek/mt76/mt7915/eeprom.h      |    5 -
 sys/contrib/dev/mediatek/mt76/mt7915/init.c        |  374 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mac.c         |  803 +++--
 sys/contrib/dev/mediatek/mt76/mt7915/mac.h         |   40 +-
 sys/contrib/dev/mediatek/mt76/mt7915/main.c        |  418 ++-
 sys/contrib/dev/mediatek/mt76/mt7915/mcu.c         |  866 +++--
 sys/contrib/dev/mediatek/mt76/mt7915/mcu.h         |   61 +-
 sys/contrib/dev/mediatek/mt76/mt7915/mmio.c        |  464 ++-
 sys/contrib/dev/mediatek/mt76/mt7915/mt7915.h      |  161 +-
 sys/contrib/dev/mediatek/mt76/mt7915/pci.c         |  116 +-
 sys/contrib/dev/mediatek/mt76/mt7915/regs.h        |  117 +-
 sys/contrib/dev/mediatek/mt76/mt7915/soc.c         |  185 +-
 sys/contrib/dev/mediatek/mt76/mt7915/testmode.c    |   71 +-
 sys/contrib/dev/mediatek/mt76/mt7921/Kconfig       |    4 +-
 sys/contrib/dev/mediatek/mt76/mt7921/Makefile      |    9 +-
 sys/contrib/dev/mediatek/mt76/mt7921/debugfs.c     |  229 +-
 sys/contrib/dev/mediatek/mt76/mt7921/eeprom.h      |   30 -
 sys/contrib/dev/mediatek/mt76/mt7921/init.c        |  238 +-
 sys/contrib/dev/mediatek/mt76/mt7921/mac.c         |  611 +---
 sys/contrib/dev/mediatek/mt76/mt7921/mac.h         |   53 -
 sys/contrib/dev/mediatek/mt76/mt7921/main.c        |  950 ++---
 sys/contrib/dev/mediatek/mt76/mt7921/mcu.c         |  524 +--
 sys/contrib/dev/mediatek/mt76/mt7921/mcu.h         |   11 -
 sys/contrib/dev/mediatek/mt76/mt7921/mt7921.h      |  402 +--
 sys/contrib/dev/mediatek/mt76/mt7921/pci.c         |  278 +-
 sys/contrib/dev/mediatek/mt76/mt7921/pci_mac.c     |   36 +-
 sys/contrib/dev/mediatek/mt76/mt7921/pci_mcu.c     |   72 +-
 sys/contrib/dev/mediatek/mt76/mt7921/regs.h        |  457 +--
 sys/contrib/dev/mediatek/mt76/mt7921/sdio.c        |   48 +-
 sys/contrib/dev/mediatek/mt76/mt7921/sdio_mac.c    |    8 +-
 sys/contrib/dev/mediatek/mt76/mt7921/sdio_mcu.c    |   16 +-
 sys/contrib/dev/mediatek/mt76/mt7921/testmode.c    |   11 +-
 sys/contrib/dev/mediatek/mt76/mt7921/trace.c       |   12 -
 sys/contrib/dev/mediatek/mt76/mt7921/usb.c         |  226 +-
 sys/contrib/dev/mediatek/mt76/mt7921/usb_mac.c     |  255 --
 sys/contrib/dev/mediatek/mt76/mt792x.h             |  367 ++
 sys/contrib/dev/mediatek/mt76/mt792x_acpi_sar.c    |  350 ++
 sys/contrib/dev/mediatek/mt76/mt792x_acpi_sar.h    |  105 +
 sys/contrib/dev/mediatek/mt76/mt792x_core.c        |  862 +++++
 sys/contrib/dev/mediatek/mt76/mt792x_debugfs.c     |  168 +
 .../mediatek/mt76/{mt7921/dma.c => mt792x_dma.c}   |  348 +-
 sys/contrib/dev/mediatek/mt76/mt792x_mac.c         |  388 ++
 sys/contrib/dev/mediatek/mt76/mt792x_regs.h        |  479 +++
 sys/contrib/dev/mediatek/mt76/mt792x_trace.c       |   14 +
 .../mt76/{mt7921/mt7921_trace.h => mt792x_trace.h} |   16 +-
 sys/contrib/dev/mediatek/mt76/mt792x_usb.c         |  309 ++
 sys/contrib/dev/mediatek/mt76/mt7996/Kconfig       |   14 +
 sys/contrib/dev/mediatek/mt76/mt7996/Makefile      |    8 +
 sys/contrib/dev/mediatek/mt76/mt7996/coredump.c    |  268 ++
 sys/contrib/dev/mediatek/mt76/mt7996/coredump.h    |   97 +
 sys/contrib/dev/mediatek/mt76/mt7996/debugfs.c     |  971 +++++
 sys/contrib/dev/mediatek/mt76/mt7996/dma.c         |  442 +++
 sys/contrib/dev/mediatek/mt76/mt7996/eeprom.c      |  262 ++
 sys/contrib/dev/mediatek/mt76/mt7996/eeprom.h      |   74 +
 sys/contrib/dev/mediatek/mt76/mt7996/init.c        |  930 +++++
 sys/contrib/dev/mediatek/mt76/mt7996/mac.c         | 2546 +++++++++++++
 sys/contrib/dev/mediatek/mt76/mt7996/mac.h         |   45 +
 sys/contrib/dev/mediatek/mt76/mt7996/main.c        | 1418 ++++++++
 sys/contrib/dev/mediatek/mt76/mt7996/mcu.c         | 3809 ++++++++++++++++++++
 sys/contrib/dev/mediatek/mt76/mt7996/mcu.h         |  700 ++++
 sys/contrib/dev/mediatek/mt76/mt7996/mmio.c        |  398 ++
 sys/contrib/dev/mediatek/mt76/mt7996/mt7996.h      |  502 +++
 sys/contrib/dev/mediatek/mt76/mt7996/pci.c         |  245 ++
 sys/contrib/dev/mediatek/mt76/mt7996/regs.h        |  596 +++
 sys/contrib/dev/mediatek/mt76/sdio.c               |    6 +-
 sys/contrib/dev/mediatek/mt76/sdio_txrx.c          |    4 +
 sys/contrib/dev/mediatek/mt76/testmode.c           |    1 +
 sys/contrib/dev/mediatek/mt76/trace.h              |    2 +-
 sys/contrib/dev/mediatek/mt76/tx.c                 |   53 +-
 sys/contrib/dev/mediatek/mt76/usb.c                |   56 +-
 sys/contrib/dev/mediatek/mt76/usb_trace.h          |    2 +-
 sys/contrib/dev/mediatek/mt76/util.c               |   10 +-
 sys/contrib/dev/mediatek/mt76/util.h               |    9 +-
 sys/modules/mt76/Makefile                          |    1 +
 sys/modules/mt76/core/Makefile                     |   20 +-
 sys/modules/mt76/mt7915/Makefile                   |    8 +
 sys/modules/mt76/mt7921/Makefile                   |    5 +-
 sys/modules/mt76/mt7996/Makefile                   |   29 +
 140 files changed, 24081 insertions(+), 5451 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
index 2ff4f30aab5d..b0aec2d4afbd 100644
--- a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
+++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h
@@ -1,7 +1,7 @@
 /*-
  * SPDX-License-Identifier: BSD-2-Clause
  *
- * Copyright (c) 2022 Bjoern A. Zeeb
+ * Copyright (c) 2022-2023 Bjoern A. Zeeb
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -31,10 +31,17 @@
 struct mtk_wed_device {
 };
 
+#define	WED_WO_STA_REC	0x6
+
 #define	mtk_wed_device_start(_dev, _mask)		do { } while(0)
 #define	mtk_wed_device_detach(_dev)			do { } while(0)
 #define	mtk_wed_device_irq_get(_dev, _mask)		0
 #define	mtk_wed_device_irq_set_mask(_dev, _mask)	do { } while(0)
+#define	mtk_wed_device_update_msg(_dev, _id, _msg, _len)	(-ENODEV)
+#define	mtk_wed_device_dma_reset(_dev)			do {} while (0)
+#define	mtk_wed_device_ppe_check(_dev, _skb, _reason, _entry) \
+    do {} while (0)
+#define	mtk_wed_device_stop(_dev)			do { } while(0)
 
 static inline bool
 mtk_wed_device_active(struct mtk_wed_device *dev __unused)
@@ -43,4 +50,11 @@ mtk_wed_device_active(struct mtk_wed_device *dev __unused)
 	return (false);
 }
 
+static inline bool
+mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused)
+{
+
+	return (false);
+}
+
 #endif	/* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */
diff --git a/sys/contrib/dev/mediatek/mt76/debugfs.c b/sys/contrib/dev/mediatek/mt76/debugfs.c
index 47e9911ee9fe..57fbcc83e074 100644
--- a/sys/contrib/dev/mediatek/mt76/debugfs.c
+++ b/sys/contrib/dev/mediatek/mt76/debugfs.c
@@ -100,23 +100,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
 }
 EXPORT_SYMBOL_GPL(mt76_seq_puts_array);
 
-static int mt76_read_rate_txpower(struct seq_file *s, void *data)
-{
-	struct mt76_dev *dev = dev_get_drvdata(s->private);
-
-	mt76_seq_puts_array(s, "CCK", dev->rate_power.cck,
-			    ARRAY_SIZE(dev->rate_power.cck));
-	mt76_seq_puts_array(s, "OFDM", dev->rate_power.ofdm,
-			    ARRAY_SIZE(dev->rate_power.ofdm));
-	mt76_seq_puts_array(s, "STBC", dev->rate_power.stbc,
-			    ARRAY_SIZE(dev->rate_power.stbc));
-	mt76_seq_puts_array(s, "HT", dev->rate_power.ht,
-			    ARRAY_SIZE(dev->rate_power.ht));
-	mt76_seq_puts_array(s, "VHT", dev->rate_power.vht,
-			    ARRAY_SIZE(dev->rate_power.vht));
-	return 0;
-}
-
 struct dentry *
 mt76_register_debugfs_fops(struct mt76_phy *phy,
 			   const struct file_operations *ops)
@@ -129,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, &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,
@@ -137,8 +120,6 @@ mt76_register_debugfs_fops(struct mt76_phy *phy,
 	debugfs_create_blob("eeprom", 0400, dir, &dev->eeprom);
 	if (dev->otp.data)
 		debugfs_create_blob("otp", 0400, dir, &dev->otp);
-	debugfs_create_devm_seqfile(dev->dev, "rate_txpower", dir,
-				    mt76_read_rate_txpower);
 	debugfs_create_devm_seqfile(dev->dev, "rx-queues", dir,
 				    mt76_rx_queues_read);
 
diff --git a/sys/contrib/dev/mediatek/mt76/dma.c b/sys/contrib/dev/mediatek/mt76/dma.c
index dba7c323d205..eaa793e4b18e 100644
--- a/sys/contrib/dev/mediatek/mt76/dma.c
+++ b/sys/contrib/dev/mediatek/mt76/dma.c
@@ -6,6 +6,7 @@
 #include <linux/dma-mapping.h>
 #if defined(__FreeBSD__)
 #include <linux/cache.h>
+#include <net/page_pool.h>
 #endif
 #include "mt76.h"
 #include "dma.h"
@@ -62,6 +63,19 @@ mt76_alloc_txwi(struct mt76_dev *dev)
 	return t;
 }
 
+static struct mt76_txwi_cache *
+mt76_alloc_rxwi(struct mt76_dev *dev)
+{
+	struct mt76_txwi_cache *t;
+
+	t = kzalloc(L1_CACHE_ALIGN(sizeof(*t)), GFP_ATOMIC);
+	if (!t)
+		return NULL;
+
+	t->ptr = NULL;
+	return t;
+}
+
 static struct mt76_txwi_cache *
 __mt76_get_txwi(struct mt76_dev *dev)
 {
@@ -78,6 +92,22 @@ __mt76_get_txwi(struct mt76_dev *dev)
 	return t;
 }
 
+static struct mt76_txwi_cache *
+__mt76_get_rxwi(struct mt76_dev *dev)
+{
+	struct mt76_txwi_cache *t = NULL;
+
+	spin_lock(&dev->wed_lock);
+	if (!list_empty(&dev->rxwi_cache)) {
+		t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache,
+				     list);
+		list_del(&t->list);
+	}
+	spin_unlock(&dev->wed_lock);
+
+	return t;
+}
+
 static struct mt76_txwi_cache *
 mt76_get_txwi(struct mt76_dev *dev)
 {
@@ -89,6 +119,18 @@ mt76_get_txwi(struct mt76_dev *dev)
 	return mt76_alloc_txwi(dev);
 }
 
+struct mt76_txwi_cache *
+mt76_get_rxwi(struct mt76_dev *dev)
+{
+	struct mt76_txwi_cache *t = __mt76_get_rxwi(dev);
+
+	if (t)
+		return t;
+
+	return mt76_alloc_rxwi(dev);
+}
+EXPORT_SYMBOL_GPL(mt76_get_rxwi);
+
 void
 mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
 {
@@ -101,6 +143,18 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
 }
 EXPORT_SYMBOL_GPL(mt76_put_txwi);
 
+void
+mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
+{
+	if (!t)
+		return;
+
+	spin_lock(&dev->wed_lock);
+	list_add(&t->list, &dev->rxwi_cache);
+	spin_unlock(&dev->wed_lock);
+}
+EXPORT_SYMBOL_GPL(mt76_put_rxwi);
+
 static void
 mt76_free_pending_txwi(struct mt76_dev *dev)
 {
@@ -115,6 +169,21 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
 	local_bh_enable();
 }
 
+void
+mt76_free_pending_rxwi(struct mt76_dev *dev)
+{
+	struct mt76_txwi_cache *t;
+
+	local_bh_disable();
+	while ((t = __mt76_get_rxwi(dev)) != NULL) {
+		if (t->ptr)
+			mt76_put_page_pool_buf(t->ptr, false);
+		kfree(t);
+	}
+	local_bh_enable();
+}
+EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
+
 static void
 mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
 {
@@ -141,6 +210,51 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
 	mt76_dma_sync_idx(dev, q);
 }
 
+static int
+mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+		    struct mt76_queue_buf *buf, void *data)
+{
+	struct mt76_desc *desc = &q->desc[q->head];
+	struct mt76_queue_entry *entry = &q->entry[q->head];
+	struct mt76_txwi_cache *txwi = NULL;
+	u32 buf1 = 0, ctrl;
+	int idx = q->head;
+	int rx_token;
+
+	ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+
+	if (mt76_queue_is_wed_rx(q)) {
+		txwi = mt76_get_rxwi(dev);
+		if (!txwi)
+			return -ENOMEM;
+
+		rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
+		if (rx_token < 0) {
+			mt76_put_rxwi(dev, txwi);
+			return -ENOMEM;
+		}
+
+		buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token);
+		ctrl |= MT_DMA_CTL_TO_HOST;
+	}
+
+	WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr));
+	WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
+	WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
+	WRITE_ONCE(desc->info, 0);
+
+	entry->dma_addr[0] = buf->addr;
+	entry->dma_len[0] = buf->len;
+	entry->txwi = txwi;
+	entry->buf = data;
+	entry->wcid = 0xffff;
+	entry->skip_buf1 = true;
+	q->head = (q->head + 1) % q->ndesc;
+	q->queued++;
+
+	return idx;
+}
+
 static int
 mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
 		 struct mt76_queue_buf *buf, int nbufs, u32 info,
@@ -148,8 +262,8 @@ 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;
 
 	if (txwi) {
 		q->entry[q->head].txwi = DMA_DUMMY_DATA;
@@ -160,7 +274,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
 		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];
@@ -192,6 +306,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++;
 	}
 
@@ -275,33 +390,61 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
 
 static void *
 mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
-		 int *len, u32 *info, bool *more)
+		 int *len, u32 *info, bool *more, bool *drop)
 {
 	struct mt76_queue_entry *e = &q->entry[idx];
 	struct mt76_desc *desc = &q->desc[idx];
-	dma_addr_t buf_addr;
-	void *buf = e->buf;
-	int buf_len = SKB_WITH_OVERHEAD(q->buf_size);
+	void *buf;
 
-	buf_addr = e->dma_addr[0];
 	if (len) {
-		u32 ctl = le32_to_cpu(READ_ONCE(desc->ctrl));
-		*len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctl);
-		*more = !(ctl & MT_DMA_CTL_LAST_SEC0);
+		u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+		*len = FIELD_GET(MT_DMA_CTL_SD_LEN0, ctrl);
+		*more = !(ctrl & MT_DMA_CTL_LAST_SEC0);
 	}
 
 	if (info)
 		*info = le32_to_cpu(desc->info);
 
-	dma_unmap_single(dev->dma_dev, buf_addr, buf_len, DMA_FROM_DEVICE);
-	e->buf = NULL;
+	if (mt76_queue_is_wed_rx(q)) {
+		u32 buf1 = le32_to_cpu(desc->buf1);
+		u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
+		struct mt76_txwi_cache *t = mt76_rx_token_release(dev, token);
+
+		if (!t)
+			return NULL;
+
+		dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
+				SKB_WITH_OVERHEAD(q->buf_size),
+				page_pool_get_dma_dir(q->page_pool));
+
+		buf = t->ptr;
+		t->dma_addr = 0;
+		t->ptr = NULL;
+
+		mt76_put_rxwi(dev, t);
+
+		if (drop) {
+			u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+
+			*drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
+					   MT_DMA_CTL_DROP));
+
+			*drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
+		}
+	} else {
+		buf = e->buf;
+		e->buf = NULL;
+		dma_sync_single_for_cpu(dev->dma_dev, e->dma_addr[0],
+				SKB_WITH_OVERHEAD(q->buf_size),
+				page_pool_get_dma_dir(q->page_pool));
+	}
 
 	return buf;
 }
 
 static void *
 mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
-		 int *len, u32 *info, bool *more)
+		 int *len, u32 *info, bool *more, bool *drop)
 {
 	int idx = q->tail;
 
@@ -317,7 +460,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
 	q->tail = (q->tail + 1) % q->ndesc;
 	q->queued--;
 
-	return mt76_dma_get_buf(dev, q, idx, len, info, more);
+	return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
 }
 
 static int
@@ -327,6 +470,9 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
 	struct mt76_queue_buf buf = {};
 	dma_addr_t addr;
 
+	if (test_bit(MT76_MCU_RESET, &dev->phy.state))
+		goto error;
+
 	if (q->queued + 1 >= q->ndesc - 1)
 		goto error;
 
@@ -368,6 +514,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
 	dma_addr_t addr;
 	u8 *txwi;
 
+	if (test_bit(MT76_RESET, &dev->phy.state))
+		goto free_skb;
+
 	t = mt76_get_txwi(dev);
 	if (!t)
 		goto free_skb;
@@ -439,19 +588,19 @@ free:
 free_skb:
 	status.skb = tx_info.skb;
 	hw = mt76_tx_status_get_hw(dev, tx_info.skb);
+	spin_lock_bh(&dev->rx_lock);
 	ieee80211_tx_status_ext(hw, &status);
+	spin_unlock_bh(&dev->rx_lock);
 
 	return ret;
 }
 
 static int
-mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+		 bool allow_direct)
 {
-	dma_addr_t addr;
-	void *buf;
-	int frames = 0;
 	int len = SKB_WITH_OVERHEAD(q->buf_size);
-	int offset = q->buf_offset;
+	int frames = 0;
 
 	if (!q->ndesc)
 		return 0;
@@ -459,22 +608,27 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
 	spin_lock_bh(&q->lock);
 
 	while (q->queued < q->ndesc - 1) {
+		enum dma_data_direction dir;
 		struct mt76_queue_buf qbuf;
+		dma_addr_t addr;
+		int offset;
+		void *buf;
 
-		buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
+		buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
 		if (!buf)
 			break;
 
-		addr = dma_map_single(dev->dma_dev, buf, len, DMA_FROM_DEVICE);
-		if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
-			skb_free_frag(buf);
-			break;
-		}
+		addr = page_pool_get_dma_addr(virt_to_head_page(buf)) + offset;
+		dir = page_pool_get_dma_dir(q->page_pool);
+		dma_sync_single_for_device(dev->dma_dev, addr, len, dir);
 
-		qbuf.addr = addr + offset;
-		qbuf.len = len - offset;
+		qbuf.addr = addr + q->buf_offset;
+		qbuf.len = len - q->buf_offset;
 		qbuf.skip_unmap = false;
-		mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, NULL);
+		if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
+			mt76_put_page_pool_buf(buf, allow_direct);
+			break;
+		}
 		frames++;
 	}
 
@@ -486,14 +640,17 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
 	return frames;
 }
 
-static int
-mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
+int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
 {
 #ifdef CONFIG_NET_MEDIATEK_SOC_WED
 	struct mtk_wed_device *wed = &dev->mmio.wed;
 	int ret, type, ring;
-	u8 flags = q->flags;
+	u8 flags;
 
+	if (!q || !q->ndesc)
+		return -EINVAL;
+
+	flags = q->flags;
 	if (!mtk_wed_device_active(wed))
 		q->flags &= ~MT_QFLAG_WED;
 
@@ -505,7 +662,7 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
 
 	switch (type) {
 	case MT76_WED_Q_TX:
-		ret = mtk_wed_device_tx_ring_setup(wed, ring, q->regs);
+		ret = mtk_wed_device_tx_ring_setup(wed, ring, q->regs, reset);
 		if (!ret)
 			q->wed_regs = wed->tx_ring[ring].reg_base;
 		break;
@@ -513,13 +670,18 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
 		/* WED txfree queue needs ring to be initialized before setup */
 		q->flags = 0;
 		mt76_dma_queue_reset(dev, q);
-		mt76_dma_rx_fill(dev, q);
+		mt76_dma_rx_fill(dev, q, false);
 		q->flags = flags;
 
 		ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
 		if (!ret)
 			q->wed_regs = wed->txfree_ring.reg_base;
 		break;
+	case MT76_WED_Q_RX:
+		ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
+		if (!ret)
+			q->wed_regs = wed->rx_ring[ring].reg_base;
+		break;
 	default:
 		ret = -EINVAL;
 	}
@@ -529,6 +691,7 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
 	return 0;
 #endif
 }
+EXPORT_SYMBOL_GPL(mt76_dma_wed_setup);
 
 static int
 mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
@@ -559,7 +722,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
 	if (!q->entry)
 		return -ENOMEM;
 
-	ret = mt76_dma_wed_setup(dev, q);
+	ret = mt76_create_page_pool(dev, q);
+	if (ret)
+		return ret;
+
+	ret = mt76_dma_wed_setup(dev, q, false);
 	if (ret)
 		return ret;
 
@@ -572,7 +739,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
 static void
 mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
 {
-	struct page *page;
 	void *buf;
 	bool more;
 
@@ -580,21 +746,21 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
 		return;
 
 	spin_lock_bh(&q->lock);
+
 	do {
-		buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more);
+		buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more, NULL);
 		if (!buf)
 			break;
 
-		skb_free_frag(buf);
+		mt76_put_page_pool_buf(buf, false);
 	} while (1);
-	spin_unlock_bh(&q->lock);
 
-	if (!q->rx_page.va)
-		return;
+	if (q->rx_head) {
+		dev_kfree_skb(q->rx_head);
+		q->rx_head = NULL;
+	}
 
-	page = virt_to_page(q->rx_page.va);
-	__page_frag_cache_drain(page, q->rx_page.pagecnt_bias);
-	memset(&q->rx_page, 0, sizeof(q->rx_page));
+	spin_unlock_bh(&q->lock);
 }
 
 static void
@@ -610,19 +776,18 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
 		q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
 
 	mt76_dma_rx_cleanup(dev, q);
-	mt76_dma_sync_idx(dev, q);
-	mt76_dma_rx_fill(dev, q);
 
-	if (!q->rx_head)
-		return;
-
-	dev_kfree_skb(q->rx_head);
-	q->rx_head = NULL;
+	/* reset WED rx queues */
+	mt76_dma_wed_setup(dev, q, true);
+	if (q->flags != MT_WED_Q_TXFREE) {
+		mt76_dma_sync_idx(dev, q);
+		mt76_dma_rx_fill(dev, q, false);
+	}
 }
 
 static void
 mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
-		  int len, bool more)
+		  int len, bool more, u32 info)
 {
 	struct sk_buff *skb = q->rx_head;
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
@@ -638,7 +803,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
 
 		skb_add_rx_frag(skb, nr_frags, page, offset, len, q->buf_size);
 	} else {
-		skb_free_frag(data);
+		mt76_put_page_pool_buf(data, true);
 	}
 
 	if (more)
@@ -646,7 +811,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
 
 	q->rx_head = NULL;
 	if (nr_frags < ARRAY_SIZE(shinfo->frags))
-		dev->drv->rx_skb(dev, q - dev->q_rx, skb);
+		dev->drv->rx_skb(dev, q - dev->q_rx, skb, &info);
 	else
 		dev_kfree_skb(skb);
 }
@@ -667,6 +832,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 	}
 
 	while (done < budget) {
+		bool drop = false;
 		u32 info;
 
 		if (check_ddone) {
@@ -677,10 +843,14 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 				break;
 		}
 
-		data = mt76_dma_dequeue(dev, q, false, &len, &info, &more);
+		data = mt76_dma_dequeue(dev, q, false, &len, &info, &more,
+					&drop);
 		if (!data)
 			break;
 
+		if (drop)
+			goto free_frag;
+
 		if (q->rx_head)
 			data_len = q->buf_size;
 		else
@@ -693,7 +863,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 		}
 
 		if (q->rx_head) {
-			mt76_add_fragment(dev, q, data, len, more);
+			mt76_add_fragment(dev, q, data, len, more, info);
 			continue;
 		}
 
@@ -701,11 +871,12 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 		    !(dev->drv->rx_check(dev, data, len)))
 			goto free_frag;
 
-		skb = build_skb(data, q->buf_size);
+		skb = napi_build_skb(data, q->buf_size);
 		if (!skb)
 			goto free_frag;
 
 		skb_reserve(skb, q->buf_offset);
+		skb_mark_for_recycle(skb);
 
 		*(u32 *)skb->cb = info;
 
@@ -717,14 +888,14 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
 			continue;
 		}
 
-		dev->drv->rx_skb(dev, q - dev->q_rx, skb);
+		dev->drv->rx_skb(dev, q - dev->q_rx, skb, &info);
 		continue;
 
 free_frag:
-		skb_free_frag(data);
+		mt76_put_page_pool_buf(data, true);
 	}
 
-	mt76_dma_rx_fill(dev, q);
+	mt76_dma_rx_fill(dev, q, true);
 	return done;
 }
 
@@ -764,10 +935,12 @@ mt76_dma_init(struct mt76_dev *dev,
 	snprintf(dev->napi_dev.name, sizeof(dev->napi_dev.name), "%s",
 		 wiphy_name(dev->hw->wiphy));
 	dev->napi_dev.threaded = 1;
+	init_completion(&dev->mmio.wed_reset);
+	init_completion(&dev->mmio.wed_reset_complete);
 
 	mt76_for_each_q_rx(dev, i) {
 		netif_napi_add(&dev->napi_dev, &dev->napi[i], poll);
-		mt76_dma_rx_fill(dev, &dev->q_rx[i]);
+		mt76_dma_rx_fill(dev, &dev->q_rx[i], false);
 		napi_enable(&dev->napi[i]);
 	}
 
@@ -814,11 +987,16 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
 		mt76_dma_tx_cleanup(dev, dev->q_mcu[i], true);
 
 	mt76_for_each_q_rx(dev, i) {
+		struct mt76_queue *q = &dev->q_rx[i];
+
 		netif_napi_del(&dev->napi[i]);
-		mt76_dma_rx_cleanup(dev, &dev->q_rx[i]);
+		mt76_dma_rx_cleanup(dev, q);
+
+		page_pool_destroy(q->page_pool);
 	}
 
 	mt76_free_pending_txwi(dev);
+	mt76_free_pending_rxwi(dev);
 
 	if (mtk_wed_device_active(&dev->mmio.wed))
 		mtk_wed_device_detach(&dev->mmio.wed);
diff --git a/sys/contrib/dev/mediatek/mt76/dma.h b/sys/contrib/dev/mediatek/mt76/dma.h
index fdf786f975ea..1b090d78cd05 100644
--- a/sys/contrib/dev/mediatek/mt76/dma.h
+++ b/sys/contrib/dev/mediatek/mt76/dma.h
@@ -15,6 +15,15 @@
 #define MT_DMA_CTL_SD_LEN0		GENMASK(29, 16)
 #define MT_DMA_CTL_LAST_SEC0		BIT(30)
 #define MT_DMA_CTL_DMA_DONE		BIT(31)
+#define MT_DMA_CTL_TO_HOST		BIT(8)
+#define MT_DMA_CTL_TO_HOST_A		BIT(12)
+#define MT_DMA_CTL_DROP			BIT(14)
+#define MT_DMA_CTL_TOKEN		GENMASK(31, 16)
+#define MT_DMA_CTL_WO_DROP		BIT(8)
+
+#define MT_DMA_PPE_CPU_REASON		GENMASK(15, 11)
+#define MT_DMA_PPE_ENTRY		GENMASK(30, 16)
+#define MT_DMA_INFO_PPE_VLD		BIT(31)
 
 #define MT_DMA_HDR_LEN			4
 #define MT_RX_INFO_LEN			4
@@ -48,5 +57,6 @@ enum mt76_mcu_evt_type {
 int mt76_dma_rx_poll(struct napi_struct *napi, int budget);
 void mt76_dma_attach(struct mt76_dev *dev);
 void mt76_dma_cleanup(struct mt76_dev *dev);
+int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset);
 
 #endif
diff --git a/sys/contrib/dev/mediatek/mt76/eeprom.c b/sys/contrib/dev/mediatek/mt76/eeprom.c
index 77918f7f10b0..91483ad5fe79 100644
--- a/sys/contrib/dev/mediatek/mt76/eeprom.c
+++ b/sys/contrib/dev/mediatek/mt76/eeprom.c
@@ -7,35 +7,42 @@
 #include <linux/of_net.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
+#include <linux/nvmem-consumer.h>
 #endif
 #include <linux/etherdevice.h>
 #include "mt76.h"
 
-int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
+#if defined(CONFIG_OF)
+static int mt76_get_of_eeprom_data(struct mt76_dev *dev, void *eep, int len)
 {
-#if defined(CONFIG_OF) && defined(CONFIG_MTD)
 	struct device_node *np = dev->dev->of_node;
-	struct mtd_info *mtd;
-	const __be32 *list;
 	const void *data;
-	const char *part;
-	phandle phandle;
 	int size;
-	size_t retlen;
-	int ret;
 
-	if (!np)
+	data = of_get_property(np, "mediatek,eeprom-data", &size);
+	if (!data)
 		return -ENOENT;
 
-	data = of_get_property(np, "mediatek,eeprom-data", &size);
-	if (data) {
-		if (size > len)
-			return -EINVAL;
+	if (size > len)
+		return -EINVAL;
 
-		memcpy(eep, data, size);
+	memcpy(eep, data, size);
 
-		return 0;
-	}
+	return 0;
+}
+#endif
+
+#if defined(CONFIG_MTD) && defined(CONFIG_OF)
+static int mt76_get_of_epprom_from_mtd(struct mt76_dev *dev, void *eep, int offset, int len)
+{
+	struct device_node *np = dev->dev->of_node;
+	struct mtd_info *mtd;
+	const __be32 *list;
+	const char *part;
+	phandle phandle;
+	size_t retlen;
+	int size;
+	int ret;
 
 	list = of_get_property(np, "mediatek,mtd-eeprom", &size);
 	if (!list)
@@ -98,6 +105,60 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
 out_put_node:
 	of_node_put(np);
 	return ret;
+}
+#endif
+
+#if defined(CONFIG_OF)
+static int mt76_get_of_epprom_from_nvmem(struct mt76_dev *dev, void *eep, int len)
+{
+	struct device_node *np = dev->dev->of_node;
+	struct nvmem_cell *cell;
+	const void *data;
+	size_t retlen;
+	int ret = 0;
+
+	cell = of_nvmem_cell_get(np, "eeprom");
+	if (IS_ERR(cell))
+		return PTR_ERR(cell);
+
+	data = nvmem_cell_read(cell, &retlen);
+	nvmem_cell_put(cell);
+
+	if (IS_ERR(data))
+		return PTR_ERR(data);
+
+	if (retlen < len) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	memcpy(eep, data, len);
*** 37779 LINES SKIPPED ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202308210136.37L1aqXB038414>