The branch main has been updated by bz:

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

commit cbb3ec25236ba72f91cbdf23f8b78b9d1af0cedf
Author:     Bjoern A. Zeeb <[email protected]>
AuthorDate: 2023-05-23 23:03:09 +0000
Commit:     Bjoern A. Zeeb <[email protected]>
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 ***


Reply via email to