Merge "[AUTO00246924][rdkb][common][app][add uci cmd for he_bss_color, transmit_power]"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch
deleted file mode 100644
index 3292a6b..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 051e070d0a019df6be9e21be1fb63352e4c4412e Mon Sep 17 00:00:00 2001
-From: YouChing Lin <ycllin@mxic.com.tw>
-Date: Wed, 22 Jul 2020 16:02:57 +0800
-Subject: [PATCH] mtd: spinand: macronix: Add support for MX31LF1GE4BC
-
-The Macronix MX31LF1GE4BC is a 3V, 1Gbit (128MB) serial
-NAND flash device.
-
-Validated by read, erase, read back, write and read back
-on Xilinx Zynq PicoZed FPGA board which included
-Macronix SPI Host (driver/spi/spi-mxic.c).
-
-Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/1595404978-31079-2-git-send-email-ycllin@mxic.com.tw
----
- drivers/mtd/nand/spi/macronix.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
-index 9ff8debd599418..9ae48ce1c46f91 100644
---- a/drivers/mtd/nand/spi/macronix.c
-+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -119,6 +119,16 @@ static const struct spinand_info macronix_spinand_table[] = {
- &update_cache_variants),
- SPINAND_HAS_QE_BIT,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
-+ SPINAND_INFO("MX31LF1GE4BC",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0 /*SPINAND_HAS_QE_BIT*/,
-+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
-+ mx35lf1ge4ab_ecc_get_status)),
- };
-
- static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch
deleted file mode 100644
index 9f48d4a..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 75b049bb7f89a58a25592f17baf91d703f0f548e Mon Sep 17 00:00:00 2001
-From: YouChing Lin <ycllin@mxic.com.tw>
-Date: Wed, 22 Jul 2020 16:02:58 +0800
-Subject: [PATCH] mtd: spinand: macronix: Add support for MX31UF1GE4BC
-
-The Macronix MX31UF1GE4BC is a 1.8V, 1Gbit (128MB) serial
-NAND flash device.
-
-Validated by read, erase, read back, write and read back
-on Xilinx Zynq PicoZed FPGA board which included
-Macronix SPI Host (driver/spi/spi-mxic.c).
-
-Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/1595404978-31079-3-git-send-email-ycllin@mxic.com.tw
----
- drivers/mtd/nand/spi/macronix.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
-index 9ae48ce1c46f91..8e801e4c3a006f 100644
---- a/drivers/mtd/nand/spi/macronix.c
-+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -129,6 +129,16 @@ static const struct spinand_info macronix_spinand_table[] = {
- 0 /*SPINAND_HAS_QE_BIT*/,
- SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
- mx35lf1ge4ab_ecc_get_status)),
-+ SPINAND_INFO("MX31UF1GE4BC",
-+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
-+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-+ NAND_ECCREQ(8, 512),
-+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-+ &write_cache_variants,
-+ &update_cache_variants),
-+ 0 /*SPINAND_HAS_QE_BIT*/,
-+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
-+ mx35lf1ge4ab_ecc_get_status)),
- };
-
- static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch
deleted file mode 100644
index 31141db..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 8511a3a9937e30949b34bea46c3dc3f65d11034b Mon Sep 17 00:00:00 2001
-From: Shivamurthy Shastri <sshivamurthy@micron.com>
-Date: Wed, 11 Mar 2020 18:57:31 +0100
-Subject: [PATCH] mtd: spinand: micron: Describe the SPI NAND device
- MT29F2G01ABAGD
-
-Add the SPI NAND device MT29F2G01ABAGD series number, size and voltage
-details as a comment.
-
-Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
-Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-3-sshivamurthy@micron.com
----
- drivers/mtd/nand/spi/micron.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index cc1ee68421c8e1..4727933c894bc8 100644
---- a/drivers/mtd/nand/spi/micron.c
-+++ b/drivers/mtd/nand/spi/micron.c
-@@ -91,6 +91,7 @@ static int micron_8_ecc_get_status(struct spinand_device *spinand,
- }
-
- static const struct spinand_info micron_spinand_table[] = {
-+ /* M79A 2Gb 3.3V */
- SPINAND_INFO("MT29F2G01ABAGD",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
- NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch
deleted file mode 100644
index 59a4234..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From 0bc68af9137dc3f30b161de4ce546c7799f88d1e Mon Sep 17 00:00:00 2001
-From: Shivamurthy Shastri <sshivamurthy@micron.com>
-Date: Wed, 11 Mar 2020 18:57:33 +0100
-Subject: [PATCH] mtd: spinand: micron: identify SPI NAND device with
- Continuous Read mode
-
-Add SPINAND_HAS_CR_FEAT_BIT flag to identify the SPI NAND device with
-the Continuous Read mode.
-
-Some of the Micron SPI NAND devices have the "Continuous Read" feature
-enabled by default, which does not fit the subsystem needs.
-
-In this mode, the READ CACHE command doesn't require the starting column
-address. The device always output the data starting from the first
-column of the cache register, and once the end of the cache register
-reached, the data output continues through the next page. With the
-continuous read mode, it is possible to read out the entire block using
-a single READ command, and once the end of the block reached, the output
-pins become High-Z state. However, during this mode the read command
-doesn't output the OOB area.
-
-Hence, we disable the feature at probe time.
-
-Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
-Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-5-sshivamurthy@micron.com
----
- drivers/mtd/nand/spi/micron.c | 16 ++++++++++++++++
- include/linux/mtd/spinand.h | 1 +
- 2 files changed, 17 insertions(+)
-
-diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index 26925714a9fbac..956f7710aca263 100644
---- a/drivers/mtd/nand/spi/micron.c
-+++ b/drivers/mtd/nand/spi/micron.c
-@@ -18,6 +18,8 @@
- #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
- #define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
-
-+#define MICRON_CFG_CR BIT(0)
-+
- static SPINAND_OP_VARIANTS(read_cache_variants,
- SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
- SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-@@ -137,7 +139,21 @@ static const struct spinand_info micron_spinand_table[] = {
- micron_8_ecc_get_status)),
- };
-
-+static int micron_spinand_init(struct spinand_device *spinand)
-+{
-+ /*
-+ * M70A device series enable Continuous Read feature at Power-up,
-+ * which is not supported. Disable this bit to avoid any possible
-+ * failure.
-+ */
-+ if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT)
-+ return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0);
-+
-+ return 0;
-+}
-+
- static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
-+ .init = micron_spinand_init,
- };
-
- const struct spinand_manufacturer micron_spinand_manufacturer = {
-diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
-index f4c4ae87181b27..1077c45721ff25 100644
---- a/include/linux/mtd/spinand.h
-+++ b/include/linux/mtd/spinand.h
-@@ -284,6 +284,7 @@ struct spinand_ecc_info {
- };
-
- #define SPINAND_HAS_QE_BIT BIT(0)
-+#define SPINAND_HAS_CR_FEAT_BIT BIT(1)
-
- /**
- * struct spinand_info - Structure used to describe SPI NAND chips
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/790-v5.7-iopoll-introduce-read_poll_timeout-macro.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/790-v5.7-iopoll-introduce-read_poll_timeout-macro.patch
deleted file mode 100644
index 26de067..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/790-v5.7-iopoll-introduce-read_poll_timeout-macro.patch
+++ /dev/null
@@ -1,269 +0,0 @@
-From patchwork Mon Mar 23 15:05:51 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Dejin Zheng <zhengdejin5@gmail.com>
-X-Patchwork-Id: 1260097
-X-Patchwork-Delegate: davem@davemloft.net
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Original-To: patchwork-incoming-netdev@ozlabs.org
-Delivered-To: patchwork-incoming-netdev@ozlabs.org
-Authentication-Results: ozlabs.org; spf=none (no SPF record)
- smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67;
- helo=vger.kernel.org;
- envelope-from=netdev-owner@vger.kernel.org;
- receiver=<UNKNOWN>)
-Authentication-Results: ozlabs.org;
- dmarc=pass (p=none dis=none) header.from=gmail.com
-Authentication-Results: ozlabs.org; dkim=pass (2048-bit key;
- unprotected) header.d=gmail.com header.i=@gmail.com
- header.a=rsa-sha256 header.s=20161025 header.b=N1ACwCYl;
- dkim-atps=neutral
-Received: from vger.kernel.org (vger.kernel.org [209.132.180.67])
- by ozlabs.org (Postfix) with ESMTP id 48mHlP3Hzhz9sSs
- for <patchwork-incoming-netdev@ozlabs.org>;
- Tue, 24 Mar 2020 02:06:25 +1100 (AEDT)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S1727267AbgCWPGW (ORCPT
- <rfc822;patchwork-incoming-netdev@ozlabs.org>);
- Mon, 23 Mar 2020 11:06:22 -0400
-Received: from mail-pj1-f68.google.com ([209.85.216.68]:50286 "EHLO
- mail-pj1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S1727024AbgCWPGV (ORCPT
- <rfc822;netdev@vger.kernel.org>); Mon, 23 Mar 2020 11:06:21 -0400
-Received: by mail-pj1-f68.google.com with SMTP id v13so6312358pjb.0;
- Mon, 23 Mar 2020 08:06:20 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=gmail.com; s=20161025;
- h=from:to:cc:subject:date:message-id:in-reply-to:references
- :mime-version:content-transfer-encoding;
- bh=GmXKgcJDZee4jC3cNKHKWCJhJ0kS9L2vONq2fIA+AaY=;
- b=N1ACwCYlon7WkTCOGFsGWeQq6lNeUjbuQa8UGIBK7O82wFqYoTVzGY8MUnU/tEjer9
- AtZt9996i6pDsvhpbunlFffuKPui1YOisSe6Xcn6Ur2AiFvfJr1DMpWE2PdmlLGH2bkH
- /Oiqbikpi9dSUfgFJ7JfIyISqKyP15jsdhhl8xtA30gWb6CuhlhBuWuLV5CqTAZKGWab
- LMFipg2GDKlx0udJoUoNAPi/hcypdWJW8DtamDxwH/OmZk2evJsfhm2MwG/1qAb95nJ0
- rU/60e4BhqadPHfO9cyvgdbR+xcCJkuSIqKWH6utfd9RamZDS2djU3XDWhFW2blmcVLb
- Ue5w==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20161025;
- h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to
- :references:mime-version:content-transfer-encoding;
- bh=GmXKgcJDZee4jC3cNKHKWCJhJ0kS9L2vONq2fIA+AaY=;
- b=AwMmzIpdEKD6duSw3Dl9aQkzxRMmPOysumBp0nIE9FvhZJ+67auGBvMa7G80/DyF4x
- BbrwsUrYoDLXs7fuLEjjZgxKwSCtYfWyPDdM/ezShIx9KZIfPiXhn6uH3eXP+g4feJN4
- IlWVwvJMDzRJOhdZVzg934FJeMs4bW7XNm07jKxjsqksHGcw5JoHsP53xNegPbIpNb8X
- h7+AwHXYAKzVC9aGYTA8bgxSD0d+SlO7CJ4nY+lHXcBR266/rt7rDFOwCdv9TUUAMCkY
- rXrgSb8vThpKY/wZ8rK3SyJcPdvDt6TnmdZO7LqTbbzAHjzJml7s+5vYhk3CSOvjGTHt
- KcMA==
-X-Gm-Message-State: ANhLgQ1lOBl50y5dc6fz/BIFJrpgXnM0GF/1DvoZm8oJbZIt2H9n38WA
- pBi6LVse2n2Ed5tvz68N8x8=
-X-Google-Smtp-Source:
- ADFU+vtPoQt/0UFiy7Bq0L9uIMvQbBOJzH8+jTojBCcjj2V26XqJvxqSMSsy9g8ZZ96F/Q8I4cpXYw==
-X-Received: by 2002:a17:902:9a09:: with SMTP id
- v9mr21358610plp.341.1584975980336;
- Mon, 23 Mar 2020 08:06:20 -0700 (PDT)
-Received: from localhost (176.122.158.203.16clouds.com. [176.122.158.203])
- by smtp.gmail.com with ESMTPSA id
- j19sm13485589pfe.102.2020.03.23.08.06.19
- (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);
- Mon, 23 Mar 2020 08:06:19 -0700 (PDT)
-From: Dejin Zheng <zhengdejin5@gmail.com>
-To: andrew@lunn.ch, f.fainelli@gmail.com, hkallweit1@gmail.com,
- linux@armlinux.org.uk, davem@davemloft.net, corbet@lwn.net,
- tglx@linutronix.de, gregkh@linuxfoundation.org,
- allison@lohutok.net, mchehab+samsung@kernel.org, netdev@vger.kernel.org
-Cc: linux-kernel@vger.kernel.org, Dejin Zheng <zhengdejin5@gmail.com>
-Subject: [PATCH net-next v7 01/10] iopoll: introduce read_poll_timeout macro
-Date: Mon, 23 Mar 2020 23:05:51 +0800
-Message-Id: <20200323150600.21382-2-zhengdejin5@gmail.com>
-X-Mailer: git-send-email 2.25.0
-In-Reply-To: <20200323150600.21382-1-zhengdejin5@gmail.com>
-References: <20200323150600.21382-1-zhengdejin5@gmail.com>
-MIME-Version: 1.0
-Sender: netdev-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-
-this macro is an extension of readx_poll_timeout macro. the accessor
-function op just supports only one parameter in the readx_poll_timeout
-macro, but this macro can supports multiple variable parameters for
-it. so functions like phy_read(struct phy_device *phydev, u32 regnum)
-and phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum) can
-also use this poll timeout core. and also expand it can sleep some time
-before read operation.
-
-Signed-off-by: Dejin Zheng <zhengdejin5@gmail.com>
----
-v6 -> v7:
- - add a parameter sleep_before_read to support that it can sleep
- some time before read operation in read_poll_timeout macro.
-v5 -> v6:
- - no changed
-v4 -> v5:
- - no changed
-v3 -> v4:
- - no changed
-v2 -> v3:
- - no changed
-v1 -> v2:
- - no changed
-
- include/linux/iopoll.h | 44 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 44 insertions(+)
-
---- a/include/linux/iopoll.h
-+++ b/include/linux/iopoll.h
-@@ -14,36 +14,41 @@
- #include <linux/io.h>
-
- /**
-- * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
-- * @op: accessor function (takes @addr as its only argument)
-- * @addr: Address to poll
-+ * read_poll_timeout - Periodically poll an address until a condition is
-+ * met or a timeout occurs
-+ * @op: accessor function (takes @args as its arguments)
- * @val: Variable to read the value into
- * @cond: Break condition (usually involving @val)
- * @sleep_us: Maximum time to sleep between reads in us (0
- * tight-loops). Should be less than ~20ms since usleep_range
- * is used (see Documentation/timers/timers-howto.rst).
- * @timeout_us: Timeout in us, 0 means never timeout
-+ * @sleep_before_read: if it is true, sleep @sleep_us before read.
-+ * @args: arguments for @op poll
- *
- * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
-- * case, the last read value at @addr is stored in @val. Must not
-+ * case, the last read value at @args is stored in @val. Must not
- * be called from atomic context if sleep_us or timeout_us are used.
- *
- * When available, you'll probably want to use one of the specialized
- * macros defined below rather than this macro directly.
- */
--#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
-+#define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \
-+ sleep_before_read, args...) \
- ({ \
- u64 __timeout_us = (timeout_us); \
- unsigned long __sleep_us = (sleep_us); \
- ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
- might_sleep_if((__sleep_us) != 0); \
-+ if (sleep_before_read && __sleep_us) \
-+ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
- for (;;) { \
-- (val) = op(addr); \
-+ (val) = op(args); \
- if (cond) \
- break; \
- if (__timeout_us && \
- ktime_compare(ktime_get(), __timeout) > 0) { \
-- (val) = op(addr); \
-+ (val) = op(args); \
- break; \
- } \
- if (__sleep_us) \
-@@ -53,6 +58,27 @@
- })
-
- /**
-+ * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
-+ * @op: accessor function (takes @addr as its only argument)
-+ * @addr: Address to poll
-+ * @val: Variable to read the value into
-+ * @cond: Break condition (usually involving @val)
-+ * @sleep_us: Maximum time to sleep between reads in us (0
-+ * tight-loops). Should be less than ~20ms since usleep_range
-+ * is used (see Documentation/timers/timers-howto.rst).
-+ * @timeout_us: Timeout in us, 0 means never timeout
-+ *
-+ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
-+ * case, the last read value at @addr is stored in @val. Must not
-+ * be called from atomic context if sleep_us or timeout_us are used.
-+ *
-+ * When available, you'll probably want to use one of the specialized
-+ * macros defined below rather than this macro directly.
-+ */
-+#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
-+ read_poll_timeout(op, val, cond, sleep_us, timeout_us, false, addr)
-+
-+/**
- * readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs
- * @op: accessor function (takes @addr as its only argument)
- * @addr: Address to poll
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -21,6 +21,7 @@
- #include <linux/timer.h>
- #include <linux/workqueue.h>
- #include <linux/mod_devicetable.h>
-+#include <linux/iopoll.h>
-
- #include <linux/atomic.h>
-
-@@ -714,6 +715,19 @@ static inline int phy_read(struct phy_de
- return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
- }
-
-+#define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \
-+ timeout_us, sleep_before_read) \
-+({ \
-+ int __ret = read_poll_timeout(phy_read, val, (cond) || val < 0, \
-+ sleep_us, timeout_us, sleep_before_read, phydev, regnum); \
-+ if (val < 0) \
-+ __ret = val; \
-+ if (__ret) \
-+ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
-+ __ret; \
-+})
-+
-+
- /**
- * __phy_read - convenience function for reading a given PHY register
- * @phydev: the phy_device struct
-@@ -766,6 +780,19 @@ static inline int __phy_write(struct phy
- */
- int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
-
-+#define phy_read_mmd_poll_timeout(phydev, devaddr, regnum, val, cond, \
-+ sleep_us, timeout_us, sleep_before_read) \
-+({ \
-+ int __ret = read_poll_timeout(phy_read_mmd, val, (cond) || val < 0, \
-+ sleep_us, timeout_us, sleep_before_read, \
-+ phydev, devaddr, regnum); \
-+ if (val < 0) \
-+ __ret = val; \
-+ if (__ret) \
-+ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
-+ __ret; \
-+})
-+
- /**
- * __phy_read_mmd - Convenience function for reading a register
- * from an MMD on a given PHY.
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -1056,18 +1056,12 @@ EXPORT_SYMBOL(phy_disconnect);
- static int phy_poll_reset(struct phy_device *phydev)
- {
- /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
-- unsigned int retries = 12;
-- int ret;
--
-- do {
-- msleep(50);
-- ret = phy_read(phydev, MII_BMCR);
-- if (ret < 0)
-- return ret;
-- } while (ret & BMCR_RESET && --retries);
-- if (ret & BMCR_RESET)
-- return -ETIMEDOUT;
-+ int ret, val;
-
-+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
-+ 50000, 600000, true);
-+ if (ret)
-+ return ret;
- /* Some chips (smsc911x) may still need up to another 1ms after the
- * BMCR_RESET bit is cleared before they are usable.
- */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/792-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/792-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch
deleted file mode 100644
index 39b29ad..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/792-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch
+++ /dev/null
@@ -1,109 +0,0 @@
-From patchwork Tue Jun 23 14:30:07 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Antoine Tenart <antoine.tenart@bootlin.com>
-X-Patchwork-Id: 1315292
-X-Patchwork-Delegate: davem@davemloft.net
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Original-To: patchwork-incoming-netdev@ozlabs.org
-Delivered-To: patchwork-incoming-netdev@ozlabs.org
-Authentication-Results: ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org
- (client-ip=23.128.96.18; helo=vger.kernel.org;
- envelope-from=netdev-owner@vger.kernel.org; receiver=<UNKNOWN>)
-Authentication-Results: ozlabs.org;
- dmarc=none (p=none dis=none) header.from=bootlin.com
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by ozlabs.org (Postfix) with ESMTP id 49rpjP0BTdz9sRN
- for <patchwork-incoming-netdev@ozlabs.org>;
- Wed, 24 Jun 2020 00:35:37 +1000 (AEST)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S1732957AbgFWOf1 (ORCPT
- <rfc822;patchwork-incoming-netdev@ozlabs.org>);
- Tue, 23 Jun 2020 10:35:27 -0400
-Received: from relay3-d.mail.gandi.net ([217.70.183.195]:35381 "EHLO
- relay3-d.mail.gandi.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S1732900AbgFWOfX (ORCPT
- <rfc822;netdev@vger.kernel.org>); Tue, 23 Jun 2020 10:35:23 -0400
-X-Originating-IP: 90.76.143.236
-Received: from localhost (lfbn-tou-1-1075-236.w90-76.abo.wanadoo.fr
- [90.76.143.236])
- (Authenticated sender: antoine.tenart@bootlin.com)
- by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 38BE860006;
- Tue, 23 Jun 2020 14:35:19 +0000 (UTC)
-From: Antoine Tenart <antoine.tenart@bootlin.com>
-To: davem@davemloft.net, andrew@lunn.ch, f.fainelli@gmail.com,
- hkallweit1@gmail.com, richardcochran@gmail.com,
- alexandre.belloni@bootlin.com, UNGLinuxDriver@microchip.com
-Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
- thomas.petazzoni@bootlin.com, allan.nielsen@microchip.com,
- foss@0leil.net, antoine.tenart@bootlin.com
-Subject: [PATCH net-next v4 1/8] net: phy: add support for a common probe
- between shared PHYs
-Date: Tue, 23 Jun 2020 16:30:07 +0200
-Message-Id: <20200623143014.47864-2-antoine.tenart@bootlin.com>
-X-Mailer: git-send-email 2.26.2
-In-Reply-To: <20200623143014.47864-1-antoine.tenart@bootlin.com>
-References: <20200623143014.47864-1-antoine.tenart@bootlin.com>
-MIME-Version: 1.0
-Sender: netdev-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-
-Shared PHYs (PHYs in the same hardware package) may have shared
-registers and their drivers would usually need to share information.
-There is currently a way to have a shared (part of the) init, by using
-phy_package_init_once(). This patch extends the logic to share parts of
-the probe to allow sharing the initialization of locks or resources
-retrieval.
-
-Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
----
- include/linux/phy.h | 18 +++++++++++++++---
- 1 file changed, 15 insertions(+), 3 deletions(-)
-
-diff --git a/include/linux/phy.h b/include/linux/phy.h
-index 9248dd2ce4ca..457489f1951c 100644
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -244,7 +244,8 @@ struct phy_package_shared {
- };
-
- /* used as bit number in atomic bitops */
--#define PHY_SHARED_F_INIT_DONE 0
-+#define PHY_SHARED_F_INIT_DONE 0
-+#define PHY_SHARED_F_PROBE_DONE 1
-
- /*
- * The Bus class for PHYs. Devices which provide access to
-@@ -1558,14 +1559,25 @@ static inline int __phy_package_write(struct phy_device *phydev,
- return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val);
- }
-
--static inline bool phy_package_init_once(struct phy_device *phydev)
-+static inline bool __phy_package_set_once(struct phy_device *phydev,
-+ unsigned int b)
- {
- struct phy_package_shared *shared = phydev->shared;
-
- if (!shared)
- return false;
-
-- return !test_and_set_bit(PHY_SHARED_F_INIT_DONE, &shared->flags);
-+ return !test_and_set_bit(b, &shared->flags);
-+}
-+
-+static inline bool phy_package_init_once(struct phy_device *phydev)
-+{
-+ return __phy_package_set_once(phydev, PHY_SHARED_F_INIT_DONE);
-+}
-+
-+static inline bool phy_package_probe_once(struct phy_device *phydev)
-+{
-+ return __phy_package_set_once(phydev, PHY_SHARED_F_PROBE_DONE);
- }
-
- extern struct bus_type mdio_bus_type;
\ No newline at end of file
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2210-v6.1-iio-adc-add-rtq6056-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2210-v6.1-iio-adc-add-rtq6056-support.patch
new file mode 100644
index 0000000..ce35b7a
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2210-v6.1-iio-adc-add-rtq6056-support.patch
@@ -0,0 +1,708 @@
+From 37b0b79827edbd5c312aa546a1fe148bda616e30 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Wed, 31 May 2023 19:53:09 +0800
+Subject: [PATCH] iio: adc: Add rtq6056 support
+
+---
+ drivers/iio/adc/Kconfig | 15 +
+ drivers/iio/adc/Makefile | 1 +
+ drivers/iio/adc/rtq6056.c | 649 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 665 insertions(+)
+ create mode 100644 drivers/iio/adc/rtq6056.c
+
+diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
+index cb57880..7457a53 100644
+--- a/drivers/iio/adc/Kconfig
++++ b/drivers/iio/adc/Kconfig
+@@ -746,6 +746,21 @@ config ROCKCHIP_SARADC
+ To compile this driver as a module, choose M here: the
+ module will be called rockchip_saradc.
+
++config RICHTEK_RTQ6056
++ tristate "Richtek RTQ6056 Current and Power Monitor ADC"
++ depends on I2C
++ select REGMAP_I2C
++ select IIO_BUFFER
++ select IIO_TRIGGERED_BUFFER
++ help
++ Say yes here to enable RQT6056 ADC support.
++ RTQ6056 is a high accuracy current-sense monitor with I2C and SMBus
++ compatible interface, and the device provides full information for
++ system by reading out the load current and power.
++
++ This driver can also be built as a module. If so, the module will be
++ called rtq6056.
++
+ config SC27XX_ADC
+ tristate "Spreadtrum SC27xx series PMICs ADC"
+ depends on MFD_SC27XX_PMIC || COMPILE_TEST
+diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
+index ef9cc48..6a4ac1b 100644
+--- a/drivers/iio/adc/Makefile
++++ b/drivers/iio/adc/Makefile
+@@ -59,6 +59,7 @@ obj-$(CONFIG_MCP3911) += mcp3911.o
+ obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
+ obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
+ obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
++obj-$(CONFIG_RICHTEK_RTQ6056) += rtq6056.o
+ obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o
+ obj-$(CONFIG_NAU7802) += nau7802.o
+ obj-$(CONFIG_NPCM_ADC) += npcm_adc.o
+diff --git a/drivers/iio/adc/rtq6056.c b/drivers/iio/adc/rtq6056.c
+new file mode 100644
+index 0000000..962058e
+--- /dev/null
++++ b/drivers/iio/adc/rtq6056.c
+@@ -0,0 +1,649 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2022 Richtek Technology Corp.
++ *
++ * ChiYuan Huang <cy_huang@richtek.com>
++ */
++
++#include <linux/bitops.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/kernel.h>
++#include <linux/mod_devicetable.h>
++#include <linux/module.h>
++#include <linux/pm_runtime.h>
++#include <linux/property.h>
++#include <linux/regmap.h>
++#include <linux/sysfs.h>
++#include <linux/types.h>
++#include <linux/util_macros.h>
++
++#include <linux/iio/buffer.h>
++#include <linux/iio/iio.h>
++#include <linux/iio/driver.h>
++#include <linux/iio/machine.h>
++#include <linux/iio/sysfs.h>
++#include <linux/iio/trigger_consumer.h>
++#include <linux/iio/triggered_buffer.h>
++
++#define RTQ6056_REG_CONFIG 0x00
++#define RTQ6056_REG_SHUNTVOLT 0x01
++#define RTQ6056_REG_BUSVOLT 0x02
++#define RTQ6056_REG_POWER 0x03
++#define RTQ6056_REG_CURRENT 0x04
++#define RTQ6056_REG_CALIBRATION 0x05
++#define RTQ6056_REG_MASKENABLE 0x06
++#define RTQ6056_REG_ALERTLIMIT 0x07
++#define RTQ6056_REG_MANUFACTID 0xFE
++#define RTQ6056_REG_DIEID 0xFF
++
++#define RTQ6056_MAX_CHANNEL 4
++#define RTQ6056_VENDOR_ID 0x1214
++#define RTQ6056_DEFAULT_CONFIG 0x4127
++#define RTQ6056_CONT_ALLON 7
++
++#define RTQ6056_CONFIG_OPMODE_MASK GENMASK(2, 0)
++#define RTQ6056_CONFIG_OPMODE(x) ((x << 0) & RTQ6056_CONFIG_OPMODE_MASK)
++#define RTQ6056_CONFIG_VSHUNTCT_MASK GENMASK(5, 3)
++#define RTQ6056_CONFIG_VSHUNTCT(x) ((x << 3) & \
++ RTQ6056_CONFIG_VSHUNTCT_MASK)
++#define RTQ6056_CONFIG_VBUSCT_MASK GENMASK(8, 6)
++#define RTQ6056_CONFIG_VBUSCT(x) ((x << 6) & RTQ6056_CONFIG_VBUSCT_MASK)
++#define RTQ6056_CONFIG_AVG_MASK GENMASK(11, 9)
++#define RTQ6056_CONFIG_AVG(x) ((x << 9) & RTQ6056_CONFIG_AVG_MASK)
++#define RTQ6056_CONFIG_RESET_MASK GENMASK(15, 15)
++#define RTQ6056_CONFIG_RESET(x) ((x << 15) & RTQ6056_CONFIG_RESET_MASK)
++
++struct rtq6056_priv {
++ struct device *dev;
++ struct regmap *regmap;
++ u32 shunt_resistor_uohm;
++ int vshuntct_us;
++ int vbusct_us;
++ int avg_sample;
++};
++
++static struct iio_map rtq6056_maps[] = {
++ {
++ .consumer_dev_name = "voltage0",
++ .consumer_channel = "voltage0",
++ .adc_channel_label = "Vshunt",
++ }, {
++ .consumer_dev_name = "voltage1",
++ .consumer_channel = "voltage1",
++ .adc_channel_label = "Vbus",
++ }, {
++ .consumer_dev_name = "power2",
++ .consumer_channel = "power2",
++ .adc_channel_label = "Power",
++ }, {
++ .consumer_dev_name = "current3",
++ .consumer_channel = "current3",
++ .adc_channel_label = "Current",
++ }, { /* sentinel */ }
++};
++
++static const struct iio_chan_spec rtq6056_channels[RTQ6056_MAX_CHANNEL + 1] = {
++ {
++ .type = IIO_VOLTAGE,
++ .indexed = 1,
++ .channel = 0,
++ .address = RTQ6056_REG_SHUNTVOLT,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
++ BIT(IIO_CHAN_INFO_SCALE) |
++ BIT(IIO_CHAN_INFO_SAMP_FREQ),
++ .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
++ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .scan_index = 0,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .endianness = IIO_CPU,
++ },
++ .datasheet_name = "voltage0",
++ },
++ {
++ .type = IIO_VOLTAGE,
++ .indexed = 1,
++ .channel = 1,
++ .address = RTQ6056_REG_BUSVOLT,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
++ BIT(IIO_CHAN_INFO_SCALE) |
++ BIT(IIO_CHAN_INFO_SAMP_FREQ),
++ .info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
++ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .scan_index = 1,
++ .scan_type = {
++ .sign = 'u',
++ .realbits = 16,
++ .storagebits = 16,
++ .endianness = IIO_CPU,
++ },
++ .datasheet_name = "voltage1",
++ },
++ {
++ .type = IIO_POWER,
++ .indexed = 1,
++ .channel = 2,
++ .address = RTQ6056_REG_POWER,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
++ BIT(IIO_CHAN_INFO_SCALE) |
++ BIT(IIO_CHAN_INFO_SAMP_FREQ),
++ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .scan_index = 2,
++ .scan_type = {
++ .sign = 'u',
++ .realbits = 16,
++ .storagebits = 16,
++ .endianness = IIO_CPU,
++ },
++ .datasheet_name = "power2",
++ },
++ {
++ .type = IIO_CURRENT,
++ .indexed = 1,
++ .channel = 3,
++ .address = RTQ6056_REG_CURRENT,
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
++ BIT(IIO_CHAN_INFO_SAMP_FREQ),
++ .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
++ .scan_index = 3,
++ .scan_type = {
++ .sign = 's',
++ .realbits = 16,
++ .storagebits = 16,
++ .endianness = IIO_CPU,
++ },
++ .datasheet_name = "current3",
++ },
++ IIO_CHAN_SOFT_TIMESTAMP(RTQ6056_MAX_CHANNEL),
++};
++
++static int rtq6056_adc_read_channel(struct rtq6056_priv *priv,
++ struct iio_chan_spec const *ch,
++ int *val)
++{
++ struct device *dev = priv->dev;
++ unsigned int addr = ch->address;
++ unsigned int regval;
++ int ret;
++
++ pm_runtime_get_sync(dev);
++ ret = regmap_read(priv->regmap, addr, ®val);
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put(dev);
++ if (ret)
++ return ret;
++
++ /* Power and VBUS is unsigned 16-bit, others are signed 16-bit */
++ if (addr == RTQ6056_REG_BUSVOLT || addr == RTQ6056_REG_POWER)
++ *val = regval;
++ else
++ *val = sign_extend32(regval, 16);
++
++ return IIO_VAL_INT;
++}
++
++static int rtq6056_adc_read_scale(struct iio_chan_spec const *ch, int *val,
++ int *val2)
++{
++ switch (ch->address) {
++ case RTQ6056_REG_SHUNTVOLT:
++ /* VSHUNT lsb 2.5uV */
++ *val = 2500;
++ *val2 = 1000000;
++ return IIO_VAL_FRACTIONAL;
++ case RTQ6056_REG_BUSVOLT:
++ /* VBUS lsb 1.25mV */
++ *val = 1250;
++ *val2 = 1000;
++ return IIO_VAL_FRACTIONAL;
++ case RTQ6056_REG_POWER:
++ /* Power lsb 25mW */
++ *val = 25;
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
++ }
++}
++
++/*
++ * Sample frequency for channel VSHUNT and VBUS. The indices correspond
++ * with the bit value expected by the chip. And it can be found at
++ * https://www.richtek.com/assets/product_file/RTQ6056/DSQ6056-00.pdf
++ */
++static const int rtq6056_samp_freq_list[] = {
++ 7194, 4926, 3717, 1904, 964, 485, 243, 122,
++};
++
++static int rtq6056_adc_set_samp_freq(struct rtq6056_priv *priv,
++ struct iio_chan_spec const *ch, int val)
++{
++ unsigned int selector;
++ int *ct, ret;
++
++ if (val > 7194 || val < 122)
++ return -EINVAL;
++
++ if (ch->address == RTQ6056_REG_SHUNTVOLT) {
++ ct = &priv->vshuntct_us;
++ } else if (ch->address == RTQ6056_REG_BUSVOLT) {
++ ct = &priv->vbusct_us;
++ } else
++ return -EINVAL;
++
++ selector = find_closest_descending(val, rtq6056_samp_freq_list,
++ ARRAY_SIZE(rtq6056_samp_freq_list));
++
++ if (ch->address == RTQ6056_REG_SHUNTVOLT) {
++ ret = regmap_update_bits(priv->regmap, RTQ6056_REG_CONFIG,
++ RTQ6056_CONFIG_VSHUNTCT_MASK,
++ RTQ6056_CONFIG_VSHUNTCT(selector));
++ } else {
++ ret = regmap_update_bits(priv->regmap, RTQ6056_REG_CONFIG,
++ RTQ6056_CONFIG_VBUSCT_MASK,
++ RTQ6056_CONFIG_VBUSCT(selector));
++ }
++ if (ret)
++ return ret;
++
++ *ct = 1000000 / rtq6056_samp_freq_list[selector];
++
++ return 0;
++}
++
++/*
++ * Available averaging rate for rtq6056. The indices correspond with the bit
++ * value expected by the chip. And it can be found at
++ * https://www.richtek.com/assets/product_file/RTQ6056/DSQ6056-00.pdf
++ */
++static const int rtq6056_avg_sample_list[] = {
++ 1, 4, 16, 64, 128, 256, 512, 1024,
++};
++
++static int rtq6056_adc_set_average(struct rtq6056_priv *priv, int val)
++{
++ unsigned int selector;
++ int ret;
++
++ if (val > 1024 || val < 1)
++ return -EINVAL;
++
++ selector = find_closest(val, rtq6056_avg_sample_list,
++ ARRAY_SIZE(rtq6056_avg_sample_list));
++
++ ret = regmap_update_bits(priv->regmap, RTQ6056_REG_CONFIG,
++ RTQ6056_CONFIG_AVG_MASK,
++ RTQ6056_CONFIG_AVG(selector));
++
++ if (ret)
++ return ret;
++
++ priv->avg_sample = rtq6056_avg_sample_list[selector];
++
++ return 0;
++}
++
++static int rtq6056_adc_get_sample_freq(struct rtq6056_priv *priv,
++ struct iio_chan_spec const *ch, int *val)
++{
++ int sample_time;
++
++ if (ch->address == RTQ6056_REG_SHUNTVOLT)
++ sample_time = priv->vshuntct_us;
++ else if (ch->address == RTQ6056_REG_BUSVOLT)
++ sample_time = priv->vbusct_us;
++ else {
++ sample_time = priv->vshuntct_us + priv->vbusct_us;
++ sample_time *= priv->avg_sample;
++ }
++
++ *val = 1000000 / sample_time;
++
++ return IIO_VAL_INT;
++}
++
++static int rtq6056_adc_read_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan, int *val,
++ int *val2, long mask)
++{
++ struct rtq6056_priv *priv = iio_priv(indio_dev);
++
++ switch (mask) {
++ case IIO_CHAN_INFO_RAW:
++ return rtq6056_adc_read_channel(priv, chan, val);
++ case IIO_CHAN_INFO_SCALE:
++ return rtq6056_adc_read_scale(chan, val, val2);
++ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
++ *val = priv->avg_sample;
++ return IIO_VAL_INT;
++ case IIO_CHAN_INFO_SAMP_FREQ:
++ return rtq6056_adc_get_sample_freq(priv, chan, val);
++ default:
++ return -EINVAL;
++ }
++}
++
++static int rtq6056_adc_read_avail(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan,
++ const int **vals, int *type, int *length,
++ long mask)
++{
++ switch (mask) {
++ case IIO_CHAN_INFO_SAMP_FREQ:
++ *vals = rtq6056_samp_freq_list;
++ *type = IIO_VAL_INT;
++ *length = ARRAY_SIZE(rtq6056_samp_freq_list);
++ return IIO_AVAIL_LIST;
++ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
++ *vals = rtq6056_avg_sample_list;
++ *type = IIO_VAL_INT;
++ *length = ARRAY_SIZE(rtq6056_avg_sample_list);
++ return IIO_AVAIL_LIST;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int rtq6056_adc_write_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan, int val,
++ int val2, long mask)
++{
++ struct rtq6056_priv *priv = iio_priv(indio_dev);
++ int ret;
++
++ ret = iio_device_claim_direct_mode(indio_dev);
++ if (ret)
++ return ret;
++
++ switch (mask) {
++ case IIO_CHAN_INFO_SAMP_FREQ:
++ ret = rtq6056_adc_set_samp_freq(priv, chan, val);
++ break;
++ case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
++ ret = rtq6056_adc_set_average(priv, val);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ iio_device_release_direct_mode(indio_dev);
++
++ return ret;
++}
++
++static int rtq6056_set_shunt_resistor(struct rtq6056_priv *priv,
++ int resistor_uohm)
++{
++ unsigned int calib_val;
++ int ret;
++
++ if (resistor_uohm <= 0) {
++ dev_err(priv->dev, "Invalid resistor [%d]\n", resistor_uohm);
++ return -EINVAL;
++ }
++
++ /* calibration = 5120000 / (Rshunt (uOhm) * current lsb (1mA)) */
++ calib_val = 5120000 / resistor_uohm;
++ ret = regmap_write(priv->regmap, RTQ6056_REG_CALIBRATION, calib_val);
++ if (ret)
++ return ret;
++
++ priv->shunt_resistor_uohm = resistor_uohm;
++
++ return 0;
++}
++
++static ssize_t shunt_resistor_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct rtq6056_priv *priv = iio_priv(dev_to_iio_dev(dev));
++ int vals[2] = { priv->shunt_resistor_uohm, 1000000 };
++
++ return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals);
++}
++
++static ssize_t shunt_resistor_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t len)
++{
++ struct iio_dev *indio_dev = dev_to_iio_dev(dev);
++ struct rtq6056_priv *priv = iio_priv(indio_dev);
++ int val, val_fract, ret;
++
++ ret = iio_device_claim_direct_mode(indio_dev);
++ if (ret)
++ return ret;
++
++ ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract);
++ if (ret)
++ goto out_store;
++
++ ret = rtq6056_set_shunt_resistor(priv, val * 1000000 + val_fract);
++
++out_store:
++ iio_device_release_direct_mode(indio_dev);
++
++ return ret ?: len;
++}
++
++static IIO_DEVICE_ATTR_RW(shunt_resistor, 0);
++
++static struct attribute *rtq6056_attributes[] = {
++ &iio_dev_attr_shunt_resistor.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group rtq6056_attribute_group = {
++ .attrs = rtq6056_attributes,
++};
++
++static const struct iio_info rtq6056_info = {
++ .attrs = &rtq6056_attribute_group,
++ .read_raw = rtq6056_adc_read_raw,
++ .read_avail = rtq6056_adc_read_avail,
++ .write_raw = rtq6056_adc_write_raw,
++};
++
++static irqreturn_t rtq6056_buffer_trigger_handler(int irq, void *p)
++{
++ struct iio_poll_func *pf = p;
++ struct iio_dev *indio_dev = pf->indio_dev;
++ struct rtq6056_priv *priv = iio_priv(indio_dev);
++ struct device *dev = priv->dev;
++ struct {
++ u16 vals[RTQ6056_MAX_CHANNEL];
++ s64 timestamp __aligned(8);
++ } data;
++ unsigned int raw;
++ int i = 0, bit, ret;
++
++ memset(&data, 0, sizeof(data));
++
++ pm_runtime_get_sync(dev);
++
++ for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) {
++ unsigned int addr = rtq6056_channels[bit].address;
++
++ ret = regmap_read(priv->regmap, addr, &raw);
++ if (ret)
++ goto out;
++
++ data.vals[i++] = raw;
++ }
++
++ iio_push_to_buffers_with_timestamp(indio_dev, &data, iio_get_time_ns(indio_dev));
++
++out:
++ pm_runtime_mark_last_busy(dev);
++ pm_runtime_put(dev);
++
++ iio_trigger_notify_done(indio_dev->trig);
++
++ return IRQ_HANDLED;
++}
++
++static void rtq6056_enter_shutdown_state(void *dev)
++{
++ struct rtq6056_priv *priv = dev_get_drvdata(dev);
++
++ /* Enter shutdown state */
++ regmap_update_bits(priv->regmap, RTQ6056_REG_CONFIG,
++ RTQ6056_CONFIG_OPMODE_MASK,
++ RTQ6056_CONFIG_OPMODE(0));
++}
++
++static bool rtq6056_is_readable_reg(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case RTQ6056_REG_CONFIG ... RTQ6056_REG_ALERTLIMIT:
++ case RTQ6056_REG_MANUFACTID ... RTQ6056_REG_DIEID:
++ return true;
++ default:
++ return false;
++ }
++}
++
++static bool rtq6056_is_writeable_reg(struct device *dev, unsigned int reg)
++{
++ switch (reg) {
++ case RTQ6056_REG_CONFIG:
++ case RTQ6056_REG_CALIBRATION ... RTQ6056_REG_ALERTLIMIT:
++ return true;
++ default:
++ return false;
++ }
++}
++
++static const struct regmap_config rtq6056_regmap_config = {
++ .reg_bits = 8,
++ .val_bits = 16,
++ .val_format_endian = REGMAP_ENDIAN_BIG,
++ .max_register = RTQ6056_REG_DIEID,
++ .readable_reg = rtq6056_is_readable_reg,
++ .writeable_reg = rtq6056_is_writeable_reg,
++};
++
++static int rtq6056_probe(struct i2c_client *i2c)
++{
++ struct iio_dev *indio_dev;
++ struct rtq6056_priv *priv;
++ struct device *dev = &i2c->dev;
++ struct regmap *regmap;
++ unsigned int vendor_id, shunt_resistor_uohm;
++ int ret;
++
++ if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_WORD_DATA))
++ return -EOPNOTSUPP;
++
++ indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
++ if (!indio_dev)
++ return -ENOMEM;
++
++ priv = iio_priv(indio_dev);
++ priv->dev = dev;
++ priv->vshuntct_us = priv->vbusct_us = 1037;
++ priv->avg_sample = 1;
++ i2c_set_clientdata(i2c, priv);
++
++ regmap = devm_regmap_init_i2c(i2c, &rtq6056_regmap_config);
++ if (IS_ERR(regmap)) {
++ dev_err(dev, "Failed to init regmap\n");
++ return PTR_ERR(regmap);
++ }
++
++ priv->regmap = regmap;
++
++ ret = regmap_read(regmap, RTQ6056_REG_MANUFACTID, &vendor_id);
++ if (ret) {
++ dev_err(dev, "Failed to get manufacturer info: %d\n", ret);
++ return ret;
++ }
++
++ if (vendor_id != RTQ6056_VENDOR_ID) {
++ dev_err(dev, "Invalid vendor id 0x%04x\n", vendor_id);
++ return -ENODEV;
++ }
++
++ /*
++ * By default, configure average sample as 1, bus and shunt conversion
++ * time as 1037 microsecond, and operating mode to all on.
++ */
++ ret = regmap_write(regmap, RTQ6056_REG_CONFIG, RTQ6056_DEFAULT_CONFIG);
++ if (ret) {
++ dev_err(dev, "Failed to enable continuous sensing: %d\n", ret);
++ return ret;
++ }
++
++ ret = devm_add_action_or_reset(dev, rtq6056_enter_shutdown_state, dev);
++ if (ret)
++ return ret;
++
++ /* By default, use 2000 micro-Ohm resistor */
++ shunt_resistor_uohm = 2000;
++ device_property_read_u32(dev, "shunt-resistor-micro-ohms",
++ &shunt_resistor_uohm);
++
++ ret = rtq6056_set_shunt_resistor(priv, shunt_resistor_uohm);
++ if (ret) {
++ dev_err(dev, "Failed to init shunt resistor: %d\n", ret);
++ goto err;
++ }
++
++ indio_dev->name = "rtq6056";
++ indio_dev->modes = INDIO_DIRECT_MODE;
++ indio_dev->channels = rtq6056_channels;
++ indio_dev->num_channels = ARRAY_SIZE(rtq6056_channels);
++ indio_dev->info = &rtq6056_info;
++
++ ret = iio_map_array_register(indio_dev, rtq6056_maps);
++ if (ret) {
++ dev_err(dev, "Failed to register iio map: %d\n", ret);
++ goto err;
++ }
++
++ ret = iio_triggered_buffer_setup(indio_dev, NULL,
++ &rtq6056_buffer_trigger_handler, NULL);
++
++ if (ret) {
++ dev_err(dev, "Failed to allocate iio trigger buffer: %d\n",
++ ret);
++ goto err;
++ }
++
++ ret = devm_iio_device_register(dev, indio_dev);
++ if (ret) {
++ dev_err(dev, "Failed to register iio device: %d\n", ret);
++ goto err;
++ }
++
++ return 0;
++
++err:
++ return ret;
++}
++
++static const struct of_device_id rtq6056_device_match[] = {
++ { .compatible = "richtek,rtq6056" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, rtq6056_device_match);
++
++static struct i2c_driver rtq6056_driver = {
++ .driver = {
++ .name = "rtq6056",
++ .of_match_table = rtq6056_device_match,
++ },
++ .probe_new = rtq6056_probe,
++};
++module_i2c_driver(rtq6056_driver);
++
++MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
++MODULE_DESCRIPTION("Richtek RTQ6056 Driver");
++MODULE_LICENSE("GPL v2");
+--
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
similarity index 83%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
index e4e283c..f9c3542 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch
@@ -1,3 +1,22 @@
+From 0aeb63ff705a42b9140cad179ebe7f5fc54d285c Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:09 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch]
+
+---
+ drivers/mtd/nand/spi/core.c | 86 ++++++++++++++++++++++---------
+ drivers/mtd/nand/spi/gigadevice.c | 45 +++++-----------
+ drivers/mtd/nand/spi/macronix.c | 30 +++--------
+ drivers/mtd/nand/spi/micron.c | 26 ++--------
+ drivers/mtd/nand/spi/paragon.c | 28 +++-------
+ drivers/mtd/nand/spi/toshiba.c | 42 +++++----------
+ drivers/mtd/nand/spi/winbond.c | 34 +++---------
+ include/linux/mtd/spinand.h | 66 ++++++++++++++++--------
+ 8 files changed, 155 insertions(+), 202 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
+index 55e636efc..9f5f95ff7 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -16,6 +16,7 @@
@@ -23,7 +42,7 @@
int ret;
ret = spi_mem_exec_op(spinand->spimem, &op);
-@@ -760,24 +762,62 @@ static const struct spinand_manufacturer
+@@ -760,24 +762,62 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = {
&winbond_spinand_manufacturer,
};
@@ -95,7 +114,7 @@
static int spinand_manufacturer_init(struct spinand_device *spinand)
{
if (spinand->manufacturer->ops->init)
-@@ -833,9 +873,9 @@ spinand_select_op_variant(struct spinand
+@@ -833,9 +873,9 @@ spinand_select_op_variant(struct spinand_device *spinand,
* @spinand: SPI NAND object
* @table: SPI NAND device description table
* @table_size: size of the device description table
@@ -107,7 +126,7 @@
* entry in the SPI NAND description table. If a match is found, the spinand
* object will be initialized with information provided by the matching
* spinand_info entry.
-@@ -844,8 +884,10 @@ spinand_select_op_variant(struct spinand
+@@ -844,8 +884,10 @@ spinand_select_op_variant(struct spinand_device *spinand,
*/
int spinand_match_and_init(struct spinand_device *spinand,
const struct spinand_info *table,
@@ -119,7 +138,7 @@
struct nand_device *nand = spinand_to_nand(spinand);
unsigned int i;
-@@ -853,13 +895,17 @@ int spinand_match_and_init(struct spinan
+@@ -853,13 +895,17 @@ int spinand_match_and_init(struct spinand_device *spinand,
const struct spinand_info *info = &table[i];
const struct spi_mem_op *op;
@@ -138,7 +157,7 @@
spinand->select_target = table[i].select_target;
op = spinand_select_op_variant(spinand,
-@@ -896,13 +942,7 @@ static int spinand_detect(struct spinand
+@@ -896,13 +942,7 @@ static int spinand_detect(struct spinand_device *spinand)
if (ret)
return ret;
@@ -153,9 +172,11 @@
if (ret) {
dev_err(dev, "unknown raw ID %*phN\n", SPINAND_MAX_ID_LEN,
spinand->id.data);
+diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
+index b13b39763..a34c5ede1 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -195,7 +195,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(
+@@ -195,7 +195,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
}
static const struct spinand_info gigadevice_spinand_table[] = {
@@ -165,7 +186,7 @@
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -204,7 +205,8 @@ static const struct spinand_info gigadev
+@@ -204,7 +205,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
gd5fxgq4xa_ecc_get_status)),
@@ -175,7 +196,7 @@
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -213,7 +215,8 @@ static const struct spinand_info gigadev
+@@ -213,7 +215,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
gd5fxgq4xa_ecc_get_status)),
@@ -185,7 +206,7 @@
NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -222,7 +225,8 @@ static const struct spinand_info gigadev
+@@ -222,7 +225,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
gd5fxgq4xa_ecc_get_status)),
@@ -195,7 +216,7 @@
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -231,7 +235,8 @@ static const struct spinand_info gigadev
+@@ -231,7 +235,8 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
gd5fxgq4uexxg_ecc_get_status)),
@@ -205,7 +226,7 @@
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
-@@ -242,39 +247,13 @@ static const struct spinand_info gigadev
+@@ -242,39 +247,13 @@ static const struct spinand_info gigadevice_spinand_table[] = {
gd5fxgq4ufxxg_ecc_get_status)),
};
@@ -247,9 +268,11 @@
+ .nchips = ARRAY_SIZE(gigadevice_spinand_table),
.ops = &gigadevice_spinand_manuf_ops,
};
+diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
+index 21def3f8f..0f900f3aa 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -99,7 +99,8 @@ static int mx35lf1ge4ab_ecc_get_status(s
+@@ -99,7 +99,8 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
}
static const struct spinand_info macronix_spinand_table[] = {
@@ -259,7 +282,7 @@
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -108,7 +109,8 @@ static const struct spinand_info macroni
+@@ -108,7 +109,8 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
@@ -269,7 +292,7 @@
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
NAND_ECCREQ(4, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -118,33 +120,13 @@ static const struct spinand_info macroni
+@@ -118,33 +120,13 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
};
@@ -305,9 +328,11 @@
+ .nchips = ARRAY_SIZE(macronix_spinand_table),
.ops = ¯onix_spinand_manuf_ops,
};
+diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
+index 7d7b1f7fc..f56f81325 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
-@@ -91,7 +91,8 @@ static int mt29f2g01abagd_ecc_get_status
+@@ -91,7 +91,8 @@ static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand,
}
static const struct spinand_info micron_spinand_table[] = {
@@ -317,7 +342,7 @@
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -102,32 +103,13 @@ static const struct spinand_info micron_
+@@ -102,32 +103,13 @@ static const struct spinand_info micron_spinand_table[] = {
mt29f2g01abagd_ecc_get_status)),
};
@@ -352,9 +377,11 @@
+ .nchips = ARRAY_SIZE(micron_spinand_table),
.ops = µn_spinand_manuf_ops,
};
+diff --git a/drivers/mtd/nand/spi/paragon.c b/drivers/mtd/nand/spi/paragon.c
+index 52307681c..519ade513 100644
--- a/drivers/mtd/nand/spi/paragon.c
+++ b/drivers/mtd/nand/spi/paragon.c
-@@ -97,7 +97,8 @@ static const struct mtd_ooblayout_ops pn
+@@ -97,7 +97,8 @@ static const struct mtd_ooblayout_ops pn26g0xa_ooblayout = {
static const struct spinand_info paragon_spinand_table[] = {
@@ -364,7 +391,7 @@
NAND_MEMORG(1, 2048, 128, 64, 1024, 21, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -106,7 +107,8 @@ static const struct spinand_info paragon
+@@ -106,7 +107,8 @@ static const struct spinand_info paragon_spinand_table[] = {
0,
SPINAND_ECCINFO(&pn26g0xa_ooblayout,
pn26g0xa_ecc_get_status)),
@@ -374,7 +401,7 @@
NAND_MEMORG(1, 2048, 128, 64, 2048, 41, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -117,31 +119,13 @@ static const struct spinand_info paragon
+@@ -117,31 +119,13 @@ static const struct spinand_info paragon_spinand_table[] = {
pn26g0xa_ecc_get_status)),
};
@@ -408,9 +435,11 @@
+ .nchips = ARRAY_SIZE(paragon_spinand_table),
.ops = ¶gon_spinand_manuf_ops,
};
+diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
+index 1cb3760ff..35da3c6e9 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
-@@ -95,7 +95,8 @@ static int tc58cxgxsx_ecc_get_status(str
+@@ -95,7 +95,8 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand,
static const struct spinand_info toshiba_spinand_table[] = {
/* 3.3V 1Gb */
@@ -420,7 +449,7 @@
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -105,7 +106,8 @@ static const struct spinand_info toshiba
+@@ -105,7 +106,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
tc58cxgxsx_ecc_get_status)),
/* 3.3V 2Gb */
@@ -430,7 +459,7 @@
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -115,7 +117,8 @@ static const struct spinand_info toshiba
+@@ -115,7 +117,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
tc58cxgxsx_ecc_get_status)),
/* 3.3V 4Gb */
@@ -440,7 +469,7 @@
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -125,7 +128,8 @@ static const struct spinand_info toshiba
+@@ -125,7 +128,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
tc58cxgxsx_ecc_get_status)),
/* 1.8V 1Gb */
@@ -450,7 +479,7 @@
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -135,7 +139,8 @@ static const struct spinand_info toshiba
+@@ -135,7 +139,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
tc58cxgxsx_ecc_get_status)),
/* 1.8V 2Gb */
@@ -460,7 +489,7 @@
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -145,7 +150,8 @@ static const struct spinand_info toshiba
+@@ -145,7 +150,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
tc58cxgxsx_ecc_get_status)),
/* 1.8V 4Gb */
@@ -470,7 +499,7 @@
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -156,33 +162,13 @@ static const struct spinand_info toshiba
+@@ -156,33 +162,13 @@ static const struct spinand_info toshiba_spinand_table[] = {
tc58cxgxsx_ecc_get_status)),
};
@@ -506,9 +535,11 @@
+ .nchips = ARRAY_SIZE(toshiba_spinand_table),
.ops = &toshiba_spinand_manuf_ops,
};
+diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
+index a6c17e0ca..766844283 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
-@@ -75,7 +75,8 @@ static int w25m02gv_select_target(struct
+@@ -75,7 +75,8 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
}
static const struct spinand_info winbond_spinand_table[] = {
@@ -518,7 +549,7 @@
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -84,7 +85,8 @@ static const struct spinand_info winbond
+@@ -84,7 +85,8 @@ static const struct spinand_info winbond_spinand_table[] = {
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
@@ -528,7 +559,7 @@
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -94,31 +96,6 @@ static const struct spinand_info winbond
+@@ -94,31 +96,6 @@ static const struct spinand_info winbond_spinand_table[] = {
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
};
@@ -560,7 +591,7 @@
static int winbond_spinand_init(struct spinand_device *spinand)
{
struct nand_device *nand = spinand_to_nand(spinand);
-@@ -138,12 +115,13 @@ static int winbond_spinand_init(struct s
+@@ -138,12 +115,13 @@ static int winbond_spinand_init(struct spinand_device *spinand)
}
static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = {
@@ -575,6 +606,8 @@
+ .nchips = ARRAY_SIZE(winbond_spinand_table),
.ops = &winbond_spinand_manuf_ops,
};
+diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
+index 4ea558bd3..f4c4ae871 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -32,9 +32,9 @@
@@ -693,7 +726,7 @@
#define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \
{ \
.read_cache = __read, \
-@@ -451,9 +472,10 @@ static inline void spinand_set_of_node(s
+@@ -451,9 +472,10 @@ static inline void spinand_set_of_node(struct spinand_device *spinand,
nanddev_set_of_node(&spinand->base, np);
}
@@ -706,3 +739,6 @@
int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
int spinand_select_target(struct spinand_device *spinand, unsigned int target);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
similarity index 66%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
index d4e9497..e3e81e5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch
@@ -1,48 +1,15 @@
-From 469b992489852b500d39048aa0013639dfe9f2e6 Mon Sep 17 00:00:00 2001
-From: Reto Schneider <reto.schneider@husqvarnagroup.com>
-Date: Thu, 11 Feb 2021 12:36:19 +0100
-Subject: [PATCH] mtd: spinand: gigadevice: Support GD5F1GQ5UExxG
+From 2f8ed664925318dacb6a92ca6383b5589cc2f7e1 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:09 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch]
-The relevant changes to the already existing GD5F1GQ4UExxG support has
-been determined by consulting the GigaDevice product change notice
-AN-0392-10, version 1.0 from November 30, 2020.
-
-As the overlaps are huge, variable names have been generalized
-accordingly.
-
-Apart from the lowered ECC strength (4 instead of 8 bits per 512 bytes),
-the new device ID, and the extra quad IO dummy byte, no changes had to
-be taken into account.
-
-New hardware features are not supported, namely:
- - Power on reset
- - Unique ID
- - Double transfer rate (DTR)
- - Parameter page
- - Random data quad IO
-
-The inverted semantic of the "driver strength" register bits, defaulting
-to 100% instead of 50% for the Q5 devices, got ignored as the driver has
-never touched them anyway.
-
-The no longer supported "read from cache during block erase"
-functionality is not reflected as the current SPI NAND core does not
-support it anyway.
-
-Implementation has been tested on MediaTek MT7688 based GARDENA smart
-Gateways using both, GigaDevice GD5F1GQ5UEYIG and GD5F1GQ4UBYIG.
-
-Signed-off-by: Reto Schneider <reto.schneider@husqvarnagroup.com>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Reviewed-by: Stefan Roese <sr@denx.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20210211113619.3502-1-code@reto-schneider.ch
---
drivers/mtd/nand/spi/gigadevice.c | 69 +++++++++++++++++++++++++++----
1 file changed, 60 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
-index 33c67403c4aa1e..1dd1c589809341 100644
+index a34c5ede1..937a04ce6 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -13,7 +13,10 @@
@@ -75,7 +42,7 @@
struct mtd_oob_region *region)
{
if (section)
-@@ -127,9 +130,10 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
+@@ -127,16 +130,17 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
return 0;
}
@@ -88,8 +55,7 @@
+ .free = gd5fxgqx_variant2_ooblayout_free,
};
- static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
-@@ -165,7 +169,7 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
+ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
u8 status2;
@@ -98,7 +64,7 @@
&status2);
int ret;
-@@ -203,6 +207,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
+@@ -174,6 +178,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
return -EINVAL;
}
@@ -142,7 +108,7 @@
static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
u8 status)
{
-@@ -282,7 +323,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
+@@ -233,7 +274,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
@@ -151,7 +117,7 @@
gd5fxgq4uexxg_ecc_get_status)),
SPINAND_INFO("GD5F1GQ4UFxxG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
-@@ -292,8 +333,18 @@ static const struct spinand_info gigadevice_spinand_table[] = {
+@@ -243,8 +284,18 @@ static const struct spinand_info gigadevice_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
@@ -171,3 +137,6 @@
};
static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2312-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2312-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch
new file mode 100644
index 0000000..d55e946
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2312-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch
@@ -0,0 +1,34 @@
+From 9c8aa0697168dac0ad3638dc075c25087d4ee19c Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:10 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2312-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch]
+
+---
+ drivers/mtd/nand/spi/macronix.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
+index 0f900f3aa..6e66d8710 100644
+--- a/drivers/mtd/nand/spi/macronix.c
++++ b/drivers/mtd/nand/spi/macronix.c
+@@ -118,6 +118,16 @@ static const struct spinand_info macronix_spinand_table[] = {
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
++ SPINAND_INFO("MX31LF1GE4BC",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0 /*SPINAND_HAS_QE_BIT*/,
++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++ mx35lf1ge4ab_ecc_get_status)),
+ };
+
+ static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2313-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2313-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch
new file mode 100644
index 0000000..8dcf798
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2313-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch
@@ -0,0 +1,34 @@
+From 34485df92908238e8603d2c9de486e7c41db45fb Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:10 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2313-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch]
+
+---
+ drivers/mtd/nand/spi/macronix.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
+index 6e66d8710..4964fe35b 100644
+--- a/drivers/mtd/nand/spi/macronix.c
++++ b/drivers/mtd/nand/spi/macronix.c
+@@ -128,6 +128,16 @@ static const struct spinand_info macronix_spinand_table[] = {
+ 0 /*SPINAND_HAS_QE_BIT*/,
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
+ mx35lf1ge4ab_ecc_get_status)),
++ SPINAND_INFO("MX31UF1GE4BC",
++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
++ NAND_ECCREQ(8, 512),
++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
++ &write_cache_variants,
++ &update_cache_variants),
++ 0 /*SPINAND_HAS_QE_BIT*/,
++ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
++ mx35lf1ge4ab_ecc_get_status)),
+ };
+
+ static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2314-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch
similarity index 63%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2314-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch
index 313b373..eaa9851 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2314-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch
@@ -1,27 +1,18 @@
-From 5ece78de88739b4c68263e9f2582380c1fd8314f Mon Sep 17 00:00:00 2001
-From: YouChing Lin <ycllin@mxic.com.tw>
-Date: Thu, 5 Nov 2020 15:23:40 +0800
-Subject: [PATCH] mtd: spinand: macronix: Add support for MX35LFxGE4AD
+From 14f6824f11e1167bf2cbbd650cd6a7a2ad856555 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:10 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2314-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch]
-The Macronix MX35LF2GE4AD / MX35LF4GE4AD are 3V, 2G / 4Gbit serial
-SLC NAND flash device (with on-die ECC).
-
-Validated by read, erase, read back, write, read back and nandtest
-on Xilinx Zynq PicoZed FPGA board which included Macronix SPI Host
-(drivers/spi/spi-mxic.c).
-
-Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/1604561020-13499-1-git-send-email-ycllin@mxic.com.tw
---
drivers/mtd/nand/spi/macronix.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
-index 8e801e4c3a006f..3786b1b03b3b4b 100644
+index 4964fe35b..16d2acafb 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -119,6 +119,26 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -118,6 +118,26 @@ static const struct spinand_info macronix_spinand_table[] = {
&update_cache_variants),
SPINAND_HAS_QE_BIT,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
@@ -48,3 +39,6 @@
SPINAND_INFO("MX31LF1GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2315-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch
similarity index 64%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2315-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch
index e323a53..41b540c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2315-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch
@@ -1,28 +1,18 @@
-From ee4e0eafa43cfd9008722fe15e17b8bf62fb6e8d Mon Sep 17 00:00:00 2001
-From: YouChing Lin <ycllin@mxic.com.tw>
-Date: Thu, 10 Dec 2020 11:22:09 +0800
-Subject: [PATCH] mtd: spinand: macronix: Add support for MX35LFxG24AD
+From 1de538322f8e3b2586d5b41bdcc0383ecba9ce32 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:10 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2315-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch]
-The Macronix MX35LF1G24AD(/2G24AD/4G24AD) are 3V, 1G/2G/4Gbit serial
-SLC NAND flash device (without on-die ECC).
-
-Validated by read, erase, read back, write, read back on Xilinx Zynq
-PicoZed FPGA board which included Macronix SPI Host(drivers/spi/spi-mxic.c)
-& S/W BCH ecc(drivers/mtd/nand/ecc-sw-bch.c) with bug fixing patch
-(mtd: nand: ecc-bch: Fix the size of calc_buf/code_buf of the BCH).
-
-Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/1607570529-22341-3-git-send-email-ycllin@mxic.com.tw
---
drivers/mtd/nand/spi/macronix.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
-index 3786b1b03b3b4b..6701aaa21a49df 100644
+index 16d2acafb..e0c71c654 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -139,6 +139,33 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -138,6 +138,33 @@ static const struct spinand_info macronix_spinand_table[] = {
0,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
@@ -56,3 +46,6 @@
SPINAND_INFO("MX31LF1GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2316-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch
similarity index 72%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2316-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch
index 9900084..fbcca17 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2316-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch
@@ -1,55 +1,18 @@
-From c374839f9b4475173e536d1eaddff45cb481dbdf Mon Sep 17 00:00:00 2001
-From: Jaime Liao <jaimeliao@mxic.com.tw>
-Date: Thu, 20 May 2021 09:45:08 +0800
-Subject: [PATCH] mtd: spinand: macronix: Add support for serial NAND flash
+From 3b7dc97f2ff2d354c7f624d4d04fd5dd8595c923 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:11 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2316-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch]
-Macronix NAND Flash devices are available in different configurations
-and densities.
-
-MX"35" means SPI NAND
-MX35"LF"/"UF" , LF means 3V and UF meands 1.8V
-MX35LF"2G" , 2G means 2Gbits
-MX35LF2G"E4"/"24"/"14",
-E4 means internal ECC and Quad I/O(x4)
-24 means 8-bit ecc requirement and Quad I/O(x4)
-14 means 4-bit ecc requirement and Quad I/O(x4)
-
-MX35LF2G14AC is 3V 2Gbit serial NAND flash device
-(without on-die ECC)
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7926/MX35LF2G14AC,%203V,%202Gb,%20v1.1.pdf
-
-MX35UF4G24AD is 1.8V 4Gbit serial NAND flash device
-(without on-die ECC)
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7980/MX35UF4G24AD,%201.8V,%204Gb,%20v0.00.pdf
-
-MX35UF4GE4AD/MX35UF2GE4AD are 1.8V 4G/2Gbit serial
-NAND flash device with 8-bit on-die ECC
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7983/MX35UF4GE4AD,%201.8V,%204Gb,%20v0.00.pdf
-
-MX35UF2GE4AC/MX35UF1GE4AC are 1.8V 2G/1Gbit serial
-NAND flash device with 8-bit on-die ECC
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7974/MX35UF2GE4AC,%201.8V,%202Gb,%20v1.0.pdf
-
-MX35UF2G14AC/MX35UF1G14AC are 1.8V 2G/1Gbit serial
-NAND flash device (without on-die ECC)
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7931/MX35UF2G14AC,%201.8V,%202Gb,%20v1.1.pdf
-
-Validated via normal(default) and QUAD mode by read, erase, read back,
-on Xilinx Zynq PicoZed FPGA board which included Macronix
-SPI Host(drivers/spi/spi-mxic.c).
-
-Signed-off-by: Jaime Liao <jaimeliao@mxic.com.tw>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/1621475108-22523-1-git-send-email-jaimeliao@mxic.com.tw
---
drivers/mtd/nand/spi/macronix.c | 112 ++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
-index 6701aaa21a49df..a9890350db0293 100644
+index e0c71c654..ede66b71b 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -186,6 +186,118 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -185,6 +185,118 @@ static const struct spinand_info macronix_spinand_table[] = {
0 /*SPINAND_HAS_QE_BIT*/,
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
@@ -168,3 +131,6 @@
};
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2317-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch
similarity index 70%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2317-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch
index cc6900a..bcc9df8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2317-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch
@@ -1,27 +1,18 @@
-From 6f802696c2faf0119781fc3b7977a4eedf9ab239 Mon Sep 17 00:00:00 2001
-From: Jaime Liao <jaimeliao@mxic.com.tw>
-Date: Mon, 9 Aug 2021 09:27:52 +0800
-Subject: [PATCH] mtd: spinand: macronix: Add Quad support for serial NAND
- flash
+From ec328d836a28d538c38f67f5467b9319d6a950a3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:11 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2317-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch]
-Adding FLAG "SPINAND_HAS_QE_BIT" for Quad mode support on Macronix
-Serial Flash.
-Validated via normal(default) and QUAD mode by read, erase, read back,
-on Xilinx Zynq PicoZed FPGA board which included Macronix
-SPI Host(drivers/spi/spi-mxic.c).
-
-Signed-off-by: Jaime Liao <jaimeliao@mxic.com.tw>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/1628472472-32008-1-git-send-email-jaimeliao@mxic.com.tw
---
drivers/mtd/nand/spi/macronix.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
-index a9890350db0293..3f31f1381a62c0 100644
+index ede66b71b..25319b4f8 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -126,7 +126,7 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -125,7 +125,7 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
@@ -30,7 +21,7 @@
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
SPINAND_INFO("MX35LF4GE4AD",
-@@ -136,7 +136,7 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -135,7 +135,7 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
@@ -39,7 +30,7 @@
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
SPINAND_INFO("MX35LF1G24AD",
-@@ -146,16 +146,16 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -145,16 +145,16 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
@@ -59,7 +50,7 @@
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
SPINAND_INFO("MX35LF4G24AD",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
-@@ -164,7 +164,7 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -163,7 +163,7 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
@@ -68,7 +59,7 @@
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
SPINAND_INFO("MX31LF1GE4BC",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
-@@ -173,7 +173,7 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -172,7 +172,7 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
@@ -77,7 +68,7 @@
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
SPINAND_INFO("MX31UF1GE4BC",
-@@ -183,7 +183,7 @@ static const struct spinand_info macronix_spinand_table[] = {
+@@ -182,7 +182,7 @@ static const struct spinand_info macronix_spinand_table[] = {
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
&write_cache_variants,
&update_cache_variants),
@@ -86,3 +77,6 @@
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
mx35lf1ge4ab_ecc_get_status)),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2318-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch
similarity index 77%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2318-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch
index b4fcfbc..2e888d3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2318-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch
@@ -1,22 +1,15 @@
-From d3137043440fb1faaaf2481184f35b9ed0c1f2c2 Mon Sep 17 00:00:00 2001
-From: Shivamurthy Shastri <sshivamurthy@micron.com>
-Date: Wed, 11 Mar 2020 18:57:30 +0100
-Subject: [PATCH] mtd: spinand: micron: Generalize the OOB layout structure and
- function names
+From aebf853ada4f73280d4cf7a1799cb0ebf84f87e1 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:11 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2318-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch]
-In order to add new Micron SPI NAND devices, we generalized the OOB
-layout structure and function names.
-
-Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
-Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-2-sshivamurthy@micron.com
---
drivers/mtd/nand/spi/micron.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index f56f81325e10ac..cc1ee68421c8e1 100644
+index f56f81325..cc1ee6842 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -34,38 +34,38 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
@@ -81,3 +74,6 @@
};
static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2319-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2319-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch
new file mode 100644
index 0000000..3ff682b
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2319-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch
@@ -0,0 +1,25 @@
+From 59766b3af8f603e740c38d2cc03c37226c78bb11 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:11 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2319-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch]
+
+---
+ drivers/mtd/nand/spi/micron.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
+index cc1ee6842..4727933c8 100644
+--- a/drivers/mtd/nand/spi/micron.c
++++ b/drivers/mtd/nand/spi/micron.c
+@@ -91,6 +91,7 @@ static int micron_8_ecc_get_status(struct spinand_device *spinand,
+ }
+
+ static const struct spinand_info micron_spinand_table[] = {
++ /* M79A 2Gb 3.3V */
+ SPINAND_INFO("MT29F2G01ABAGD",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2320-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch
similarity index 75%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2320-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch
index be3a3b1..4c5e911 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2320-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch
@@ -1,20 +1,15 @@
-From a15335a17f4abf48ed9739c3b119232f9392cb60 Mon Sep 17 00:00:00 2001
-From: Shivamurthy Shastri <sshivamurthy@micron.com>
-Date: Wed, 11 Mar 2020 18:57:32 +0100
-Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices
+From 66ea40f7c5b196eee609c5e3322aac3a7ac59e03 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:12 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2320-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch]
-Add device table for M79A and M78A series Micron SPI NAND devices.
-
-Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
-Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-4-sshivamurthy@micron.com
---
drivers/mtd/nand/spi/micron.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index 4727933c894bc8..26925714a9fbac 100644
+index 4727933c8..26925714a 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -102,6 +102,39 @@ static const struct spinand_info micron_spinand_table[] = {
@@ -57,3 +52,6 @@
};
static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2321-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2321-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch
new file mode 100644
index 0000000..ae7ac72
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2321-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch
@@ -0,0 +1,61 @@
+From 65c3b878a33bb7edd5413860537fecdff94aaba6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:12 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2321-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch]
+
+---
+ drivers/mtd/nand/spi/micron.c | 16 ++++++++++++++++
+ include/linux/mtd/spinand.h | 1 +
+ 2 files changed, 17 insertions(+)
+
+diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
+index 26925714a..956f7710a 100644
+--- a/drivers/mtd/nand/spi/micron.c
++++ b/drivers/mtd/nand/spi/micron.c
+@@ -18,6 +18,8 @@
+ #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
+ #define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
+
++#define MICRON_CFG_CR BIT(0)
++
+ static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+@@ -137,7 +139,21 @@ static const struct spinand_info micron_spinand_table[] = {
+ micron_8_ecc_get_status)),
+ };
+
++static int micron_spinand_init(struct spinand_device *spinand)
++{
++ /*
++ * M70A device series enable Continuous Read feature at Power-up,
++ * which is not supported. Disable this bit to avoid any possible
++ * failure.
++ */
++ if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT)
++ return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0);
++
++ return 0;
++}
++
+ static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
++ .init = micron_spinand_init,
+ };
+
+ const struct spinand_manufacturer micron_spinand_manufacturer = {
+diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
+index f4c4ae871..1077c4572 100644
+--- a/include/linux/mtd/spinand.h
++++ b/include/linux/mtd/spinand.h
+@@ -284,6 +284,7 @@ struct spinand_ecc_info {
+ };
+
+ #define SPINAND_HAS_QE_BIT BIT(0)
++#define SPINAND_HAS_CR_FEAT_BIT BIT(1)
+
+ /**
+ * struct spinand_info - Structure used to describe SPI NAND chips
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2322-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch
similarity index 70%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2322-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch
index 158492f..426d674 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2322-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch
@@ -1,20 +1,15 @@
-From a7e5daccc310c3b892ae5e598cadb7a9274c2547 Mon Sep 17 00:00:00 2001
-From: Shivamurthy Shastri <sshivamurthy@micron.com>
-Date: Wed, 11 Mar 2020 18:57:34 +0100
-Subject: [PATCH] mtd: spinand: micron: Add M70A series Micron SPI NAND devices
+From 5a4cd6ba8f7ae6744ca44f78c761f26e843c0341 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:12 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2322-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch]
-Add device table for M70A series Micron SPI NAND devices.
-
-Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
-Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-6-sshivamurthy@micron.com
---
drivers/mtd/nand/spi/micron.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index 956f7710aca263..d6fd630087822c 100644
+index 956f7710a..d6fd63008 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -137,6 +137,28 @@ static const struct spinand_info micron_spinand_table[] = {
@@ -46,3 +41,6 @@
};
static int micron_spinand_init(struct spinand_device *spinand)
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2323-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch
similarity index 83%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2323-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch
index 8f8f1da..2e0a356 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2323-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch
@@ -1,24 +1,15 @@
-From 9f9ae0c253c1e058fbc845e26c4a32a7d777f0dc Mon Sep 17 00:00:00 2001
-From: Shivamurthy Shastri <sshivamurthy@micron.com>
-Date: Wed, 11 Mar 2020 18:57:35 +0100
-Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices with
- multiple dies
+From ac7be09336555cf993d904bd9e42c05d1769288a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:12 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2323-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch]
-Add device table for new Micron SPI NAND devices, which have multiple
-dies.
-
-Also, enable support to select the dies.
-
-Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
-Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-7-sshivamurthy@micron.com
---
drivers/mtd/nand/spi/micron.c | 58 +++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index d6fd630087822c..5d370cfcdaaaa9 100644
+index d6fd63008..5d370cfcd 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -20,6 +20,14 @@
@@ -107,3 +98,6 @@
};
static int micron_spinand_init(struct spinand_device *spinand)
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2324-mtd-spinand-micron-Use-more-specific-names.patch
similarity index 92%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2324-mtd-spinand-micron-Use-more-specific-names.patch
index ec03ffe..e397967 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/456-mtd-spinand-micron-Use-more-specific-names.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2324-mtd-spinand-micron-Use-more-specific-names.patch
@@ -1,20 +1,15 @@
-From bdb84a22b02b0c2ca76bb3e3e16942338f67999b Mon Sep 17 00:00:00 2001
-From: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
-Date: Sun, 8 Nov 2020 19:37:34 +0800
-Subject: [PATCH] mtd: spinand: micron: Use more specific names
+From 5abef195abf3faa6f8e22a2e6996316f14c4f21c Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:13 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2324-mtd-spinand-micron-Use-more-specific-names.patch]
-Rename the read/write/update of SPINAND_OP_VARIANTS() to more
-specialized names.
-
-Signed-off-by: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20201108113735.2533-2-nthirumalesha7@gmail.com
---
drivers/mtd/nand/spi/micron.c | 60 +++++++++++++++++------------------
1 file changed, 30 insertions(+), 30 deletions(-)
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index 5d370cfcdaaaa9..afe3ba37dcfb8e 100644
+index 5d370cfcd..afe3ba37d 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -28,7 +28,7 @@
@@ -157,3 +152,6 @@
SPINAND_HAS_CR_FEAT_BIT,
SPINAND_ECCINFO(µn_8_ooblayout,
micron_8_ecc_get_status),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2325-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch
similarity index 83%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2325-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch
index ecd2b71..b6914ce 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2325-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch
@@ -1,20 +1,15 @@
-From 8c573d9419bf61f7b66b6114f1171f3a8a4a0e38 Mon Sep 17 00:00:00 2001
-From: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
-Date: Sun, 8 Nov 2020 19:37:35 +0800
-Subject: [PATCH] mtd: spinand: micron: Add support for MT29F2G01AAAED
+From 5cea72055a3bce2b8b5a1f8cb6d46165eeccd8b9 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:13 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2325-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch]
-The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit
-ECC
-
-Signed-off-by: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/20201108113735.2533-3-nthirumalesha7@gmail.com
---
drivers/mtd/nand/spi/micron.c | 64 +++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
-index afe3ba37dcfb8e..50b7295bc92226 100644
+index afe3ba37d..50b7295bc 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -44,6 +44,19 @@ static SPINAND_OP_VARIANTS(x4_update_cache_variants,
@@ -102,3 +97,6 @@
};
static int micron_spinand_init(struct spinand_device *spinand)
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2326-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch
similarity index 73%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2326-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch
index 80672e6..74bab62 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2326-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch
@@ -1,32 +1,18 @@
-From 6b49e58d6d9dab031a16af2af5439f28a37c4cd9 Mon Sep 17 00:00:00 2001
-From: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
-Date: Tue, 24 Mar 2020 15:49:44 +0900
-Subject: [PATCH] mtd: spinand: toshiba: Rename function name to change suffix
- and prefix (8Gbit)
+From af4301a675f4fcbaa787f1d3bd07df1c08a093c3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:13 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2326-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch]
-The suffix was changed from "G" to "J" to classify between 1st generation
-and 2nd generation serial NAND devices (which now belong to the Kioxia
-brand).
-As reference that's
-1st generation device of 1Gbit product is "TC58CVG0S3HRAIG"
-2nd generation device of 1Gbit product is "TC58CVG0S3HRAIJ".
-
-The 8Gbit type "TH58CxG3S0HRAIJ" is new to Kioxia's serial NAND lineup and
-the prefix was changed from "TC58" to "TH58".
-
-Thus the functions were renamed from tc58cxgxsx_*() to tx58cxgxsxraix_*().
-
-Signed-off-by: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/0dedd9869569a17625822dba87878254d253ba0e.1584949601.git.ytc-mb-yfuruyama7@kioxia.com
---
- drivers/mtd/nand/spi/toshiba.c | 60 +++++++++++++++++-----------------
- 1 file changed, 30 insertions(+), 30 deletions(-)
+ drivers/mtd/nand/spi/toshiba.c | 65 ++++++++++++++++++++--------------
+ 1 file changed, 38 insertions(+), 27 deletions(-)
+diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
+index 35da3c6e9..7ce5997dd 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
-@@ -25,8 +25,8 @@ static SPINAND_OP_VARIANTS(write_cache_v
+@@ -25,8 +25,8 @@ static SPINAND_OP_VARIANTS(write_cache_variants,
static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD(false, 0, NULL, 0));
@@ -37,7 +23,7 @@
{
if (section > 0)
return -ERANGE;
-@@ -37,8 +37,8 @@ static int tc58cxgxsx_ooblayout_ecc(stru
+@@ -37,8 +37,8 @@ static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section,
return 0;
}
@@ -48,7 +34,7 @@
{
if (section > 0)
return -ERANGE;
-@@ -50,13 +50,13 @@ static int tc58cxgxsx_ooblayout_free(str
+@@ -50,13 +50,13 @@ static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section,
return 0;
}
@@ -67,7 +53,7 @@
{
struct nand_device *nand = spinand_to_nand(spinand);
u8 mbf = 0;
-@@ -95,7 +95,7 @@ static int tc58cxgxsx_ecc_get_status(str
+@@ -95,7 +95,7 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand,
static const struct spinand_info toshiba_spinand_table[] = {
/* 3.3V 1Gb */
@@ -76,7 +62,7 @@
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
-@@ -103,10 +103,10 @@ static const struct spinand_info toshiba
+@@ -103,10 +103,10 @@ static const struct spinand_info toshiba_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
0,
@@ -90,7 +76,7 @@
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
-@@ -114,10 +114,10 @@ static const struct spinand_info toshiba
+@@ -114,10 +114,10 @@ static const struct spinand_info toshiba_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
0,
@@ -104,7 +90,7 @@
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
-@@ -125,10 +125,21 @@ static const struct spinand_info toshiba
+@@ -125,10 +125,21 @@ static const struct spinand_info toshiba_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
0,
@@ -129,7 +115,7 @@
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
-@@ -136,10 +147,10 @@ static const struct spinand_info toshiba
+@@ -136,10 +147,10 @@ static const struct spinand_info toshiba_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
0,
@@ -143,7 +129,7 @@
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
-@@ -147,10 +158,10 @@ static const struct spinand_info toshiba
+@@ -147,10 +158,10 @@ static const struct spinand_info toshiba_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
0,
@@ -157,7 +143,7 @@
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(8, 512),
-@@ -158,8 +169,8 @@ static const struct spinand_info toshiba
+@@ -158,8 +169,8 @@ static const struct spinand_info toshiba_spinand_table[] = {
&write_cache_variants,
&update_cache_variants),
0,
@@ -168,3 +154,6 @@
};
static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2327-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch
similarity index 85%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2327-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch
index ffa1ad8..12a55cb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2327-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch
@@ -1,25 +1,18 @@
-From 798fcdd010006e87b3154d6454c657af7b033002 Mon Sep 17 00:00:00 2001
-From: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
-Date: Tue, 24 Mar 2020 15:49:55 +0900
-Subject: [PATCH] mtd: spinand: toshiba: Support for new Kioxia Serial NAND
+From 1d16ff587875717c950c983af8eaa474d0a855ca Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:13 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2327-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch]
-Add support for new Kioxia products.
-The new Kioxia products support program load x4 command, and have
-HOLD_D bit which is equivalent to QE bit.
-
-Signed-off-by: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
-Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
-Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
-Link: https://lore.kernel.org/linux-mtd/aa69e455beedc5ce0d7141359b9364ed8aec9e65.1584949601.git.ytc-mb-yfuruyama7@kioxia.com
---
drivers/mtd/nand/spi/toshiba.c | 128 ++++++++++++++++++++++++++++-----
1 file changed, 111 insertions(+), 17 deletions(-)
diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
-index 5d217dd4b2539a..bc801d83343e5c 100644
+index 7ce5997dd..be51a2eaf 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
-@@ -20,6 +20,18 @@ static SPINAND_OP_VARIANTS(read_cache_variants,
+@@ -19,6 +19,18 @@ static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
@@ -38,7 +31,7 @@
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD(true, 0, NULL, 0));
-@@ -95,7 +107,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
+@@ -94,7 +106,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
}
static const struct spinand_info toshiba_spinand_table[] = {
@@ -47,7 +40,7 @@
SPINAND_INFO("TC58CVG0S3HRAIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-@@ -106,7 +118,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
+@@ -105,7 +117,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
0,
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
tx58cxgxsxraix_ecc_get_status)),
@@ -56,7 +49,7 @@
SPINAND_INFO("TC58CVG1S3HRAIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-@@ -117,7 +129,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
+@@ -116,7 +128,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
0,
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
tx58cxgxsxraix_ecc_get_status)),
@@ -65,7 +58,7 @@
SPINAND_INFO("TC58CVG2S0HRAIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
-@@ -128,18 +140,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
+@@ -127,18 +139,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
0,
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
tx58cxgxsxraix_ecc_get_status)),
@@ -85,7 +78,7 @@
SPINAND_INFO("TC58CYG0S3HRAIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
-@@ -150,7 +151,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
+@@ -149,7 +150,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
0,
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
tx58cxgxsxraix_ecc_get_status)),
@@ -94,7 +87,7 @@
SPINAND_INFO("TC58CYG1S3HRAIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
-@@ -161,7 +162,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
+@@ -160,7 +161,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
0,
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
tx58cxgxsxraix_ecc_get_status)),
@@ -103,7 +96,7 @@
SPINAND_INFO("TC58CYG2S0HRAIG",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
-@@ -172,6 +173,99 @@ static const struct spinand_info toshiba_spinand_table[] = {
+@@ -171,6 +172,99 @@ static const struct spinand_info toshiba_spinand_table[] = {
0,
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
tx58cxgxsxraix_ecc_get_status)),
@@ -203,3 +196,6 @@
};
static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2360-v5.16-spi-add-power-control-when-set_cs.patch
similarity index 62%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2360-v5.16-spi-add-power-control-when-set_cs.patch
index f3e7940..1016204 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/827-v5.16-spi-add-power-control-when-set_cs.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2360-v5.16-spi-add-power-control-when-set_cs.patch
@@ -1,14 +1,15 @@
-drivers: spi: backport PM improvement for SPI framework
+From 0078d23c468b3b3fd73d65f1652de0b355b95081 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:18 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2360-v5.16-spi-add-power-control-when-set_cs.patch]
-Fix PM improvement for SPI framework.
-As to set_cs takes effect immediately, power spi
-is needed when setup spi.
+---
+ drivers/spi/spi.c | 24 +++++++++++++++++++++++-
+ 1 file changed, 23 insertions(+), 1 deletion(-)
-(cherry picked from commit d948e6ca189985495a21cd622c31e30e72b6b688)
-Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=d948e6ca189985495a21cd622c31e30e72b6b688
-(cherry picked from commit 57a9460705f105e1d79d1410c5cfe285beda8986)
-Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=57a9460705f105e1d79d1410c5cfe285beda8986
-
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 197a47eab..e562735a3 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3170,7 +3170,29 @@ int spi_setup(struct spi_device *spi)
@@ -43,5 +44,5 @@
if (spi->rt && !spi->controller->rt) {
spi->controller->rt = true;
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2700-v5.7-iopoll-introduce-read_poll_timeout-macro.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2700-v5.7-iopoll-introduce-read_poll_timeout-macro.patch
new file mode 100644
index 0000000..d7fc25c
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2700-v5.7-iopoll-introduce-read_poll_timeout-macro.patch
@@ -0,0 +1,176 @@
+From bc97a676615bd0ec66bb2a2a42c939455bf5bed6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:27 +0800
+Subject: [PATCH]
+ [networking][999-2700-v5.7-iopoll-introduce-read_poll_timeout-macro.patch]
+
+---
+ drivers/net/phy/phy_device.c | 16 +++++----------
+ include/linux/iopoll.h | 40 +++++++++++++++++++++++++++++-------
+ include/linux/phy.h | 27 ++++++++++++++++++++++++
+ 3 files changed, 65 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 76a68bb02..0349801df 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1056,18 +1056,12 @@ EXPORT_SYMBOL(phy_disconnect);
+ static int phy_poll_reset(struct phy_device *phydev)
+ {
+ /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
+- unsigned int retries = 12;
+- int ret;
+-
+- do {
+- msleep(50);
+- ret = phy_read(phydev, MII_BMCR);
+- if (ret < 0)
+- return ret;
+- } while (ret & BMCR_RESET && --retries);
+- if (ret & BMCR_RESET)
+- return -ETIMEDOUT;
++ int ret, val;
+
++ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
++ 50000, 600000, true);
++ if (ret)
++ return ret;
+ /* Some chips (smsc911x) may still need up to another 1ms after the
+ * BMCR_RESET bit is cleared before they are usable.
+ */
+diff --git a/include/linux/iopoll.h b/include/linux/iopoll.h
+index 35e15dfd4..cb20c733b 100644
+--- a/include/linux/iopoll.h
++++ b/include/linux/iopoll.h
+@@ -14,36 +14,41 @@
+ #include <linux/io.h>
+
+ /**
+- * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
+- * @op: accessor function (takes @addr as its only argument)
+- * @addr: Address to poll
++ * read_poll_timeout - Periodically poll an address until a condition is
++ * met or a timeout occurs
++ * @op: accessor function (takes @args as its arguments)
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @sleep_us: Maximum time to sleep between reads in us (0
+ * tight-loops). Should be less than ~20ms since usleep_range
+ * is used (see Documentation/timers/timers-howto.rst).
+ * @timeout_us: Timeout in us, 0 means never timeout
++ * @sleep_before_read: if it is true, sleep @sleep_us before read.
++ * @args: arguments for @op poll
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
+- * case, the last read value at @addr is stored in @val. Must not
++ * case, the last read value at @args is stored in @val. Must not
+ * be called from atomic context if sleep_us or timeout_us are used.
+ *
+ * When available, you'll probably want to use one of the specialized
+ * macros defined below rather than this macro directly.
+ */
+-#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
++#define read_poll_timeout(op, val, cond, sleep_us, timeout_us, \
++ sleep_before_read, args...) \
+ ({ \
+ u64 __timeout_us = (timeout_us); \
+ unsigned long __sleep_us = (sleep_us); \
+ ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
+ might_sleep_if((__sleep_us) != 0); \
++ if (sleep_before_read && __sleep_us) \
++ usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
+ for (;;) { \
+- (val) = op(addr); \
++ (val) = op(args); \
+ if (cond) \
+ break; \
+ if (__timeout_us && \
+ ktime_compare(ktime_get(), __timeout) > 0) { \
+- (val) = op(addr); \
++ (val) = op(args); \
+ break; \
+ } \
+ if (__sleep_us) \
+@@ -52,6 +57,27 @@
+ (cond) ? 0 : -ETIMEDOUT; \
+ })
+
++/**
++ * readx_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs
++ * @op: accessor function (takes @addr as its only argument)
++ * @addr: Address to poll
++ * @val: Variable to read the value into
++ * @cond: Break condition (usually involving @val)
++ * @sleep_us: Maximum time to sleep between reads in us (0
++ * tight-loops). Should be less than ~20ms since usleep_range
++ * is used (see Documentation/timers/timers-howto.rst).
++ * @timeout_us: Timeout in us, 0 means never timeout
++ *
++ * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
++ * case, the last read value at @addr is stored in @val. Must not
++ * be called from atomic context if sleep_us or timeout_us are used.
++ *
++ * When available, you'll probably want to use one of the specialized
++ * macros defined below rather than this macro directly.
++ */
++#define readx_poll_timeout(op, addr, val, cond, sleep_us, timeout_us) \
++ read_poll_timeout(op, val, cond, sleep_us, timeout_us, false, addr)
++
+ /**
+ * readx_poll_timeout_atomic - Periodically poll an address until a condition is met or a timeout occurs
+ * @op: accessor function (takes @addr as its only argument)
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index a1070d60e..107dcbea4 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -21,6 +21,7 @@
+ #include <linux/timer.h>
+ #include <linux/workqueue.h>
+ #include <linux/mod_devicetable.h>
++#include <linux/iopoll.h>
+
+ #include <linux/atomic.h>
+
+@@ -714,6 +715,19 @@ static inline int phy_read(struct phy_device *phydev, u32 regnum)
+ return mdiobus_read(phydev->mdio.bus, phydev->mdio.addr, regnum);
+ }
+
++#define phy_read_poll_timeout(phydev, regnum, val, cond, sleep_us, \
++ timeout_us, sleep_before_read) \
++({ \
++ int __ret = read_poll_timeout(phy_read, val, (cond) || val < 0, \
++ sleep_us, timeout_us, sleep_before_read, phydev, regnum); \
++ if (val < 0) \
++ __ret = val; \
++ if (__ret) \
++ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
++ __ret; \
++})
++
++
+ /**
+ * __phy_read - convenience function for reading a given PHY register
+ * @phydev: the phy_device struct
+@@ -766,6 +780,19 @@ static inline int __phy_write(struct phy_device *phydev, u32 regnum, u16 val)
+ */
+ int phy_read_mmd(struct phy_device *phydev, int devad, u32 regnum);
+
++#define phy_read_mmd_poll_timeout(phydev, devaddr, regnum, val, cond, \
++ sleep_us, timeout_us, sleep_before_read) \
++({ \
++ int __ret = read_poll_timeout(phy_read_mmd, val, (cond) || val < 0, \
++ sleep_us, timeout_us, sleep_before_read, \
++ phydev, devaddr, regnum); \
++ if (val < 0) \
++ __ret = val; \
++ if (__ret) \
++ phydev_err(phydev, "%s failed: %d\n", __func__, __ret); \
++ __ret; \
++})
++
+ /**
+ * __phy_read_mmd - Convenience function for reading a register
+ * from an MMD on a given PHY.
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/791-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2701-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch
similarity index 66%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/791-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2701-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch
index b47f2bf..e74f20b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/791-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2701-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch
@@ -1,97 +1,20 @@
-From patchwork Wed May 6 14:53:13 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Michael Walle <michael@walle.cc>
-X-Patchwork-Id: 1284481
-X-Patchwork-Delegate: davem@davemloft.net
-Return-Path: <netdev-owner@vger.kernel.org>
-X-Original-To: patchwork-incoming-netdev@ozlabs.org
-Delivered-To: patchwork-incoming-netdev@ozlabs.org
-Authentication-Results: ozlabs.org;
- spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org
- (client-ip=23.128.96.18; helo=vger.kernel.org;
- envelope-from=netdev-owner@vger.kernel.org; receiver=<UNKNOWN>)
-Authentication-Results: ozlabs.org;
- dmarc=none (p=none dis=none) header.from=walle.cc
-Authentication-Results: ozlabs.org;
- dkim=pass (1024-bit key;
- secure) header.d=walle.cc header.i=@walle.cc header.a=rsa-sha256
- header.s=mail2016061301 header.b=m9HhLh3d;
- dkim-atps=neutral
-Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
- by ozlabs.org (Postfix) with ESMTP id 49HKQ62Q28z9sSG
- for <patchwork-incoming-netdev@ozlabs.org>;
- Thu, 7 May 2020 00:55:10 +1000 (AEST)
-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
- id S1729301AbgEFOzD (ORCPT
- <rfc822;patchwork-incoming-netdev@ozlabs.org>);
- Wed, 6 May 2020 10:55:03 -0400
-Received: from ssl.serverraum.org ([176.9.125.105]:43029 "EHLO
- ssl.serverraum.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
- with ESMTP id S1729078AbgEFOzC (ORCPT
- <rfc822;netdev@vger.kernel.org>); Wed, 6 May 2020 10:55:02 -0400
-Received: from apollo.fritz.box (unknown
- [IPv6:2a02:810c:c200:2e91:6257:18ff:fec4:ca34])
- (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
- key-exchange ECDHE (P-384) server-signature RSA-PSS (2048 bits)
- server-digest SHA256)
- (No client certificate requested)
- by ssl.serverraum.org (Postfix) with ESMTPSA id 2354022EEB;
- Wed, 6 May 2020 16:54:57 +0200 (CEST)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=walle.cc;
- s=mail2016061301;
- t=1588776897;
- h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
- to:to:cc:cc:mime-version:mime-version:
- content-transfer-encoding:content-transfer-encoding:
- in-reply-to:in-reply-to:references:references;
- bh=Y1HXOD90+xthCbcF5aODRvO5s4y3GjqVZeWMcm2C9hg=;
- b=m9HhLh3dnD9BTg85PIRYHxEzW+9tKI8srVGI3MjgXJkJaWDcnUKGyPN86orzkyHrB0ai5O
- VyiY7R2tdN04JifV18FNmxuUW/9Pc3kWUfo+q974YzVhTm0Tkrc3osn/smhyhl7PxpHZMl
- VHiTEHII3umwamTkGQq8kpYUr38joLY=
-From: Michael Walle <michael@walle.cc>
-To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org
-Cc: Andrew Lunn <andrew@lunn.ch>,
- Florian Fainelli <f.fainelli@gmail.com>,
- Heiner Kallweit <hkallweit1@gmail.com>,
- Russell King <linux@armlinux.org.uk>,
- "David S . Miller" <davem@davemloft.net>,
- Vladimir Oltean <vladimir.oltean@nxp.com>,
- Antoine Tenart <antoine.tenart@bootlin.com>,
- Michael Walle <michael@walle.cc>
-Subject: [PATCH net-next v3 1/3] net: phy: add concept of shared storage for
- PHYs
-Date: Wed, 6 May 2020 16:53:13 +0200
-Message-Id: <20200506145315.13967-2-michael@walle.cc>
-X-Mailer: git-send-email 2.20.1
-In-Reply-To: <20200506145315.13967-1-michael@walle.cc>
-References: <20200506145315.13967-1-michael@walle.cc>
-MIME-Version: 1.0
-X-Spam: Yes
-Sender: netdev-owner@vger.kernel.org
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
+From 2dca4de7282d3003f3703f707d773f4dbbc0f28e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:27 +0800
+Subject: [PATCH]
+ [networking][999-2701-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch]
-There are packages which contain multiple PHY devices, eg. a quad PHY
-transceiver. Provide functions to allocate and free shared storage.
-
-Usually, a quad PHY contains global registers, which don't belong to any
-PHY. Provide convenience functions to access these registers.
-
-Signed-off-by: Michael Walle <michael@walle.cc>
-Reviewed-by: Andrew Lunn <andrew@lunn.ch>
-Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/mdio_bus.c | 1 +
drivers/net/phy/phy_device.c | 138 +++++++++++++++++++++++++++++++++++
include/linux/phy.h | 89 ++++++++++++++++++++++
3 files changed, 228 insertions(+)
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
+index fdf8221f4..d9f2cee33 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
-@@ -404,6 +404,7 @@ int __mdiobus_register(struct mii_bus *b
+@@ -404,6 +404,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner)
}
mutex_init(&bus->mdio_lock);
@@ -99,12 +22,15 @@
/* de-assert bus level PHY GPIO reset */
gpiod = devm_gpiod_get_optional(&bus->dev, "reset", GPIOD_OUT_LOW);
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 0349801df..99f265a1c 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
-@@ -1448,6 +1448,144 @@ bool phy_driver_is_genphy_10g(struct phy
+@@ -1447,6 +1447,144 @@ bool phy_driver_is_genphy_10g(struct phy_device *phydev)
+ }
EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g);
- /**
++/**
+ * phy_package_join - join a common PHY group
+ * @phydev: target phy_device struct
+ * @addr: cookie and PHY address for global register access
@@ -242,10 +168,11 @@
+}
+EXPORT_SYMBOL_GPL(devm_phy_package_join);
+
-+/**
+ /**
* phy_detach - detach a PHY device from its network device
* @phydev: target phy_device struct
- *
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 107dcbea4..d26dba255 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -22,6 +22,7 @@
@@ -256,7 +183,7 @@
#include <linux/atomic.h>
-@@ -208,6 +209,28 @@ struct sfp_bus;
+@@ -211,6 +212,28 @@ struct sfp_bus;
struct sfp_upstream_ops;
struct sk_buff;
@@ -285,7 +212,7 @@
/*
* The Bus class for PHYs. Devices which provide access to
* PHYs should register using this structure
-@@ -255,6 +278,12 @@ struct mii_bus {
+@@ -258,6 +281,12 @@ struct mii_bus {
int reset_delay_us;
/* RESET GPIO descriptor pointer */
struct gpio_desc *reset_gpiod;
@@ -298,7 +225,7 @@
};
#define to_mii_bus(d) container_of(d, struct mii_bus, dev)
-@@ -434,6 +463,10 @@ struct phy_device {
+@@ -437,6 +466,10 @@ struct phy_device {
/* For use by PHYs to maintain extra state */
void *priv;
@@ -309,7 +236,7 @@
/* Interrupt and Polling infrastructure */
struct delayed_work state_queue;
-@@ -1232,6 +1265,10 @@ int phy_ethtool_get_link_ksettings(struc
+@@ -1242,6 +1275,10 @@ int phy_ethtool_get_link_ksettings(struct net_device *ndev,
int phy_ethtool_set_link_ksettings(struct net_device *ndev,
const struct ethtool_link_ksettings *cmd);
int phy_ethtool_nway_reset(struct net_device *ndev);
@@ -320,7 +247,7 @@
#if IS_ENABLED(CONFIG_PHYLIB)
int __init mdio_bus_init(void);
-@@ -1284,6 +1321,58 @@ static inline int phy_ethtool_get_stats(
+@@ -1294,6 +1331,58 @@ static inline int phy_ethtool_get_stats(struct phy_device *phydev,
return 0;
}
@@ -379,3 +306,6 @@
extern struct bus_type mdio_bus_type;
struct mdio_board_info {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2702-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2702-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch
new file mode 100644
index 0000000..c2f2c10
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2702-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch
@@ -0,0 +1,55 @@
+From 3fc10755d5f6a5618519f2b5b3a68febfc5984b0 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:27 +0800
+Subject: [PATCH]
+ [networking][999-2702-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch]
+
+---
+ include/linux/phy.h | 18 +++++++++++++++---
+ 1 file changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index d26dba255..4f2c105f5 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -232,7 +232,8 @@ struct phy_package_shared {
+ };
+
+ /* used as bit number in atomic bitops */
+-#define PHY_SHARED_F_INIT_DONE 0
++#define PHY_SHARED_F_INIT_DONE 0
++#define PHY_SHARED_F_PROBE_DONE 1
+
+ /*
+ * The Bus class for PHYs. Devices which provide access to
+@@ -1373,14 +1374,25 @@ static inline int __phy_package_write(struct phy_device *phydev,
+ return __mdiobus_write(phydev->mdio.bus, shared->addr, regnum, val);
+ }
+
+-static inline bool phy_package_init_once(struct phy_device *phydev)
++static inline bool __phy_package_set_once(struct phy_device *phydev,
++ unsigned int b)
+ {
+ struct phy_package_shared *shared = phydev->shared;
+
+ if (!shared)
+ return false;
+
+- return !test_and_set_bit(PHY_SHARED_F_INIT_DONE, &shared->flags);
++ return !test_and_set_bit(b, &shared->flags);
++}
++
++static inline bool phy_package_init_once(struct phy_device *phydev)
++{
++ return __phy_package_set_once(phydev, PHY_SHARED_F_INIT_DONE);
++}
++
++static inline bool phy_package_probe_once(struct phy_device *phydev)
++{
++ return __phy_package_set_once(phydev, PHY_SHARED_F_PROBE_DONE);
+ }
+
+ extern struct bus_type mdio_bus_type;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/793-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2703-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch
similarity index 63%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/793-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2703-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch
index 83df94a..3551935 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/793-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/999-2703-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch
@@ -1,17 +1,19 @@
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -92,6 +92,8 @@ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c
- obj-$(CONFIG_LXT_PHY) += lxt.o
- obj-$(CONFIG_MARVELL_PHY) += marvell.o
- obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o
-+obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
-+obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
- obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
- obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
- obj-$(CONFIG_MICREL_PHY) += micrel.o
+From 0e0b69abbc9fdba0bf1ea723cee71b2a2402559e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:28 +0800
+Subject: [PATCH]
+ [networking][999-2703-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch]
+
+---
+ drivers/net/phy/Kconfig | 17 +++++++++++++++++
+ drivers/net/phy/Makefile | 2 ++
+ 2 files changed, 19 insertions(+)
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 5eeccfee2..ec5c66d0a 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
-@@ -507,6 +507,23 @@ config MESON_GXL_PHY
+@@ -512,6 +512,23 @@ config MESON_GXL_PHY
---help---
Currently has a driver for the Amlogic Meson GXL Internal PHY
@@ -35,3 +37,19 @@
config MICREL_PHY
tristate "Micrel PHYs"
---help---
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index 437ff2a2c..f4feb0e3d 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -94,6 +94,8 @@ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
+ obj-$(CONFIG_LXT_PHY) += lxt.o
+ obj-$(CONFIG_MARVELL_PHY) += marvell.o
+ obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o
++obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
++obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
+ obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
+ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
+ obj-$(CONFIG_MICREL_PHY) += micrel.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
index aab01cf..23bf73b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/backport-5.4/backport-5.4.inc
@@ -163,9 +163,7 @@
file://406-v5.13-0003-dt-bindings-mtd-Document-use-of-nvmem-cells-compatib.patch \
file://407-v5.13-0001-dt-bindings-mtd-add-binding-for-Linksys-Northstar-pa.patch \
file://407-v5.13-0002-mtd-parsers-ofpart-support-Linksys-Northstar-partiti.patch \
- file://408-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch \
file://410-mtd-fix-calculating-partition-end-address.patch \
- file://411-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch \
file://412-v5.19-mtd-call-of_platform_populate-for-MTD-partitions.patch \
file://413-v6.0-mtd-next-mtd-core-introduce-of-support-for-dynamic-partitions.patch \
file://414-v6.1-mtd-allow-getting-MTD-device-associated-with-a-speci.patch \
@@ -174,23 +172,7 @@
file://417-v6.2-0001-mtd-core-simplify-a-bit-code-find-partition-matching.patch \
file://417-v6.2-0002-mtd-core-try-to-find-OF-node-for-every-MTD-partition.patch \
file://420-v6.2-mtd-parsers-add-TP-Link-SafeLoader-partitions-table-.patch \
- file://430-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch \
file://430-v6.3-ubi-Fix-failure-attaching-when-vid_hdr-offset-equals.patch \
- file://431-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch \
- file://432-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch \
- file://433-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch \
- file://434-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch \
- file://435-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch \
- file://450-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch \
- file://451-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch \
- file://452-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch \
- file://453-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch \
- file://454-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch \
- file://455-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch \
- file://456-mtd-spinand-micron-Use-more-specific-names.patch \
- file://457-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch \
- file://470-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch \
- file://471-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch \
file://600-v5.12-net-extract-napi-poll-functionality-to-__napi_poll.patch \
file://601-v5.12-net-implement-threaded-able-napi-poll-loop-support.patch \
file://602-v5.12-net-add-sysfs-attribute-to-control-napi-threaded-mod.patch \
@@ -270,10 +252,6 @@
file://780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch \
file://781-v5.18-1-net-dsa-Move-VLAN-filtering-syncing-out-of-dsa_switc.patch \
file://781-v5.18-2-net-dsa-Avoid-cross-chip-syncing-of-VLAN-filtering.patch \
- file://790-v5.7-iopoll-introduce-read_poll_timeout-macro.patch \
- file://791-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch \
- file://792-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch;apply=no \
- file://793-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch \
file://800-v5.5-iio-imu-Add-support-for-the-FXOS8700-IMU.patch \
file://800-v5.5-scsi-core-Add-sysfs-attributes-for-VPD-pages-0h-and-.patch \
file://801-v5.19-nvmem-core-support-passing-DT-node-in-cell-info.patch \
@@ -304,7 +282,6 @@
file://822-v6.2-0003-nvmem-u-boot-env-add-Broadcom-format-support.patch \
file://825-v5.8-spi-rb4xx-null-pointer-bug-fix.patch \
file://826-v5.8-spi-rb4xx-update-driver-to-be-device-tree-aware.patch \
- file://827-v5.16-spi-add-power-control-when-set_cs.patch \
file://831-v5.13-0001-firmware-bcm47xx_nvram-rename-finding-function-and-i.patch \
file://831-v5.13-0002-firmware-bcm47xx_nvram-add-helper-checking-for-NVRAM.patch \
file://831-v5.13-0003-firmware-bcm47xx_nvram-extract-code-copying-NVRAM.patch \
@@ -320,5 +297,29 @@
file://900-v5.9-0001-dt-bindings-Add-multicolor-class-dt-bindings-documen.patch \
file://900-v5.9-0002-leds-Add-multicolor-ID-to-the-color-ID-list.patch \
file://900-v5.9-0003-leds-add-RGB-color-option-as-that-is-different-from-.patch \
+ file://999-2210-v6.1-iio-adc-add-rtq6056-support.patch \
+ file://999-2310-v5.7-mtd-nand-spi-rework-detect-procedure-for-different-read-id-op.patch \
+ file://999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch \
+ file://999-2312-mtd-spinand-macronix-Add-support-for-MX31LF1GE4BC.patch \
+ file://999-2313-mtd-spinand-macronix-Add-support-for-MX31UF1GE4BC.patch \
+ file://999-2314-mtd-spinand-macronix-Add-support-for-MX35LFxGE4AD.patch \
+ file://999-2315-mtd-spinand-macronix-Add-support-for-MX35LFxG24AD.patch \
+ file://999-2316-mtd-spinand-macronix-Add-support-for-serial-NAND-flash.patch \
+ file://999-2317-mtd-spinand-macronix-Add-Quad-support-for-serial-NAND-flash.patch \
+ file://999-2318-mtd-spinand-micron-Generalize-the-OOB-layout-structure-and-function-names.patch \
+ file://999-2319-mtd-spinand-micron-Describe-the-SPI-NAND-device-MT29F2G01ABAGD.patch \
+ file://999-2320-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices.patch \
+ file://999-2321-mtd-spinand-micron-identify-SPI-NAND-device-with-Continuous-Read-mode.patch \
+ file://999-2322-mtd-spinand-micron-Add-M70A-series-Micron-SPI-NAND-devices.patch \
+ file://999-2323-mtd-spinand-micron-Add-new-Micron-SPI-NAND-devices-with-multiple-dies.patch \
+ file://999-2324-mtd-spinand-micron-Use-more-specific-names.patch \
+ file://999-2325-mtd-spinand-micron-Add-support-for-MT29F2G01AAAED.patch \
+ file://999-2326-mtd-spinand-toshiba-Rename-function-name-to-change-suffix-and-prefix-8Gbit.patch \
+ file://999-2327-mtd-spinand-toshiba-Support-for-new-Kioxia-Serial-NAND.patch \
+ file://999-2360-v5.16-spi-add-power-control-when-set_cs.patch \
+ file://999-2700-v5.7-iopoll-introduce-read_poll_timeout-macro.patch \
+ file://999-2701-v5.8-net-phy-add-concept-of-shared-storage-for-PHYs.patch \
+ file://999-2702-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch;apply=no \
+ file://999-2703-net-phy-backport-v5.4-mediatek-ge-and-v6.4-mediatek-ge-soc.patch \
file://999-update-uapi-header-files-for-bridger.patch \
"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c b/recipes-kernel/linux/linux-mediatek-5.4/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c
index 1ddcf67..1cafc91 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm_wfi.c
@@ -31,6 +31,7 @@
#define CFERAM_NAME "cferam"
#define CFERAM_NAME_LEN (sizeof(CFERAM_NAME) - 1)
+#define CFERAM_NAME_MAX_LEN 32
#define KERNEL_NAME "vmlinux.lz"
#define KERNEL_NAME_LEN (sizeof(KERNEL_NAME) - 1)
#define OPENWRT_NAME "1-openwrt"
@@ -157,17 +158,28 @@
const struct mtd_partition **pparts,
uint8_t *buf, loff_t off, loff_t size, bool cfe_part)
{
+ struct device_node *mtd_node;
struct mtd_partition *parts;
loff_t cfe_off, kernel_off, rootfs_off;
unsigned int num_parts = BCM_WFI_PARTS, cur_part = 0;
+ const char *cferam_name = CFERAM_NAME;
+ size_t cferam_name_len;
int ret;
+ mtd_node = mtd_get_of_node(master);
+ if (mtd_node)
+ of_property_read_string(mtd_node, "brcm,cferam", &cferam_name);
+
+ cferam_name_len = strnlen(cferam_name, CFERAM_NAME_MAX_LEN);
+ if (cferam_name_len > 0)
+ cferam_name_len--;
+
if (cfe_part) {
num_parts++;
cfe_off = off;
- ret = jffs2_find_file(master, buf, CFERAM_NAME,
- CFERAM_NAME_LEN, &cfe_off,
+ ret = jffs2_find_file(master, buf, cferam_name,
+ cferam_name_len, &cfe_off,
size - (cfe_off - off), NULL, NULL);
if (ret)
return ret;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/930-cmdline-boot-parameters.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/999-2540-cmdline-boot-parameters.patch
similarity index 72%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/930-cmdline-boot-parameters.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/999-2540-cmdline-boot-parameters.patch
index 6a6c8a6..eadc288 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/930-cmdline-boot-parameters.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/999-2540-cmdline-boot-parameters.patch
@@ -1,6 +1,19 @@
+From 32fdf519125a828c6fbbbc8dfdfda22791e710e6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:24 +0800
+Subject: [PATCH] [adv-feature][999-2540-cmdline-boot-parameters.patch]
+
+---
+ kernel/Makefile | 2 ++
+ kernel/boot_param.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+)
+ create mode 100644 kernel/boot_param.c
+
+diff --git a/kernel/Makefile b/kernel/Makefile
+index d038b0de8..be219c6ca 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
-@@ -12,6 +12,8 @@ obj-y = fork.o exec_domain.o panic.o
+@@ -12,6 +12,8 @@ obj-y = fork.o exec_domain.o panic.o \
notifier.o ksysfs.o cred.o reboot.o \
async.o range.o smpboot.o ucount.o
@@ -9,7 +22,10 @@
obj-$(CONFIG_MODULES) += kmod.o
obj-$(CONFIG_MULTIUSER) += groups.o
---- a/kernel/boot_param.c
+diff --git a/kernel/boot_param.c b/kernel/boot_param.c
+new file mode 100644
+index 000000000..3dfe828bc
+--- /dev/null
+++ b/kernel/boot_param.c
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
@@ -56,3 +72,6 @@
+
+static char env_part[BOOT_PARAM_STR_MAX_LEN];
+module_param_string(env_part, env_part, BOOT_PARAM_STR_MAX_LEN, 0444);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/hack-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/hack-5.4.inc
index 431e127..11b86e3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/hack-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/hack-5.4/hack-5.4.inc
@@ -41,5 +41,5 @@
file://910-kobject_uevent.patch \
file://911-kobject_add_broadcast_uevent.patch \
file://921-always-create-console-node-in-initramfs.patch \
- file://930-cmdline-boot-parameters.patch \
+ file://999-2540-cmdline-boot-parameters.patch \
"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/499-mtd-add-nmbm-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/499-mtd-add-nmbm-support.patch
deleted file mode 100644
index 5cbaae2..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/499-mtd-add-nmbm-support.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -228,6 +228,8 @@ source "drivers/mtd/ubi/Kconfig"
-
- source "drivers/mtd/hyperbus/Kconfig"
-
-+source "drivers/mtd/nmbm/Kconfig"
-+
- source "drivers/mtd/composite/Kconfig"
-
- endif # MTD
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -33,5 +33,7 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
- obj-$(CONFIG_MTD_UBI) += ubi/
- obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
-
-+obj-y += nmbm/
-+
- # Composite drivers must be loaded last
- obj-y += composite/
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2328-mtd-add-nmbm-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2328-mtd-add-nmbm-support.patch
new file mode 100644
index 0000000..1ed432c
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2328-mtd-add-nmbm-support.patch
@@ -0,0 +1,38 @@
+From 648532e848587a525aa02add84b119844a4aabc3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:14 +0800
+Subject: [PATCH] [spi-and-storage][999-2328-mtd-add-nmbm-support.patch]
+
+---
+ drivers/mtd/Kconfig | 2 ++
+ drivers/mtd/Makefile | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
+index 503f19763..3ed42b402 100644
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -228,6 +228,8 @@ source "drivers/mtd/ubi/Kconfig"
+
+ source "drivers/mtd/hyperbus/Kconfig"
+
++source "drivers/mtd/nmbm/Kconfig"
++
+ source "drivers/mtd/composite/Kconfig"
+
+ endif # MTD
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index 147e79596..f27f66784 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -33,5 +33,7 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
+ obj-$(CONFIG_MTD_UBI) += ubi/
+ obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
+
++obj-y += nmbm/
++
+ # Composite drivers must be loaded last
+ obj-y += composite/
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2329-ubi-add-configurable-rootdev.patch
similarity index 66%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2329-ubi-add-configurable-rootdev.patch
index e0102c7..1ee6142 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/500-ubi-add-configurable-rootdev.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2329-ubi-add-configurable-rootdev.patch
@@ -1,3 +1,15 @@
+From 27ae9a1b684cd183ccf6881d32710b8890113d20 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:14 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2329-ubi-add-configurable-rootdev.patch]
+
+---
+ drivers/mtd/ubi/block.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
+index 873f9cb24..33e969fd3 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -97,6 +97,12 @@ static DEFINE_IDR(ubiblock_minor_idr);
@@ -13,7 +25,7 @@
static int __init ubiblock_set_param(const char *val,
const struct kernel_param *kp)
{
-@@ -460,8 +466,9 @@ int ubiblock_create(struct ubi_volume_in
+@@ -460,8 +466,9 @@ int ubiblock_create(struct ubi_volume_info *vi)
dev->ubi_num, dev->vol_id, vi->name);
mutex_unlock(&devices_mutex);
@@ -24,7 +36,7 @@
ROOT_DEV == 0) {
pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n",
dev->ubi_num, dev->vol_id, vi->name);
-@@ -681,7 +688,7 @@ static void __init ubiblock_create_auto_
+@@ -681,7 +688,7 @@ static void __init ubiblock_create_auto_rootfs(void)
struct ubi_volume_info vi;
for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) {
@@ -33,3 +45,6 @@
if (IS_ERR(desc))
continue;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2704-netfilter_optional_tcp_window_check.patch
similarity index 69%
rename from recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2704-netfilter_optional_tcp_window_check.patch
index f6a3a82..0aea6d3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/613-netfilter_optional_tcp_window_check.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/999-2704-netfilter_optional_tcp_window_check.patch
@@ -1,11 +1,16 @@
-From: Felix Fietkau <nbd@nbd.name>
-Subject: netfilter: optional tcp window check
+From 1f85572a62a39799a9bac846d46965d9a57a1e24 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:28 +0800
+Subject: [PATCH]
+ [networking][999-2704-netfilter_optional_tcp_window_check.patch]
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
- net/netfilter/nf_conntrack_proto_tcp.c | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
+ net/netfilter/nf_conntrack_proto_tcp.c | 8 +++++++-
+ net/netfilter/nf_conntrack_standalone.c | 11 +++++++++++
+ 2 files changed, 18 insertions(+), 1 deletion(-)
+diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
+index aed967e2f..e219b6f34 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -31,6 +31,9 @@
@@ -18,7 +23,7 @@
/* "Be conservative in what you do,
be liberal in what you accept from others."
If it's non-zero, we mark only out of window RST segments as INVALID. */
-@@ -476,6 +479,9 @@ static bool tcp_in_window(const struct n
+@@ -476,6 +479,9 @@ static bool tcp_in_window(const struct nf_conn *ct,
s32 receiver_offset;
bool res, in_recv_win;
@@ -28,7 +33,7 @@
/*
* Get the required data from the packet.
*/
-@@ -1139,7 +1145,7 @@ int nf_conntrack_tcp_packet(struct nf_co
+@@ -1139,7 +1145,7 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct,
IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
timeout = timeouts[TCP_CONNTRACK_UNACK];
@@ -37,6 +42,8 @@
timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
timeout = timeouts[TCP_CONNTRACK_RETRANS];
else
+diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
+index 73415bf51..236954e4f 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -25,6 +25,9 @@
@@ -57,7 +64,7 @@
__NF_SYSCTL_CT_LAST_SYSCTL,
};
-@@ -969,6 +973,13 @@ static struct ctl_table nf_ct_sysctl_tab
+@@ -969,6 +973,13 @@ static struct ctl_table nf_ct_sysctl_table[] = {
.proc_handler = proc_dointvec_jiffies,
},
#endif
@@ -71,3 +78,6 @@
{}
};
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/pending-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/pending-5.4.inc
index 3ac355f..af11131 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/pending-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/generic/pending-5.4/pending-5.4.inc
@@ -65,15 +65,12 @@
file://496-dt-bindings-add-bindings-for-mtd-concat-devices.patch \
file://497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch \
file://498-mtd-mtdconcat-select-readwrite-function.patch \
- file://499-mtd-add-nmbm-support.patch \
- file://500-ubi-add-configurable-rootdev.patch \
file://530-jffs2_make_lzma_available.patch \
file://532-jffs2_eofdetect.patch \
file://600-netfilter_conntrack_flush.patch \
file://610-netfilter_match_bypass_default_checks.patch \
file://611-netfilter_match_bypass_default_table.patch \
file://612-netfilter_match_reduce_memory_access.patch \
- file://613-netfilter_optional_tcp_window_check.patch \
file://620-net_sched-codel-do-not-defer-queue-length-update.patch \
file://630-packet_socket_type.patch \
file://655-increase_skb_pad.patch \
@@ -123,4 +120,7 @@
file://834-ledtrig-libata.patch \
file://840-hwrng-bcm2835-set-quality-to-1000.patch \
file://920-mangle_bootargs.patch \
+ file://999-2328-mtd-add-nmbm-support.patch \
+ file://999-2329-ubi-add-configurable-rootdev.patch \
+ file://999-2704-netfilter_optional_tcp_window_check.patch \
"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi
index 820e8bb..81851a0 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986a.dtsi
@@ -124,9 +124,9 @@
#size-cells = <2>;
ranges;
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+ /* 256 KiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
+ reg = <0 0x43000000 0 0x40000>;
no-map;
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi
index 96c68a5..6fcfa57 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm/boot/dts/mt7986b.dtsi
@@ -124,9 +124,9 @@
#size-cells = <2>;
ranges;
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+ /* 256 KiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
+ reg = <0 0x43000000 0 0x40000>;
no-map;
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index 820e8bb..81851a0 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -124,9 +124,9 @@
#size-cells = <2>;
ranges;
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+ /* 256 KiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
+ reg = <0 0x43000000 0 0x40000>;
no-map;
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
index 96c68a5..6fcfa57 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7986b.dtsi
@@ -124,9 +124,9 @@
#size-cells = <2>;
ranges;
- /* 192 KiB reserved for ARM Trusted Firmware (BL31) */
+ /* 256 KiB reserved for ARM Trusted Firmware (BL31) */
secmon_reserved: secmon@43000000 {
- reg = <0 0x43000000 0 0x30000>;
+ reg = <0 0x43000000 0 0x40000>;
no-map;
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
index 98dc4df..9ef502b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988.dtsi
@@ -732,7 +732,7 @@
"eint";
gpio-controller;
#gpio-cells = <2>;
- gpio-ranges = <&pio 0 0 83>;
+ gpio-ranges = <&pio 0 0 84>;
interrupt-controller;
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gic>;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
index 9e2e9a9..2cf886c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-88d-10g-spim-nand.dts
@@ -263,7 +263,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts
index 201f9ee..bf2abb6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-emmc.dts
@@ -102,7 +102,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts
index d664a46..aa93f3c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-sd.dts
@@ -93,7 +93,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts
index c7e83fd..b8fb6aa 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-snfi-nand.dts
@@ -127,7 +127,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
index cf117ca..0f94eea 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nand.dts
@@ -182,6 +182,13 @@
compatible = "infineon,dps310";
reg = <0x77>;
};
+
+ rtq6056: rtq6056@40 {
+ compatible = "richtek,rtq6056";
+ reg = <0x40>;
+ shunt-resistor-micro-ohms = <10000>;
+ #io-channel-cells = <1>;
+ };
};
&spi0 {
@@ -258,7 +265,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
index a9fc3c5..70a7554 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
@@ -127,7 +127,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts
index 2a24f7d..7f7ddfd 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-dsa-i2p5g-spim-nand.dts
@@ -73,6 +73,58 @@
};
};
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ status = "okay";
+
+ rt5190a_64: rt5190a@64 {
+ compatible = "richtek,rt5190a";
+ reg = <0x64>;
+ /*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
+ vin2-supply = <&rt5190_buck1>;
+ vin3-supply = <&rt5190_buck1>;
+ vin4-supply = <&rt5190_buck1>;
+
+ regulators {
+ rt5190_buck1: buck1 {
+ regulator-name = "rt5190a-buck1";
+ regulator-min-microvolt = <5090000>;
+ regulator-max-microvolt = <5090000>;
+ regulator-allowed-modes =
+ <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ };
+ buck2 {
+ regulator-name = "vcore";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ };
+ buck3 {
+ regulator-name = "proc";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-boot-on;
+ };
+ buck4 {
+ regulator-name = "rt5190a-buck4";
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-allowed-modes =
+ <RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
+ regulator-boot-on;
+ };
+ ldo {
+ regulator-name = "rt5190a-ldo";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
&uart0 {
status = "okay";
};
@@ -166,6 +218,13 @@
};
};
+ i2c0_pins: i2c0-pins-g0 {
+ mux {
+ function = "i2c";
+ groups = "i2c0_1";
+ };
+ };
+
pcie0_pins: pcie0-pins {
mux {
function = "pcie";
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts
index fde3572..13e25e1 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand-4pcie.dts
@@ -213,7 +213,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
index 0941b06..3865bf8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988a-gsw-10g-spim-nand.dts
@@ -229,7 +229,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts
index ba29680..8e5751b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-emmc.dts
@@ -102,7 +102,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts
index 133da0c..a681b8b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-sd.dts
@@ -93,7 +93,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-snfi-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-snfi-nand.dts
index 7721c07..6a7773f 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-snfi-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-snfi-nand.dts
@@ -127,7 +127,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
index 06b5702..d7df193 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nand.dts
@@ -247,7 +247,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
index 61cdf7b..4f281a3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
@@ -127,7 +127,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts
index a86e77e..1b04950 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7988d-gsw-10g-spim-nand.dts
@@ -223,7 +223,7 @@
conf {
groups = "mdc_mdio0";
- drive-strength = <MTK_DRIVE_8mA>;
+ drive-strength = <MTK_DRIVE_10mA>;
};
};
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
index 9987630..1b5d356 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.c
@@ -41,8 +41,10 @@
u32 hw_lro_norule_flush_cnt[MTK_HW_LRO_RING_NUM];
u32 mtk_hwlro_stats_ebl;
u32 dbg_show_level;
+u32 cur_rss_num;
-static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb;
+static struct proc_dir_entry *proc_hw_lro_stats, *proc_hw_lro_auto_tlb,
+ *proc_rss_ctrl;
typedef int (*mtk_lro_dbg_func) (int par);
struct mtk_eth_debug {
@@ -302,10 +304,10 @@
if (kstrtoul(token, 16, (unsigned long *)&value))
return -EINVAL;
- pr_info("%s:phy=%d, reg=0x%x, val=0x%x\n", __func__,
+ pr_info("%s:phy=%d, reg=0x%lx, val=0x%lx\n", __func__,
0x1f, reg, value);
mt7530_mdio_w32(eth, reg, value);
- pr_info("%s:phy=%d, reg=0x%x, val=0x%x confirm..\n", __func__,
+ pr_info("%s:phy=%d, reg=0x%lx, val=0x%x confirm..\n", __func__,
0x1f, reg, mt7530_mdio_r32(eth, reg));
return len;
@@ -350,12 +352,12 @@
if (kstrtoul(token, 16, (unsigned long *)&value))
return -EINVAL;
- pr_info("%s:phy=%d, reg=0x%x, val=0x%x\n", __func__,
+ pr_info("%s:phy=%ld, reg=0x%lx, val=0x%lx\n", __func__,
phy, reg, value);
_mtk_mdio_write(eth, phy, reg, value);
- pr_info("%s:phy=%d, reg=0x%x, val=0x%x confirm..\n", __func__,
+ pr_info("%s:phy=%ld, reg=0x%lx, val=0x%x confirm..\n", __func__,
phy, reg, _mtk_mdio_read(eth, phy, reg));
return len;
@@ -369,7 +371,7 @@
int count = len;
unsigned long dbg_level = 0;
- len = min(count, sizeof(buf) - 1);
+ len = min((size_t)count, sizeof(buf) - 1);
if (copy_from_user(buf, ptr, len))
return -EFAULT;
@@ -695,8 +697,6 @@
int esw_cnt_read(struct seq_file *seq, void *v)
{
- unsigned int pkt_cnt = 0;
- int i = 0;
struct mtk_eth *eth = g_eth;
gdm_cnt_read(eth);
@@ -1121,6 +1121,60 @@
.open = dbg_regs_open,
.read = seq_read,
.llseek = seq_lseek,
+ .release = single_release
+};
+
+ssize_t rss_ctrl_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *data)
+{
+ char buf[32];
+ char *p_buf;
+ char *p_token = NULL;
+ char *p_delimiter = " \t";
+ long num = 4;
+ u32 len = count;
+ int ret;
+
+ if (len >= sizeof(buf)) {
+ pr_info("Input handling fail!\n");
+ return -1;
+ }
+
+ if (copy_from_user(buf, buffer, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+
+ p_buf = buf;
+ p_token = strsep(&p_buf, p_delimiter);
+ if (!p_token)
+ num = 4;
+ else
+ ret = kstrtol(p_token, 10, &num);
+
+ if (!mtk_rss_set_indr_tbl(g_eth, num))
+ cur_rss_num = num;
+
+ return count;
+}
+
+int rss_ctrl_read(struct seq_file *seq, void *v)
+{
+ pr_info("ADMA is using %d-RSS.\n", cur_rss_num);
+ return 0;
+}
+
+static int rss_ctrl_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rss_ctrl_read, 0);
+}
+
+static const struct file_operations rss_ctrl_fops = {
+ .owner = THIS_MODULE,
+ .open = rss_ctrl_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = rss_ctrl_write,
.release = single_release
};
@@ -1837,6 +1891,17 @@
if (!proc_dbg_regs)
pr_notice("!! FAIL to create %s PROC !!\n", PROCREG_DBG_REGS);
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSS)) {
+ proc_rss_ctrl =
+ proc_create(PROCREG_RSS_CTRL, 0, proc_reg_dir,
+ &rss_ctrl_fops);
+ if (!proc_rss_ctrl)
+ pr_info("!! FAIL to create %s PROC !!\n",
+ PROCREG_RSS_CTRL);
+
+ cur_rss_num = g_eth->soc->rss_num;
+ }
+
if (g_eth->hwlro) {
proc_hw_lro_stats =
proc_create(PROCREG_HW_LRO_STATS, 0, proc_reg_dir,
@@ -1881,6 +1946,9 @@
if (proc_dbg_regs)
remove_proc_entry(PROCREG_DBG_REGS, proc_reg_dir);
+ if (proc_rss_ctrl)
+ remove_proc_entry(PROCREG_RSS_CTRL, proc_reg_dir);
+
if (g_eth->hwlro) {
if (proc_hw_lro_stats)
remove_proc_entry(PROCREG_HW_LRO_STATS, proc_reg_dir);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
index ec7167b..3e7c137 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_dbg.h
@@ -61,6 +61,7 @@
#define PROCREG_RXRING "rx_ring"
#define PROCREG_DIR "mtketh"
#define PROCREG_DBG_REGS "dbg_regs"
+#define PROCREG_RSS_CTRL "rss_ctrl"
#define PROCREG_HW_LRO_STATS "hw_lro_stats"
#define PROCREG_HW_LRO_AUTO_TLB "hw_lro_auto_tlb"
#define PROCREG_RESET_EVENT "reset_event"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
index 5ab74ad..66b4646 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_reset.c
@@ -326,7 +326,7 @@
{
static u32 err_cnt_qtx;
u32 err_flag = 0;
- u32 i = 0, is_rx_fc = 0;
+ u32 is_rx_fc = 0;
u32 is_qfsm_hang = (mtk_r32(eth, MTK_QDMA_FSM) & 0xF00) != 0;
u32 is_qfwd_hang = mtk_r32(eth, MTK_QDMA_FWD_CNT) == 0;
@@ -624,7 +624,7 @@
switch (event) {
case MTK_WIFI_RESET_DONE:
case MTK_FE_STOP_TRAFFIC_DONE:
- pr_info("%s rcv done event:%x\n", __func__, event);
+ pr_info("%s rcv done event:%lx\n", __func__, event);
mtk_rest_cnt--;
if(!mtk_rest_cnt) {
complete(&wait_ser_done);
@@ -642,7 +642,7 @@
case MTK_FE_STOP_TRAFFIC_DONE_FAIL:
mtk_stop_fail = true;
mtk_reset_flag = MTK_FE_START_RESET;
- pr_info("%s rcv done event:%x\n", __func__, event);
+ pr_info("%s rcv done event:%lx\n", __func__, event);
complete(&wait_ser_done);
mtk_rest_cnt = mtk_wifi_num;
break;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 02f1d34..78ac67e 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -1053,11 +1053,11 @@
/* fall through */
case PHY_INTERFACE_MODE_1000BASEX:
phylink_set(mask, 1000baseX_Full);
- /* fall through; */
+ /* fall through */
case PHY_INTERFACE_MODE_2500BASEX:
phylink_set(mask, 2500baseX_Full);
phylink_set(mask, 2500baseT_Full);
- /* fall through; */
+ /* fall through */
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
@@ -3015,6 +3015,24 @@
return 0;
}
+int mtk_rss_set_indr_tbl(struct mtk_eth *eth, int num)
+{
+ u32 i, config;
+
+ if (num <= 0 || num > MTK_RX_NAPI_NUM)
+ return -EOPNOTSUPP;
+
+ for (i = 0, config = 0; i < 16; i++) {
+ config <<= 2;
+ config |= (i % num);
+ }
+
+ for (i = 0; i < 8; i++)
+ mtk_w32(eth, config, MTK_RSS_INDR_TABLE_DW(i));
+
+ return 0;
+}
+
static int mtk_rss_init(struct mtk_eth *eth)
{
u32 val;
@@ -3045,14 +3063,7 @@
mtk_w32(eth, val, MTK_PDMA_RSS_GLO_CFG);
/* Select the size of indirection table */
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW0);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW1);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW2);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW3);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW4);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW5);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW6);
- mtk_w32(eth, MTK_RSS_INDR_TABLE_SIZE4, MTK_RSS_INDR_TABLE_DW7);
+ mtk_rss_set_indr_tbl(eth, eth->soc->rss_num);
/* Pause */
val |= MTK_RSS_CFG_REQ;
@@ -3972,8 +3983,6 @@
static void mtk_pending_work(struct work_struct *work)
{
struct mtk_eth *eth = container_of(work, struct mtk_eth, pending_work);
- struct device_node *phy_node = NULL;
- struct mtk_mac *mac = NULL;
int err, i = 0;
unsigned long restart = 0;
u32 val = 0;
@@ -4346,7 +4355,6 @@
static int mtk_set_eee(struct net_device *dev, struct ethtool_eee *eee)
{
struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
if (mac->type == MTK_GDM_TYPE) {
if (eee->tx_lpi_enabled && eee->tx_lpi_timer > 255)
@@ -4911,6 +4919,7 @@
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4927,6 +4936,7 @@
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rx_dma_l4_valid = RX_DMA_L4_VALID,
@@ -4944,6 +4954,7 @@
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4960,6 +4971,7 @@
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4977,6 +4989,7 @@
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4994,6 +5007,7 @@
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -5011,6 +5025,7 @@
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -5028,6 +5043,7 @@
.required_clks = MT7988_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .rss_num = 4,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -5044,6 +5060,7 @@
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 7465188..01e15fe 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -267,15 +267,8 @@
#define MTK_RSS_CFG_REQ BIT(2)
#define MTK_RSS_IPV6_STATIC_HASH (0x7 << 8)
#define MTK_RSS_IPV4_STATIC_HASH (0x7 << 12)
-#define MTK_RSS_INDR_TABLE_DW0 (MTK_PDMA_RSS_GLO_CFG + 0x50)
-#define MTK_RSS_INDR_TABLE_DW1 (MTK_PDMA_RSS_GLO_CFG + 0x54)
-#define MTK_RSS_INDR_TABLE_DW2 (MTK_PDMA_RSS_GLO_CFG + 0x58)
-#define MTK_RSS_INDR_TABLE_DW3 (MTK_PDMA_RSS_GLO_CFG + 0x5C)
-#define MTK_RSS_INDR_TABLE_DW4 (MTK_PDMA_RSS_GLO_CFG + 0x60)
-#define MTK_RSS_INDR_TABLE_DW5 (MTK_PDMA_RSS_GLO_CFG + 0x64)
-#define MTK_RSS_INDR_TABLE_DW6 (MTK_PDMA_RSS_GLO_CFG + 0x68)
-#define MTK_RSS_INDR_TABLE_DW7 (MTK_PDMA_RSS_GLO_CFG + 0x6C)
-#define MTK_RSS_INDR_TABLE_SIZE4 0x39393939
+#define MTK_RSS_INDR_TABLE_DW(x) (MTK_PDMA_RSS_GLO_CFG + 0x50 + \
+ ((x) * 0x4))
/* PDMA Global Configuration Register */
#define MTK_PDMA_GLO_CFG (PDMA_BASE + 0x204)
@@ -1535,7 +1528,7 @@
MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \
MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII | \
MTK_GMAC2_XGMII | MTK_MUX_GMAC2_TO_XGMII | MTK_RSS | \
- MTK_NETSYS_RX_V2)
+ MTK_NETSYS_RX_V2 | MTK_8GB_ADDRESSING)
struct mtk_tx_dma_desc_info {
dma_addr_t addr;
@@ -1614,6 +1607,7 @@
struct mtk_soc_data {
const struct mtk_reg_map *reg_map;
u32 ana_rgc3;
+ u32 rss_num;
u64 caps;
u64 required_clks;
bool required_pctl;
@@ -1870,4 +1864,5 @@
int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+int mtk_rss_set_indr_tbl(struct mtk_eth *eth, int num);
#endif /* MTK_ETH_H */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
index 95e5e3c..05f4955 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_hnat/hnat_nf_hook.c
@@ -825,6 +825,9 @@
mtk_hnat_ipv4_nf_pre_routing(void *priv, struct sk_buff *skb,
const struct nf_hook_state *state)
{
+ struct flow_offload_hw_path hw_path = { .dev = skb->dev,
+ .virt_dev = skb->dev };
+
if (!skb)
goto drop;
@@ -835,6 +838,19 @@
hnat_set_head_frags(state, skb, -1, hnat_set_iif);
+ /*
+ * Avoid mistakenly binding of outer IP, ports in SW L2TP decap flow.
+ * In pre-routing, if dev is virtual iface, TOPS module is not loaded,
+ * and it's L2TP flow, then do not bind.
+ */
+ if (skb_hnat_iface(skb) == FOE_MAGIC_GE_VIRTUAL
+ && skb->dev->netdev_ops->ndo_flow_offload_check) {
+ skb->dev->netdev_ops->ndo_flow_offload_check(&hw_path);
+
+ if (hw_path.flags & FLOW_OFFLOAD_PATH_TNL)
+ skb_hnat_alg(skb) = 1;
+ }
+
pre_routing_print(skb, state->in, state->out, __func__);
/* packets from external devices -> xxx ,step 1 , learning stage & bound stage*/
@@ -964,10 +980,20 @@
struct neighbour *neigh = NULL;
struct dst_entry *dst = skb_dst(skb);
struct ethhdr *eth;
+ u16 eth_pppoe_hlen = ETH_HLEN + PPPOE_SES_HLEN;
if (hw_path->flags & FLOW_OFFLOAD_PATH_PPPOE) {
- memcpy(eth_hdr(skb)->h_source, hw_path->eth_src, ETH_ALEN);
- memcpy(eth_hdr(skb)->h_dest, hw_path->eth_dest, ETH_ALEN);
+ if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP) {
+ eth = (struct ethhdr *)(skb->data - eth_pppoe_hlen);
+ eth->h_proto = skb->protocol;
+ ether_addr_copy(eth->h_dest, hw_path->eth_dest);
+ ether_addr_copy(eth->h_source, hw_path->eth_src);
+ } else {
+ eth = eth_hdr(skb);
+ memcpy(eth->h_source, hw_path->eth_src, ETH_ALEN);
+ memcpy(eth->h_dest, hw_path->eth_dest, ETH_ALEN);
+ }
+
return 0;
}
@@ -1150,6 +1176,20 @@
return entry;
}
+static struct ethhdr *get_ipv6_ipip_ethhdr(struct sk_buff *skb,
+ struct flow_offload_hw_path *hw_path)
+{
+ struct ethhdr *eth;
+ u16 eth_pppoe_hlen = ETH_HLEN + PPPOE_SES_HLEN;
+
+ if (hw_path->flags & FLOW_OFFLOAD_PATH_PPPOE)
+ eth = (struct ethhdr *)(skb->data - eth_pppoe_hlen);
+ else
+ eth = (struct ethhdr *)(skb->data - ETH_HLEN);
+
+ return eth;
+}
+
static unsigned int skb_to_hnat_info(struct sk_buff *skb,
const struct net_device *dev,
struct foe_entry *foe,
@@ -1174,7 +1214,7 @@
if (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPIP)
/* point to ethernet header for DS-Lite and MapE */
- eth = (struct ethhdr *)(skb->data - ETH_HLEN);
+ eth = get_ipv6_ipip_ethhdr(skb, hw_path);
else
eth = eth_hdr(skb);
@@ -1416,6 +1456,11 @@
break;
case NEXTHDR_IPIP:
+ iph = (struct iphdr *)skb_inner_network_header(skb);
+ /* don't process inner fragment packets */
+ if (ip_is_fragment(iph))
+ return 0;
+
if ((!mape_toggle &&
entry.bfib1.pkt_type == IPV4_DSLITE) ||
(mape_toggle &&
@@ -2444,6 +2489,10 @@
if (unlikely(!skb_hnat_is_hashed(skb)))
return 0;
+ /* Do not bind if pkt is fragmented */
+ if (ip_is_fragment(ip_hdr(skb)))
+ return 0;
+
if (out->netdev_ops->ndo_flow_offload_check) {
out->netdev_ops->ndo_flow_offload_check(&hw_path);
out = (IS_GMAC1_MODE) ? hw_path.virt_dev : hw_path.dev;
@@ -2491,7 +2540,7 @@
entry->ipv4_hnapt.m_timestamp = foe_timestamp(hnat_priv);
if (entry_hnat_is_bound(entry)) {
- memset(skb_hnat_info(skb), 0, FOE_INFO_LEN);
+ memset(skb_hnat_info(skb), 0, sizeof(struct hnat_desc));
return -1;
}
@@ -2551,6 +2600,9 @@
sizeof(_ports), &_ports);
if (unlikely(!pptr))
return NF_ACCEPT;
+ /* don't process inner fragment packets */
+ if (ip_is_fragment(iph))
+ return NF_ACCEPT;
entry->bfib1.udp = udp;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
index c2acab2..3cc8f90 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -440,22 +440,18 @@
sgm_mode = SGMII_IF_MODE_SGMII |
SGMII_REMOTE_FAULT_DIS |
SGMII_SPEED_DUPLEX_AN;
- } else if (phylink_autoneg_inband(mode)) {
- /* 1000base-X or HSGMII with autoneg */
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- return -EINVAL;
-
+ } else if (interface == PHY_INTERFACE_MODE_2500BASEX) {
+ /* HSGMII without autoneg */
+ speed = SGMII_SPEED_1000;
+ sgm_mode = SGMII_IF_MODE_SGMII;
+ } else {
+ /* 1000base-X with/without autoneg */
bmcr = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
advertising) ? SGMII_AN_ENABLE : 0;
if (bmcr)
sgm_mode = SGMII_SPEED_DUPLEX_AN;
else
speed = SGMII_SPEED_1000;
- } else {
- /* 1000base-X or HSGMII without autoneg */
- speed = SGMII_SPEED_1000;
- if (interface == PHY_INTERFACE_MODE_2500BASEX)
- sgm_mode = SGMII_IF_MODE_SGMII;
}
if (mpcs->interface != interface ||
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
index e6007f6..a181fc2 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_usxgmii.c
@@ -792,7 +792,8 @@
unsigned int cur = offset;
unsigned int val1 = 0, val2 = 0, val3 = 0, val4 = 0;
- pr_info("\n============ %s ============ pmap:%x\n", name, pmap);
+ pr_info("\n============ %s ============ pmap:%lx\n",
+ name, (unsigned long)pmap);
while (cur < offset + range) {
regmap_read(pmap, cur, &val1);
regmap_read(pmap, cur + 0x4, &val2);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
index 2825a36..1047943 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-2p5ge.c
@@ -222,10 +222,20 @@
if (ret < 0)
return ret;
phydev->duplex = (ret & MTK_PHY_FDX_ENABLE) ? DUPLEX_FULL : DUPLEX_HALF;
+ /* FIXME: The current firmware always enables rate adaptation mode. */
+ phydev->rate_matching = RATE_MATCH_PAUSE;
return 0;
}
+static int mt798x_2p5ge_phy_get_rate_matching(struct phy_device *phydev,
+ phy_interface_t iface)
+{
+ if (iface == PHY_INTERFACE_MODE_XGMII)
+ return RATE_MATCH_PAUSE;
+ return RATE_MATCH_NONE;
+}
+
static struct phy_driver mtk_gephy_driver[] = {
{
PHY_ID_MATCH_EXACT(0x00339c11),
@@ -234,6 +244,7 @@
.config_aneg = mt798x_2p5ge_phy_config_aneg,
.get_features = mt798x_2p5ge_phy_get_features,
.read_status = mt798x_2p5ge_phy_read_status,
+ .get_rate_matching = mt798x_2p5ge_phy_get_rate_matching,
//.config_intr = genphy_no_config_intr,
//.handle_interrupt = genphy_no_ack_interrupt,
//.suspend = genphy_suspend,
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge-soc.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge-soc.c
index f25fb8e..489e524 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge-soc.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/phy/mediatek-ge-soc.c
@@ -502,7 +502,7 @@
u16 reg, val;
if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988)
- bias = -2;
+ bias = -1;
val = clamp_val(bias + tx_r50_cal_val, 0, 63);
@@ -718,6 +718,11 @@
static void mt798x_phy_common_finetune(struct phy_device *phydev)
{
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+ /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
+ __phy_write(phydev, 0x11, 0xc71);
+ __phy_write(phydev, 0x12, 0xc);
+ __phy_write(phydev, 0x10, 0x8fae);
+
/* EnabRandUpdTrig = 1 */
__phy_write(phydev, 0x11, 0x2f00);
__phy_write(phydev, 0x12, 0xe);
@@ -728,15 +733,56 @@
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x83aa);
+ /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */
+ __phy_write(phydev, 0x11, 0x240);
+ __phy_write(phydev, 0x12, 0x0);
+ __phy_write(phydev, 0x10, 0x9680);
+
- /* TrFreeze = 0 */
+ /* TrFreeze = 0 (mt7988 default) */
__phy_write(phydev, 0x11, 0x0);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x9686);
+ /* SSTrKp100 = 5 */
+ /* SSTrKf100 = 6 */
+ /* SSTrKp1000Mas = 5 */
+ /* SSTrKf1000Mas = 6 */
/* SSTrKp1000Slv = 5 */
+ /* SSTrKf1000Slv = 6 */
__phy_write(phydev, 0x11, 0xbaef);
__phy_write(phydev, 0x12, 0x2e);
__phy_write(phydev, 0x10, 0x968c);
+ phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+}
+
+static void mt7981_phy_finetune(struct phy_device *phydev)
+{
+ u16 val[8] = { 0x01ce, 0x01c1,
+ 0x020f, 0x0202,
+ 0x03d0, 0x03c0,
+ 0x0013, 0x0005 };
+ int i, k;
+
+ /* 100M eye finetune:
+ * Keep middle level of TX MLT3 shapper as default.
+ * Only change TX MLT3 overshoot level here.
+ */
+ for (k = 0, i = 1; i < 12; i++) {
+ if (i % 3 == 0)
+ continue;
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
+ }
+
+ phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
+ /* ResetSyncOffset = 6 */
+ __phy_write(phydev, 0x11, 0x600);
+ __phy_write(phydev, 0x12, 0x0);
+ __phy_write(phydev, 0x10, 0x8fc0);
+
+ /* VgaDecRate = 1 */
+ __phy_write(phydev, 0x11, 0x4c2a);
+ __phy_write(phydev, 0x12, 0x3e);
+ __phy_write(phydev, 0x10, 0x8fa4);
/* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2,
* MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2
@@ -751,7 +797,7 @@
__phy_write(phydev, 0x10, 0x8ec0);
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
- /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9));
@@ -782,48 +828,7 @@
phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_PUMP_EN_PAIRCD, 0x0);
/* Adjust LDO output voltage */
phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222);
-}
-static void mt7981_phy_finetune(struct phy_device *phydev)
-{
- u16 val[8] = { 0x01ce, 0x01c1,
- 0x020f, 0x0202,
- 0x03d0, 0x03c0,
- 0x0013, 0x0005 };
- int i, k;
-
- /* 100M eye finetune:
- * Keep middle level of TX MLT3 shapper as default.
- * Only change TX MLT3 overshoot level here.
- */
- for (k = 0, i = 1; i < 12; i++) {
- if (i % 3 == 0)
- continue;
- phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]);
- }
-
- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */
- __phy_write(phydev, 0x11, 0xc71);
- __phy_write(phydev, 0x12, 0xc);
- __phy_write(phydev, 0x10, 0x8fae);
-
- /* ResetSyncOffset = 6 */
- __phy_write(phydev, 0x11, 0x600);
- __phy_write(phydev, 0x12, 0x0);
- __phy_write(phydev, 0x10, 0x8fc0);
-
- /* VgaDecRate = 1 */
- __phy_write(phydev, 0x11, 0x4c2a);
- __phy_write(phydev, 0x12, 0x3e);
- __phy_write(phydev, 0x10, 0x8fa4);
-
- /* FfeUpdGainForce = 4 */
- __phy_write(phydev, 0x11, 0x240);
- __phy_write(phydev, 0x12, 0x0);
- __phy_write(phydev, 0x10, 0x9680);
-
- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
}
static void mt7988_phy_finetune(struct phy_device *phydev)
@@ -845,12 +850,6 @@
MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8);
phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5);
-
- /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */
- __phy_write(phydev, 0x11, 0x671);
- __phy_write(phydev, 0x12, 0xc);
- __phy_write(phydev, 0x10, 0x8fae);
-
/* ResetSyncOffset = 5 */
__phy_write(phydev, 0x11, 0x500);
__phy_write(phydev, 0x12, 0x0);
@@ -858,13 +857,28 @@
/* VgaDecRate is 1 at default on mt7988 */
- phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+ /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7,
+ * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7
+ */
+ __phy_write(phydev, 0x11, 0xb90a);
+ __phy_write(phydev, 0x12, 0x6f);
+ __phy_write(phydev, 0x10, 0x8f82);
+
+ /* RemAckCntLimitCtrl = 1 */
+ __phy_write(phydev, 0x11, 0xfbba);
+ __phy_write(phydev, 0x12, 0xc3);
+ __phy_write(phydev, 0x10, 0x87f8);
- phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30);
- /* TxClkOffset = 2 */
- __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK,
- FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2));
phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0);
+
+ /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */
+ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234,
+ MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK,
+ BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa));
+
+ /* rg_tr_lpf_cnt_val = 1023 */
+ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff);
+
}
static void mt798x_phy_eee(struct phy_device *phydev)
@@ -897,11 +911,11 @@
MTK_PHY_LPI_SLV_SEND_TX_EN,
FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120));
- phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
- MTK_PHY_LPI_SEND_LOC_TIMER_MASK |
- MTK_PHY_LPI_TXPCS_LOC_RCV,
- FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117));
+ /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */
+ phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239,
+ MTK_PHY_LPI_TXPCS_LOC_RCV);
+ /* This also fixes some IoT issues, such as CH340 */
phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7,
MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK,
FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) |
@@ -935,7 +949,7 @@
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x9690);
- /* REG_EEE_st2TrKf1000 = 3 */
+ /* REG_EEE_st2TrKf1000 = 2 */
__phy_write(phydev, 0x11, 0x114f);
__phy_write(phydev, 0x12, 0x2);
__phy_write(phydev, 0x10, 0x969a);
@@ -960,7 +974,7 @@
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x96b8);
- /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */
+ /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */
__phy_write(phydev, 0x11, 0x1463);
__phy_write(phydev, 0x12, 0x0);
__phy_write(phydev, 0x10, 0x96ca);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
index d685328..49c0be1 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/pinctrl/mediatek/pinctrl-mt7988.c
@@ -817,7 +817,7 @@
static int mt7988_i2c2_0_pins[] = { 69, 70 };
static int mt7988_i2c2_0_funcs[] = { 4, 4 };
-static int mt7988_i2c2_1_pins[] = { 70, 71 };
+static int mt7988_i2c2_1_pins[] = { 71, 72 };
static int mt7988_i2c2_1_funcs[] = { 1, 1 };
/* eth */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/1004-mtketh-add-threaded-napi-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3000-mtketh-add-threaded-napi-support.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/1004-mtketh-add-threaded-napi-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3000-mtketh-add-threaded-napi-support.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/1007-mtketh-add-qdma-sw-solution-for-mac80211-sdk.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3001-mtketh-add-qdma-sw-solution-for-mac80211-sdk.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/1007-mtketh-add-qdma-sw-solution-for-mac80211-sdk.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3001-mtketh-add-qdma-sw-solution-for-mac80211-sdk.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3002-ovs-add-multicast-to-unicast-support.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8011-ovs-add-multicast-to-unicast-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3002-ovs-add-multicast-to-unicast-support.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-mt7622-backport-nf-hw-offload-framework-and-ups.patch
similarity index 99%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-mt7622-backport-nf-hw-offload-framework-and-ups.patch
index 17f2cb1..b52782f 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9990-mt7622-backport-nf-hw-offload-framework-and-ups.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3003-mt7622-backport-nf-hw-offload-framework-and-ups.patch
@@ -135,33 +135,33 @@
.required_pctl = true,
.has_sram = false,
+ .offload_version = 2,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
@@ -4424,6 +4444,7 @@ static const struct mtk_soc_data mt7621_
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .offload_version = 2,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
@@ -4439,6 +4460,7 @@ static const struct mtk_soc_data mt7622_
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .offload_version = 2,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
@@ -4453,6 +4475,7 @@ static const struct mtk_soc_data mt7623_
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
+ .offload_version = 2,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index b6380ffeb..349f98503 100755
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1266,7 +1266,7 @@
index 000000000..4294f0c74
--- /dev/null
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -0,0 +1,541 @@
+@@ -0,0 +1,535 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
@@ -1735,14 +1735,11 @@
+{
+ struct mtk_mac *mac = netdev_priv(dev);
+ struct mtk_eth *eth = mac->hw;
-+ struct nf_flowtable *flowtable;
+ static LIST_HEAD(block_cb_list);
+ struct flow_block_cb *block_cb;
+ flow_setup_cb_t *cb;
+ int err = 0;
+
-+ flowtable = container_of(f->block, struct nf_flowtable, flow_block);
-+
+ if (!eth->ppe.foe_table)
+ return -EOPNOTSUPP;
+
@@ -1752,8 +1749,6 @@
+ cb = mtk_eth_setup_tc_block_cb;
+ f->driver_block_list = &block_cb_list;
+
-+ down_write(&flowtable->flow_block_lock);
-+
+ switch (f->command) {
+ case FLOW_BLOCK_BIND:
+ block_cb = flow_block_cb_lookup(f->block, cb, dev);
@@ -1788,7 +1783,6 @@
+ }
+
+unlock:
-+ up_write(&flowtable->flow_block_lock);
+ return err;
+}
+
@@ -4922,7 +4916,7 @@
index 000000000..d94c6fb92
--- /dev/null
+++ b/net/netfilter/nf_flow_table_offload.c
-@@ -0,0 +1,1197 @@
+@@ -0,0 +1,1199 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
@@ -5766,7 +5760,7 @@
+ if (cmd == FLOW_CLS_REPLACE)
+ cls_flow.rule = flow_rule->rule;
+
-+ down_write(&flowtable->flow_block_lock);
++ down_read(&flowtable->flow_block_lock);
+ list_for_each_entry(block_cb, block_cb_list, list) {
+ err = block_cb->cb(TC_SETUP_CLSFLOWER, &cls_flow,
+ block_cb->cb_priv);
@@ -5775,7 +5769,7 @@
+
+ i++;
+ }
-+ up_write(&flowtable->flow_block_lock);
++ up_read(&flowtable->flow_block_lock);
+
+ if (cmd == FLOW_CLS_STATS)
+ memcpy(stats, &cls_flow.stats, sizeof(*stats));
@@ -5994,7 +5988,7 @@
+ struct flow_block_cb *block_cb, *next;
+ int err = 0;
+
-+ down_read(&flowtable->flow_block_lock);
++ down_write(&flowtable->flow_block_lock);
+
+ switch (cmd) {
+ case FLOW_BLOCK_BIND:
@@ -6011,7 +6005,7 @@
+ err = -EOPNOTSUPP;
+ }
+
-+ up_read(&flowtable->flow_block_lock);
++ up_write(&flowtable->flow_block_lock);
+
+ return err;
+}
@@ -6057,7 +6051,9 @@
+
+ nf_flow_table_block_offload_init(bo, dev_net(dev), cmd, flowtable,
+ extack);
++ down_write(&flowtable->flow_block_lock);
+ err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_FT, bo);
++ up_write(&flowtable->flow_block_lock);
+ if (err < 0)
+ return err;
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9992-dts-mt7986-wed-changes.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3004-dts-mt7986-wed-changes.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9992-dts-mt7986-wed-changes.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3004-dts-mt7986-wed-changes.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3005-add-wed.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9993-add-wed.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3005-add-wed.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9994-ethernet-update-ppe-from-mt7622-to-mt7986.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3006-ethernet-update-ppe-from-mt7622-to-mt7986.patch
similarity index 99%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9994-ethernet-update-ppe-from-mt7622-to-mt7986.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3006-ethernet-update-ppe-from-mt7622-to-mt7986.patch
index 033f588..c0efd12 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9994-ethernet-update-ppe-from-mt7622-to-mt7986.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3006-ethernet-update-ppe-from-mt7622-to-mt7986.patch
@@ -51,6 +51,7 @@
.required_pctl = false,
.has_sram = true,
+ .offload_version = 2,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma),
@@ -60,7 +61,6 @@
},
};
- static const struct mtk_soc_data mt7981_data = {
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index b52378bd6..fce1a7172 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9995-flow-offload-add-mkhnat-dual-ppe-new-v2.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3007-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
similarity index 98%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9995-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3007-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
index 5d6f0d1..954c6e2 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9995-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3007-flow-offload-add-mkhnat-dual-ppe-new-v2.patch
@@ -165,7 +165,7 @@
struct rhashtable flow_table;
};
-@@ -1668,8 +1674,10 @@ int mtk_gmac_usxgmii_path_setup(struct m
+@@ -1668,9 +1674,11 @@ int mtk_gmac_usxgmii_path_setup(struct m
void mtk_usxgmii_reset(struct mtk_xgmii *ss, int mac_id);
int mtk_dump_usxgmii(struct regmap *pmap, char *name, u32 offset, u32 range);
@@ -174,6 +174,7 @@
int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
void *type_data);
void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
+ int mtk_rss_set_indr_tbl(struct mtk_eth *eth, int num);
+
+int mtk_ppe_debugfs_init(struct mtk_eth *eth);
#endif /* MTK_ETH_H */
@@ -429,15 +430,13 @@
f->stats.lastused = jiffies - idle * HZ;
return 0;
-@@ -540,12 +564,14 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
+@@ -540,10 +564,12 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
static LIST_HEAD(block_cb_list);
struct flow_block_cb *block_cb;
flow_setup_cb_t *cb;
- int err = 0;
+ int i, err = 0;
- flowtable = container_of(f->block, struct nf_flowtable, flow_block);
-
- if (!eth->ppe || !eth->ppe->foe_table)
- return -EOPNOTSUPP;
+ for (i = 0; i < eth->ppe_num; i++) {
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9996-add-wed-tx-support-for-mt7986.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3008-add-wed-tx-support-for-mt7986.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9996-add-wed-tx-support-for-mt7986.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3008-add-wed-tx-support-for-mt7986.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9996-add-wed-tx-wds-support-for-mt7986.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3009-add-wed-tx-wds-support-for-mt7986.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9996-add-wed-tx-wds-support-for-mt7986.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3009-add-wed-tx-wds-support-for-mt7986.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9997-add-wed-rx-support-for-mt7896.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3010-add-wed-rx-support-for-mt7896.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9997-add-wed-rx-support-for-mt7896.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3010-add-wed-rx-support-for-mt7896.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9998-add-wed-ser-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3011-add-wed-ser-support.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9998-add-wed-ser-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3011-add-wed-ser-support.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-1-ethernet-update-ppe-backward-compatible-two-way-hash.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-ethernet-update-ppe-backward-compatible-two-way-hash.patch
old mode 100644
new mode 100755
similarity index 96%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-1-ethernet-update-ppe-backward-compatible-two-way-hash.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-ethernet-update-ppe-backward-compatible-two-way-hash.patch
index ab5bbab..cfe29e7
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-1-ethernet-update-ppe-backward-compatible-two-way-hash.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3012-ethernet-update-ppe-backward-compatible-two-way-hash.patch
@@ -18,49 +18,49 @@
.has_sram = false,
+ .hash_way = 2,
.offload_version = 2,
+ .rss_num = 0,
.txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
@@ -4573,6 +4575,7 @@ static const struct mtk_soc_data mt7621_
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .hash_way = 2,
.offload_version = 2,
+ .rss_num = 0,
.txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
@@ -4589,6 +4592,7 @@ static const struct mtk_soc_data mt7622_
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .hash_way = 2,
.offload_version = 2,
+ .rss_num = 0,
.txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
@@ -4604,6 +4608,7 @@ static const struct mtk_soc_data mt7623_
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.has_sram = false,
+ .hash_way = 2,
.offload_version = 2,
+ .rss_num = 0,
.txrx = {
- .txd_size = sizeof(struct mtk_tx_dma),
@@ -4635,6 +4640,7 @@ static const struct mtk_soc_data mt7986_
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .hash_way = 4,
.offload_version = 2,
+ .rss_num = 0,
.txrx = {
- .txd_size = sizeof(struct mtk_tx_dma_v2),
@@ -4651,6 +4657,8 @@ static const struct mtk_soc_data mt7981_
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
.has_sram = true,
+ .hash_way = 4,
+ .offload_version = 2,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
- .rxd_size = sizeof(struct mtk_rx_dma_v2),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 4a69bd0..35a7543 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-2-flow-offload-add-mtkhnat-flow-accounting.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3013-flow-offload-add-mtkhnat-flow-accounting.patch
old mode 100644
new mode 100755
similarity index 98%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-2-flow-offload-add-mtkhnat-flow-accounting.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3013-flow-offload-add-mtkhnat-flow-accounting.patch
index 5b6253f..ed90d2c
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-2-flow-offload-add-mtkhnat-flow-accounting.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3013-flow-offload-add-mtkhnat-flow-accounting.patch
@@ -19,7 +19,7 @@
+ .has_accounting = false,
.hash_way = 2,
.offload_version = 2,
- .txrx = {
+ .rss_num = 0,
@@ -4073,6 +4075,7 @@ static const struct mtk_soc_data mt7621_data = {
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
@@ -27,7 +27,7 @@
+ .has_accounting = false,
.hash_way = 2,
.offload_version = 2,
- .txrx = {
+ .rss_num = 0,
@@ -4090,6 +4093,7 @@ static const struct mtk_soc_data mt7622_data = {
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
@@ -35,7 +35,7 @@
+ .has_accounting = true,
.hash_way = 2,
.offload_version = 2,
- .txrx = {
+ .rss_num = 0,
@@ -4106,6 +4110,7 @@ static const struct mtk_soc_data mt7623_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
@@ -43,15 +43,15 @@
+ .has_accounting = false,
.hash_way = 2,
.offload_version = 2,
- .txrx = {
+ .rss_num = 0,
@@ -4123,6 +4128,7 @@ static const struct mtk_soc_data mt7629_data = {
.required_clks = MT7629_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .has_accounting = true,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
@@ -4138,6 +4144,7 @@ static const struct mtk_soc_data mt7986_data = {
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
@@ -59,7 +59,7 @@
+ .has_accounting = true,
.hash_way = 4,
.offload_version = 2,
- .txrx = {
+ .rss_num = 0,
@@ -4155,6 +4162,7 @@ static const struct mtk_soc_data mt7981_data = {
.required_clks = MT7981_CLKS_BITMAP,
.required_pctl = false,
@@ -67,15 +67,15 @@
+ .has_accounting = true,
.hash_way = 4,
.offload_version = 2,
- .txrx = {
+ .rss_num = 0,
@@ -4171,6 +4179,7 @@ static const struct mtk_soc_data rt5350_data = {
.required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false,
.has_sram = false,
+ .has_accounting = false,
+ .rss_num = 0,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
- .rxd_size = sizeof(struct mtk_rx_dma),
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index f659633..5e16fa8 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-3-flow-offload-add-mtkhnat-qdma-qos.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3014-flow-offload-add-mtkhnat-qdma-qos.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-3-flow-offload-add-mtkhnat-qdma-qos.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3014-flow-offload-add-mtkhnat-qdma-qos.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-4-flow-offload-ovs-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3015-flow-offload-ovs-support.patch
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-4-flow-offload-ovs-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3015-flow-offload-ovs-support.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-5-update-net-bridge-for-bridger.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3016-update-net-bridge-for-bridger.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-5-update-net-bridge-for-bridger.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3016-update-net-bridge-for-bridger.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-6-ethernet-update-ppe-from-mt7986-to-mt7988.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-ethernet-update-ppe-from-mt7986-to-mt7988.patch
old mode 100644
new mode 100755
similarity index 99%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-6-ethernet-update-ppe-from-mt7986-to-mt7988.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-ethernet-update-ppe-from-mt7986-to-mt7988.patch
index aac0808..d9af44d
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-6-ethernet-update-ppe-from-mt7986-to-mt7988.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3017-ethernet-update-ppe-from-mt7986-to-mt7988.patch
@@ -41,6 +41,7 @@
+ .has_accounting = true,
+ .hash_way = 4,
+ .offload_version = 2,
+ .rss_num = 4,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -50,7 +51,6 @@
.qdma_tx_sch = 4,
},
};
-
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 5b39d87..94bd423 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-7-mediatek-ethernet-add-wifi2wifi-offload-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3018-mediatek-ethernet-add-wifi2wifi-offload-support.patch
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-7-mediatek-ethernet-add-wifi2wifi-offload-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3018-mediatek-ethernet-add-wifi2wifi-offload-support.patch
index 85e15c9..c810ff1 100755
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-7-mediatek-ethernet-add-wifi2wifi-offload-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3018-mediatek-ethernet-add-wifi2wifi-offload-support.patch
@@ -56,7 +56,7 @@
if (!tc_can_offload(dev))
return -EOPNOTSUPP;
-@@ -577,17 +587,22 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_pri
+@@ -577,14 +587,19 @@ mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_pri
return err;
}
@@ -69,7 +69,6 @@
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
+ struct mtk_mac *mac;
- struct nf_flowtable *flowtable;
static LIST_HEAD(block_cb_list);
struct flow_block_cb *block_cb;
flow_setup_cb_t *cb;
@@ -80,8 +79,6 @@
+ eth = mac->hw;
+ }
+
- flowtable = container_of(f->block, struct nf_flowtable, flow_block);
-
for (i = 0; i < eth->ppe_num; i++) {
@@ -610,7 +625,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
flow_block_cb_incref(block_cb);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-8-flow-offload-add-mtkhnat-dscp.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3019-flow-offload-add-mtkhnat-dscp.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-8-flow-offload-add-mtkhnat-dscp.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3019-flow-offload-add-mtkhnat-dscp.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-9-flow-offload-add-mtkhnat-netlink.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3020-flow-offload-add-mtkhnat-netlink.patch
old mode 100644
new mode 100755
similarity index 100%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/9999-9-flow-offload-add-mtkhnat-netlink.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/flow_patch/999-3020-flow-offload-add-mtkhnat-netlink.patch
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
index e706419..47252dd 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/mt7988.cfg
@@ -243,6 +243,10 @@
CONFIG_I2C_MT65XX=y
CONFIG_ICPLUS_PHY=y
CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_IIO_TRIGGER=y
+CONFIG_IIO_TRIGGERED_BUFFER=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
@@ -264,6 +268,7 @@
CONFIG_MAGIC_SYSRQ=y
CONFIG_MAGIC_SYSRQ_SERIAL=y
CONFIG_MARVELL_10G_PHY=y
+CONFIG_MARVELL_PHY=y
CONFIG_MAXLINEAR_GPHY=y
CONFIG_MD=y
CONFIG_MDIO_BUS=y
@@ -409,6 +414,9 @@
CONFIG_RCU_NEED_SEGCBLIST=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_REALTEK_PHY=y
+CONFIG_REED_SOLOMON=y
+CONFIG_REED_SOLOMON_DEC8=y
+CONFIG_REED_SOLOMON_ENC8=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MMIO=y
@@ -418,6 +426,7 @@
CONFIG_REGULATOR_RT5190A=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RFS_ACCEL=y
+CONFIG_RICHTEK_RTQ6056=y
CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
@@ -504,6 +513,3 @@
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA32=y
-# CONFIG_BPF_KPROBE_OVERRIDE is not set
-# CONFIG_HIST_TRIGGERS is not set
-# CONFIG_FUNCTION_ERROR_INJECTION is not set
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/1002-mtkhnat-add-support-for-virtual-interface-acceleration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-2708-mtkhnat-add-support-for-virtual-interface-acceleration.patch
similarity index 76%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/1002-mtkhnat-add-support-for-virtual-interface-acceleration.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-2708-mtkhnat-add-support-for-virtual-interface-acceleration.patch
index 150087a..4d21ebd 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/1002-mtkhnat-add-support-for-virtual-interface-acceleration.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-2708-mtkhnat-add-support-for-virtual-interface-acceleration.patch
@@ -1,8 +1,21 @@
+From fd6e50fdeb1d943b889a5aa093790a798ae598d3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:29 +0800
+Subject: [PATCH]
+ [networking][999-2708-mtkhnat-add-support-for-virtual-interface-acceleration.patch]
+
+---
+ include/net/netfilter/nf_flow_table.h | 3 +++
+ net/8021q/vlan_dev.c | 1 +
+ net/ipv6/ip6_tunnel.c | 24 ++++++++++++++++++++++++
+ net/ipv6/sit.c | 24 ++++++++++++++++++++++++
+ 4 files changed, 52 insertions(+)
+
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
-index 3d73c0c..960ade1 100644
+index 16dbf5461..4cb73a7cb 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
-@@ -92,9 +92,12 @@ struct flow_offload {
+@@ -94,9 +94,12 @@ struct flow_offload {
#define FLOW_OFFLOAD_PATH_VLAN BIT(1)
#define FLOW_OFFLOAD_PATH_PPPOE BIT(2)
#define FLOW_OFFLOAD_PATH_DSA BIT(3)
@@ -16,10 +29,10 @@
u8 eth_src[ETH_ALEN];
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
-index be6801524..c51af70f6 100644
+index f973bec77..dbb3cea5c 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
-@@ -761,6 +761,7 @@ static int vlan_dev_flow_offload_check(struct flow_offload_hw_path *path)
+@@ -764,6 +764,7 @@ static int vlan_dev_flow_offload_check(struct flow_offload_hw_path *path)
path->flags |= FLOW_OFFLOAD_PATH_VLAN;
path->vlan_proto = vlan->vlan_proto;
path->vlan_id = vlan->vlan_id;
@@ -28,7 +41,7 @@
if (vlan->real_dev->netdev_ops->ndo_flow_offload_check)
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
-index 1b7e3141c..da4e34f74 100644
+index 71ef26e60..f8302fdd5 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -57,6 +57,11 @@
@@ -43,7 +56,7 @@
MODULE_AUTHOR("Ville Nuorvala");
MODULE_DESCRIPTION("IPv6 tunneling device");
MODULE_LICENSE("GPL");
-@@ -1880,6 +1885,22 @@ int ip6_tnl_get_iflink(const struct net_device *dev)
+@@ -1889,6 +1894,22 @@ int ip6_tnl_get_iflink(const struct net_device *dev)
}
EXPORT_SYMBOL(ip6_tnl_get_iflink);
@@ -66,7 +79,7 @@
int ip6_tnl_encap_add_ops(const struct ip6_tnl_encap_ops *ops,
unsigned int num)
{
-@@ -1941,6 +1962,9 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
+@@ -1950,6 +1971,9 @@ static const struct net_device_ops ip6_tnl_netdev_ops = {
.ndo_change_mtu = ip6_tnl_change_mtu,
.ndo_get_stats = ip6_get_stats,
.ndo_get_iflink = ip6_tnl_get_iflink,
@@ -77,7 +90,7 @@
#define IPXIPX_FEATURES (NETIF_F_SG | \
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
-index 98954830c..42b6e8c4c 100644
+index 117960895..0844a95e3 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -52,6 +52,11 @@
@@ -92,7 +105,7 @@
/*
This version of net/ipv6/sit.c is cloned of net/ipv4/ip_gre.c
-@@ -1345,6 +1350,22 @@ ipip6_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+@@ -1342,6 +1347,22 @@ done:
return err;
}
@@ -115,7 +128,7 @@
static const struct net_device_ops ipip6_netdev_ops = {
.ndo_init = ipip6_tunnel_init,
.ndo_uninit = ipip6_tunnel_uninit,
-@@ -1352,6 +1373,9 @@ static const struct net_device_ops ipip6_netdev_ops = {
+@@ -1349,6 +1370,9 @@ static const struct net_device_ops ipip6_netdev_ops = {
.ndo_do_ioctl = ipip6_tunnel_ioctl,
.ndo_get_stats64 = ip_tunnel_get_stats64,
.ndo_get_iflink = ip_tunnel_get_iflink,
@@ -125,3 +138,6 @@
};
static void ipip6_dev_free(struct net_device *dev)
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-2726-mtkhnat-tnl-interface-offload-check.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-2726-mtkhnat-tnl-interface-offload-check.patch
new file mode 100644
index 0000000..e94185f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/nf_hnat/999-2726-mtkhnat-tnl-interface-offload-check.patch
@@ -0,0 +1,62 @@
+--- a/include/net/netfilter/nf_flow_table.h
++++ b/include/net/netfilter/nf_flow_table.h
+@@ -96,6 +96,7 @@ struct flow_offload {
+ #define FLOW_OFFLOAD_PATH_DSA BIT(3)
+ #define FLOW_OFFLOAD_PATH_DSLITE BIT(4)
+ #define FLOW_OFFLOAD_PATH_6RD BIT(5)
++#define FLOW_OFFLOAD_PATH_TNL BIT(6)
+
+ struct flow_offload_hw_path {
+ struct net_device *dev;
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -89,6 +89,7 @@
+ #include <linux/nsproxy.h>
+ #include <net/net_namespace.h>
+ #include <net/netns/generic.h>
++#include <net/netfilter/nf_flow_table.h>
+ #include <net/ip.h>
+ #include <net/udp.h>
+ #include <net/inet_common.h>
+@@ -124,9 +125,14 @@ struct pppol2tp_session {
+ };
+
+ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb);
++static int l2tp_ppp_flow_offload_check(struct ppp_channel *chan,
++ struct flow_offload_hw_path *path);
+
+ static const struct ppp_channel_ops pppol2tp_chan_ops = {
+ .start_xmit = pppol2tp_xmit,
++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
++ .flow_offload_check = l2tp_ppp_flow_offload_check,
++#endif /* IS_ENABLED(CONFIG_NF_FLOW_TABLE) */
+ };
+
+ static const struct proto_ops pppol2tp_ops;
+@@ -335,6 +341,26 @@ error:
+ return error;
+ }
+
++#if IS_ENABLED(CONFIG_NF_FLOW_TABLE)
++static int l2tp_ppp_flow_offload_check(struct ppp_channel *chan,
++ struct flow_offload_hw_path *path)
++{
++ struct sock *sk = (struct sock *)chan->private;
++ struct l2tp_session *session;
++
++ if (path->flags & FLOW_OFFLOAD_PATH_TNL)
++ return -EEXIST;
++
++ session = pppol2tp_sock_to_session(sk);
++ if (!session)
++ return -EINVAL;
++
++ path->flags |= FLOW_OFFLOAD_PATH_TNL;
++
++ return 0;
++}
++#endif /* IS_ENABLED(CONFIG_NF_FLOW_TABLE) */
++
+ /* Transmit function called by generic PPP driver. Sends PPP frame
+ * over PPPoL2TP socket.
+ *
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0001-cpufreq-add-the-missing-platform-driver-unregister.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0001-cpufreq-add-the-missing-platform-driver-unregister.patch
deleted file mode 100644
index fdf953d..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0001-cpufreq-add-the-missing-platform-driver-unregister.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
-index 927ebc5..03bb7b5 100644
---- a/drivers/cpufreq/mediatek-cpufreq.c
-+++ b/drivers/cpufreq/mediatek-cpufreq.c
-@@ -573,6 +573,7 @@ static int __init mtk_cpufreq_driver_init(void)
- pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0);
- if (IS_ERR(pdev)) {
- pr_err("failed to register mtk-cpufreq platform device\n");
-+ platform_driver_unregister(&mtk_cpufreq_platdrv);
- return PTR_ERR(pdev);
- }
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0006-powerdomain-add-mt7988-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0006-powerdomain-add-mt7988-support.patch
deleted file mode 100644
index 7fc4f1d..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0006-powerdomain-add-mt7988-support.patch
+++ /dev/null
@@ -1,9 +0,0 @@
-diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
-index b017330..1c485e3 100644
---- a/drivers/soc/mediatek/Makefile
-+++ b/drivers/soc/mediatek/Makefile
-@@ -3,3 +3,4 @@ obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
- obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
- obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
- obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
-+obj-$(CONFIG_MTK_SCPSYS) += mtk-pm-domains.o
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0020-dts-mt7622-enable-new-mtk-snand-for-ubi.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0020-dts-mt7622-enable-new-mtk-snand-for-ubi.patch
deleted file mode 100644
index 3a9e061..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0020-dts-mt7622-enable-new-mtk-snand-for-ubi.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -567,6 +567,20 @@
- status = "disabled";
- };
-
-+ snand: snfi@1100d000 {
-+ compatible = "mediatek,mt7622-snand";
-+ reg = <0 0x1100d000 0 0x1000>, <0 0x1100e000 0 0x1000>;
-+ reg-names = "nfi", "ecc";
-+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
-+ clocks = <&pericfg CLK_PERI_NFI_PD>,
-+ <&pericfg CLK_PERI_SNFI_PD>,
-+ <&pericfg CLK_PERI_NFIECC_PD>;
-+ clock-names = "nfi_clk", "pad_clk", "ecc_clk";
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ status = "disabled";
-+ };
-+
- nor_flash: spi@11014000 {
- compatible = "mediatek,mt7622-nor",
- "mediatek,mt8173-nor";
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0021-dts-mt7622-remove-cooling-device.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0021-dts-mt7622-remove-cooling-device.patch
deleted file mode 100644
index efcc14f..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0021-dts-mt7622-remove-cooling-device.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
-@@ -167,25 +167,6 @@
- };
- };
-
-- cooling-maps {
-- map0 {
-- trip = <&cpu_passive>;
-- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
-- };
--
-- map1 {
-- trip = <&cpu_active>;
-- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
-- };
--
-- map2 {
-- trip = <&cpu_hot>;
-- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
-- };
-- };
- };
- };
-
---
-2.29.2
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0200-show_model_name_in_cpuinfo_on_arm64.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0200-show_model_name_in_cpuinfo_on_arm64.patch
deleted file mode 100644
index 98e5ab6..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0200-show_model_name_in_cpuinfo_on_arm64.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Index: linux-5.4.70/arch/arm64/kernel/cpuinfo.c
-===================================================================
---- linux-5.4.70.orig/arch/arm64/kernel/cpuinfo.c
-+++ linux-5.4.70/arch/arm64/kernel/cpuinfo.c
-@@ -139,9 +139,8 @@ static int c_show(struct seq_file *m, vo
- * "processor". Give glibc what it expects.
- */
- seq_printf(m, "processor\t: %d\n", i);
-- if (compat)
-- seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
-- MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
-+ seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
-+ MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
-
- seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
- loops_per_jiffy / (500000UL/HZ),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0491-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0491-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch
deleted file mode 100644
index 7951d63..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0491-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/mtd/nand/spi/macronix.c
-+++ b/drivers/mtd/nand/spi/macronix.c
-@@ -86,7 +86,7 @@ static int mx35lf1ge4ab_ecc_get_status(s
- if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
- return nand->eccreq.strength;
-
-- if (WARN_ON(eccsr > nand->eccreq.strength || !eccsr))
-+ if (eccsr > nand->eccreq.strength || !eccsr)
- return nand->eccreq.strength;
-
- return eccsr;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0504-macsec-revert-async-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0504-macsec-revert-async-support.patch
deleted file mode 100644
index d52db50..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0504-macsec-revert-async-support.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/net/macsec.c
-+++ b/drivers/net/macsec.c
-@@ -1309,8 +1309,7 @@
- struct crypto_aead *tfm;
- int ret;
-
-- /* Pick a sync gcm(aes) cipher to ensure order is preserved. */
-- tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
-+ tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
-
- if (IS_ERR(tfm))
- return tfm;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0666-spi-mtk-nor-fix-timeout-calculation-overflow.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0666-spi-mtk-nor-fix-timeout-calculation-overflow.patch
deleted file mode 100644
index 86b2089..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0666-spi-mtk-nor-fix-timeout-calculation-overflow.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From patchwork Tue Sep 22 11:49:02 2020
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Chuanhong Guo <gch981213@gmail.com>
-X-Patchwork-Id: 11792387
-Return-Path:
- <SRS0=i66O=C7=lists.infradead.org=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@kernel.org>
-Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org
- [172.30.200.123])
- by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 21EB0618
- for <patchwork-linux-arm@patchwork.kernel.org>;
- Tue, 22 Sep 2020 11:51:33 +0000 (UTC)
-Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134])
- (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
- (No client certificate requested)
- by mail.kernel.org (Postfix) with ESMTPS id E15FF221EB
- for <patchwork-linux-arm@patchwork.kernel.org>;
- Tue, 22 Sep 2020 11:51:32 +0000 (UTC)
-Authentication-Results: mail.kernel.org;
- dkim=pass (2048-bit key) header.d=lists.infradead.org
- header.i=@lists.infradead.org header.b="KBg/skkC";
- dkim=fail reason="signature verification failed" (2048-bit key)
- header.d=gmail.com header.i=@gmail.com header.b="Gtqp4rrT"
-DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E15FF221EB
-Authentication-Results: mail.kernel.org;
- dmarc=fail (p=none dis=none) header.from=gmail.com
-Authentication-Results: mail.kernel.org;
- spf=none
- smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org
-DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
- d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding:
- Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive:
- List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From:
- Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender
- :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner;
- bh=Xg61WV47qNPjINdHDPnF6T3q8GN8f9evwhTMdYR0Zqs=; b=KBg/skkCvnF7/8AlleTay0p/H2
- hC4Lzo+slWhX5/eepUEXzhTr5ORf4Dx9gD65UEuordKQKFpg6Y9ApoGaYtmBJ0vABdAZt+oVG4sFf
- K3z3CYV6EZ5qvwsZt53Xm3YsHojgu+Lnc/MGgGWBRjCtTP7gshm480pZ0w6ADgHvrym5hNajUF6+5
- zMm5Wwq34jxUApGU7k5FAPsvO5ctYCuhECq/mLB6tplCVh3/+XLdSiHMUlY17fh+xs732kgaDotuQ
- QYgXtDmMB1pVKCq5cf3Bcuz7Ww47vLSx4rBxtdB/vpp2w9SdrU6K8Q7DuJ3+XrGfbMhKtBU5ektA8
- GxEUUaKw==;
-Received: from localhost ([::1] helo=merlin.infradead.org)
- by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux))
- id 1kKgo2-0000Ze-Fb; Tue, 22 Sep 2020 11:50:00 +0000
-Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543])
- by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux))
- id 1kKgnr-0000Vv-6z; Tue, 22 Sep 2020 11:49:49 +0000
-Received: by mail-pg1-x543.google.com with SMTP id o25so6798387pgm.0;
- Tue, 22 Sep 2020 04:49:46 -0700 (PDT)
-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;
- h=from:to:cc:subject:date:message-id:mime-version
- :content-transfer-encoding;
- bh=EJwpKrbgqo/Jc/SWHvyAGB9CrpkZ5L1Hzq9tInFHTYk=;
- b=Gtqp4rrTgM1+bYxfUQXe+lfPcgHRW6GccdN42Iszl6ozMbezvftl1BUcKE22S6eFW3
- Vs+lcKZN9Eh9C53YAAd0cuZYhJ2GqlfGNLA/9SyB7s/gIwHqO9Cuu17YpB9dAFfEUxoS
- 825uUcTeRe6BTagZAh2/MBluiMY3TszRi94MbOftxUg+wSqp0wMAPe9RN0gAEc/l2xgK
- 8PhXbZv3uItI4QqoKYiz93vrF/zYhj+oGTI44g2li2fpAgCNL7lXCpSE2C9NsEe+YqTw
- aO5A3W8t4jvp8oCJEvr/MWY1ZZLd1fVJ17W3aGXoDi/7EUcAvX9G5Ee7U68UXGMtty/d
- z5Nw==
-X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
- d=1e100.net; s=20161025;
- h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version
- :content-transfer-encoding;
- bh=EJwpKrbgqo/Jc/SWHvyAGB9CrpkZ5L1Hzq9tInFHTYk=;
- b=XhcpP16zYyJr/qCT9JbO3fn8RyfI44xJL3hvgNrlcr4ljkEZ4TF6OfyhjdEZYeeA3C
- kLlWuAqrSn6mweuhS2LZ0BV5QL/YYaVO4wP4B/y3j+tNbnW3JNM0NtEY19pOtaM4vYK/
- tPuNxld5RvJWxQ9BLs8hH6y7j/ob6oDug170P5YkwK6Wa/FLCi2bw92/vldhdnFP/Nny
- 1bbiWRVls1Ra/Q3z90tGViMkBdlcff6MI9DR5M6a1HTQN7kN9rLDCMGs3r9XVComY07N
- ECbrZbL+iJwuRuT43RAUxE72X/Pn0WYD20unzITf8bta92usNDRgEuxc1bLyL+uHxgUk
- YQKA==
-X-Gm-Message-State: AOAM531Xr1Bg4uwupCAPpH4eBWVrXGALjIWa+5AVNZ8w6ltS4BGgWv6b
- e4g6ycKnUp/KalpJhOMi90o=
-X-Google-Smtp-Source:
- ABdhPJx36OliaaLkiX3ZeZNNWgd/qSKiRor2X0eeHScDrjMSi5bTiEzAfX5j7hkQgqz8ZUT0qqLRNA==
-X-Received: by 2002:a63:1863:: with SMTP id 35mr3131307pgy.413.1600775385014;
- Tue, 22 Sep 2020 04:49:45 -0700 (PDT)
-Received: from guoguo-omen.lan ([156.96.148.94])
- by smtp.gmail.com with ESMTPSA id r4sm2223750pjf.4.2020.09.22.04.49.42
- (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
- Tue, 22 Sep 2020 04:49:44 -0700 (PDT)
-From: Chuanhong Guo <gch981213@gmail.com>
-To: linux-spi@vger.kernel.org
-Subject: [PATCH v2] spi: spi-mtk-nor: fix timeout calculation overflow
-Date: Tue, 22 Sep 2020 19:49:02 +0800
-Message-Id: <20200922114905.2942859-1-gch981213@gmail.com>
-X-Mailer: git-send-email 2.26.2
-MIME-Version: 1.0
-X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3
-X-CRM114-CacheID: sfid-20200922_074948_345420_69207EBE
-X-CRM114-Status: GOOD ( 12.60 )
-X-Spam-Score: 2.6 (++)
-X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary:
- Content analysis details: (2.6 points)
- pts rule name description
- ---- ----------------------
- --------------------------------------------------
- 2.6 RCVD_IN_SBL RBL: Received via a relay in Spamhaus SBL
- [156.96.148.94 listed in zen.spamhaus.org]
- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/,
- no trust [2607:f8b0:4864:20:0:0:0:543 listed in]
- [list.dnswl.org]
- 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail
- provider [gch981213[at]gmail.com]
- 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends
- in digit [gch981213[at]gmail.com]
- -0.0 SPF_PASS SPF: sender matches SPF record
- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record
- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature
- -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from
- author's domain
- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from
- envelope-from domain
- 0.1 DKIM_SIGNED Message has a DKIM or DK signature,
- not necessarily
- valid
-X-BeenThere: linux-arm-kernel@lists.infradead.org
-X-Mailman-Version: 2.1.29
-Precedence: list
-List-Id: <linux-arm-kernel.lists.infradead.org>
-List-Unsubscribe:
- <http://lists.infradead.org/mailman/options/linux-arm-kernel>,
- <mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>
-List-Archive: <http://lists.infradead.org/pipermail/linux-arm-kernel/>
-List-Post: <mailto:linux-arm-kernel@lists.infradead.org>
-List-Help: <mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>
-List-Subscribe:
- <http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,
- <mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>
-Cc: linux-kernel@vger.kernel.org, stable@vger.kernel.org,
- Mark Brown <broonie@kernel.org>, linux-mediatek@lists.infradead.org,
- bayi.cheng@mediatek.com, Matthias Brugger <matthias.bgg@gmail.com>,
- Chuanhong Guo <gch981213@gmail.com>, linux-arm-kernel@lists.infradead.org
-Sender: "linux-arm-kernel" <linux-arm-kernel-bounces@lists.infradead.org>
-Errors-To:
- linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org
-
-CLK_TO_US macro is used to calculate potential transfer time for various
-timeout handling. However it overflows on transfer bigger than 512 bytes
-because it first did (len * 8 * 1000000).
-This controller typically operates at 45MHz. This patch did 2 things:
-1. calculate clock / 1000000 first
-2. add a 4M transfer size cap so that the final timeout in DMA reading
- doesn't overflow
-
-Fixes: 881d1ee9fe81f ("spi: add support for mediatek spi-nor controller")
-Cc: <stable@vger.kernel.org>
-Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
----
-
-Change since v1: fix transfer size cap to 4M
-
- drivers/spi/spi-mtk-nor.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
-index 6e6ca2b8e6c82..62f5ff2779884 100644
---- a/drivers/spi/spi-mtk-nor.c
-+++ b/drivers/spi/spi-mtk-nor.c
-@@ -89,7 +89,7 @@
- // Buffered page program can do one 128-byte transfer
- #define MTK_NOR_PP_SIZE 128
-
--#define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq)
-+#define CLK_TO_US(sp, clkcnt) DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000)
-
- struct mtk_nor {
- struct spi_controller *ctlr;
-@@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
- if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
- if ((op->data.dir == SPI_MEM_DATA_IN) &&
- mtk_nor_match_read(op)) {
-+ // limit size to prevent timeout calculation overflow
-+ if (op->data.nbytes > 0x400000)
-+ op->data.nbytes = 0x400000;
-+
- if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) ||
- (op->data.nbytes < MTK_NOR_DMA_ALIGN))
- op->data.nbytes = 1;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0667-spi-mediatek-fix-timeout-for-large-data.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0667-spi-mediatek-fix-timeout-for-large-data.patch
deleted file mode 100644
index a04f5d6..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0667-spi-mediatek-fix-timeout-for-large-data.patch
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -720,6 +720,23 @@ static irqreturn_t mtk_spi_interrupt(int
- return IRQ_HANDLED;
- }
-
-+static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
-+ struct spi_mem_op *op)
-+{
-+ int opcode_len;
-+
-+ if(!op->data.nbytes)
-+ return 0;
-+
-+ if (op->data.dir != SPI_MEM_NO_DATA) {
-+ opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
-+ if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE)
-+ op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE -opcode_len;
-+ }
-+
-+ return 0;
-+}
-+
- static bool mtk_spi_mem_supports_op(struct spi_mem *mem,
- const struct spi_mem_op *op)
- {
-@@ -946,6 +963,7 @@ err_exit:
- }
-
- static const struct spi_controller_mem_ops mtk_spi_mem_ops = {
-+ .adjust_op_size = mtk_spi_mem_adjust_op_size,
- .supports_op = mtk_spi_mem_supports_op,
- .exec_op = mtk_spi_mem_exec_op,
- };
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0668-spi-mediatek-fix-dma-unmap-twice.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0668-spi-mediatek-fix-dma-unmap-twice.patch
deleted file mode 100644
index 31562bf..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0668-spi-mediatek-fix-dma-unmap-twice.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -946,12 +946,10 @@ static int mtk_spi_mem_exec_op(struct sp
- reg_val &= ~SPI_CMD_RX_DMA;
- writel(reg_val, mdata->base + SPI_CMD_REG);
-
-+unmap_rx_dma:
- if (op->data.dir == SPI_MEM_DATA_IN)
- dma_unmap_single(mdata->dev, mdata->rx_dma,
- op->data.nbytes, DMA_FROM_DEVICE);
--unmap_rx_dma:
-- dma_unmap_single(mdata->dev, mdata->rx_dma,
-- op->data.nbytes, DMA_FROM_DEVICE);
- unmap_tx_dma:
- dma_unmap_single(mdata->dev, mdata->tx_dma,
- tx_size, DMA_TO_DEVICE);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0669-fix-SPIM-NAND-and-NOR-probing.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0669-fix-SPIM-NAND-and-NOR-probing.patch
deleted file mode 100644
index 582771b..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0669-fix-SPIM-NAND-and-NOR-probing.patch
+++ /dev/null
@@ -1,33 +0,0 @@
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -1073,7 +1073,7 @@ static int mtk_spi_probe(struct platform
- goto err_put_master;
- }
-
--/*
-+
- mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
- if (IS_ERR(mdata->parent_clk)) {
- ret = PTR_ERR(mdata->parent_clk);
-@@ -1101,17 +1101,17 @@ static int mtk_spi_probe(struct platform
- goto err_put_master;
- }
-
-- ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
-+ /*ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
- clk_disable_unprepare(mdata->spi_clk);
- goto err_put_master;
- }
-
-- clk_disable_unprepare(mdata->spi_clk);
-+ clk_disable_unprepare(mdata->sel_clk);*/
-+
-+ //pm_runtime_enable(&pdev->dev);
-
-- pm_runtime_enable(&pdev->dev);
--*/
- ret = devm_spi_register_master(&pdev->dev, master);
- if (ret) {
- dev_err(&pdev->dev, "failed to register master (%d)\n", ret);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0701-fix-mtk-nfi-driver-dependency.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0701-fix-mtk-nfi-driver-dependency.patch
deleted file mode 100644
index 3023076..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0701-fix-mtk-nfi-driver-dependency.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -429,6 +429,7 @@ config SPI_MT65XX
-
- config SPI_MTK_SNFI
- tristate "MediaTek SPI NAND interface"
-+ depends on MTD
- select MTD_SPI_NAND
- help
- This selects the SPI NAND FLASH interface(SNFI),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0920-kernel-MT7988-fix-spi-dma-unmap.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0920-kernel-MT7988-fix-spi-dma-unmap.patch
deleted file mode 100644
index 5129e37..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0920-kernel-MT7988-fix-spi-dma-unmap.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-From 38d0cd2179791e27f06e1cfc6773f35b699ee99a Mon Sep 17 00:00:00 2001
-From: liya Li <ot_liya.li@mediatek.com>
-Date: Thu, 2 Feb 2023 14:26:39 +0800
-Subject: [PATCH] [WCNCR00293802][kernel][MT7988] fix spi dma unmap
-
-[Description]
-Use dma_unmap_single before memcpy to ensure that
-CPU can get the latest and correct data
-
-[Release-log]
-N/A
-
-Signed-off-by: liya Li <ot_liya.li@mediatek.com>
-Change-Id: Ib0b51e34e289c670f0d020fb62a15078ed116203
----
- drivers/spi/spi-mt65xx.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
-index 1b272d15cc..2034d19790 100644
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -978,12 +978,12 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
-
- unmap_rx_dma:
- if (op->data.dir == SPI_MEM_DATA_IN) {
-+ dma_unmap_single(mdata->dev, mdata->rx_dma,
-+ op->data.nbytes, DMA_FROM_DEVICE);
- if(!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
- memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes);
- kfree(rx_tmp_buf);
- }
-- dma_unmap_single(mdata->dev, mdata->rx_dma,
-- op->data.nbytes, DMA_FROM_DEVICE);
- }
- unmap_tx_dma:
- dma_unmap_single(mdata->dev, mdata->tx_dma,
---
-2.18.0
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0961-dual-image-mount-rootfs.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0961-dual-image-mount-rootfs.patch
deleted file mode 100755
index 99f72c0..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0961-dual-image-mount-rootfs.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Index: linux-5.4.224/init/do_mounts.c
-===================================================================
---- linux-5.4.224.orig/init/do_mounts.c
-+++ linux-5.4.224/init/do_mounts.c
-@@ -576,7 +576,8 @@ void __init mount_root(void)
- }
- #endif
- #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-- if (!mount_ubi_rootfs())
-+ extern bool dual_boot;
-+ if (!dual_boot && !mount_ubi_rootfs())
- return;
- #endif
- #ifdef CONFIG_BLOCK
-Index: linux-5.4.224/kernel/boot_param.c
-===================================================================
---- linux-5.4.224.orig/kernel/boot_param.c
-+++ linux-5.4.224/kernel/boot_param.c
-@@ -10,7 +10,7 @@
-
- #define BOOT_PARAM_STR_MAX_LEN 256
-
--static bool dual_boot;
-+bool dual_boot;
- module_param(dual_boot, bool, 0444);
-
- static bool no_split_rootfs_data;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/2000-misc-add-mtk-platform.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/2000-misc-add-mtk-platform.patch
deleted file mode 100644
index f280e10..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/2000-misc-add-mtk-platform.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-diff -urN a/drivers/misc/Kconfig b/drivers/misc/Kconfig
---- a/drivers/misc/Kconfig 2021-06-29 15:10:00.970788831 +0800
-+++ b/drivers/misc/Kconfig 2021-06-29 15:09:41.579158152 +0800
-@@ -481,4 +481,5 @@
- source "drivers/misc/ocxl/Kconfig"
- source "drivers/misc/cardreader/Kconfig"
- source "drivers/misc/habanalabs/Kconfig"
-+source "drivers/misc/mediatek/Kconfig"
- endmenu
-diff -urN a/drivers/misc/Makefile b/drivers/misc/Makefile
---- a/drivers/misc/Makefile 2021-06-29 15:10:15.150518461 +0800
-+++ b/drivers/misc/Makefile 2021-06-29 15:09:46.939056121 +0800
-@@ -57,3 +57,4 @@
- obj-$(CONFIG_PVPANIC) += pvpanic.o
- obj-$(CONFIG_HABANA_AI) += habanalabs/
- obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
-+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/400-mtd-add-mtk-snand-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/400-mtd-add-mtk-snand-driver.patch
deleted file mode 100644
index f283bd2..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/400-mtd-add-mtk-snand-driver.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -230,6 +230,8 @@ source "drivers/mtd/hyperbus/Kconfig"
-
- source "drivers/mtd/nmbm/Kconfig"
-
-+source "drivers/mtd/mtk-snand/Kconfig"
-+
- source "drivers/mtd/composite/Kconfig"
-
- endif # MTD
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -35,5 +35,7 @@ obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
-
- obj-y += nmbm/
-
-+obj-$(CONFIG_MTK_SPI_NAND) += mtk-snand/
-+
- # Composite drivers must be loaded last
- obj-y += composite/
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/415-mtd-spinand-fix-F50L1G41LB-ecc-check.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/415-mtd-spinand-fix-F50L1G41LB-ecc-check.patch
deleted file mode 100644
index e4e51bb..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/415-mtd-spinand-fix-F50L1G41LB-ecc-check.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/mtd/nand/spi/gigadevice.c
-+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -263,8 +263,7 @@ static const struct spinand_info gigadev
- &write_cache_variants,
- &update_cache_variants),
- 0,
-- SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
-- gd5fxgq4xa_ecc_get_status)),
-+ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, NULL)),
- SPINAND_INFO("GD5F1GQ4xA",
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
- NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/416-mtd-spinor-support-EN25QX128A.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/416-mtd-spinor-support-EN25QX128A.patch
deleted file mode 100644
index 2985532..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/416-mtd-spinor-support-EN25QX128A.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/mtd/spi-nor/spi-nor.c 2022-12-14 15:29:28.587567592 +0800
-+++ b/drivers/mtd/spi-nor/spi-nor.c 2022-12-14 15:04:52.625250000 +0800
-@@ -2246,6 +2246,9 @@ static const struct flash_info spi_nor_i
- { "en25qh64", INFO(0x1c7017, 0, 64 * 1024, 128,
- SECT_4K | SPI_NOR_DUAL_READ) },
- { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) },
-+ { "en25qx128", INFO(0x1c7118, 0, 64 * 1024, 256,
-+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
- { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
- { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/492-mtd-tests-fix-pagetest-load.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/492-mtd-tests-fix-pagetest-load.patch
deleted file mode 100644
index f10b5c5..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/492-mtd-tests-fix-pagetest-load.patch
+++ /dev/null
@@ -1,42 +0,0 @@
---- a/drivers/mtd/tests/pagetest.c 2022-11-28 16:08:26.978090509 +0800
-+++ b/drivers/mtd/tests/pagetest.c 2022-11-28 16:10:04.351026850 +0800
-@@ -25,6 +25,10 @@ static int dev = -EINVAL;
- module_param(dev, int, S_IRUGO);
- MODULE_PARM_DESC(dev, "MTD device number to use");
-
-+static int count = 10000;
-+module_param(count, int, 0444);
-+MODULE_PARM_DESC(count, "Number of operations to do (default is 10000)");
-+
- static struct mtd_info *mtd;
- static unsigned char *twopages;
- static unsigned char *writebuf;
-@@ -331,7 +335,7 @@ static int __init mtd_pagetest_init(void
- return -EINVAL;
- }
-
-- pr_info("MTD device: %d\n", dev);
-+ pr_info("MTD device: %d count:%d\n", dev, count);
-
- mtd = get_mtd_device(NULL, dev);
- if (IS_ERR(mtd)) {
-@@ -376,6 +380,7 @@ static int __init mtd_pagetest_init(void
- if (err)
- goto out;
-
-+LOOP:
- /* Erase all eraseblocks */
- pr_info("erasing whole device\n");
- err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
-@@ -435,7 +440,10 @@ static int __init mtd_pagetest_init(void
- if (err)
- goto out;
-
-- pr_info("finished with %d errors\n", errcnt);
-+ pr_info("finished with %d errors count:%d\n", errcnt, count);
-+
-+ if (count-- > 0)
-+ goto LOOP;
- out:
-
- kfree(bbt);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7000-fix-race-inside-napi-enable.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7000-fix-race-inside-napi-enable.patch
deleted file mode 100644
index 052f40c..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7000-fix-race-inside-napi-enable.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From git@z Thu Jan 1 00:00:00 1970
-Subject: [PATCH v2] napi: fix race inside napi_enable
-From: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Date: Sat, 18 Sep 2021 16:52:32 +0800
-Message-Id: <20210918085232.71436-1-xuanzhuo@linux.alibaba.com>
-To: netdev@vger.kernel.org, linyunsheng@huawei.com
-Cc: "David S. Miller" <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>, Eric Dumazet <edumazet@google.com>, Daniel Borkmann <daniel@iogearbox.net>, Antoine Tenart <atenart@kernel.org>, Alexander Lobakin <alobakin@pm.me>, Wei Wang <weiwan@google.com>, Taehee Yoo <ap420073@gmail.com>,Björn Töpel <bjorn@kernel.org>, Arnd Bergmann <arnd@arndb.de>, Kumar Kartikeya Dwivedi <memxor@gmail.com>, Neil Horman <nhorman@redhat.com>, Dust Li <dust.li@linux.alibaba.com>
-List-Id: <netdev.vger.kernel.org>
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 7bit
-
-The process will cause napi.state to contain NAPI_STATE_SCHED and
-not in the poll_list, which will cause napi_disable() to get stuck.
-
-The prefix "NAPI_STATE_" is removed in the figure below, and
-NAPI_STATE_HASHED is ignored in napi.state.
-
- CPU0 | CPU1 | napi.state
-===============================================================================
-napi_disable() | | SCHED | NPSVC
-napi_enable() | |
-{ | |
- smp_mb__before_atomic(); | |
- clear_bit(SCHED, &n->state); | | NPSVC
- | napi_schedule_prep() | SCHED | NPSVC
- | napi_poll() |
- | napi_complete_done() |
- | { |
- | if (n->state & (NPSVC | | (1)
- | _BUSY_POLL))) |
- | return false; |
- | ................ |
- | } | SCHED | NPSVC
- | |
- clear_bit(NPSVC, &n->state); | | SCHED
-} | |
- | |
-napi_schedule_prep() | | SCHED | MISSED (2)
-
-(1) Here return direct. Because of NAPI_STATE_NPSVC exists.
-(2) NAPI_STATE_SCHED exists. So not add napi.poll_list to sd->poll_list
-
-Since NAPI_STATE_SCHED already exists and napi is not in the
-sd->poll_list queue, NAPI_STATE_SCHED cannot be cleared and will always
-exist.
-
-1. This will cause this queue to no longer receive packets.
-2. If you encounter napi_disable under the protection of rtnl_lock, it
- will cause the entire rtnl_lock to be locked, affecting the overall
- system.
-
-This patch uses cmpxchg to implement napi_enable(), which ensures that
-there will be no race due to the separation of clear two bits.
-
-Fixes: 2d8bff12699abc ("netpoll: Close race condition between poll_one_napi and napi_disable")
-Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
-Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
----
- net/core/dev.c | 16 ++++++++++------
- 1 file changed, 10 insertions(+), 6 deletions(-)
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index 74fd402d26dd..7ee9fecd3aff 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -6923,12 +6923,16 @@ EXPORT_SYMBOL(napi_disable);
- */
- void napi_enable(struct napi_struct *n)
- {
-- BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
-- smp_mb__before_atomic();
-- clear_bit(NAPI_STATE_SCHED, &n->state);
-- clear_bit(NAPI_STATE_NPSVC, &n->state);
-- if (n->dev->threaded && n->thread)
-- set_bit(NAPI_STATE_THREADED, &n->state);
-+ unsigned long val, new;
-+
-+ do {
-+ val = READ_ONCE(n->state);
-+ BUG_ON(!test_bit(NAPI_STATE_SCHED, &val));
-+
-+ new = val & ~(NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC);
-+ if (n->dev->threaded && n->thread)
-+ new |= NAPIF_STATE_THREADED;
-+ } while (cmpxchg(&n->state, val, new) != val);
- }
- EXPORT_SYMBOL(napi_enable);
-
-
---
-2.31.0
-
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7001-net-make-napi-disable-symmetric-with-enable.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7001-net-make-napi-disable-symmetric-with-enable.patch
deleted file mode 100644
index ac84ffc..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7001-net-make-napi-disable-symmetric-with-enable.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From git@z Thu Jan 1 00:00:00 1970
-Subject: [PATCH v2] net: make napi_disable() symmetric with enable
-From: Jakub Kicinski <kuba@kernel.org>
-Date: Fri, 24 Sep 2021 13:24:53 -0700
-Message-Id: <20210924202453.1051687-1-kuba@kernel.org>
-To: davem@davemloft.net
-Cc: netdev@vger.kernel.org, eric.dumazet@gmail.com, weiwan@google.com, xuanzhuo@linux.alibaba.com, Jakub Kicinski <kuba@kernel.org>
-List-Id: <netdev.vger.kernel.org>
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 7bit
-
-Commit 3765996e4f0b ("napi: fix race inside napi_enable") fixed
-an ordering bug in napi_enable() and made the napi_enable() diverge
-from napi_disable(). The state transitions done on disable are
-not symmetric to enable.
-
-There is no known bug in napi_disable() this is just refactoring.
-
-Eric suggests we can also replace msleep(1) with a more opportunistic
-usleep_range().
-
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- net/core/dev.c | 17 ++++++++++++-----
- 1 file changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index f24c3a9..f0a556a 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -6386,18 +6386,25 @@ EXPORT_SYMBOL(netif_napi_add);
-
- void napi_disable(struct napi_struct *n)
- {
-+ unsigned long val, new;
-+
- might_sleep();
- set_bit(NAPI_STATE_DISABLE, &n->state);
-
-- while (test_and_set_bit(NAPI_STATE_SCHED, &n->state))
-- msleep(1);
-- while (test_and_set_bit(NAPI_STATE_NPSVC, &n->state))
-- msleep(1);
-+ do {
-+ val = READ_ONCE(n->state);
-+ if (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) {
-+ usleep_range(20, 200);
-+ continue;
-+ }
-+
-+ new = val | NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC;
-+ new &= ~(NAPIF_STATE_THREADED);
-+ } while (cmpxchg(&n->state, val, new) != val);
-
- hrtimer_cancel(&n->timer);
-
- clear_bit(NAPI_STATE_DISABLE, &n->state);
-- clear_bit(NAPI_STATE_THREADED, &n->state);
- }
- EXPORT_SYMBOL(napi_disable);
-
---
-2.31.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7002-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7002-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch
deleted file mode 100644
index 0daf233..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/7002-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From git@z Thu Jan 1 00:00:00 1970
-Subject: [PATCH v2] net: fix premature exit from NAPI state polling in napi_disable()
-From: Alexander Lobakin <alexandr.lobakin@intel.com>
-Date: Wed, 10 Nov 2021 20:56:05 +0100
-Message-Id: <20211110195605.1304-1-alexandr.lobakin@intel.com>
-To: "David S. Miller" <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>
-Cc: Alexander Lobakin <alexandr.lobakin@intel.com>, Jesse Brandeburg <jesse.brandeburg@intel.com>, Maciej Fijalkowski <maciej.fijalkowski@intel.com>, Michal Swiatkowski <michal.swiatkowski@intel.com>, Xuan Zhuo <xuanzhuo@linux.alibaba.com>, Antoine Tenart <atenart@kernel.org>, Eric Dumazet <edumazet@google.com>, Wei Wang <weiwan@google.com>,Björn Töpel <bjorn@kernel.org>, netdev@vger.kernel.org, linux-kernel@vger.kernel.org
-List-Id: <linux-kernel.vger.kernel.org>
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 7bit
-
-Commit 719c57197010 ("net: make napi_disable() symmetric with
-enable") accidentally introduced a bug sometimes leading to a kernel
-BUG when bringing an iface up/down under heavy traffic load.
-
-Prior to this commit, napi_disable() was polling n->state until
-none of (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC) is set and then
-always flip them. Now there's a possibility to get away with the
-NAPIF_STATE_SCHE unset as 'continue' drops us to the cmpxchg()
-call with an unitialized variable, rather than straight to
-another round of the state check.
-
-Error path looks like:
-
-napi_disable():
-unsigned long val, new; /* new is uninitialized */
-
-do {
- val = READ_ONCE(n->state); /* NAPIF_STATE_NPSVC and/or
- NAPIF_STATE_SCHED is set */
- if (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) { /* true */
- usleep_range(20, 200);
- continue; /* go straight to the condition check */
- }
- new = val | <...>
-} while (cmpxchg(&n->state, val, new) != val); /* state == val, cmpxchg()
- writes garbage */
-
-napi_enable():
-do {
- val = READ_ONCE(n->state);
- BUG_ON(!test_bit(NAPI_STATE_SCHED, &val)); /* 50/50 boom */
-<...>
-
-while the typical BUG splat is like:
-
-[ 172.652461] ------------[ cut here ]------------
-[ 172.652462] kernel BUG at net/core/dev.c:6937!
-[ 172.656914] invalid opcode: 0000 [#1] PREEMPT SMP PTI
-[ 172.661966] CPU: 36 PID: 2829 Comm: xdp_redirect_cp Tainted: G I 5.15.0 #42
-[ 172.670222] Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.02.01.0014.082620210524 08/26/2021
-[ 172.680646] RIP: 0010:napi_enable+0x5a/0xd0
-[ 172.684832] Code: 07 49 81 cc 00 01 00 00 4c 89 e2 48 89 d8 80 e6 fb f0 48 0f b1 55 10 48 39 c3 74 10 48 8b 5d 10 f6 c7 04 75 3d f6 c3 01 75 b4 <0f> 0b 5b 5d 41 5c c3 65 ff 05 b8 e5 61 53 48 c7 c6 c0 f3 34 ad 48
-[ 172.703578] RSP: 0018:ffffa3c9497477a8 EFLAGS: 00010246
-[ 172.708803] RAX: ffffa3c96615a014 RBX: 0000000000000000 RCX: ffff8a4b575301a0
-< snip >
-[ 172.782403] Call Trace:
-[ 172.784857] <TASK>
-[ 172.786963] ice_up_complete+0x6f/0x210 [ice]
-[ 172.791349] ice_xdp+0x136/0x320 [ice]
-[ 172.795108] ? ice_change_mtu+0x180/0x180 [ice]
-[ 172.799648] dev_xdp_install+0x61/0xe0
-[ 172.803401] dev_xdp_attach+0x1e0/0x550
-[ 172.807240] dev_change_xdp_fd+0x1e6/0x220
-[ 172.811338] do_setlink+0xee8/0x1010
-[ 172.814917] rtnl_setlink+0xe5/0x170
-[ 172.818499] ? bpf_lsm_binder_set_context_mgr+0x10/0x10
-[ 172.823732] ? security_capable+0x36/0x50
-< snip >
-
-Fix this by replacing 'do { } while (cmpxchg())' with an "infinite"
-for-loop with an explicit break.
-
-From v1 [0]:
- - just use a for-loop to simplify both the fix and the existing
- code (Eric).
-
-[0] https://lore.kernel.org/netdev/20211110191126.1214-1-alexandr.lobakin@intel.com
-
-Fixes: 719c57197010 ("net: make napi_disable() symmetric with enable")
-Suggested-by: Eric Dumazet <edumazet@google.com> # for-loop
-Signed-off-by: Alexander Lobakin <alexandr.lobakin@intel.com>
-Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
-Reviewed-by: Eric Dumazet <edumazet@google.com>
----
- net/core/dev.c | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/net/core/dev.c b/net/core/dev.c
-index c8f7c15..fe2c856 100644
---- a/net/core/dev.c
-+++ b/net/core/dev.c
-@@ -6391,7 +6391,7 @@ void napi_disable(struct napi_struct *n)
- might_sleep();
- set_bit(NAPI_STATE_DISABLE, &n->state);
-
-- do {
-+ for ( ; ; ) {
- val = READ_ONCE(n->state);
- if (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) {
- usleep_range(20, 200);
-@@ -6400,7 +6400,10 @@ void napi_disable(struct napi_struct *n)
-
- new = val | NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC;
- new &= ~(NAPIF_STATE_THREADED);
-- } while (cmpxchg(&n->state, val, new) != val);
-+
-+ if (cmpxchg(&n->state, val, new) == val)
-+ break;
-+ }
-
- hrtimer_cancel(&n->timer);
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/740-add-gpy211-phy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/740-add-gpy211-phy-support.patch
deleted file mode 100644
index 2496084..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/740-add-gpy211-phy-support.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-Index: linux-5.4.119/drivers/net/phy/Kconfig
-===================================================================
---- linux-5.4.119.orig/drivers/net/phy/Kconfig
-+++ linux-5.4.119/drivers/net/phy/Kconfig
-@@ -468,6 +468,11 @@ config FIXED_PHY
-
- Currently tested with mpc866ads and mpc8349e-mitx.
-
-+config GPY211_PHY
-+ tristate "GPY211 PHY"
-+ ---help---
-+ Supports the Intel GPY211 PHY with rate adaption.
-+
- config ICPLUS_PHY
- tristate "ICPlus PHYs"
- ---help---
-Index: linux-5.4.119/drivers/net/phy/Makefile
-===================================================================
---- linux-5.4.119.orig/drivers/net/phy/Makefile
-+++ linux-5.4.119/drivers/net/phy/Makefile
-@@ -86,6 +86,7 @@ obj-$(CONFIG_DP83TC811_PHY) += dp83tc811
- obj-$(CONFIG_DP83848_PHY) += dp83848.o
- obj-$(CONFIG_DP83867_PHY) += dp83867.o
- obj-$(CONFIG_FIXED_PHY) += fixed_phy.o
-+obj-$(CONFIG_GPY211_PHY) += gpy211.o
- obj-$(CONFIG_ICPLUS_PHY) += icplus.o
- obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
- obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch
deleted file mode 100644
index 6de04c3..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-en8801sc-gphy-support.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-Index: drivers/net/phy/Kconfig
-===================================================================
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -350,6 +350,11 @@ config AIROHA_EN8801S_PHY
- depends on HWMON || HWMON=n
- select MDIO_I2C
-
-+config AIROHA_EN8801SC_PHY
-+ tristate "Drivers for Airoha EN8801S Gigabit PHYs for MediaTek SoC."
-+ ---help---
-+ Currently supports the Airoha EN8801S PHY for MediaTek SoC.
-+
- config AIROHA_EN8811H_PHY
- tristate "Drivers for Airoha EN8811H 2.5G Gigabit PHY"
- ---help---
-Index: drivers/net/phy/Makefile
-===================================================================
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -68,5 +68,6 @@ ifdef CONFIG_HWMON
- aquantia-objs += aquantia_hwmon.o
- endif
-+obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
- obj-$(CONFIG_AIROHA_EN8811H_PHY) += air_en8811h.o
- obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
- obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/746-add-mediatek-2p5ge-phy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/746-add-mediatek-2p5ge-phy-support.patch
deleted file mode 100644
index 161e90f..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/746-add-mediatek-2p5ge-phy-support.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -431,6 +431,11 @@ config MEDIATEK_GE_SOC_PHY
- present in the SoCs efuse and will dynamically calibrate VCM
- (common-mode voltage) during startup.
-
-+config MEDIATEK_2P5GE_PHY
-+ tristate "MediaTek 2.5Gb Ethernet PHYs"
-+ ---help---
-+ Supports MediaTek internal 2.5Gb Ethernet PHYs.
-+
- config MICREL_PHY
- tristate "Micrel PHYs"
- ---help---
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -79,6 +79,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
- obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o
- obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
- obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
-+obj-$(CONFIG_MEDIATEK_2P5GE_PHY)+= mediatek-2p5ge.o
- obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
- obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
- obj-$(CONFIG_MICREL_PHY) += micrel.o
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8001-PATCH-2-4-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8001-PATCH-2-4-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch
deleted file mode 100644
index f83e220..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8001-PATCH-2-4-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 8a79db5e83a5d52c74e6f3c40d6f312cf899213e Mon Sep 17 00:00:00 2001
-From: Jyri Sarha <jsarha@ti.com>
-Date: Wed, 8 Jan 2020 10:30:07 +0200
-Subject: [PATCH 1/5] dt-bindings: phy: Add PHY_TYPE_DP definition
-
-Add definition for DisplayPort phy type.
-
-Signed-off-by: Jyri Sarha <jsarha@ti.com>
-Reviewed-by: Roger Quadros <rogerq@ti.com>
-Reviewed-by: Kishon Vijay Abraham I <kishon@ti.com>
-Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
----
- include/dt-bindings/phy/phy.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
-index b6a1eaf1b339..1f3f866fae7b 100644
---- a/include/dt-bindings/phy/phy.h
-+++ b/include/dt-bindings/phy/phy.h
-@@ -16,5 +16,6 @@
- #define PHY_TYPE_USB2 3
- #define PHY_TYPE_USB3 4
- #define PHY_TYPE_UFS 5
-+#define PHY_TYPE_DP 6
-
- #endif /* _DT_BINDINGS_PHY */
---
-2.18.0
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8002-PATCH-3-4-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8002-PATCH-3-4-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch
deleted file mode 100644
index 7bd1ca7..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8002-PATCH-3-4-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From c5d3cdad688ed75fb311a3a671eb30ba7106d7d3 Mon Sep 17 00:00:00 2001
-From: Dilip Kota <eswara.kota@linux.intel.com>
-Date: Tue, 19 May 2020 14:19:19 +0800
-Subject: [PATCH 2/5] dt-bindings: phy: Add PHY_TYPE_XPCS definition
-
-Add definition for Ethernet PCS phy type.
-
-Signed-off-by: Dilip Kota <eswara.kota@linux.intel.com>
-Acked-by: Rob Herring <robh@kernel.org>
-Acked-By: Vinod Koul <vkoul@kernel.org>
-Link: https://lore.kernel.org/r/6091f0d2a1046f1e3656d9e33b6cc433d5465eaf.1589868358.git.eswara.kota@linux.intel.com
-Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
----
- include/dt-bindings/phy/phy.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
-index 1f3f866fae7b..3727ef72138b 100644
---- a/include/dt-bindings/phy/phy.h
-+++ b/include/dt-bindings/phy/phy.h
-@@ -17,5 +17,6 @@
- #define PHY_TYPE_USB3 4
- #define PHY_TYPE_UFS 5
- #define PHY_TYPE_DP 6
-+#define PHY_TYPE_XPCS 7
-
- #endif /* _DT_BINDINGS_PHY */
---
-2.18.0
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8003-PATCH-4-4-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8003-PATCH-4-4-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch
deleted file mode 100644
index ef5df66..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8003-PATCH-4-4-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From cea0f76a483d1270ac6f6513964e3e75193dda48 Mon Sep 17 00:00:00 2001
-From: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
-Date: Mon, 29 Jun 2020 15:00:52 +0300
-Subject: [PATCH 3/5] dt-bindings: phy: Add DT bindings for Xilinx ZynqMP PSGTR
- PHY
-
-Add DT bindings for the Xilinx ZynqMP PHY. ZynqMP SoCs have a High Speed
-Processing System Gigabit Transceiver which provides PHY capabilities to
-USB, SATA, PCIE, Display Port and Ehernet SGMII controllers.
-
-Signed-off-by: Anurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
-Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Reviewed-by: Rob Herring <robh@kernel.org>
-Link: https://lore.kernel.org/r/20200629120054.29338-2-laurent.pinchart@ideasonboard.com
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
----
- include/dt-bindings/phy/phy.h | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
-index 3727ef72138b..36e8c241cf48 100644
---- a/include/dt-bindings/phy/phy.h
-+++ b/include/dt-bindings/phy/phy.h
-@@ -18,5 +18,6 @@
- #define PHY_TYPE_UFS 5
- #define PHY_TYPE_DP 6
- #define PHY_TYPE_XPCS 7
-+#define PHY_TYPE_SGMII 8
-
- #endif /* _DT_BINDINGS_PHY */
---
-2.18.0
-
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9103-drivers-spi-mt65xx-add-dts-buswidth-flow.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9103-drivers-spi-mt65xx-add-dts-buswidth-flow.patch
deleted file mode 100644
index 31ceb83..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9103-drivers-spi-mt65xx-add-dts-buswidth-flow.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/spi/spi-mt65xx.c
-+++ b/drivers/spi/spi-mt65xx.c
-@@ -1080,7 +1080,7 @@ static int mtk_spi_probe(struct platform
- master->flags = SPI_MASTER_MUST_TX;
-
- if (mdata->dev_comp->ipm_design)
-- master->mode_bits |= SPI_LOOP;
-+ master->mode_bits |= SPI_LOOP | SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD;
-
- if (mdata->dev_comp->ipm_design) {
- mdata->dev = dev;
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-mdiobus-add-c45.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1600-mdiobus-add-c45.patch
similarity index 86%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-mdiobus-add-c45.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1600-mdiobus-add-c45.patch
index 93c00b8..acc6d2a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/745-mdiobus-add-c45.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1600-mdiobus-add-c45.patch
@@ -1,3 +1,12 @@
+From abf7f24a61f01977b657285d6425b1185354a29a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:05:59 +0800
+Subject: [PATCH] [backport-networking-generic][999-1600-mdiobus-add-c45.patch]
+
+---
+ include/linux/mdio.h | 49 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 0f1f784de..006d1c1e9 100644
--- a/include/linux/mdio.h
@@ -68,5 +77,5 @@
int mdiobus_unregister_device(struct mdio_device *mdiodev);
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1700-macsec-revert-async-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1700-macsec-revert-async-support.patch
new file mode 100644
index 0000000..3212b6b
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1700-macsec-revert-async-support.patch
@@ -0,0 +1,27 @@
+From 8b45e5c6b6b419305ef893e1dfdd4c69c020958b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:05:59 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1700-macsec-revert-async-support.patch]
+
+---
+ drivers/net/macsec.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index f729f55f6..e3f03c89c 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -1311,8 +1311,7 @@ static struct crypto_aead *macsec_alloc_tfm(char *key, int key_len, int icv_len)
+ struct crypto_aead *tfm;
+ int ret;
+
+- /* Pick a sync gcm(aes) cipher to ensure order is preserved. */
+- tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
++ tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
+
+ if (IS_ERR(tfm))
+ return tfm;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/741-add-default-setting-to-dsa-unused-port.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1701-add-default-setting-to-dsa-unused-port.patch
similarity index 71%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/741-add-default-setting-to-dsa-unused-port.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1701-add-default-setting-to-dsa-unused-port.patch
index 7769ebd..888a312 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/741-add-default-setting-to-dsa-unused-port.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1701-add-default-setting-to-dsa-unused-port.patch
@@ -1,8 +1,19 @@
-Index: linux-5.4.124/drivers/net/dsa/mt7530.c
-===================================================================
---- linux-5.4.124.orig/drivers/net/dsa/mt7530.c
-+++ linux-5.4.124/drivers/net/dsa/mt7530.c
-@@ -1021,6 +1021,9 @@ mt7530_stp_state_set(struct dsa_switch *
+From e3dd6804fa642a733b7a6932d60bb83b6363555c Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:05:59 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1701-add-default-setting-to-dsa-unused-port.patch]
+
+---
+ drivers/net/dsa/mt7530.c | 62 ++++++++++++++++++++++++++++++++++++++--
+ drivers/net/dsa/mt7530.h | 1 +
+ 2 files changed, 60 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
+index 8ce3d51e8..008432d5c 100644
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1022,6 +1022,9 @@ mt7530_stp_state_set(struct dsa_switch *ds, int port, u8 state)
struct mt7530_priv *priv = ds->priv;
u32 stp_state;
@@ -12,10 +23,11 @@
switch (state) {
case BR_STATE_DISABLED:
stp_state = MT7530_STP_DISABLED;
-@@ -1676,10 +1679,58 @@ mt7530_setup(struct dsa_switch *ds)
+@@ -1674,11 +1677,59 @@ mt7530_setup(struct dsa_switch *ds)
+ return 0;
}
- static int
++static int
+setup_unused_ports(struct dsa_switch *ds, u32 pm)
+{
+ struct mt7530_priv *priv = ds->priv;
@@ -62,7 +74,7 @@
+ return 0;
+}
+
-+static int
+ static int
mt7531_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
@@ -71,7 +83,7 @@
u32 val, id;
int ret, i;
-@@ -1767,7 +1818,9 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -1766,7 +1817,9 @@ mt7531_setup(struct dsa_switch *ds)
mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
@@ -82,7 +94,7 @@
mt753x_cpu_port_enable(ds, i);
else
mt7530_port_disable(ds, i);
-@@ -1777,6 +1830,9 @@ mt7531_setup(struct dsa_switch *ds)
+@@ -1776,6 +1829,9 @@ mt7531_setup(struct dsa_switch *ds)
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
}
@@ -92,7 +104,7 @@
ds->configure_vlan_while_not_filtering = true;
/* Flush the FDB table */
-@@ -2101,7 +2157,7 @@ mt7531_mac_config(struct dsa_switch *ds,
+@@ -2100,7 +2156,7 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
case PHY_INTERFACE_MODE_RGMII_RXID:
case PHY_INTERFACE_MODE_RGMII_TXID:
dp = dsa_to_port(ds, port);
@@ -101,7 +113,7 @@
return mt7531_rgmii_setup(priv, port, interface, phydev);
case PHY_INTERFACE_MODE_SGMII:
return mt7531_sgmii_setup_mode_an(priv, port, interface);
-@@ -2641,7 +2697,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -2640,7 +2696,7 @@ mt7530_probe(struct mdio_device *mdiodev)
if (!priv)
return -ENOMEM;
@@ -110,10 +122,10 @@
if (!priv->ds)
return -ENOMEM;
-Index: linux-5.4.124/drivers/net/dsa/mt7530.h
-===================================================================
---- linux-5.4.124.orig/drivers/net/dsa/mt7530.h
-+++ linux-5.4.124/drivers/net/dsa/mt7530.h
+diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
+index 6424bc90e..aa758b2d2 100644
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
@@ -10,6 +10,7 @@
#define MT7530_CPU_PORT 6
#define MT7530_NUM_FDB_RECORDS 2048
@@ -122,3 +134,6 @@
enum mt753x_id {
ID_MT7530 = 0,
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1702-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1702-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
index 948bb69..bf4cef7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1702-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch
@@ -1,8 +1,38 @@
-Index: linux-5.4.124/drivers/net/dsa/mt7530.c
-===================================================================
---- linux-5.4.124.orig/drivers/net/dsa/mt7530.c
-+++ linux-5.4.124/drivers/net/dsa/mt7530.c
-@@ -1830,6 +1830,8 @@ mt7531_setup(struct dsa_switch *ds)
+From b736c4488d00e4b6e363220746c666176c12ea90 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:05:59 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1702-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch]
+
+---
+ drivers/net/dsa/Makefile | 3 +-
+ drivers/net/dsa/mt7530.c | 2 +
+ drivers/net/dsa/mt7530.h | 1 +
+ drivers/net/dsa/mt7531_phy.c | 1378 ++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/mt7531_phy.h | 262 +++++++
+ 5 files changed, 1645 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/dsa/mt7531_phy.c
+ create mode 100644 drivers/net/dsa/mt7531_phy.h
+
+diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
+index ae70b7962..0aa10bc3d 100644
+--- a/drivers/net/dsa/Makefile
++++ b/drivers/net/dsa/Makefile
+@@ -6,7 +6,8 @@ ifdef CONFIG_NET_DSA_LOOP
+ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
+ endif
+ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
+-obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
++obj-$(CONFIG_NET_DSA_MT7530) += mt7530-dsa.o
++mt7530-dsa-objs := mt7530.o mt7531_phy.o
+ obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
+ obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
+ obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
+diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
+index 008432d5c..e4c021eeb 100644
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1829,6 +1829,8 @@ mt7531_setup(struct dsa_switch *ds)
PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
}
@@ -11,20 +41,21 @@
/* Group and enable unused ports as a standalone dumb switch. */
setup_unused_ports(ds, unused_pm);
-Index: linux-5.4.124/drivers/net/dsa/mt7530.h
-===================================================================
---- linux-5.4.124.orig/drivers/net/dsa/mt7530.h
-+++ linux-5.4.124/drivers/net/dsa/mt7530.h
-@@ -782,4 +782,5 @@ static inline void INIT_MT7530_DUMMY_POL
+diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
+index aa758b2d2..8f1e827ff 100644
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -782,4 +782,5 @@ static inline void INIT_MT7530_DUMMY_POLL(struct mt7530_dummy_poll *p,
p->reg = reg;
}
+int mt7531_phy_setup(struct dsa_switch *ds);
#endif /* __MT7530_H */
-Index: linux-5.4.124/drivers/net/dsa/mt7531_phy.c
-===================================================================
+diff --git a/drivers/net/dsa/mt7531_phy.c b/drivers/net/dsa/mt7531_phy.c
+new file mode 100644
+index 000000000..a5c1e7d54
--- /dev/null
-+++ linux-5.4.124/drivers/net/dsa/mt7531_phy.c
++++ b/drivers/net/dsa/mt7531_phy.c
@@ -0,0 +1,1378 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
@@ -1404,10 +1435,11 @@
+
+ return ret;
+}
-Index: linux-5.4.124/drivers/net/dsa/mt7531_phy.h
-===================================================================
+diff --git a/drivers/net/dsa/mt7531_phy.h b/drivers/net/dsa/mt7531_phy.h
+new file mode 100644
+index 000000000..4cacabf54
--- /dev/null
-+++ linux-5.4.124/drivers/net/dsa/mt7531_phy.h
++++ b/drivers/net/dsa/mt7531_phy.h
@@ -0,0 +1,262 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
@@ -1671,17 +1703,6 @@
+ DSP_MAX = 0x3e,
+};
+#endif /* _MT753X_REGS_H_ */
-Index: linux-5.4.124/drivers/net/dsa/Makefile
-===================================================================
---- linux-5.4.124.orig/drivers/net/dsa/Makefile
-+++ linux-5.4.124/drivers/net/dsa/Makefile
-@@ -6,7 +6,8 @@ ifdef CONFIG_NET_DSA_LOOP
- obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
- endif
- obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
--obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
-+obj-$(CONFIG_NET_DSA_MT7530) += mt7530-dsa.o
-+mt7530-dsa-objs := mt7530.o mt7531_phy.o
- obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
- obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
- obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/746-mxl-gpy-phy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1703-mxl-gpy-phy-support.patch
similarity index 96%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/746-mxl-gpy-phy-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1703-mxl-gpy-phy-support.patch
index 5ff2798..056622a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/746-mxl-gpy-phy-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1703-mxl-gpy-phy-support.patch
@@ -1,3 +1,17 @@
+From 4dad0228a64a810460928cd55c4dee0dd35708a0 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:32 +0800
+Subject: [PATCH] [networking][999-1703-mxl-gpy-phy-support.patch]
+
+---
+ drivers/net/phy/Kconfig | 6 +
+ drivers/net/phy/Makefile | 1 +
+ drivers/net/phy/mxl-gpy.c | 738 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 745 insertions(+)
+ create mode 100644 drivers/net/phy/mxl-gpy.c
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 45aaf7203..c0e09c99d 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -516,6 +516,12 @@ config MARVELL_10G_PHY
@@ -13,9 +27,11 @@
config MESON_GXL_PHY
tristate "Amlogic Meson GXL Internal PHY"
depends on ARCH_MESON || COMPILE_TEST
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index 998de790e..8b57d6105 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
-@@ -95,6 +95,7 @@ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c
+@@ -96,6 +96,7 @@ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_LXT_PHY) += lxt.o
obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o
@@ -23,6 +39,9 @@
obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
obj-$(CONFIG_MEDIATEK_2P5GE_PHY)+= mediatek-2p5ge.o
+diff --git a/drivers/net/phy/mxl-gpy.c b/drivers/net/phy/mxl-gpy.c
+new file mode 100644
+index 000000000..730427832
--- /dev/null
+++ b/drivers/net/phy/mxl-gpy.c
@@ -0,0 +1,738 @@
@@ -764,3 +783,6 @@
+MODULE_DESCRIPTION("Maxlinear Ethernet GPY Driver");
+MODULE_AUTHOR("Xu Liang");
+MODULE_LICENSE("GPL");
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/747-net-phy-aquantia-add-AQR113C.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1704-net-phy-aquantia-add-AQR113C.patch
similarity index 76%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/747-net-phy-aquantia-add-AQR113C.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1704-net-phy-aquantia-add-AQR113C.patch
index d99d75f..46960d6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/747-net-phy-aquantia-add-AQR113C.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1704-net-phy-aquantia-add-AQR113C.patch
@@ -1,5 +1,15 @@
+From 23e3cea0589cd65b9c405f23720e4ba8b1264cb3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:00 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1704-net-phy-aquantia-add-AQR113C.patch]
+
+---
+ drivers/net/phy/aquantia_main.c | 45 +++++++++++++++------------------
+ 1 file changed, 21 insertions(+), 24 deletions(-)
+
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
-index 75d8351..ac8dd8e 100644
+index 75d8351ee..e7495c9a7 100644
--- a/drivers/net/phy/aquantia_main.c
+++ b/drivers/net/phy/aquantia_main.c
@@ -22,6 +22,7 @@
@@ -10,7 +20,7 @@
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3)
-@@ -268,17 +268,6 @@ static int aqr_read_status(struct phy_device *phydev)
+@@ -303,17 +304,6 @@ static int aqr_read_status(struct phy_device *phydev)
return genphy_c45_read_status(phydev);
}
@@ -28,7 +38,7 @@
static int aqr107_read_rate(struct phy_device *phydev)
{
int val;
-@@ -353,13 +342,7 @@ static int aqr107_read_status(struct phy_device *phydev)
+@@ -388,13 +378,7 @@ static int aqr107_read_status(struct phy_device *phydev)
break;
}
@@ -43,7 +53,7 @@
return aqr107_read_rate(phydev);
}
-@@ -500,9 +483,6 @@ static int aqr107_config_init(struct phy_device *phydev)
+@@ -516,9 +500,6 @@ static int aqr107_config_init(struct phy_device *phydev)
if (!ret)
aqr107_chip_info(phydev);
@@ -53,7 +63,7 @@
return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
}
-@@ -527,9 +507,6 @@ static int aqcs109_config_init(struct phy_device *phydev)
+@@ -543,9 +524,6 @@ static int aqcs109_config_init(struct phy_device *phydev)
if (ret)
return ret;
@@ -63,7 +73,7 @@
return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
}
-@@ -695,6 +696,24 @@ static struct phy_driver aqr_driver[] = {
+@@ -695,6 +673,24 @@ static struct phy_driver aqr_driver[] = {
.ack_interrupt = aqr_ack_interrupt,
.read_status = aqr_read_status,
},
@@ -88,7 +98,7 @@
};
module_phy_driver(aqr_driver);
-@@ -707,6 +726,7 @@ static struct mdio_device_id __maybe_unused aqr_tbl[] = {
+@@ -707,6 +703,7 @@ static struct mdio_device_id __maybe_unused aqr_tbl[] = {
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
@@ -96,3 +106,6 @@
{ }
};
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/748-add-netlink-support-for-dsa.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1705-add-netlink-support-for-dsa.patch
similarity index 84%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/748-add-netlink-support-for-dsa.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1705-add-netlink-support-for-dsa.patch
index 8853324..3f9adab 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/748-add-netlink-support-for-dsa.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1705-add-netlink-support-for-dsa.patch
@@ -1,8 +1,24 @@
-Index: linux-5.4.203/drivers/net/dsa/Makefile
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/Makefile
-+++ linux-5.4.203/drivers/net/dsa/Makefile
-@@ -7,7 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
+From 3e75ca66195dec023ca2e837ff748c317fd7ac26 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:00 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1705-add-netlink-support-for-dsa.patch]
+
+---
+ drivers/net/dsa/Makefile | 2 +-
+ drivers/net/dsa/mt7530.c | 24 ++-
+ drivers/net/dsa/mt7530.h | 8 +
+ drivers/net/dsa/mt7530_nl.c | 311 ++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/mt7530_nl.h | 49 ++++++
+ 5 files changed, 386 insertions(+), 8 deletions(-)
+ create mode 100644 drivers/net/dsa/mt7530_nl.c
+ create mode 100644 drivers/net/dsa/mt7530_nl.h
+
+diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
+index 0aa10bc3d..ef563c6c1 100644
+--- a/drivers/net/dsa/Makefile
++++ b/drivers/net/dsa/Makefile
+@@ -7,7 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
endif
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530-dsa.o
@@ -11,40 +27,40 @@
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
-Index: linux-5.4.203/drivers/net/dsa/mt7530.c
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/mt7530.c
-+++ linux-5.4.203/drivers/net/dsa/mt7530.c
+diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
+index e4c021eeb..63f8a632b 100644
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
@@ -21,6 +21,7 @@
#include <net/dsa.h>
-
+
#include "mt7530.h"
+#include "mt7530_nl.h"
-
+
/* String, offset, and register size in bytes if different from 4 bytes */
static const struct mt7530_mib_desc mt7530_mib[] = {
-@@ -222,7 +223,7 @@ mt7530_mii_read(struct mt7530_priv *priv
+@@ -222,7 +223,7 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
return (hi << 16) | (lo & 0xffff);
}
-
+
-static void
+void
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
struct mii_bus *bus = priv->bus;
-@@ -255,7 +256,7 @@ _mt7530_read(struct mt7530_dummy_poll *p
+@@ -255,7 +256,7 @@ _mt7530_read(struct mt7530_dummy_poll *p)
return val;
}
-
+
-static u32
+u32
mt7530_read(struct mt7530_priv *priv, u32 reg)
{
struct mt7530_dummy_poll p;
-@@ -614,7 +615,7 @@ static int mt7530_phy_write(struct dsa_s
+@@ -614,7 +615,7 @@ static int mt7530_phy_write(struct dsa_switch *ds, int port, int regnum,
return mdiobus_write_nested(priv->bus, port, regnum, val);
}
-
+
-static int
+int
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
@@ -53,7 +69,7 @@
@@ -663,7 +664,7 @@ out:
return ret;
}
-
+
-static int
+int
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
@@ -62,7 +78,7 @@
@@ -711,7 +712,7 @@ out:
return ret;
}
-
+
-static int
+int
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
@@ -71,24 +87,24 @@
@@ -749,7 +750,7 @@ out:
return ret;
}
-
+
-static int
+int
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
u16 data)
{
-@@ -2690,6 +2691,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -2691,6 +2692,7 @@ mt7530_probe(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv;
struct device_node *dn;
+ int ret;
-
+
dn = mdiodev->dev.of_node;
-
-@@ -2765,7 +2767,13 @@ mt7530_probe(struct mdio_device *mdiodev
+
+@@ -2766,7 +2768,13 @@ mt7530_probe(struct mdio_device *mdiodev)
mutex_init(&priv->reg_mutex);
dev_set_drvdata(&mdiodev->dev, priv);
-
+
- return dsa_register_switch(priv->ds);
+ ret = dsa_register_switch(priv->ds);
+ if (ret)
@@ -98,24 +114,24 @@
+
+ return 0;
}
-
+
static void
-@@ -2786,6 +2794,8 @@ mt7530_remove(struct mdio_device *mdiode
-
+@@ -2787,6 +2795,8 @@ mt7530_remove(struct mdio_device *mdiodev)
+
dsa_unregister_switch(priv->ds);
mutex_destroy(&priv->reg_mutex);
+
+ mt7530_nl_exit();
}
-
+
static struct mdio_driver mt7530_mdio_driver = {
-Index: linux-5.4.203/drivers/net/dsa/mt7530.h
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/mt7530.h
-+++ linux-5.4.203/drivers/net/dsa/mt7530.h
-@@ -783,4 +783,12 @@ static inline void INIT_MT7530_DUMMY_POL
+diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
+index 8f1e827ff..130d7e5ec 100644
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -783,4 +783,12 @@ static inline void INIT_MT7530_DUMMY_POLL(struct mt7530_dummy_poll *p,
}
-
+
int mt7531_phy_setup(struct dsa_switch *ds);
+u32 mt7530_read(struct mt7530_priv *priv, u32 reg);
+void mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val);
@@ -126,10 +142,11 @@
+
+
#endif /* __MT7530_H */
-Index: linux-5.4.203/drivers/net/dsa/mt7530_nl.c
-===================================================================
+diff --git a/drivers/net/dsa/mt7530_nl.c b/drivers/net/dsa/mt7530_nl.c
+new file mode 100644
+index 000000000..676adef70
--- /dev/null
-+++ linux-5.4.203/drivers/net/dsa/mt7530_nl.c
++++ b/drivers/net/dsa/mt7530_nl.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
@@ -442,10 +459,11 @@
+ sw_priv = NULL;
+ genl_unregister_family(&mt7530_nl_family);
+}
-Index: linux-5.4.203/drivers/net/dsa/mt7530_nl.h
-===================================================================
+diff --git a/drivers/net/dsa/mt7530_nl.h b/drivers/net/dsa/mt7530_nl.h
+new file mode 100644
+index 000000000..4619288c2
--- /dev/null
-+++ linux-5.4.203/drivers/net/dsa/mt7530_nl.h
++++ b/drivers/net/dsa/mt7530_nl.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
@@ -496,3 +514,6 @@
+#endif /* __KERNEL__ */
+
+#endif /* _MT7530_NL_H_ */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/749-net-dsa-support-mt7988.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1706-net-dsa-support-mt7988.patch
similarity index 83%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/749-net-dsa-support-mt7988.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1706-net-dsa-support-mt7988.patch
index 7c468d8..c53c205 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/749-net-dsa-support-mt7988.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1706-net-dsa-support-mt7988.patch
@@ -1,19 +1,30 @@
-Index: linux-5.4.203/drivers/net/dsa/mt7530.c
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/mt7530.c
-+++ linux-5.4.203/drivers/net/dsa/mt7530.c
+From 90508a46a0fd6416dcaad2c7f0ef25a5a421bf4f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:00 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1706-net-dsa-support-mt7988.patch]
+
+---
+ drivers/net/dsa/mt7530.c | 191 ++++++++++++++++++++++++++++++++-------
+ drivers/net/dsa/mt7530.h | 11 ++-
+ 2 files changed, 164 insertions(+), 38 deletions(-)
+
+diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
+index 63f8a632b..2cd5dae9c 100644
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
@@ -19,6 +19,7 @@
#include <linux/reset.h>
#include <linux/gpio/consumer.h>
#include <net/dsa.h>
+#include <linux/of_address.h>
-
+
#include "mt7530.h"
#include "mt7530_nl.h"
-@@ -170,28 +171,44 @@ core_clear(struct mt7530_priv *priv, u32
+@@ -170,28 +171,44 @@ core_clear(struct mt7530_priv *priv, u32 reg, u32 val)
core_rmw(priv, reg, val, 0);
}
-
+
+static void
+mtk_w32(struct mt7530_priv *priv, u32 val, unsigned reg)
+{
@@ -32,21 +43,12 @@
struct mii_bus *bus = priv->bus;
u16 page, r, lo, hi;
- int ret;
--
++ int ret = 0;
+
- page = (reg >> 6) & 0x3ff;
- r = (reg >> 2) & 0xf;
- lo = val & 0xffff;
- hi = val >> 16;
--
-- /* MT7530 uses 31 as the pseudo port */
-- ret = bus->write(bus, 0x1f, 0x1f, page);
-- if (ret < 0)
-- goto err;
-+ int ret = 0;
-
-- ret = bus->write(bus, 0x1f, r, lo);
-- if (ret < 0)
-- goto err;
+ if (priv->direct_access){
+ mtk_w32(priv, val, reg);
+ } else {
@@ -54,26 +56,33 @@
+ r = (reg >> 2) & 0xf;
+ lo = val & 0xffff;
+ hi = val >> 16;
-+
+
+- /* MT7530 uses 31 as the pseudo port */
+- ret = bus->write(bus, 0x1f, 0x1f, page);
+- if (ret < 0)
+- goto err;
+ /* MT7530 uses 31 as the pseudo port */
+ ret = bus->write(bus, 0x1f, 0x1f, page);
+ if (ret < 0)
+ goto err;
-+
+
+- ret = bus->write(bus, 0x1f, r, lo);
+- if (ret < 0)
+- goto err;
+ ret = bus->write(bus, 0x1f, r, lo);
+ if (ret < 0)
+ goto err;
-
+
- ret = bus->write(bus, 0x1f, 0x10, hi);
+ ret = bus->write(bus, 0x1f, 0x10, hi);
+ }
err:
if (ret < 0)
dev_err(&bus->dev,
-@@ -206,21 +223,25 @@ mt7530_mii_read(struct mt7530_priv *priv
+@@ -206,21 +223,25 @@ mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
u16 page, r, lo, hi;
int ret;
-
+
- page = (reg >> 6) & 0x3ff;
- r = (reg >> 2) & 0xf;
+ if (priv->direct_access){
@@ -81,7 +90,7 @@
+ } else {
+ page = (reg >> 6) & 0x3ff;
+ r = (reg >> 2) & 0xf;
-
+
- /* MT7530 uses 31 as the pseudo port */
- ret = bus->write(bus, 0x1f, 0x1f, page);
- if (ret < 0) {
@@ -96,19 +105,19 @@
+ "failed to read mt7530 register\n");
+ return ret;
+ }
-
+
- lo = bus->read(bus, 0x1f, r);
- hi = bus->read(bus, 0x1f, 0x10);
+ lo = bus->read(bus, 0x1f, r);
+ hi = bus->read(bus, 0x1f, 0x10);
-
+
- return (hi << 16) | (lo & 0xffff);
+ return (hi << 16) | (lo & 0xffff);
+ }
}
-
+
void
-@@ -1906,9 +1927,9 @@ mt7531_phy_supported(struct dsa_switch *
+@@ -1907,9 +1928,9 @@ mt7531_phy_supported(struct dsa_switch *ds, int port,
if (mt7531_is_rgmii_port(priv, port))
return phy_interface_mode_is_rgmii(state->interface);
fallthrough;
@@ -121,7 +130,7 @@
goto unsupported;
break;
default:
-@@ -2017,6 +2038,13 @@ static void mt7531_sgmii_validate(struct
+@@ -2018,6 +2039,13 @@ static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
phylink_set(supported, 1000baseX_Full);
phylink_set(supported, 2500baseX_Full);
phylink_set(supported, 2500baseT_Full);
@@ -134,8 +143,8 @@
+ phylink_set(supported, 10000baseER_Full);
}
}
-
-@@ -2165,6 +2193,8 @@ mt7531_mac_config(struct dsa_switch *ds,
+
+@@ -2166,6 +2194,8 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
case PHY_INTERFACE_MODE_NA:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
@@ -143,8 +152,8 @@
+ case PHY_INTERFACE_MODE_10GKR:
if (phylink_autoneg_inband(mode))
return -EINVAL;
-
-@@ -2302,8 +2332,8 @@ static void mt753x_phylink_mac_link_up(s
+
+@@ -2303,8 +2333,8 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
/* MT753x MAC works in 1G full duplex mode for all up-clocked
* variants.
*/
@@ -155,10 +164,10 @@
speed = SPEED_1000;
duplex = DUPLEX_FULL;
}
-@@ -2402,8 +2432,8 @@ mt753x_phylink_validate(struct dsa_switc
-
+@@ -2403,8 +2433,8 @@ mt753x_phylink_validate(struct dsa_switch *ds, int port,
+
phylink_set_port_modes(mask);
-
+
- if (state->interface != PHY_INTERFACE_MODE_TRGMII ||
- !phy_interface_mode_is_8023z(state->interface)) {
+ if (state->interface != PHY_INTERFACE_MODE_TRGMII || state->interface != PHY_INTERFACE_MODE_USXGMII ||
@@ -166,10 +175,10 @@
phylink_set(mask, 10baseT_Half);
phylink_set(mask, 10baseT_Full);
phylink_set(mask, 100baseT_Half);
-@@ -2607,6 +2637,66 @@ mt753x_phy_write(struct dsa_switch *ds,
+@@ -2608,6 +2638,66 @@ mt753x_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
return priv->info->phy_write(ds, port, regnum, val);
}
-
+
+static int
+mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
+{
@@ -233,7 +242,7 @@
static const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
-@@ -2676,12 +2766,28 @@ static const struct mt753x_info mt753x_t
+@@ -2677,12 +2767,28 @@ static const struct mt753x_info mt753x_table[] = {
.mac_pcs_an_restart = mt7531_sgmii_restart_an,
.mac_pcs_link_up = mt7531_sgmii_link_up_force,
},
@@ -253,7 +262,7 @@
+ },
+
};
-
+
static const struct of_device_id mt7530_of_match[] = {
{ .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
{ .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
@@ -262,18 +271,18 @@
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, mt7530_of_match);
-@@ -2691,6 +2797,7 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -2692,6 +2798,7 @@ mt7530_probe(struct mdio_device *mdiodev)
{
struct mt7530_priv *priv;
struct device_node *dn;
+ struct device_node *switch_node = NULL;
int ret;
-
+
dn = mdiodev->dev.of_node;
-@@ -2760,6 +2867,16 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -2761,6 +2868,16 @@ mt7530_probe(struct mdio_device *mdiodev)
}
}
-
+
+ switch_node = of_find_node_by_name(NULL, "switch0");
+ if(switch_node) {
+ priv->base = of_iomap(switch_node, 0);
@@ -287,48 +296,47 @@
priv->bus = mdiodev->bus;
priv->dev = &mdiodev->dev;
priv->ds->priv = priv;
-@@ -2768,9 +2885,12 @@ mt7530_probe(struct mdio_device *mdiodev
+@@ -2769,9 +2886,12 @@ mt7530_probe(struct mdio_device *mdiodev)
dev_set_drvdata(&mdiodev->dev, priv);
-
+
ret = dsa_register_switch(priv->ds);
- if (ret)
- return ret;
--
+ if (ret) {
+ if(priv->base)
+ iounmap(priv->base);
-+
+
+ return ret;
+ }
mt7530_nl_init(&priv);
-
+
return 0;
-@@ -2795,6 +2915,9 @@ mt7530_remove(struct mdio_device *mdiode
+@@ -2796,6 +2916,9 @@ mt7530_remove(struct mdio_device *mdiodev)
dsa_unregister_switch(priv->ds);
mutex_destroy(&priv->reg_mutex);
-
+
+ if(priv->base)
+ iounmap(priv->base);
+
mt7530_nl_exit();
}
-
-Index: linux-5.4.203/drivers/net/dsa/mt7530.h
-===================================================================
---- linux-5.4.203.orig/drivers/net/dsa/mt7530.h
-+++ linux-5.4.203/drivers/net/dsa/mt7530.h
+
+diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
+index 130d7e5ec..7b175c5f2 100644
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
@@ -16,6 +16,7 @@ enum mt753x_id {
ID_MT7530 = 0,
ID_MT7621 = 1,
ID_MT7531 = 2,
+ ID_MT7988 = 3,
};
-
+
#define NUM_TRGMII_CTRL 5
@@ -51,11 +52,11 @@ enum mt753x_id {
#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
-
+
-#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_CFC : MT7530_MFC)
@@ -338,7 +346,7 @@
-#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
MT7531_MIRROR_MASK : MIRROR_MASK)
-
+
/* Registers for BPDU and PAE frame control*/
@@ -261,7 +262,7 @@ enum mt7530_vlan_port_attr {
MT7531_FORCE_DPX | \
@@ -358,3 +366,6 @@
const struct mt753x_info *info;
unsigned int id;
bool mcm;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-gphy-calibration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1707-add-mdio-bus-for-gphy-calibration.patch
old mode 100755
new mode 100644
similarity index 82%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-gphy-calibration.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1707-add-mdio-bus-for-gphy-calibration.patch
index e3efa34..cfa2a0c
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/750-add-mdio-bus-for-gphy-calibration.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1707-add-mdio-bus-for-gphy-calibration.patch
@@ -1,11 +1,21 @@
-Index: linux-5.4.215/drivers/net/dsa/mt7530.c
-===================================================================
---- linux-5.4.215.orig/drivers/net/dsa/mt7530.c
-+++ linux-5.4.215/drivers/net/dsa/mt7530.c
-@@ -847,6 +847,117 @@ mt7531_ind_phy_write(struct dsa_switch *
+From c816d165754d8fd002478cce6eb774b9390c795f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:01 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1707-add-mdio-bus-for-gphy-calibration.patch]
+
+---
+ drivers/net/dsa/mt7530.c | 115 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 115 insertions(+)
+
+diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
+index 2cd5dae9c..290a2e77a 100644
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -847,6 +847,117 @@ mt7531_ind_phy_write(struct dsa_switch *ds, int port, int regnum,
return ret;
}
-
+
+static int mt753x_mdio_read(struct mii_bus *bus, int addr, int regnum)
+{
+ struct mt7530_priv *priv = bus->priv;
@@ -120,14 +130,17 @@
static void
mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,
uint8_t *data)
-@@ -2694,6 +2805,10 @@ mt7988_setup(struct dsa_switch *ds)
+@@ -2695,6 +2806,10 @@ mt7988_setup(struct dsa_switch *ds)
if (ret < 0)
return ret;
-
+
+ ret = mt753x_setup_mdio(ds);
+ if (ret < 0)
+ dev_err(priv->dev, "mt753x_setup_mdio failed\n");
+
return 0;
}
+
+--
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/754-net-phy-add-5GBASER.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1708-net-phy-add-5GBASER.patch
similarity index 72%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/754-net-phy-add-5GBASER.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1708-net-phy-add-5GBASER.patch
index 8165303..b112bdb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/754-net-phy-add-5GBASER.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1708-net-phy-add-5GBASER.patch
@@ -1,16 +1,29 @@
+From 4df7f1c284d2c63bc78c2a517e510a8d250dd4c4 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:01 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1708-net-phy-add-5GBASER.patch]
+
+---
+ drivers/net/phy/marvell10g.c | 4 ++++
+ drivers/net/phy/phylink.c | 4 ++++
+ drivers/net/phy/sfp-bus.c | 3 +++
+ include/linux/phy.h | 3 +++
+ 4 files changed, 14 insertions(+)
+
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
-index daed73a..7d080d5 100644
+index 512f27b0b..1e4631761 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
-@@ -516,6 +516,7 @@ static void mv3310_update_interface(struct phy_device *phydev)
-
+@@ -386,6 +386,7 @@ static void mv3310_update_interface(struct phy_device *phydev)
+ {
if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
+ phydev->interface == PHY_INTERFACE_MODE_5GBASER ||
phydev->interface == PHY_INTERFACE_MODE_10GKR) && phydev->link) {
/* The PHY automatically switches its serdes interface (and
* active PHYXS instance) between Cisco SGMII, 10GBase-KR and
-@@ -527,6 +528,9 @@ static void mv3310_update_interface(struct phy_device *phydev)
+@@ -397,6 +398,9 @@ static void mv3310_update_interface(struct phy_device *phydev)
case SPEED_10000:
phydev->interface = PHY_INTERFACE_MODE_10GKR;
break;
@@ -21,7 +34,7 @@
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
break;
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
-index b3f25a9..6a38a1c 100644
+index b3f25a939..f360d9225 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -299,6 +299,10 @@ static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
@@ -36,10 +49,10 @@
phylink_set(pl->supported, 10baseT_Half);
phylink_set(pl->supported, 10baseT_Full);
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
-index 0d5ac2a..a702c9b 100644
+index 42f0441f2..a2f451c31 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
-@@ -302,6 +302,9 @@ phy_interface_t sfp_select_interface(struct sfp_bus *bus,
+@@ -389,6 +389,9 @@ phy_interface_t sfp_select_interface(struct sfp_bus *bus,
phylink_test(link_modes, 10000baseT_Full))
return PHY_INTERFACE_MODE_10GKR;
@@ -50,10 +63,10 @@
return PHY_INTERFACE_MODE_2500BASEX;
diff --git a/include/linux/phy.h b/include/linux/phy.h
-index 34bdd16..77fad08 100644
+index 19444cd96..a1070d60e 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
-@@ -98,6 +98,7 @@ typedef enum {
+@@ -97,6 +97,7 @@ typedef enum {
PHY_INTERFACE_MODE_TRGMII,
PHY_INTERFACE_MODE_1000BASEX,
PHY_INTERFACE_MODE_2500BASEX,
@@ -61,7 +74,7 @@
PHY_INTERFACE_MODE_RXAUI,
PHY_INTERFACE_MODE_XAUI,
/* 10GBASE-KR, XFI, SFI - single lane 10G Serdes */
-@@ -172,6 +173,8 @@ static inline const char *phy_modes(phy_interface_t interface)
+@@ -171,6 +172,8 @@ static inline const char *phy_modes(phy_interface_t interface)
return "1000base-x";
case PHY_INTERFACE_MODE_2500BASEX:
return "2500base-x";
@@ -70,3 +83,6 @@
case PHY_INTERFACE_MODE_RXAUI:
return "rxaui";
case PHY_INTERFACE_MODE_XAUI:
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-net-phy-sfp-add-rollball-support.patch
similarity index 83%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-net-phy-sfp-add-rollball-support.patch
index 5a6e865..bac49cf 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/755-net-phy-sfp-add-rollball-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1709-net-phy-sfp-add-rollball-support.patch
@@ -1,270 +1,575 @@
---- a/drivers/net/phy/mdio-i2c.c
-+++ b/drivers/net/phy/mdio-i2c.c
-@@ -12,6 +12,7 @@
- #include <linux/i2c.h>
- #include <linux/mdio/mdio-i2c.h>
- #include <linux/phy.h>
-+#include <linux/sfp.h>
+From 1631a36b9ac022ce6ffb58b039a7e85ad3414ed5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:01 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1709-net-phy-sfp-add-rollball-support.patch]
+
+---
+ drivers/net/phy/marvell.c | 2 +-
+ drivers/net/phy/marvell10g.c | 168 +++++++++++++--
+ drivers/net/phy/mdio-i2c.c | 309 +++++++++++++++++++++++++++-
+ drivers/net/phy/phylink.c | 74 +++++--
+ drivers/net/phy/sfp-bus.c | 102 +---------
+ drivers/net/phy/sfp.c | 373 +++++++++++++++++++++++++++++-----
+ drivers/net/phy/sfp.h | 11 +-
+ include/linux/mdio/mdio-i2c.h | 10 +-
+ 8 files changed, 874 insertions(+), 175 deletions(-)
+
+diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
+index 49801c2eb..f25881745 100644
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -2175,7 +2175,7 @@ static struct phy_driver marvell_drivers[] = {
+ .phy_id = MARVELL_PHY_ID_88E1111,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E1111",
+- /* PHY_GBIT_FEATURES */
++ .features = PHY_GBIT_FEATURES,
+ .probe = marvell_probe,
+ .config_init = &m88e1111_config_init,
+ .config_aneg = &marvell_config_aneg,
+diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
+index 1e4631761..7d080d52e 100644
+--- a/drivers/net/phy/marvell10g.c
++++ b/drivers/net/phy/marvell10g.c
+@@ -32,6 +32,15 @@
+ #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
- /*
- * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
-@@ -28,7 +29,7 @@ static unsigned int i2c_mii_phy_addr(int
- return phy_id + 0x40;
- }
+ enum {
++ MV_PMA_21X0_PORT_CTRL = 0xc04a,
++ MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15),
++ MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7,
++ MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0,
++ MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1,
++ MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2,
++ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4,
++ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5,
++ MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
+ MV_PMA_BOOT = 0xc050,
+ MV_PMA_BOOT_FATAL = BIT(0),
--static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
-+static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
- {
- struct i2c_adapter *i2c = bus->priv;
- struct i2c_msg msgs[2];
-@@ -62,7 +63,8 @@ static int i2c_mii_read(struct mii_bus *
- return data[0] << 8 | data[1];
- }
+@@ -53,7 +62,18 @@ enum {
--static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
-+static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
-+ u16 val)
- {
- struct i2c_adapter *i2c = bus->priv;
- struct i2c_msg msg;
-@@ -91,9 +93,288 @@ static int i2c_mii_write(struct mii_bus
- return ret < 0 ? ret : 0;
- }
+ /* Vendor2 MMD registers */
+ MV_V2_PORT_CTRL = 0xf001,
+- MV_V2_PORT_CTRL_PWRDOWN = 0x0800,
++ MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
++ MV_V2_33X0_PORT_CTRL_SWRST = BIT(15),
++ MV_V2_33X0_PORT_CTRL_MACTYPE_MASK = 0x7,
++ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI = 0x0,
++ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH = 0x1,
++ MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN = 0x1,
++ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH = 0x2,
++ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI = 0x3,
++ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER = 0x4,
++ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
++ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
++ MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
+ MV_V2_TEMP_CTRL = 0xf08a,
+ MV_V2_TEMP_CTRL_MASK = 0xc000,
+ MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
+@@ -62,11 +82,24 @@ enum {
+ MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */
+ };
--struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
-+/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
-+ * instead via address 0x51, when SFP page is set to 0x03 and password to
-+ * 0xffffffff.
-+ *
-+ * address size contents description
-+ * ------- ---- -------- -----------
-+ * 0x80 1 CMD 0x01/0x02/0x04 for write/read/done
-+ * 0x81 1 DEV Clause 45 device
-+ * 0x82 2 REG Clause 45 register
-+ * 0x84 2 VAL Register value
-+ */
-+#define ROLLBALL_PHY_I2C_ADDR 0x51
-+
-+#define ROLLBALL_PASSWORD (SFP_VSL + 3)
-+
-+#define ROLLBALL_CMD_ADDR 0x80
-+#define ROLLBALL_DATA_ADDR 0x81
-+
-+#define ROLLBALL_CMD_WRITE 0x01
-+#define ROLLBALL_CMD_READ 0x02
-+#define ROLLBALL_CMD_DONE 0x04
++struct mv3310_chip {
++ int (*get_mactype)(struct phy_device *phydev);
++ int (*init_interface)(struct phy_device *phydev, int mactype);
++};
+
-+#define SFP_PAGE_ROLLBALL_MDIO 3
+ struct mv3310_priv {
++ bool rate_match;
++ phy_interface_t const_interface;
+
-+static int __i2c_transfer_err(struct i2c_adapter *i2c, struct i2c_msg *msgs,
-+ int num)
+ struct device *hwmon_dev;
+ char *hwmon_name;
+ };
+
++static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
+{
-+ int ret;
-+
-+ ret = __i2c_transfer(i2c, msgs, num);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret != num)
-+ return -EIO;
-+ else
-+ return 0;
++ return phydev->drv->driver_data;
+}
+
-+static int __i2c_rollball_get_page(struct i2c_adapter *i2c, int bus_addr,
-+ u8 *page)
+ #ifdef CONFIG_HWMON
+ static umode_t mv3310_hwmon_is_visible(const void *data,
+ enum hwmon_sensor_types type,
+@@ -155,13 +188,6 @@ static int mv3310_hwmon_config(struct phy_device *phydev, bool enable)
+ MV_V2_TEMP_CTRL_MASK, val);
+ }
+
+-static void mv3310_hwmon_disable(void *data)
+-{
+- struct phy_device *phydev = data;
+-
+- mv3310_hwmon_config(phydev, false);
+-}
+-
+ static int mv3310_hwmon_probe(struct phy_device *phydev)
+ {
+ struct device *dev = &phydev->mdio.dev;
+@@ -185,10 +211,6 @@ static int mv3310_hwmon_probe(struct phy_device *phydev)
+ if (ret)
+ return ret;
+
+- ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev);
+- if (ret)
+- return ret;
+-
+ priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
+ priv->hwmon_name, phydev,
+ &mv3310_hwmon_chip_info, NULL);
+@@ -262,6 +284,11 @@ static int mv3310_probe(struct phy_device *phydev)
+ return phy_sfp_probe(phydev, &mv3310_sfp_ops);
+ }
+
++static void mv3310_remove(struct phy_device *phydev)
+{
-+ struct i2c_msg msgs[2];
-+ u8 addr = SFP_PAGE;
-+
-+ msgs[0].addr = bus_addr;
-+ msgs[0].flags = 0;
-+ msgs[0].len = 1;
-+ msgs[0].buf = &addr;
-+
-+ msgs[1].addr = bus_addr;
-+ msgs[1].flags = I2C_M_RD;
-+ msgs[1].len = 1;
-+ msgs[1].buf = page;
-+
-+ return __i2c_transfer_err(i2c, msgs, 2);
++ mv3310_hwmon_config(phydev, false);
+}
+
-+static int __i2c_rollball_set_page(struct i2c_adapter *i2c, int bus_addr,
-+ u8 page)
+ static int mv3310_suspend(struct phy_device *phydev)
+ {
+ return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
+@@ -297,8 +324,84 @@ static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
+ MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
+ }
+
++static int mv2110_get_mactype(struct phy_device *phydev)
+{
-+ struct i2c_msg msg;
-+ u8 buf[2];
-+
-+ buf[0] = SFP_PAGE;
-+ buf[1] = page;
++ int mactype;
+
-+ msg.addr = bus_addr;
-+ msg.flags = 0;
-+ msg.len = 2;
-+ msg.buf = buf;
++ mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
++ if (mactype < 0)
++ return mactype;
+
-+ return __i2c_transfer_err(i2c, &msg, 1);
++ return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
+}
+
-+/* In order to not interfere with other SFP code (which possibly may manipulate
-+ * SFP_PAGE), for every transfer we do this:
-+ * 1. lock the bus
-+ * 2. save content of SFP_PAGE
-+ * 3. set SFP_PAGE to 3
-+ * 4. do the transfer
-+ * 5. restore original SFP_PAGE
-+ * 6. unlock the bus
-+ * Note that one might think that steps 2 to 5 could be theoretically done all
-+ * in one call to i2c_transfer (by constructing msgs array in such a way), but
-+ * unfortunately tests show that this does not work :-( Changed SFP_PAGE does
-+ * not take into account until i2c_transfer() is done.
-+ */
-+static int i2c_transfer_rollball(struct i2c_adapter *i2c,
-+ struct i2c_msg *msgs, int num)
++static int mv3310_get_mactype(struct phy_device *phydev)
+{
-+ int ret, main_err = 0;
-+ u8 saved_page;
++ int mactype;
+
-+ i2c_lock_bus(i2c, I2C_LOCK_SEGMENT);
++ mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
++ if (mactype < 0)
++ return mactype;
+
-+ /* save original page */
-+ ret = __i2c_rollball_get_page(i2c, msgs->addr, &saved_page);
-+ if (ret)
-+ goto unlock;
++ return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
++}
+
-+ /* change to RollBall MDIO page */
-+ ret = __i2c_rollball_set_page(i2c, msgs->addr, SFP_PAGE_ROLLBALL_MDIO);
-+ if (ret)
-+ goto unlock;
++static int mv2110_init_interface(struct phy_device *phydev, int mactype)
++{
++ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+
-+ /* do the transfer; we try to restore original page if this fails */
-+ ret = __i2c_transfer_err(i2c, msgs, num);
-+ if (ret)
-+ main_err = ret;
++ priv->rate_match = false;
+
-+ /* restore original page */
-+ ret = __i2c_rollball_set_page(i2c, msgs->addr, saved_page);
++ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
++ priv->rate_match = true;
+
-+unlock:
-+ i2c_unlock_bus(i2c, I2C_LOCK_SEGMENT);
++ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
++ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
++ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
++ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
++ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
++ mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
++ priv->const_interface = PHY_INTERFACE_MODE_NA;
++ else
++ return -EINVAL;
+
-+ return main_err ? : ret;
++ return 0;
+}
+
-+static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf,
-+ size_t len)
++static int mv3310_init_interface(struct phy_device *phydev, int mactype)
+{
-+ struct i2c_adapter *i2c = bus->priv;
-+ struct i2c_msg msgs[2];
-+ u8 cmd_addr, tmp, *res;
-+ int i, ret;
++ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+
-+ cmd_addr = ROLLBALL_CMD_ADDR;
++ priv->rate_match = false;
+
-+ res = buf ? buf : &tmp;
-+ len = buf ? len : 1;
++ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
++ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
++ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
++ priv->rate_match = true;
+
-+ msgs[0].addr = bus_addr;
-+ msgs[0].flags = 0;
-+ msgs[0].len = 1;
-+ msgs[0].buf = &cmd_addr;
++ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
++ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
++ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
++ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
++ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
++ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
++ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
++ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
++ priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
++ else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
++ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
++ priv->const_interface = PHY_INTERFACE_MODE_XAUI;
++ else
++ return -EINVAL;
+
-+ msgs[1].addr = bus_addr;
-+ msgs[1].flags = I2C_M_RD;
-+ msgs[1].len = len;
-+ msgs[1].buf = res;
++ return 0;
++}
+
-+ /* By experiment it takes up to 70 ms to access a register for these
-+ * SFPs. Sleep 20ms between iterations and try 10 times.
-+ */
-+ i = 10;
-+ do {
-+ msleep(20);
+ static int mv3310_config_init(struct phy_device *phydev)
+ {
++ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
++ int err, mactype;
+
-+ ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
-+ if (ret)
-+ return ret;
+ /* Check that the PHY interface type is compatible */
+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
+@@ -307,6 +410,16 @@ static int mv3310_config_init(struct phy_device *phydev)
+ phydev->interface != PHY_INTERFACE_MODE_10GKR)
+ return -ENODEV;
+
++ mactype = chip->get_mactype(phydev);
++ if (mactype < 0)
++ return mactype;
+
-+ if (*res == ROLLBALL_CMD_DONE)
-+ return 0;
-+ } while (i-- > 0);
++ err = chip->init_interface(phydev, mactype);
++ if (err) {
++ phydev_err(phydev, "MACTYPE configuration invalid\n");
++ return err;
++ }
+
-+ dev_info(&bus->dev, "poll timed out\n");
+ return 0;
+ }
+
+@@ -384,6 +497,23 @@ static int mv3310_aneg_done(struct phy_device *phydev)
+
+ static void mv3310_update_interface(struct phy_device *phydev)
+ {
++ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
+
-+ return -ETIMEDOUT;
-+}
++ if (!phydev->link)
++ return;
+
-+static int i2c_rollball_mii_cmd(struct mii_bus *bus, int bus_addr, u8 cmd,
-+ u8 *data, size_t len)
-+{
-+ struct i2c_adapter *i2c = bus->priv;
-+ struct i2c_msg msgs[2];
-+ u8 cmdbuf[2];
++ /* In all of the "* with Rate Matching" modes the PHY interface is fixed
++ * at 10Gb. The PHY adapts the rate to actual wire speed with help of
++ * internal 16KB buffer.
++ *
++ * In USXGMII mode the PHY interface mode is also fixed.
++ */
++ if (priv->rate_match ||
++ priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
++ phydev->interface = priv->const_interface;
++ return;
++ }
+
-+ cmdbuf[0] = ROLLBALL_CMD_ADDR;
-+ cmdbuf[1] = cmd;
+ if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
+ phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
+ phydev->interface == PHY_INTERFACE_MODE_5GBASER ||
+@@ -503,11 +633,22 @@ static int mv3310_read_status(struct phy_device *phydev)
+ return 0;
+ }
+
++static const struct mv3310_chip mv3310_type = {
++ .get_mactype = mv3310_get_mactype,
++ .init_interface = mv3310_init_interface,
++};
+
-+ msgs[0].addr = bus_addr;
-+ msgs[0].flags = 0;
-+ msgs[0].len = len;
-+ msgs[0].buf = data;
++static const struct mv3310_chip mv2111_type = {
++ .get_mactype = mv2110_get_mactype,
++ .init_interface = mv2110_init_interface,
++};
+
-+ msgs[1].addr = bus_addr;
-+ msgs[1].flags = 0;
-+ msgs[1].len = sizeof(cmdbuf);
-+ msgs[1].buf = cmdbuf;
+ static struct phy_driver mv3310_drivers[] = {
+ {
+ .phy_id = MARVELL_PHY_ID_88X3310,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "mv88x3310",
++ .driver_data = &mv3310_type,
+ .get_features = mv3310_get_features,
+ .soft_reset = genphy_no_soft_reset,
+ .config_init = mv3310_config_init,
+@@ -517,11 +658,13 @@ static struct phy_driver mv3310_drivers[] = {
+ .config_aneg = mv3310_config_aneg,
+ .aneg_done = mv3310_aneg_done,
+ .read_status = mv3310_read_status,
++ .remove = mv3310_remove,
+ },
+ {
+ .phy_id = MARVELL_PHY_ID_88E2110,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "mv88x2110",
++ .driver_data = &mv2111_type,
+ .probe = mv3310_probe,
+ .suspend = mv3310_suspend,
+ .resume = mv3310_resume,
+@@ -530,6 +673,7 @@ static struct phy_driver mv3310_drivers[] = {
+ .config_aneg = mv3310_config_aneg,
+ .aneg_done = mv3310_aneg_done,
+ .read_status = mv3310_read_status,
++ .remove = mv3310_remove,
+ },
+ };
+
+diff --git a/drivers/net/phy/mdio-i2c.c b/drivers/net/phy/mdio-i2c.c
+index 09200a70b..85db63c33 100644
+--- a/drivers/net/phy/mdio-i2c.c
++++ b/drivers/net/phy/mdio-i2c.c
+@@ -12,6 +12,7 @@
+ #include <linux/i2c.h>
+ #include <linux/mdio/mdio-i2c.h>
+ #include <linux/phy.h>
++#include <linux/sfp.h>
+
+ /*
+ * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
+@@ -28,7 +29,7 @@ static unsigned int i2c_mii_phy_addr(int phy_id)
+ return phy_id + 0x40;
+ }
+
+-static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
++static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
+ {
+ struct i2c_adapter *i2c = bus->priv;
+ struct i2c_msg msgs[2];
+@@ -62,7 +63,8 @@ static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
+ return data[0] << 8 | data[1];
+ }
+
+-static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
++static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
++ u16 val)
+ {
+ struct i2c_adapter *i2c = bus->priv;
+ struct i2c_msg msg;
+@@ -91,9 +93,288 @@ static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+ return ret < 0 ? ret : 0;
+ }
+
+-struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
++/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
++ * instead via address 0x51, when SFP page is set to 0x03 and password to
++ * 0xffffffff.
++ *
++ * address size contents description
++ * ------- ---- -------- -----------
++ * 0x80 1 CMD 0x01/0x02/0x04 for write/read/done
++ * 0x81 1 DEV Clause 45 device
++ * 0x82 2 REG Clause 45 register
++ * 0x84 2 VAL Register value
++ */
++#define ROLLBALL_PHY_I2C_ADDR 0x51
+
-+ return i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
-+}
++#define ROLLBALL_PASSWORD (SFP_VSL + 3)
+
-+static int i2c_mii_read_rollball(struct mii_bus *bus, int phy_id, int reg)
-+{
-+ u8 buf[4], res[6];
-+ int bus_addr, ret;
-+ u16 val;
++#define ROLLBALL_CMD_ADDR 0x80
++#define ROLLBALL_DATA_ADDR 0x81
+
-+ if (!(reg & MII_ADDR_C45))
-+ return -EOPNOTSUPP;
++#define ROLLBALL_CMD_WRITE 0x01
++#define ROLLBALL_CMD_READ 0x02
++#define ROLLBALL_CMD_DONE 0x04
+
-+ bus_addr = i2c_mii_phy_addr(phy_id);
-+ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
-+ return 0xffff;
++#define SFP_PAGE_ROLLBALL_MDIO 3
+
-+ buf[0] = ROLLBALL_DATA_ADDR;
-+ buf[1] = (reg >> 16) & 0x1f;
-+ buf[2] = (reg >> 8) & 0xff;
-+ buf[3] = reg & 0xff;
++static int __i2c_transfer_err(struct i2c_adapter *i2c, struct i2c_msg *msgs,
++ int num)
++{
++ int ret;
+
-+ ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_READ, buf,
-+ sizeof(buf));
++ ret = __i2c_transfer(i2c, msgs, num);
+ if (ret < 0)
+ return ret;
++ else if (ret != num)
++ return -EIO;
++ else
++ return 0;
++}
+
-+ ret = i2c_rollball_mii_poll(bus, bus_addr, res, sizeof(res));
-+ if (ret == -ETIMEDOUT)
-+ return 0xffff;
-+ else if (ret < 0)
-+ return ret;
++static int __i2c_rollball_get_page(struct i2c_adapter *i2c, int bus_addr,
++ u8 *page)
++{
++ struct i2c_msg msgs[2];
++ u8 addr = SFP_PAGE;
+
-+ val = res[4] << 8 | res[5];
++ msgs[0].addr = bus_addr;
++ msgs[0].flags = 0;
++ msgs[0].len = 1;
++ msgs[0].buf = &addr;
+
-+ return val;
++ msgs[1].addr = bus_addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = 1;
++ msgs[1].buf = page;
++
++ return __i2c_transfer_err(i2c, msgs, 2);
+}
+
-+static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int reg,
-+ u16 val)
++static int __i2c_rollball_set_page(struct i2c_adapter *i2c, int bus_addr,
++ u8 page)
+{
-+ int bus_addr, ret;
-+ u8 buf[6];
++ struct i2c_msg msg;
++ u8 buf[2];
+
-+ if (!(reg & MII_ADDR_C45))
-+ return -EOPNOTSUPP;
++ buf[0] = SFP_PAGE;
++ buf[1] = page;
+
-+ bus_addr = i2c_mii_phy_addr(phy_id);
-+ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
-+ return 0;
++ msg.addr = bus_addr;
++ msg.flags = 0;
++ msg.len = 2;
++ msg.buf = buf;
+
-+ buf[0] = ROLLBALL_DATA_ADDR;
++ return __i2c_transfer_err(i2c, &msg, 1);
++}
++
++/* In order to not interfere with other SFP code (which possibly may manipulate
++ * SFP_PAGE), for every transfer we do this:
++ * 1. lock the bus
++ * 2. save content of SFP_PAGE
++ * 3. set SFP_PAGE to 3
++ * 4. do the transfer
++ * 5. restore original SFP_PAGE
++ * 6. unlock the bus
++ * Note that one might think that steps 2 to 5 could be theoretically done all
++ * in one call to i2c_transfer (by constructing msgs array in such a way), but
++ * unfortunately tests show that this does not work :-( Changed SFP_PAGE does
++ * not take into account until i2c_transfer() is done.
++ */
++static int i2c_transfer_rollball(struct i2c_adapter *i2c,
++ struct i2c_msg *msgs, int num)
++{
++ int ret, main_err = 0;
++ u8 saved_page;
++
++ i2c_lock_bus(i2c, I2C_LOCK_SEGMENT);
++
++ /* save original page */
++ ret = __i2c_rollball_get_page(i2c, msgs->addr, &saved_page);
++ if (ret)
++ goto unlock;
++
++ /* change to RollBall MDIO page */
++ ret = __i2c_rollball_set_page(i2c, msgs->addr, SFP_PAGE_ROLLBALL_MDIO);
++ if (ret)
++ goto unlock;
++
++ /* do the transfer; we try to restore original page if this fails */
++ ret = __i2c_transfer_err(i2c, msgs, num);
++ if (ret)
++ main_err = ret;
++
++ /* restore original page */
++ ret = __i2c_rollball_set_page(i2c, msgs->addr, saved_page);
++
++unlock:
++ i2c_unlock_bus(i2c, I2C_LOCK_SEGMENT);
++
++ return main_err ? : ret;
++}
++
++static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf,
++ size_t len)
++{
++ struct i2c_adapter *i2c = bus->priv;
++ struct i2c_msg msgs[2];
++ u8 cmd_addr, tmp, *res;
++ int i, ret;
++
++ cmd_addr = ROLLBALL_CMD_ADDR;
++
++ res = buf ? buf : &tmp;
++ len = buf ? len : 1;
++
++ msgs[0].addr = bus_addr;
++ msgs[0].flags = 0;
++ msgs[0].len = 1;
++ msgs[0].buf = &cmd_addr;
++
++ msgs[1].addr = bus_addr;
++ msgs[1].flags = I2C_M_RD;
++ msgs[1].len = len;
++ msgs[1].buf = res;
++
++ /* By experiment it takes up to 70 ms to access a register for these
++ * SFPs. Sleep 20ms between iterations and try 10 times.
++ */
++ i = 10;
++ do {
++ msleep(20);
++
++ ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
++ if (ret)
++ return ret;
++
++ if (*res == ROLLBALL_CMD_DONE)
++ return 0;
++ } while (i-- > 0);
++
++ dev_info(&bus->dev, "poll timed out\n");
++
++ return -ETIMEDOUT;
++}
++
++static int i2c_rollball_mii_cmd(struct mii_bus *bus, int bus_addr, u8 cmd,
++ u8 *data, size_t len)
++{
++ struct i2c_adapter *i2c = bus->priv;
++ struct i2c_msg msgs[2];
++ u8 cmdbuf[2];
++
++ cmdbuf[0] = ROLLBALL_CMD_ADDR;
++ cmdbuf[1] = cmd;
++
++ msgs[0].addr = bus_addr;
++ msgs[0].flags = 0;
++ msgs[0].len = len;
++ msgs[0].buf = data;
++
++ msgs[1].addr = bus_addr;
++ msgs[1].flags = 0;
++ msgs[1].len = sizeof(cmdbuf);
++ msgs[1].buf = cmdbuf;
++
++ return i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
++}
++
++static int i2c_mii_read_rollball(struct mii_bus *bus, int phy_id, int reg)
++{
++ u8 buf[4], res[6];
++ int bus_addr, ret;
++ u16 val;
++
++ if (!(reg & MII_ADDR_C45))
++ return -EOPNOTSUPP;
++
++ bus_addr = i2c_mii_phy_addr(phy_id);
++ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
++ return 0xffff;
++
++ buf[0] = ROLLBALL_DATA_ADDR;
++ buf[1] = (reg >> 16) & 0x1f;
++ buf[2] = (reg >> 8) & 0xff;
++ buf[3] = reg & 0xff;
++
++ ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_READ, buf,
++ sizeof(buf));
++ if (ret < 0)
++ return ret;
++
++ ret = i2c_rollball_mii_poll(bus, bus_addr, res, sizeof(res));
++ if (ret == -ETIMEDOUT)
++ return 0xffff;
++ else if (ret < 0)
++ return ret;
++
++ val = res[4] << 8 | res[5];
++
++ return val;
++}
++
++static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int reg,
++ u16 val)
++{
++ int bus_addr, ret;
++ u8 buf[6];
++
++ if (!(reg & MII_ADDR_C45))
++ return -EOPNOTSUPP;
++
++ bus_addr = i2c_mii_phy_addr(phy_id);
++ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
++ return 0;
++
++ buf[0] = ROLLBALL_DATA_ADDR;
+ buf[1] = (reg >> 16) & 0x1f;
+ buf[2] = (reg >> 8) & 0xff;
+ buf[3] = reg & 0xff;
@@ -317,7 +622,7 @@
if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
return ERR_PTR(-EINVAL);
-@@ -104,10 +385,28 @@ struct mii_bus *mdio_i2c_alloc(struct de
+@@ -104,10 +385,28 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent));
mii->parent = parent;
@@ -348,27 +653,11 @@
return mii;
}
EXPORT_SYMBOL_GPL(mdio_i2c_alloc);
---- a/include/linux/mdio/mdio-i2c.h
-+++ b/include/linux/mdio/mdio-i2c.h
-@@ -11,6 +11,14 @@ struct device;
- struct i2c_adapter;
- struct mii_bus;
-
--struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
-+enum mdio_i2c_proto {
-+ MDIO_I2C_NONE,
-+ MDIO_I2C_MARVELL_C22,
-+ MDIO_I2C_C45,
-+ MDIO_I2C_ROLLBALL,
-+};
-+
-+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
-+ enum mdio_i2c_proto protocol);
-
- #endif
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
+index f360d9225..67f34ed4c 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
-@@ -483,62 +483,105 @@ static void phylink_resolve(struct work_
+@@ -483,62 +483,105 @@ static void phylink_resolve(struct work_struct *w)
struct phylink *pl = container_of(w, struct phylink, resolve);
struct phylink_link_state link_state;
struct net_device *ndev = pl->netdev;
@@ -498,6 +787,8 @@
mod_timer(&pl->link_poll, jiffies + HZ);
if (pl->phydev)
phy_start(pl->phydev);
+diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
+index a2f451c31..4be24406b 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -10,12 +10,6 @@
@@ -601,7 +892,18 @@
/**
* sfp_parse_port() - Parse the EEPROM base ID, setting the port type
* @bus: a pointer to the &struct sfp_bus structure for the sfp module
-@@ -359,7 +272,7 @@ void sfp_parse_support(struct sfp_bus *b
+@@ -236,6 +149,10 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
+ unsigned int br_min, br_nom, br_max;
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(modes) = { 0, };
+
++ phylink_set(modes, Autoneg);
++ phylink_set(modes, Pause);
++ phylink_set(modes, Asym_Pause);
++
+ /* Decode the bitrate information to MBd */
+ br_min = br_nom = br_max = 0;
+ if (id->base.br_nominal) {
+@@ -359,14 +276,10 @@ void sfp_parse_support(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
phylink_set(modes, 1000baseX_Full);
}
@@ -610,6 +912,13 @@
bus->sfp_quirk->modes(id, modes);
bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
+-
+- phylink_set(support, Autoneg);
+- phylink_set(support, Pause);
+- phylink_set(support, Asym_Pause);
+ }
+ EXPORT_SYMBOL_GPL(sfp_parse_support);
+
@@ -737,12 +650,13 @@ void sfp_link_down(struct sfp_bus *bus)
}
EXPORT_SYMBOL_GPL(sfp_link_down);
@@ -626,9 +935,11 @@
if (ops && ops->module_insert)
ret = ops->module_insert(bus->upstream, id);
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
+index f8d1742e0..0fdf5d6d4 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
-@@ -165,6 +165,7 @@ static const enum gpiod_flags gpio_flags
+@@ -165,6 +165,7 @@ static const enum gpiod_flags gpio_flags[] = {
* on board (for a copper SFP) time to initialise.
*/
#define T_WAIT msecs_to_jiffies(50)
@@ -636,7 +947,7 @@
#define T_START_UP msecs_to_jiffies(300)
#define T_START_UP_BAD_GPON msecs_to_jiffies(60000)
-@@ -204,8 +205,11 @@ static const enum gpiod_flags gpio_flags
+@@ -204,8 +205,11 @@ static const enum gpiod_flags gpio_flags[] = {
/* SFP modules appear to always have their PHY configured for bus address
* 0x56 (which with mdio-i2c, translates to a PHY address of 22).
@@ -676,7 +987,26 @@
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
-@@ -303,6 +313,156 @@ static const struct of_device_id sfp_of_
+@@ -287,6 +297,18 @@ static bool sfp_module_supported(const struct sfp_eeprom_id *id)
+ !memcmp(id->base.vendor_pn, "UF-INSTANT ", 16))
+ return true;
+
++ /* SFP GPON module SK-LiNK SFP-GE-LX20 SM1310 and SM1550 Instant
++ * has in its EEPROM stored phys id UNK instead of SFP. Therefore
++ * mark this module explicitly as supported based on vendor name
++ * and pn match.
++ */
++ if (id->base.phys_id == SFF8024_ID_UNK &&
++ id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP &&
++ !memcmp(id->base.vendor_name, "SK-LINK ", 16) &&
++ (!memcmp(id->base.vendor_pn, "SFP-GE-LX20-SM13", 16) ||
++ !memcmp(id->base.vendor_pn, "SFP-GE-LX-SM1550", 16)))
++ return true;
++
+ return false;
+ }
+
+@@ -303,6 +325,180 @@ static const struct of_device_id sfp_of_match[] = {
};
MODULE_DEVICE_TABLE(of, sfp_of_match);
@@ -732,6 +1062,21 @@
+ linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, modes);
+}
+
++static void sfp_quirk_disable_autoneg(const struct sfp_eeprom_id *id,
++ unsigned long *modes)
++{
++ linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, modes);
++}
++
++static void sfp_quirk_oem_2_5g(const struct sfp_eeprom_id *id,
++ unsigned long *modes)
++{
++ /* Copper 2.5G SFP */
++ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, modes);
++ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes);
++ sfp_quirk_disable_autoneg(id, modes);
++}
++
+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
+ unsigned long *modes)
+{
@@ -773,10 +1118,19 @@
+ // 2500MBd NRZ in their EEPROM
+ SFP_QUIRK_M("Lantech", "8330-262D-E", '\0', sfp_quirk_2500basex),
+
++ // CISCO PLRXPL-VC-S43-CG can operate at 10000baseSR, but not report
++ // in their EEPROM
+ SFP_QUIRK_M("CISCO-JDSU", "PLRXPL-VC-S43-CG", '\0', sfp_quirk_10000baseSR),
+
+ SFP_QUIRK_M("UBNT", "UF-INSTANT", '\0', sfp_quirk_ubnt_uf_instant),
+
++ // OEM SFP-2.5G-T can operate at 2500base-T, but not report
++ // in their EEPROM
++ SFP_QUIRK_M("OEM", "SFP-2.5G-T", '\0', sfp_quirk_oem_2_5g),
++ // TP-LINK TL-SM410U can operate at 2500base-T, but not report
++ // in their EEPROM
++ SFP_QUIRK_M("TP-LINK", "TL-SM410U", '\0', sfp_quirk_oem_2_5g),
++
+ SFP_QUIRK_F("ETU", "ESP-T5-R", '\0', sfp_fixup_rollball_cc),
+ SFP_QUIRK_F("OEM", "SFP-10G-T", '\0', sfp_fixup_rollball_cc),
+ SFP_QUIRK_F("OEM", "RTSFP-10", '\0', sfp_fixup_rollball_cc),
@@ -833,7 +1187,7 @@
static unsigned long poll_jiffies;
static unsigned int sfp_gpio_get_state(struct sfp *sfp)
-@@ -414,9 +554,6 @@ static int sfp_i2c_write(struct sfp *sfp
+@@ -414,9 +610,6 @@ static int sfp_i2c_write(struct sfp *sfp, bool a2, u8 dev_addr, void *buf,
static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
{
@@ -843,7 +1197,7 @@
if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
return -EINVAL;
-@@ -424,7 +561,15 @@ static int sfp_i2c_configure(struct sfp
+@@ -424,7 +617,15 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
sfp->read = sfp_i2c_read;
sfp->write = sfp_i2c_write;
@@ -860,7 +1214,7 @@
if (IS_ERR(i2c_mii))
return PTR_ERR(i2c_mii);
-@@ -442,6 +587,12 @@ static int sfp_i2c_configure(struct sfp
+@@ -442,6 +643,12 @@ static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
return 0;
}
@@ -873,7 +1227,7 @@
/* Interface */
static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
{
-@@ -487,17 +638,18 @@ static void sfp_soft_set_state(struct sf
+@@ -487,17 +694,18 @@ static void sfp_soft_set_state(struct sfp *sfp, unsigned int state)
static void sfp_soft_start_poll(struct sfp *sfp)
{
const struct sfp_eeprom_id *id = &sfp->id;
@@ -901,7 +1255,7 @@
if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
!sfp->need_poll)
-@@ -511,10 +663,11 @@ static void sfp_soft_stop_poll(struct sf
+@@ -511,10 +719,11 @@ static void sfp_soft_stop_poll(struct sfp *sfp)
static unsigned int sfp_get_state(struct sfp *sfp)
{
@@ -916,7 +1270,7 @@
state |= sfp_soft_get_state(sfp);
return state;
-@@ -1448,12 +1601,12 @@ static void sfp_sm_phy_detach(struct sfp
+@@ -1448,12 +1657,12 @@ static void sfp_sm_phy_detach(struct sfp *sfp)
sfp->mod_phy = NULL;
}
@@ -931,7 +1285,7 @@
if (phy == ERR_PTR(-ENODEV))
return PTR_ERR(phy);
if (IS_ERR(phy)) {
-@@ -1548,6 +1701,14 @@ static void sfp_sm_fault(struct sfp *sfp
+@@ -1548,6 +1757,14 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
}
}
@@ -946,7 +1300,7 @@
/* Probe a SFP for a PHY device if the module supports copper - the PHY
* normally sits at I2C bus address 0x56, and may either be a clause 22
* or clause 45 PHY.
-@@ -1563,19 +1724,23 @@ static int sfp_sm_probe_for_phy(struct s
+@@ -1563,36 +1780,52 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
{
int err = 0;
@@ -979,7 +1333,6 @@
return err;
}
-@@ -1755,17 +1783,29 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp)
static int sfp_module_parse_power(struct sfp *sfp)
{
u32 power_mW = 1000;
@@ -1014,7 +1367,7 @@
/* The module appears not to implement bus address
* 0xa2, so assume that the module powers up in the
* indicated mode.
-@@ -1782,13 +1822,21 @@ static int sfp_module_parse_power(struct sfp *sfp)
+@@ -1609,13 +1842,21 @@ static int sfp_module_parse_power(struct sfp *sfp)
}
}
@@ -1038,7 +1391,34 @@
power_mW / 1000, (power_mW / 100) % 10);
return 0;
}
-@@ -1819,11 +1984,33 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1692,7 +1933,7 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
+ {
+ /* SFP module inserted - read I2C data */
+ struct sfp_eeprom_id id;
+- bool cotsworks;
++ bool cotsworks, sklink;
+ u8 check;
+ int ret;
+
+@@ -1747,10 +1988,16 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
+ */
+ cotsworks = !memcmp(id.base.vendor_name, "COTSWORKS ", 16);
+
++ /* SK-LiNK do not seem to update the checksums when they
++ * do the final programming with the final module part number,
++ * serial number and date code.
++ */
++ sklink = !memcmp(id.base.vendor_name, "SK-LINK ", 16);
++
+ /* Validate the checksum over the base structure */
+ check = sfp_check(&id.base, sizeof(id.base) - 1);
+ if (check != id.base.cc_base) {
+- if (cotsworks) {
++ if (cotsworks || sklink) {
+ dev_warn(sfp->dev,
+ "EEPROM base structure checksum failure (0x%02x != 0x%02x)\n",
+ check, id.base.cc_base);
+@@ -1819,11 +2066,33 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
if (ret < 0)
return ret;
@@ -1076,7 +1456,7 @@
return 0;
}
-@@ -1936,7 +2123,8 @@ static void sfp_sm_module(struct sfp *sf
+@@ -1936,7 +2205,8 @@ static void sfp_sm_module(struct sfp *sfp, unsigned int event)
break;
/* Report the module insertion to the upstream device */
@@ -1086,7 +1466,7 @@
if (err < 0) {
sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
break;
-@@ -1995,6 +2183,8 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1995,6 +2265,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
sfp_module_stop(sfp->sfp_bus);
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);
@@ -1095,7 +1475,7 @@
sfp_module_tx_disable(sfp);
sfp_soft_stop_poll(sfp);
sfp_sm_next(sfp, SFP_S_DOWN, 0);
-@@ -2018,9 +2208,10 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2018,9 +2290,10 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
/* We need to check the TX_FAULT state, which is not defined
* while TX_DISABLE is asserted. The earliest we want to do
@@ -1108,7 +1488,7 @@
break;
case SFP_S_WAIT:
-@@ -2034,8 +2225,8 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2034,8 +2307,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
* deasserting.
*/
timeout = sfp->module_t_start_up;
@@ -1119,7 +1499,7 @@
else
timeout = 1;
-@@ -2057,6 +2248,12 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2057,6 +2330,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
sfp->sm_fault_retries == N_FAULT_INIT);
} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
init_done:
@@ -1132,7 +1512,7 @@
sfp->sm_phy_retries = R_PHY_RETRY;
goto phy_probe;
}
-@@ -2409,6 +2606,8 @@ static int sfp_probe(struct platform_dev
+@@ -2409,6 +2688,8 @@ static int sfp_probe(struct platform_device *pdev)
return PTR_ERR(sfp->gpio[i]);
}
@@ -1141,6 +1521,8 @@
sfp->get_state = sfp_gpio_get_state;
sfp->set_state = sfp_gpio_set_state;
+diff --git a/drivers/net/phy/sfp.h b/drivers/net/phy/sfp.h
+index b83f70526..f533e2dd6 100644
--- a/drivers/net/phy/sfp.h
+++ b/drivers/net/phy/sfp.h
@@ -6,6 +6,14 @@
@@ -1158,7 +1540,7 @@
struct sfp_socket_ops {
void (*attach)(struct sfp *sfp);
void (*detach)(struct sfp *sfp);
-@@ -20,7 +27,8 @@ int sfp_add_phy(struct sfp_bus *bus, str
+@@ -20,7 +28,8 @@ int sfp_add_phy(struct sfp_bus *bus, struct phy_device *phydev);
void sfp_remove_phy(struct sfp_bus *bus);
void sfp_link_up(struct sfp_bus *bus);
void sfp_link_down(struct sfp_bus *bus);
@@ -1168,274 +1550,26 @@
void sfp_module_remove(struct sfp_bus *bus);
int sfp_module_start(struct sfp_bus *bus);
void sfp_module_stop(struct sfp_bus *bus);
---- a/drivers/net/phy/marvell10g.c
-+++ b/drivers/net/phy/marvell10g.c
-@@ -32,6 +32,15 @@
- #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
-
- enum {
-+ MV_PMA_21X0_PORT_CTRL = 0xc04a,
-+ MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15),
-+ MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7,
-+ MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0,
-+ MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1,
-+ MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2,
-+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4,
-+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5,
-+ MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
- MV_PMA_BOOT = 0xc050,
- MV_PMA_BOOT_FATAL = BIT(0),
-
-@@ -53,7 +62,18 @@ enum {
-
- /* Vendor2 MMD registers */
- MV_V2_PORT_CTRL = 0xf001,
-- MV_V2_PORT_CTRL_PWRDOWN = 0x0800,
-+ MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
-+ MV_V2_33X0_PORT_CTRL_SWRST = BIT(15),
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_MASK = 0x7,
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI = 0x0,
-+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH = 0x1,
-+ MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN = 0x1,
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH = 0x2,
-+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI = 0x3,
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER = 0x4,
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
-+ MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
- MV_V2_TEMP_CTRL = 0xf08a,
- MV_V2_TEMP_CTRL_MASK = 0xc000,
- MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
-@@ -62,11 +82,24 @@ enum {
- MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */
- };
-
-+struct mv3310_chip {
-+ int (*get_mactype)(struct phy_device *phydev);
-+ int (*init_interface)(struct phy_device *phydev, int mactype);
-+};
-+
- struct mv3310_priv {
-+ bool rate_match;
-+ phy_interface_t const_interface;
-+
- struct device *hwmon_dev;
- char *hwmon_name;
- };
-
-+static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
-+{
-+ return phydev->drv->driver_data;
-+}
-+
- #ifdef CONFIG_HWMON
- static umode_t mv3310_hwmon_is_visible(const void *data,
- enum hwmon_sensor_types type,
-@@ -155,13 +188,6 @@ static int mv3310_hwmon_config(struct ph
- MV_V2_TEMP_CTRL_MASK, val);
- }
-
--static void mv3310_hwmon_disable(void *data)
--{
-- struct phy_device *phydev = data;
--
-- mv3310_hwmon_config(phydev, false);
--}
--
- static int mv3310_hwmon_probe(struct phy_device *phydev)
- {
- struct device *dev = &phydev->mdio.dev;
-@@ -185,10 +211,6 @@ static int mv3310_hwmon_probe(struct phy
- if (ret)
- return ret;
-
-- ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev);
-- if (ret)
-- return ret;
--
- priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
- priv->hwmon_name, phydev,
- &mv3310_hwmon_chip_info, NULL);
-@@ -262,6 +284,11 @@ static int mv3310_probe(struct phy_devic
- return phy_sfp_probe(phydev, &mv3310_sfp_ops);
- }
-
-+static void mv3310_remove(struct phy_device *phydev)
-+{
-+ mv3310_hwmon_config(phydev, false);
-+}
-+
- static int mv3310_suspend(struct phy_device *phydev)
- {
- return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
-@@ -297,8 +324,84 @@ static bool mv3310_has_pma_ngbaset_quirk
- MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
- }
-
-+static int mv2110_get_mactype(struct phy_device *phydev)
-+{
-+ int mactype;
-+
-+ mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
-+ if (mactype < 0)
-+ return mactype;
-+
-+ return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
-+}
-+
-+static int mv3310_get_mactype(struct phy_device *phydev)
-+{
-+ int mactype;
-+
-+ mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
-+ if (mactype < 0)
-+ return mactype;
-+
-+ return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
-+}
-+
-+static int mv2110_init_interface(struct phy_device *phydev, int mactype)
-+{
-+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
-+
-+ priv->rate_match = false;
-+
-+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
-+ priv->rate_match = true;
-+
-+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
-+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
-+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
-+ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
-+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
-+ mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
-+ priv->const_interface = PHY_INTERFACE_MODE_NA;
-+ else
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+static int mv3310_init_interface(struct phy_device *phydev, int mactype)
-+{
-+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
-+
-+ priv->rate_match = false;
-+
-+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
-+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
-+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
-+ priv->rate_match = true;
-+
-+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
-+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
-+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
-+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
-+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
-+ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
-+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
-+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
-+ priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
-+ else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
-+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
-+ priv->const_interface = PHY_INTERFACE_MODE_XAUI;
-+ else
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
- static int mv3310_config_init(struct phy_device *phydev)
- {
-+ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
-+ int err, mactype;
-+
- /* Check that the PHY interface type is compatible */
- if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
- phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
-@@ -307,6 +410,16 @@ static int mv3310_config_init(struct phy
- phydev->interface != PHY_INTERFACE_MODE_10GKR)
- return -ENODEV;
-
-+ mactype = chip->get_mactype(phydev);
-+ if (mactype < 0)
-+ return mactype;
-+
-+ err = chip->init_interface(phydev, mactype);
-+ if (err) {
-+ phydev_err(phydev, "MACTYPE configuration invalid\n");
-+ return err;
-+ }
-+
- return 0;
- }
-
-@@ -384,6 +497,23 @@ static int mv3310_aneg_done(struct phy_d
-
- static void mv3310_update_interface(struct phy_device *phydev)
- {
-+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
-+
-+ if (!phydev->link)
-+ return;
-+
-+ /* In all of the "* with Rate Matching" modes the PHY interface is fixed
-+ * at 10Gb. The PHY adapts the rate to actual wire speed with help of
-+ * internal 16KB buffer.
-+ *
-+ * In USXGMII mode the PHY interface mode is also fixed.
-+ */
-+ if (priv->rate_match ||
-+ priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
-+ phydev->interface = priv->const_interface;
-+ return;
-+ }
-+
- if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
- phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
- phydev->interface == PHY_INTERFACE_MODE_5GBASER ||
-@@ -503,11 +633,22 @@ static int mv3310_read_status(struct phy
- return 0;
- }
+diff --git a/include/linux/mdio/mdio-i2c.h b/include/linux/mdio/mdio-i2c.h
+index 751dab281..1c2114068 100644
+--- a/include/linux/mdio/mdio-i2c.h
++++ b/include/linux/mdio/mdio-i2c.h
+@@ -11,6 +11,14 @@ struct device;
+ struct i2c_adapter;
+ struct mii_bus;
-+static const struct mv3310_chip mv3310_type = {
-+ .get_mactype = mv3310_get_mactype,
-+ .init_interface = mv3310_init_interface,
-+};
-+
-+static const struct mv3310_chip mv2111_type = {
-+ .get_mactype = mv2110_get_mactype,
-+ .init_interface = mv2110_init_interface,
+-struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
++enum mdio_i2c_proto {
++ MDIO_I2C_NONE,
++ MDIO_I2C_MARVELL_C22,
++ MDIO_I2C_C45,
++ MDIO_I2C_ROLLBALL,
+};
+
- static struct phy_driver mv3310_drivers[] = {
- {
- .phy_id = MARVELL_PHY_ID_88X3310,
- .phy_id_mask = MARVELL_PHY_ID_MASK,
- .name = "mv88x3310",
-+ .driver_data = &mv3310_type,
- .get_features = mv3310_get_features,
- .soft_reset = genphy_no_soft_reset,
- .config_init = mv3310_config_init,
-@@ -517,11 +658,13 @@ static struct phy_driver mv3310_drivers[
- .config_aneg = mv3310_config_aneg,
- .aneg_done = mv3310_aneg_done,
- .read_status = mv3310_read_status,
-+ .remove = mv3310_remove,
- },
- {
- .phy_id = MARVELL_PHY_ID_88E2110,
- .phy_id_mask = MARVELL_PHY_ID_MASK,
- .name = "mv88x2110",
-+ .driver_data = &mv2111_type,
- .probe = mv3310_probe,
- .suspend = mv3310_suspend,
- .resume = mv3310_resume,
-@@ -530,6 +673,7 @@ static struct phy_driver mv3310_drivers[
- .config_aneg = mv3310_config_aneg,
- .aneg_done = mv3310_aneg_done,
- .read_status = mv3310_read_status,
-+ .remove = mv3310_remove,
- },
- };
++struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
++ enum mdio_i2c_proto protocol);
+ #endif
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1710-net-phy-add-phylink-pcs-support.patch
similarity index 96%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1710-net-phy-add-phylink-pcs-support.patch
index 99e4141..8f298c3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/757-net-phy-add-phylink-pcs-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1710-net-phy-add-phylink-pcs-support.patch
@@ -1,5 +1,16 @@
+From 45878f8001b0ad75c5497a999a43b5901c1e03a6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:01 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1710-net-phy-add-phylink-pcs-support.patch]
+
+---
+ drivers/net/phy/phylink.c | 306 ++++++++++++++++++++++++++++++--------
+ include/linux/phylink.h | 195 ++++++++++++++++++++++++
+ 2 files changed, 443 insertions(+), 58 deletions(-)
+
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
-index 67f34ed..ead9b37 100644
+index 67f34ed4c..9c76517ea 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -40,8 +40,9 @@ enum {
@@ -446,7 +457,7 @@
clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
phylink_run_resolve(pl);
-@@ -1055,10 +1238,19 @@ void phylink_start(struct phylink *pl)
+@@ -1055,10 +1239,19 @@ void phylink_start(struct phylink *pl)
irq = 0;
}
if (irq <= 0)
@@ -469,7 +480,7 @@
mod_timer(&pl->link_poll, jiffies + HZ);
if (pl->phydev)
phy_start(pl->phydev);
-@@ -1202,7 +1394,7 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
+@@ -1202,7 +1395,7 @@ int phylink_ethtool_ksettings_get(struct phylink *pl,
if (pl->phydev)
break;
@@ -478,7 +489,7 @@
/* The MAC is reporting the link results from its own PCS
* layer via in-band status. Report these as the current
-@@ -1314,7 +1506,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
+@@ -1314,7 +1507,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
if (pl->cur_link_an_mode == MLO_AN_INBAND &&
!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
phylink_mac_config(pl, &pl->link_config);
@@ -487,7 +498,7 @@
}
mutex_unlock(&pl->state_mutex);
-@@ -1341,7 +1533,7 @@ int phylink_ethtool_nway_reset(struct phylink *pl)
+@@ -1341,7 +1534,7 @@ int phylink_ethtool_nway_reset(struct phylink *pl)
if (pl->phydev)
ret = phy_restart_aneg(pl->phydev);
@@ -496,7 +507,7 @@
return ret;
}
-@@ -1410,7 +1602,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
+@@ -1410,7 +1603,7 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
case MLO_AN_INBAND:
phylink_mac_config(pl, config);
@@ -505,7 +516,7 @@
break;
}
}
-@@ -1621,10 +1813,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
+@@ -1621,10 +1814,7 @@ static int phylink_mii_read(struct phylink *pl, unsigned int phy_id,
case MLO_AN_INBAND:
if (phy_id == 0) {
@@ -517,7 +528,7 @@
val = phylink_mii_emul_read(reg, &state);
}
break;
-@@ -2010,7 +2010,7 @@ static int phylink_sfp_config(struct phylink *pl, u8 mode,
+@@ -1820,7 +2010,7 @@ static int phylink_sfp_config(struct phylink *pl, u8 mode,
if (changed && !test_bit(PHYLINK_DISABLE_STOPPED,
&pl->phylink_disable_state))
@@ -527,7 +538,7 @@
return ret;
}
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
-index 8229f56..ba0f09d 100644
+index 8229f56a1..ba0f09d02 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -63,17 +63,23 @@ enum phylink_op_type {
@@ -782,3 +793,6 @@
struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
phy_interface_t iface,
const struct phylink_mac_ops *ops);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/758-net-phy-add-phylink-pcs-decode-helper.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1711-net-phy-add-phylink-pcs-decode-helper.patch
similarity index 93%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/758-net-phy-add-phylink-pcs-decode-helper.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1711-net-phy-add-phylink-pcs-decode-helper.patch
index 164578a..1c7ff1c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/758-net-phy-add-phylink-pcs-decode-helper.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1711-net-phy-add-phylink-pcs-decode-helper.patch
@@ -1,5 +1,23 @@
+From 318f81610f630a026fd5ca0d4da7e34df25df663 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:02 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1711-net-phy-add-phylink-pcs-decode-helper.patch]
+
+---
+ drivers/net/phy/Makefile | 3 +-
+ drivers/net/phy/linkmode.c | 95 +++++++++++++++++++
+ drivers/net/phy/phylink.c | 188 +++++++++++++++++++++++++++++++++++++
+ include/linux/linkmode.h | 6 ++
+ include/linux/mii.h | 39 ++++++++
+ include/linux/phylink.h | 30 ++++++
+ include/uapi/linux/mdio.h | 26 +++++
+ include/uapi/linux/mii.h | 17 ++++
+ 8 files changed, 403 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/phy/linkmode.c
+
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
-index 799ff9c..54ad7e8 100644
+index 8ea612a85..437ff2a2c 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,7 +1,8 @@
@@ -14,7 +32,7 @@
ifdef CONFIG_MDIO_DEVICE
diff --git a/drivers/net/phy/linkmode.c b/drivers/net/phy/linkmode.c
new file mode 100644
-index 0000000..a5a347b
+index 000000000..a5a347bca
--- /dev/null
+++ b/drivers/net/phy/linkmode.c
@@ -0,0 +1,95 @@
@@ -114,10 +132,10 @@
+}
+EXPORT_SYMBOL_GPL(linkmode_set_pause);
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
-index ead9b37..fec6d0e 100644
+index 9c76517ea..6b63b9839 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
-@@ -2184,4 +2184,192 @@ void phylink_helper_basex_speed(struct phylink_link_state *state)
+@@ -2185,4 +2185,192 @@ void phylink_helper_basex_speed(struct phylink_link_state *state)
}
EXPORT_SYMBOL_GPL(phylink_helper_basex_speed);
@@ -311,7 +329,7 @@
+
MODULE_LICENSE("GPL v2");
diff --git a/include/linux/linkmode.h b/include/linux/linkmode.h
-index a99c588..d38da4e 100644
+index a99c58866..d38da4e89 100644
--- a/include/linux/linkmode.h
+++ b/include/linux/linkmode.h
@@ -82,4 +82,10 @@ static inline int linkmode_equal(const unsigned long *src1,
@@ -326,7 +344,7 @@
+
#endif /* __LINKMODE_H */
diff --git a/include/linux/mii.h b/include/linux/mii.h
-index 4ce8901..54b7f64 100644
+index 4ce8901a1..54b7f64b0 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -485,6 +485,45 @@ static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising)
@@ -376,7 +394,7 @@
* mii_advertise_flowctrl - get flow control advertisement flags
* @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
-index ba0f09d..48ff9fe 100644
+index ba0f09d02..48ff9fead 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -490,4 +490,34 @@ int phylink_mii_ioctl(struct phylink *, struct ifreq *, int);
@@ -415,7 +433,7 @@
+ uint16_t lpa);
#endif
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
-index 4bcb41c..3f302e2 100644
+index 4bcb41c71..3f302e252 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -324,4 +324,30 @@ static inline __u16 mdio_phy_id_c45(int prtad, int devad)
@@ -450,7 +468,7 @@
+
#endif /* _UAPI__LINUX_MDIO_H__ */
diff --git a/include/uapi/linux/mii.h b/include/uapi/linux/mii.h
-index 51b48e4..90f9b4e 100644
+index 51b48e4be..90f9b4e1b 100644
--- a/include/uapi/linux/mii.h
+++ b/include/uapi/linux/mii.h
@@ -131,6 +131,23 @@
@@ -477,3 +495,6 @@
/* 1000BASE-T Control register */
#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
#define ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1712-net-phy-add-phylink-rate-matching-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1712-net-phy-add-phylink-rate-matching-support.patch
new file mode 100644
index 0000000..3b9d2a6
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-1712-net-phy-add-phylink-rate-matching-support.patch
@@ -0,0 +1,413 @@
+diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
+index 8406412..96d9e1f 100644
+--- a/drivers/net/phy/phy-core.c
++++ b/drivers/net/phy/phy-core.c
+@@ -62,6 +62,27 @@ const char *phy_duplex_to_str(unsigned int duplex)
+ }
+ EXPORT_SYMBOL_GPL(phy_duplex_to_str);
+
++/**
++ * phy_rate_matching_to_str - Return a string describing the rate matching
++ *
++ * @rate_matching: Type of rate matching to describe
++ */
++const char *phy_rate_matching_to_str(int rate_matching)
++{
++ switch (rate_matching) {
++ case RATE_MATCH_NONE:
++ return "none";
++ case RATE_MATCH_PAUSE:
++ return "pause";
++ case RATE_MATCH_CRS:
++ return "crs";
++ case RATE_MATCH_OPEN_LOOP:
++ return "open-loop";
++ }
++ return "Unsupported (update phy-core.c)";
++}
++EXPORT_SYMBOL_GPL(phy_rate_matching_to_str);
++
+ /* A mapping of all SUPPORTED settings to speed/duplex. This table
+ * must be grouped by speed and sorted in descending match priority
+ * - iow, descending speed. */
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index e223f0d..6f2e4c7 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -106,6 +106,33 @@ void phy_print_status(struct phy_device *phydev)
+ }
+ EXPORT_SYMBOL(phy_print_status);
+
++/**
++ * phy_get_rate_matching - determine if rate matching is supported
++ * @phydev: The phy device to return rate matching for
++ * @iface: The interface mode to use
++ *
++ * This determines the type of rate matching (if any) that @phy supports
++ * using @iface. @iface may be %PHY_INTERFACE_MODE_NA to determine if any
++ * interface supports rate matching.
++ *
++ * Return: The type of rate matching @phy supports for @iface, or
++ * %RATE_MATCH_NONE.
++ */
++int phy_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface)
++{
++ int ret = RATE_MATCH_NONE;
++
++ if (phydev->drv->get_rate_matching) {
++ mutex_lock(&phydev->lock);
++ ret = phydev->drv->get_rate_matching(phydev, iface);
++ mutex_unlock(&phydev->lock);
++ }
++
++ return ret;
++}
++EXPORT_SYMBOL_GPL(phy_get_rate_matching);
++
+ /**
+ * phy_clear_interrupt - Ack the phy device's interrupt
+ * @phydev: the phy_device struct
+@@ -380,6 +407,7 @@ void phy_ethtool_ksettings_get(struct phy_device *phydev,
+
+ cmd->base.speed = phydev->speed;
+ cmd->base.duplex = phydev->duplex;
++ cmd->base.rate_matching = phydev->rate_matching;
+ if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
+ cmd->base.port = PORT_BNC;
+ else
+diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
+index 6b63b98..949e3b8 100644
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -155,6 +155,64 @@ static const char *phylink_an_mode_str(unsigned int mode)
+ return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
+ }
+
++/**
++ * phylink_interface_max_speed() - get the maximum speed of a phy interface
++ * @interface: phy interface mode defined by &typedef phy_interface_t
++ *
++ * Determine the maximum speed of a phy interface. This is intended to help
++ * determine the correct speed to pass to the MAC when the phy is performing
++ * rate matching.
++ *
++ * Return: The maximum speed of @interface
++ */
++static int phylink_interface_max_speed(phy_interface_t interface)
++{
++ switch (interface) {
++ case PHY_INTERFACE_MODE_RMII:
++ case PHY_INTERFACE_MODE_SMII:
++ case PHY_INTERFACE_MODE_REVMII:
++ case PHY_INTERFACE_MODE_MII:
++ return SPEED_100;
++
++ case PHY_INTERFACE_MODE_TBI:
++ case PHY_INTERFACE_MODE_MOCA:
++ case PHY_INTERFACE_MODE_RTBI:
++ case PHY_INTERFACE_MODE_1000BASEX:
++ case PHY_INTERFACE_MODE_TRGMII:
++ case PHY_INTERFACE_MODE_RGMII_TXID:
++ case PHY_INTERFACE_MODE_RGMII_RXID:
++ case PHY_INTERFACE_MODE_RGMII_ID:
++ case PHY_INTERFACE_MODE_RGMII:
++ case PHY_INTERFACE_MODE_QSGMII:
++ case PHY_INTERFACE_MODE_SGMII:
++ case PHY_INTERFACE_MODE_GMII:
++ return SPEED_1000;
++
++ case PHY_INTERFACE_MODE_2500BASEX:
++ return SPEED_2500;
++
++ case PHY_INTERFACE_MODE_5GBASER:
++ return SPEED_5000;
++
++ case PHY_INTERFACE_MODE_XGMII:
++ case PHY_INTERFACE_MODE_RXAUI:
++ case PHY_INTERFACE_MODE_XAUI:
++ case PHY_INTERFACE_MODE_10GKR:
++ case PHY_INTERFACE_MODE_USXGMII:
++ return SPEED_10000;
++
++ case PHY_INTERFACE_MODE_INTERNAL:
++ case PHY_INTERFACE_MODE_NA:
++ case PHY_INTERFACE_MODE_MAX:
++ /* No idea! Garbage in, unknown out */
++ return SPEED_UNKNOWN;
++ }
++
++ /* If we get here, someone forgot to add an interface mode above */
++ WARN_ON_ONCE(1);
++ return SPEED_UNKNOWN;
++}
++
+ static int phylink_validate_mac_and_pcs(struct phylink *pl,
+ unsigned long *supported,
+ struct phylink_link_state *state)
+@@ -402,11 +460,12 @@ static void phylink_mac_config(struct phylink *pl,
+ const struct phylink_link_state *state)
+ {
+ phylink_dbg(pl,
+- "%s: mode=%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
++ "%s: mode=%s/%s/%s/%s/%s adv=%*pb pause=%02x link=%u an=%u\n",
+ __func__, phylink_an_mode_str(pl->cur_link_an_mode),
+ phy_modes(state->interface),
+ phy_speed_to_str(state->speed),
+ phy_duplex_to_str(state->duplex),
++ phy_rate_matching_to_str(state->rate_matching),
+ __ETHTOOL_LINK_MODE_MASK_NBITS, state->advertising,
+ state->pause, state->link, state->an_enabled);
+
+@@ -499,6 +558,7 @@ static void phylink_mac_pcs_get_state(struct phylink *pl,
+ linkmode_zero(state->lp_advertising);
+ state->interface = pl->link_config.interface;
+ state->an_enabled = pl->link_config.an_enabled;
++ state->rate_matching = pl->link_config.rate_matching;
+ if (state->an_enabled) {
+ state->speed = SPEED_UNKNOWN;
+ state->duplex = DUPLEX_UNKNOWN;
+@@ -614,9 +674,32 @@ static void phylink_link_up(struct phylink *pl,
+ {
+ struct net_device *ndev = pl->netdev;
+ int speed, duplex;
++ bool rx_pause;
+
+ speed = link_state.speed;
+ duplex = link_state.duplex;
++ rx_pause = !!(link_state.pause & MLO_PAUSE_RX);
++
++ switch (link_state.rate_matching) {
++ case RATE_MATCH_PAUSE:
++ /* The PHY is doing rate matchion from the media rate (in
++ * the link_state) to the interface speed, and will send
++ * pause frames to the MAC to limit its transmission speed.
++ */
++ speed = phylink_interface_max_speed(link_state.interface);
++ duplex = DUPLEX_FULL;
++ rx_pause = true;
++ break;
++
++ case RATE_MATCH_CRS:
++ /* The PHY is doing rate matchion from the media rate (in
++ * the link_state) to the interface speed, and will cause
++ * collisions to the MAC to limit its transmission speed.
++ */
++ speed = phylink_interface_max_speed(link_state.interface);
++ duplex = DUPLEX_HALF;
++ break;
++ }
+
+ pl->cur_interface = link_state.interface;
+
+@@ -626,8 +709,7 @@ static void phylink_link_up(struct phylink *pl,
+
+ pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
+ pl->cur_interface, speed, duplex,
+- !!(link_state.pause & MLO_PAUSE_TX),
+- !!(link_state.pause & MLO_PAUSE_RX));
++ !!(link_state.pause & MLO_PAUSE_TX), rx_pause);
+
+ if (ndev)
+ netif_carrier_on(ndev);
+@@ -719,6 +801,17 @@ static void phylink_resolve(struct work_struct *w)
+ }
+ link_state.interface = pl->phy_state.interface;
+
++ /* If we are doing rate matching, then the
++ * link speed/duplex comes from the PHY
++ */
++ if (pl->phy_state.rate_matching) {
++ link_state.rate_matching =
++ pl->phy_state.rate_matching;
++ link_state.speed = pl->phy_state.speed;
++ link_state.duplex =
++ pl->phy_state.duplex;
++ }
++
+ /* If we have a PHY, we need to update with
+ * the PHY flow control bits.
+ */
+@@ -935,6 +1028,7 @@ static void phylink_phy_change(struct phy_device *phydev, bool up,
+ mutex_lock(&pl->state_mutex);
+ pl->phy_state.speed = phydev->speed;
+ pl->phy_state.duplex = phydev->duplex;
++ pl->phy_state.rate_matching = phydev->rate_matching;
+ pl->phy_state.pause = MLO_PAUSE_NONE;
+ if (phydev->pause)
+ pl->phy_state.pause |= MLO_PAUSE_SYM;
+@@ -946,10 +1040,11 @@ static void phylink_phy_change(struct phy_device *phydev, bool up,
+
+ phylink_run_resolve(pl);
+
+- phylink_dbg(pl, "phy link %s %s/%s/%s\n", up ? "up" : "down",
++ phylink_dbg(pl, "phy link %s %s/%s/%s/%s\n", up ? "up" : "down",
+ phy_modes(phydev->interface),
+ phy_speed_to_str(phydev->speed),
+- phy_duplex_to_str(phydev->duplex));
++ phy_duplex_to_str(phydev->duplex),
++ phy_rate_matching_to_str(phydev->rate_matching));
+ }
+
+ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
+@@ -971,6 +1066,12 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
+ memset(&config, 0, sizeof(config));
+ linkmode_copy(supported, phy->supported);
+ linkmode_copy(config.advertising, phy->advertising);
++
++ /* Check whether we would use rate matching for the proposed interface
++ * mode.
++ */
++ config.rate_matching = phy_get_rate_matching(phy, interface);
++
+ config.interface = interface;
+
+ ret = phylink_validate(pl, supported, &config);
+@@ -988,6 +1089,7 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
+ mutex_lock(&pl->state_mutex);
+ pl->phydev = phy;
+ pl->phy_state.interface = interface;
++ pl->phy_state.rate_matching = RATE_MATCH_NONE;
+ linkmode_copy(pl->supported, supported);
+ linkmode_copy(pl->link_config.advertising, config.advertising);
+
+@@ -1348,8 +1450,10 @@ static void phylink_get_ksettings(const struct phylink_link_state *state,
+ {
+ phylink_merge_link_mode(kset->link_modes.advertising, state->advertising);
+ linkmode_copy(kset->link_modes.lp_advertising, state->lp_advertising);
+- kset->base.speed = state->speed;
+- kset->base.duplex = state->duplex;
++ if (kset->base.rate_matching == RATE_MATCH_NONE) {
++ kset->base.speed = state->speed;
++ kset->base.duplex = state->duplex;
++ }
+ kset->base.autoneg = state->an_enabled ? AUTONEG_ENABLE :
+ AUTONEG_DISABLE;
+ }
+diff --git a/include/linux/phy.h b/include/linux/phy.h
+index 4f2c105..df9fb90 100644
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -423,6 +423,8 @@ struct phy_device {
+ /* Interrupts are enabled */
+ unsigned interrupts:1;
+
++ int rate_matching;
++
+ enum phy_state state;
+
+ u32 dev_flags;
+@@ -544,6 +546,18 @@ struct phy_driver {
+ */
+ int (*get_features)(struct phy_device *phydev);
+
++ /**
++ * @get_rate_matching: Get the supported type of rate matching for a
++ * particular phy interface. This is used by phy consumers to determine
++ * whether to advertise lower-speed modes for that interface. It is
++ * assumed that if a rate matching mode is supported on an interface,
++ * then that interface's rate can be adapted to all slower link speeds
++ * supported by the phy. If the interface is not supported, this should
++ * return %RATE_MATCH_NONE.
++ */
++ int (*get_rate_matching)(struct phy_device *phydev,
++ phy_interface_t iface);
++
+ /* PHY Power Management */
+ int (*suspend)(struct phy_device *phydev);
+ int (*resume)(struct phy_device *phydev);
+@@ -704,6 +718,7 @@ struct phy_fixup {
+
+ const char *phy_speed_to_str(int speed);
+ const char *phy_duplex_to_str(unsigned int duplex);
++const char *phy_rate_matching_to_str(int rate_matching);
+
+ /* A structure for mapping a particular speed and duplex
+ * combination to a particular SUPPORTED and ADVERTISED value
+@@ -1242,6 +1257,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
+ void phy_request_interrupt(struct phy_device *phydev);
+ void phy_free_interrupt(struct phy_device *phydev);
+ void phy_print_status(struct phy_device *phydev);
++int phy_get_rate_matching(struct phy_device *phydev,
++ phy_interface_t iface);
+ int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
+ void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode);
+ void phy_advertise_supported(struct phy_device *phydev);
+diff --git a/include/linux/phylink.h b/include/linux/phylink.h
+index 48ff9fe..e1c022f 100644
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -38,6 +38,10 @@ static inline bool phylink_autoneg_inband(unsigned int mode)
+ * @speed: link speed, one of the SPEED_* constants.
+ * @duplex: link duplex mode, one of DUPLEX_* constants.
+ * @pause: link pause state, described by MLO_PAUSE_* constants.
++ * @rate_matching: rate matching being performed, one of the RATE_MATCH_*
++ * constants. If rate matching is taking place, then the speed/duplex of
++ * the medium link mode (@speed and @duplex) and the speed/duplex of the phy
++ * interface mode (@interface) are different.
+ * @link: true if the link is up.
+ * @an_enabled: true if autonegotiation is enabled/desired.
+ * @an_complete: true if autonegotiation has completed.
+@@ -49,6 +53,7 @@ struct phylink_link_state {
+ int speed;
+ int duplex;
+ int pause;
++ int rate_matching;
+ unsigned int link:1;
+ unsigned int an_enabled:1;
+ unsigned int an_complete:1;
+diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
+index 8d465e5..ce41d2f 100644
+--- a/include/uapi/linux/ethtool.h
++++ b/include/uapi/linux/ethtool.h
+@@ -1643,6 +1643,20 @@ static inline int ethtool_validate_duplex(__u8 duplex)
+ return 0;
+ }
+
++/* These are used to throttle the rate of data on the phy interface when the
++ * native speed of the interface is higher than the link speed. These should
++ * not be used for phy interfaces which natively support multiple speeds (e.g.
++ * MII or SGMII).
++ */
++/* No rate matching performed. */
++#define RATE_MATCH_NONE 0
++/* The phy sends pause frames to throttle the MAC. */
++#define RATE_MATCH_PAUSE 1
++/* The phy asserts CRS to prevent the MAC from transmitting. */
++#define RATE_MATCH_CRS 2
++/* The MAC is programmed with a sufficiently-large IPG. */
++#define RATE_MATCH_OPEN_LOOP 3
++
+ /* Which connector port. */
+ #define PORT_TP 0x00
+ #define PORT_AUI 0x01
+@@ -1832,6 +1846,7 @@ enum ethtool_reset_flags {
+ * autonegotiation; 0 if unknown or not applicable. Read-only.
+ * @transceiver: Used to distinguish different possible PHY types,
+ * reported consistently by PHYLIB. Read-only.
++ * @rate_matching: Rate adaptation performed by the PHY
+ *
+ * If autonegotiation is disabled, the speed and @duplex represent the
+ * fixed link mode and are writable if the driver supports multiple
+@@ -1879,7 +1894,8 @@ struct ethtool_link_settings {
+ __u8 eth_tp_mdix_ctrl;
+ __s8 link_mode_masks_nwords;
+ __u8 transceiver;
+- __u8 reserved1[3];
++ __u8 reserved1[2];
++ __u8 rate_matching;
+ __u32 reserved[7];
+ __u32 link_mode_masks[0];
+ /* layout of link_mode_masks fields:
+diff --git a/net/core/ethtool.c b/net/core/ethtool.c
+index 9ae38c3..41a8b1d 100644
+--- a/net/core/ethtool.c
++++ b/net/core/ethtool.c
+@@ -656,6 +656,7 @@ static int ethtool_get_link_ksettings(struct net_device *dev,
+ link_ksettings.base.cmd = ETHTOOL_GLINKSETTINGS;
+ link_ksettings.base.link_mode_masks_nwords
+ = __ETHTOOL_LINK_MODE_MASK_NU32;
++ link_ksettings.base.rate_matching = RATE_MATCH_NONE;
+
+ return store_link_ksettings_for_user(useraddr, &link_ksettings);
+ }
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2000-show_model_name_in_cpuinfo_on_arm64.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2000-show_model_name_in_cpuinfo_on_arm64.patch
new file mode 100644
index 0000000..12ad322
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2000-show_model_name_in_cpuinfo_on_arm64.patch
@@ -0,0 +1,29 @@
+From 9fb8ad91c5e221d44089ca908311842d61c8f289 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:02 +0800
+Subject: [PATCH]
+ [basic-part][999-2000-show_model_name_in_cpuinfo_on_arm64.patch]
+
+---
+ arch/arm64/kernel/cpuinfo.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
+index 90b35011a..4324f12a2 100644
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -139,9 +139,8 @@ static int c_show(struct seq_file *m, void *v)
+ * "processor". Give glibc what it expects.
+ */
+ seq_printf(m, "processor\t: %d\n", i);
+- if (compat)
+- seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
+- MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
++ seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
++ MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
+
+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ loops_per_jiffy / (500000UL/HZ),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1023-kgdb-add-interrupt-control.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2001-kgdb-add-interrupt-control.patch
similarity index 76%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1023-kgdb-add-interrupt-control.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2001-kgdb-add-interrupt-control.patch
index e0ee954..7973173 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1023-kgdb-add-interrupt-control.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2001-kgdb-add-interrupt-control.patch
@@ -1,5 +1,14 @@
+From 766f65096433dde206cdfa19c2cd644be6beaf32 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:02 +0800
+Subject: [PATCH] [basic-part][999-2001-kgdb-add-interrupt-control.patch]
+
+---
+ arch/arm64/kernel/kgdb.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
-index 1a157ca..258fe4b 100644
+index 1a157ca33..258fe4b38 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -18,6 +18,10 @@
@@ -40,3 +49,6 @@
kgdb_handle_exception(0, SIGTRAP, 0, regs);
return DBG_HOOK_HANDLED;
}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0001-clk-mtk-add-mt7986-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2010-clk-mtk-add-mt7986-support.patch
similarity index 79%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0001-clk-mtk-add-mt7986-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2010-clk-mtk-add-mt7986-support.patch
index 930e88b..0708076 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0001-clk-mtk-add-mt7986-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2010-clk-mtk-add-mt7986-support.patch
@@ -1,11 +1,21 @@
+From cd39b20ca69be67d38a2366e64c496f157f12672 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:02 +0800
+Subject: [PATCH] [basic-part][999-2010-clk-mtk-add-mt7986-support.patch]
+
+---
+ drivers/clk/mediatek/Kconfig | 9 +++++++++
+ drivers/clk/mediatek/Makefile | 2 ++
+ 2 files changed, 11 insertions(+)
+
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
-index 7efc361..5f11280 100644
+index 7efc3617b..1c48fe9f5 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -258,6 +258,15 @@ config COMMON_CLK_MT7629_HIFSYS
This driver supports MediaTek MT7629 HIFSYS clocks providing
to PCI-E and USB.
-
+
+config COMMON_CLK_MT7986
+ bool "Clock driver for MediaTek MT7986"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
@@ -19,7 +29,7 @@
bool "Clock driver for MediaTek MT8135"
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
-index 8cdb76a..8c392f4 100644
+index 8cdb76a5c..8c392f4ef 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
@@ -37,5 +47,5 @@
+obj-y += clk-bringup.o
\ No newline at end of file
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0002-clk-mtk-add-mt7981-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2011-clk-mtk-add-mt7981-support.patch
similarity index 75%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0002-clk-mtk-add-mt7981-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2011-clk-mtk-add-mt7981-support.patch
index 72f9e8a..7bf43f4 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0002-clk-mtk-add-mt7981-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2011-clk-mtk-add-mt7981-support.patch
@@ -1,5 +1,15 @@
+From 0c59e472d0ace19f00d06b4ccf5dba6a7831c001 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:03 +0800
+Subject: [PATCH] [basic-part][999-2011-clk-mtk-add-mt7981-support.patch]
+
+---
+ drivers/clk/mediatek/Kconfig | 8 ++++++++
+ drivers/clk/mediatek/Makefile | 1 +
+ 2 files changed, 9 insertions(+)
+
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
-index 1c48fe9..23393d5 100644
+index 1c48fe9f5..23393d5ec 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -267,6 +267,14 @@ config COMMON_CLK_MT7986
@@ -18,7 +28,7 @@
bool "Clock driver for MediaTek MT8135"
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
-index 8c392f4..ffe0850 100644
+index 8c392f4ef..ffe0850e1 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
@@ -30,5 +40,5 @@
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0003-clk-mtk-add-mt7988-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2012-clk-mtk-add-mt7988-support.patch
similarity index 78%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0003-clk-mtk-add-mt7988-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2012-clk-mtk-add-mt7988-support.patch
index e673148..d29a023 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0003-clk-mtk-add-mt7988-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2012-clk-mtk-add-mt7988-support.patch
@@ -1,5 +1,15 @@
+From 63786d6f950d63c586b4efac77d3244b959ba5a6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:03 +0800
+Subject: [PATCH] [basic-part][999-2012-clk-mtk-add-mt7988-support.patch]
+
+---
+ drivers/clk/mediatek/Kconfig | 8 ++++++++
+ drivers/clk/mediatek/Makefile | 3 ++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
-index 23393d5..cf3a53e 100644
+index 23393d5ec..cf3a53e9b 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -275,6 +275,14 @@ config COMMON_CLK_MT7981
@@ -18,7 +28,7 @@
bool "Clock driver for MediaTek MT8135"
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
-index ffe0850..43ca85d 100644
+index ffe0850e1..43ca85d10 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
@@ -36,3 +46,6 @@
-obj-y += clk-bringup.o
\ No newline at end of file
+obj-y += clk-bringup.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0005-clk-mtk-add-chg-shift-control.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2013-clk-mtk-add-chg-shift-control.patch
similarity index 69%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0005-clk-mtk-add-chg-shift-control.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2013-clk-mtk-add-chg-shift-control.patch
index 4a9ff6f..7853f41 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0005-clk-mtk-add-chg-shift-control.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2013-clk-mtk-add-chg-shift-control.patch
@@ -1,5 +1,15 @@
+From e640a8767e5ab047b8a4c89041ee3872132ce38a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:03 +0800
+Subject: [PATCH] [basic-part][999-2013-clk-mtk-add-chg-shift-control.patch]
+
+---
+ drivers/clk/mediatek/clk-mtk.h | 1 +
+ drivers/clk/mediatek/clk-pll.c | 5 ++++-
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
-index c3d6756..d84c45d 100644
+index c3d6756b0..d84c45d75 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -231,6 +231,7 @@ struct mtk_pll_data {
@@ -11,7 +21,7 @@
const char *parent_name;
};
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
-index f440f2c..db318fe 100644
+index f440f2cd0..db318fe1c 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -136,7 +136,10 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
@@ -26,3 +36,6 @@
writel(chg, pll->pcw_chg_addr);
if (pll->tuner_addr)
writel(val + 1, pll->tuner_addr);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/401-pinctrl-add-mt7986-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2020-pinctrl-add-mt7986-driver.patch
similarity index 72%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/401-pinctrl-add-mt7986-driver.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2020-pinctrl-add-mt7986-driver.patch
index a02873d..ba9e2bb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/401-pinctrl-add-mt7986-driver.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2020-pinctrl-add-mt7986-driver.patch
@@ -1,5 +1,15 @@
+From 1cbd50ca51ad80b9c2527c1aaccb57b92dd6d635 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:03 +0800
+Subject: [PATCH] [basic-part][999-2020-pinctrl-add-mt7986-driver.patch]
+
+---
+ drivers/pinctrl/mediatek/Kconfig | 7 +++++++
+ drivers/pinctrl/mediatek/Makefile | 1 +
+ 2 files changed, 8 insertions(+)
+
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
-index 701f9af..9109f91 100644
+index 701f9af63..9109f911a 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -100,6 +100,13 @@ config PINCTRL_MT7622
@@ -17,7 +27,7 @@
bool "Mediatek MT8173 pin control"
depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
-index a74325a..d408585 100644
+index a74325abd..d4085859a 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-mt6797.o
@@ -28,3 +38,6 @@
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/401-pinctrl-enable-mt7988-pinctrl-config.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2021-pinctrl-enable-mt7988-pinctrl-config.patch
similarity index 62%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/401-pinctrl-enable-mt7988-pinctrl-config.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2021-pinctrl-enable-mt7988-pinctrl-config.patch
index 01f01f6..84f0b84 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/401-pinctrl-enable-mt7988-pinctrl-config.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2021-pinctrl-enable-mt7988-pinctrl-config.patch
@@ -1,8 +1,19 @@
+From c0566aeb32196514614c335efb3e280595da99c3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:04 +0800
+Subject: [PATCH]
+ [basic-part][999-2021-pinctrl-enable-mt7988-pinctrl-config.patch]
+
+---
+ drivers/pinctrl/mediatek/Kconfig | 7 +++++++
+ drivers/pinctrl/mediatek/Makefile | 1 +
+ 2 files changed, 8 insertions(+)
+
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
-index e7ec276..b6341dd 100644
+index 9109f911a..a2223dbe0 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
-@@ -112,6 +112,13 @@ config PINCTRL_MT7986
+@@ -107,6 +107,13 @@ config PINCTRL_MT7986
default ARM64 && ARCH_MEDIATEK
select PINCTRL_MTK_MOORE
@@ -17,14 +28,17 @@
bool "Mediatek MT8173 pin control"
depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
-index e6813cf..6e28df9 100644
+index d4085859a..6526efc2c 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
-@@ -17,6 +17,7 @@ obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
+@@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o
+ obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
- obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
+obj-$(CONFIG_PINCTRL_MT7988) += pinctrl-mt7988.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/402-pinctrl-add-mt7981-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2022-pinctrl-add-mt7981-driver.patch
similarity index 74%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/402-pinctrl-add-mt7981-driver.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2022-pinctrl-add-mt7981-driver.patch
index 9e67ee7..10f0938 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/402-pinctrl-add-mt7981-driver.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2022-pinctrl-add-mt7981-driver.patch
@@ -1,15 +1,15 @@
-From 1b529849f324edec053a34292e3f874bde8f7401 Mon Sep 17 00:00:00 2001
+From af29af4ab3fb39d3884ea9f7352e672c89093c3b Mon Sep 17 00:00:00 2001
From: Sam Shih <sam.shih@mediatek.com>
-Date: Fri, 25 Jun 2021 15:43:55 +0800
-Subject: [PATCH] Add mt7981 pinctrl driver support
+Date: Fri, 2 Jun 2023 13:06:04 +0800
+Subject: [PATCH] [basic-part][999-2022-pinctrl-add-mt7981-driver.patch]
---
- drivers/pinctrl/mediatek/Kconfig | 7 +++++++
+ drivers/pinctrl/mediatek/Kconfig | 5 +++++
drivers/pinctrl/mediatek/Makefile | 1 +
- 2 files changed, 8 insertions(+)
+ 2 files changed, 6 insertions(+)
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
-index 9109f91..d40aee5 100644
+index a2223dbe0..b6341dd83 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -100,6 +100,11 @@ config PINCTRL_MT7622
@@ -25,7 +25,7 @@
bool "Mediatek MT7986 pin control"
depends on OF
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
-index d408585..e6813cf 100644
+index 6526efc2c..b80ef66da 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_PINCTRL_MT6797) += pinctrl-mt6797.o
@@ -34,8 +34,8 @@
obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
+obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o
obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o
+ obj-$(CONFIG_PINCTRL_MT7988) += pinctrl-mt7988.o
obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o
- obj-$(CONFIG_PINCTRL_MT8183) += pinctrl-mt8183.o
--
-2.6.4
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2040-powerdomain-add-mt7988-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2040-powerdomain-add-mt7988-support.patch
new file mode 100644
index 0000000..33f4ae6
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2040-powerdomain-add-mt7988-support.patch
@@ -0,0 +1,21 @@
+From c04a931b0f3f8c1af74197ef22a9cbcb96697c9f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:04 +0800
+Subject: [PATCH] [basic-part][999-2040-powerdomain-add-mt7988-support.patch]
+
+---
+ drivers/soc/mediatek/Makefile | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
+index b01733074..1c485e3ba 100644
+--- a/drivers/soc/mediatek/Makefile
++++ b/drivers/soc/mediatek/Makefile
+@@ -3,3 +3,4 @@ obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
+ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o
+ obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
+ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
++obj-$(CONFIG_MTK_SCPSYS) += mtk-pm-domains.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0960-watchdog-add-mt7986-assert.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2050-watchdog-add-mt7986-assert.patch
similarity index 95%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0960-watchdog-add-mt7986-assert.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2050-watchdog-add-mt7986-assert.patch
index 619fc10..2b0f938 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0960-watchdog-add-mt7986-assert.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2050-watchdog-add-mt7986-assert.patch
@@ -1,5 +1,14 @@
+From d02a2cf00764f83a9efdc08685381ee9167b0a9e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:04 +0800
+Subject: [PATCH] [basic-part][999-2050-watchdog-add-mt7986-assert.patch]
+
+---
+ drivers/watchdog/mtk_wdt.c | 202 +++++++++++++++++++++++++++++++++++--
+ 1 file changed, 193 insertions(+), 9 deletions(-)
+
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
-index 9c3d003..30127d1 100644
+index 9c3d00332..30127d1e7 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -9,6 +9,8 @@
@@ -326,3 +335,6 @@
-MODULE_VERSION(DRV_VERSION);
+MODULE_VERSION(DRV_VERSION);
\ No newline at end of file
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0111-mt7986-trng-add-rng-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2100-mt7986-trng-add-rng-support.patch
similarity index 68%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0111-mt7986-trng-add-rng-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2100-mt7986-trng-add-rng-support.patch
index 1b132a3..bef2e1c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0111-mt7986-trng-add-rng-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2100-mt7986-trng-add-rng-support.patch
@@ -1,18 +1,14 @@
-From 6d4a858d6f7db2a86f6513a543feb8f7b8a8b4c1 Mon Sep 17 00:00:00 2001
-From: "Mingming.Su" <Mingming.Su@mediatek.com>
-Date: Wed, 30 Jun 2021 16:59:32 +0800
-Subject: [PATCH] mt7986: trng: add rng support
+From 28b23dd56546943c99dc4e884576e629b417fb6d Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:05 +0800
+Subject: [PATCH] [slow-speed-io][999-2100-mt7986-trng-add-rng-support.patch]
-1. Add trng compatible name for MT7986
-2. Fix mtk_rng_wait_ready() function
-
-Signed-off-by: Mingming.Su <Mingming.Su@mediatek.com>
---
drivers/char/hw_random/mtk-rng.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c
-index e649be5a5..496adb0a0 100644
+index 6670516fa..a8bd06da7 100644
--- a/drivers/char/hw_random/mtk-rng.c
+++ b/drivers/char/hw_random/mtk-rng.c
@@ -22,7 +22,7 @@
@@ -33,7 +29,7 @@
}
static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
-@@ -181,6 +181,7 @@ static UNIVERSAL_DEV_PM_OPS(mtk_rng_pm_ops, mtk_rng_runtime_suspend,
+@@ -186,6 +186,7 @@ static const struct dev_pm_ops mtk_rng_pm_ops = {
#endif /* CONFIG_PM */
static const struct of_device_id mtk_rng_match[] = {
@@ -42,5 +38,5 @@
{},
};
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1661-Add-trngv2-driver-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2101-Add-trngv2-driver-support.patch
similarity index 95%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1661-Add-trngv2-driver-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2101-Add-trngv2-driver-support.patch
index 7c09a71..2169d20 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1661-Add-trngv2-driver-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2101-Add-trngv2-driver-support.patch
@@ -1,7 +1,7 @@
-From ae5611b1b7a857edb3d9c8e900b550c76f7c236e Mon Sep 17 00:00:00 2001
-From: "Mingming.Su" <Mingming.Su@mediatek.com>
-Date: Fri, 17 Dec 2021 20:27:34 +0800
-Subject: [PATCH] Add trngv2 driver support
+From cff177b10455d17fec2c2a412a4f5491af3be315 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:05 +0800
+Subject: [PATCH] [slow-speed-io][999-2101-Add-trngv2-driver-support.patch]
---
drivers/char/hw_random/mtk-rng.c | 105 +++++++++++++++++++++++--------
@@ -181,5 +181,5 @@
};
MODULE_DEVICE_TABLE(of, mtk_rng_match);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1662-trng-Add-trng-support-for-mt7988.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2102-trng-Add-trng-support-for-mt7988.patch
similarity index 77%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1662-trng-Add-trng-support-for-mt7988.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2102-trng-Add-trng-support-for-mt7988.patch
index a8f1dfe..80d3df8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1662-trng-Add-trng-support-for-mt7988.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2102-trng-Add-trng-support-for-mt7988.patch
@@ -1,11 +1,9 @@
-From cbd37bfc8221c1a81d235ddfb1898536a821c650 Mon Sep 17 00:00:00 2001
-From: "mingming.su" <Mingming.Su@mediatek.com>
-Date: Wed, 7 Sep 2022 15:44:46 +0800
-Subject: [PATCH] trng: Add trng support for mt7988
+From a63382c6164e5c856057a394f53c91cb0d79222f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:05 +0800
+Subject: [PATCH]
+ [slow-speed-io][999-2102-trng-Add-trng-support-for-mt7988.patch]
-Add trng support for mt7988.
-
-Signed-off-by: mingming.su <Mingming.Su@mediatek.com>
---
drivers/char/hw_random/mtk-rng.c | 5 +++++
1 file changed, 5 insertions(+)
@@ -34,5 +32,5 @@
{},
};
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9019-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
similarity index 74%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9019-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
index 5635f55..47ac32a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9019-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch
@@ -1,19 +1,20 @@
-From 6110010f7b88392a3094f2aaec91ee54151cde2a Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:43:02 +0800
-Subject: [PATCH] drivers: char: tpm: Add calibration example for SPI TPM
- module
+From daaf90f34aa73625585f56d766e51c7b718bebc3 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:05 +0800
+Subject: [PATCH]
+ [slow-speed-io][999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
drivers/char/tpm/tpm_tis_core.c | 19 +++++++++++++++++++
drivers/char/tpm/tpm_tis_core.h | 2 ++
drivers/char/tpm/tpm_tis_spi.c | 7 +++++++
3 files changed, 28 insertions(+)
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
+index 70f785994..b9898a56d 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
-@@ -817,6 +817,21 @@ static const struct tpm_class_ops tpm_ti
+@@ -817,6 +817,21 @@ static const struct tpm_class_ops tpm_tis = {
.clk_enable = tpm_tis_clkrun_enable,
};
@@ -35,7 +36,7 @@
int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
const struct tpm_tis_phy_ops *phy_ops,
acpi_handle acpi_dev_handle)
-@@ -864,6 +879,10 @@ int tpm_tis_core_init(struct device *dev
+@@ -864,6 +879,10 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if (chip->ops->clk_enable != NULL)
chip->ops->clk_enable(chip, true);
@@ -46,6 +47,8 @@
if (wait_startup(chip, 0) != 0) {
rc = -ENODEV;
goto out_err;
+diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h
+index 7337819f5..7bb0bc8b6 100644
--- a/drivers/char/tpm/tpm_tis_core.h
+++ b/drivers/char/tpm/tpm_tis_core.h
@@ -106,6 +106,7 @@ struct tpm_tis_phy_ops {
@@ -64,9 +67,11 @@
int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
const struct tpm_tis_phy_ops *phy_ops,
acpi_handle acpi_dev_handle);
+diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c
+index 19513e622..3be2d53a5 100644
--- a/drivers/char/tpm/tpm_tis_spi.c
+++ b/drivers/char/tpm/tpm_tis_spi.c
-@@ -184,12 +184,19 @@ static int tpm_tis_spi_write32(struct tp
+@@ -184,12 +184,19 @@ static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
return rc;
}
@@ -86,3 +91,6 @@
};
static int tpm_tis_spi_probe(struct spi_device *dev)
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-i2c-busses-add-mt7986-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2110-i2c-busses-add-mt7986-support.patch
similarity index 75%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-i2c-busses-add-mt7986-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2110-i2c-busses-add-mt7986-support.patch
index a375842..e97ff9b 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0900-i2c-busses-add-mt7986-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2110-i2c-busses-add-mt7986-support.patch
@@ -1,11 +1,20 @@
+From 64902a41254881d559a2f1e4d2966f16e4a7f98a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:06 +0800
+Subject: [PATCH] [slow-speed-io][999-2110-i2c-busses-add-mt7986-support.patch]
+
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
-index e1ef012..4fd4721 100644
+index 5587e7c54..14d96c876 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -289,6 +289,19 @@ static const struct mtk_i2c_compatible mt7622_compat = {
.ltiming_adjust = 0,
};
-
+
+static const struct mtk_i2c_compatible mt7986_compat = {
+ .quirks = &mt7622_i2c_quirks,
+ .regs = mt_i2c_regs_v1,
@@ -30,3 +39,6 @@
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
{}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0901-i2c-busses-add-mt7981-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2111-i2c-busses-add-mt7981-support.patch
similarity index 79%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0901-i2c-busses-add-mt7981-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2111-i2c-busses-add-mt7981-support.patch
index f79d2f8..ba37f4a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0901-i2c-busses-add-mt7981-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2111-i2c-busses-add-mt7981-support.patch
@@ -1,5 +1,14 @@
+From c4ad4b0aa7fb10beb510b99caba9cd027a88a723 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:06 +0800
+Subject: [PATCH] [slow-speed-io][999-2111-i2c-busses-add-mt7981-support.patch]
+
+---
+ drivers/i2c/busses/i2c-mt65xx.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
-index e1ef012..4fd4721 100644
+index 14d96c876..995e8bbaf 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -157,7 +157,7 @@ static const u16 mt_i2c_regs_v1[] = {
@@ -39,5 +48,5 @@
{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/500-auxadc-add-auxadc-32k-clk.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2120-auxadc-add-auxadc-32k-clk.patch
similarity index 73%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/500-auxadc-add-auxadc-32k-clk.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2120-auxadc-add-auxadc-32k-clk.patch
index dc0dd2f..2125916 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/500-auxadc-add-auxadc-32k-clk.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2120-auxadc-add-auxadc-32k-clk.patch
@@ -1,5 +1,14 @@
+From ab1b6a5a856d2ade01ce7f677dc8943ffc476c35 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:06 +0800
+Subject: [PATCH] [slow-speed-io][999-2120-auxadc-add-auxadc-32k-clk.patch]
+
+---
+ drivers/iio/adc/mt6577_auxadc.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
-index 2449d91..b8a43eb 100644
+index 9cdb9084c..34f94554f 100644
--- a/drivers/iio/adc/mt6577_auxadc.c
+++ b/drivers/iio/adc/mt6577_auxadc.c
@@ -42,6 +42,7 @@ struct mtk_auxadc_compatible {
@@ -10,7 +19,7 @@
struct mutex lock;
const struct mtk_auxadc_compatible *dev_comp;
};
-@@ -214,6 +215,12 @@ static int __maybe_unused mt6577_auxadc_resume(struct device *dev)
+@@ -222,6 +223,12 @@ static int __maybe_unused mt6577_auxadc_resume(struct device *dev)
return ret;
}
@@ -23,7 +32,7 @@
mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
MT6577_AUXADC_PDN_EN, 0);
mdelay(MT6577_AUXADC_POWER_READY_MS);
-@@ -228,6 +235,8 @@ static int __maybe_unused mt6577_auxadc_suspend(struct device *dev)
+@@ -236,6 +243,8 @@ static int __maybe_unused mt6577_auxadc_suspend(struct device *dev)
mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
0, MT6577_AUXADC_PDN_EN);
@@ -32,7 +41,7 @@
clk_disable_unprepare(adc_dev->adc_clk);
return 0;
-@@ -272,6 +281,17 @@ static int mt6577_auxadc_probe(struct platform_device *pdev)
+@@ -280,6 +289,17 @@ static int mt6577_auxadc_probe(struct platform_device *pdev)
return ret;
}
@@ -50,7 +59,7 @@
adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
if (!adc_clk_rate) {
ret = -EINVAL;
-@@ -301,6 +321,7 @@ static int mt6577_auxadc_probe(struct platform_device *pdev)
+@@ -309,6 +329,7 @@ err_power_off:
mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
0, MT6577_AUXADC_PDN_EN);
err_disable_clk:
@@ -58,7 +67,7 @@
clk_disable_unprepare(adc_dev->adc_clk);
return ret;
}
-@@ -315,6 +336,7 @@ static int mt6577_auxadc_remove(struct platform_device *pdev)
+@@ -323,6 +344,7 @@ static int mt6577_auxadc_remove(struct platform_device *pdev)
mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
0, MT6577_AUXADC_PDN_EN);
@@ -66,3 +75,6 @@
clk_disable_unprepare(adc_dev->adc_clk);
return 0;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0930-pwm-add-mt7986-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2130-pwm-add-mt7986-support.patch
similarity index 72%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0930-pwm-add-mt7986-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2130-pwm-add-mt7986-support.patch
index a791d3a..dac5409 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0930-pwm-add-mt7986-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2130-pwm-add-mt7986-support.patch
@@ -1,11 +1,20 @@
+From dcce03b49e8bac8a2c371c24dbcc9a6922861b8a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:07 +0800
+Subject: [PATCH] [slow-speed-io][999-2130-pwm-add-mt7986-support.patch]
+
+---
+ drivers/pwm/pwm-mediatek.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
-index b94e0d0..35a0db2 100644
+index b94e0d09c..35a0db2ff 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -302,6 +302,11 @@ static const struct pwm_mediatek_of_data mt7629_pwm_data = {
.pwm45_fixup = false,
};
-
+
+static const struct pwm_mediatek_of_data mt7986_pwm_data = {
+ .num_pwms = 2,
+ .pwm45_fixup = false,
@@ -22,3 +31,6 @@
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
{ },
};
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0931-pwm-add-mt7981-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2131-pwm-add-mt7981-support.patch
similarity index 83%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0931-pwm-add-mt7981-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2131-pwm-add-mt7981-support.patch
index 0de7966..e137dc4 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0931-pwm-add-mt7981-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2131-pwm-add-mt7981-support.patch
@@ -1,8 +1,17 @@
+From c6dc9128df3673041cade417331ad2579e669520 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:07 +0800
+Subject: [PATCH] [slow-speed-io][999-2131-pwm-add-mt7981-support.patch]
+
+---
+ drivers/pwm/pwm-mediatek.c | 51 +++++++++++++++++++++++++++++++++++---
+ 1 file changed, 48 insertions(+), 3 deletions(-)
+
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
-index 7c56ee2..3a5a456 100644
+index 35a0db2ff..f4393bd46 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
-@@ -33,10 +32,13 @@
+@@ -32,10 +32,13 @@
#define PWM45THRES_FIXUP 0x34
#define PWM_CLK_DIV_MAX 7
@@ -16,7 +25,7 @@
};
/**
-@@ -57,10 +59,14 @@ struct pwm_mediatek_chip {
+@@ -56,10 +59,14 @@ struct pwm_mediatek_chip {
const struct pwm_mediatek_of_data *soc;
};
@@ -32,7 +41,7 @@
static inline struct pwm_mediatek_chip *
to_pwm_mediatek_chip(struct pwm_chip *chip)
{
-@@ -108,14 +114,38 @@ static void pwm_mediatek_clk_disable(struct pwm_chip *chip,
+@@ -107,14 +114,38 @@ static void pwm_mediatek_clk_disable(struct pwm_chip *chip,
static inline u32 pwm_mediatek_readl(struct pwm_mediatek_chip *chip,
unsigned int num, unsigned int offset)
{
@@ -73,7 +82,7 @@
}
static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
-@@ -281,36 +311,49 @@ static int pwm_mediatek_remove(struct platform_device *pdev)
+@@ -280,36 +311,49 @@ static int pwm_mediatek_remove(struct platform_device *pdev)
static const struct pwm_mediatek_of_data mt2712_pwm_data = {
.num_pwms = 8,
.pwm45_fixup = false,
@@ -123,7 +132,7 @@
};
static const struct of_device_id pwm_mediatek_of_match[] = {
-@@ -319,6 +362,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
+@@ -318,6 +362,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
{ .compatible = "mediatek,mt7623-pwm", .data = &mt7623_pwm_data },
{ .compatible = "mediatek,mt7628-pwm", .data = &mt7628_pwm_data },
{ .compatible = "mediatek,mt7629-pwm", .data = &mt7629_pwm_data },
@@ -131,3 +140,6 @@
{ .compatible = "mediatek,mt7986-pwm", .data = &mt7986_pwm_data },
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
{ },
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0932-add-pwm-feature-in-mt7988-project.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2132-add-pwm-feature-in-mt7988-project.patch
similarity index 70%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0932-add-pwm-feature-in-mt7988-project.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2132-add-pwm-feature-in-mt7988-project.patch
index 8268e7d..afa7720 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0932-add-pwm-feature-in-mt7988-project.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2132-add-pwm-feature-in-mt7988-project.patch
@@ -1,9 +1,19 @@
+From 1ad5b06d70ce07cd377d6a9580b922b1fa68e674 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:07 +0800
+Subject: [PATCH]
+ [slow-speed-io][999-2132-add-pwm-feature-in-mt7988-project.patch]
+
+---
+ drivers/pwm/pwm-mediatek.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
-index 3a5a456..6d6206e 100644
+index f4393bd46..9701092e7 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -350,6 +350,12 @@ static const struct pwm_mediatek_of_data mt7986_pwm_data = {
- .reg_ver = REG_V2,
+ .reg_ver = REG_V1,
};
+static const struct pwm_mediatek_of_data mt7988_pwm_data = {
@@ -23,3 +33,6 @@
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
{ },
};
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0950-pwm-mediatek-add-longer-period-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2133-pwm-mediatek-add-longer-period-support.patch
similarity index 85%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0950-pwm-mediatek-add-longer-period-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2133-pwm-mediatek-add-longer-period-support.patch
index 0934ae2..79afa46 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0950-pwm-mediatek-add-longer-period-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2133-pwm-mediatek-add-longer-period-support.patch
@@ -1,5 +1,15 @@
+From 58d5a373d2d42b5292c1c2242133bcf0b082c6e0 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:07 +0800
+Subject: [PATCH]
+ [slow-speed-io][999-2133-pwm-mediatek-add-longer-period-support.patch]
+
+---
+ drivers/pwm/pwm-mediatek.c | 34 ++++++++++++++++++++++++++++++----
+ 1 file changed, 30 insertions(+), 4 deletions(-)
+
diff --git a/drivers/pwm/pwm-mediatek.c b/drivers/pwm/pwm-mediatek.c
-index 9701092..79d15a9 100644
+index 9701092e7..79d15a9c0 100644
--- a/drivers/pwm/pwm-mediatek.c
+++ b/drivers/pwm/pwm-mediatek.c
@@ -152,8 +152,11 @@ static int pwm_mediatek_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -63,3 +73,6 @@
pwm_mediatek_writel(pc, pwm->hwpwm, reg_width, cnt_period);
pwm_mediatek_writel(pc, pwm->hwpwm, reg_thres, cnt_duty);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/6001-mtk-thermal-add-lvts-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2140-mtk-thermal-add-lvts-support.patch
similarity index 71%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/6001-mtk-thermal-add-lvts-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2140-mtk-thermal-add-lvts-support.patch
index 1591144..a9ca6d7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/6001-mtk-thermal-add-lvts-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2140-mtk-thermal-add-lvts-support.patch
@@ -1,5 +1,15 @@
+From 23c38736374866e0f1423dde94ac6e80eb644132 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:08 +0800
+Subject: [PATCH] [slow-speed-io][999-2140-mtk-thermal-add-lvts-support.patch]
+
+---
+ drivers/thermal/Kconfig | 5 +++++
+ drivers/thermal/Makefile | 1 +
+ 2 files changed, 6 insertions(+)
+
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
-index 001a21ab..67d3da48 100644
+index 001a21abc..67d3da488 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -348,6 +348,11 @@ config MTK_THERMAL
@@ -15,7 +25,7 @@
depends on X86 || X86_INTEL_QUARK || COMPILE_TEST
source "drivers/thermal/intel/Kconfig"
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
-index 74a37c7f..6be9ff19 100644
+index 74a37c7f8..6be9ff194 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_QCOM_TSENS) += qcom/
@@ -26,3 +36,6 @@
obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0400-sound-add-some-helpers-to-control-mtk_memif.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2150-sound-add-some-helpers-to-control-mtk_memif.patch
similarity index 87%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0400-sound-add-some-helpers-to-control-mtk_memif.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2150-sound-add-some-helpers-to-control-mtk_memif.patch
index ddeb5a4..85c5ceb 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0400-sound-add-some-helpers-to-control-mtk_memif.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2150-sound-add-some-helpers-to-control-mtk_memif.patch
@@ -1,6 +1,20 @@
+From 21c1013ecce400652b42489935190df542c9fa4b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:08 +0800
+Subject: [PATCH]
+ [slow-speed-io][999-2150-sound-add-some-helpers-to-control-mtk_memif.patch]
+
+---
+ sound/soc/mediatek/common/mtk-afe-fe-dai.c | 216 +++++++++++++++++++++
+ sound/soc/mediatek/common/mtk-afe-fe-dai.h | 16 ++
+ sound/soc/mediatek/common/mtk-base-afe.h | 28 ++-
+ 3 files changed, 259 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+index 10ea4fdbe..309dc1ef6 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
-@@ -361,6 +361,222 @@
+@@ -361,6 +361,222 @@ int mtk_afe_dai_resume(struct snd_soc_dai *dai)
}
EXPORT_SYMBOL_GPL(mtk_afe_dai_resume);
@@ -223,9 +237,11 @@
MODULE_DESCRIPTION("Mediatek simple fe dai operator");
MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");
MODULE_LICENSE("GPL v2");
+diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.h b/sound/soc/mediatek/common/mtk-afe-fe-dai.h
+index 55074fb98..507e3e7c3 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.h
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.h
-@@ -34,4 +34,20 @@
+@@ -34,4 +34,20 @@ int mtk_dynamic_irq_release(struct mtk_base_afe *afe, int irq_id);
int mtk_afe_dai_suspend(struct snd_soc_dai *dai);
int mtk_afe_dai_resume(struct snd_soc_dai *dai);
@@ -246,9 +262,11 @@
+int mtk_memif_set_pbuf_size(struct mtk_base_afe *afe,
+ int id, int pbuf_size);
#endif
+diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
+index 60cb609a9..a8cf44d98 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
-@@ -16,21 +16,38 @@
+@@ -16,21 +16,38 @@ struct mtk_base_memif_data {
const char *name;
int reg_ofs_base;
int reg_ofs_cur;
@@ -288,7 +306,7 @@
};
struct mtk_base_irq_data {
-@@ -84,6 +101,12 @@
+@@ -84,6 +101,12 @@ struct mtk_base_afe {
unsigned int rate);
int (*irq_fs)(struct snd_pcm_substream *substream,
unsigned int rate);
@@ -301,7 +319,7 @@
void *platform_priv;
};
-@@ -95,6 +118,9 @@
+@@ -95,6 +118,9 @@ struct mtk_base_afe_memif {
const struct mtk_base_memif_data *data;
int irq_usage;
int const_irq;
@@ -311,3 +329,6 @@
};
struct mtk_base_afe_irq {
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0401-sound-refine-hw-params-and-hw-prepare.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2151-sound-refine-hw-params-and-hw-prepare.patch
similarity index 87%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0401-sound-refine-hw-params-and-hw-prepare.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2151-sound-refine-hw-params-and-hw-prepare.patch
index 3e24d51..f097f4a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0401-sound-refine-hw-params-and-hw-prepare.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2151-sound-refine-hw-params-and-hw-prepare.patch
@@ -1,3 +1,15 @@
+From 35cc92b8996980021f881a202b8e1233ca41eb0d Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:08 +0800
+Subject: [PATCH]
+ [slow-speed-io][999-2151-sound-refine-hw-params-and-hw-prepare.patch]
+
+---
+ sound/soc/mediatek/common/mtk-afe-fe-dai.c | 143 +++++++++++----------
+ 1 file changed, 77 insertions(+), 66 deletions(-)
+
+diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+index 309dc1ef6..e761cb66b 100644
--- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -6,11 +6,13 @@
@@ -14,7 +26,7 @@
#include "mtk-afe-fe-dai.h"
#include "mtk-base-afe.h"
-@@ -120,50 +122,64 @@
+@@ -120,50 +122,64 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
@@ -49,10 +61,7 @@
- 1, msb_at_bit33, memif->data->msb_shift);
+ if (afe->request_dram_resource)
+ afe->request_dram_resource(afe->dev);
-
-- /* set channel */
-- if (memif->data->mono_shift >= 0) {
-- unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
++
+ dev_dbg(afe->dev, "%s(), %s, ch %d, rate %d, fmt %d, dma_addr %pad, dma_area %p, dma_bytes 0x%zx\n",
+ __func__, memif->data->name,
+ channels, rate, format,
@@ -74,9 +83,12 @@
+ return ret;
+ }
+ /* set channel */
+- if (memif->data->mono_shift >= 0) {
+- unsigned int mono = (params_channels(params) == 1) ? 1 : 0;
+-
- mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg,
- 1, mono, memif->data->mono_shift);
-+ /* set channel */
+ ret = mtk_memif_set_channel(afe, id, channels);
+ if (ret) {
+ dev_err(afe->dev, "%s(), error, id %d, set channel %d, ret %d\n",
@@ -112,7 +124,7 @@
return 0;
}
-@@ -172,6 +188,11 @@
+@@ -172,6 +188,11 @@ EXPORT_SYMBOL_GPL(mtk_afe_fe_hw_params);
int mtk_afe_fe_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
@@ -124,7 +136,7 @@
return snd_pcm_lib_free_pages(substream);
}
EXPORT_SYMBOL_GPL(mtk_afe_fe_hw_free);
-@@ -182,20 +203,25 @@
+@@ -182,20 +203,25 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime * const runtime = substream->runtime;
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
@@ -154,7 +166,7 @@
/* set irq counter */
mtk_regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
-@@ -219,15 +245,19 @@
+@@ -219,15 +245,19 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -177,7 +189,7 @@
default:
return -EINVAL;
}
-@@ -239,34 +269,15 @@
+@@ -239,34 +269,15 @@ int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
@@ -219,3 +231,6 @@
return 0;
}
EXPORT_SYMBOL_GPL(mtk_afe_fe_prepare);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0402-sound-add-mt7986-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2152-sound-add-mt7986-driver.patch
similarity index 70%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0402-sound-add-mt7986-driver.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2152-sound-add-mt7986-driver.patch
index 973f565..41eb05e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0402-sound-add-mt7986-driver.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2152-sound-add-mt7986-driver.patch
@@ -1,6 +1,18 @@
+From 593cfdef7ef160c49db5c7ae315cb963f32a947a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:08 +0800
+Subject: [PATCH] [slow-speed-io][999-2152-sound-add-mt7986-driver.patch]
+
+---
+ sound/soc/mediatek/Kconfig | 30 ++++++++++++++++++++++++++++++
+ sound/soc/mediatek/Makefile | 1 +
+ 2 files changed, 31 insertions(+)
+
+diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
+index 111e44b64..25e392428 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
-@@ -53,6 +53,36 @@
+@@ -53,6 +53,36 @@ config SND_SOC_MT6797_MT6351
Select Y if you have such device.
If unsure select "N".
@@ -37,6 +49,8 @@
config SND_SOC_MT8173
tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
+diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
+index 76032cae6..9690326b2 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -2,5 +2,6 @@
@@ -46,3 +60,6 @@
+obj-$(CONFIG_SND_SOC_MT79XX) += mt79xx/
obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0801-mtk-sd-add-mt7986-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2300-mtk-sd-add-mt7986-support.patch
similarity index 60%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0801-mtk-sd-add-mt7986-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2300-mtk-sd-add-mt7986-support.patch
index 6b76993..5a36ab0 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0801-mtk-sd-add-mt7986-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2300-mtk-sd-add-mt7986-support.patch
@@ -1,6 +1,17 @@
+From b4ad228b3e415f980932a2200d93b56f135e6bc8 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:09 +0800
+Subject: [PATCH] [spi-and-storage][999-2300-mtk-sd-add-mt7986-support.patch]
+
+---
+ drivers/mmc/host/mtk-sd.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index 1254a5650..b25e8567f 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
-@@ -508,6 +508,18 @@ static const struct mtk_mmc_compatible m
+@@ -508,6 +508,18 @@ static const struct mtk_mmc_compatible mt7622_compat = {
.support_64g = false,
};
@@ -19,7 +30,7 @@
static const struct mtk_mmc_compatible mt8516_compat = {
.clk_div_bits = 12,
.hs400_tune = false,
-@@ -537,6 +549,7 @@ static const struct of_device_id msdc_of
+@@ -537,6 +549,7 @@ static const struct of_device_id msdc_of_ids[] = {
{ .compatible = "mediatek,mt2701-mmc", .data = &mt2701_compat},
{ .compatible = "mediatek,mt2712-mmc", .data = &mt2712_compat},
{ .compatible = "mediatek,mt7622-mmc", .data = &mt7622_compat},
@@ -27,3 +38,6 @@
{ .compatible = "mediatek,mt8516-mmc", .data = &mt8516_compat},
{ .compatible = "mediatek,mt7620-mmc", .data = &mt7620_compat},
{}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0802-mtk-sd-Add-subsys-clock-control.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2301-mtk-sd-Add-subsys-clock-control.patch
similarity index 81%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0802-mtk-sd-Add-subsys-clock-control.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2301-mtk-sd-Add-subsys-clock-control.patch
index 8732cef..9ac8a25 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0802-mtk-sd-Add-subsys-clock-control.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2301-mtk-sd-Add-subsys-clock-control.patch
@@ -1,3 +1,15 @@
+From 80d83b8abe9bc8878ba7a40b4e399b8ea2ff8ad2 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:09 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2301-mtk-sd-Add-subsys-clock-control.patch]
+
+---
+ drivers/mmc/host/mtk-sd.c | 76 +++++++++++++++++++++++++++++----------
+ 1 file changed, 58 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
+index b25e8567f..ef344a4bd 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -33,6 +33,7 @@
@@ -17,7 +29,7 @@
u32 mclk; /* mmc subsystem clock frequency */
u32 src_clk_freq; /* source clock frequency */
unsigned char timing;
-@@ -745,6 +748,7 @@ static void msdc_set_timeout(struct msdc
+@@ -745,6 +748,7 @@ static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
static void msdc_gate_clock(struct msdc_host *host)
{
@@ -25,7 +37,7 @@
clk_disable_unprepare(host->src_clk_cg);
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->bus_clk);
-@@ -753,10 +757,18 @@ static void msdc_gate_clock(struct msdc_
+@@ -753,10 +757,18 @@ static void msdc_gate_clock(struct msdc_host *host)
static void msdc_ungate_clock(struct msdc_host *host)
{
@@ -44,7 +56,7 @@
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
}
-@@ -2195,6 +2207,50 @@ static void msdc_of_property_parse(struc
+@@ -2195,6 +2207,50 @@ static void msdc_of_property_parse(struct platform_device *pdev,
host->hs400_cmd_resp_sel_rising = false;
}
@@ -95,7 +107,7 @@
static int msdc_drv_probe(struct platform_device *pdev)
{
struct mmc_host *mmc;
-@@ -2235,25 +2291,9 @@ static int msdc_drv_probe(struct platfor
+@@ -2235,25 +2291,9 @@ static int msdc_drv_probe(struct platform_device *pdev)
if (ret)
goto host_free;
@@ -123,3 +135,6 @@
host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
"hrst");
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0490-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2330-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch
similarity index 86%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0490-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2330-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch
index 6d2a4b8..42467b6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0490-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2330-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch
@@ -1,3 +1,15 @@
+From 2c71a01b9363f44ca077ec0e27b6a06a15617497 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:14 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2330-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch]
+
+---
+ drivers/mtd/nand/spi/winbond.c | 129 ++++++++++++++++++++++++++++++++-
+ 1 file changed, 127 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
+index 766844283..6473b0367 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -15,6 +15,23 @@
@@ -24,7 +36,7 @@
static SPINAND_OP_VARIANTS(read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
-@@ -31,6 +48,29 @@ static SPINAND_OP_VARIANTS(update_cache_
+@@ -31,6 +48,29 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
SPINAND_PROG_LOAD(false, 0, NULL, 0));
@@ -54,7 +66,7 @@
static int w25m02gv_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *region)
{
-@@ -74,9 +114,61 @@ static int w25m02gv_select_target(struct
+@@ -74,9 +114,61 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
return spi_mem_exec_op(spinand->spimem, &op);
}
@@ -117,7 +129,7 @@
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -85,8 +177,18 @@ static const struct spinand_info winbond
+@@ -85,8 +177,18 @@ static const struct spinand_info winbond_spinand_table[] = {
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
@@ -137,7 +149,7 @@
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(1, 512),
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
-@@ -94,6 +196,29 @@ static const struct spinand_info winbond
+@@ -94,6 +196,29 @@ static const struct spinand_info winbond_spinand_table[] = {
&update_cache_variants),
0,
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
@@ -167,3 +179,6 @@
};
static int winbond_spinand_init(struct spinand_device *spinand)
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2331-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2331-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch
new file mode 100644
index 0000000..b19492b
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2331-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch
@@ -0,0 +1,26 @@
+From 6d8d4dc76ac31cfdecef99c72aad6a65f963d4a0 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:14 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2331-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch]
+
+---
+ drivers/mtd/nand/spi/macronix.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
+index 25319b4f8..d3ae24ecc 100644
+--- a/drivers/mtd/nand/spi/macronix.c
++++ b/drivers/mtd/nand/spi/macronix.c
+@@ -86,7 +86,7 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
+ if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
+ return nand->eccreq.strength;
+
+- if (WARN_ON(eccsr > nand->eccreq.strength || !eccsr))
++ if (eccsr > nand->eccreq.strength || !eccsr)
+ return nand->eccreq.strength;
+
+ return eccsr;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2332-mtd-add-mtk-snand-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2332-mtd-add-mtk-snand-driver.patch
new file mode 100644
index 0000000..a020a2f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2332-mtd-add-mtk-snand-driver.patch
@@ -0,0 +1,38 @@
+From 6fa8802185f08391dd3eb6e0609268e1108a7f57 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:15 +0800
+Subject: [PATCH] [spi-and-storage][999-2332-mtd-add-mtk-snand-driver.patch]
+
+---
+ drivers/mtd/Kconfig | 2 ++
+ drivers/mtd/Makefile | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
+index 3ed42b402..4b6f9d851 100644
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -230,6 +230,8 @@ source "drivers/mtd/hyperbus/Kconfig"
+
+ source "drivers/mtd/nmbm/Kconfig"
+
++source "drivers/mtd/mtk-snand/Kconfig"
++
+ source "drivers/mtd/composite/Kconfig"
+
+ endif # MTD
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index f27f66784..df786f994 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -35,5 +35,7 @@ obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
+
+ obj-y += nmbm/
+
++obj-$(CONFIG_MTK_SPI_NAND) += mtk-snand/
++
+ # Composite drivers must be loaded last
+ obj-y += composite/
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/412-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
similarity index 70%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/412-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
index 32bce58..d37dd56 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/412-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch
@@ -1,6 +1,18 @@
+From 39ee4e9fb5fd3ce678223147df9d9bef0ce822cd Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:15 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch]
+
+---
+ drivers/mtd/nand/spi/gigadevice.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
+index 937a04ce6..ce88f0c91 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -39,6 +39,15 @@ static SPINAND_OP_VARIANTS(read_cache_va
+@@ -39,6 +39,15 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f,
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
@@ -16,7 +28,7 @@
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
SPINAND_PROG_LOAD(true, 0, NULL, 0));
-@@ -265,6 +274,16 @@ static int gd5fxgq4ufxxg_ecc_get_status(
+@@ -236,6 +245,16 @@ static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
}
static const struct spinand_info gigadevice_spinand_table[] = {
@@ -33,7 +45,7 @@
SPINAND_INFO("GD5F1GQ4xA",
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-@@ -337,7 +356,7 @@ static const struct spinand_info gigadev
+@@ -290,7 +309,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
@@ -42,3 +54,6 @@
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/413-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
similarity index 86%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/413-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
index 83e4c71..c609bd7 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/413-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch
@@ -1,6 +1,18 @@
+From b8ffe42101eb8abfb6530396e0c74a85b43eed44 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:15 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch]
+
+---
+ drivers/mtd/nand/spi/gigadevice.c | 98 +++++++++++++++++++++++++++++--
+ 1 file changed, 94 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
+index ce88f0c91..a4e89529d 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -39,8 +39,9 @@ static SPINAND_OP_VARIANTS(read_cache_va
+@@ -39,8 +39,9 @@ static SPINAND_OP_VARIANTS(read_cache_variants_f,
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
@@ -12,7 +24,7 @@
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
-@@ -48,6 +49,15 @@ static SPINAND_OP_VARIANTS(gd5f1gq5_read
+@@ -48,6 +49,15 @@ static SPINAND_OP_VARIANTS(gd5f1gq5_read_cache_variants,
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
@@ -28,7 +40,7 @@
static SPINAND_OP_VARIANTS(write_cache_variants,
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
SPINAND_PROG_LOAD(true, 0, NULL, 0));
-@@ -249,7 +259,7 @@ static const struct spinand_info gigadev
+@@ -249,7 +259,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(8, 512),
@@ -37,7 +49,7 @@
&write_cache_variants,
&update_cache_variants),
0,
-@@ -309,7 +319,87 @@ static const struct spinand_info gigadev
+@@ -309,7 +319,87 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
@@ -126,3 +138,6 @@
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/414-mtd-spinand-fix-gigadevice-read-dummy.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch
similarity index 68%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/414-mtd-spinand-fix-gigadevice-read-dummy.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch
index 5c5af56..977c65c 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/414-mtd-spinand-fix-gigadevice-read-dummy.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch
@@ -1,6 +1,18 @@
+From be41be0e740933fa976ad2990b94ef1e62542a8e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:15 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch]
+
+---
+ drivers/mtd/nand/spi/gigadevice.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
+index a4e89529d..b163ea5dc 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
-@@ -379,7 +379,7 @@ static const struct spinand_info gigadev
+@@ -379,7 +379,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x31),
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
NAND_ECCREQ(4, 512),
@@ -9,7 +21,7 @@
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
-@@ -389,17 +389,17 @@ static const struct spinand_info gigadev
+@@ -389,17 +389,17 @@ static const struct spinand_info gigadevice_spinand_table[] = {
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x32),
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
NAND_ECCREQ(4, 512),
@@ -30,3 +42,6 @@
&write_cache_variants,
&update_cache_variants),
SPINAND_HAS_QE_BIT,
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch
new file mode 100644
index 0000000..644c6b3
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch
@@ -0,0 +1,27 @@
+From c93adec4ad0e8ca47f1a622fb3a5ae445251af36 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:16 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch]
+
+---
+ drivers/mtd/nand/spi/gigadevice.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
+index b163ea5dc..6ee569de2 100644
+--- a/drivers/mtd/nand/spi/gigadevice.c
++++ b/drivers/mtd/nand/spi/gigadevice.c
+@@ -263,8 +263,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+- SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
+- gd5fxgq4xa_ecc_get_status)),
++ SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, NULL)),
+ SPINAND_INFO("GD5F1GQ4xA",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2337-mtd-spinor-support-EN25QX128A.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2337-mtd-spinor-support-EN25QX128A.patch
new file mode 100644
index 0000000..239d246
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2337-mtd-spinor-support-EN25QX128A.patch
@@ -0,0 +1,27 @@
+From 6e915b8dd6ddb6f56ebf23123c26fb90fd5f5198 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:16 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2337-mtd-spinor-support-EN25QX128A.patch]
+
+---
+ drivers/mtd/spi-nor/spi-nor.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
+index 2599bbea8..8d2bc03cd 100644
+--- a/drivers/mtd/spi-nor/spi-nor.c
++++ b/drivers/mtd/spi-nor/spi-nor.c
+@@ -2249,6 +2249,9 @@ static const struct flash_info spi_nor_ids[] = {
+ { "en25qh64", INFO(0x1c7017, 0, 64 * 1024, 128,
+ SECT_4K | SPI_NOR_DUAL_READ) },
+ { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) },
++ { "en25qx128", INFO(0x1c7118, 0, 64 * 1024, 256,
++ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
++ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+ { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) },
+ { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
+
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2338-mtd-tests-fix-pagetest-load.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2338-mtd-tests-fix-pagetest-load.patch
new file mode 100644
index 0000000..776d990
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2338-mtd-tests-fix-pagetest-load.patch
@@ -0,0 +1,56 @@
+From eaa6d1a21a8ea3c68498ef4ff0cf91d109e4d821 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:16 +0800
+Subject: [PATCH] [spi-and-storage][999-2338-mtd-tests-fix-pagetest-load.patch]
+
+---
+ drivers/mtd/tests/pagetest.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c
+index 8eb40b6e6..d1c8a932e 100644
+--- a/drivers/mtd/tests/pagetest.c
++++ b/drivers/mtd/tests/pagetest.c
+@@ -25,6 +25,10 @@ static int dev = -EINVAL;
+ module_param(dev, int, S_IRUGO);
+ MODULE_PARM_DESC(dev, "MTD device number to use");
+
++static int count = 10000;
++module_param(count, int, 0444);
++MODULE_PARM_DESC(count, "Number of operations to do (default is 10000)");
++
+ static struct mtd_info *mtd;
+ static unsigned char *twopages;
+ static unsigned char *writebuf;
+@@ -331,7 +335,7 @@ static int __init mtd_pagetest_init(void)
+ return -EINVAL;
+ }
+
+- pr_info("MTD device: %d\n", dev);
++ pr_info("MTD device: %d count:%d\n", dev, count);
+
+ mtd = get_mtd_device(NULL, dev);
+ if (IS_ERR(mtd)) {
+@@ -376,6 +380,7 @@ static int __init mtd_pagetest_init(void)
+ if (err)
+ goto out;
+
++LOOP:
+ /* Erase all eraseblocks */
+ pr_info("erasing whole device\n");
+ err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt);
+@@ -435,7 +440,10 @@ static int __init mtd_pagetest_init(void)
+ if (err)
+ goto out;
+
+- pr_info("finished with %d errors\n", errcnt);
++ pr_info("finished with %d errors count:%d\n", errcnt, count);
++
++ if (count-- > 0)
++ goto LOOP;
+ out:
+
+ kfree(bbt);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9017-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2339-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch
similarity index 87%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9017-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2339-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch
index 374531b..cf785fe 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9017-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2339-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch
@@ -1,9 +1,9 @@
-From 6bd88d34cb5a5cb1d7c544c9f5b430105b000308 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:39:56 +0800
-Subject: [PATCH] drivers: mtd: spinand: Add calibration support for spinand
+From ddd2951e2f35477a81fb882a976a5a1fe981883d Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:17 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2339-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
drivers/mtd/nand/spi/core.c | 58 +++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
@@ -85,5 +85,5 @@
if (ret)
goto err_free_bufs;
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9018-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2340-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch
similarity index 68%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9018-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2340-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch
index fd1bd1a..b6a4255 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9018-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2340-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch
@@ -1,16 +1,18 @@
-From b242e30661dac5c1c127999600029cd5b3f6b458 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:40:59 +0800
-Subject: [PATCH] drivers: mtd: spi-nor: Add calibration support for spi-nor
+From f392188951839efae7807b6287a62c78d1ed0088 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:17 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2340-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
- drivers/mtd/spi-nor/spi-nor.c | 17 +++++++++++++++++
- 1 file changed, 17 insertions(+)
+ drivers/mtd/spi-nor/spi-nor.c | 40 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
+index 8d2bc03cd..198b57a92 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -4897,6 +4897,35 @@ static void spi_nor_debugfs_init(struct
+@@ -4899,6 +4899,35 @@ static void spi_nor_debugfs_init(struct spi_nor *nor,
info->id_len, info->id);
}
@@ -46,7 +48,7 @@
static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
const char *name)
{
-@@ -4971,6 +5000,17 @@ int spi_nor_scan(struct spi_nor *nor, co
+@@ -4973,6 +5002,17 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
if (!nor->bouncebuf)
return -ENOMEM;
@@ -64,3 +66,6 @@
info = spi_nor_get_flash_info(nor, name);
if (IS_ERR(info))
return PTR_ERR(info);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8004-nvmem-core-Add-functions-to-make-number-reading-easy.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2350-nvmem-core-Add-functions-to-make-number-reading-easy.patch
similarity index 69%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8004-nvmem-core-Add-functions-to-make-number-reading-easy.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2350-nvmem-core-Add-functions-to-make-number-reading-easy.patch
index 969ec3f..a4147dd 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8004-nvmem-core-Add-functions-to-make-number-reading-easy.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2350-nvmem-core-Add-functions-to-make-number-reading-easy.patch
@@ -1,65 +1,16 @@
-From 8dc0b1158dcffd78ea2b3a5604b82ee826de687b Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Mon, 8 Nov 2021 13:58:51 +0800
-Subject: [PATCH 1/5] nvmem: core: Add functions to make number reading easy
+From 21a99150a566b69edc7f3b9bc369bb4525e04acd Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:17 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2350-nvmem-core-Add-functions-to-make-number-reading-easy.patch]
-Sometimes the clients of nvmem just want to get a number out of
-nvmem. They don't want to think about exactly how many bytes the nvmem
-cell took up. They just want the number. Let's make it easy.
-
-In general this concept is useful because nvmem space is precious and
-usually the fewest bits are allocated that will hold a given value on
-a given system. However, even though small numbers might be fine on
-one system that doesn't mean that logically the number couldn't be
-bigger. Imagine nvmem containing a max frequency for a component. On
-one system perhaps that fits in 16 bits. On another system it might
-fit in 32 bits. The code reading this number doesn't care--it just
-wants the number.
-
-We'll provide two functions: nvmem_cell_read_variable_le_u32() and
-nvmem_cell_read_variable_le_u64().
-
-Comparing these to the existing functions like nvmem_cell_read_u32():
-* These new functions have no problems if the value was stored in
- nvmem in fewer bytes. It's OK to use these function as long as the
- value stored will fit in 32-bits (or 64-bits).
-* These functions avoid problems that the earlier APIs had with bit
- offsets. For instance, you can't use nvmem_cell_read_u32() to read a
- value has nbits=32 and bit_offset=4 because the nvmem cell must be
- at least 5 bytes big to hold this value. The new API accounts for
- this and works fine.
-* These functions make it very explicit that they assume that the
- number was stored in little endian format. The old functions made
- this assumption whenever bit_offset was non-zero (see
- nvmem_shift_read_buffer_in_place()) but didn't whenever the
- bit_offset was zero.
-
-NOTE: it's assumed that we don't need an 8-bit or 16-bit version of
-this function. The 32-bit version of the function can be used to read
-8-bit or 16-bit data.
-
-At the moment, I'm only adding the "unsigned" versions of these
-functions, but if it ends up being useful someone could add a "signed"
-version that did 2's complement sign extension.
-
-At the moment, I'm only adding the "little endian" versions of these
-functions. Adding the "big endian" version would require adding "big
-endian" support to nvmem_shift_read_buffer_in_place().
-
-Signed-off-by: Douglas Anderson <dianders@chromium.org>
-Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20210330111241.19401-7-srinivas.kandagatla@linaro.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Change-Id: I3e1d96ec1680812d5e24681c79852c9b36899559
---
drivers/nvmem/core.c | 161 +++++++++++++++++++++++++++------
include/linux/nvmem-consumer.h | 15 +++
2 files changed, 150 insertions(+), 26 deletions(-)
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
-index c0f4324d8f7c..e26b25b5c288 100644
+index 19ac0d055..f65305b6d 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1102,16 +1102,8 @@ int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len)
@@ -270,10 +221,10 @@
/**
* nvmem_device_cell_read() - Read a given nvmem device and cell
diff --git a/include/linux/nvmem-consumer.h b/include/linux/nvmem-consumer.h
-index 5c17cb733224..e328c0f7eef3 100644
+index 0f490b288..227b93158 100644
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
-@@ -63,6 +63,10 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len);
+@@ -64,6 +64,10 @@ void *nvmem_cell_read(struct nvmem_cell *cell, size_t *len);
int nvmem_cell_write(struct nvmem_cell *cell, void *buf, size_t len);
int nvmem_cell_read_u16(struct device *dev, const char *cell_id, u16 *val);
int nvmem_cell_read_u32(struct device *dev, const char *cell_id, u32 *val);
@@ -284,7 +235,7 @@
/* direct nvmem device read/write interface */
struct nvmem_device *nvmem_device_get(struct device *dev, const char *name);
-@@ -134,6 +138,17 @@ static inline int nvmem_cell_read_u32(struct device *dev,
+@@ -135,6 +139,17 @@ static inline int nvmem_cell_read_u32(struct device *dev,
{
return -EOPNOTSUPP;
}
@@ -303,5 +254,5 @@
static inline struct nvmem_device *nvmem_device_get(struct device *dev,
const char *name)
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8005-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2351-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
similarity index 62%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8005-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2351-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
index 8de4c2a..c042918 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8005-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2351-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch
@@ -1,21 +1,15 @@
-From 44ae4ed142265a6d50a9d3e6f4c395f97b6849ab Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Sat, 6 Nov 2021 20:06:30 +0800
-Subject: [PATCH 2/5] nvmem: mtk-efuse: support minimum one byte access stride
- and granularity
+From 6b7498e172d4458499a3ba406bf7975478f46d21 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:17 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2351-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch]
-In order to support nvmem bits property, should support minimum 1 byte
-read stride and minimum 1 byte read granularity at the same time.
-
-Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Change-Id: Iafe1ebf195d58a3e9e3518913f795d14a01dfd3b
---
drivers/nvmem/mtk-efuse.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/nvmem/mtk-efuse.c b/drivers/nvmem/mtk-efuse.c
-index 856d9c3fc38e..2e728fed0b49 100644
+index 856d9c3fc..2e728fed0 100644
--- a/drivers/nvmem/mtk-efuse.c
+++ b/drivers/nvmem/mtk-efuse.c
@@ -19,11 +19,12 @@ static int mtk_reg_read(void *context,
@@ -47,5 +41,5 @@
econfig.reg_write = mtk_reg_write;
econfig.size = resource_size(res);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0666-add-spimem-support-to-mtk-spi.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2361-add-spimem-support-to-mtk-spi.patch
similarity index 94%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0666-add-spimem-support-to-mtk-spi.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2361-add-spimem-support-to-mtk-spi.patch
index d50aa25..2d2aeaa 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0666-add-spimem-support-to-mtk-spi.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2361-add-spimem-support-to-mtk-spi.patch
@@ -1,21 +1,16 @@
-From 675b477b2a50b2fb97f35944756f89644bf70092 Mon Sep 17 00:00:00 2001
-From: Qii Wang <qii.wang@mediatek.com>
-Date: Tue, 5 Jan 2021 16:48:39 +0800
-Subject: [PATCH] spi: mediatek: support IPM Design
+From 85e3059aee9943eddfd2b7c9fc83481751005c09 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:18 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2361-add-spimem-support-to-mtk-spi.patch]
-[Description]
-1. support sigle mode;
-2. support dual/quad mode with spi-mem framework.
-
-Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
-Reviewed-by: Qii Wang <qii.wang@mediatek.com>
---
drivers/spi/spi-mt65xx.c | 395 +++++++++++++++++++++--
include/linux/platform_data/spi-mt65xx.h | 2 +-
2 files changed, 370 insertions(+), 27 deletions(-)
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
-index 8acf24f7c..9183c64e4 100644
+index 29d44f5d5..dbb471769 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -17,6 +17,7 @@
@@ -282,8 +277,8 @@
+ mtk_spi_prepare_transfer(master, xfer->speed_hz);
mtk_spi_setup_packet(master);
- cnt = xfer->len / 4;
-@@ -455,7 +553,7 @@ static int mtk_spi_dma_transfer(struct spi_master *master,
+ if (xfer->tx_buf) {
+@@ -456,7 +554,7 @@ static int mtk_spi_dma_transfer(struct spi_master *master,
mdata->cur_transfer = xfer;
mdata->num_xfered = 0;
@@ -292,7 +287,7 @@
cmd = readl(mdata->base + SPI_CMD_REG);
if (xfer->tx_buf)
-@@ -532,6 +630,13 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
+@@ -533,6 +631,13 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
else
mdata->state = MTK_SPI_IDLE;
@@ -306,7 +301,7 @@
if (!master->can_dma(master, NULL, trans)) {
if (trans->rx_buf) {
cnt = mdata->xfer_len / 4;
-@@ -615,12 +720,241 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
+@@ -616,12 +721,241 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
@@ -549,7 +544,7 @@
int i, irq, ret, addr_bits;
master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
-@@ -629,7 +963,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -630,7 +964,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
return -ENOMEM;
}
@@ -558,7 +553,7 @@
master->dev.of_node = pdev->dev.of_node;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
-@@ -648,9 +982,25 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -649,9 +983,25 @@ static int mtk_spi_probe(struct platform_device *pdev)
mdata = spi_master_get_devdata(master);
mdata->dev_comp = of_id->data;
@@ -584,7 +579,7 @@
if (mdata->dev_comp->need_pad_sel) {
mdata->pad_num = of_property_count_u32_elems(
pdev->dev.of_node,
-@@ -683,15 +1033,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -684,15 +1034,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
}
platform_set_drvdata(pdev, master);
@@ -601,7 +596,7 @@
if (IS_ERR(mdata->base)) {
ret = PTR_ERR(mdata->base);
goto err_put_master;
-@@ -713,6 +1055,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -714,6 +1056,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master;
}
@@ -609,7 +604,7 @@
mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
if (IS_ERR(mdata->parent_clk)) {
ret = PTR_ERR(mdata->parent_clk);
-@@ -750,7 +1093,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -751,7 +1094,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
clk_disable_unprepare(mdata->spi_clk);
pm_runtime_enable(&pdev->dev);
@@ -632,5 +627,5 @@
};
#endif
--
-2.17.1
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2362-spi-mtk-nor-fix-timeout-calculation-overflow.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2362-spi-mtk-nor-fix-timeout-calculation-overflow.patch
new file mode 100644
index 0000000..d7f7d9b
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2362-spi-mtk-nor-fix-timeout-calculation-overflow.patch
@@ -0,0 +1,37 @@
+From 2231dfcbcffef50846a9c240651c62771d7e33b0 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:18 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2362-spi-mtk-nor-fix-timeout-calculation-overflow.patch]
+
+---
+ drivers/spi/spi-mtk-nor.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
+index c15a99105..4f72f08c0 100644
+--- a/drivers/spi/spi-mtk-nor.c
++++ b/drivers/spi/spi-mtk-nor.c
+@@ -89,7 +89,7 @@
+ // Buffered page program can do one 128-byte transfer
+ #define MTK_NOR_PP_SIZE 128
+
+-#define CLK_TO_US(sp, clkcnt) ((clkcnt) * 1000000 / sp->spi_freq)
++#define CLK_TO_US(sp, clkcnt) DIV_ROUND_UP(clkcnt, sp->spi_freq / 1000000)
+
+ struct mtk_nor {
+ struct spi_controller *ctlr;
+@@ -177,6 +177,10 @@ static int mtk_nor_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+ if ((op->addr.nbytes == 3) || (op->addr.nbytes == 4)) {
+ if ((op->data.dir == SPI_MEM_DATA_IN) &&
+ mtk_nor_match_read(op)) {
++ // limit size to prevent timeout calculation overflow
++ if (op->data.nbytes > 0x400000)
++ op->data.nbytes = 0x400000;
++
+ if ((op->addr.val & MTK_NOR_DMA_ALIGN_MASK) ||
+ (op->data.nbytes < MTK_NOR_DMA_ALIGN))
+ op->data.nbytes = 1;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2363-spi-mediatek-fix-timeout-for-large-data.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2363-spi-mediatek-fix-timeout-for-large-data.patch
new file mode 100644
index 0000000..2a05ef3
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2363-spi-mediatek-fix-timeout-for-large-data.patch
@@ -0,0 +1,49 @@
+From 8efe8045522d7bd790b9ae7408c64f497a54e643 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:18 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2363-spi-mediatek-fix-timeout-for-large-data.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index dbb471769..871eff03f 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -721,6 +721,23 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
+ return IRQ_HANDLED;
+ }
+
++static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
++ struct spi_mem_op *op)
++{
++ int opcode_len;
++
++ if(!op->data.nbytes)
++ return 0;
++
++ if (op->data.dir != SPI_MEM_NO_DATA) {
++ opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
++ if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE)
++ op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE -opcode_len;
++ }
++
++ return 0;
++}
++
+ static bool mtk_spi_mem_supports_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+ {
+@@ -947,6 +964,7 @@ err_exit:
+ }
+
+ static const struct spi_controller_mem_ops mtk_spi_mem_ops = {
++ .adjust_op_size = mtk_spi_mem_adjust_op_size,
+ .supports_op = mtk_spi_mem_supports_op,
+ .exec_op = mtk_spi_mem_exec_op,
+ };
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2364-spi-mediatek-fix-dma-unmap-twice.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2364-spi-mediatek-fix-dma-unmap-twice.patch
new file mode 100644
index 0000000..997e16f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2364-spi-mediatek-fix-dma-unmap-twice.patch
@@ -0,0 +1,31 @@
+From 548735b3ae97333e3630febcf15298304aa42dcf Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:19 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2364-spi-mediatek-fix-dma-unmap-twice.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 871eff03f..3a8f67f1e 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -947,12 +947,10 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
+ reg_val &= ~SPI_CMD_RX_DMA;
+ writel(reg_val, mdata->base + SPI_CMD_REG);
+
++unmap_rx_dma:
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ dma_unmap_single(mdata->dev, mdata->rx_dma,
+ op->data.nbytes, DMA_FROM_DEVICE);
+-unmap_rx_dma:
+- dma_unmap_single(mdata->dev, mdata->rx_dma,
+- op->data.nbytes, DMA_FROM_DEVICE);
+ unmap_tx_dma:
+ dma_unmap_single(mdata->dev, mdata->tx_dma,
+ tx_size, DMA_TO_DEVICE);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2365-fix-SPIM-NAND-and-NOR-probing.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2365-fix-SPIM-NAND-and-NOR-probing.patch
new file mode 100644
index 0000000..02e460a
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2365-fix-SPIM-NAND-and-NOR-probing.patch
@@ -0,0 +1,48 @@
+From 1a41f923f66c03c40e6703dd69f8bfbe2791ce70 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:19 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2365-fix-SPIM-NAND-and-NOR-probing.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 3a8f67f1e..05697e1d1 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1072,7 +1072,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+ goto err_put_master;
+ }
+
+-/*
++
+ mdata->parent_clk = devm_clk_get(&pdev->dev, "parent-clk");
+ if (IS_ERR(mdata->parent_clk)) {
+ ret = PTR_ERR(mdata->parent_clk);
+@@ -1100,17 +1100,17 @@ static int mtk_spi_probe(struct platform_device *pdev)
+ goto err_put_master;
+ }
+
+- ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
++ /*ret = clk_set_parent(mdata->sel_clk, mdata->parent_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to clk_set_parent (%d)\n", ret);
+ clk_disable_unprepare(mdata->spi_clk);
+ goto err_put_master;
+ }
+
+- clk_disable_unprepare(mdata->spi_clk);
++ clk_disable_unprepare(mdata->sel_clk);*/
++
++ //pm_runtime_enable(&pdev->dev);
+
+- pm_runtime_enable(&pdev->dev);
+-*/
+ ret = devm_spi_register_master(&pdev->dev, master);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register master (%d)\n", ret);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0670-fix-SPIM-dma-buffer-not-aligned.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2366-fix-SPIM-dma-buffer-not-aligned.patch
similarity index 68%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0670-fix-SPIM-dma-buffer-not-aligned.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2366-fix-SPIM-dma-buffer-not-aligned.patch
index d4534e7..fed7675 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0670-fix-SPIM-dma-buffer-not-aligned.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2366-fix-SPIM-dma-buffer-not-aligned.patch
@@ -1,6 +1,18 @@
+From 475f064022a716bda4574406d8365627c3bcf131 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:19 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2366-fix-SPIM-dma-buffer-not-aligned.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 33 +++++++++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 05697e1d1..2883dc908 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
-@@ -184,7 +184,7 @@ static const struct mtk_spi_compatible m
+@@ -184,7 +184,7 @@ static const struct mtk_spi_compatible mt8183_compat = {
*/
static const struct mtk_chip_config mtk_default_chip_info = {
.sample_sel = 0,
@@ -9,7 +21,7 @@
};
static const struct of_device_id mtk_spi_of_match[] = {
-@@ -730,8 +730,11 @@ static int mtk_spi_mem_adjust_op_size(st
+@@ -731,8 +731,11 @@ static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
if (op->data.dir != SPI_MEM_NO_DATA) {
opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
@@ -22,7 +34,7 @@
}
return 0;
-@@ -758,10 +761,6 @@ static bool mtk_spi_mem_supports_op(stru
+@@ -759,10 +762,6 @@ static bool mtk_spi_mem_supports_op(struct spi_mem *mem,
return false;
}
@@ -33,7 +45,7 @@
return true;
}
-@@ -820,6 +819,7 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -821,6 +820,7 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
struct mtk_spi *mdata = spi_master_get_devdata(mem->spi->master);
u32 reg_val, nio = 1, tx_size;
char *tx_tmp_buf;
@@ -41,7 +53,7 @@
int ret = 0;
mdata->use_spimem = true;
-@@ -914,10 +914,18 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -915,10 +915,18 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
}
if (op->data.dir == SPI_MEM_DATA_IN) {
@@ -63,7 +75,7 @@
if (dma_mapping_error(mdata->dev, mdata->rx_dma)) {
ret = -ENOMEM;
goto unmap_tx_dma;
-@@ -947,9 +955,14 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -948,9 +956,14 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
writel(reg_val, mdata->base + SPI_CMD_REG);
unmap_rx_dma:
@@ -79,3 +91,6 @@
unmap_tx_dma:
dma_unmap_single(mdata->dev, mdata->tx_dma,
tx_size, DMA_TO_DEVICE);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2367-fix-mtk-nfi-driver-dependency.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2367-fix-mtk-nfi-driver-dependency.patch
new file mode 100644
index 0000000..9ef3678
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2367-fix-mtk-nfi-driver-dependency.patch
@@ -0,0 +1,25 @@
+From 8a165fdcdddc69e2bc048636695521d5b6966ff7 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:19 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2367-fix-mtk-nfi-driver-dependency.patch]
+
+---
+ drivers/spi/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index b26bf6b46..4b97ca45c 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -429,6 +429,7 @@ config SPI_MT65XX
+
+ config SPI_MTK_SNFI
+ tristate "MediaTek SPI NAND interface"
++ depends on MTD
+ select MTD_SPI_NAND
+ help
+ This selects the SPI NAND FLASH interface(SNFI),
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2368-kernel-MT7988-fix-spi-dma-unmap.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2368-kernel-MT7988-fix-spi-dma-unmap.patch
new file mode 100644
index 0000000..4774cb3
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2368-kernel-MT7988-fix-spi-dma-unmap.patch
@@ -0,0 +1,32 @@
+From f715b301cff26297a1f4af71e6982de3d56673dd Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:20 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2368-kernel-MT7988-fix-spi-dma-unmap.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 2883dc908..b03257132 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -957,12 +957,12 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
+
+ unmap_rx_dma:
+ if (op->data.dir == SPI_MEM_DATA_IN) {
++ dma_unmap_single(mdata->dev, mdata->rx_dma,
++ op->data.nbytes, DMA_FROM_DEVICE);
+ if(!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
+ memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes);
+ kfree(rx_tmp_buf);
+ }
+- dma_unmap_single(mdata->dev, mdata->rx_dma,
+- op->data.nbytes, DMA_FROM_DEVICE);
+ }
+ unmap_tx_dma:
+ dma_unmap_single(mdata->dev, mdata->tx_dma,
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9009-Add-spi-runtime-PM-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2369-Add-spi-runtime-PM-support.patch
similarity index 84%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9009-Add-spi-runtime-PM-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2369-Add-spi-runtime-PM-support.patch
index 8371b57..92dbb42 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9009-Add-spi-runtime-PM-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2369-Add-spi-runtime-PM-support.patch
@@ -1,22 +1,14 @@
-From 0c1e4af01506c913cc54e63f66bb5470f50790c7 Mon Sep 17 00:00:00 2001
-From: Leilk Liu <leilk.liu@mediatek.com>
-Date: Tue, 13 Jul 2021 21:45:59 +0800
-Subject: [PATCH] [Add spi runtime PM support]
+From c8ea5f2bbc2ece3efcb7b8c704a7bee4c5f7adef Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:20 +0800
+Subject: [PATCH] [spi-and-storage][999-2369-Add-spi-runtime-PM-support.patch]
-[Description]
-Add ahb clk and enable runtime pm
-
-[Release-log]
-N/A
-
-Change-Id: I0529f6e829f5fc4c5880508971c97b9434820340
-Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
---
drivers/spi/spi-mt65xx.c | 77 ++++++++++++++++++++++++++++++++++------
1 file changed, 67 insertions(+), 10 deletions(-)
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
-index 7e54984..ff2d825 100644
+index b03257132..7c3ee3381 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -119,6 +119,8 @@ struct mtk_spi_compatible {
@@ -74,7 +66,7 @@
},
{ .compatible = "mediatek,mt2701-spi",
.data = (void *)&mtk_common_compat,
-@@ -992,7 +1006,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -993,7 +1007,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
return -ENOMEM;
}
@@ -83,7 +75,7 @@
master->dev.of_node = pdev->dev.of_node;
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
-@@ -1106,22 +1120,40 @@ static int mtk_spi_probe(struct platform_device *pdev)
+@@ -1107,22 +1121,40 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master;
}
@@ -127,7 +119,7 @@
ret = devm_spi_register_master(&pdev->dev, master);
if (ret) {
-@@ -1201,8 +1233,11 @@ static int mtk_spi_suspend(struct device *dev)
+@@ -1202,8 +1234,11 @@ static int mtk_spi_suspend(struct device *dev)
if (ret)
return ret;
@@ -140,7 +132,7 @@
return ret;
}
-@@ -1214,6 +1249,14 @@ static int mtk_spi_resume(struct device *dev)
+@@ -1215,6 +1250,14 @@ static int mtk_spi_resume(struct device *dev)
struct mtk_spi *mdata = spi_master_get_devdata(master);
if (!pm_runtime_suspended(dev)) {
@@ -155,7 +147,7 @@
ret = clk_prepare_enable(mdata->spi_clk);
if (ret < 0) {
dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
-@@ -1222,8 +1265,11 @@ static int mtk_spi_resume(struct device *dev)
+@@ -1223,8 +1266,11 @@ static int mtk_spi_resume(struct device *dev)
}
ret = spi_master_resume(master);
@@ -168,7 +160,7 @@
return ret;
}
-@@ -1237,6 +1283,9 @@ static int mtk_spi_runtime_suspend(struct device *dev)
+@@ -1238,6 +1284,9 @@ static int mtk_spi_runtime_suspend(struct device *dev)
clk_disable_unprepare(mdata->spi_clk);
@@ -178,7 +170,7 @@
return 0;
}
-@@ -1246,6 +1295,14 @@ static int mtk_spi_runtime_resume(struct device *dev)
+@@ -1247,6 +1296,14 @@ static int mtk_spi_runtime_resume(struct device *dev)
struct mtk_spi *mdata = spi_master_get_devdata(master);
int ret;
@@ -194,5 +186,5 @@
if (ret < 0) {
dev_err(dev, "failed to enable spi_clk (%d)\n", ret);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9011-Modify-tick_delay-for-spi-work-safety.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2370-Modify-tick_delay-for-spi-work-safety.patch
similarity index 64%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9011-Modify-tick_delay-for-spi-work-safety.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2370-Modify-tick_delay-for-spi-work-safety.patch
index dd73f82..7adee7d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9011-Modify-tick_delay-for-spi-work-safety.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2370-Modify-tick_delay-for-spi-work-safety.patch
@@ -1,14 +1,15 @@
-From 02205bef8a645d4374d2869e3a5a5a1d7c2e693a Mon Sep 17 00:00:00 2001
-From: Qii Wang <qii.wang@mediatek.com>
-Date: Sat, 14 May 2022 14:18:13 +0800
-Subject: [PATCH] [Modify tick_delay for spi work safety]
+From adcc9739e6457df20339161299cf267de9699a2e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:20 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2370-Modify-tick_delay-for-spi-work-safety.patch]
---
drivers/spi/spi-mt65xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
-index bef03bd8c..c19e2d4d7 100644
+index 7c3ee3381..83a2417a8 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -195,7 +195,7 @@ static const struct mtk_spi_compatible mt8183_compat = {
@@ -21,5 +22,5 @@
static const struct of_device_id mtk_spi_of_match[] = {
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9013-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2371-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch
similarity index 92%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9013-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2371-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch
index d64f376..47611e5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9013-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2371-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch
@@ -1,10 +1,9 @@
-From 45ec6dfcc5f48127d5bd440fb615bbf48f3fc9c1 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:29:51 +0800
-Subject: [PATCH] drivers: spi-mt65xx: Move chip_config to driver's private
- data
+From 8fc345d6238b0fb81f6737d21ca9d7efb1dd1489 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:20 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2371-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
drivers/spi/spi-mt65xx.c | 31 +++++++++++-------------
include/linux/platform_data/spi-mt65xx.h | 17 -------------
@@ -12,7 +11,7 @@
delete mode 100644 include/linux/platform_data/spi-mt65xx.h
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
-index c19e2d4d7..0afd00891 100644
+index 83a2417a8..32a0b0264 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -14,7 +14,6 @@
@@ -138,5 +137,5 @@
-};
-#endif
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch
similarity index 87%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch
index 750c87b..d438084 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9014-drivers-spi-Add-support-for-dynamic-calibration.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch
@@ -1,17 +1,19 @@
-From a84c53fce4ccd67c147dcbb2dcf4fdeceab05981 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:35:52 +0800
-Subject: [PATCH] drivers: spi: Add support for dynamic calibration
+From a7d7d3c4d6a949135a34dff1e987a52de9f227b7 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:21 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
- drivers/spi/spi.c | 137 ++++++++++++++++++++++++++++++++++++++++
+ drivers/spi/spi.c | 141 ++++++++++++++++++++++++++++++++++++++++
include/linux/spi/spi.h | 42 ++++++++++++
- 2 files changed, 179 insertions(+)
+ 2 files changed, 183 insertions(+)
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index e562735a3..28bad4a8b 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
-@@ -1109,6 +1109,74 @@ static int spi_transfer_wait(struct spi_
+@@ -1109,6 +1109,74 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
return 0;
}
@@ -86,7 +88,7 @@
static void _spi_transfer_delay_ns(u32 ns)
{
if (!ns)
-@@ -1720,6 +1788,75 @@ void spi_flush_queue(struct spi_controll
+@@ -1720,6 +1788,75 @@ void spi_flush_queue(struct spi_controller *ctlr)
/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OF)
@@ -162,7 +164,7 @@
static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
struct device_node *nc)
{
-@@ -1841,6 +1978,10 @@ of_register_spi_device(struct spi_contro
+@@ -1841,6 +1978,10 @@ of_register_spi_device(struct spi_controller *ctlr, struct device_node *nc)
if (rc)
goto err_out;
@@ -173,6 +175,8 @@
/* Store a pointer to the node in the device structure */
of_node_get(nc);
spi->dev.of_node = nc;
+diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
+index 7067f85ce..5330cd9b0 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -264,6 +264,40 @@ struct spi_driver {
@@ -228,7 +232,7 @@
int (*fw_translate_cs)(struct spi_controller *ctlr, unsigned cs);
};
-@@ -1369,6 +1408,9 @@ spi_register_board_info(struct spi_board
+@@ -1369,6 +1408,9 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n)
{ return 0; }
#endif
@@ -238,3 +242,6 @@
/* If you're hotplugging an adapter with devices (parport, usb, etc)
* use spi_new_device() to describe each device. You can also call
* spi_unregister_device() to start making that device vanish, but
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9015-drivers-spi-mem-Add-spi-calibration-hook.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2373-drivers-spi-mem-Add-spi-calibration-hook.patch
similarity index 82%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9015-drivers-spi-mem-Add-spi-calibration-hook.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2373-drivers-spi-mem-Add-spi-calibration-hook.patch
index dcea7de..c16f87e 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9015-drivers-spi-mem-Add-spi-calibration-hook.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2373-drivers-spi-mem-Add-spi-calibration-hook.patch
@@ -1,9 +1,9 @@
-From a4f235c3a3c4d25aa6a4417ce64831ca0b38c324 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:37:55 +0800
-Subject: [PATCH] drivers: spi-mem: Add spi calibration hook
+From 945b61ae2d00d59eacebb70496ce9bc530767929 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:21 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2373-drivers-spi-mem-Add-spi-calibration-hook.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
drivers/spi/spi-mem.c | 8 ++++++++
include/linux/spi/spi-mem.h | 4 ++++
@@ -44,5 +44,5 @@
struct spi_mem_dirmap_desc *
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9016-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2374-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch
similarity index 78%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9016-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2374-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch
index 2c51aa9..f39b229 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9016-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2374-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch
@@ -1,15 +1,15 @@
-From ac9ed3898b80a81ce220a682749767ef189094a8 Mon Sep 17 00:00:00 2001
-From: "SkyLake.Huang" <skylake.huang@mediatek.com>
-Date: Thu, 23 Jun 2022 18:39:03 +0800
-Subject: [PATCH] drivers: spi-mt65xx: Add controller's calibration paramter
+From 6411311c9df3bce87ad46650053eb52cf12be889 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:21 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2374-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch]
-Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
drivers/spi/spi-mt65xx.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
-index 0afd00891..1b272d15c 100644
+index 32a0b0264..2034d1979 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -727,6 +727,21 @@ static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
@@ -44,5 +44,5 @@
if (!of_id) {
dev_err(&pdev->dev, "failed to probe of_node\n");
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9102-spi-update-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2375-spi-update-driver.patch
similarity index 91%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9102-spi-update-driver.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2375-spi-update-driver.patch
index 4900733..48e7187 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9102-spi-update-driver.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2375-spi-update-driver.patch
@@ -1,3 +1,14 @@
+From f8707b14c517f9402456c3c1e98f64d0eb8a4af5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:21 +0800
+Subject: [PATCH] [spi-and-storage][999-2375-spi-update-driver.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 414 ++++++++++++++++++++++-----------------
+ 1 file changed, 231 insertions(+), 183 deletions(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index 2034d1979..b80f8dcd9 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -12,7 +12,7 @@
@@ -71,7 +82,7 @@
struct completion spimem_done;
bool use_spimem;
struct device *dev;
-@@ -154,21 +152,10 @@ static const struct mtk_spi_compatible m
+@@ -154,21 +152,10 @@ static const struct mtk_spi_compatible mt2712_compat = {
.must_tx = true,
};
@@ -94,7 +105,7 @@
};
static const struct mtk_spi_compatible mt6765_compat = {
-@@ -194,13 +181,25 @@ static const struct mtk_spi_compatible m
+@@ -194,13 +181,25 @@ static const struct mtk_spi_compatible mt8183_compat = {
.enhance_timing = true,
};
@@ -122,7 +133,7 @@
{ .compatible = "mediatek,mt2701-spi",
.data = (void *)&mtk_common_compat,
},
-@@ -228,6 +227,12 @@ static const struct of_device_id mtk_spi
+@@ -228,6 +227,12 @@ static const struct of_device_id mtk_spi_of_match[] = {
{ .compatible = "mediatek,mt8183-spi",
.data = (void *)&mt8183_compat,
},
@@ -135,7 +146,7 @@
{}
};
MODULE_DEVICE_TABLE(of, mtk_spi_of_match);
-@@ -256,27 +261,30 @@ static int mtk_spi_hw_init(struct spi_ma
+@@ -256,27 +261,30 @@ static int mtk_spi_hw_init(struct spi_master *master,
cpha = spi->mode & SPI_CPHA ? 1 : 0;
cpol = spi->mode & SPI_CPOL ? 1 : 0;
@@ -176,7 +187,7 @@
reg_val = readl(mdata->base + SPI_CMD_REG);
if (mdata->dev_comp->ipm_design) {
/* SPI transfer without idle time until packet length done */
-@@ -375,12 +383,11 @@ static void mtk_spi_set_cs(struct spi_de
+@@ -375,12 +383,11 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable)
static void mtk_spi_prepare_transfer(struct spi_master *master,
u32 speed_hz)
{
@@ -192,7 +203,7 @@
else
div = 1;
-@@ -388,13 +395,19 @@ static void mtk_spi_prepare_transfer(str
+@@ -388,13 +395,19 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
cs_time = sck_time * 2;
if (mdata->dev_comp->enhance_timing) {
@@ -214,7 +225,7 @@
reg_val |= (((cs_time - 1) & 0xffff)
<< SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
writel(reg_val, mdata->base + SPI_CFG0_REG);
-@@ -453,14 +466,17 @@ static void mtk_spi_enable_transfer(stru
+@@ -453,14 +466,17 @@ static void mtk_spi_enable_transfer(struct spi_master *master)
writel(cmd, mdata->base + SPI_CMD_REG);
}
@@ -238,7 +249,7 @@
return mult_delta;
}
-@@ -472,22 +488,22 @@ static void mtk_spi_update_mdata_len(str
+@@ -472,22 +488,22 @@ static void mtk_spi_update_mdata_len(struct spi_master *master)
if (mdata->tx_sgl_len && mdata->rx_sgl_len) {
if (mdata->tx_sgl_len > mdata->rx_sgl_len) {
@@ -265,7 +276,7 @@
mdata->xfer_len = mdata->rx_sgl_len - mult_delta;
mdata->rx_sgl_len = mult_delta;
}
-@@ -598,6 +614,19 @@ static int mtk_spi_transfer_one(struct s
+@@ -598,6 +614,19 @@ static int mtk_spi_transfer_one(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *xfer)
{
@@ -285,7 +296,7 @@
if (master->can_dma(master, spi, xfer))
return mtk_spi_dma_transfer(master, spi, xfer);
else
-@@ -618,8 +647,9 @@ static int mtk_spi_setup(struct spi_devi
+@@ -618,8 +647,9 @@ static int mtk_spi_setup(struct spi_device *spi)
{
struct mtk_spi *mdata = spi_master_get_devdata(spi->master);
@@ -297,7 +308,7 @@
return 0;
}
-@@ -747,9 +777,6 @@ static int mtk_spi_mem_adjust_op_size(st
+@@ -747,9 +777,6 @@ static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
{
int opcode_len;
@@ -307,7 +318,7 @@
if (op->data.dir != SPI_MEM_NO_DATA) {
opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes;
if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) {
-@@ -765,8 +792,7 @@ static int mtk_spi_mem_adjust_op_size(st
+@@ -765,8 +792,7 @@ static int mtk_spi_mem_adjust_op_size(struct spi_mem *mem,
static bool mtk_spi_mem_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
@@ -317,7 +328,7 @@
return false;
if (op->addr.nbytes && op->dummy.nbytes &&
-@@ -814,13 +840,18 @@ static int mtk_spi_transfer_wait(struct
+@@ -814,13 +840,18 @@ static int mtk_spi_transfer_wait(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct mtk_spi *mdata = spi_master_get_devdata(mem->spi->master);
@@ -340,7 +351,7 @@
ms += ms + 1000; /* 1s tolerance */
if (ms > UINT_MAX)
-@@ -839,9 +870,8 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -839,9 +870,8 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct mtk_spi *mdata = spi_master_get_devdata(mem->spi->master);
@@ -352,7 +363,7 @@
int ret = 0;
mdata->use_spimem = true;
-@@ -887,9 +917,11 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -887,9 +917,11 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
op->dummy.buswidth == 4 ||
op->data.buswidth == 4)
nio = 4;
@@ -365,7 +376,7 @@
reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN;
if (op->data.dir == SPI_MEM_DATA_IN)
-@@ -902,11 +934,13 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -902,11 +934,13 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
if (op->data.dir == SPI_MEM_DATA_OUT)
tx_size += op->data.nbytes;
@@ -381,7 +392,7 @@
tx_tmp_buf[0] = op->cmd.opcode;
-@@ -937,12 +971,15 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -937,12 +971,15 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
if (op->data.dir == SPI_MEM_DATA_IN) {
if(!IS_ALIGNED((size_t)op->data.buf.in, 4)) {
@@ -402,7 +413,7 @@
mdata->rx_dma = dma_map_single(mdata->dev,
rx_tmp_buf,
-@@ -950,7 +987,7 @@ static int mtk_spi_mem_exec_op(struct sp
+@@ -950,7 +987,7 @@ static int mtk_spi_mem_exec_op(struct spi_mem *mem,
DMA_FROM_DEVICE);
if (dma_mapping_error(mdata->dev, mdata->rx_dma)) {
ret = -ENOMEM;
@@ -428,7 +439,7 @@
unmap_tx_dma:
dma_unmap_single(mdata->dev, mdata->tx_dma,
tx_size, DMA_TO_DEVICE);
-@@ -1003,19 +1042,19 @@ static const struct spi_controller_mem_o
+@@ -1003,19 +1042,19 @@ static const struct spi_controller_mem_ops mtk_spi_mem_ops = {
static int mtk_spi_probe(struct platform_device *pdev)
{
@@ -452,7 +463,7 @@
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
master->set_cs = mtk_spi_set_cs;
-@@ -1023,23 +1062,16 @@ static int mtk_spi_probe(struct platform
+@@ -1023,23 +1062,16 @@ static int mtk_spi_probe(struct platform_device *pdev)
master->transfer_one = mtk_spi_transfer_one;
master->can_dma = mtk_spi_can_dma;
master->setup = mtk_spi_setup;
@@ -478,7 +489,7 @@
if (mdata->dev_comp->enhance_timing)
master->mode_bits |= SPI_CS_HIGH;
-@@ -1050,27 +1082,23 @@ static int mtk_spi_probe(struct platform
+@@ -1050,27 +1082,23 @@ static int mtk_spi_probe(struct platform_device *pdev)
if (mdata->dev_comp->ipm_design)
master->mode_bits |= SPI_LOOP;
@@ -511,7 +522,7 @@
sizeof(u32), GFP_KERNEL);
if (!mdata->pad_sel) {
ret = -ENOMEM;
-@@ -1078,11 +1106,11 @@ static int mtk_spi_probe(struct platform
+@@ -1078,11 +1106,11 @@ static int mtk_spi_probe(struct platform_device *pdev)
}
for (i = 0; i < mdata->pad_num; i++) {
@@ -525,7 +536,7 @@
i, mdata->pad_sel[i]);
ret = -EINVAL;
goto err_put_master;
-@@ -1103,122 +1131,118 @@ static int mtk_spi_probe(struct platform
+@@ -1103,122 +1131,118 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master;
}
@@ -702,7 +713,7 @@
err_put_master:
spi_master_put(master);
-@@ -1229,11 +1253,22 @@ static int mtk_spi_remove(struct platfor
+@@ -1229,11 +1253,22 @@ static int mtk_spi_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct mtk_spi *mdata = spi_master_get_devdata(master);
@@ -726,7 +737,7 @@
return 0;
}
-@@ -1250,8 +1285,7 @@ static int mtk_spi_suspend(struct device
+@@ -1250,8 +1285,7 @@ static int mtk_spi_suspend(struct device *dev)
if (!pm_runtime_suspended(dev)) {
clk_disable_unprepare(mdata->spi_clk);
@@ -736,7 +747,7 @@
}
return ret;
-@@ -1264,26 +1298,24 @@ static int mtk_spi_resume(struct device
+@@ -1264,26 +1298,24 @@ static int mtk_spi_resume(struct device *dev)
struct mtk_spi *mdata = spi_master_get_devdata(master);
if (!pm_runtime_suspended(dev)) {
@@ -771,7 +782,7 @@
}
return ret;
-@@ -1296,10 +1328,13 @@ static int mtk_spi_runtime_suspend(struc
+@@ -1296,10 +1328,13 @@ static int mtk_spi_runtime_suspend(struct device *dev)
struct spi_master *master = dev_get_drvdata(dev);
struct mtk_spi *mdata = spi_master_get_devdata(master);
@@ -788,7 +799,7 @@
return 0;
}
-@@ -1310,18 +1345,31 @@ static int mtk_spi_runtime_resume(struct
+@@ -1310,18 +1345,31 @@ static int mtk_spi_runtime_resume(struct device *dev)
struct mtk_spi *mdata = spi_master_get_devdata(master);
int ret;
@@ -827,3 +838,6 @@
}
return 0;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2376-drivers-spi-mt65xx-add-dts-buswidth-flow.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2376-drivers-spi-mt65xx-add-dts-buswidth-flow.patch
new file mode 100644
index 0000000..ffe6003
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2376-drivers-spi-mt65xx-add-dts-buswidth-flow.patch
@@ -0,0 +1,26 @@
+From 89740f80939ddd9b73648da2a97c8f31ae16050a Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:22 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2376-drivers-spi-mt65xx-add-dts-buswidth-flow.patch]
+
+---
+ drivers/spi/spi-mt65xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
+index b80f8dcd9..ac95e26c1 100644
+--- a/drivers/spi/spi-mt65xx.c
++++ b/drivers/spi/spi-mt65xx.c
+@@ -1080,7 +1080,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
+ master->flags = SPI_MASTER_MUST_TX;
+
+ if (mdata->dev_comp->ipm_design)
+- master->mode_bits |= SPI_LOOP;
++ master->mode_bits |= SPI_LOOP | SPI_RX_DUAL | SPI_TX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD;
+
+ if (mdata->dev_comp->ipm_design) {
+ mdata->dev = dev;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0322-fix-dirty-race-between-do_tmpfile.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2380-fix-dirty-race-between-do_tmpfile.patch
similarity index 88%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0322-fix-dirty-race-between-do_tmpfile.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2380-fix-dirty-race-between-do_tmpfile.patch
index 94ce9bd..63943f8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0322-fix-dirty-race-between-do_tmpfile.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2380-fix-dirty-race-between-do_tmpfile.patch
@@ -1,4 +1,15 @@
+From d08d34636d1384d5ddb141e0bb72afa591c12118 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:22 +0800
+Subject: [PATCH]
+ [spi-and-storage][999-2380-fix-dirty-race-between-do_tmpfile.patch]
+
+---
+ fs/ubifs/dir.c | 60 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
+index 332c0b02a..97b231c43 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -356,6 +356,32 @@ out_budg:
@@ -98,3 +109,6 @@
static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry)
{
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2500-cpufreq-add-the-missing-platform-driver-unregister.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2500-cpufreq-add-the-missing-platform-driver-unregister.patch
new file mode 100644
index 0000000..b03956f
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2500-cpufreq-add-the-missing-platform-driver-unregister.patch
@@ -0,0 +1,25 @@
+From 074bd5464b2e05ad5c8ed9ba0442a8abdfd4e2fc Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:22 +0800
+Subject: [PATCH]
+ [adv-feature][999-2500-cpufreq-add-the-missing-platform-driver-unregister.patch]
+
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
+index 927ebc582..03bb7b58d 100644
+--- a/drivers/cpufreq/mediatek-cpufreq.c
++++ b/drivers/cpufreq/mediatek-cpufreq.c
+@@ -573,6 +573,7 @@ static int __init mtk_cpufreq_driver_init(void)
+ pdev = platform_device_register_simple("mtk-cpufreq", -1, NULL, 0);
+ if (IS_ERR(pdev)) {
+ pr_err("failed to register mtk-cpufreq platform device\n");
++ platform_driver_unregister(&mtk_cpufreq_platdrv);
+ return PTR_ERR(pdev);
+ }
+
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0002-cpufreq-Enable-clocks-and-regulators.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2501-cpufreq-Enable-clocks-and-regulators.patch
similarity index 85%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0002-cpufreq-Enable-clocks-and-regulators.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2501-cpufreq-Enable-clocks-and-regulators.patch
index 2fa9359..ca84955 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0002-cpufreq-Enable-clocks-and-regulators.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2501-cpufreq-Enable-clocks-and-regulators.patch
@@ -1,5 +1,15 @@
+From 31b16ccb455139f23e4989c0795564350774c8c6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:22 +0800
+Subject: [PATCH]
+ [adv-feature][999-2501-cpufreq-Enable-clocks-and-regulators.patch]
+
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 41 +++++++++++++++++++++++++++---
+ 1 file changed, 37 insertions(+), 4 deletions(-)
+
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
-index 03bb7b5..010a947 100644
+index 03bb7b58d..010a947a6 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -351,6 +351,12 @@ static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu)
@@ -86,3 +96,6 @@
dev_pm_opp_of_cpumask_remove_table(&info->cpus);
}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0003-cpufreq-add-mt7988a-spim-snand-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2502-cpufreq-add-mt7988a-spim-snand-support.patch
similarity index 94%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0003-cpufreq-add-mt7988a-spim-snand-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2502-cpufreq-add-mt7988a-spim-snand-support.patch
index ee87f4e..b40509d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0003-cpufreq-add-mt7988a-spim-snand-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2502-cpufreq-add-mt7988a-spim-snand-support.patch
@@ -1,5 +1,15 @@
+From 8abbdaf99bd93b9009482e49c94455d5c10a29f6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:23 +0800
+Subject: [PATCH]
+ [adv-feature][999-2502-cpufreq-add-mt7988a-spim-snand-support.patch]
+
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 83 +++++++++++++++++++++++++++++-
+ 1 file changed, 81 insertions(+), 2 deletions(-)
+
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
-index 010a947..291f629 100644
+index 010a947a6..b23b6d2b4 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -38,6 +38,7 @@ struct mtk_cpu_dvfs_info {
@@ -210,3 +220,6 @@
{ }
};
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2503-cpufreq-mtk-vbining-add-mt7988-support.patch
similarity index 78%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2503-cpufreq-mtk-vbining-add-mt7988-support.patch
index aa31f22..032d163 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0007-cpufreq-mtk-vbining-add-mt7988-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2503-cpufreq-mtk-vbining-add-mt7988-support.patch
@@ -1,5 +1,15 @@
+From 96af4d1381b43bafba252d38c2a344f1011de638 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:23 +0800
+Subject: [PATCH]
+ [adv-feature][999-2503-cpufreq-mtk-vbining-add-mt7988-support.patch]
+
+---
+ drivers/cpufreq/mediatek-cpufreq.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c
-index b23b6d2..147a224 100644
+index b23b6d2b4..c22945100 100644
--- a/drivers/cpufreq/mediatek-cpufreq.c
+++ b/drivers/cpufreq/mediatek-cpufreq.c
@@ -15,6 +15,7 @@
@@ -45,3 +55,6 @@
ret = dev_pm_opp_init_cpufreq_table(info->cpu_dev, &freq_table);
if (ret) {
pr_err("failed to init cpufreq table for cpu%d: %d\n",
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0950-add-pmic-config.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2530-add-pmic-config.patch
similarity index 76%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0950-add-pmic-config.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2530-add-pmic-config.patch
index f5384f3..0194261 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0950-add-pmic-config.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2530-add-pmic-config.patch
@@ -1,5 +1,15 @@
+From 4ff5fd6b2d7df7b572bce364d6a1853665e378ac Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:23 +0800
+Subject: [PATCH] [adv-feature][999-2530-add-pmic-config.patch]
+
+---
+ drivers/regulator/Kconfig | 10 ++++++++++
+ drivers/regulator/Makefile | 1 +
+ 2 files changed, 11 insertions(+)
+
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
-index 3ee6353..2e393a7 100644
+index 3ee63531f..5c573ced5 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -798,6 +798,16 @@ config REGULATOR_RT5033
@@ -20,7 +30,7 @@
tristate "Samsung S2MPA01 voltage regulator"
depends on MFD_SEC_CORE
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
-index 2210ba5..bf75b77 100644
+index 2210ba56f..bf75b7755 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
@@ -32,5 +42,5 @@
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2550-dual-image-mount-rootfs.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2550-dual-image-mount-rootfs.patch
new file mode 100644
index 0000000..350e7d3
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2550-dual-image-mount-rootfs.patch
@@ -0,0 +1,40 @@
+From 7be8614176dc79bc242a12b7669f330058e36df6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:24 +0800
+Subject: [PATCH] [adv-feature][999-2550-dual-image-mount-rootfs.patch]
+
+---
+ init/do_mounts.c | 3 ++-
+ kernel/boot_param.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/init/do_mounts.c b/init/do_mounts.c
+index cd5fca8aa..2dfc0dac7 100644
+--- a/init/do_mounts.c
++++ b/init/do_mounts.c
+@@ -576,7 +576,8 @@ void __init mount_root(void)
+ }
+ #endif
+ #ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
+- if (!mount_ubi_rootfs())
++ extern bool dual_boot;
++ if (!dual_boot && !mount_ubi_rootfs())
+ return;
+ #endif
+ #ifdef CONFIG_BLOCK
+diff --git a/kernel/boot_param.c b/kernel/boot_param.c
+index 3dfe828bc..cc0b2b8b0 100644
+--- a/kernel/boot_param.c
++++ b/kernel/boot_param.c
+@@ -10,7 +10,7 @@
+
+ #define BOOT_PARAM_STR_MAX_LEN 256
+
+-static bool dual_boot;
++bool dual_boot;
+ module_param(dual_boot, bool, 0444);
+
+ static bool no_split_rootfs_data;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1015-pcie-add-pcie-gen3-upstream-driver.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2600-pcie-add-pcie-gen3-upstream-driver.patch
similarity index 76%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1015-pcie-add-pcie-gen3-upstream-driver.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2600-pcie-add-pcie-gen3-upstream-driver.patch
index 4b99d9d..6e5b96a 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1015-pcie-add-pcie-gen3-upstream-driver.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2600-pcie-add-pcie-gen3-upstream-driver.patch
@@ -1,5 +1,16 @@
+From 99a6452c7481de2f1a36699dd60361c49602cc77 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:24 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2600-pcie-add-pcie-gen3-upstream-driver.patch]
+
+---
+ drivers/pci/controller/Kconfig | 13 +++++++++++++
+ drivers/pci/controller/Makefile | 1 +
+ 2 files changed, 14 insertions(+)
+
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
-index 70e0782..67988f8 100644
+index 70e078238..67988f868 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -241,6 +241,19 @@ config PCIE_MEDIATEK
@@ -23,7 +34,7 @@
bool "Mobiveil AXI PCIe controller"
depends on ARCH_ZYNQMP || COMPILE_TEST
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
-index a2a22c9..54a496a 100644
+index a2a22c9d9..54a496a68 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o
@@ -34,3 +45,6 @@
obj-$(CONFIG_PCIE_MOBIVEIL) += pcie-mobiveil.o
obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o
obj-$(CONFIG_VMD) += vmd.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1024-pcie-add-multi-MSI-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2601-pcie-add-multi-MSI-support.patch
similarity index 75%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1024-pcie-add-multi-MSI-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2601-pcie-add-multi-MSI-support.patch
index 5cf486c..80ce145 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1024-pcie-add-multi-MSI-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2601-pcie-add-multi-MSI-support.patch
@@ -1,8 +1,17 @@
+From f001395855db2d04f499a2e2936f1d54dcaab225 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:24 +0800
+Subject: [PATCH] [high-speed-io][999-2601-pcie-add-multi-MSI-support.patch]
+
+---
+ drivers/pci/controller/pcie-mediatek.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
-index 2a54fa7a3..132b3204c 100644
+index db3672917..44a046005 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
-@@ -446,24 +446,24 @@ static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int vir
+@@ -440,24 +440,24 @@ static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int vir
unsigned int nr_irqs, void *args)
{
struct mtk_pcie_port *port = domain->host_data;
@@ -36,7 +45,7 @@
return 0;
}
-@@ -501,7 +501,7 @@ static struct irq_chip mtk_msi_irq_chip = {
+@@ -495,7 +495,7 @@ static struct irq_chip mtk_msi_irq_chip = {
static struct msi_domain_info mtk_msi_domain_info = {
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
@@ -45,7 +54,7 @@
.chip = &mtk_msi_irq_chip,
};
-@@ -633,14 +633,14 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
+@@ -627,14 +627,14 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
if (status & MSI_STATUS){
unsigned long imsi_status;
@@ -62,3 +71,6 @@
}
}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2610-tphy-support-type-switch-by-pericfg.patch
similarity index 77%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2610-tphy-support-type-switch-by-pericfg.patch
index 032ef35..da92a39 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2610-tphy-support-type-switch-by-pericfg.patch
@@ -1,21 +1,15 @@
-From 34687407776d46f08926b91f118adc484c4ac231 Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Fri, 17 Sep 2021 15:56:53 +0800
-Subject: [PATCH 1/8] phy: phy-mtk-tphy: support type switch by pericfg
+From 3ef64d448a36853279de5324f9bf00041b9f3ce5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:25 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2610-tphy-support-type-switch-by-pericfg.patch]
-Add support type switch between USB3, PCIe, SATA and SGMII by
-pericfg register, this is used to take the place of efuse or
-jumper.
-
-Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 83 ++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index cb2ed3b25068..a59fe65f69e5 100644
+index d1ecf0880..c6e073401 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -10,6 +10,7 @@
@@ -26,9 +20,9 @@
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
-@@ -263,6 +264,14 @@
- #define RG_CDR_BIRLTD0_GEN3_MSK GENMASK(4, 0)
- #define RG_CDR_BIRLTD0_GEN3_VAL(x) (0x1f & (x))
+@@ -268,6 +269,14 @@
+ #define HIF_SYSCFG1 0x14
+ #define HIF_SYSCFG1_PHY2_MASK (0x3 << 20)
+/* PHY switch between pcie/usb3/sgmii/sata */
+#define USB_PHY_SWITCH_CTRL 0x0
@@ -41,7 +35,7 @@
enum mtk_phy_version {
MTK_PHY_V1 = 1,
MTK_PHY_V2,
-@@ -296,7 +305,10 @@ struct mtk_phy_instance {
+@@ -301,7 +310,10 @@ struct mtk_phy_instance {
};
struct clk *ref_clk; /* reference clock of anolog phy */
u32 index;
@@ -53,7 +47,7 @@
int eye_src;
int eye_vrt;
int eye_term;
-@@ -890,6 +902,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
+@@ -900,6 +912,64 @@ static void u2_phy_props_set(struct mtk_tphy *tphy,
}
}
@@ -118,7 +112,7 @@
static int mtk_phy_init(struct phy *phy)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-@@ -922,6 +992,9 @@ static int mtk_phy_init(struct phy *phy)
+@@ -932,6 +1002,9 @@ static int mtk_phy_init(struct phy *phy)
case PHY_TYPE_SATA:
sata_phy_instance_init(tphy, instance);
break;
@@ -128,7 +122,7 @@
default:
dev_err(tphy->dev, "incompatible PHY type\n");
return -EINVAL;
-@@ -1010,7 +1083,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1020,7 +1093,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
if (!(instance->type == PHY_TYPE_USB2 ||
instance->type == PHY_TYPE_USB3 ||
instance->type == PHY_TYPE_PCIE ||
@@ -138,7 +132,7 @@
dev_err(dev, "unsupported device type: %d\n", instance->type);
return ERR_PTR(-EINVAL);
}
-@@ -1025,6 +1099,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1035,6 +1109,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
}
phy_parse_property(tphy, instance);
@@ -146,7 +140,7 @@
return instance->phy;
}
-@@ -1163,6 +1238,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
+@@ -1183,6 +1258,10 @@ static int mtk_tphy_probe(struct platform_device *pdev)
retval = PTR_ERR(instance->ref_clk);
goto put_child;
}
@@ -158,5 +152,5 @@
provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch
similarity index 88%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch
index 05eb738..1f958e8 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch
@@ -1,21 +1,15 @@
-From a2eaa93a5887ddd20af0373244481139627d0d77 Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Mon, 8 Nov 2021 14:51:38 +0800
-Subject: [PATCH 2/8] phy: phy-mtk-tphy: add support efuse setting
+From 004157ce74543694981c461e95ac0cc1fa8721d7 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:25 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch]
-Due to some SoCs have a bit shift issue that will drop a bit for usb3
-phy or pcie phy, fix it by adding software efuse reading and setting,
-but only support it optionally for versoin.
-
-Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Change-Id: Ibf88868668b3889f18c7930531981400cac732f1
---
drivers/phy/mediatek/phy-mtk-tphy.c | 195 ++++++++++++++++++++++++++++
1 file changed, 195 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index a59fe65f69e5..ce2731b2f5ff 100644
+index c6e073401..fcf8c845f 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -12,6 +12,7 @@
@@ -26,7 +20,7 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/phy/phy.h>
-@@ -39,11 +40,16 @@
+@@ -41,11 +42,16 @@
#define SSUSB_SIFSLV_V2_U3PHYD 0x200
#define SSUSB_SIFSLV_V2_U3PHYA 0x400
@@ -43,7 +37,7 @@
#define PA1_RG_VRT_SEL GENMASK(14, 12)
#define PA1_RG_VRT_SEL_VAL(x) ((0x7 & (x)) << 12)
#define PA1_RG_TERM_SEL GENMASK(10, 8)
-@@ -115,6 +121,8 @@
+@@ -117,6 +123,8 @@
#define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24)
#define U3P_U3_PHYA_REG0 0x000
@@ -52,7 +46,7 @@
#define P3A_RG_CLKDRV_OFF GENMASK(3, 2)
#define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2)
-@@ -169,6 +177,25 @@
+@@ -171,6 +179,25 @@
#define P3D_RG_FWAKE_TH GENMASK(21, 16)
#define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16)
@@ -78,7 +72,7 @@
#define U3P_U3_PHYD_CDR1 0x05c
#define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24)
#define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24)
-@@ -275,11 +302,23 @@
+@@ -280,11 +307,23 @@
enum mtk_phy_version {
MTK_PHY_V1 = 1,
MTK_PHY_V2,
@@ -102,7 +96,7 @@
enum mtk_phy_version version;
};
-@@ -304,6 +343,10 @@ struct mtk_phy_instance {
+@@ -309,6 +348,10 @@ struct mtk_phy_instance {
struct u3phy_banks u3_banks;
};
struct clk *ref_clk; /* reference clock of anolog phy */
@@ -113,7 +107,7 @@
u32 index;
u32 type;
struct regmap *type_sw;
-@@ -960,6 +1003,139 @@ static int phy_type_set(struct mtk_phy_instance *instance)
+@@ -970,6 +1013,139 @@ static int phy_type_set(struct mtk_phy_instance *instance)
return 0;
}
@@ -253,7 +247,7 @@
static int mtk_phy_init(struct phy *phy)
{
struct mtk_phy_instance *instance = phy_get_drvdata(phy);
-@@ -978,6 +1154,8 @@ static int mtk_phy_init(struct phy *phy)
+@@ -988,6 +1164,8 @@ static int mtk_phy_init(struct phy *phy)
return ret;
}
@@ -262,7 +256,7 @@
switch (instance->type) {
case PHY_TYPE_USB2:
u2_phy_instance_init(tphy, instance);
-@@ -1062,6 +1240,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1072,6 +1250,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
struct mtk_phy_instance *instance = NULL;
struct device_node *phy_np = args->np;
int index;
@@ -270,7 +264,7 @@
if (args->args_count != 1) {
dev_err(dev, "invalid number of cells in 'phy' property\n");
-@@ -1098,6 +1277,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1108,6 +1287,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
return ERR_PTR(-EINVAL);
}
@@ -281,7 +275,7 @@
phy_parse_property(tphy, instance);
phy_type_set(instance);
-@@ -1120,14 +1303,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
+@@ -1130,14 +1313,26 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
static const struct mtk_phy_pdata tphy_v2_pdata = {
.avoid_rx_sen_degradation = false,
@@ -309,5 +303,5 @@
{ .compatible = "mediatek,mt2701-u3phy", .data = &tphy_v1_pdata },
{ .compatible = "mediatek,mt2712-u3phy", .data = &tphy_v2_pdata },
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2612-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
similarity index 88%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2612-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
index 1c6711f..1a70ada 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2612-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch
@@ -1,21 +1,18 @@
-From 2abe803824f0331c42eb9853199d5f147cee3a06 Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Tue, 25 Jan 2022 16:50:47 +0800
-Subject: [PATCH 3/8] phy: phy-mtk-tphy: Add PCIe 2 lane efuse support
+From e63fdeaa652ad5fd8d7a591e346abe587fd9bede Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:25 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2612-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch]
-Add PCIe 2 lane efuse support in tphy driver.
-
-Signed-off-by: Jie Yang <jieyy.yang@mediatek.com>
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 140 ++++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index ce2731b2f5ff..b855e759b0da 100644
+index fcf8c845f..6c07885be 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -40,6 +40,15 @@
+@@ -42,6 +42,15 @@
#define SSUSB_SIFSLV_V2_U3PHYD 0x200
#define SSUSB_SIFSLV_V2_U3PHYA 0x400
@@ -31,7 +28,7 @@
#define U3P_MISC_REG1 0x04
#define MR1_EFUSE_AUTO_LOAD_DIS BIT(6)
-@@ -303,6 +312,7 @@ enum mtk_phy_version {
+@@ -308,6 +317,7 @@ enum mtk_phy_version {
MTK_PHY_V1 = 1,
MTK_PHY_V2,
MTK_PHY_V3,
@@ -39,7 +36,7 @@
};
struct mtk_phy_pdata {
-@@ -347,6 +357,9 @@ struct mtk_phy_instance {
+@@ -352,6 +362,9 @@ struct mtk_phy_instance {
u32 efuse_intr;
u32 efuse_tx_imp;
u32 efuse_rx_imp;
@@ -49,7 +46,7 @@
u32 index;
u32 type;
struct regmap *type_sw;
-@@ -890,6 +903,36 @@ static void phy_v2_banks_init(struct mtk_tphy *tphy,
+@@ -900,6 +913,36 @@ static void phy_v2_banks_init(struct mtk_tphy *tphy,
}
}
@@ -86,7 +83,7 @@
static void phy_parse_property(struct mtk_tphy *tphy,
struct mtk_phy_instance *instance)
{
-@@ -1072,6 +1115,40 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1082,6 +1125,40 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
dev_info(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
instance->efuse_intr, instance->efuse_rx_imp,
instance->efuse_tx_imp);
@@ -127,7 +124,7 @@
break;
default:
dev_err(dev, "no sw efuse for type %d\n", instance->type);
-@@ -1105,6 +1182,31 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1115,6 +1192,31 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
break;
case PHY_TYPE_USB3:
@@ -159,7 +156,7 @@
case PHY_TYPE_PCIE:
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
-@@ -1129,6 +1231,35 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1139,6 +1241,35 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
pr_err("%s set efuse, tx_imp %x, rx_imp %x intr %x\n",
__func__, instance->efuse_tx_imp,
instance->efuse_rx_imp, instance->efuse_intr);
@@ -195,7 +192,7 @@
break;
default:
dev_warn(dev, "no sw efuse for type %d\n", instance->type);
-@@ -1272,6 +1403,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
+@@ -1282,6 +1413,8 @@ static struct phy *mtk_phy_xlate(struct device *dev,
phy_v1_banks_init(tphy, instance);
} else if (tphy->pdata->version == MTK_PHY_V2) {
phy_v2_banks_init(tphy, instance);
@@ -204,7 +201,7 @@
} else {
dev_err(dev, "phy version is not supported\n");
return ERR_PTR(-EINVAL);
-@@ -1323,12 +1456,19 @@ static const struct mtk_phy_pdata mt8195_pdata = {
+@@ -1333,12 +1466,19 @@ static const struct mtk_phy_pdata mt8195_pdata = {
.version = MTK_PHY_V3,
};
@@ -225,5 +222,5 @@
};
MODULE_DEVICE_TABLE(of, mtk_tphy_id_table);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2613-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
similarity index 81%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2613-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
index e84ca6c..64e68c3 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2613-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch
@@ -1,21 +1,18 @@
-From 355e7f114a47819c3c6545a97ad308d627da5d1a Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Tue, 25 Jan 2022 19:03:34 +0800
-Subject: [PATCH 4/8] phy: phy-mtk-tphy: add auto-load-valid check mechanism
- support
+From 0e03f2c1ade35e8d40c87425414d0a6ccef0439c Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:25 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2613-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch]
-add auto-load-valid check mechanism support
-
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 67 +++++++++++++++++++++++++++--
1 file changed, 64 insertions(+), 3 deletions(-)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index b855e759b0da..a5b17a1aed5c 100644
+index 6c07885be..149464f37 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -354,9 +354,13 @@ struct mtk_phy_instance {
+@@ -359,9 +359,13 @@ struct mtk_phy_instance {
};
struct clk *ref_clk; /* reference clock of anolog phy */
u32 efuse_sw_en;
@@ -29,7 +26,7 @@
u32 efuse_intr_ln1;
u32 efuse_tx_imp_ln1;
u32 efuse_rx_imp_ln1;
-@@ -1050,6 +1054,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1060,6 +1064,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
{
struct device *dev = &instance->phy->dev;
int ret = 0;
@@ -37,7 +34,7 @@
dev_err(dev, "try to get sw efuse\n");
-@@ -1068,6 +1073,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1078,6 +1083,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
switch (instance->type) {
case PHY_TYPE_USB2:
@@ -58,7 +55,7 @@
ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
if (ret) {
dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
-@@ -1085,6 +1104,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1095,6 +1114,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
break;
case PHY_TYPE_USB3:
case PHY_TYPE_PCIE:
@@ -79,7 +76,7 @@
ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
if (ret) {
dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
-@@ -1119,6 +1152,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
+@@ -1129,6 +1162,20 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
if (tphy->pdata->version != MTK_PHY_V4)
break;
@@ -100,7 +97,7 @@
ret = nvmem_cell_read_variable_le_u32(dev, "intr_ln1", &instance->efuse_intr_ln1);
if (ret) {
dev_err(dev, "fail to get u3 lane1 intr efuse, %d\n", ret);
-@@ -1170,6 +1217,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1180,6 +1227,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
switch (instance->type) {
case PHY_TYPE_USB2:
@@ -111,7 +108,7 @@
tmp = readl(u2_banks->misc + U3P_MISC_REG1);
tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
writel(tmp, u2_banks->misc + U3P_MISC_REG1);
-@@ -1182,6 +1233,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1192,6 +1243,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
break;
case PHY_TYPE_USB3:
@@ -122,7 +119,7 @@
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
-@@ -1208,6 +1263,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1218,6 +1273,10 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
break;
case PHY_TYPE_PCIE:
@@ -133,7 +130,7 @@
tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
-@@ -1232,9 +1291,11 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
+@@ -1242,9 +1301,11 @@ static void phy_efuse_set(struct mtk_phy_instance *instance)
__func__, instance->efuse_tx_imp,
instance->efuse_rx_imp, instance->efuse_intr);
@@ -149,5 +146,5 @@
tmp = readl(u3_banks->phyd + SSUSB_LN1_OFFSET + U3P_U3_PHYD_RSV);
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2614-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
similarity index 77%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2614-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
index 36362f5..ef3b3a6 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2614-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch
@@ -1,20 +1,18 @@
-From 3295585b4e77f4a365bd1a4e17d8be6ee504584a Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Sat, 15 Oct 2022 17:38:54 +0800
-Subject: [PATCH 5/8] tphy: one setting of TTSSC-Freq-Dev for all IC cases
+From a977dbd79bc888d32fb974f328efa650722590c2 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:26 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2614-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch]
-try to use one setting of TTSSC-Freq-Dev to covery all IC cases
-
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
---
drivers/phy/mediatek/phy-mtk-tphy.c | 37 +++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
-index a5b17a1aed5c..49a2625c1fc1 100644
+index 149464f37..e7ed93799 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
-@@ -219,6 +219,14 @@
+@@ -221,6 +221,14 @@
#define P3D_RG_RXDET_STB2_SET_P3 GENMASK(8, 0)
#define P3D_RG_RXDET_STB2_SET_P3_VAL(x) (0x1ff & (x))
@@ -29,7 +27,7 @@
#define U3P_SPLLC_XTALCTL3 0x018
#define XC3_RG_U3_XTAL_RX_PWD BIT(9)
#define XC3_RG_U3_FRC_XTAL_RX_PWD BIT(8)
-@@ -373,6 +381,8 @@ struct mtk_phy_instance {
+@@ -378,6 +386,8 @@ struct mtk_phy_instance {
int eye_vrt;
int eye_term;
bool bc12_en;
@@ -38,7 +36,7 @@
};
struct mtk_tphy {
-@@ -514,6 +524,20 @@ static void u3_phy_instance_init(struct mtk_tphy *tphy,
+@@ -520,6 +530,20 @@ static void u3_phy_instance_init(struct mtk_tphy *tphy,
tmp |= P3D_RG_RXDET_STB2_SET_P3_VAL(0x10);
writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RXDET2);
@@ -59,7 +57,7 @@
dev_dbg(tphy->dev, "%s(%d)\n", __func__, instance->index);
}
-@@ -942,6 +966,19 @@ static void phy_parse_property(struct mtk_tphy *tphy,
+@@ -952,6 +976,19 @@ static void phy_parse_property(struct mtk_tphy *tphy,
{
struct device *dev = &instance->phy->dev;
@@ -80,5 +78,5 @@
return;
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8010-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch
similarity index 89%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8010-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch
index c20e930..fcd38ac 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/8010-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch
@@ -1,5 +1,15 @@
+From 50cefacc6c001eea1d9b1c78ba27304566f304f1 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:26 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch]
+
+---
+ drivers/phy/mediatek/phy-mtk-xsphy.c | 81 +++++++++++++++++++++++++++-
+ 1 file changed, 80 insertions(+), 1 deletion(-)
+
diff --git a/drivers/phy/mediatek/phy-mtk-xsphy.c b/drivers/phy/mediatek/phy-mtk-xsphy.c
-index 8c51131..e77092c 100644
+index 8c5113194..e77092c3e 100644
--- a/drivers/phy/mediatek/phy-mtk-xsphy.c
+++ b/drivers/phy/mediatek/phy-mtk-xsphy.c
@@ -12,10 +12,12 @@
@@ -140,3 +150,6 @@
}
provider = devm_of_phy_provider_register(dev, mtk_phy_xlate);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2620-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
similarity index 80%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2620-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
index 9d1ca10..f38ed0d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2620-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch
@@ -1,21 +1,16 @@
-From 0df9413c8ff0df4ed69b6e1577d7cd5fd2d72e5e Mon Sep 17 00:00:00 2001
+From 9ef2a9d208fba86dfbc06d4f2f743562bd14c145 Mon Sep 17 00:00:00 2001
From: Sam Shih <sam.shih@mediatek.com>
-Date: Tue, 25 Oct 2022 18:25:25 +0800
-Subject: [PATCH 1/3] xHCI: change compliance mode de-emphasis default as gen1
+Date: Fri, 2 Jun 2023 13:06:26 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2620-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch]
-Port0 is using Gen2 Phy for 10GHz, and Port0 is running
-on 5GHz actually. hence to change compliance mode de-
-emphasis default as Gen1.
-
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Signed-off-by: Sam Shih <sam.shih@mediatek.com>
---
drivers/usb/host/xhci-mtk.c | 18 +++++++++++++++++-
drivers/usb/host/xhci-mtk.h | 1 +
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
-index 5c0eb35cd007..77ddb8c05500 100644
+index 5c0eb35cd..77ddb8c05 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -22,6 +22,11 @@
@@ -65,7 +60,7 @@
if (ret) {
dev_err(dev, "failed to parse uwk property\n");
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
-index 2f702342de66..8a884e7b481b 100644
+index 2f702342d..8a884e7b4 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -156,6 +156,7 @@ struct xhci_hcd_mtk {
@@ -77,5 +72,5 @@
static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2621-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
similarity index 86%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2621-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
index 07b87fc..d6974a5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2621-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch
@@ -1,11 +1,9 @@
-From 083b79c977495cafc70c5d044db1f3f6c0587b1c Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Mon, 15 Aug 2022 12:40:22 +0800
-Subject: [PATCH 2/3] xHCI: MT79xx USB 2.0 USBIF compliance toolkit
+From f6aea6b89ce99b4f490fe1e1062b88042096703e Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:26 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2621-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch]
-MT79xx USB 2.0 USBIF compliance toolkit
-
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
---
drivers/usb/host/Kconfig | 9 +++++++++
drivers/usb/host/Makefile | 10 ++++++++++
@@ -16,7 +14,7 @@
6 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
-index 79b2e79dddd0..12b1bf9aa043 100644
+index 79b2e79dd..12b1bf9aa 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -69,6 +69,15 @@ config USB_XHCI_MTK
@@ -36,7 +34,7 @@
tristate "xHCI support for Marvell Armada 375/38x/37xx"
select USB_XHCI_PLATFORM
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
-index b191361257cc..f064f836db2b 100644
+index b19136125..f064f836d 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -21,6 +21,16 @@ endif
@@ -57,7 +55,7 @@
xhci-plat-hcd-y := xhci-plat.o
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
-index 77ddb8c05500..7a200793169b 100644
+index 77ddb8c05..7a2007931 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -18,10 +18,10 @@
@@ -90,7 +88,7 @@
pm_runtime_put_noidle(&dev->dev);
pm_runtime_disable(&dev->dev);
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
-index 8a884e7b481b..e815d7091acc 100644
+index 8a884e7b4..e815d7091 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -157,6 +157,13 @@ struct xhci_hcd_mtk {
@@ -108,10 +106,10 @@
static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
-index 5ce16a259e61..b6f8383f7371 100644
+index b8915790a..dd1b520af 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -713,7 +713,7 @@ EXPORT_SYMBOL_GPL(xhci_run);
+@@ -714,7 +714,7 @@ EXPORT_SYMBOL_GPL(xhci_run);
* Disable device contexts, disable IRQs, and quiesce the HC.
* Reset the HC, finish any completed transactions, and cleanup memory.
*/
@@ -121,10 +119,10 @@
u32 temp;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
-index 0dc448630197..80b3124c43e2 100644
+index e696f1508..07f904167 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
-@@ -2070,6 +2070,7 @@ int xhci_halt(struct xhci_hcd *xhci);
+@@ -2073,6 +2073,7 @@ int xhci_halt(struct xhci_hcd *xhci);
int xhci_start(struct xhci_hcd *xhci);
int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us);
int xhci_run(struct usb_hcd *hcd);
@@ -133,5 +131,5 @@
void xhci_shutdown(struct usb_hcd *hcd);
void xhci_init_driver(struct hc_driver *drv,
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9002-PATCH-1-1-usb-add-embedded-Host-feature-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2622-usb-add-embedded-Host-feature-support.patch
similarity index 77%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9002-PATCH-1-1-usb-add-embedded-Host-feature-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2622-usb-add-embedded-Host-feature-support.patch
index c4970eb..7776441 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9002-PATCH-1-1-usb-add-embedded-Host-feature-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2622-usb-add-embedded-Host-feature-support.patch
@@ -1,18 +1,9 @@
-From be6839b4144867c7ea6ffbedb6c6a2a42976e16d Mon Sep 17 00:00:00 2001
-From: Zhanyong Wang <zhanyong.wang@mediatek.com>
-Date: Thu, 17 Jun 2021 16:09:04 +0800
-Subject: [PATCH 3/3] usb: add embedded Host feature support
+From 32950d08c99f51e88a2db8dd30c5076a4947de24 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:27 +0800
+Subject: [PATCH]
+ [high-speed-io][999-2622-usb-add-embedded-Host-feature-support.patch]
-add EH(Embedded Host) feature for PET authentication
-1. need CONFIG_USB_OTG_WHITELIST enable
- CONFIG_USB_OTG_WHITELIST=y
-
-2. host device tree node need include "tpl-support" keyword
- &xhci {
- tpl-support;
- }
-
-Signed-off-by: Zhanyong Wang <zhanyong.wang@mediatek.com>
---
drivers/usb/core/hub.c | 9 +++++---
drivers/usb/core/otg_whitelist.h | 39 ++++++++++++++++++++++++++++++++
@@ -20,10 +11,10 @@
3 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index 4cf0dc7f330d..f2f330606d0c 100644
+index f787e9771..7687711f1 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -2422,6 +2422,8 @@ static int usb_enumerate_device(struct usb_device *udev)
+@@ -2424,6 +2424,8 @@ static int usb_enumerate_device(struct usb_device *udev)
if (err < 0)
dev_dbg(&udev->dev, "HNP fail, %d\n", err);
}
@@ -32,7 +23,7 @@
return -ENOTSUPP;
}
-@@ -4779,9 +4781,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
+@@ -4781,9 +4783,10 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
goto fail;
}
if (r) {
@@ -47,7 +38,7 @@
continue;
}
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
-index 2ae90158ded7..a8dd221334c1 100644
+index 2ae90158d..a8dd22133 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -39,9 +39,44 @@ static struct usb_device_id whitelist_table[] = {
@@ -107,10 +98,10 @@
}
diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
-index d4345657945d..2a4b73a658f9 100644
+index 7a2007931..19b54c343 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
-@@ -571,6 +571,8 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+@@ -575,6 +575,8 @@ static int xhci_mtk_probe(struct platform_device *pdev)
goto disable_device_wakeup;
}
@@ -120,5 +111,5 @@
if (ret)
goto put_usb3_hcd;
--
-2.18.0
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/744-en8811h-2p5gphy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2704-en8811h-2p5gphy-support.patch
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/744-en8811h-2p5gphy-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2704-en8811h-2p5gphy-support.patch
index 5a3e423..5e3c619 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/744-en8811h-2p5gphy-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2704-en8811h-2p5gphy-support.patch
@@ -1,10 +1,25 @@
+From b5aa08e6dd4e06ffd3fb4de2ffc6af1e3da0bce4 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:00 +0800
+Subject: [PATCH]
+ [backport-networking-drivers][999-1703-en8811h-2p5gphy-support.patch]
+
+---
+ drivers/net/phy/Kconfig | 5 +
+ drivers/net/phy/Makefile | 1 +
+ drivers/net/phy/air_en8811h.c | 702 ++++++++++++++++++++++++++++++++++
+ drivers/net/phy/air_en8811h.h | 151 ++++++++
+ 4 files changed, 859 insertions(+)
+ create mode 100644 drivers/net/phy/air_en8811h.c
+ create mode 100644 drivers/net/phy/air_en8811h.h
+
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
-index 207046b..21a4497 100644
+index 170dd00cd..5eeccfee2 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
-@@ -350,6 +350,11 @@ config AIROHA_EN8801SC_PHY
- ---help---
- Currently supports the Airoha EN8801S PHY for MT7981 SoC.
+@@ -345,6 +345,11 @@ config SFP
+ depends on HWMON || HWMON=n
+ select MDIO_I2C
+config AIROHA_EN8811H_PHY
+ tristate "Drivers for Airoha EN8811H 2.5G Gigabit PHY"
@@ -15,10 +30,10 @@
tristate "Analog Devices Industrial Ethernet PHYs"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
-index 1b13c02..744b249 100644
+index 2368c1d19..8ea612a85 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
-@@ -71,6 +71,7 @@ ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
+@@ -67,6 +67,7 @@ aquantia-objs += aquantia_main.o
ifdef CONFIG_HWMON
aquantia-objs += aquantia_hwmon.o
endif
@@ -28,7 +43,7 @@
obj-$(CONFIG_AT803X_PHY) += at803x.o
diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
new file mode 100644
-index 0000000..cf564fc
+index 000000000..cf564fc04
--- /dev/null
+++ b/drivers/net/phy/air_en8811h.c
@@ -0,0 +1,702 @@
@@ -736,7 +751,7 @@
+module_exit(en8811h_phy_driver_unregister);
diff --git a/drivers/net/phy/air_en8811h.h b/drivers/net/phy/air_en8811h.h
new file mode 100644
-index 0000000..1c91627
+index 000000000..1c9162795
--- /dev/null
+++ b/drivers/net/phy/air_en8811h.h
@@ -0,0 +1,151 @@
@@ -891,3 +906,6 @@
+} AIR_LED_MODE_T;
+
+#endif /* End of __EN8811H_MD32_H */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0100-hwnat_Kconfig_Makefile.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2705-hwnat_Kconfig_Makefile.patch
old mode 100755
new mode 100644
similarity index 61%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0100-hwnat_Kconfig_Makefile.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2705-hwnat_Kconfig_Makefile.patch
index e0ac7ab..fbb8410
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0100-hwnat_Kconfig_Makefile.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2705-hwnat_Kconfig_Makefile.patch
@@ -1,6 +1,18 @@
---- a/net/Kconfig 2020-04-29 17:25:49.750444000 +0800
-+++ b/net/Kconfig 2020-04-29 17:42:40.950424000 +0800
-@@ -451,6 +451,18 @@
+From bc06d56dc89af9d13d3b993dae0de46e76dfc3a7 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:28 +0800
+Subject: [PATCH] [networking][999-2705-hwnat_Kconfig_Makefile.patch]
+
+---
+ net/Kconfig | 12 ++++++++++++
+ net/Makefile | 3 +++
+ 2 files changed, 15 insertions(+)
+
+diff --git a/net/Kconfig b/net/Kconfig
+index 46d9b3827..123e4bc28 100644
+--- a/net/Kconfig
++++ b/net/Kconfig
+@@ -460,6 +460,18 @@ config FAILOVER
migration of VMs with direct attached VFs by failing over to the
paravirtual datapath when the VF is unplugged.
@@ -19,9 +31,11 @@
endif # if NET
# Used by archs to tell that they support BPF JIT compiler plus which flavour.
---- a/net/Makefile 2020-04-23 16:36:46.000000000 +0800
-+++ b/net/Makefile 2020-04-29 17:42:58.106487000 +0800
-@@ -62,6 +62,9 @@
+diff --git a/net/Makefile b/net/Makefile
+index 9603e98f0..673f0a664 100644
+--- a/net/Makefile
++++ b/net/Makefile
+@@ -62,6 +62,9 @@ endif
obj-$(CONFIG_6LOWPAN) += 6lowpan/
obj-$(CONFIG_IEEE802154) += ieee802154/
obj-$(CONFIG_MAC802154) += mac802154/
@@ -31,3 +45,6 @@
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2706-crypto-add-eip197-inside-secure-support.patch
similarity index 82%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2706-crypto-add-eip197-inside-secure-support.patch
index 8b9ccce..a144c36 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/0505-crypto-add-eip197-inside-secure-support.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2706-crypto-add-eip197-inside-secure-support.patch
@@ -1,6 +1,19 @@
+From 7baac266ec5e64236ff94447286a9cc74815d259 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:28 +0800
+Subject: [PATCH]
+ [networking][999-2706-crypto-add-eip197-inside-secure-support.patch]
+
+---
+ drivers/crypto/inside-secure/safexcel.c | 69 ++++++++++++++++++++++---
+ drivers/crypto/inside-secure/safexcel.h | 15 ++++++
+ 2 files changed, 78 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c
+index 647c5a0c1..6f4fc15b7 100644
--- a/drivers/crypto/inside-secure/safexcel.c
+++ b/drivers/crypto/inside-secure/safexcel.c
-@@ -304,6 +304,11 @@
+@@ -304,6 +304,11 @@ static void eip197_init_firmware(struct safexcel_crypto_priv *priv)
/* Enable access to all IFPP program memories */
writel(EIP197_PE_ICE_RAM_CTRL_FPP_PROG_EN,
EIP197_PE(priv) + EIP197_PE_ICE_RAM_CTRL(pe));
@@ -12,7 +25,7 @@
}
}
-@@ -403,13 +408,13 @@
+@@ -403,13 +408,13 @@ static int eip197_load_firmwares(struct safexcel_crypto_priv *priv)
const struct firmware *fw[FW_NB];
char fw_path[37], *dir = NULL;
int i, j, ret = 0, pe;
@@ -28,7 +41,7 @@
else
return -ENODEV;
-@@ -442,6 +447,9 @@
+@@ -442,6 +447,9 @@ retry_fw:
ipuesz = eip197_write_firmware(priv, fw[FW_IPUE]);
@@ -38,7 +51,7 @@
if (eip197_start_firmware(priv, ipuesz, ifppsz, minifw)) {
dev_dbg(priv->dev, "Firmware loaded successfully\n");
return 0;
-@@ -592,6 +600,11 @@
+@@ -592,6 +600,11 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
*/
if (priv->flags & SAFEXCEL_HW_EIP197) {
val = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
@@ -50,7 +63,7 @@
val |= EIP197_MST_CTRL_TX_MAX_CMD(5);
writel(val, EIP197_HIA_AIC(priv) + EIP197_HIA_MST_CTRL);
}
-@@ -792,6 +805,12 @@
+@@ -792,6 +805,12 @@ static int safexcel_hw_init(struct safexcel_crypto_priv *priv)
return ret;
}
@@ -63,7 +76,7 @@
return safexcel_hw_setup_cdesc_rings(priv) ?:
safexcel_hw_setup_rdesc_rings(priv) ?:
0;
-@@ -1498,6 +1517,9 @@
+@@ -1498,6 +1517,9 @@ static int safexcel_probe_generic(void *pdev,
hwopt = readl(EIP197_GLOBAL(priv) + EIP197_OPTIONS);
hiaopt = readl(EIP197_HIA_AIC(priv) + EIP197_HIA_OPTIONS);
@@ -73,7 +86,7 @@
if (priv->flags & SAFEXCEL_HW_EIP197) {
/* EIP197 */
peopt = readl(EIP197_PE(priv) + EIP197_PE_OPTIONS(0));
-@@ -1516,8 +1538,37 @@
+@@ -1516,8 +1538,37 @@ static int safexcel_probe_generic(void *pdev,
EIP197_N_RINGS_MASK;
if (hiaopt & EIP197_HIA_OPT_HAS_PE_ARB)
priv->flags |= EIP197_PE_ARB;
@@ -112,7 +125,7 @@
/* If not a full TRC, then assume simple TRC */
if (!(hwopt & EIP197_OPT_HAS_TRC))
priv->flags |= EIP197_SIMPLE_TRC;
-@@ -1555,13 +1606,14 @@
+@@ -1555,13 +1606,14 @@ static int safexcel_probe_generic(void *pdev,
EIP197_PE_EIP96_OPTIONS(0));
/* Print single info line describing what we just detected */
@@ -129,7 +142,7 @@
safexcel_configure(priv);
-@@ -1690,6 +1742,7 @@
+@@ -1690,6 +1742,7 @@ static int safexcel_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct safexcel_crypto_priv *priv;
@@ -137,7 +150,7 @@
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-@@ -1701,7 +1754,11 @@
+@@ -1701,7 +1754,11 @@ static int safexcel_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
@@ -150,6 +163,8 @@
if (IS_ERR(priv->base)) {
dev_err(dev, "failed to get resource\n");
return PTR_ERR(priv->base);
+diff --git a/drivers/crypto/inside-secure/safexcel.h b/drivers/crypto/inside-secure/safexcel.h
+index c031c197e..e9909c336 100644
--- a/drivers/crypto/inside-secure/safexcel.h
+++ b/drivers/crypto/inside-secure/safexcel.h
@@ -22,6 +22,7 @@
@@ -202,7 +217,7 @@
/* EIP197_STRC_CONFIG */
#define EIP197_STRC_CONFIG_INIT BIT(31)
#define EIP197_STRC_CONFIG_LARGE_REC(s) (s<<8)
-@@ -777,6 +788,7 @@
+@@ -777,6 +788,7 @@ enum safexcel_flags {
EIP197_PE_ARB = BIT(2),
EIP197_ICE = BIT(3),
EIP197_SIMPLE_TRC = BIT(4),
@@ -210,7 +225,7 @@
};
struct safexcel_hwconfig {
-@@ -784,7 +796,10 @@
+@@ -784,7 +796,10 @@ struct safexcel_hwconfig {
int hwver;
int hiaver;
int ppver;
@@ -221,3 +236,6 @@
int hwdataw;
int hwcfsize;
int hwrfsize;
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1001-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2707-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch
similarity index 66%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1001-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2707-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch
index 72719c8..879e79d 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/1001-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2707-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch
@@ -1,5 +1,15 @@
+From 5583834362f5a9050e701e324f6a9b4d7bf5fcdf Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:29 +0800
+Subject: [PATCH]
+ [networking][999-2707-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch]
+
+---
+ net/core/skbuff.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index 5ba1c72f..f4239459 100644
+index 409f33e16..d91b2dfe2 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -69,6 +69,7 @@
@@ -20,3 +30,6 @@
/*
* if shinfo is shared we must drop the old head gracefully, but if it
* is not we can just drop the old head and let the existing refcount
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2709-fix-race-inside-napi-enable.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2709-fix-race-inside-napi-enable.patch
new file mode 100644
index 0000000..0d90686
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2709-fix-race-inside-napi-enable.patch
@@ -0,0 +1,39 @@
+From f57826291fc2ff833c01b39c01fa5b74b69485da Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:29 +0800
+Subject: [PATCH] [networking][999-2709-fix-race-inside-napi-enable.patch]
+
+---
+ net/core/dev.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 81892cd83..503af0034 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -6413,12 +6413,16 @@ EXPORT_SYMBOL(napi_disable);
+ */
+ void napi_enable(struct napi_struct *n)
+ {
+- BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
+- smp_mb__before_atomic();
+- clear_bit(NAPI_STATE_SCHED, &n->state);
+- clear_bit(NAPI_STATE_NPSVC, &n->state);
+- if (n->dev->threaded && n->thread)
+- set_bit(NAPI_STATE_THREADED, &n->state);
++ unsigned long val, new;
++
++ do {
++ val = READ_ONCE(n->state);
++ BUG_ON(!test_bit(NAPI_STATE_SCHED, &val));
++
++ new = val & ~(NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC);
++ if (n->dev->threaded && n->thread)
++ new |= NAPIF_STATE_THREADED;
++ } while (cmpxchg(&n->state, val, new) != val);
+ }
+ EXPORT_SYMBOL(napi_enable);
+
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2710-net-make-napi-disable-symmetric-with-enable.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2710-net-make-napi-disable-symmetric-with-enable.patch
new file mode 100644
index 0000000..0de5a63
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2710-net-make-napi-disable-symmetric-with-enable.patch
@@ -0,0 +1,48 @@
+From 8e758bb3fc5eee316843eeaad1601ee44ce1c899 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:30 +0800
+Subject: [PATCH]
+ [networking][999-2710-net-make-napi-disable-symmetric-with-enable.patch]
+
+---
+ net/core/dev.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 503af0034..cccd7b407 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -6389,18 +6389,25 @@ EXPORT_SYMBOL(netif_napi_add);
+
+ void napi_disable(struct napi_struct *n)
+ {
++ unsigned long val, new;
++
+ might_sleep();
+ set_bit(NAPI_STATE_DISABLE, &n->state);
+
+- while (test_and_set_bit(NAPI_STATE_SCHED, &n->state))
+- msleep(1);
+- while (test_and_set_bit(NAPI_STATE_NPSVC, &n->state))
+- msleep(1);
++ do {
++ val = READ_ONCE(n->state);
++ if (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) {
++ usleep_range(20, 200);
++ continue;
++ }
++
++ new = val | NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC;
++ new &= ~(NAPIF_STATE_THREADED);
++ } while (cmpxchg(&n->state, val, new) != val);
+
+ hrtimer_cancel(&n->timer);
+
+ clear_bit(NAPI_STATE_DISABLE, &n->state);
+- clear_bit(NAPI_STATE_THREADED, &n->state);
+ }
+ EXPORT_SYMBOL(napi_disable);
+
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2711-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2711-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch
new file mode 100644
index 0000000..ef18a49
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2711-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch
@@ -0,0 +1,38 @@
+From a3eac970a1a3e2fc8cdc98acd2594e0578725ad6 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:30 +0800
+Subject: [PATCH]
+ [networking][999-2711-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch]
+
+---
+ net/core/dev.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index cccd7b407..794c768e3 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -6394,7 +6394,7 @@ void napi_disable(struct napi_struct *n)
+ might_sleep();
+ set_bit(NAPI_STATE_DISABLE, &n->state);
+
+- do {
++ for ( ; ; ) {
+ val = READ_ONCE(n->state);
+ if (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)) {
+ usleep_range(20, 200);
+@@ -6403,7 +6403,10 @@ void napi_disable(struct napi_struct *n)
+
+ new = val | NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC;
+ new &= ~(NAPIF_STATE_THREADED);
+- } while (cmpxchg(&n->state, val, new) != val);
++
++ if (cmpxchg(&n->state, val, new) == val)
++ break;
++ }
+
+ hrtimer_cancel(&n->timer);
+
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/730-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2712-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch
similarity index 68%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/730-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2712-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch
index 6b10584..a76a784 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/730-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2712-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch
@@ -1,6 +1,18 @@
---- linux-5.4.77.orig/net/dsa/tag_mtk.c
-+++ linux-5.4.77/net/dsa/tag_mtk.c
-@@ -73,22 +73,28 @@ static struct sk_buff *mtk_tag_rcv(struc
+From 0f2e84b06686745694f276c4aae6cf9d132a56af Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:30 +0800
+Subject: [PATCH]
+ [networking][999-2712-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch]
+
+---
+ net/dsa/tag_mtk.c | 32 +++++++++++++++++++-------------
+ 1 file changed, 19 insertions(+), 13 deletions(-)
+
+diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
+index edc505e07..c386fdc90 100644
+--- a/net/dsa/tag_mtk.c
++++ b/net/dsa/tag_mtk.c
+@@ -80,22 +80,28 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
bool is_multicast_skb = is_multicast_ether_addr(dest) &&
!is_broadcast_ether_addr(dest);
@@ -42,3 +54,6 @@
/* Get source port information */
port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/738-mt7531-gsw-internal_phy_calibration.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2713-mt7531-gsw-internal_phy_calibration.patch
old mode 100755
new mode 100644
similarity index 97%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/738-mt7531-gsw-internal_phy_calibration.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2713-mt7531-gsw-internal_phy_calibration.patch
index 361eca6..e0759b2
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/738-mt7531-gsw-internal_phy_calibration.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2713-mt7531-gsw-internal_phy_calibration.patch
@@ -1,5 +1,21 @@
-Index: drivers/net/phy/mtk/mt753x/Makefile
-===================================================================
+From e17d8763f1279f43edf51a8ceb8b4f78d67eaefa Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:30 +0800
+Subject: [PATCH]
+ [networking][999-2713-mt7531-gsw-internal_phy_calibration.patch]
+
+---
+ drivers/net/phy/mtk/mt753x/Makefile | 2 +-
+ drivers/net/phy/mtk/mt753x/mt7531.c | 21 +
+ drivers/net/phy/mtk/mt753x/mt753x.h | 2 +
+ drivers/net/phy/mtk/mt753x/mt753x_phy.c | 1069 +++++++++++++++++++++++
+ drivers/net/phy/mtk/mt753x/mt753x_phy.h | 145 +++
+ 5 files changed, 1238 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/net/phy/mtk/mt753x/mt753x_phy.c
+ create mode 100644 drivers/net/phy/mtk/mt753x/mt753x_phy.h
+
+diff --git a/drivers/net/phy/mtk/mt753x/Makefile b/drivers/net/phy/mtk/mt753x/Makefile
+index e304fcb41..b5a63fe91 100644
--- a/drivers/net/phy/mtk/mt753x/Makefile
+++ b/drivers/net/phy/mtk/mt753x/Makefile
@@ -7,5 +7,5 @@ obj-$(CONFIG_MT753X_GSW) += mt753x.o
@@ -9,11 +25,11 @@
- mt753x_common.o mt753x_vlan.o mt753x_nl.o
+ mt753x_common.o mt753x_vlan.o mt753x_nl.o mt753x_phy.o
-Index: drivers/net/phy/mtk/mt753x/mt7531.c
-===================================================================
+diff --git a/drivers/net/phy/mtk/mt753x/mt7531.c b/drivers/net/phy/mtk/mt753x/mt7531.c
+index b27c679a5..512a89a94 100755
--- a/drivers/net/phy/mtk/mt753x/mt7531.c
+++ b/drivers/net/phy/mtk/mt753x/mt7531.c
-@@ -658,6 +658,27 @@ static void mt7531_core_pll_setup(struct
+@@ -662,6 +662,27 @@ static void mt7531_core_pll_setup(struct gsw_mt753x *gsw)
static int mt7531_internal_phy_calibration(struct gsw_mt753x *gsw)
{
@@ -41,11 +57,11 @@
return 0;
}
-Index: drivers/net/phy/mtk/mt753x/mt753x.h
-===================================================================
+diff --git a/drivers/net/phy/mtk/mt753x/mt753x.h b/drivers/net/phy/mtk/mt753x/mt753x.h
+index 344d2b0c6..252ce350f 100644
--- a/drivers/net/phy/mtk/mt753x/mt753x.h
+++ b/drivers/net/phy/mtk/mt753x/mt753x.h
-@@ -140,6 +140,8 @@ void mt753x_irq_enable(struct gsw_mt753x
+@@ -146,6 +146,8 @@ void mt753x_irq_enable(struct gsw_mt753x *gsw);
int mt753x_phy_calibration(struct gsw_mt753x *gsw, u8 phyaddr);
int extphy_init(struct gsw_mt753x *gsw, int addr);
@@ -54,9 +70,9 @@
/* MDIO Indirect Access Registers */
#define MII_MMD_ACC_CTL_REG 0x0d
#define MMD_CMD_S 14
-Index: drivers/net/phy/mtk/mt753x/mt753x_phy.c
-===================================================================
+diff --git a/drivers/net/phy/mtk/mt753x/mt753x_phy.c b/drivers/net/phy/mtk/mt753x/mt753x_phy.c
new file mode 100644
+index 000000000..0c6f9c930
--- /dev/null
+++ b/drivers/net/phy/mtk/mt753x/mt753x_phy.c
@@ -0,0 +1,1069 @@
@@ -1129,9 +1145,9 @@
+
+ return ret;
+}
-Index: drivers/net/phy/mtk/mt753x/mt753x_phy.h
-===================================================================
+diff --git a/drivers/net/phy/mtk/mt753x/mt753x_phy.h b/drivers/net/phy/mtk/mt753x/mt753x_phy.h
new file mode 100644
+index 000000000..1b9e2ea80
--- /dev/null
+++ b/drivers/net/phy/mtk/mt753x/mt753x_phy.h
@@ -0,0 +1,145 @@
@@ -1280,3 +1296,6 @@
+#define DA_TX_I2MPB_D_GBE BITS(8, 13)
+
+#endif /* _MT753X_REGS_H_ */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/739-mt7531-gsw-port5_external_phy_init.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2714-mt7531-gsw-port5_external_phy_init.patch
old mode 100755
new mode 100644
similarity index 87%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/739-mt7531-gsw-port5_external_phy_init.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2714-mt7531-gsw-port5_external_phy_init.patch
index 0d88c60..237c68e
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/739-mt7531-gsw-port5_external_phy_init.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2714-mt7531-gsw-port5_external_phy_init.patch
@@ -1,9 +1,9 @@
-From 9206472ba03032aea120604e8637b52408ca4b3a Mon Sep 17 00:00:00 2001
-From: Landen Chao <landen.chao@mediatek.com>
-Date: Fri, 29 May 2020 15:12:35 +0800
-Subject: [PATCH 2/2] 740_patch
+From 13b169a35dfff523263d20d0d97e46401f6c692f Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:31 +0800
+Subject: [PATCH]
+ [networking][999-2714-mt7531-gsw-port5_external_phy_init.patch]
-Change-Id: I7e0164751702f573d5185c4290ff78688f42f603
---
drivers/net/phy/mtk/mt753x/Makefile | 3 +-
drivers/net/phy/mtk/mt753x/mt7531.c | 3 +
@@ -15,7 +15,7 @@
create mode 100644 drivers/net/phy/mtk/mt753x/mt753x_extphy.h
diff --git a/drivers/net/phy/mtk/mt753x/Makefile b/drivers/net/phy/mtk/mt753x/Makefile
-index 384b0ff7..694ffa83 100644
+index b5a63fe91..16e977528 100644
--- a/drivers/net/phy/mtk/mt753x/Makefile
+++ b/drivers/net/phy/mtk/mt753x/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_MT753X_GSW) += mt753x.o
@@ -27,10 +27,10 @@
+ mt753x_extphy.o
diff --git a/drivers/net/phy/mtk/mt753x/mt7531.c b/drivers/net/phy/mtk/mt753x/mt7531.c
-index 04729835..4a2943b1 100644
+index 512a89a94..3e2187d21 100755
--- a/drivers/net/phy/mtk/mt753x/mt7531.c
+++ b/drivers/net/phy/mtk/mt753x/mt7531.c
-@@ -265,6 +265,9 @@ static int mt7531_set_port_sgmii_force_mode(struct gsw_mt753x *gsw, u32 port,
+@@ -264,6 +264,9 @@ static int mt7531_set_port_sgmii_force_mode(struct gsw_mt753x *gsw, u32 port,
return -EINVAL;
}
@@ -41,11 +41,11 @@
switch (port_cfg->speed) {
diff --git a/drivers/net/phy/mtk/mt753x/mt753x.h b/drivers/net/phy/mtk/mt753x/mt753x.h
-index 5053a7d7..a3f343cd 100644
+index 252ce350f..c23fd9e5f 100644
--- a/drivers/net/phy/mtk/mt753x/mt753x.h
+++ b/drivers/net/phy/mtk/mt753x/mt753x.h
-@@ -154,6 +154,7 @@ void mt753x_irq_worker(struct work_struct *work);
- void mt753x_irq_enable(struct gsw_mt753x *gsw);
+@@ -147,6 +147,7 @@ int mt753x_phy_calibration(struct gsw_mt753x *gsw, u8 phyaddr);
+ int extphy_init(struct gsw_mt753x *gsw, int addr);
int mt753x_phy_calibration(struct gsw_mt753x *gsw, u8 phyaddr);
+int extphy_init(struct gsw_mt753x *gsw, int addr);
@@ -54,7 +54,7 @@
#define MII_MMD_ACC_CTL_REG 0x0d
diff --git a/drivers/net/phy/mtk/mt753x/mt753x_extphy.c b/drivers/net/phy/mtk/mt753x/mt753x_extphy.c
new file mode 100644
-index 00000000..f58e8a62
+index 000000000..f58e8a62d
--- /dev/null
+++ b/drivers/net/phy/mtk/mt753x/mt753x_extphy.c
@@ -0,0 +1,69 @@
@@ -129,7 +129,7 @@
+}
diff --git a/drivers/net/phy/mtk/mt753x/mt753x_extphy.h b/drivers/net/phy/mtk/mt753x/mt753x_extphy.h
new file mode 100644
-index 00000000..2b72c8a9
+index 000000000..2b72c8a9d
--- /dev/null
+++ b/drivers/net/phy/mtk/mt753x/mt753x_extphy.h
@@ -0,0 +1,18 @@
@@ -152,5 +152,5 @@
+};
+#endif
--
-2.17.1
+2.34.1
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2715-add-gpy211-phy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2715-add-gpy211-phy-support.patch
new file mode 100644
index 0000000..7613c86
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2715-add-gpy211-phy-support.patch
@@ -0,0 +1,41 @@
+From e18ad3270a1bdd776f5d7b13c4756efbd890825b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:31 +0800
+Subject: [PATCH] [networking][999-2715-add-gpy211-phy-support.patch]
+
+---
+ drivers/net/phy/Kconfig | 5 +++++
+ drivers/net/phy/Makefile | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index ec5c66d0a..3a3c12566 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -473,6 +473,11 @@ config FIXED_PHY
+
+ Currently tested with mpc866ads and mpc8349e-mitx.
+
++config GPY211_PHY
++ tristate "GPY211 PHY"
++ ---help---
++ Supports the Intel GPY211 PHY with rate adaption.
++
+ config ICPLUS_PHY
+ tristate "ICPlus PHYs"
+ ---help---
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index f4feb0e3d..1d368d1d5 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -88,6 +88,7 @@ obj-$(CONFIG_DP83TC811_PHY) += dp83tc811.o
+ obj-$(CONFIG_DP83848_PHY) += dp83848.o
+ obj-$(CONFIG_DP83867_PHY) += dp83867.o
+ obj-$(CONFIG_FIXED_PHY) += fixed_phy.o
++obj-$(CONFIG_GPY211_PHY) += gpy211.o
+ obj-$(CONFIG_ICPLUS_PHY) += icplus.o
+ obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
+ obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2716-en8801sc-gphy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2716-en8801sc-gphy-support.patch
new file mode 100644
index 0000000..47168b9
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2716-en8801sc-gphy-support.patch
@@ -0,0 +1,41 @@
+From 43abbf9e88d9cf44e123a17d6d46db06fbb51da7 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:31 +0800
+Subject: [PATCH] [networking][999-2716-en8801sc-gphy-support.patch]
+
+---
+ drivers/net/phy/Kconfig | 5 +++++
+ drivers/net/phy/Makefile | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 3a3c12566..87eaaad76 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -345,6 +345,11 @@ config SFP
+ depends on HWMON || HWMON=n
+ select MDIO_I2C
+
++config AIROHA_EN8801SC_PHY
++ tristate "Drivers for Airoha EN8801S Gigabit PHYs for MediaTek SoC."
++ ---help---
++ Currently supports the Airoha EN8801S PHY for MediaTek SoC.
++
+ config AIROHA_EN8811H_PHY
+ tristate "Drivers for Airoha EN8811H 2.5G Gigabit PHY"
+ ---help---
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index 1d368d1d5..801550726 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -68,6 +68,7 @@ aquantia-objs += aquantia_main.o
+ ifdef CONFIG_HWMON
+ aquantia-objs += aquantia_hwmon.o
+ endif
++obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
+ obj-$(CONFIG_AIROHA_EN8811H_PHY) += air_en8811h.o
+ obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
+ obj-$(CONFIG_AX88796B_PHY) += ax88796b.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2717-add-mediatek-2p5ge-phy-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2717-add-mediatek-2p5ge-phy-support.patch
new file mode 100644
index 0000000..b750c57
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2717-add-mediatek-2p5ge-phy-support.patch
@@ -0,0 +1,41 @@
+From d3e70b511ec583b7cced3ffd3c34700084c9149d Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:31 +0800
+Subject: [PATCH] [networking][999-2717-add-mediatek-2p5ge-phy-support.patch]
+
+---
+ drivers/net/phy/Kconfig | 5 +++++
+ drivers/net/phy/Makefile | 1 +
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index 87eaaad76..45aaf7203 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -539,6 +539,11 @@ config MEDIATEK_GE_SOC_PHY
+ present in the SoCs efuse and will dynamically calibrate VCM
+ (common-mode voltage) during startup.
+
++config MEDIATEK_2P5GE_PHY
++ tristate "MediaTek 2.5Gb Ethernet PHYs"
++ ---help---
++ Supports MediaTek internal 2.5Gb Ethernet PHYs.
++
+ config MICREL_PHY
+ tristate "Micrel PHYs"
+ ---help---
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index 801550726..998de790e 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -98,6 +98,7 @@ obj-$(CONFIG_MARVELL_PHY) += marvell.o
+ obj-$(CONFIG_MARVELL_10G_PHY) += marvell10g.o
+ obj-$(CONFIG_MEDIATEK_GE_PHY) += mediatek-ge.o
+ obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mediatek-ge-soc.o
++obj-$(CONFIG_MEDIATEK_2P5GE_PHY)+= mediatek-2p5ge.o
+ obj-$(CONFIG_MESON_GXL_PHY) += meson-gxl.o
+ obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
+ obj-$(CONFIG_MICREL_PHY) += micrel.o
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch
similarity index 96%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch
index 0e38dad..c128bbe 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/751-net-phy-aquantia-add-firmware-download.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2719-net-phy-aquantia-add-firmware-download.patch
@@ -1,5 +1,20 @@
+From 2fd17c806f5ad23f9958c358cdc26f618f05d5df Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:32 +0800
+Subject: [PATCH]
+ [networking][999-2719-net-phy-aquantia-add-firmware-download.patch]
+
+---
+ drivers/net/phy/Kconfig | 33 +-
+ drivers/net/phy/Makefile | 3 +
+ drivers/net/phy/aquantia.h | 64 ++
+ drivers/net/phy/aquantia_firmware.c | 1090 +++++++++++++++++++++++++++
+ drivers/net/phy/aquantia_main.c | 92 ++-
+ 5 files changed, 1241 insertions(+), 41 deletions(-)
+ create mode 100644 drivers/net/phy/aquantia_firmware.c
+
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
-index 7b49c94..5a79af2 100644
+index c0e09c99d..d467834eb 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -372,7 +372,38 @@ config AMD_PHY
@@ -43,10 +58,10 @@
config AX88796B_PHY
tristate "Asix PHYs"
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
-index 043a697..4f67110 100644
+index 8b57d6105..e9653de36 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
-@@ -67,5 +67,8 @@ aquantia-objs += aquantia_main.o
+@@ -68,6 +68,9 @@ aquantia-objs += aquantia_main.o
ifdef CONFIG_HWMON
aquantia-objs += aquantia_hwmon.o
endif
@@ -54,9 +69,10 @@
+aquantia-objs += aquantia_firmware.o
+endif
obj-$(CONFIG_AIROHA_EN8801SC_PHY) += en8801sc.o
+ obj-$(CONFIG_AIROHA_EN8811H_PHY) += air_en8811h.o
obj-$(CONFIG_AQUANTIA_PHY) += aquantia.o
diff --git a/drivers/net/phy/aquantia.h b/drivers/net/phy/aquantia.h
-index 5a16caa..ab1c241 100644
+index 5a16caab7..ab1c241d3 100644
--- a/drivers/net/phy/aquantia.h
+++ b/drivers/net/phy/aquantia.h
@@ -9,8 +9,72 @@
@@ -134,10 +150,10 @@
+#endif
diff --git a/drivers/net/phy/aquantia_firmware.c b/drivers/net/phy/aquantia_firmware.c
new file mode 100644
-index 0000000..622557c
+index 000000000..d2828aad4
--- /dev/null
+++ b/drivers/net/phy/aquantia_firmware.c
-@@ -0,0 +1,1090 @@
+@@ -0,0 +1,1091 @@
+// SPDX-License-Identifier: GPL-2.0
+/* FW download driver for Aquantia PHY
+ */
@@ -1196,7 +1212,8 @@
+ "aqr_firmware_gandload_thread");
+ if (IS_ERR(gangload_kthread)) {
+ dev_err(dev,
-+ "failed to create aqr_firmware_gandload_thread\n");
++ "failed to create aqr_firmware_gandload_thread(%ld)\n",
++ PTR_ERR(gangload_kthread));
+ return PTR_ERR(gangload_kthread);
+ }
+ wake_up_process(gangload_kthread);
@@ -1229,7 +1246,7 @@
+ return ret;
+}
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
-index a8c828b..d98757f 100644
+index e7495c9a7..36f1aac4f 100644
--- a/drivers/net/phy/aquantia_main.c
+++ b/drivers/net/phy/aquantia_main.c
@@ -8,10 +8,12 @@
@@ -1245,7 +1262,7 @@
#include "aquantia.h"
-@@ -39,7 +40,6 @@
+@@ -39,7 +41,6 @@
#define MDIO_AN_VEND_PROV_2500BASET_FULL BIT(10)
#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN BIT(4)
#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK GENMASK(3, 0)
@@ -1253,7 +1270,7 @@
#define MDIO_AN_TX_VEND_STATUS1 0xc800
#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK GENMASK(3, 1)
-@@ -73,18 +73,6 @@
+@@ -73,18 +74,6 @@
#define MDIO_AN_RX_VEND_STAT3 0xe832
#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
@@ -1272,7 +1289,7 @@
/* Vendor specific 1, MDIO_MMD_VEND1 */
#define VEND1_GLOBAL_FW_ID 0x0020
#define VEND1_GLOBAL_FW_ID_MAJOR GENMASK(15, 8)
-@@ -124,31 +112,6 @@
+@@ -124,31 +113,6 @@
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2 BIT(1)
#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 BIT(0)
@@ -1304,7 +1321,7 @@
static int aqr107_get_sset_count(struct phy_device *phydev)
{
return AQR107_SGMII_STAT_SZ;
-@@ -422,7 +361,7 @@ static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
+@@ -398,7 +362,7 @@ static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
return 0;
}
@@ -1313,7 +1330,7 @@
{
int val = 0;
-@@ -482,7 +421,7 @@ static int aqr107_wait_reset_complete(struct phy_device *phydev)
+@@ -458,7 +422,7 @@ static int aqr107_wait_reset_complete(struct phy_device *phydev)
return val ? 0 : -ETIMEDOUT;
}
@@ -1322,7 +1339,7 @@
{
u8 fw_major, fw_minor, build_id, prov_id;
int val;
-@@ -505,6 +444,21 @@ static void aqr107_chip_info(struct phy_device *phydev)
+@@ -481,6 +445,21 @@ static void aqr107_chip_info(struct phy_device *phydev)
fw_major, fw_minor, build_id, prov_id);
}
@@ -1344,7 +1361,7 @@
static int aqr107_config_init(struct phy_device *phydev)
{
int ret;
-@@ -520,6 +470,12 @@ static int aqr107_config_init(struct phy_device *phydev)
+@@ -499,6 +478,12 @@ static int aqr107_config_init(struct phy_device *phydev)
ret = aqr107_wait_reset_complete(phydev);
if (!ret)
aqr107_chip_info(phydev);
@@ -1357,7 +1374,7 @@
return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
}
-@@ -604,12 +556,39 @@ static void aqr107_link_change_notify(struct phy_device *phydev)
+@@ -574,12 +559,41 @@ static void aqr107_link_change_notify(struct phy_device *phydev)
static int aqr107_suspend(struct phy_device *phydev)
{
@@ -1388,12 +1405,17 @@
+ "aqr_firmware_heartbeat_thread");
+ if (IS_ERR(priv->heartbeat_thread)) {
+ phydev_err(phydev,
-+ "Failed to create aqr_firmware_heartbeat_thread\n");
-+ }
-+ wake_up_process(priv->heartbeat_thread);
++ "Failed to create aqr_firmware_heartbeat_thread(%ld)\n",
++ PTR_ERR(priv->heartbeat_thread));
++ priv->heartbeat_thread = NULL;
++ } else
++ wake_up_process(priv->heartbeat_thread);
+ }
+ spin_unlock(&priv->lock);
+#endif
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
MDIO_CTRL1_LPOWER);
}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/752-net-dsa-phy-coverity-scan.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2720-net-dsa-phy-coverity-scan.patch
old mode 100755
new mode 100644
similarity index 78%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/752-net-dsa-phy-coverity-scan.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2720-net-dsa-phy-coverity-scan.patch
index 17921e8..dfdb019
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/752-net-dsa-phy-coverity-scan.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2720-net-dsa-phy-coverity-scan.patch
@@ -1,7 +1,18 @@
-diff -Naur a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
---- a/drivers/net/dsa/mt7530.c 2022-11-25 14:10:39.452491570 +0800
-+++ b/drivers/net/dsa/mt7530.c 2022-11-28 09:47:11.157096408 +0800
-@@ -2476,7 +2476,7 @@
+From 98719219a038adac88f2fae9caaecb7e84704d09 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:32 +0800
+Subject: [PATCH] [networking][999-2720-net-dsa-phy-coverity-scan.patch]
+
+---
+ drivers/net/dsa/mt7530.c | 4 ++-
+ drivers/net/dsa/mt7531_phy.c | 56 +++++++++++++++++++-----------------
+ 2 files changed, 32 insertions(+), 28 deletions(-)
+
+diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
+index 290a2e77a..21fa3e300 100644
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2477,7 +2477,7 @@ static int
mt7531_cpu_port_config(struct dsa_switch *ds, int port)
{
struct mt7530_priv *priv = ds->priv;
@@ -10,7 +21,7 @@
int speed;
switch (port) {
-@@ -2496,6 +2496,8 @@
+@@ -2497,6 +2497,8 @@ mt7531_cpu_port_config(struct dsa_switch *ds, int port)
priv->p6_interface = interface;
break;
};
@@ -19,10 +30,11 @@
if (interface == PHY_INTERFACE_MODE_2500BASEX)
speed = SPEED_2500;
-diff -Naur a/drivers/net/dsa/mt7531_phy.c b/drivers/net/dsa/mt7531_phy.c
---- a/drivers/net/dsa/mt7531_phy.c 2022-11-25 14:10:47.032465430 +0800
-+++ b/drivers/net/dsa/mt7531_phy.c 2022-11-29 09:56:05.024665073 +0800
-@@ -252,7 +252,7 @@
+diff --git a/drivers/net/dsa/mt7531_phy.c b/drivers/net/dsa/mt7531_phy.c
+index a5c1e7d54..aaa03c678 100644
+--- a/drivers/net/dsa/mt7531_phy.c
++++ b/drivers/net/dsa/mt7531_phy.c
+@@ -252,7 +252,7 @@ static int ge_cal_rext(struct dsa_switch *ds, u8 phyaddr, u32 delay)
u16 dev1e_17a_tmp, dev1e_e0_tmp;
/* *** Iext/Rext Cal start ************ */
@@ -31,7 +43,7 @@
/* analog calibration enable, Rext calibration enable */
/* 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a */
/* 1e_dc[0]:rg_txvos_calen */
-@@ -296,7 +296,7 @@
+@@ -296,7 +296,7 @@ static int ge_cal_rext(struct dsa_switch *ds, u8 phyaddr, u32 delay)
all_ana_cal_status = ANACAL_FINISH;
//printk(" GE Rext AnaCal Done! (%d)(0x%x) \r\n", cnt, rg_zcal_ctrl);
} else {
@@ -40,7 +52,7 @@
dev1e_e0_tmp = tc_phy_read_dev_reg(ds, PHY0, 0x1e, 0xe0);
if ((rg_zcal_ctrl == 0x3F) || (rg_zcal_ctrl == 0x00)) {
all_ana_cal_status = ANACAL_SATURATION; /* need to FT(IC fail?) */
-@@ -718,32 +718,34 @@
+@@ -718,32 +718,34 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
} else if (phyaddr == 1) {
if (calibration_pair == ANACAL_PAIR_A)
tx_amp_temp = tx_amp_temp - 1;
@@ -91,7 +103,7 @@
}
reg_temp = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg)&(~0xff00);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
-@@ -858,7 +860,7 @@
+@@ -858,7 +860,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = 0x0000;
reg_backup |= ((tx_amp_temp << 10) | (tx_amp_temp << 0));
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x12, reg_backup);
@@ -100,7 +112,7 @@
//printk("PORT[%d] 1e.012 = %x (OFFSET_1000M_PAIR_A)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x16);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -866,7 +868,7 @@
+@@ -866,7 +868,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (tx_amp_temp << 0);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x16, reg_backup);
@@ -109,7 +121,7 @@
//printk("PORT[%d] 1e.016 = %x (OFFSET_TESTMODE_1000M_PAIR_A)\n", phyaddr, reg_backup);
}
else if(calibration_pair == ANACAL_PAIR_B){
-@@ -876,7 +878,7 @@
+@@ -876,7 +878,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = 0x0000;
reg_backup |= ((tx_amp_temp << 8) | (tx_amp_temp << 0));
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x17, reg_backup);
@@ -118,7 +130,7 @@
//printk("PORT[%d] 1e.017 = %x (OFFSET_1000M_PAIR_B)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x18);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -884,7 +886,7 @@
+@@ -884,7 +886,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (tx_amp_temp << 0);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x18, reg_backup);
@@ -127,7 +139,7 @@
//printk("PORT[%d] 1e.018 = %x (OFFSET_TESTMODE_1000M_PAIR_B)\n", phyaddr, reg_backup);
}
else if(calibration_pair == ANACAL_PAIR_C){
-@@ -894,7 +896,7 @@
+@@ -894,7 +896,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f00));
reg_backup |= (tx_amp_temp << 8);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x19, reg_backup);
@@ -136,7 +148,7 @@
//printk("PORT[%d] 1e.019 = %x (OFFSET_1000M_PAIR_C)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x20);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -902,7 +904,7 @@
+@@ -902,7 +904,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (tx_amp_temp << 0);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x20, reg_backup);
@@ -145,7 +157,7 @@
//printk("PORT[%d] 1e.020 = %x (OFFSET_TESTMODE_1000M_PAIR_C)\n", phyaddr, reg_backup);
}
else if(calibration_pair == ANACAL_PAIR_D){
-@@ -912,7 +914,7 @@
+@@ -912,7 +914,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f00));
reg_backup |= (tx_amp_temp << 8);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x21, reg_backup);
@@ -154,7 +166,7 @@
//printk("PORT[%d] 1e.021 = %x (OFFSET_1000M_PAIR_D)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(ds, phyaddr, 0x1e, 0x22);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -920,7 +922,7 @@
+@@ -920,7 +922,7 @@ static int ge_cal_tx_amp(struct dsa_switch *ds, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (tx_amp_temp << 0);
tc_phy_write_dev_reg(ds, phyaddr, 0x1e, 0x22, reg_backup);
@@ -163,7 +175,7 @@
//printk("PORT[%d] 1e.022 = %x (OFFSET_TESTMODE_1000M_PAIR_D)\n", phyaddr, reg_backup);
}
-@@ -1352,7 +1354,7 @@
+@@ -1352,7 +1354,7 @@ static void mt7531_eee_setting(struct dsa_switch *ds, u32 port)
int mt7531_phy_setup(struct dsa_switch *ds)
{
@@ -172,4 +184,6 @@
int i;
mt7531_phy_setting(ds);
-
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/753-net-mt753x-phy-coverity-scan.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2721-net-mt753x-phy-coverity-scan.patch
old mode 100755
new mode 100644
similarity index 79%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/753-net-mt753x-phy-coverity-scan.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2721-net-mt753x-phy-coverity-scan.patch
index c4d7d4c..a9b1316
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/753-net-mt753x-phy-coverity-scan.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2721-net-mt753x-phy-coverity-scan.patch
@@ -1,7 +1,18 @@
-diff -Naur a/drivers/net/phy/mtk/mt753x/mt753x_common.c b/drivers/net/phy/mtk/mt753x/mt753x_common.c
---- a/drivers/net/phy/mtk/mt753x/mt753x_common.c 2022-11-25 14:12:06.308223474 +0800
-+++ b/drivers/net/phy/mtk/mt753x/mt753x_common.c 2022-11-25 14:21:52.038450276 +0800
-@@ -49,6 +49,9 @@
+From 520aea1caf199f454a0988f23d000c18256caa2b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:32 +0800
+Subject: [PATCH] [networking][999-2721-net-mt753x-phy-coverity-scan.patch]
+
+---
+ drivers/net/phy/mtk/mt753x/mt753x_common.c | 3 ++
+ drivers/net/phy/mtk/mt753x/mt753x_phy.c | 56 +++++++++++-----------
+ 2 files changed, 32 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/net/phy/mtk/mt753x/mt753x_common.c b/drivers/net/phy/mtk/mt753x/mt753x_common.c
+index 4015ddf12..0e08c8532 100644
+--- a/drivers/net/phy/mtk/mt753x/mt753x_common.c
++++ b/drivers/net/phy/mtk/mt753x/mt753x_common.c
+@@ -49,6 +49,9 @@ static void display_port_link_status(struct gsw_mt753x *gsw, u32 port)
case MAC_SPD_2500:
speed = "2.5Gbps";
break;
@@ -11,10 +22,11 @@
}
if (pmsr & MAC_LNK_STS) {
-diff -Naur a/drivers/net/phy/mtk/mt753x/mt753x_phy.c b/drivers/net/phy/mtk/mt753x/mt753x_phy.c
---- a/drivers/net/phy/mtk/mt753x/mt753x_phy.c 2022-11-25 14:12:34.160149995 +0800
-+++ b/drivers/net/phy/mtk/mt753x/mt753x_phy.c 2022-11-29 14:12:28.261884707 +0800
-@@ -141,7 +141,7 @@
+diff --git a/drivers/net/phy/mtk/mt753x/mt753x_phy.c b/drivers/net/phy/mtk/mt753x/mt753x_phy.c
+index 0c6f9c930..afc46cdd8 100644
+--- a/drivers/net/phy/mtk/mt753x/mt753x_phy.c
++++ b/drivers/net/phy/mtk/mt753x/mt753x_phy.c
+@@ -141,7 +141,7 @@ int ge_cal_rext(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
u16 dev1e_17a_tmp, dev1e_e0_tmp;
/* *** Iext/Rext Cal start ************ */
@@ -23,7 +35,7 @@
/* analog calibration enable, Rext calibration enable */
/* 1e_db[12]:rg_cal_ckinv, [8]:rg_ana_calen, [4]:rg_rext_calen, [0]:rg_zcalen_a */
/* 1e_dc[0]:rg_txvos_calen */
-@@ -185,7 +185,7 @@
+@@ -185,7 +185,7 @@ int ge_cal_rext(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
all_ana_cal_status = ANACAL_FINISH;
//printk(" GE Rext AnaCal Done! (%d)(0x%x) \r\n", cnt, rg_zcal_ctrl);
} else {
@@ -32,7 +44,7 @@
dev1e_e0_tmp = tc_phy_read_dev_reg(gsw, PHY0, 0x1e, 0xe0);
if ((rg_zcal_ctrl == 0x3F) || (rg_zcal_ctrl == 0x00)) {
all_ana_cal_status = ANACAL_SATURATION; /* need to FT(IC fail?) */
-@@ -580,33 +580,35 @@
+@@ -580,33 +580,35 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
} else if (phyaddr == 1) {
if (calibration_pair == ANACAL_PAIR_A)
tx_amp_temp = tx_amp_temp - 1;
@@ -85,7 +97,7 @@
reg_temp = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, tx_amp_reg)&(~0xff00);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, tx_amp_reg_100,(tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, tx_amp_reg, (tx_amp_temp|((tx_amp_temp)<<tx_amp_reg_shift)));
-@@ -704,7 +706,7 @@
+@@ -704,7 +706,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = 0x0000;
reg_backup |= ((reg_tmp << 10) | (reg_tmp << 0));
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x12, reg_backup);
@@ -94,7 +106,7 @@
//printk("PORT[%d] 1e.012 = %x (OFFSET_1000M_PAIR_A)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x16);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -712,7 +714,7 @@
+@@ -712,7 +714,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (reg_tmp << 0);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x16, reg_backup);
@@ -103,7 +115,7 @@
//printk("PORT[%d] 1e.016 = %x (OFFSET_TESTMODE_1000M_PAIR_A)\n", phyaddr, reg_backup);
}
else if(calibration_pair == ANACAL_PAIR_B){
-@@ -722,7 +724,7 @@
+@@ -722,7 +724,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = 0x0000;
reg_backup |= ((reg_tmp << 8) | (reg_tmp << 0));
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x17, reg_backup);
@@ -112,7 +124,7 @@
//printk("PORT[%d] 1e.017 = %x (OFFSET_1000M_PAIR_B)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x18);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -730,7 +732,7 @@
+@@ -730,7 +732,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (reg_tmp << 0);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x18, reg_backup);
@@ -121,7 +133,7 @@
//printk("PORT[%d] 1e.018 = %x (OFFSET_TESTMODE_1000M_PAIR_B)\n", phyaddr, reg_backup);
}
else if(calibration_pair == ANACAL_PAIR_C){
-@@ -740,7 +742,7 @@
+@@ -740,7 +742,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f00));
reg_backup |= (reg_tmp << 8);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x19, reg_backup);
@@ -130,7 +142,7 @@
//printk("PORT[%d] 1e.019 = %x (OFFSET_1000M_PAIR_C)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x20);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -748,7 +750,7 @@
+@@ -748,7 +750,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (reg_tmp << 0);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x20, reg_backup);
@@ -139,7 +151,7 @@
//printk("PORT[%d] 1e.020 = %x (OFFSET_TESTMODE_1000M_PAIR_C)\n", phyaddr, reg_backup);
}
else if(calibration_pair == ANACAL_PAIR_D){
-@@ -758,7 +760,7 @@
+@@ -758,7 +760,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f00));
reg_backup |= (reg_tmp << 8);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x21, reg_backup);
@@ -148,7 +160,7 @@
//printk("PORT[%d] 1e.021 = %x (OFFSET_1000M_PAIR_D)\n", phyaddr, reg_backup);
reg_backup = tc_phy_read_dev_reg(gsw, phyaddr, 0x1e, 0x22);
reg_tmp = ((reg_backup & 0x3f) >> 0);
-@@ -766,7 +768,7 @@
+@@ -766,7 +768,7 @@ int ge_cal_tx_amp(struct gsw_mt753x *gsw, u8 phyaddr, u32 delay)
reg_backup = (reg_backup & (~0x3f));
reg_backup |= (reg_tmp << 0);
tc_phy_write_dev_reg(gsw, phyaddr, 0x1e, 0x22, reg_backup);
@@ -157,3 +169,6 @@
//printk("PORT[%d] 1e.022 = %x (OFFSET_TESTMODE_1000M_PAIR_D)\n", phyaddr, reg_backup);
}
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2722-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2722-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch
new file mode 100644
index 0000000..8e87e12
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2722-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch
@@ -0,0 +1,24 @@
+From 14155ead210d465dc00552fa2537bdafc25054a5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:33 +0800
+Subject: [PATCH]
+ [networking][999-2722-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch]
+
+---
+ include/dt-bindings/phy/phy.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
+index b6a1eaf1b..1f3f866fa 100644
+--- a/include/dt-bindings/phy/phy.h
++++ b/include/dt-bindings/phy/phy.h
+@@ -16,5 +16,6 @@
+ #define PHY_TYPE_USB2 3
+ #define PHY_TYPE_USB3 4
+ #define PHY_TYPE_UFS 5
++#define PHY_TYPE_DP 6
+
+ #endif /* _DT_BINDINGS_PHY */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2723-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2723-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch
new file mode 100644
index 0000000..c0e2127
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2723-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch
@@ -0,0 +1,24 @@
+From 971fc691db21a6d231545f8519d920301818c2d5 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:33 +0800
+Subject: [PATCH]
+ [networking][999-2723-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch]
+
+---
+ include/dt-bindings/phy/phy.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
+index 1f3f866fa..3727ef721 100644
+--- a/include/dt-bindings/phy/phy.h
++++ b/include/dt-bindings/phy/phy.h
+@@ -17,5 +17,6 @@
+ #define PHY_TYPE_USB3 4
+ #define PHY_TYPE_UFS 5
+ #define PHY_TYPE_DP 6
++#define PHY_TYPE_XPCS 7
+
+ #endif /* _DT_BINDINGS_PHY */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2724-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2724-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch
new file mode 100644
index 0000000..41db424
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2724-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch
@@ -0,0 +1,24 @@
+From 313a776ae1ef71f826cd39545e358a3735c1a032 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:33 +0800
+Subject: [PATCH]
+ [networking][999-2724-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch]
+
+---
+ include/dt-bindings/phy/phy.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h
+index 3727ef721..36e8c241c 100644
+--- a/include/dt-bindings/phy/phy.h
++++ b/include/dt-bindings/phy/phy.h
+@@ -18,5 +18,6 @@
+ #define PHY_TYPE_UFS 5
+ #define PHY_TYPE_DP 6
+ #define PHY_TYPE_XPCS 7
++#define PHY_TYPE_SGMII 8
+
+ #endif /* _DT_BINDINGS_PHY */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9010-iwconfig-wireless-rate-fix.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2725-iwconfig-wireless-rate-fix.patch
similarity index 63%
rename from recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9010-iwconfig-wireless-rate-fix.patch
rename to recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2725-iwconfig-wireless-rate-fix.patch
index b29e4cc..951afc2 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/9010-iwconfig-wireless-rate-fix.patch
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2725-iwconfig-wireless-rate-fix.patch
@@ -1,20 +1,34 @@
---- a/include/uapi/linux/wireless.h
-+++ b/include/uapi/linux/wireless.h
-@@ -678,7 +678,7 @@
- * Generic format for most parameters that fit in an int
- */
- struct iw_param {
-- __s32 value; /* The value of the parameter itself */
-+ __u64 value; /* The value of the parameter itself */
- __u8 fixed; /* Hardware should not use auto select */
- __u8 disabled; /* Disable the feature */
- __u16 flags; /* Various specifc flags (if any) */
-@@ -1002,7 +1002,7 @@ struct iw_range {
-
- /* Rates */
- __u8 num_bitrates; /* Number of entries in the list */
-- __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */
-+ __u64 bitrate[IW_MAX_BITRATES]; /* list, in bps */
-
- /* RTS threshold */
- __s32 min_rts; /* Minimal RTS threshold */
+From 572be3e7a2e9f41c64dd6c8c89cc763b97ecab6c Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:33 +0800
+Subject: [PATCH] [networking][999-2725-iwconfig-wireless-rate-fix.patch]
+
+---
+ include/uapi/linux/wireless.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/uapi/linux/wireless.h b/include/uapi/linux/wireless.h
+index 24f3371ad..590c90b14 100644
+--- a/include/uapi/linux/wireless.h
++++ b/include/uapi/linux/wireless.h
+@@ -678,7 +678,7 @@
+ * Generic format for most parameters that fit in an int
+ */
+ struct iw_param {
+- __s32 value; /* The value of the parameter itself */
++ __u64 value; /* The value of the parameter itself */
+ __u8 fixed; /* Hardware should not use auto select */
+ __u8 disabled; /* Disable the feature */
+ __u16 flags; /* Various specifc flags (if any) */
+@@ -1002,7 +1002,7 @@ struct iw_range {
+
+ /* Rates */
+ __u8 num_bitrates; /* Number of entries in the list */
+- __s32 bitrate[IW_MAX_BITRATES]; /* list, in bps */
++ __u64 bitrate[IW_MAX_BITRATES]; /* list, in bps */
+
+ /* RTS threshold */
+ __s32 min_rts; /* Minimal RTS threshold */
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2800-misc-add-mtk-platform.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2800-misc-add-mtk-platform.patch
new file mode 100644
index 0000000..19cab49
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2800-misc-add-mtk-platform.patch
@@ -0,0 +1,32 @@
+From cbf9eb1b168ed4b650d464512f6502d3d1668813 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:34 +0800
+Subject: [PATCH] [misc][999-2800-misc-add-mtk-platform.patch]
+
+---
+ drivers/misc/Kconfig | 1 +
+ drivers/misc/Makefile | 1 +
+ 2 files changed, 2 insertions(+)
+
+diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
+index c55b63750..4cd30fab5 100644
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -481,4 +481,5 @@ source "drivers/misc/cxl/Kconfig"
+ source "drivers/misc/ocxl/Kconfig"
+ source "drivers/misc/cardreader/Kconfig"
+ source "drivers/misc/habanalabs/Kconfig"
++source "drivers/misc/mediatek/Kconfig"
+ endmenu
+diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
+index c1860d35d..30b5d29a1 100644
+--- a/drivers/misc/Makefile
++++ b/drivers/misc/Makefile
+@@ -57,3 +57,4 @@ obj-y += cardreader/
+ obj-$(CONFIG_PVPANIC) += pvpanic.o
+ obj-$(CONFIG_HABANA_AI) += habanalabs/
+ obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
++obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2900-dts-mt7622-enable-new-mtk-snand-for-ubi.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2900-dts-mt7622-enable-new-mtk-snand-for-ubi.patch
new file mode 100644
index 0000000..d12f629
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2900-dts-mt7622-enable-new-mtk-snand-for-ubi.patch
@@ -0,0 +1,38 @@
+From 9ec485a8a2002d6625b8b43158887ecac572ce76 Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:34 +0800
+Subject: [PATCH]
+ [uncategorized][999-2900-dts-mt7622-enable-new-mtk-snand-for-ubi.patch]
+
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index 988c31403..d7f147414 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -568,6 +568,20 @@
+ status = "disabled";
+ };
+
++ snand: snfi@1100d000 {
++ compatible = "mediatek,mt7622-snand";
++ reg = <0 0x1100d000 0 0x1000>, <0 0x1100e000 0 0x1000>;
++ reg-names = "nfi", "ecc";
++ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
++ clocks = <&pericfg CLK_PERI_NFI_PD>,
++ <&pericfg CLK_PERI_SNFI_PD>,
++ <&pericfg CLK_PERI_NFIECC_PD>;
++ clock-names = "nfi_clk", "pad_clk", "ecc_clk";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ status = "disabled";
++ };
++
+ nor_flash: spi@11014000 {
+ compatible = "mediatek,mt7622-nor",
+ "mediatek,mt8173-nor";
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2901-dts-mt7622-remove-cooling-device.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2901-dts-mt7622-remove-cooling-device.patch
new file mode 100644
index 0000000..16bf5b8
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2901-dts-mt7622-remove-cooling-device.patch
@@ -0,0 +1,43 @@
+From abe2d8053a5323638eedb60e1e58d2bf34b98a3b Mon Sep 17 00:00:00 2001
+From: Sam Shih <sam.shih@mediatek.com>
+Date: Fri, 2 Jun 2023 13:06:34 +0800
+Subject: [PATCH]
+ [uncategorized][999-2901-dts-mt7622-remove-cooling-device.patch]
+
+---
+ arch/arm64/boot/dts/mediatek/mt7622.dtsi | 19 -------------------
+ 1 file changed, 19 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+index d7f147414..753a97a2f 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+@@ -167,25 +167,6 @@
+ };
+ };
+
+- cooling-maps {
+- map0 {
+- trip = <&cpu_passive>;
+- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+- };
+-
+- map1 {
+- trip = <&cpu_active>;
+- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+- };
+-
+- map2 {
+- trip = <&cpu_hot>;
+- cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+- <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+- };
+- };
+ };
+ };
+
+--
+2.34.1
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
index 2a6b31a..e21e5f5 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/patches-5.4.inc
@@ -1,27 +1,13 @@
#patch patches-5.4 (come from openwrt/lede/target/linux/mediatek)
SRC_URI_append = " \
- file://0001-clk-mtk-add-mt7986-support.patch \
- file://0001-cpufreq-add-the-missing-platform-driver-unregister.patch \
file://0001-v5.7-spi-make-spi-max-frequency-optional.patch \
- file://0002-clk-mtk-add-mt7981-support.patch \
- file://0002-cpufreq-Enable-clocks-and-regulators.patch \
file://0002-v5.7-spi-add-support-for-mediatek-spi-nor-controller.patch \
- file://0003-clk-mtk-add-mt7988-support.patch \
- file://0003-cpufreq-add-mt7988a-spim-snand-support.patch \
file://0003-switch-add-mt7531.patch \
- file://0005-clk-mtk-add-chg-shift-control.patch \
file://0005-dts-mt7622-add-gsw.patch \
file://0005-dts-mt7629-add-gsw.patch \
file://0006-dts-fix-bpi2-console.patch \
file://0006-dts-fix-bpi64-console.patch \
- file://0006-powerdomain-add-mt7988-support.patch \
- file://0007-cpufreq-mtk-vbining-add-mt7988-support.patch \
file://0010-dts-mt7629-rfb-fix-firmware-partition.patch \
- file://0020-dts-mt7622-enable-new-mtk-snand-for-ubi.patch \
- file://0021-dts-mt7622-remove-cooling-device.patch \
- file://0100-hwnat_Kconfig_Makefile.patch \
- file://0111-mt7986-trng-add-rng-support.patch \
- file://0200-show_model_name_in_cpuinfo_on_arm64.patch \
file://0226-phy-phy-mtk-tphy-Add-hifsys-support.patch \
file://0227-arm-dts-Add-Unielec-U7623-DTS.patch \
file://0301-mtd-mtk-ecc-move-mtk-ecc-header-file-to-include-mtd.patch \
@@ -29,122 +15,136 @@
file://0307-dts-mt7629-add-snand-support.patch \
file://0308-dts-mt7622-add-snand-support.patch \
file://0310-dts-add-wmac-support-for-mt7622-rfb1.patch \
- file://0322-fix-dirty-race-between-do_tmpfile.patch \
- file://0400-sound-add-some-helpers-to-control-mtk_memif.patch \
- file://0401-sound-refine-hw-params-and-hw-prepare.patch \
- file://0402-sound-add-mt7986-driver.patch \
- file://0490-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch \
- file://0491-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch \
file://0500-v5.6-crypto-backport-inside-secure.patch \
file://0501-crypto-add-eip97-inside-secure-support.patch \
file://0502-dts-mt7623-eip97-inside-secure-support.patch \
file://0503-crypto-fix-eip97-cache-incoherent.patch \
- file://0504-macsec-revert-async-support.patch \
- file://0505-crypto-add-eip197-inside-secure-support.patch \
file://0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch;apply=no \
file://0601-net-dsa-propagate-resolved-link-config-via-mac_link_.patch \
file://0602-net-dsa-mt7530-use-resolved-link-config-in-mac_link_.patch \
file://0603-net-dsa-mt7530-Extend-device-data-ready-for-adding-a.patch \
file://0604-net-dsa-mt7530-Add-the-support-of-MT7531-switch.patch \
file://0605-arm64-dts-mt7622-add-mt7531-dsa-to-bananapi-bpi-r64-board.patch \
- file://0666-add-spimem-support-to-mtk-spi.patch \
- file://0666-spi-mtk-nor-fix-timeout-calculation-overflow.patch \
- file://0667-spi-mediatek-fix-timeout-for-large-data.patch \
- file://0668-spi-mediatek-fix-dma-unmap-twice.patch \
- file://0669-fix-SPIM-NAND-and-NOR-probing.patch \
- file://0670-fix-SPIM-dma-buffer-not-aligned.patch \
- file://0701-fix-mtk-nfi-driver-dependency.patch \
- file://0801-mtk-sd-add-mt7986-support.patch \
- file://0802-mtk-sd-Add-subsys-clock-control.patch \
file://0900-bt-mtk-serial-fix.patch \
- file://0900-i2c-busses-add-mt7986-support.patch \
- file://0901-i2c-busses-add-mt7981-support.patch \
- file://0920-kernel-MT7988-fix-spi-dma-unmap.patch \
- file://0930-pwm-add-mt7986-support.patch \
- file://0931-pwm-add-mt7981-support.patch \
- file://0932-add-pwm-feature-in-mt7988-project.patch \
- file://0950-add-pmic-config.patch \
- file://0950-pwm-mediatek-add-longer-period-support.patch \
- file://0960-watchdog-add-mt7986-assert.patch \
- file://0961-dual-image-mount-rootfs.patch \
file://0990-gsw-rtl8367s-mt7622-support.patch \
file://0991-dt-bindings-PCI-Mediatek-Update-PCIe-binding.patch \
file://0992-PCI-mediatek-Use-regmap-to-get-shared-pcie-cfg-base.patch \
file://0993-arm64-dts-mediatek-Split-PCIe-node-for-MT2712-MT7622.patch \
file://0994-ARM-dts-mediatek-Update-mt7629-PCIe-node.patch \
- file://1001-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch \
file://1003-dts-mt7622-rfb-change-to-ax-mtd-layout.patch \
file://1010-pcie-mediatek-fix-clearing-interrupt-status.patch \
- file://1015-pcie-add-pcie-gen3-upstream-driver.patch \
file://1020-spi-nor-w25q512jv.patch \
file://1021-ubnt-ledbar-driver.patch \
- file://1023-kgdb-add-interrupt-control.patch \
- file://1024-pcie-add-multi-MSI-support.patch \
- file://1661-Add-trngv2-driver-support.patch \
- file://1662-trng-Add-trng-support-for-mt7988.patch \
- file://2000-misc-add-mtk-platform.patch \
- file://400-mtd-add-mtk-snand-driver.patch \
- file://401-pinctrl-add-mt7986-driver.patch \
- file://401-pinctrl-enable-mt7988-pinctrl-config.patch \
- file://402-pinctrl-add-mt7981-driver.patch \
- file://412-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch \
- file://413-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch \
- file://414-mtd-spinand-fix-gigadevice-read-dummy.patch \
- file://415-mtd-spinand-fix-F50L1G41LB-ecc-check.patch \
- file://416-mtd-spinor-support-EN25QX128A.patch \
- file://492-mtd-tests-fix-pagetest-load.patch \
- file://500-auxadc-add-auxadc-32k-clk.patch \
- file://6001-mtk-thermal-add-lvts-support.patch \
- file://7000-fix-race-inside-napi-enable.patch \
- file://7001-net-make-napi-disable-symmetric-with-enable.patch \
- file://7002-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch \
- file://730-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch \
- file://738-mt7531-gsw-internal_phy_calibration.patch;apply=no \
- file://739-mt7531-gsw-port5_external_phy_init.patch;apply=no \
- file://740-add-gpy211-phy-support.patch \
- file://741-add-default-setting-to-dsa-unused-port.patch \
- file://742-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch \
- file://744-en8811h-2p5gphy-support.patch \
- file://745-en8801sc-gphy-support.patch \
- file://745-mdiobus-add-c45.patch \
- file://746-add-mediatek-2p5ge-phy-support.patch \
- file://746-mxl-gpy-phy-support.patch \
- file://747-net-phy-aquantia-add-AQR113C.patch \
- file://748-add-netlink-support-for-dsa.patch \
- file://749-net-dsa-support-mt7988.patch \
- file://750-add-mdio-bus-for-gphy-calibration.patch \
- file://751-net-phy-aquantia-add-firmware-download.patch \
- file://752-net-dsa-phy-coverity-scan.patch \
- file://753-net-mt753x-phy-coverity-scan.patch;apply=no \
- file://754-net-phy-add-5GBASER.patch \
- file://755-net-phy-sfp-add-rollball-support.patch \
- file://757-net-phy-add-phylink-pcs-support.patch;apply=no \
- file://758-net-phy-add-phylink-pcs-decode-helper.patch \
- file://8000-PATCH-1-4-tphy-support-type-switch-by-pericfg.patch \
- file://8001-PATCH-2-4-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch \
- file://8002-PATCH-3-4-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch \
- file://8003-PATCH-4-4-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch \
- file://8004-nvmem-core-Add-functions-to-make-number-reading-easy.patch \
- file://8005-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch \
- file://8006-phy-phy-mtk-tphy-add-support-efuse-setting.patch \
- file://8007-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch \
- file://8008-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch \
- file://8009-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch \
- file://8010-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch \
- file://8011-ovs-add-multicast-to-unicast-support.patch \
- file://9000-PATCH-1-1-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch \
- file://9001-PATCH-1-2-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch \
- file://9002-PATCH-1-1-usb-add-embedded-Host-feature-support.patch \
- file://9009-Add-spi-runtime-PM-support.patch \
- file://9010-iwconfig-wireless-rate-fix.patch;apply=no \
- file://9011-Modify-tick_delay-for-spi-work-safety.patch \
- file://9013-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch \
- file://9014-drivers-spi-Add-support-for-dynamic-calibration.patch \
- file://9015-drivers-spi-mem-Add-spi-calibration-hook.patch \
- file://9016-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch \
- file://9017-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch \
- file://9018-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch \
- file://9019-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch \
- file://9102-spi-update-driver.patch \
- file://9103-drivers-spi-mt65xx-add-dts-buswidth-flow.patch \
+ file://999-1600-mdiobus-add-c45.patch \
+ file://999-1700-macsec-revert-async-support.patch \
+ file://999-1701-add-default-setting-to-dsa-unused-port.patch \
+ file://999-1702-net-dsa-add-MT7531-Gigabit-Ethernet-PHY-setting.patch \
+ file://999-1703-mxl-gpy-phy-support.patch \
+ file://999-1704-net-phy-aquantia-add-AQR113C.patch \
+ file://999-1705-add-netlink-support-for-dsa.patch \
+ file://999-1706-net-dsa-support-mt7988.patch \
+ file://999-1707-add-mdio-bus-for-gphy-calibration.patch \
+ file://999-1708-net-phy-add-5GBASER.patch \
+ file://999-1709-net-phy-sfp-add-rollball-support.patch \
+ file://999-1710-net-phy-add-phylink-pcs-support.patch;apply=no \
+ file://999-1711-net-phy-add-phylink-pcs-decode-helper.patch \
+ file://999-1712-net-phy-add-phylink-rate-matching-support.patch;apply=no \
+ file://999-2000-show_model_name_in_cpuinfo_on_arm64.patch \
+ file://999-2001-kgdb-add-interrupt-control.patch \
+ file://999-2010-clk-mtk-add-mt7986-support.patch \
+ file://999-2011-clk-mtk-add-mt7981-support.patch \
+ file://999-2012-clk-mtk-add-mt7988-support.patch \
+ file://999-2013-clk-mtk-add-chg-shift-control.patch \
+ file://999-2020-pinctrl-add-mt7986-driver.patch \
+ file://999-2021-pinctrl-enable-mt7988-pinctrl-config.patch \
+ file://999-2022-pinctrl-add-mt7981-driver.patch \
+ file://999-2040-powerdomain-add-mt7988-support.patch \
+ file://999-2050-watchdog-add-mt7986-assert.patch \
+ file://999-2100-mt7986-trng-add-rng-support.patch \
+ file://999-2101-Add-trngv2-driver-support.patch \
+ file://999-2102-trng-Add-trng-support-for-mt7988.patch \
+ file://999-2103-drivers-char-tpm-Add-calibration-example-for-SPI-TPM-module.patch \
+ file://999-2110-i2c-busses-add-mt7986-support.patch \
+ file://999-2111-i2c-busses-add-mt7981-support.patch \
+ file://999-2120-auxadc-add-auxadc-32k-clk.patch \
+ file://999-2130-pwm-add-mt7986-support.patch \
+ file://999-2131-pwm-add-mt7981-support.patch \
+ file://999-2132-add-pwm-feature-in-mt7988-project.patch \
+ file://999-2133-pwm-mediatek-add-longer-period-support.patch \
+ file://999-2140-mtk-thermal-add-lvts-support.patch \
+ file://999-2150-sound-add-some-helpers-to-control-mtk_memif.patch \
+ file://999-2151-sound-refine-hw-params-and-hw-prepare.patch \
+ file://999-2152-sound-add-mt7986-driver.patch \
+ file://999-2300-mtk-sd-add-mt7986-support.patch \
+ file://999-2301-mtk-sd-Add-subsys-clock-control.patch \
+ file://999-2330-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-series.patch \
+ file://999-2331-mtd-spinand-macronix-suppress-mx35lf1ge4ab-warning-log.patch \
+ file://999-2332-mtd-add-mtk-snand-driver.patch \
+ file://999-2333-mtd-spinand-gigadevice-Add-support-for-F50L1G41LB-and-GD5F1GQ5UExxG.patch \
+ file://999-2334-mtd-spinand-gigadevice-Add-support-for-GD5FxGQxUExxG-GD5FxGQxUExxH-and-GD5FxGMxUExxG-series.patch \
+ file://999-2335-mtd-spinand-fix-gigadevice-read-dummy.patch \
+ file://999-2336-mtd-spinand-fix-F50L1G41LB-ecc-check.patch \
+ file://999-2337-mtd-spinor-support-EN25QX128A.patch \
+ file://999-2338-mtd-tests-fix-pagetest-load.patch \
+ file://999-2339-drivers-mtd-spinand-Add-calibration-support-for-spinand.patch \
+ file://999-2340-drivers-mtd-spi-nor-Add-calibration-support-for-spi-nor.patch \
+ file://999-2350-nvmem-core-Add-functions-to-make-number-reading-easy.patch \
+ file://999-2351-nvmem-mtk-efuse-support-minimum-one-byte-access-stri.patch \
+ file://999-2361-add-spimem-support-to-mtk-spi.patch \
+ file://999-2362-spi-mtk-nor-fix-timeout-calculation-overflow.patch \
+ file://999-2363-spi-mediatek-fix-timeout-for-large-data.patch \
+ file://999-2364-spi-mediatek-fix-dma-unmap-twice.patch \
+ file://999-2365-fix-SPIM-NAND-and-NOR-probing.patch \
+ file://999-2366-fix-SPIM-dma-buffer-not-aligned.patch \
+ file://999-2367-fix-mtk-nfi-driver-dependency.patch \
+ file://999-2368-kernel-MT7988-fix-spi-dma-unmap.patch \
+ file://999-2369-Add-spi-runtime-PM-support.patch \
+ file://999-2370-Modify-tick_delay-for-spi-work-safety.patch \
+ file://999-2371-drivers-spi-mt65xx-Move-chip_config-to-driver-priv.patch \
+ file://999-2372-drivers-spi-Add-support-for-dynamic-calibration.patch \
+ file://999-2373-drivers-spi-mem-Add-spi-calibration-hook.patch \
+ file://999-2374-drivers-spi-mt65xx-Add-controller-calibration-parameter.patch \
+ file://999-2375-spi-update-driver.patch \
+ file://999-2376-drivers-spi-mt65xx-add-dts-buswidth-flow.patch \
+ file://999-2380-fix-dirty-race-between-do_tmpfile.patch \
+ file://999-2500-cpufreq-add-the-missing-platform-driver-unregister.patch \
+ file://999-2501-cpufreq-Enable-clocks-and-regulators.patch \
+ file://999-2502-cpufreq-add-mt7988a-spim-snand-support.patch \
+ file://999-2503-cpufreq-mtk-vbining-add-mt7988-support.patch \
+ file://999-2530-add-pmic-config.patch \
+ file://999-2550-dual-image-mount-rootfs.patch \
+ file://999-2600-pcie-add-pcie-gen3-upstream-driver.patch \
+ file://999-2601-pcie-add-multi-MSI-support.patch \
+ file://999-2610-tphy-support-type-switch-by-pericfg.patch \
+ file://999-2611-phy-phy-mtk-tphy-add-support-efuse-setting.patch \
+ file://999-2612-phy-phy-mtk-tphy-Add-PCIe-2-lane-efuse-support.patch \
+ file://999-2613-phy-phy-mtk-tphy-add-auto-load-valid-check-mechanism.patch \
+ file://999-2614-tphy-one-setting-of-TTSSC-Freq-Dev-for-all-IC-cases.patch \
+ file://999-2615-phy-phy-mtk-xsphy-support-type-switch-by-pericfg.patch \
+ file://999-2620-xHCI-change-compliance-mode-de-emphasis-default-as-g.patch \
+ file://999-2621-xHCI-MT7986-USB-2.0-USBIF-compliance-toolkit.patch \
+ file://999-2622-usb-add-embedded-Host-feature-support.patch \
+ file://999-2704-en8811h-2p5gphy-support.patch \
+ file://999-2705-hwnat_Kconfig_Makefile.patch \
+ file://999-2706-crypto-add-eip197-inside-secure-support.patch \
+ file://999-2707-mtkhnat-ipv6-fix-pskb-expand-head-limitation.patch \
+ file://999-2709-fix-race-inside-napi-enable.patch \
+ file://999-2710-net-make-napi-disable-symmetric-with-enable.patch \
+ file://999-2711-net-fix-premature-exit-from-napi-state-polling-in-napi-disable-v2.patch \
+ file://999-2712-net-ethernet-mtk_eth_soc-add-mtk-dsa-tag-rx-offload.patch \
+ file://999-2713-mt7531-gsw-internal_phy_calibration.patch;apply=no \
+ file://999-2714-mt7531-gsw-port5_external_phy_init.patch;apply=no \
+ file://999-2715-add-gpy211-phy-support.patch \
+ file://999-2716-en8801sc-gphy-support.patch \
+ file://999-2717-add-mediatek-2p5ge-phy-support.patch \
+ file://999-2719-net-phy-aquantia-add-firmware-download.patch \
+ file://999-2720-net-dsa-phy-coverity-scan.patch \
+ file://999-2721-net-mt753x-phy-coverity-scan.patch;apply=no \
+ file://999-2722-dt-bindings-phy-Add-PHY_TYPE_DP-definition.patch \
+ file://999-2723-dt-bindings-phy-Add-PHY_TYPE_XPCS-definition.patch \
+ file://999-2724-dt-bindings-phy-Add-DT-bindings-for-Xilinx-ZynqMP-PS.patch \
+ file://999-2725-iwconfig-wireless-rate-fix.patch;apply=no \
+ file://999-2800-misc-add-mtk-platform.patch \
+ file://999-2900-dts-mt7622-enable-new-mtk-snand-for-ubi.patch \
+ file://999-2901-dts-mt7622-remove-cooling-device.patch \
"
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3021-mtk-wed-add-wed3-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3021-mtk-wed-add-wed3-support.patch
new file mode 100644
index 0000000..bccc43e
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3021-mtk-wed-add-wed3-support.patch
@@ -0,0 +1,3720 @@
+From 400f8349a31ffc48538aa7df64a88111de9a738b Mon Sep 17 00:00:00 2001
+From: Sujuan Chen <sujuan.chen@mediatek.com>
+Date: Thu, 13 Apr 2023 15:51:08 +0800
+Subject: [PATCH] mtk:wed:add wed3 support
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ arch/arm64/boot/dts/mediatek/mt7988.dtsi | 152 ++-
+ .../dts/mediatek/mt7988a-dsa-10g-spim-nor.dts | 16 +-
+ .../dts/mediatek/mt7988d-dsa-10g-spim-nor.dts | 16 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 3 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 5 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.c | 17 +-
+ drivers/net/ethernet/mediatek/mtk_ppe.h | 2 +-
+ .../net/ethernet/mediatek/mtk_ppe_offload.c | 13 +-
+ drivers/net/ethernet/mediatek/mtk_wed.c | 1164 +++++++++++++----
+ drivers/net/ethernet/mediatek/mtk_wed.h | 25 +-
+ .../net/ethernet/mediatek/mtk_wed_debugfs.c | 584 ++++++++-
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 13 +-
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.h | 5 +-
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 338 ++++-
+ include/linux/netdevice.h | 7 +
+ include/linux/soc/mediatek/mtk_wed.h | 81 +-
+ 16 files changed, 1446 insertions(+), 333 deletions(-)
+ mode change 100755 => 100644 drivers/net/ethernet/mediatek/mtk_ppe.c
+
+diff --git a/arch/arm64/boot/dts/mediatek/mt7988.dtsi b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+index 364deef..f9a0120 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7988.dtsi
++++ b/arch/arm64/boot/dts/mediatek/mt7988.dtsi
+@@ -191,44 +191,49 @@
+ status = "disabled";
+ };
+
+- wed: wed@15010000 {
+- compatible = "mediatek,wed";
+- wed_num = <3>;
+- /* add this property for wed get the pci slot number. */
+- pci_slot_map = <0>, <1>, <2>;
+- reg = <0 0x15010000 0 0x2000>,
+- <0 0x15012000 0 0x2000>,
+- <0 0x15014000 0 0x2000>;
++ wed0: wed@15010000 {
++ compatible = "mediatek,mt7988-wed",
++ "syscon";
++ reg = <0 0x15010000 0 0x2000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+- };
+-
+- wed2: wed2@15012000 {
+- compatible = "mediatek,wed2";
+- wed_num = <3>;
+- /* add this property for wed get the pci slot number. */
+- reg = <0 0x15010000 0 0x2000>,
+- <0 0x15012000 0 0x2000>,
+- <0 0x15014000 0 0x2000>;
++ interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
++ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif0>;
++ mediatek,wocpu_ilm = <&wocpu0_ilm>;
++ mediatek,wocpu_dlm = <&wocpu0_dlm>;
++ mediatek,wocpu_boot = <&cpu0_boot>;
++ mediatek,wocpu_emi = <&wocpu0_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
++ };
++
++ wed1: wed@15012000 {
++ compatible = "mediatek,mt7988-wed",
++ "syscon";
++ reg = <0 0x15012000 0 0x2000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
+- };
+-
+- wed3: wed3@15014000 {
+- compatible = "mediatek,wed3";
+- wed_num = <3>;
+- /* add this property for wed get the pci slot number. */
+- reg = <0 0x15010000 0 0x2000>,
+- <0 0x15012000 0 0x2000>,
+- <0 0x15014000 0 0x2000>;
++ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
++ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif1>;
++ mediatek,wocpu_ilm = <&wocpu1_ilm>;
++ mediatek,wocpu_dlm = <&wocpu1_dlm>;
++ mediatek,wocpu_boot = <&cpu1_boot>;
++ mediatek,wocpu_emi = <&wocpu1_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
++ };
++
++ wed2: wed@15014000 {
++ compatible = "mediatek,mt7988-wed",
++ "syscon";
++ reg = <0 0x15014000 0 0x2000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
++ mediatek,wed_pcie = <&wed_pcie>;
++ mediatek,ap2woccif = <&ap2woccif2>;
++ mediatek,wocpu_ilm = <&wocpu2_ilm>;
++ mediatek,wocpu_dlm = <&wocpu2_dlm>;
++ mediatek,wocpu_boot = <&cpu2_boot>;
++ mediatek,wocpu_emi = <&wocpu2_emi>;
++ mediatek,wocpu_data = <&wocpu_data>;
+ };
+
+ wdma: wdma@15104800 {
+@@ -238,15 +243,25 @@
+ <0 0x15105000 0 0x400>;
+ };
+
+- ap2woccif: ap2woccif@151A5000 {
+- compatible = "mediatek,ap2woccif";
+- reg = <0 0x151A5000 0 0x1000>,
+- <0 0x152A5000 0 0x1000>,
+- <0 0x153A5000 0 0x1000>;
++ ap2woccif0: ap2woccif@151A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x151A5000 0 0x1000>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
++ };
++
++ ap2woccif1: ap2woccif@152A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x152A5000 0 0x1000>;
+ interrupt-parent = <&gic>;
+- interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+- <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
++ interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
++ };
++
++ ap2woccif2: ap2woccif@153A5000 {
++ compatible = "mediatek,ap2woccif", "syscon";
++ reg = <0 0x153A5000 0 0x1000>;
++ interrupt-parent = <&gic>;
++ interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ wocpu0_ilm: wocpu0_ilm@151E0000 {
+@@ -254,31 +269,53 @@
+ reg = <0 0x151E0000 0 0x8000>;
+ };
+
+- wocpu1_ilm: wocpu1_ilm@152E0000 {
+- compatible = "mediatek,wocpu1_ilm";
++ wocpu1_ilm: wocpu_ilm@152E0000 {
++ compatible = "mediatek,wocpu_ilm";
+ reg = <0 0x152E0000 0 0x8000>;
+ };
+
+- wocpu2_ilm: wocpu2_ilm@153E0000 {
+- compatible = "mediatek,wocpu2_ilm";
+- reg = <0 0x153E0000 0 0x8000>;
++ wocpu2_ilm: wocpu_ilm@153E0000 {
++ compatible = "mediatek,wocpu_ilm";
++ reg = <0 0x153E0000 0 0x8000>;
++ };
++
++ wocpu0_dlm: wocpu_dlm@151E8000 {
++ compatible = "mediatek,wocpu_dlm";
++ reg = <0 0x151E8000 0 0x2000>;
++
++ resets = <ðsysrst 0>;
++ reset-names = "wocpu_rst";
++ };
++
++ wocpu1_dlm: wocpu_dlm@0x152E8000 {
++ compatible = "mediatek,wocpu_dlm";
++ reg = <0 0x152E8000 0 0x2000>;
++
++ resets = <ðsysrst 0>;
++ reset-names = "wocpu_rst";
+ };
+
+- wocpu_dlm: wocpu_dlm@151E8000 {
++ wocpu2_dlm: wocpu_dlm@0x153E8000 {
+ compatible = "mediatek,wocpu_dlm";
+- reg = <0 0x151E8000 0 0x2000>,
+- <0 0x152E8000 0 0x2000>,
+- <0 0x153E8000 0 0x2000>;
++ reg = <0 0x153E8000 0 0x2000>;
+
+ resets = <ðsysrst 0>;
+ reset-names = "wocpu_rst";
+ };
+
+- cpu_boot: wocpu_boot@15194000 {
+- compatible = "mediatek,wocpu_boot";
+- reg = <0 0x15194000 0 0x1000>,
+- <0 0x15294000 0 0x1000>,
+- <0 0x15394000 0 0x1000>;
++ cpu0_boot: wocpu_boot@15194000 {
++ compatible = "mediatek,wocpu0_boot";
++ reg = <0 0x15194000 0 0x1000>;
++ };
++
++ cpu1_boot: wocpu_boot@15294000 {
++ compatible = "mediatek,wocpu1_boot";
++ reg = <0 0x15294000 0 0x1000>;
++ };
++
++ cpu2_boot: wocpu_boot@15394000 {
++ compatible = "mediatek,wocpu2_boot";
++ reg = <0 0x15394000 0 0x1000>;
+ };
+
+ reserved-memory {
+@@ -827,6 +864,7 @@
+ <&topckgen CK_TOP_CB_SGM_325M>;
+ mediatek,ethsys = <ðsys>;
+ mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
++ mediatek,wed = <&wed0>, <&wed1>, <&wed2>;
+ mediatek,usxgmiisys = <&usxgmiisys0>, <&usxgmiisys1>;
+ mediatek,xfi_pextp = <&xfi_pextp0>, <&xfi_pextp1>;
+ mediatek,xfi_pll = <&xfi_pll>;
+diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
+index 7db5164..0a6db8b 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988a-dsa-10g-spim-nor.dts
+@@ -341,9 +341,23 @@
+ status = "okay";
+ };
+
+-&wed {
++&wed0 {
+ dy_txbm_enable = "true";
+ dy_txbm_budge = <8>;
+ txbm_init_sz = <10>;
+ status = "okay";
+ };
++
++&wed1 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
++
++&wed2 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
+\ No newline at end of file
+diff --git a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
+index 67c6508..c407b33 100644
+--- a/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
++++ b/arch/arm64/boot/dts/mediatek/mt7988d-dsa-10g-spim-nor.dts
+@@ -325,9 +325,23 @@
+ status = "okay";
+ };
+
+-&wed {
++&wed0 {
+ dy_txbm_enable = "true";
+ dy_txbm_budge = <8>;
+ txbm_init_sz = <10>;
+ status = "okay";
+ };
++
++&wed1 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
++
++&wed2 {
++ dy_txbm_enable = "true";
++ dy_txbm_budge = <8>;
++ txbm_init_sz = <10>;
++ status = "okay";
++};
+\ No newline at end of file
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+index 388982c..d59c29f 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4709,7 +4709,8 @@ static int mtk_probe(struct platform_device *pdev)
+ "mediatek,wed", i);
+ static const u32 wdma_regs[] = {
+ MTK_WDMA0_BASE,
+- MTK_WDMA1_BASE
++ MTK_WDMA1_BASE,
++ MTK_WDMA2_BASE
+ };
+ void __iomem *wdma;
+ u32 wdma_phy;
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+index a9feaed..70e8377 100644
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -605,9 +605,12 @@
+ #define RX_DMA_SPORT_MASK 0x7
+ #define RX_DMA_SPORT_MASK_V2 0xf
+
+-#if defined(CONFIG_MEDIATEK_NETSYS_V2)
++#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+ #define MTK_WDMA0_BASE 0x4800
+ #define MTK_WDMA1_BASE 0x4c00
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++#define MTK_WDMA2_BASE 0x5000
++#endif
+ #else
+ #define MTK_WDMA0_BASE 0x2800
+ #define MTK_WDMA1_BASE 0x2c00
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c
+old mode 100755
+new mode 100644
+index bc13a9b..3910163
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -9,6 +9,7 @@
+ #include <linux/if_ether.h>
+ #include <linux/if_vlan.h>
+ #include <net/dsa.h>
++#include <net/route.h>
+ #include "mtk_eth_soc.h"
+ #include "mtk_ppe.h"
+ #include "mtk_ppe_regs.h"
+@@ -396,7 +397,7 @@ int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid)
+ }
+
+ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+- int bss, int wcid)
++ int bss, int wcid, bool amsdu_en)
+ {
+ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
+ u32 *ib2 = mtk_foe_entry_ib2(entry);
+@@ -408,6 +409,9 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+
+ l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
+ FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ l2->winfo_pao = FIELD_PREP(MTK_FOE_WINFO_PAO_AMSDU_EN, amsdu_en);
++#endif
+ #else
+ if (wdma_idx)
+ *ib2 |= MTK_FOE_IB2_WDMA_DEVIDX;
+@@ -443,6 +447,17 @@ int mtk_foe_entry_set_dscp(struct mtk_foe_entry *entry, int dscp)
+ *ib2 &= ~MTK_FOE_IB2_DSCP;
+ *ib2 |= FIELD_PREP(MTK_FOE_IB2_DSCP, dscp);
+
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++ struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
++
++ if (*ib2 & MTK_FOE_IB2_WDMA_WINFO &&
++ l2->winfo_pao & MTK_FOE_WINFO_PAO_AMSDU_EN) {
++ u8 tid = rt_tos2priority(dscp) & 0xf;
++
++ l2->winfo_pao |= FIELD_PREP(MTK_FOE_WINFO_PAO_TID, tid);
++ }
++#endif
++
+ return 0;
+ }
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.h b/drivers/net/ethernet/mediatek/mtk_ppe.h
+index df10040..9e7d5aa 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -428,7 +428,7 @@ int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port);
+ int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
+ int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
+ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
+- int bss, int wcid);
++ int bss, int wcid, bool amsdu_en);
+ int mtk_foe_entry_set_qid(struct mtk_foe_entry *entry, int qid);
+ int mtk_foe_entry_set_dscp(struct mtk_foe_entry *entry, int dscp);
+ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
+diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+index 9bc0857..86fc9a1 100644
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -112,6 +112,7 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_i
+ info->queue = path.mtk_wdma.queue;
+ info->bss = path.mtk_wdma.bss;
+ info->wcid = path.mtk_wdma.wcid;
++ info->amsdu_en = path.mtk_wdma.amsdu_en;
+
+ return 0;
+ }
+@@ -193,13 +194,15 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
+
+ if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
+ mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss,
+- info.wcid);
++ info.wcid, info.amsdu_en);
+ pse_port = PSE_PPE0_PORT;
+ #if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
+ if (info.wdma_idx == 0)
+ pse_port = PSE_WDMA0_PORT;
+ else if (info.wdma_idx == 1)
+ pse_port = PSE_WDMA1_PORT;
++ else if (info.wdma_idx == 2)
++ pse_port = PSE_WDMA2_PORT;
+ else
+ return -EOPNOTSUPP;
+ #endif
+@@ -458,8 +461,8 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
+ if (err)
+ return err;
+
+- if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
+- return err;
++ /*if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0)
++ return err;*/
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+@@ -499,8 +502,8 @@ clear:
+ mtk_foe_entry_clear(eth->ppe[i], entry);
+ free:
+ kfree(entry);
+- if (wed_index >= 0)
+- mtk_wed_flow_remove(wed_index);
++ /*if (wed_index >= 0)
++ mtk_wed_flow_remove(wed_index);*/
+ return err;
+ }
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 37a86c3..e3809db 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -28,7 +28,7 @@ struct wo_cmd_ring {
+ u32 cnt;
+ u32 unit;
+ };
+-static struct mtk_wed_hw *hw_list[2];
++static struct mtk_wed_hw *hw_list[3];
+ static DEFINE_MUTEX(hw_lock);
+
+ static void
+@@ -73,6 +73,26 @@ mtk_wdma_read_reset(struct mtk_wed_device *dev)
+ return wdma_r32(dev, MTK_WDMA_GLO_CFG);
+ }
+
++static u32
++mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++{
++ if (wed_r32(dev, reg) & mask)
++ return true;
++
++ return false;
++}
++
++static int
++mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
++{
++ int sleep = 1000;
++ int timeout = 100 * sleep;
++ u32 val;
++
++ return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
++ timeout, false, dev, reg, mask);
++}
++
+ static int
+ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+ {
+@@ -235,6 +255,8 @@ mtk_wed_assign(struct mtk_wed_device *dev)
+ continue;
+
+ hw->wed_dev = dev;
++ hw->pci_base = MTK_WED_PCIE_BASE;
++
+ return hw;
+ }
+
+@@ -242,23 +264,84 @@ mtk_wed_assign(struct mtk_wed_device *dev)
+ }
+
+ static int
+-mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
++mtk_wed_pao_buffer_alloc(struct mtk_wed_device *dev)
++{
++ struct mtk_wed_pao *pao;
++ int i, j;
++
++ pao = kzalloc(sizeof(struct mtk_wed_pao), GFP_KERNEL);
++ if (!pao)
++ return -ENOMEM;
++
++ dev->hw->wed_pao = pao;
++
++ for (i = 0; i < 32; i++) {
++ /* each segment is 64K*/
++ pao->hif_txd[i] = (char *)__get_free_pages(GFP_ATOMIC |
++ GFP_DMA32 |
++ __GFP_ZERO, 4);
++ if (!pao->hif_txd[i])
++ goto err;
++
++ pao->hif_txd_phys[i] = dma_map_single(dev->hw->dev,
++ pao->hif_txd[i],
++ 16 * PAGE_SIZE,
++ DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(dev->hw->dev,
++ pao->hif_txd_phys[i])))
++ goto err;
++ }
++
++ return 0;
++
++err:
++ for (j = 0; j < i; j++)
++ dma_unmap_single(dev->hw->dev, pao->hif_txd_phys[j],
++ 16 * PAGE_SIZE, DMA_TO_DEVICE);
++
++ return -ENOMEM;
++}
++
++static int
++mtk_wed_pao_free_buffer(struct mtk_wed_device *dev)
++{
++ struct mtk_wed_pao *pao = dev->hw->wed_pao;
++ int i;
++
++ for (i = 0; i < 32; i++) {
++ dma_unmap_single(dev->hw->dev, pao->hif_txd_phys[i],
++ 16 * PAGE_SIZE, DMA_TO_DEVICE);
++ free_pages((unsigned long)pao->hif_txd[i], 4);
++ }
++
++ return 0;
++}
++
++static int
++mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev)
+ {
+ struct mtk_wdma_desc *desc;
++ void *desc_ptr;
+ dma_addr_t desc_phys;
+- void **page_list;
++ struct dma_page_info *page_list;
+ u32 last_seg = MTK_WDMA_DESC_CTRL_LAST_SEG1;
+ int token = dev->wlan.token_start;
+- int ring_size, n_pages, page_idx;
+- int i;
+-
++ int ring_size, pkt_nums, n_pages, page_idx;
++ int i, ret = 0;
+
+ if (dev->ver == MTK_WED_V1) {
+ ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+- } else {
++ pkt_nums = ring_size;
++ dev->tx_buf_ring.desc_size = sizeof(struct mtk_wdma_desc);
++ } else if (dev->hw->version == 2) {
+ ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
+ MTK_WED_WDMA_RING_SIZE * 2;
+ last_seg = MTK_WDMA_DESC_CTRL_LAST_SEG0;
++ dev->tx_buf_ring.desc_size = sizeof(struct mtk_wdma_desc);
++ } else if (dev->hw->version == 3) {
++ ring_size = MTK_WED_TX_BM_DMA_SIZE;
++ pkt_nums = MTK_WED_TX_BM_PKT_CNT;
++ dev->tx_buf_ring.desc_size = sizeof(struct mtk_rxbm_desc);
+ }
+
+ n_pages = ring_size / MTK_WED_BUF_PER_PAGE;
+@@ -267,18 +350,20 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
+ if (!page_list)
+ return -ENOMEM;
+
+- dev->buf_ring.size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+- dev->buf_ring.pages = page_list;
++ dev->tx_buf_ring.size = ring_size;
++ dev->tx_buf_ring.pages = page_list;
++ dev->tx_buf_ring.pkt_nums = pkt_nums;
+
+- desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
+- &desc_phys, GFP_KERNEL);
+- if (!desc)
++ desc_ptr = dma_alloc_coherent(dev->hw->dev,
++ ring_size * dev->tx_buf_ring.desc_size,
++ &desc_phys, GFP_KERNEL);
++ if (!desc_ptr)
+ return -ENOMEM;
+
+- dev->buf_ring.desc = desc;
+- dev->buf_ring.desc_phys = desc_phys;
++ dev->tx_buf_ring.desc = desc_ptr;
++ dev->tx_buf_ring.desc_phys = desc_phys;
+
+- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
++ for (i = 0, page_idx = 0; i < pkt_nums; i += MTK_WED_BUF_PER_PAGE) {
+ dma_addr_t page_phys, buf_phys;
+ struct page *page;
+ void *buf;
+@@ -295,7 +380,10 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
+ return -ENOMEM;
+ }
+
+- page_list[page_idx++] = page;
++ page_list[page_idx].addr = page;
++ page_list[page_idx].addr_phys = page_phys;
++ page_idx++;
++
+ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
+ DMA_BIDIRECTIONAL);
+
+@@ -303,19 +391,23 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
+ buf_phys = page_phys;
+
+ for (s = 0; s < MTK_WED_BUF_PER_PAGE; s++) {
+- u32 txd_size;
+-
+- txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
+-
++ desc = desc_ptr;
+ desc->buf0 = buf_phys;
+- desc->buf1 = buf_phys + txd_size;
+- desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0,
+- txd_size) |
+- FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
+- MTK_WED_BUF_SIZE - txd_size) |
+- last_seg;
+- desc->info = 0;
+- desc++;
++ if (dev->hw->version < 3) {
++ u32 txd_size;
++
++ txd_size = dev->wlan.init_buf(buf, buf_phys, token++);
++ desc->buf1 = buf_phys + txd_size;
++ desc->ctrl = FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN0,
++ txd_size) |
++ FIELD_PREP(MTK_WDMA_DESC_CTRL_LEN1,
++ MTK_WED_BUF_SIZE - txd_size) |
++ last_seg;
++ desc->info = 0;
++ } else {
++ desc->ctrl = token << 16;
++ }
++ desc_ptr += dev->tx_buf_ring.desc_size;
+
+ buf += MTK_WED_BUF_SIZE;
+ buf_phys += MTK_WED_BUF_SIZE;
+@@ -325,15 +417,18 @@ mtk_wed_buffer_alloc(struct mtk_wed_device *dev)
+ DMA_BIDIRECTIONAL);
+ }
+
+- return 0;
++ if (dev->hw->version == 3)
++ ret = mtk_wed_pao_buffer_alloc(dev);
++
++ return ret;
+ }
+
+ static void
+-mtk_wed_free_buffer(struct mtk_wed_device *dev)
++mtk_wed_free_tx_buffer(struct mtk_wed_device *dev)
+ {
+- struct mtk_wdma_desc *desc = dev->buf_ring.desc;
+- void **page_list = dev->buf_ring.pages;
+- int ring_size, page_idx;
++ struct mtk_rxbm_desc *desc = dev->tx_buf_ring.desc;
++ struct dma_page_info *page_list = dev->tx_buf_ring.pages;
++ int ring_size, page_idx, pkt_nums;
+ int i;
+
+ if (!page_list)
+@@ -342,33 +437,33 @@ mtk_wed_free_buffer(struct mtk_wed_device *dev)
+ if (!desc)
+ goto free_pagelist;
+
+- if (dev->ver == MTK_WED_V1) {
+- ring_size = dev->wlan.nbuf & ~(MTK_WED_BUF_PER_PAGE - 1);
+- } else {
+- ring_size = MTK_WED_VLD_GROUP_SIZE * MTK_WED_PER_GROUP_PKT +
+- MTK_WED_WDMA_RING_SIZE * 2;
++ pkt_nums = ring_size = dev->tx_buf_ring.size;
++ if (dev->hw->version == 3) {
++ mtk_wed_pao_free_buffer(dev);
++ pkt_nums = dev->tx_buf_ring.pkt_nums;
+ }
+
+- for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_BUF_PER_PAGE) {
+- void *page = page_list[page_idx++];
++ for (i = 0, page_idx = 0; i < pkt_nums; i += MTK_WED_BUF_PER_PAGE) {
++ void *page = page_list[page_idx].addr;
+
+ if (!page)
+ break;
+
+- dma_unmap_page(dev->hw->dev, desc[i].buf0,
++ dma_unmap_page(dev->hw->dev, page_list[page_idx].addr_phys,
+ PAGE_SIZE, DMA_BIDIRECTIONAL);
+ __free_page(page);
++ page_idx++;
+ }
+
+- dma_free_coherent(dev->hw->dev, ring_size * sizeof(*desc),
+- desc, dev->buf_ring.desc_phys);
++ dma_free_coherent(dev->hw->dev, ring_size * dev->tx_buf_ring.desc_size,
++ dev->tx_buf_ring.desc, dev->tx_buf_ring.desc_phys);
+
+ free_pagelist:
+ kfree(page_list);
+ }
+
+ static int
+-mtk_wed_rx_bm_alloc(struct mtk_wed_device *dev)
++mtk_wed_rx_buffer_alloc(struct mtk_wed_device *dev)
+ {
+ struct mtk_rxbm_desc *desc;
+ dma_addr_t desc_phys;
+@@ -389,7 +484,7 @@ mtk_wed_rx_bm_alloc(struct mtk_wed_device *dev)
+ }
+
+ static void
+-mtk_wed_free_rx_bm(struct mtk_wed_device *dev)
++mtk_wed_free_rx_buffer(struct mtk_wed_device *dev)
+ {
+ struct mtk_rxbm_desc *desc = dev->rx_buf_ring.desc;
+ int ring_size = dev->rx_buf_ring.size;
+@@ -403,6 +498,113 @@ mtk_wed_free_rx_bm(struct mtk_wed_device *dev)
+ desc, dev->rx_buf_ring.desc_phys);
+ }
+
++/* TODO */
++static int
++mtk_wed_rx_page_buffer_alloc(struct mtk_wed_device *dev)
++{
++ int ring_size = dev->wlan.rx_nbuf, buf_num = MTK_WED_RX_PG_BM_CNT;
++ struct mtk_rxbm_desc *desc;
++ dma_addr_t desc_phys;
++ struct dma_page_info *page_list;
++ int n_pages, page_idx;
++ int i;
++
++ n_pages = buf_num / MTK_WED_RX_PAGE_BUF_PER_PAGE;
++
++ page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL);
++ if (!page_list)
++ return -ENOMEM;
++
++ dev->rx_page_buf_ring.size = ring_size & ~(MTK_WED_BUF_PER_PAGE - 1);
++ dev->rx_page_buf_ring.pages = page_list;
++ dev->rx_page_buf_ring.pkt_nums = buf_num;
++
++ desc = dma_alloc_coherent(dev->hw->dev, ring_size * sizeof(*desc),
++ &desc_phys, GFP_KERNEL);
++ if (!desc)
++ return -ENOMEM;
++
++ dev->rx_page_buf_ring.desc = desc;
++ dev->rx_page_buf_ring.desc_phys = desc_phys;
++
++ for (i = 0, page_idx = 0; i < buf_num; i += MTK_WED_RX_PAGE_BUF_PER_PAGE) {
++ dma_addr_t page_phys, buf_phys;
++ struct page *page;
++ void *buf;
++ int s;
++
++ page = __dev_alloc_pages(GFP_KERNEL, 0);
++ if (!page)
++ return -ENOMEM;
++
++ page_phys = dma_map_page(dev->hw->dev, page, 0, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++ if (dma_mapping_error(dev->hw->dev, page_phys)) {
++ __free_page(page);
++ return -ENOMEM;
++ }
++
++ page_list[page_idx].addr= page;
++ page_list[page_idx].addr_phys= page_phys;
++ page_idx++;
++
++ dma_sync_single_for_cpu(dev->hw->dev, page_phys, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++
++ buf = page_to_virt(page);
++ buf_phys = page_phys;
++
++ for (s = 0; s < MTK_WED_RX_PAGE_BUF_PER_PAGE; s++) {
++
++ desc->buf0 = cpu_to_le32(buf_phys);
++ desc++;
++
++ buf += MTK_WED_PAGE_BUF_SIZE;
++ buf_phys += MTK_WED_PAGE_BUF_SIZE;
++ }
++
++ dma_sync_single_for_device(dev->hw->dev, page_phys, PAGE_SIZE,
++ DMA_BIDIRECTIONAL);
++ }
++
++ return 0;
++}
++
++static void
++mtk_wed_rx_page_free_buffer(struct mtk_wed_device *dev)
++{
++ struct mtk_rxbm_desc *desc = dev->rx_page_buf_ring.desc;
++ struct dma_page_info *page_list = dev->rx_page_buf_ring.pages;
++ int ring_size, page_idx;
++ int i;
++
++ if (!page_list)
++ return;
++
++ if (!desc)
++ goto free_pagelist;
++
++ ring_size = dev->rx_page_buf_ring.pkt_nums;
++
++ for (i = 0, page_idx = 0; i < ring_size; i += MTK_WED_RX_PAGE_BUF_PER_PAGE) {
++ void *page = page_list[page_idx].addr;
++
++ if (!page)
++ break;
++
++ dma_unmap_page(dev->hw->dev, page_list[page_idx].addr_phys,
++ PAGE_SIZE, DMA_BIDIRECTIONAL);
++ __free_page(page);
++ page_idx++;
++ }
++
++ dma_free_coherent(dev->hw->dev, dev->rx_page_buf_ring.size * sizeof(*desc),
++ desc, dev->rx_page_buf_ring.desc_phys);
++
++free_pagelist:
++ kfree(page_list);
++}
++
+ static void
+ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int scale)
+ {
+@@ -416,19 +618,25 @@ mtk_wed_free_ring(struct mtk_wed_device *dev, struct mtk_wed_ring *ring, int sca
+ static void
+ mtk_wed_free_tx_rings(struct mtk_wed_device *dev)
+ {
+- int i;
++ int i, scale = dev->hw->version > 1 ? 2 : 1;
+
+ for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++)
+- mtk_wed_free_ring(dev, &dev->tx_ring[i], 1);
++ if (!(dev->rx_ring[i].flags & MTK_WED_RING_CONFIGURED))
++ mtk_wed_free_ring(dev, &dev->tx_ring[i], 1);
++
+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+- mtk_wed_free_ring(dev, &dev->tx_wdma[i], dev->ver);
++ if ((dev->rx_ring[i].flags & MTK_WED_RING_CONFIGURED))
++ mtk_wed_free_ring(dev, &dev->tx_wdma[i], scale);
+ }
+
+ static void
+ mtk_wed_free_rx_rings(struct mtk_wed_device *dev)
+ {
+- mtk_wed_free_rx_bm(dev);
++ mtk_wed_free_rx_buffer(dev);
+ mtk_wed_free_ring(dev, &dev->rro.rro_ring, 1);
++
++ if (dev->wlan.hwrro)
++ mtk_wed_rx_page_free_buffer(dev);
+ }
+
+ static void
+@@ -437,7 +645,7 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
+ u32 wdma_mask;
+
+ wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
+- if (dev->ver > MTK_WED_V1)
++ if (mtk_wed_get_rx_capa(dev))
+ wdma_mask |= FIELD_PREP(MTK_WDMA_INT_MASK_TX_DONE,
+ GENMASK(1, 0));
+ /* wed control cr set */
+@@ -447,7 +655,7 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
+ MTK_WED_CTRL_WED_TX_BM_EN |
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+- if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
+ MTK_WED_PCIE_INT_TRIGGER_STATUS);
+
+@@ -458,6 +666,8 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
+ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
+ } else {
++ if (dev->hw->version == 3)
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_TKID_ALI_EN);
+
+ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_TX,
+ MTK_WED_WPDMA_INT_CTRL_TX0_DONE_EN |
+@@ -475,18 +685,20 @@ mtk_wed_set_int(struct mtk_wed_device *dev, u32 irq_mask)
+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_TX_FREE_DONE_TRIG,
+ dev->wlan.txfree_tbit));
+
+- wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
+- MTK_WED_WPDMA_INT_CTRL_RX0_EN |
+- MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
+- MTK_WED_WPDMA_INT_CTRL_RX1_EN |
+- MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
+- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
+- dev->wlan.rx_tbit[0]) |
+- FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
+- dev->wlan.rx_tbit[1]));
++ if (mtk_wed_get_rx_capa(dev))
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RX,
++ MTK_WED_WPDMA_INT_CTRL_RX0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RX0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RX1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RX1_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX0_DONE_TRIG,
++ dev->wlan.rx_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RX1_DONE_TRIG,
++ dev->wlan.rx_tbit[1]));
+ }
++
+ wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
+- if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
+ } else {
+ wed_w32(dev, MTK_WED_WDMA_INT_CLR, wdma_mask);
+@@ -506,6 +718,21 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
+ {
+ u32 mask = MTK_WED_EXT_INT_STATUS_ERROR_MASK;
+
++ switch (dev->hw->version) {
++ case 1:
++ mask |= MTK_WED_EXT_INT_STATUS_TX_DRV_R_RESP_ERR;
++ break;
++ case 2 :
++ mask |= MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH2 |
++ MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH2 |
++ MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT |
++ MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR;
++ break;
++ case 3:
++ mask = MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT;
++ break;
++ }
++
+ if (!dev->hw->num_flows)
+ mask &= ~MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD;
+
+@@ -514,31 +741,86 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
+ }
+
+ static void
+-mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
++mtk_wed_pao_init(struct mtk_wed_device *dev)
+ {
+- if (en) {
+- wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
+- wed_w32(dev, MTK_WED_TXP_DW1,
+- FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103));
+- } else {
+- wed_w32(dev, MTK_WED_TXP_DW1,
+- FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100));
+- wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
++ struct mtk_wed_pao *pao = dev->hw->wed_pao;
++ int i;
++
++ for (i = 0; i < 32; i++)
++ wed_w32(dev, MTK_WED_PAO_HIFTXD_BASE_L(i),
++ pao->hif_txd_phys[i]);
++
++ /* init all sta parameter */
++ wed_w32(dev, MTK_WED_PAO_STA_INFO_INIT, MTK_WED_PAO_STA_RMVL |
++ MTK_WED_PAO_STA_WTBL_HDRT_MODE |
++ FIELD_PREP(MTK_WED_PAO_STA_MAX_AMSDU_LEN,
++ dev->wlan.max_amsdu_len >> 8) |
++ FIELD_PREP(MTK_WED_PAO_STA_MAX_AMSDU_NUM,
++ dev->wlan.max_amsdu_nums));
++
++ wed_w32(dev, MTK_WED_PAO_STA_INFO, MTK_WED_PAO_STA_INFO_DO_INIT);
++
++ if (mtk_wed_poll_busy(dev, MTK_WED_PAO_STA_INFO,
++ MTK_WED_PAO_STA_INFO_DO_INIT)) {
++ dev_err(dev->hw->dev, "mtk_wed%d: pao init failed!\n",
++ dev->hw->index);
++ return;
+ }
++
++ /* init pao txd src */
++ wed_set(dev, MTK_WED_PAO_HIFTXD_CFG,
++ FIELD_PREP(MTK_WED_PAO_HIFTXD_SRC, dev->hw->index));
++
++ /* init qmem */
++ wed_set(dev, MTK_WED_PAO_PSE, MTK_WED_PAO_PSE_RESET);
++ if (mtk_wed_poll_busy(dev, MTK_WED_PAO_MON_QMEM_STS1, BIT(29))) {
++ pr_info("%s: init pao qmem fail\n", __func__);
++ return;
++ }
++
++ /* eagle E1 PCIE1 tx ring 22 flow control issue */
++ if (dev->wlan.chip_id == 0x7991) {
++ wed_clr(dev, MTK_WED_PAO_AMSDU_FIFO,
++ MTK_WED_PAO_AMSDU_IS_PRIOR0_RING);
++ }
++
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN);
++
++ return;
+ }
+
+-static void
+-mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
++static int
++mtk_wed_hwrro_init(struct mtk_wed_device *dev)
+ {
+-#define MTK_WFMDA_RX_DMA_EN BIT(2)
++ if (!mtk_wed_get_rx_capa(dev))
++ return 0;
++
++ wed_set(dev, MTK_WED_RRO_PG_BM_RX_DMAM,
++ FIELD_PREP(MTK_WED_RRO_PG_BM_RX_SDL0, 128));
++
++ wed_w32(dev, MTK_WED_RRO_PG_BM_BASE,
++ dev->rx_page_buf_ring.desc_phys);
++
++ wed_w32(dev, MTK_WED_RRO_PG_BM_INIT_PTR,
++ MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX |
++ FIELD_PREP(MTK_WED_RRO_PG_BM_SW_TAIL_IDX,
++ MTK_WED_RX_PG_BM_CNT));
++
++ /* enable rx_page_bm to fetch dmad */
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
++
++ return 0;
++}
+
++static int
++mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev,
++ struct mtk_wed_ring *ring)
++{
+ int timeout = 3;
+- u32 cur_idx, regs;
++ u32 cur_idx;
+
+ do {
+- regs = MTK_WED_WPDMA_RING_RX_DATA(idx) +
+- MTK_WED_RING_OFS_CPU_IDX;
+- cur_idx = wed_r32(dev, regs);
++ cur_idx = readl(ring->wpdma + MTK_WED_RING_OFS_CPU_IDX);
+ if (cur_idx == MTK_WED_RX_RING_SIZE - 1)
+ break;
+
+@@ -546,70 +828,133 @@ mtk_wed_check_wfdma_rx_fill(struct mtk_wed_device *dev, int idx)
+ timeout--;
+ } while (timeout > 0);
+
+- if (timeout) {
+- unsigned int val;
++ return timeout;
++}
+
+- val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
+- dev->wlan.phy_base);
+- val |= MTK_WFMDA_RX_DMA_EN;
+
+- wifi_w32(dev, dev->wlan.wpdma_rx_glo -
+- dev->wlan.phy_base, val);
++static void
++mtk_wed_set_512_support(struct mtk_wed_device *dev, bool en)
++{
++ if (en) {
++ wed_w32(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
++ wed_w32(dev, MTK_WED_TXP_DW1,
++ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0103));
+ } else {
+- dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable failed!\n",
+- dev->hw->index, idx);
++ wed_w32(dev, MTK_WED_TXP_DW1,
++ FIELD_PREP(MTK_WED_WPDMA_WRITE_TXP, 0x0100));
++ wed_clr(dev, MTK_WED_TXDP_CTRL, MTK_WED_TXDP_DW9_OVERWR);
+ }
+ }
+
+ static void
+ mtk_wed_dma_enable(struct mtk_wed_device *dev)
+ {
+- wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
+- MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
++#define MTK_WFMDA_RX_DMA_EN BIT(2)
++
++ if (dev->hw->version == 1)
++ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
++ MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
+
+ wed_set(dev, MTK_WED_GLO_CFG,
+ MTK_WED_GLO_CFG_TX_DMA_EN |
+ MTK_WED_GLO_CFG_RX_DMA_EN);
++
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ FIELD_PREP(MTK_WED_WDMA_RX_PREF_BURST_SIZE, 0x10) |
++ FIELD_PREP(MTK_WED_WDMA_RX_PREF_LOW_THRES, 0x8));
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_DDONE2_EN);
++
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
++
+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+- MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN |
++ MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR);
+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+
+ wdma_set(dev, MTK_WDMA_GLO_CFG,
+- MTK_WDMA_GLO_CFG_TX_DMA_EN |
++ MTK_WDMA_GLO_CFG_TX_DMA_EN /*|
+ MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
+- MTK_WDMA_GLO_CFG_RX_INFO2_PRERES);
++ MTK_WDMA_GLO_CFG_RX_INFO2_PRERES*/);
+
+- if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ wdma_set(dev, MTK_WDMA_GLO_CFG,
+ MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
+ } else {
+ int idx = 0;
+
+- wed_set(dev, MTK_WED_WPDMA_CTRL,
+- MTK_WED_WPDMA_CTRL_SDL1_FIXED);
+-
+- wed_set(dev, MTK_WED_WDMA_GLO_CFG,
+- MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
+- MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
++ if (mtk_wed_get_rx_capa(dev))
++ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
++ MTK_WED_WDMA_GLO_CFG_TX_DRV_EN |
++ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
+
+ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_PKT_PROC |
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC);
+
++ if (dev->hw->version == 3) {
++ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
++ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST);
++ wed_set(dev, MTK_WED_WPDMA_GLO_CFG,
++ MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK |
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK |
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
++
++ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
++ //wdma_w32(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++ if (mtk_wed_get_rx_capa(dev)) {
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_EN |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE, 0x10) |
++ FIELD_PREP(MTK_WED_WPDMA_RX_D_PREF_LOW_THRES, 0x8));
++
++ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
++
++ wdma_set(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
++
++ wdma_set(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
++ }
++ }
++
+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP |
+ MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV);
+
++ if (!mtk_wed_get_rx_capa(dev))
++ return;
++
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RXD_READ_LEN);
+ wed_set(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RX_DRV_EN |
+ FIELD_PREP(MTK_WED_WPDMA_RX_D_RXD_READ_LEN, 0x18) |
+ FIELD_PREP(MTK_WED_WPDMA_RX_D_INIT_PHASE_RXEN_SEL,
+ 0x2));
+
+- for (idx = 0; idx < dev->hw->ring_num; idx++)
+- mtk_wed_check_wfdma_rx_fill(dev, idx);
++ for (idx = 0; idx < dev->hw->ring_num; idx++) {
++ struct mtk_wed_ring *ring = &dev->rx_ring[idx];
++
++ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
++ continue;
++
++ if(mtk_wed_check_wfdma_rx_fill(dev, ring)) {
++ unsigned int val;
++
++ val = wifi_r32(dev, dev->wlan.wpdma_rx_glo -
++ dev->wlan.phy_base);
++ val |= MTK_WFMDA_RX_DMA_EN;
++
++ wifi_w32(dev, dev->wlan.wpdma_rx_glo -
++ dev->wlan.phy_base, val);
++
++ dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable successful!\n",
++ dev->hw->index, idx);
++ } else {
++ dev_err(dev->hw->dev, "mtk_wed%d: rx(%d) dma enable failed!\n",
++ dev->hw->index, idx);
++ }
++ }
+ }
+ }
+
+@@ -644,15 +989,20 @@ mtk_wed_dma_disable(struct mtk_wed_device *dev)
+ MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
+ MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK);
+- }
+
+- mtk_wed_set_512_support(dev, false);
++ if (dev->hw->version == 3 && mtk_wed_get_rx_capa(dev)) {
++ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG,
++ MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG,
++ MTK_WDMA_PREF_RX_CFG_PREF_EN);
++ }
++ }
+ }
+
+ static void
+ mtk_wed_stop(struct mtk_wed_device *dev)
+ {
+- if (dev->ver > MTK_WED_V1) {
++ if (mtk_wed_get_rx_capa(dev)) {
+ wed_w32(dev, MTK_WED_EXT_INT_MASK1, 0);
+ wed_w32(dev, MTK_WED_EXT_INT_MASK2, 0);
+ }
+@@ -677,13 +1027,21 @@ mtk_wed_deinit(struct mtk_wed_device *dev)
+ MTK_WED_CTRL_WED_TX_BM_EN |
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+- if (dev->hw->ver == 1)
++ if (dev->hw->version == 1)
+ return;
+
+ wed_clr(dev, MTK_WED_CTRL,
+ MTK_WED_CTRL_RX_ROUTE_QM_EN |
+ MTK_WED_CTRL_WED_RX_BM_EN |
+ MTK_WED_CTRL_RX_RRO_QM_EN);
++
++ if (dev->hw->version == 3) {
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN);
++ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_TX_PAO);
++ wed_clr(dev, MTK_WED_PCIE_INT_CTRL,
++ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
++ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER);
++ }
+ }
+
+ static void
+@@ -702,9 +1060,9 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+
+ mtk_wdma_tx_reset(dev);
+
+- mtk_wed_free_buffer(dev);
++ mtk_wed_free_tx_buffer(dev);
+ mtk_wed_free_tx_rings(dev);
+- if (dev->ver > MTK_WED_V1) {
++ if (mtk_wed_get_rx_capa(dev)) {
+ mtk_wed_wo_reset(dev);
+ mtk_wed_free_rx_rings(dev);
+ mtk_wed_wo_exit(hw);
+@@ -728,73 +1086,97 @@ mtk_wed_detach(struct mtk_wed_device *dev)
+ mutex_unlock(&hw_lock);
+ }
+
++#define IRQ_MASK_APMCU 0x1000301c
+ static void
+ mtk_wed_bus_init(struct mtk_wed_device *dev)
+ {
+-#define PCIE_BASE_ADDR0 0x11280000
++ switch (dev->wlan.bus_type) {
++ case MTK_WED_BUS_PCIE: {
++ struct device_node *np = dev->hw->eth->dev->of_node;
++ struct regmap *regs;
++ unsigned long addr;
++ u32 value;
+
+- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
+- struct device_node *node;
+- void __iomem * base_addr;
+- u32 value = 0;
++ if (dev->hw->version == 2) {
++ regs = syscon_regmap_lookup_by_phandle(np,
++ "mediatek,wed-pcie");
++ if (IS_ERR(regs))
++ break;
+
+- node = of_parse_phandle(dev->hw->node, "mediatek,wed_pcie", 0);
+- if (!node) {
+- pr_err("%s: no wed_pcie node\n", __func__);
+- return;
++ regmap_update_bits(regs, 0, BIT(0), BIT(0));
+ }
+
+- base_addr = of_iomap(node, 0);
+-
+- value = readl(base_addr);
+- value |= BIT(0);
+- writel(value, base_addr);
++ if (dev->wlan.msi) {
++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, dev->hw->pci_base| 0xc08);
++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, dev->hw->pci_base | 0xc04);
++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(8));
++ } else {
++ wed_w32(dev, MTK_WED_PCIE_CFG_INTM, dev->hw->pci_base | 0x180);
++ wed_w32(dev, MTK_WED_PCIE_CFG_BASE, dev->hw->pci_base | 0x184);
++ wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
++ }
+
+- wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
+- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
++ if (dev->hw->version < 3 || dev->hw->index) {
++ wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
++ } else {
++ /* set mask apmcu */
++ addr = (unsigned long)ioremap(IRQ_MASK_APMCU, 4);
++ value = readl((void *)addr);
++ value |= 0x7;
++ writel(value, (void *)addr);
++ iounmap((void *)addr);
++ }
+
+ /* pcie interrupt control: pola/source selection */
+ wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+ MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
+- FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
+- wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
++ MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER |
++ FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, dev->hw->index));
+
+- value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
+- value = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
+- wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
+- wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
+-
+- value = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
+- value = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
+-
+- wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
+- wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
+-
+- /* pola setting */
+- value = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
+- wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+- MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
+- } else if (dev->wlan.bus_type == MTK_WED_BUS_AXI) {
++ break;
++ }
++ case MTK_WED_BUS_AXI:
+ wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
+ MTK_WED_WPDMA_INT_CTRL_SIG_SRC |
+ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0));
++ break;
++ default:
++ break;
+ }
++
+ return;
+ }
+
+ static void
+ mtk_wed_set_wpdma(struct mtk_wed_device *dev)
+ {
+- if (dev->ver > MTK_WED_V1) {
++ if (dev->hw->version == 1) {
++ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
++ } else {
++ mtk_wed_bus_init(dev);
++
+ wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_int);
+ wed_w32(dev, MTK_WED_WPDMA_CFG_INT_MASK, dev->wlan.wpdma_mask);
+- wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
++ wed_w32(dev, MTK_WED_WPDMA_CFG_TX, dev->wlan.wpdma_tx);
+ wed_w32(dev, MTK_WED_WPDMA_CFG_TX_FREE, dev->wlan.wpdma_txfree);
+
+- wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
+- wed_w32(dev, MTK_WED_WPDMA_RX_RING, dev->wlan.wpdma_rx);
+- } else {
+- wed_w32(dev, MTK_WED_WPDMA_CFG_BASE, dev->wlan.wpdma_phys);
++ if (mtk_wed_get_rx_capa(dev)) {
++ int i;
++
++ wed_w32(dev, MTK_WED_WPDMA_RX_GLO_CFG, dev->wlan.wpdma_rx_glo);
++ wed_w32(dev, MTK_WED_WPDMA_RX_RING0, dev->wlan.wpdma_rx);
++ wed_w32(dev, MTK_WED_WPDMA_RX_RING1, dev->wlan.wpdma_rx + 0x10);
++
++ if (dev->wlan.hwrro) {
++ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(0), dev->wlan.wpdma_rx_rro[0]);
++ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(1), dev->wlan.wpdma_rx_rro[1]);
++ for (i = 0; i < MTK_WED_RX_PAGE_QUEUES; i++) {
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING_CFG(i),
++ dev->wlan.wpdma_rx_pg + i * 0x10);
++ }
++ }
++ }
+ }
+ }
+
+@@ -806,21 +1188,25 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
+ mtk_wed_deinit(dev);
+ mtk_wed_reset(dev, MTK_WED_RESET_WED);
+
+- if (dev->ver > MTK_WED_V1)
+- mtk_wed_bus_init(dev);
+-
+ mtk_wed_set_wpdma(dev);
+
+- mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
+- MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
+- MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
+- set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
+- MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
+- MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
++ if (dev->hw->version == 3) {
++ mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE;
++ set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2);
++ } else {
++ mask = MTK_WED_WDMA_GLO_CFG_BT_SIZE |
++ MTK_WED_WDMA_GLO_CFG_DYNAMIC_DMAD_RECYCLE |
++ MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
++ set = FIELD_PREP(MTK_WED_WDMA_GLO_CFG_BT_SIZE, 2) |
++ MTK_WED_WDMA_GLO_CFG_DYNAMIC_SKIP_DMAD_PREP |
++ MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
++ }
++
+ wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
+
+- if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ u32 offset;
++
+ offset = dev->hw->index ? 0x04000400 : 0;
+ wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
+ wed_w32(dev, MTK_WED_WDMA_OFFSET1, 0x29002800 + offset);
+@@ -907,11 +1293,16 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
+ } while (1);
+
+ /* configure RX_ROUTE_QM */
+- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
+- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
+- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
+- FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
+- wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
++ if (dev->hw->version == 2) {
++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_TXDMAD_FPORT);
++ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
++ FIELD_PREP(MTK_WED_RTQM_TXDMAD_FPORT, 0x3 + dev->hw->index));
++ wed_clr(dev, MTK_WED_RTQM_GLO_CFG, MTK_WED_RTQM_Q_RST);
++ } else {
++ wed_set(dev, MTK_WED_RTQM_ENQ_CFG0,
++ FIELD_PREP(MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT, 0x3 + dev->hw->index));
++ }
+
+ /* enable RX_ROUTE_QM */
+ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+@@ -920,23 +1311,45 @@ mtk_wed_route_qm_hw_init(struct mtk_wed_device *dev)
+ static void
+ mtk_wed_tx_hw_init(struct mtk_wed_device *dev)
+ {
+- int size = dev->buf_ring.size;
++ int size = dev->wlan.nbuf;
+ int rev_size = MTK_WED_TX_RING_SIZE / 2;
+- int thr = 1;
++ int thr_lo = 1, thr_hi = 1;
+
+- if (dev->ver > MTK_WED_V1) {
++ if (dev->hw->version == 1) {
++ wed_w32(dev, MTK_WED_TX_BM_CTRL,
++ MTK_WED_TX_BM_CTRL_PAUSE |
++ FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, size / 128) |
++ FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, rev_size / 128));
++ } else {
+ size = MTK_WED_WDMA_RING_SIZE * ARRAY_SIZE(dev->tx_wdma) +
+- dev->buf_ring.size;
++ dev->tx_buf_ring.size;
+ rev_size = size;
+- thr = 0;
++ thr_lo = 0;
++ thr_hi = MTK_WED_TX_BM_DYN_THR_HI;
++
++ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
++ MTK_WED_TX_TKID_CTRL_PAUSE |
++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM,
++ size / 128) |
++ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
++ size / 128));
++
++ /* return SKBID + SDP back to bm */
++ if (dev->ver == 3) {
++ wed_set(dev, MTK_WED_TX_TKID_CTRL,
++ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
++ size = dev->wlan.nbuf;
++ rev_size = size;
++ } else {
++ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
++ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
++ MTK_WED_TX_TKID_DYN_THR_HI);
++ }
+ }
+
+- wed_w32(dev, MTK_WED_TX_BM_CTRL,
+- MTK_WED_TX_BM_CTRL_PAUSE |
+- FIELD_PREP(MTK_WED_TX_BM_CTRL_VLD_GRP_NUM, size / 128) |
+- FIELD_PREP(MTK_WED_TX_BM_CTRL_RSV_GRP_NUM, rev_size / 128));
++ mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
+
+- wed_w32(dev, MTK_WED_TX_BM_BASE, dev->buf_ring.desc_phys);
++ wed_w32(dev, MTK_WED_TX_BM_BASE, dev->tx_buf_ring.desc_phys);
+
+ wed_w32(dev, MTK_WED_TX_BM_TKID,
+ FIELD_PREP(MTK_WED_TX_BM_TKID_START,
+@@ -946,25 +1359,44 @@ mtk_wed_tx_hw_init(struct mtk_wed_device *dev)
+
+ wed_w32(dev, MTK_WED_TX_BM_BUF_LEN, MTK_WED_PKT_SIZE);
+
+- wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
+- FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, thr) |
+- MTK_WED_TX_BM_DYN_THR_HI);
++ if (dev->hw->version < 3)
++ wed_w32(dev, MTK_WED_TX_BM_DYN_THR,
++ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, thr_lo) |
++ FIELD_PREP(MTK_WED_TX_BM_DYN_THR_LO, thr_hi));
++ else {
++ /* change to new bm */
++ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR, dev->tx_buf_ring.pkt_nums |
++ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
++ wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_LEGACY_EN);
++ }
+
+- if (dev->ver > MTK_WED_V1) {
++ if (dev->hw->version != 1) {
+ wed_w32(dev, MTK_WED_TX_TKID_CTRL,
+ MTK_WED_TX_TKID_CTRL_PAUSE |
+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM,
+- dev->buf_ring.size / 128) |
++ size / 128) |
+ FIELD_PREP(MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM,
+- dev->buf_ring.size / 128));
+- wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
+- FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
+- MTK_WED_TX_TKID_DYN_THR_HI);
++ size / 128));
++
++ /* return SKBID + SDP back to bm */
++ if (dev->ver == 3)
++ wed_set(dev, MTK_WED_TX_TKID_CTRL,
++ MTK_WED_TX_TKID_CTRL_FREE_FORMAT);
++ else
++ wed_w32(dev, MTK_WED_TX_TKID_DYN_THR,
++ FIELD_PREP(MTK_WED_TX_TKID_DYN_THR_LO, 0) |
++ MTK_WED_TX_TKID_DYN_THR_HI);
+ }
+- mtk_wed_reset(dev, MTK_WED_RESET_TX_BM);
++ wed_w32(dev, MTK_WED_TX_BM_TKID,
++ FIELD_PREP(MTK_WED_TX_BM_TKID_START,
++ dev->wlan.token_start) |
++ FIELD_PREP(MTK_WED_TX_BM_TKID_END,
++ dev->wlan.token_start + dev->wlan.nbuf - 1));
+
++ wed_w32(dev, MTK_WED_TX_BM_INIT_PTR, dev->tx_buf_ring.pkt_nums |
++ MTK_WED_TX_BM_INIT_SW_TAIL_IDX);
+ wed_clr(dev, MTK_WED_TX_BM_CTRL, MTK_WED_TX_BM_CTRL_PAUSE);
+- if (dev->ver > MTK_WED_V1)
++ if (dev->hw->version != 1)
+ wed_clr(dev, MTK_WED_TX_TKID_CTRL, MTK_WED_TX_TKID_CTRL_PAUSE);
+ }
+
+@@ -977,7 +1409,26 @@ mtk_wed_rx_hw_init(struct mtk_wed_device *dev)
+
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX, 0);
+
++ /* reset prefetch index of ring */
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX,
++ MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR);
++
++ /* reset prefetch FIFO of ring */
++ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR |
++ MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR);
++ wed_w32(dev, MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG, 0);
++
+ mtk_wed_rx_bm_hw_init(dev);
++ if (dev->wlan.hwrro)
++ mtk_wed_hwrro_init(dev);
+ mtk_wed_rro_hw_init(dev);
+ mtk_wed_route_qm_hw_init(dev);
+ }
+@@ -991,7 +1442,7 @@ mtk_wed_hw_init(struct mtk_wed_device *dev)
+ dev->init_done = true;
+ mtk_wed_set_ext_int(dev, false);
+ mtk_wed_tx_hw_init(dev);
+- if (dev->ver > MTK_WED_V1)
++ if (mtk_wed_get_rx_capa(dev))
+ mtk_wed_rx_hw_init(dev);
+ }
+
+@@ -1015,26 +1466,6 @@ mtk_wed_ring_reset(struct mtk_wdma_desc *desc, int size, int scale, bool tx)
+ }
+ }
+
+-static u32
+-mtk_wed_check_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
+-{
+- if (wed_r32(dev, reg) & mask)
+- return true;
+-
+- return false;
+-}
+-
+-static int
+-mtk_wed_poll_busy(struct mtk_wed_device *dev, u32 reg, u32 mask)
+-{
+- int sleep = 1000;
+- int timeout = 100 * sleep;
+- u32 val;
+-
+- return read_poll_timeout(mtk_wed_check_busy, val, !val, sleep,
+- timeout, false, dev, reg, mask);
+-}
+-
+ static void
+ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ {
+@@ -1133,7 +1564,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ mtk_wed_ring_reset(desc, MTK_WED_RX_RING_SIZE, 1, false);
+ }
+
+- mtk_wed_free_rx_bm(dev);
++ mtk_wed_free_rx_buffer(dev);
+ }
+
+
+@@ -1271,12 +1702,15 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_wed_device *dev,
+ int idx, int size, bool reset)
+ {
+ struct mtk_wed_ring *wdma = &dev->tx_wdma[idx];
++ int scale = dev->hw->version > 1 ? 2 : 1;
+
+ if(!reset)
+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+- dev->ver, true))
++ scale, true))
+ return -ENOMEM;
+
++ wdma->flags |= MTK_WED_RING_CONFIGURED;
++
+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE,
+ wdma->desc_phys);
+ wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT,
+@@ -1296,12 +1730,31 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev,
+ int idx, int size, bool reset)
+ {
+ struct mtk_wed_ring *wdma = &dev->rx_wdma[idx];
++ int scale = dev->hw->version > 1 ? 2 : 1;
+
+ if (!reset)
+ if (mtk_wed_ring_alloc(dev, wdma, MTK_WED_WDMA_RING_SIZE,
+- dev->ver, true))
++ scale, true))
+ return -ENOMEM;
+
++ if (dev->hw->version == 3) {
++ struct mtk_wdma_desc *desc = wdma->desc;
++ int i;
++
++ for (i = 0; i < MTK_WED_WDMA_RING_SIZE; i++) {
++ desc->buf0 = 0;
++ desc->ctrl = MTK_WDMA_DESC_CTRL_DMA_DONE;
++ desc->buf1 = 0;
++ desc->info = MTK_WDMA_TXD0_DESC_INFO_DMA_DONE;
++ desc++;
++ desc->buf0 = 0;
++ desc->ctrl = MTK_WDMA_DESC_CTRL_DMA_DONE;
++ desc->buf1 = 0;
++ desc->info = MTK_WDMA_TXD1_DESC_INFO_DMA_DONE;
++ desc++;
++ }
++ }
++
+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE,
+ wdma->desc_phys);
+ wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT,
+@@ -1312,7 +1765,7 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_wed_device *dev,
+ MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_DMA_IDX, 0);
+ if (reset)
+ mtk_wed_ring_reset(wdma->desc, MTK_WED_WDMA_RING_SIZE,
+- dev->ver, true);
++ scale, true);
+ if (idx == 0) {
+ wed_w32(dev, MTK_WED_WDMA_RING_TX
+ + MTK_WED_RING_OFS_BASE, wdma->desc_phys);
+@@ -1395,7 +1848,7 @@ mtk_wed_send_msg(struct mtk_wed_device *dev, int cmd_id, void *data, int len)
+ {
+ struct mtk_wed_wo *wo = dev->hw->wed_wo;
+
+- if (dev->ver == MTK_WED_V1)
++ if (!mtk_wed_get_rx_capa(dev))
+ return 0;
+
+ return mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, cmd_id, data, len, true);
+@@ -1420,13 +1873,87 @@ mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
+ }
+ }
+
++static void
++mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask)
++{
++ int idx, ret;
++
++ wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
++ wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
++
++ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hwrro)
++ return;
++
++ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
++
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_RX,
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG,
++ dev->wlan.rro_rx_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG,
++ dev->wlan.rro_rx_tbit[1]));
++
++ wed_w32(dev, MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG,
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN |
++ MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG,
++ dev->wlan.rx_pg_tbit[0]) |
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG,
++ dev->wlan.rx_pg_tbit[1])|
++ FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG,
++ dev->wlan.rx_pg_tbit[2]));
++
++ /*
++ * RRO_MSDU_PG_RING2_CFG1_FLD_DRV_EN should be enabled after
++ * WM FWDL completed, otherwise RRO_MSDU_PG ring may broken
++ */
++ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
++
++ for (idx = 0; idx < MTK_WED_RX_QUEUES; idx++) {
++ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
++
++ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
++ continue;
++
++ ret = mtk_wed_check_wfdma_rx_fill(dev, ring);
++ if (!ret)
++ dev_err(dev->hw->dev, "mtk_wed%d: rx_rro_ring(%d) init failed!\n",
++ dev->hw->index, idx);
++ }
++
++ for (idx = 0; idx < MTK_WED_RX_PAGE_QUEUES; idx++){
++ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
++ if(!(ring->flags & MTK_WED_RING_CONFIGURED))
++ continue;
++
++ ret = mtk_wed_check_wfdma_rx_fill(dev, ring);
++ if (!ret)
++ dev_err(dev->hw->dev, "mtk_wed%d: rx_page_ring(%d) init failed!\n",
++ dev->hw->index, idx);
++ }
++}
++
+ static void
+ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ {
+ int i, ret;
+
+- if (dev->ver > MTK_WED_V1)
+- ret = mtk_wed_rx_bm_alloc(dev);
++ if (mtk_wed_get_rx_capa(dev)) {
++ ret = mtk_wed_rx_buffer_alloc(dev);
++ if (ret)
++ return;
++
++ if (dev->wlan.hwrro)
++ mtk_wed_rx_page_buffer_alloc(dev);
++ }
+
+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+ if (!dev->tx_wdma[i].desc)
+@@ -1437,7 +1964,7 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ mtk_wed_set_int(dev, irq_mask);
+ mtk_wed_set_ext_int(dev, true);
+
+- if (dev->ver == MTK_WED_V1) {
++ if (dev->hw->version == 1) {
+ u32 val;
+
+ val = dev->wlan.wpdma_phys |
+@@ -1448,33 +1975,52 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+ val |= BIT(1);
+ val |= BIT(0);
+ regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
+- } else {
++ } else if (mtk_wed_get_rx_capa(dev)) {
+ /* driver set mid ready and only once */
+ wed_w32(dev, MTK_WED_EXT_INT_MASK1,
+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
+ wed_w32(dev, MTK_WED_EXT_INT_MASK2,
+ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
++ if (dev->hw->version == 3)
++ wed_w32(dev, MTK_WED_EXT_INT_MASK3,
++ MTK_WED_EXT_INT_STATUS_WPDMA_MID_RDY);
+
+ wed_r32(dev, MTK_WED_EXT_INT_MASK1);
+ wed_r32(dev, MTK_WED_EXT_INT_MASK2);
++ if (dev->hw->version == 3)
++ wed_r32(dev, MTK_WED_EXT_INT_MASK3);
+
+ ret = mtk_wed_rro_cfg(dev);
+ if (ret)
+ return;
+ }
+- mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
++
++ if (dev->hw->version == 2)
++ mtk_wed_set_512_support(dev, dev->wlan.wcid_512);
++ else if (dev->hw->version == 3)
++ mtk_wed_pao_init(dev);
+
+ mtk_wed_dma_enable(dev);
+ dev->running = true;
+ }
+
++static int
++mtk_wed_get_pci_base(struct mtk_wed_device *dev)
++{
++ if (dev->hw->index == 0)
++ return MTK_WED_PCIE_BASE0;
++ else if (dev->hw->index == 1)
++ return MTK_WED_PCIE_BASE1;
++ else
++ return MTK_WED_PCIE_BASE2;
++}
++
+ static int
+ mtk_wed_attach(struct mtk_wed_device *dev)
+ __releases(RCU)
+ {
+ struct mtk_wed_hw *hw;
+ struct device *device;
+- u16 ver;
+ int ret = 0;
+
+ RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
+@@ -1494,34 +2040,30 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ goto out;
+ }
+
+- device = dev->wlan.bus_type == MTK_WED_BUS_PCIE
+- ? &dev->wlan.pci_dev->dev
+- : &dev->wlan.platform_dev->dev;
++ device = dev->wlan.bus_type == MTK_WED_BUS_PCIE ?
++ &dev->wlan.pci_dev->dev
++ : &dev->wlan.platform_dev->dev;
+ dev_info(device, "attaching wed device %d version %d\n",
+- hw->index, hw->ver);
++ hw->index, hw->version);
+
+ dev->hw = hw;
+ dev->dev = hw->dev;
+ dev->irq = hw->irq;
+ dev->wdma_idx = hw->index;
++ dev->ver = hw->version;
++
++ if (dev->hw->version == 3)
++ dev->hw->pci_base = mtk_wed_get_pci_base(dev);
+
+ if (hw->eth->dma_dev == hw->eth->dev &&
+ of_dma_is_coherent(hw->eth->dev->of_node))
+ mtk_eth_set_dma_device(hw->eth, hw->dev);
+
+- dev->ver = FIELD_GET(MTK_WED_REV_ID_MAJOR,
+- wed_r32(dev, MTK_WED_REV_ID));
+- if (dev->ver > MTK_WED_V1)
+- ver = FIELD_GET(MTK_WED_REV_ID_MINOR,
+- wed_r32(dev, MTK_WED_REV_ID));
+-
+- dev->rev_id = ((dev->ver << 28) | ver << 16);
+-
+- ret = mtk_wed_buffer_alloc(dev);
++ ret = mtk_wed_tx_buffer_alloc(dev);
+ if (ret)
+ goto error;
+
+- if (dev->ver > MTK_WED_V1) {
++ if (mtk_wed_get_rx_capa(dev)) {
+ ret = mtk_wed_rro_alloc(dev);
+ if (ret)
+ goto error;
+@@ -1533,15 +2075,20 @@ mtk_wed_attach(struct mtk_wed_device *dev)
+ init_completion(&dev->wlan_reset_done);
+ atomic_set(&dev->fe_reset, 0);
+
+- if (dev->ver == MTK_WED_V1)
++ if (dev->hw->version != 1)
++ dev->rev_id = wed_r32(dev, MTK_WED_REV_ID);
++ else
+ regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
+ BIT(hw->index), 0);
+- else
++
++ if (mtk_wed_get_rx_capa(dev))
+ ret = mtk_wed_wo_init(hw);
+
+ error:
+- if (ret)
++ if (ret) {
++ pr_info("%s: detach wed\n", __func__);
+ mtk_wed_detach(dev);
++ }
+ out:
+ mutex_unlock(&hw_lock);
+
+@@ -1576,8 +2123,26 @@ mtk_wed_tx_ring_setup(struct mtk_wed_device *dev, int idx,
+ if (mtk_wed_wdma_rx_ring_setup(dev, idx, MTK_WED_WDMA_RING_SIZE, reset))
+ return -ENOMEM;
+
++ if (dev->hw->version == 3 && idx == 1) {
++ /* reset prefetch index */
++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
++
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR |
++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR);
++
++ /* reset prefetch FIFO */
++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG,
++ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR |
++ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR);
++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0);
++ }
++
+ ring->reg_base = MTK_WED_RING_TX(idx);
+ ring->wpdma = regs;
++ ring->flags |= MTK_WED_RING_CONFIGURED;
+
+ /* WED -> WPDMA */
+ wpdma_tx_w32(dev, idx, MTK_WED_RING_OFS_BASE, ring->desc_phys);
+@@ -1599,7 +2164,7 @@ mtk_wed_txfree_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
+ struct mtk_wed_ring *ring = &dev->txfree_ring;
+ int i, idx = 1;
+
+- if(dev->ver > MTK_WED_V1)
++ if(dev->hw->version > 1)
+ idx = 0;
+
+ /*
+@@ -1652,6 +2217,129 @@ mtk_wed_rx_ring_setup(struct mtk_wed_device *dev,
+ return 0;
+ }
+
++static int
++mtk_wed_rro_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
++{
++ struct mtk_wed_ring *ring = &dev->rx_rro_ring[idx];
++
++ ring->wpdma = regs;
++
++ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_BASE,
++ readl(regs));
++ wed_w32(dev, MTK_WED_RRO_RX_D_RX(idx) + MTK_WED_RING_OFS_COUNT,
++ readl(regs + MTK_WED_RING_OFS_COUNT));
++
++ ring->flags |= MTK_WED_RING_CONFIGURED;
++
++ return 0;
++}
++
++static int
++mtk_wed_msdu_pg_rx_ring_setup(struct mtk_wed_device *dev, int idx, void __iomem *regs)
++{
++ struct mtk_wed_ring *ring = &dev->rx_page_ring[idx];
++
++ ring->wpdma = regs;
++
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_BASE,
++ readl(regs));
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_CTRL0(idx) + MTK_WED_RING_OFS_COUNT,
++ readl(regs + MTK_WED_RING_OFS_COUNT));
++
++ ring->flags |= MTK_WED_RING_CONFIGURED;
++
++ return 0;
++}
++
++static int
++mtk_wed_ind_rx_ring_setup(struct mtk_wed_device *dev, void __iomem *regs)
++{
++ struct mtk_wed_ring *ring = &dev->ind_cmd_ring;
++ u32 val = readl(regs + MTK_WED_RING_OFS_COUNT);
++ int i = 0, cnt = 0;
++
++ ring->wpdma = regs;
++
++ if (readl(regs) & 0xf)
++ pr_info("%s(): address is not 16-byte alignment\n", __func__);
++
++ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_BASE,
++ readl(regs) & 0xfffffff0);
++
++ wed_w32(dev, MTK_WED_IND_CMD_RX_CTRL1 + MTK_WED_RING_OFS_COUNT,
++ readl(regs + MTK_WED_RING_OFS_COUNT));
++
++ /* ack sn cr */
++ wed_w32(dev, MTK_WED_RRO_CFG0, dev->wlan.phy_base +
++ dev->wlan.ind_cmd.ack_sn_addr);
++ wed_w32(dev, MTK_WED_RRO_CFG1,
++ FIELD_PREP(MTK_WED_RRO_CFG1_MAX_WIN_SZ,
++ dev->wlan.ind_cmd.win_size) |
++ FIELD_PREP(MTK_WED_RRO_CFG1_PARTICL_SE_ID,
++ dev->wlan.ind_cmd.particular_sid));
++
++ /* particular session addr element */
++ wed_w32(dev, MTK_WED_ADDR_ELEM_CFG0, dev->wlan.ind_cmd.particular_se_phys);
++
++ for (i = 0; i < dev->wlan.ind_cmd.se_group_nums; i++) {
++ wed_w32(dev, MTK_WED_RADDR_ELEM_TBL_WDATA,
++ dev->wlan.ind_cmd.addr_elem_phys[i] >> 4);
++ wed_w32(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
++ MTK_WED_ADDR_ELEM_TBL_WR | (i & 0x7f));
++
++ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
++ while (!(val & MTK_WED_ADDR_ELEM_TBL_WR_RDY) &&
++ cnt < 100) {
++ val = wed_r32(dev, MTK_WED_ADDR_ELEM_TBL_CFG);
++ cnt++;
++ }
++ if (cnt >= 100) {
++ dev_err(dev->hw->dev, "mtk_wed%d: write ba session base failed!\n",
++ dev->hw->index);
++ }
++ /*if (mtk_wed_poll_busy(dev, MTK_WED_ADDR_ELEM_TBL_CFG,
++ MTK_WED_ADDR_ELEM_TBL_WR_RDY)) {
++ dev_err(dev->hw->dev, "mtk_wed%d: write ba session base failed!\n",
++ dev->hw->index);
++ return -1;
++ }*/
++ }
++
++ /* pn check init */
++ for (i = 0; i < dev->wlan.ind_cmd.particular_sid; i++) {
++ wed_w32(dev, MTK_WED_PN_CHECK_WDATA_M,
++ MTK_WED_PN_CHECK_IS_FIRST);
++
++ wed_w32(dev, MTK_WED_PN_CHECK_CFG, MTK_WED_PN_CHECK_WR |
++ FIELD_PREP(MTK_WED_PN_CHECK_SE_ID, i));
++
++ cnt = 0;
++ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
++ while (!(val & MTK_WED_PN_CHECK_WR_RDY) &&
++ cnt < 100) {
++ val = wed_r32(dev, MTK_WED_PN_CHECK_CFG);
++ cnt++;
++ }
++ if (cnt >= 100) {
++ dev_err(dev->hw->dev, "mtk_wed%d: session(%d) init failed!\n",
++ dev->hw->index, i);
++ }
++ /*if (mtk_wed_poll_busy(dev, MTK_WED_PN_CHECK_CFG,
++ MTK_WED_PN_CHECK_WR_RDY)) {
++ dev_err(dev->hw->dev, "mtk_wed%d: session(%d) init failed!\n",
++ dev->hw->index, i);
++ //return -1;
++ }*/
++ }
++
++ wed_w32(dev, MTK_WED_RX_IND_CMD_CNT0, MTK_WED_RX_IND_CMD_DBG_CNT_EN);
++
++ wed_set(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
++
++ return 0;
++}
++
++
+ static u32
+ mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
+ {
+@@ -1660,6 +2348,8 @@ mtk_wed_irq_get(struct mtk_wed_device *dev, u32 mask)
+ val = wed_r32(dev, MTK_WED_EXT_INT_STATUS);
+ wed_w32(dev, MTK_WED_EXT_INT_STATUS, val);
+ val &= MTK_WED_EXT_INT_STATUS_ERROR_MASK;
++ if (dev->hw->version == 3)
++ val &= MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT;
+ WARN_RATELIMIT(val, "mtk_wed%d: error status=%08x\n",
+ dev->hw->index, val);
+
+@@ -1752,6 +2442,9 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ .tx_ring_setup = mtk_wed_tx_ring_setup,
+ .txfree_ring_setup = mtk_wed_txfree_ring_setup,
+ .rx_ring_setup = mtk_wed_rx_ring_setup,
++ .rro_rx_ring_setup = mtk_wed_rro_rx_ring_setup,
++ .msdu_pg_rx_ring_setup = mtk_wed_msdu_pg_rx_ring_setup,
++ .ind_rx_ring_setup = mtk_wed_ind_rx_ring_setup,
+ .msg_update = mtk_wed_send_msg,
+ .start = mtk_wed_start,
+ .stop = mtk_wed_stop,
+@@ -1763,6 +2456,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ .detach = mtk_wed_detach,
+ .setup_tc = mtk_wed_eth_setup_tc,
+ .ppe_check = mtk_wed_ppe_check,
++ .start_hwrro = mtk_wed_start_hwrro,
+ };
+ struct device_node *eth_np = eth->dev->of_node;
+ struct platform_device *pdev;
+@@ -1802,9 +2496,10 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ hw->wdma_phy = wdma_phy;
+ hw->index = index;
+ hw->irq = irq;
+- hw->ver = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
++ hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) ?
++ 3 : MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+
+- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++ if (hw->version == 1) {
+ hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
+ "mediatek,pcie-mirror");
+ hw->hifsys = syscon_regmap_lookup_by_phandle(eth_np,
+@@ -1819,7 +2514,6 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
+ regmap_write(hw->mirror, 0, 0);
+ regmap_write(hw->mirror, 4, 0);
+ }
+- hw->ver = MTK_WED_V1;
+ }
+
+ mtk_wed_hw_add_debugfs(hw);
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.h b/drivers/net/ethernet/mediatek/mtk_wed.h
+index 490873c..fcf7bd0 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed.h
+@@ -10,10 +10,13 @@
+ #include <linux/netdevice.h>
+ #define MTK_PCIE_BASE(n) (0x1a143000 + (n) * 0x2000)
+
+-#define MTK_WED_PKT_SIZE 1900
++#define MTK_WED_PKT_SIZE 1920//1900
+ #define MTK_WED_BUF_SIZE 2048
++#define MTK_WED_PAGE_BUF_SIZE 128
+ #define MTK_WED_BUF_PER_PAGE (PAGE_SIZE / 2048)
++#define MTK_WED_RX_PAGE_BUF_PER_PAGE (PAGE_SIZE / 128)
+ #define MTK_WED_RX_RING_SIZE 1536
++#define MTK_WED_RX_PG_BM_CNT 8192
+
+ #define MTK_WED_TX_RING_SIZE 2048
+ #define MTK_WED_WDMA_RING_SIZE 512
+@@ -27,6 +30,9 @@
+ #define MTK_WED_RRO_QUE_CNT 8192
+ #define MTK_WED_MIOD_ENTRY_CNT 128
+
++#define MTK_WED_TX_BM_DMA_SIZE 65536
++#define MTK_WED_TX_BM_PKT_CNT 32768
++
+ #define MODULE_ID_WO 1
+
+ struct mtk_eth;
+@@ -43,6 +49,8 @@ struct mtk_wed_hw {
+ struct dentry *debugfs_dir;
+ struct mtk_wed_device *wed_dev;
+ struct mtk_wed_wo *wed_wo;
++ struct mtk_wed_pao *wed_pao;
++ u32 pci_base;
+ u32 debugfs_reg;
+ u32 num_flows;
+ u32 wdma_phy;
+@@ -50,7 +58,8 @@ struct mtk_wed_hw {
+ int ring_num;
+ int irq;
+ int index;
+- u32 ver;
++ int token_id;
++ u32 version;
+ };
+
+ struct mtk_wdma_info {
+@@ -58,6 +67,18 @@ struct mtk_wdma_info {
+ u8 queue;
+ u16 wcid;
+ u8 bss;
++ u32 usr_info;
++ u8 tid;
++ u8 is_fixedrate;
++ u8 is_prior;
++ u8 is_sp;
++ u8 hf;
++ u8 amsdu_en;
++};
++
++struct mtk_wed_pao {
++ char *hif_txd[32];
++ dma_addr_t hif_txd_phys[32];
+ };
+
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+index 4a9e684..51e3d7c 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_debugfs.c
+@@ -11,9 +11,11 @@ struct reg_dump {
+ u16 offset;
+ u8 type;
+ u8 base;
++ u32 mask;
+ };
+
+ enum {
++ DUMP_TYPE_END,
+ DUMP_TYPE_STRING,
+ DUMP_TYPE_WED,
+ DUMP_TYPE_WDMA,
+@@ -23,8 +25,11 @@ enum {
+ DUMP_TYPE_WED_RRO,
+ };
+
++#define DUMP_END() { .type = DUMP_TYPE_END }
+ #define DUMP_STR(_str) { _str, 0, DUMP_TYPE_STRING }
+ #define DUMP_REG(_reg, ...) { #_reg, MTK_##_reg, __VA_ARGS__ }
++#define DUMP_REG_MASK(_reg, _mask) { #_mask, MTK_##_reg, DUMP_TYPE_WED, 0, MTK_##_mask }
++
+ #define DUMP_RING(_prefix, _base, ...) \
+ { _prefix " BASE", _base, __VA_ARGS__ }, \
+ { _prefix " CNT", _base + 0x4, __VA_ARGS__ }, \
+@@ -32,6 +37,7 @@ enum {
+ { _prefix " DIDX", _base + 0xc, __VA_ARGS__ }
+
+ #define DUMP_WED(_reg) DUMP_REG(_reg, DUMP_TYPE_WED)
++#define DUMP_WED_MASK(_reg, _mask) DUMP_REG_MASK(_reg, _mask)
+ #define DUMP_WED_RING(_base) DUMP_RING(#_base, MTK_##_base, DUMP_TYPE_WED)
+
+ #define DUMP_WDMA(_reg) DUMP_REG(_reg, DUMP_TYPE_WDMA)
+@@ -52,36 +58,49 @@ print_reg_val(struct seq_file *s, const char *name, u32 val)
+
+ static void
+ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
+- const struct reg_dump *regs, int n_regs)
++ const struct reg_dump **regs)
+ {
+- const struct reg_dump *cur;
++ const struct reg_dump **cur_o = regs, *cur;
++ bool newline = false;
+ u32 val;
+
+- for (cur = regs; cur < ®s[n_regs]; cur++) {
+- switch (cur->type) {
+- case DUMP_TYPE_STRING:
+- seq_printf(s, "%s======== %s:\n",
+- cur > regs ? "\n" : "",
+- cur->name);
+- continue;
+- case DUMP_TYPE_WED:
+- case DUMP_TYPE_WED_RRO:
+- val = wed_r32(dev, cur->offset);
+- break;
+- case DUMP_TYPE_WDMA:
+- val = wdma_r32(dev, cur->offset);
+- break;
+- case DUMP_TYPE_WPDMA_TX:
+- val = wpdma_tx_r32(dev, cur->base, cur->offset);
+- break;
+- case DUMP_TYPE_WPDMA_TXFREE:
+- val = wpdma_txfree_r32(dev, cur->offset);
+- break;
+- case DUMP_TYPE_WPDMA_RX:
+- val = wpdma_rx_r32(dev, cur->base, cur->offset);
+- break;
++ while (*cur_o) {
++ cur = *cur_o;
++
++ while (cur->type != DUMP_TYPE_END) {
++ switch (cur->type) {
++ case DUMP_TYPE_STRING:
++ seq_printf(s, "%s======== %s:\n",
++ newline ? "\n" : "",
++ cur->name);
++ newline = true;
++ cur++;
++ continue;
++ case DUMP_TYPE_WED:
++ case DUMP_TYPE_WED_RRO:
++ val = wed_r32(dev, cur->offset);
++ break;
++ case DUMP_TYPE_WDMA:
++ val = wdma_r32(dev, cur->offset);
++ break;
++ case DUMP_TYPE_WPDMA_TX:
++ val = wpdma_tx_r32(dev, cur->base, cur->offset);
++ break;
++ case DUMP_TYPE_WPDMA_TXFREE:
++ val = wpdma_txfree_r32(dev, cur->offset);
++ break;
++ case DUMP_TYPE_WPDMA_RX:
++ val = wpdma_rx_r32(dev, cur->base, cur->offset);
++ break;
++ }
++
++ if (cur->mask)
++ val = (cur->mask & val) >> (ffs(cur->mask) - 1);
++
++ print_reg_val(s, cur->name, val);
++ cur++;
+ }
+- print_reg_val(s, cur->name, val);
++ cur_o++;
+ }
+ }
+
+@@ -89,7 +108,7 @@ dump_wed_regs(struct seq_file *s, struct mtk_wed_device *dev,
+ static int
+ wed_txinfo_show(struct seq_file *s, void *data)
+ {
+- static const struct reg_dump regs[] = {
++ static const struct reg_dump regs_common[] = {
+ DUMP_STR("WED TX"),
+ DUMP_WED(WED_TX_MIB(0)),
+ DUMP_WED_RING(WED_RING_TX(0)),
+@@ -128,16 +147,32 @@ wed_txinfo_show(struct seq_file *s, void *data)
+ DUMP_WDMA_RING(WDMA_RING_RX(0)),
+ DUMP_WDMA_RING(WDMA_RING_RX(1)),
+
+- DUMP_STR("TX FREE"),
++ DUMP_STR("WED TX FREE"),
+ DUMP_WED(WED_RX_MIB(0)),
++ DUMP_WED_RING(WED_RING_RX(0)),
++ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(0)),
++
++ DUMP_WED(WED_RX_MIB(1)),
++ DUMP_WED_RING(WED_RING_RX(1)),
++ DUMP_WED(WED_WPDMA_RX_COHERENT_MIB(1)),
++ DUMP_STR("WED_WPDMA TX FREE"),
++ DUMP_WED_RING(WED_WPDMA_RING_RX(0)),
++ DUMP_WED_RING(WED_WPDMA_RING_RX(1)),
++ DUMP_END(),
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
+ };
++
+ struct mtk_wed_hw *hw = s->private;
+ struct mtk_wed_device *dev = hw->wed_dev;
+
+ if (!dev)
+ return 0;
+
+- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
++ dump_wed_regs(s, dev, regs);
+
+ return 0;
+ }
+@@ -146,7 +181,7 @@ DEFINE_SHOW_ATTRIBUTE(wed_txinfo);
+ static int
+ wed_rxinfo_show(struct seq_file *s, void *data)
+ {
+- static const struct reg_dump regs[] = {
++ static const struct reg_dump regs_common[] = {
+ DUMP_STR("WPDMA RX"),
+ DUMP_WPDMA_RX_RING(0),
+ DUMP_WPDMA_RX_RING(1),
+@@ -164,7 +199,7 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ DUMP_WED_RING(WED_RING_RX_DATA(0)),
+ DUMP_WED_RING(WED_RING_RX_DATA(1)),
+
+- DUMP_STR("WED RRO"),
++ DUMP_STR("WED WO RRO"),
+ DUMP_WED_RRO_RING(WED_RROQM_MIOD_CTRL0),
+ DUMP_WED(WED_RROQM_MID_MIB),
+ DUMP_WED(WED_RROQM_MOD_MIB),
+@@ -175,16 +210,6 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ DUMP_WED(WED_RROQM_FDBK_ANC_MIB),
+ DUMP_WED(WED_RROQM_FDBK_ANC2H_MIB),
+
+- DUMP_STR("WED Route QM"),
+- DUMP_WED(WED_RTQM_R2H_MIB(0)),
+- DUMP_WED(WED_RTQM_R2Q_MIB(0)),
+- DUMP_WED(WED_RTQM_Q2H_MIB(0)),
+- DUMP_WED(WED_RTQM_R2H_MIB(1)),
+- DUMP_WED(WED_RTQM_R2Q_MIB(1)),
+- DUMP_WED(WED_RTQM_Q2H_MIB(1)),
+- DUMP_WED(WED_RTQM_Q2N_MIB),
+- DUMP_WED(WED_RTQM_Q2B_MIB),
+- DUMP_WED(WED_RTQM_PFDBK_MIB),
+
+ DUMP_STR("WED WDMA TX"),
+ DUMP_WED(WED_WDMA_TX_MIB),
+@@ -205,15 +230,99 @@ wed_rxinfo_show(struct seq_file *s, void *data)
+ DUMP_WED(WED_RX_BM_INTF2),
+ DUMP_WED(WED_RX_BM_INTF),
+ DUMP_WED(WED_RX_BM_ERR_STS),
++ DUMP_END()
++ };
++
++ static const struct reg_dump regs_v2[] = {
++ DUMP_STR("WED Route QM"),
++ DUMP_WED(WED_RTQM_R2H_MIB(0)),
++ DUMP_WED(WED_RTQM_R2Q_MIB(0)),
++ DUMP_WED(WED_RTQM_Q2H_MIB(0)),
++ DUMP_WED(WED_RTQM_R2H_MIB(1)),
++ DUMP_WED(WED_RTQM_R2Q_MIB(1)),
++ DUMP_WED(WED_RTQM_Q2H_MIB(1)),
++ DUMP_WED(WED_RTQM_Q2N_MIB),
++ DUMP_WED(WED_RTQM_Q2B_MIB),
++ DUMP_WED(WED_RTQM_PFDBK_MIB),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump regs_v3[] = {
++ DUMP_STR("WED RX RRO DATA"),
++ DUMP_WED_RING(WED_RRO_RX_D_RX(0)),
++ DUMP_WED_RING(WED_RRO_RX_D_RX(1)),
++
++ DUMP_STR("WED RX MSDU PAGE"),
++ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(0)),
++ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(1)),
++ DUMP_WED_RING(WED_RRO_MSDU_PG_CTRL0(2)),
++
++ DUMP_STR("WED RX IND CMD"),
++ DUMP_WED(WED_IND_CMD_RX_CTRL1),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL2, WED_IND_CMD_MAX_CNT),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_PROC_IDX),
++ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_DMA_IDX),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0, WED_IND_CMD_MAGIC_CNT),
++ DUMP_WED_MASK(RRO_IND_CMD_SIGNATURE, RRO_IND_CMD_MAGIC_CNT),
++ DUMP_WED_MASK(WED_IND_CMD_RX_CTRL0,
++ WED_IND_CMD_PREFETCH_FREE_CNT),
++ DUMP_WED_MASK(WED_RRO_CFG1, WED_RRO_CFG1_PARTICL_SE_ID),
++
++ DUMP_STR("WED ADDR ELEM"),
++ DUMP_WED(WED_ADDR_ELEM_CFG0),
++ DUMP_WED_MASK(WED_ADDR_ELEM_CFG1,
++ WED_ADDR_ELEM_PREFETCH_FREE_CNT),
++
++ DUMP_STR("WED Route QM"),
++ DUMP_WED(WED_RTQM_ENQ_I2Q_DMAD_CNT),
++ DUMP_WED(WED_RTQM_ENQ_I2N_DMAD_CNT),
++ DUMP_WED(WED_RTQM_ENQ_I2Q_PKT_CNT),
++ DUMP_WED(WED_RTQM_ENQ_I2N_PKT_CNT),
++ DUMP_WED(WED_RTQM_ENQ_USED_ENTRY_CNT),
++ DUMP_WED(WED_RTQM_ENQ_ERR_CNT),
++
++ DUMP_WED(WED_RTQM_DEQ_DMAD_CNT),
++ DUMP_WED(WED_RTQM_DEQ_Q2I_DMAD_CNT),
++ DUMP_WED(WED_RTQM_DEQ_PKT_CNT),
++ DUMP_WED(WED_RTQM_DEQ_Q2I_PKT_CNT),
++ DUMP_WED(WED_RTQM_DEQ_USED_PFDBK_CNT),
++ DUMP_WED(WED_RTQM_DEQ_ERR_CNT),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs_new_v2[] = {
++ ®s_common[0],
++ ®s_v2[0],
++ NULL,
++ };
++
++ static const struct reg_dump *regs_new_v3[] = {
++ ®s_common[0],
++ ®s_v3[0],
++ NULL,
+ };
+
+ struct mtk_wed_hw *hw = s->private;
+ struct mtk_wed_device *dev = hw->wed_dev;
++ const struct reg_dump **regs;
+
+ if (!dev)
+ return 0;
+
+- dump_wed_regs(s, dev, regs, ARRAY_SIZE(regs));
++ switch(dev->hw->version) {
++ case 2:
++ regs = regs_new_v2;
++ break;
++ case 3:
++ regs = regs_new_v3;
++ break;
++ default:
++ return 0;
++ }
++
++ dump_wed_regs(s, dev, regs);
+
+ return 0;
+ }
+@@ -248,6 +357,383 @@ mtk_wed_reg_get(void *data, u64 *val)
+ DEFINE_DEBUGFS_ATTRIBUTE(fops_regval, mtk_wed_reg_get, mtk_wed_reg_set,
+ "0x%08llx\n");
+
++static int
++wed_token_txd_show(struct seq_file *s, void *data)
++{
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++ struct dma_page_info *page_list = dev->tx_buf_ring.pages;
++ int token = dev->wlan.token_start;
++ u32 val = hw->token_id, size = 1;
++ int page_idx = (val - token) / 2;
++ int i;
++
++ if (val < token) {
++ size = val;
++ page_idx = 0;
++ }
++
++ for (i = 0; i < size; i += MTK_WED_BUF_PER_PAGE) {
++ void *page = page_list[page_idx++].addr;
++ void *buf;
++ int j;
++
++ if (!page)
++ break;
++
++ buf = page_to_virt(page);
++
++ for (j = 0; j < MTK_WED_BUF_PER_PAGE; j++) {
++ printk("[TXD]:token id = %d\n", token + 2 * (page_idx - 1) + j);
++ print_hex_dump(KERN_ERR , "", DUMP_PREFIX_OFFSET, 16, 1, (u8 *)buf, 128, false);
++ seq_printf(s, "\n");
++
++ buf += MTK_WED_BUF_SIZE;
++ }
++ }
++
++ return 0;
++}
++
++DEFINE_SHOW_ATTRIBUTE(wed_token_txd);
++
++static int
++wed_pao_show(struct seq_file *s, void *data)
++{
++ static const struct reg_dump regs_common[] = {
++ DUMP_STR("PAO AMDSU INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_FIFO_DMAD),
++
++ DUMP_STR("PAO AMDSU ENG0 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(0)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(0)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(0)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(0)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(0)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(0),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(0),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(0),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(0),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(0),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG1 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(1)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(1)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(1)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(1)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(1)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(1),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(1),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(1),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG2 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(2)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(2)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(2)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(2)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(2)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(2),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(2),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(2),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG3 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(3)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(3)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(3)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(3)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(3)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(3),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(3),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(3),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(3),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(3),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG4 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(4)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(4)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(4)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(4)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(4)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(4),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(4),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG5 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(5)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(5)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(5)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(5)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(5)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(5),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(5),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(5),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(5),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(5),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG6 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(6)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(6)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(6)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(6)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(6)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(6),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(6),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(6),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(6),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(6),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG7 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(7)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(7)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(7)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(7)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(7)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(7),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(7),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(7),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(7),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(4),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO AMDSU ENG8 INFO"),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_DMAD(8)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QFPL(8)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENI(8)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_QENO(8)),
++ DUMP_WED(WED_PAO_MON_AMSDU_ENG_MERG(8)),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(8),
++ WED_PAO_AMSDU_ENG_MAX_PL_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT8(8),
++ WED_PAO_AMSDU_ENG_MAX_QGPP_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(8),
++ WED_PAO_AMSDU_ENG_CUR_ENTRY),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(8),
++ WED_PAO_AMSDU_ENG_MAX_BUF_MERGED),
++ DUMP_WED_MASK(WED_PAO_MON_AMSDU_ENG_CNT9(8),
++ WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED),
++
++ DUMP_STR("PAO QMEM INFO"),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(0), WED_PAO_QMEM_FQ_CNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(0), WED_PAO_QMEM_SP_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(1), WED_PAO_QMEM_TID0_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(1), WED_PAO_QMEM_TID1_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(2), WED_PAO_QMEM_TID2_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(2), WED_PAO_QMEM_TID3_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(3), WED_PAO_QMEM_TID4_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(3), WED_PAO_QMEM_TID5_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(4), WED_PAO_QMEM_TID6_QCNT),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_CNT(4), WED_PAO_QMEM_TID7_QCNT),
++
++
++ DUMP_STR("PAO QMEM HEAD INFO"),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(0), WED_PAO_QMEM_FQ_HEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(0), WED_PAO_QMEM_SP_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(1), WED_PAO_QMEM_TID0_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(1), WED_PAO_QMEM_TID1_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(2), WED_PAO_QMEM_TID2_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(2), WED_PAO_QMEM_TID3_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(3), WED_PAO_QMEM_TID4_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(3), WED_PAO_QMEM_TID5_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(4), WED_PAO_QMEM_TID6_QHEAD),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(4), WED_PAO_QMEM_TID7_QHEAD),
++
++ DUMP_STR("PAO QMEM TAIL INFO"),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(5), WED_PAO_QMEM_FQ_TAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(5), WED_PAO_QMEM_SP_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(6), WED_PAO_QMEM_TID0_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(6), WED_PAO_QMEM_TID1_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(7), WED_PAO_QMEM_TID2_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(7), WED_PAO_QMEM_TID3_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(8), WED_PAO_QMEM_TID4_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(8), WED_PAO_QMEM_TID5_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(9), WED_PAO_QMEM_TID6_QTAIL),
++ DUMP_WED_MASK(WED_PAO_MON_QMEM_PTR(9), WED_PAO_QMEM_TID7_QTAIL),
++
++ DUMP_STR("PAO HIFTXD MSDU INFO"),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(1)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(2)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(3)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(4)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(5)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(6)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(7)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(8)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(9)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(10)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(11)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(12)),
++ DUMP_WED(WED_PAO_MON_HIFTXD_FETCH_MSDU(13)),
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
++ };
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++
++ if (!dev)
++ return 0;
++
++ dump_wed_regs(s, dev, regs);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_pao);
++
++static int
++wed_rtqm_show(struct seq_file *s, void *data)
++{
++ static const struct reg_dump regs_common[] = {
++ DUMP_STR("WED Route QM IGRS0(N2H + Recycle)"),
++ DUMP_WED(WED_RTQM_IGRS0_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS0_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS0_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS0_FDROP_CNT),
++
++
++ DUMP_STR("WED Route QM IGRS1(Legacy)"),
++ DUMP_WED(WED_RTQM_IGRS1_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS1_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS1_I2H_PKT_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS1_FDROP_CNT),
++
++ DUMP_STR("WED Route QM IGRS2(RRO3.0)"),
++ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS2_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS2_I2H_PKT_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS2_FDROP_CNT),
++
++ DUMP_STR("WED Route QM IGRS3(DEBUG)"),
++ DUMP_WED(WED_RTQM_IGRS2_I2HW_DMAD_CNT),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_DMAD_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS3_I2HW_PKT_CNT),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(0)),
++ DUMP_WED(WED_RTQM_IGRS3_I2H_PKT_CNT(1)),
++ DUMP_WED(WED_RTQM_IGRS3_FDROP_CNT),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
++ };
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++
++ if (!dev)
++ return 0;
++
++ dump_wed_regs(s, dev, regs);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_rtqm);
++
++
++static int
++wed_rro_show(struct seq_file *s, void *data)
++{
++ static const struct reg_dump regs_common[] = {
++ DUMP_STR("RRO/IND CMD CNT"),
++ DUMP_WED(WED_RX_IND_CMD_CNT(1)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(2)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(3)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(4)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(5)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(6)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(7)),
++ DUMP_WED(WED_RX_IND_CMD_CNT(8)),
++ DUMP_WED_MASK(WED_RX_IND_CMD_CNT(9),
++ WED_IND_CMD_MAGIC_CNT_FAIL_CNT),
++
++ DUMP_WED(WED_RX_ADDR_ELEM_CNT(0)),
++ DUMP_WED_MASK(WED_RX_ADDR_ELEM_CNT(1),
++ WED_ADDR_ELEM_SIG_FAIL_CNT),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(1)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(2)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(3)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(4)),
++ DUMP_WED(WED_RX_MSDU_PG_CNT(5)),
++ DUMP_WED_MASK(WED_RX_PN_CHK_CNT,
++ WED_PN_CHK_FAIL_CNT),
++
++ DUMP_END()
++ };
++
++ static const struct reg_dump *regs[] = {
++ ®s_common[0],
++ NULL,
++ };
++ struct mtk_wed_hw *hw = s->private;
++ struct mtk_wed_device *dev = hw->wed_dev;
++
++ if (!dev)
++ return 0;
++
++ dump_wed_regs(s, dev, regs);
++
++ return 0;
++}
++DEFINE_SHOW_ATTRIBUTE(wed_rro);
++
+ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
+ {
+ struct dentry *dir;
+@@ -261,8 +747,18 @@ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
+ debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
+ debugfs_create_file_unsafe("regval", 0600, dir, hw, &fops_regval);
+ debugfs_create_file_unsafe("txinfo", 0400, dir, hw, &wed_txinfo_fops);
+- debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
+- if (hw->ver != MTK_WED_V1) {
++ debugfs_create_u32("token_id", 0600, dir, &hw->token_id);
++ debugfs_create_file_unsafe("token_txd", 0600, dir, hw, &wed_token_txd_fops);
++
++ if (hw->version == 3)
++ debugfs_create_file_unsafe("pao", 0400, dir, hw, &wed_pao_fops);
++
++ if (hw->version != 1) {
++ debugfs_create_file_unsafe("rxinfo", 0400, dir, hw, &wed_rxinfo_fops);
++ if (hw->version == 3) {
++ debugfs_create_file_unsafe("rtqm", 0400, dir, hw, &wed_rtqm_fops);
++ debugfs_create_file_unsafe("rro", 0400, dir, hw, &wed_rro_fops);
++ }
+ wed_wo_mcu_debugfs(hw, dir);
+ }
+ }
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+index 96e30a3..055594d 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -242,7 +242,7 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+ u32 ofs = 0;
+ u32 boot_cr, val;
+
+- mcu = wo->hw->index ? MT7986_FIRMWARE_WO_2 : MT7986_FIRMWARE_WO_1;
++ mcu = wo->hw->index ? MTK_FIRMWARE_WO_1 : MTK_FIRMWARE_WO_0;
+
+ ret = request_firmware(&fw, mcu, wo->hw->dev);
+ if (ret)
+@@ -289,8 +289,12 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+ }
+
+ /* write the start address */
+- boot_cr = wo->hw->index ?
+- WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR : WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
++ if (wo->hw->version == 3)
++ boot_cr = WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
++ else
++ boot_cr = wo->hw->index ?
++ WOX_MCU_CFG_LS_WA_BOOT_ADDR_ADDR : WOX_MCU_CFG_LS_WM_BOOT_ADDR_ADDR;
++
+ wo_w32(wo, boot_cr, (wo->region[WO_REGION_EMI].addr_pa >> 16));
+
+ /* wo firmware reset */
+@@ -298,8 +302,7 @@ mtk_wed_load_firmware(struct mtk_wed_wo *wo)
+
+ val = wo_r32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR);
+
+- val |= wo->hw->index ? WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WA_CPU_RSTB_MASK :
+- WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
++ val |= WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_WM_CPU_RSTB_MASK;
+
+ wo_w32(wo, WOX_MCU_CFG_LS_WF_MCU_CFG_WM_WA_ADDR, val);
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
+index 19e1199..c07bdb6 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.h
+@@ -16,8 +16,9 @@
+ #define WARP_OK_STATUS (0)
+ #define WARP_ALREADY_DONE_STATUS (1)
+
+-#define MT7986_FIRMWARE_WO_1 "mediatek/mt7986_wo_0.bin"
+-#define MT7986_FIRMWARE_WO_2 "mediatek/mt7986_wo_1.bin"
++#define MTK_FIRMWARE_WO_0 "mediatek/mtk_wo_0.bin"
++#define MTK_FIRMWARE_WO_1 "mediatek/mtk_wo_1.bin"
++#define MTK_FIRMWARE_WO_2 "mediatek/mtk_wo_2.bin"
+
+ #define WOCPU_EMI_DEV_NODE "mediatek,wocpu_emi"
+ #define WOCPU_ILM_DEV_NODE "mediatek,wocpu_ilm"
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+index 403a36b..4e619ff 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+@@ -20,6 +20,9 @@
+ #define MTK_WDMA_DESC_CTRL_DMA_DONE BIT(31)
+ #define MTK_WED_RX_BM_TOKEN GENMASK(31, 16)
+
++#define MTK_WDMA_TXD0_DESC_INFO_DMA_DONE BIT(29)
++#define MTK_WDMA_TXD1_DESC_INFO_DMA_DONE BIT(31)
++
+ struct mtk_wdma_desc {
+ __le32 buf0;
+ __le32 ctrl;
+@@ -51,6 +54,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RESET_WDMA_INT_AGENT BIT(19)
+ #define MTK_WED_RESET_RX_RRO_QM BIT(20)
+ #define MTK_WED_RESET_RX_ROUTE_QM BIT(21)
++#define MTK_WED_RESET_TX_PAO BIT(22)
+ #define MTK_WED_RESET_WED BIT(31)
+
+ #define MTK_WED_CTRL 0x00c
+@@ -58,6 +62,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_WPDMA_INT_AGENT_BUSY BIT(1)
+ #define MTK_WED_CTRL_WDMA_INT_AGENT_EN BIT(2)
+ #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
++#define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
++#define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
++#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7)
+ #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
+ #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
+ #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
+@@ -68,9 +75,14 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_RX_RRO_QM_BUSY BIT(15)
+ #define MTK_WED_CTRL_RX_ROUTE_QM_EN BIT(16)
+ #define MTK_WED_CTRL_RX_ROUTE_QM_BUSY BIT(17)
++#define MTK_WED_CTRL_TX_TKID_ALI_EN BIT(20)
++#define MTK_WED_CTRL_TX_TKID_ALI_BUSY BIT(21)
++#define MTK_WED_CTRL_TX_PAO_EN BIT(22)
++#define MTK_WED_CTRL_TX_PAO_BUSY BIT(23)
+ #define MTK_WED_CTRL_FINAL_DIDX_READ BIT(24)
+ #define MTK_WED_CTRL_ETH_DMAD_FMT BIT(25)
+ #define MTK_WED_CTRL_MIB_READ_CLEAR BIT(28)
++#define MTK_WED_CTRL_FLD_MIB_RD_CLR BIT(28)
+
+ #define MTK_WED_EXT_INT_STATUS 0x020
+ #define MTK_WED_EXT_INT_STATUS_TF_LEN_ERR BIT(0)
+@@ -78,12 +90,10 @@ struct mtk_wdma_desc {
+ #define MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID BIT(4)
+ #define MTK_WED_EXT_INT_STATUS_TX_FBUF_LO_TH BIT(8)
+ #define MTK_WED_EXT_INT_STATUS_TX_FBUF_HI_TH BIT(9)
+-#if defined(CONFIG_MEDIATEK_NETSYS_V2)
+-#define MTK_WED_EXT_INT_STATUS_TX_TKID_LO_TH BIT(10)
+-#define MTK_WED_EXT_INT_STATUS_TX_TKID_HI_TH BIT(11)
+-#endif
+-#define MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY BIT(12)
+-#define MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER BIT(13)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH2 BIT(10)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH2 BIT(11)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_LO_TH BIT(12)
++#define MTK_WED_EXT_INT_STATUS_RX_FBUF_HI_TH BIT(13)
+ #define MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR BIT(16)
+ #define MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR BIT(17)
+ #define MTK_WED_EXT_INT_STATUS_RX_DRV_COHERENT BIT(18)
+@@ -100,17 +110,15 @@ struct mtk_wdma_desc {
+ #define MTK_WED_EXT_INT_STATUS_ERROR_MASK (MTK_WED_EXT_INT_STATUS_TF_LEN_ERR | \
+ MTK_WED_EXT_INT_STATUS_TKID_WO_PYLD | \
+ MTK_WED_EXT_INT_STATUS_TKID_TITO_INVALID | \
+- MTK_WED_EXT_INT_STATUS_RX_FREE_AT_EMPTY | \
+- MTK_WED_EXT_INT_STATUS_RX_FBUF_DMAD_ER | \
+ MTK_WED_EXT_INT_STATUS_RX_DRV_R_RESP_ERR | \
+ MTK_WED_EXT_INT_STATUS_RX_DRV_W_RESP_ERR | \
+ MTK_WED_EXT_INT_STATUS_RX_DRV_INIT_WDMA_EN | \
+- MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR | \
+- MTK_WED_EXT_INT_STATUS_TX_DMA_W_RESP_ERR)
++ MTK_WED_EXT_INT_STATUS_TX_DMA_R_RESP_ERR)
+
+ #define MTK_WED_EXT_INT_MASK 0x028
+ #define MTK_WED_EXT_INT_MASK1 0x02c
+ #define MTK_WED_EXT_INT_MASK2 0x030
++#define MTK_WED_EXT_INT_MASK3 0x034
+
+ #define MTK_WED_STATUS 0x060
+ #define MTK_WED_STATUS_TX GENMASK(15, 8)
+@@ -118,9 +126,14 @@ struct mtk_wdma_desc {
+ #define MTK_WED_TX_BM_CTRL 0x080
+ #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
+ #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
++#define MTK_WED_TX_BM_CTRL_LEGACY_EN BIT(26)
++#define MTK_WED_TX_TKID_CTRL_FREE_FORMAT BIT(27)
+ #define MTK_WED_TX_BM_CTRL_PAUSE BIT(28)
+
+ #define MTK_WED_TX_BM_BASE 0x084
++#define MTK_WED_TX_BM_INIT_PTR 0x088
++#define MTK_WED_TX_BM_SW_TAIL_IDX GENMASK(16, 0)
++#define MTK_WED_TX_BM_INIT_SW_TAIL_IDX BIT(16)
+
+ #define MTK_WED_TX_BM_BUF_LEN 0x08c
+
+@@ -134,22 +147,24 @@ struct mtk_wdma_desc {
+ #if defined(CONFIG_MEDIATEK_NETSYS_V2)
+ #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(8, 0)
+ #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(24, 16)
+-
+-#define MTK_WED_TX_BM_TKID 0x0c8
+-#define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
+-#define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
+ #else
+ #define MTK_WED_TX_BM_DYN_THR_LO GENMASK(6, 0)
+ #define MTK_WED_TX_BM_DYN_THR_HI GENMASK(22, 16)
++#endif
+
+-#define MTK_WED_TX_BM_TKID 0x088
++#define MTK_WED_TX_BM_TKID 0x0c8
+ #define MTK_WED_TX_BM_TKID_START GENMASK(15, 0)
+ #define MTK_WED_TX_BM_TKID_END GENMASK(31, 16)
+-#endif
+
+ #define MTK_WED_TX_TKID_CTRL 0x0c0
++#if defined(CONFIG_MEDIATEK_NETSYS_V3)
++#define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(7, 0)
++#define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(23, 16)
++#else
+ #define MTK_WED_TX_TKID_CTRL_VLD_GRP_NUM GENMASK(6, 0)
+ #define MTK_WED_TX_TKID_CTRL_RSV_GRP_NUM GENMASK(22, 16)
++#endif
++
+ #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
+
+ #define MTK_WED_TX_TKID_DYN_THR 0x0e0
+@@ -220,12 +235,15 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_PKT_PROC BIT(5)
+ #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R0_CRX_SYNC BIT(6)
+ #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_R1_CRX_SYNC BIT(7)
+-#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(18, 16)
++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_VER GENMASK(15, 12)
++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4 BIT(18)
+ #define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNSUPPORT_FMT BIT(19)
+-#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_UEVENT_PKT_FMT_CHK BIT(20)
++#define MTK_WED_WPDMA_GLO_CFG_RX_DRV_EVENT_PKT_FMT_CHK BIT(20)
+ #define MTK_WED_WPDMA_GLO_CFG_RX_DDONE2_WR BIT(21)
+ #define MTK_WED_WPDMA_GLO_CFG_TX_TKID_KEEP BIT(24)
++#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST BIT(25)
+ #define MTK_WED_WPDMA_GLO_CFG_TX_DMAD_DW3_PREV BIT(28)
++#define MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK BIT(30)
+
+ /* CONFIG_MEDIATEK_NETSYS_V1 */
+ #define MTK_WED_WPDMA_GLO_CFG_RX_BT_SIZE GENMASK(5, 4)
+@@ -288,9 +306,11 @@ struct mtk_wdma_desc {
+ #define MTK_WED_PCIE_INT_TRIGGER_STATUS BIT(16)
+
+ #define MTK_WED_PCIE_INT_CTRL 0x57c
+-#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
+-#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
+ #define MTK_WED_PCIE_INT_CTRL_POLL_EN GENMASK(13, 12)
++#define MTK_WED_PCIE_INT_CTRL_SRC_SEL GENMASK(17, 16)
++#define MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA BIT(20)
++#define MTK_WED_PCIE_INT_CTRL_MSK_IRQ_FILTER BIT(21)
++
+ #define MTK_WED_WPDMA_CFG_BASE 0x580
+ #define MTK_WED_WPDMA_CFG_INT_MASK 0x584
+ #define MTK_WED_WPDMA_CFG_TX 0x588
+@@ -319,20 +339,50 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
+
+ #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
+-#define MTK_WED_WPDMA_RX_RING 0x770
++#if defined(CONFIG_MEDIATEK_NETSYS_V2)
++#define MTK_WED_WPDMA_RX_RING0 0x770
++#else
++#define MTK_WED_WPDMA_RX_RING0 0x7d0
++#endif
++#define MTK_WED_WPDMA_RX_RING1 0x7d8
+
+ #define MTK_WED_WPDMA_RX_D_MIB(_n) (0x774 + (_n) * 4)
+ #define MTK_WED_WPDMA_RX_D_PROCESSED_MIB(_n) (0x784 + (_n) * 4)
+ #define MTK_WED_WPDMA_RX_D_COHERENT_MIB 0x78c
+
++#define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
++#define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
++#define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
++#define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
++
++#define MTK_WED_WPDMA_RX_D_PREF_RX0_SIDX 0x7b8
++#define MTK_WED_WPDMA_RX_D_PREF_SIDX_IDX_CLR BIT(15)
++
++#define MTK_WED_WPDMA_RX_D_PREF_RX1_SIDX 0x7bc
++
++#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG 0x7c0
++#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R0_CLR BIT(0)
++#define MTK_WED_WPDMA_RX_D_PREF_FIFO_CFG_R1_CLR BIT(16)
++
+ #define MTK_WED_WDMA_RING_TX 0x800
+
+ #define MTK_WED_WDMA_TX_MIB 0x810
+
+-
+ #define MTK_WED_WDMA_RING_RX(_n) (0x900 + (_n) * 0x10)
+ #define MTK_WED_WDMA_RX_THRES(_n) (0x940 + (_n) * 0x4)
+
++#define MTK_WED_WDMA_RX_PREF_CFG 0x950
++#define MTK_WED_WDMA_RX_PREF_EN BIT(0)
++#define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
++#define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
++#define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
++#define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
++#define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
++
++#define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
++#define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
++#define MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR BIT(16)
++
+ #define MTK_WED_WDMA_GLO_CFG 0xa04
+ #define MTK_WED_WDMA_GLO_CFG_TX_DRV_EN BIT(0)
+ #define MTK_WED_WDMA_GLO_CFG_TX_DDONE_CHK BIT(1)
+@@ -365,6 +415,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WDMA_INT_TRIGGER_RX_DONE GENMASK(17, 16)
+
+ #define MTK_WED_WDMA_INT_CTRL 0xa2c
++#define MTK_WED_WDMA_INT_POLL_PRD GENMASK(7, 0)
+ #define MTK_WED_WDMA_INT_POLL_SRC_SEL GENMASK(17, 16)
+
+ #define MTK_WED_WDMA_CFG_BASE 0xaa0
+@@ -426,6 +477,18 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_INT_GRP1 0x250
+ #define MTK_WDMA_INT_GRP2 0x254
+
++#define MTK_WDMA_PREF_TX_CFG 0x2d0
++#define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
++
++#define MTK_WDMA_PREF_RX_CFG 0x2dc
++#define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
++
++#define MTK_WDMA_WRBK_TX_CFG 0x300
++#define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
++
++#define MTK_WDMA_WRBK_RX_CFG 0x344
++#define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
++
+ #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
+ #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
+ #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
+@@ -439,6 +502,31 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
+ #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
+
++#define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
++#define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
++#define MTK_WED_RTQM_IGRS0_I2H_PKT_CNT(_n) (0xb2c + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS0_FDROP_CNT 0xb34
++
++
++#define MTK_WED_RTQM_IGRS1_I2HW_DMAD_CNT 0xb44
++#define MTK_WED_RTQM_IGRS1_I2H_DMAD_CNT(_n) (0xb48 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS1_I2HW_PKT_CNT 0xb50
++#define MTK_WED_RTQM_IGRS1_I2H_PKT_CNT(_n) (0xb54+ (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS1_FDROP_CNT 0xb5c
++
++#define MTK_WED_RTQM_IGRS2_I2HW_DMAD_CNT 0xb6c
++#define MTK_WED_RTQM_IGRS2_I2H_DMAD_CNT(_n) (0xb70 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS2_I2HW_PKT_CNT 0xb78
++#define MTK_WED_RTQM_IGRS2_I2H_PKT_CNT(_n) (0xb7c+ (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS2_FDROP_CNT 0xb84
++
++#define MTK_WED_RTQM_IGRS3_I2HW_DMAD_CNT 0xb94
++#define MTK_WED_RTQM_IGRS3_I2H_DMAD_CNT(_n) (0xb98 + (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS3_I2HW_PKT_CNT 0xba0
++#define MTK_WED_RTQM_IGRS3_I2H_PKT_CNT(_n) (0xba4+ (_n) * 0x4)
++#define MTK_WED_RTQM_IGRS3_FDROP_CNT 0xbac
++
+ #define MTK_WED_RTQM_R2H_MIB(_n) (0xb70 + (_n) * 0x4)
+ #define MTK_WED_RTQM_R2Q_MIB(_n) (0xb78 + (_n) * 0x4)
+ #define MTK_WED_RTQM_Q2N_MIB 0xb80
+@@ -447,6 +535,24 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RTQM_Q2B_MIB 0xb8c
+ #define MTK_WED_RTQM_PFDBK_MIB 0xb90
+
++#define MTK_WED_RTQM_ENQ_CFG0 0xbb8
++#define MTK_WED_RTQM_ENQ_CFG_TXDMAD_FPORT GENMASK(15, 12)
++
++#define MTK_WED_RTQM_FDROP_MIB 0xb84
++#define MTK_WED_RTQM_ENQ_I2Q_DMAD_CNT 0xbbc
++#define MTK_WED_RTQM_ENQ_I2N_DMAD_CNT 0xbc0
++#define MTK_WED_RTQM_ENQ_I2Q_PKT_CNT 0xbc4
++#define MTK_WED_RTQM_ENQ_I2N_PKT_CNT 0xbc8
++#define MTK_WED_RTQM_ENQ_USED_ENTRY_CNT 0xbcc
++#define MTK_WED_RTQM_ENQ_ERR_CNT 0xbd0
++
++#define MTK_WED_RTQM_DEQ_DMAD_CNT 0xbd8
++#define MTK_WED_RTQM_DEQ_Q2I_DMAD_CNT 0xbdc
++#define MTK_WED_RTQM_DEQ_PKT_CNT 0xbe0
++#define MTK_WED_RTQM_DEQ_Q2I_PKT_CNT 0xbe4
++#define MTK_WED_RTQM_DEQ_USED_PFDBK_CNT 0xbe8
++#define MTK_WED_RTQM_DEQ_ERR_CNT 0xbec
++
+ #define MTK_WED_RROQM_GLO_CFG 0xc04
+ #define MTK_WED_RROQM_RST_IDX 0xc08
+ #define MTK_WED_RROQM_RST_IDX_MIOD BIT(0)
+@@ -487,8 +593,8 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RX_BM_BASE 0xd84
+ #define MTK_WED_RX_BM_INIT_PTR 0xd88
+ #define MTK_WED_RX_BM_PTR 0xd8c
+-#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
+ #define MTK_WED_RX_BM_PTR_TAIL GENMASK(15, 0)
++#define MTK_WED_RX_BM_PTR_HEAD GENMASK(32, 16)
+
+ #define MTK_WED_RX_BM_BLEN 0xd90
+ #define MTK_WED_RX_BM_STS 0xd94
+@@ -496,7 +602,193 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RX_BM_INTF 0xd9c
+ #define MTK_WED_RX_BM_ERR_STS 0xda8
+
++#define MTK_RRO_IND_CMD_SIGNATURE 0xe00
++#define MTK_RRO_IND_CMD_DMA_IDX GENMASK(11, 0)
++#define MTK_RRO_IND_CMD_MAGIC_CNT GENMASK(30, 28)
++
++#define MTK_WED_IND_CMD_RX_CTRL0 0xe04
++#define MTK_WED_IND_CMD_PROC_IDX GENMASK(11, 0)
++#define MTK_WED_IND_CMD_PREFETCH_FREE_CNT GENMASK(19, 16)
++#define MTK_WED_IND_CMD_MAGIC_CNT GENMASK(30, 28)
++
++#define MTK_WED_IND_CMD_RX_CTRL1 0xe08
++#define MTK_WED_IND_CMD_RX_CTRL2 0xe0c
++#define MTK_WED_IND_CMD_MAX_CNT GENMASK(11, 0)
++#define MTK_WED_IND_CMD_BASE_M GENMASK(19, 16)
++
++#define MTK_WED_RRO_CFG0 0xe10
++#define MTK_WED_RRO_CFG1 0xe14
++#define MTK_WED_RRO_CFG1_MAX_WIN_SZ GENMASK(31, 29)
++#define MTK_WED_RRO_CFG1_ACK_SN_BASE_M GENMASK(19, 16)
++#define MTK_WED_RRO_CFG1_PARTICL_SE_ID GENMASK(11, 0)
++
++#define MTK_WED_ADDR_ELEM_CFG0 0xe18
++#define MTK_WED_ADDR_ELEM_CFG1 0xe1c
++#define MTK_WED_ADDR_ELEM_PREFETCH_FREE_CNT GENMASK(19, 16)
++
++#define MTK_WED_ADDR_ELEM_TBL_CFG 0xe20
++#define MTK_WED_ADDR_ELEM_TBL_OFFSET GENMASK(6, 0)
++#define MTK_WED_ADDR_ELEM_TBL_RD_RDY BIT(28)
++#define MTK_WED_ADDR_ELEM_TBL_WR_RDY BIT(29)
++#define MTK_WED_ADDR_ELEM_TBL_RD BIT(30)
++#define MTK_WED_ADDR_ELEM_TBL_WR BIT(31)
++
++#define MTK_WED_RADDR_ELEM_TBL_WDATA 0xe24
++#define MTK_WED_RADDR_ELEM_TBL_RDATA 0xe28
++
++#define MTK_WED_PN_CHECK_CFG 0xe30
++#define MTK_WED_PN_CHECK_SE_ID GENMASK(11, 0)
++#define MTK_WED_PN_CHECK_RD_RDY BIT(28)
++#define MTK_WED_PN_CHECK_WR_RDY BIT(29)
++#define MTK_WED_PN_CHECK_RD BIT(30)
++#define MTK_WED_PN_CHECK_WR BIT(31)
++
++#define MTK_WED_PN_CHECK_WDATA_M 0xe38
++#define MTK_WED_PN_CHECK_IS_FIRST BIT(17)
++
++#define MTK_WED_RRO_MSDU_PG_RING_CFG(_n) (0xe44 + (_n) * 0x8)
++
++#define MTK_WED_RRO_MSDU_PG_RING2_CFG 0xe58
++#define MTK_WED_RRO_MSDU_PG_DRV_CLR BIT(26)
++#define MTK_WED_RRO_MSDU_PG_DRV_EN BIT(31)
++
++#define MTK_WED_RRO_MSDU_PG_CTRL0(_n) (0xe5c + (_n) * 0xc)
++#define MTK_WED_RRO_MSDU_PG_CTRL1(_n) (0xe60 + (_n) * 0xc)
++#define MTK_WED_RRO_MSDU_PG_CTRL2(_n) (0xe64 + (_n) * 0xc)
++
++#define MTK_WED_RRO_RX_D_RX(_n) (0xe80 + (_n) * 0x10)
++
++#define MTK_WED_RRO_RX_MAGIC_CNT BIT(13)
++
++#define MTK_WED_RRO_RX_D_CFG(_n) (0xea0 + (_n) * 0x4)
++#define MTK_WED_RRO_RX_D_DRV_CLR BIT(26)
++#define MTK_WED_RRO_RX_D_DRV_EN BIT(31)
++
++#define MTK_WED_RRO_PG_BM_RX_DMAM 0xeb0
++#define MTK_WED_RRO_PG_BM_RX_SDL0 GENMASK(13, 0)
++
++#define MTK_WED_RRO_PG_BM_BASE 0xeb4
++#define MTK_WED_RRO_PG_BM_INIT_PTR 0xeb8
++#define MTK_WED_RRO_PG_BM_SW_TAIL_IDX GENMASK(15, 0)
++#define MTK_WED_RRO_PG_BM_INIT_SW_TAIL_IDX BIT(16)
++
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX 0xeec
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_EN BIT(0)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_CLR BIT(1)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX0_DONE_TRIG GENMASK(6, 2)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_EN BIT(8)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_CLR BIT(9)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_RX1_DONE_TRIG GENMASK(14, 10)
++
++#define MTK_WED_WPDMA_INT_CTRL_RRO_MSDU_PG 0xef4
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_EN BIT(0)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_CLR BIT(1)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG0_DONE_TRIG GENMASK(6, 2)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_EN BIT(8)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_CLR BIT(9)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG1_DONE_TRIG GENMASK(14, 10)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_EN BIT(16)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
++#define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
++
++#define MTK_WED_RX_IND_CMD_CNT0 0xf20
++#define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
++
++#define MTK_WED_RX_IND_CMD_CNT(_n) (0xf20 + (_n) * 0x4)
++#define MTK_WED_IND_CMD_MAGIC_CNT_FAIL_CNT GENMASK(15, 0)
++
++#define MTK_WED_RX_ADDR_ELEM_CNT(_n) (0xf48 + (_n) * 0x4)
++#define MTK_WED_ADDR_ELEM_SIG_FAIL_CNT GENMASK(15, 0)
++#define MTK_WED_ADDR_ELEM_FIRST_SIG_FAIL_CNT GENMASK(31, 16)
++#define MTK_WED_ADDR_ELEM_ACKSN_CNT GENMASK(27, 0)
++
++#define MTK_WED_RX_MSDU_PG_CNT(_n) (0xf5c + (_n) * 0x4)
++
++#define MTK_WED_RX_PN_CHK_CNT 0xf70
++#define MTK_WED_PN_CHK_FAIL_CNT GENMASK(15, 0)
++
+ #define MTK_WED_WOCPU_VIEW_MIOD_BASE 0x8000
+ #define MTK_WED_PCIE_INT_MASK 0x0
+
++#define MTK_WED_PAO_AMSDU_FIFO 0x1800
++#define MTK_WED_PAO_AMSDU_IS_PRIOR0_RING BIT(10)
++
++#define MTK_WED_PAO_STA_INFO 0x01810
++#define MTK_WED_PAO_STA_INFO_DO_INIT BIT(0)
++#define MTK_WED_PAO_STA_INFO_SET_INIT BIT(1)
++
++#define MTK_WED_PAO_STA_INFO_INIT 0x01814
++#define MTK_WED_PAO_STA_WTBL_HDRT_MODE BIT(0)
++#define MTK_WED_PAO_STA_RMVL BIT(1)
++#define MTK_WED_PAO_STA_MAX_AMSDU_LEN GENMASK(7, 2)
++#define MTK_WED_PAO_STA_MAX_AMSDU_NUM GENMASK(11, 8)
++
++#define MTK_WED_PAO_HIFTXD_BASE_L(_n) (0x1980 + (_n) * 0x4)
++
++#define MTK_WED_PAO_PSE 0x1910
++#define MTK_WED_PAO_PSE_RESET BIT(16)
++
++#define MTK_WED_PAO_HIFTXD_CFG 0x1968
++#define MTK_WED_PAO_HIFTXD_SRC GENMASK(16, 15)
++
++#define MTK_WED_PAO_MON_AMSDU_FIFO_DMAD 0x1a34
++
++#define MTK_WED_PAO_MON_AMSDU_ENG_DMAD(_n) (0x1a80 + (_n) * 0x50)
++#define MTK_WED_PAO_MON_AMSDU_ENG_QFPL(_n) (0x1a84 + (_n) * 0x50)
++#define MTK_WED_PAO_MON_AMSDU_ENG_QENI(_n) (0x1a88 + (_n) * 0x50)
++#define MTK_WED_PAO_MON_AMSDU_ENG_QENO(_n) (0x1a8c + (_n) * 0x50)
++#define MTK_WED_PAO_MON_AMSDU_ENG_MERG(_n) (0x1a90 + (_n) * 0x50)
++
++#define MTK_WED_PAO_MON_AMSDU_ENG_CNT8(_n) (0x1a94 + (_n) * 0x50)
++#define MTK_WED_PAO_AMSDU_ENG_MAX_QGPP_CNT GENMASK(10, 0)
++#define MTK_WED_PAO_AMSDU_ENG_MAX_PL_CNT GENMASK(27, 16)
++
++#define MTK_WED_PAO_MON_AMSDU_ENG_CNT9(_n) (0x1a98 + (_n) * 0x50)
++#define MTK_WED_PAO_AMSDU_ENG_CUR_ENTRY GENMASK(10, 0)
++#define MTK_WED_PAO_AMSDU_ENG_MAX_BUF_MERGED GENMASK(20, 16)
++#define MTK_WED_PAO_AMSDU_ENG_MAX_MSDU_MERGED GENMASK(28, 24)
++
++#define MTK_WED_PAO_MON_QMEM_STS1 0x1e04
++
++#define MTK_WED_PAO_MON_QMEM_CNT(_n) (0x1e0c + (_n) * 0x4)
++#define MTK_WED_PAO_QMEM_FQ_CNT GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_SP_QCNT GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID0_QCNT GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID1_QCNT GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID2_QCNT GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID3_QCNT GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID4_QCNT GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID5_QCNT GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID6_QCNT GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID7_QCNT GENMASK(11, 0)
++
++#define MTK_WED_PAO_MON_QMEM_PTR(_n) (0x1e20 + (_n) * 0x4)
++#define MTK_WED_PAO_QMEM_FQ_HEAD GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_SP_QHEAD GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID0_QHEAD GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID1_QHEAD GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID2_QHEAD GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID3_QHEAD GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID4_QHEAD GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID5_QHEAD GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID6_QHEAD GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID7_QHEAD GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_FQ_TAIL GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_SP_QTAIL GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID0_QTAIL GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID1_QTAIL GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID2_QTAIL GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID3_QTAIL GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID4_QTAIL GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID5_QTAIL GENMASK(11, 0)
++#define MTK_WED_PAO_QMEM_TID6_QTAIL GENMASK(27, 16)
++#define MTK_WED_PAO_QMEM_TID7_QTAIL GENMASK(11, 0)
++
++#define MTK_WED_PAO_MON_HIFTXD_FETCH_MSDU(_n) (0x1ec4 + (_n) * 0x4)
++
++#define MTK_WED_PCIE_BASE 0x11280000
++
++#define MTK_WED_PCIE_BASE0 0x11300000
++#define MTK_WED_PCIE_BASE1 0x11310000
++#define MTK_WED_PCIE_BASE2 0x11290000
+ #endif
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 58b5ce6..5e51790 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -873,6 +873,13 @@ struct net_device_path {
+ u8 queue;
+ u16 wcid;
+ u8 bss;
++ u32 usr_info;
++ u8 tid;
++ u8 is_fixedrate;
++ u8 is_prior;
++ u8 is_sp;
++ u8 hf;
++ u8 amsdu_en;
+ } mtk_wdma;
+ };
+ };
+diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
+index 27cf284..60336e0 100644
+--- a/include/linux/soc/mediatek/mtk_wed.h
++++ b/include/linux/soc/mediatek/mtk_wed.h
+@@ -5,11 +5,14 @@
+ #include <linux/rcupdate.h>
+ #include <linux/regmap.h>
+ #include <linux/pci.h>
++#include <linux/skbuff.h>
++#include <linux/iopoll.h>
+
+ #define WED_WO_STA_REC 0x6
+
+ #define MTK_WED_TX_QUEUES 2
+ #define MTK_WED_RX_QUEUES 2
++#define MTK_WED_RX_PAGE_QUEUES 3
+
+ enum mtk_wed_wo_cmd {
+ MTK_WED_WO_CMD_WED_CFG,
+@@ -55,10 +58,13 @@ enum mtk_wed_bus_tye {
+ struct mtk_wed_hw;
+ struct mtk_wdma_desc;
+
++#define MTK_WED_RING_CONFIGURED BIT(0)
++
+ struct mtk_wed_ring {
+ struct mtk_wdma_desc *desc;
+ dma_addr_t desc_phys;
+ int size;
++ u32 flags;
+
+ u32 reg_base;
+ void __iomem *wpdma;
+@@ -69,11 +75,18 @@ struct mtk_rxbm_desc {
+ __le32 token;
+ } __packed __aligned(4);
+
++struct dma_page_info {
++ void *addr;
++ dma_addr_t addr_phys;
++};
++
+ struct dma_buf {
+ int size;
+- void **pages;
+- struct mtk_wdma_desc *desc;
++ int pkt_nums;
++ void *desc;
++ int desc_size;
+ dma_addr_t desc_phys;
++ struct dma_page_info *pages;
+ };
+
+ struct dma_entry {
+@@ -97,6 +110,7 @@ struct mtk_wed_device {
+ struct device *dev;
+ struct mtk_wed_hw *hw;
+ bool init_done, running;
++ bool wdma_init_done;
+ int wdma_idx;
+ int irq;
+ u8 ver;
+@@ -108,7 +122,11 @@ struct mtk_wed_device {
+ struct mtk_wed_ring rx_ring[MTK_WED_RX_QUEUES];
+ struct mtk_wed_ring rx_wdma[MTK_WED_RX_QUEUES];
+
+- struct dma_buf buf_ring;
++ struct mtk_wed_ring rx_rro_ring[MTK_WED_RX_QUEUES];
++ struct mtk_wed_ring rx_page_ring[MTK_WED_RX_PAGE_QUEUES];
++ struct mtk_wed_ring ind_cmd_ring;
++
++ struct dma_buf tx_buf_ring;
+
+ struct {
+ int size;
+@@ -117,6 +135,8 @@ struct mtk_wed_device {
+ dma_addr_t desc_phys;
+ } rx_buf_ring;
+
++ struct dma_buf rx_page_buf_ring;
++
+ struct {
+ struct mtk_wed_ring rro_ring;
+ void __iomem *rro_desc;
+@@ -131,8 +151,9 @@ struct mtk_wed_device {
+ struct platform_device *platform_dev;
+ struct pci_dev *pci_dev;
+ };
++ enum mtk_wed_bus_tye bus_type;
+ void __iomem *base;
+- u32 bus_type;
++ void __iomem *regs;
+ u32 phy_base;
+
+ u32 wpdma_phys;
+@@ -142,9 +163,13 @@ struct mtk_wed_device {
+ u32 wpdma_txfree;
+ u32 wpdma_rx_glo;
+ u32 wpdma_rx;
++ u32 wpdma_rx_rro[MTK_WED_RX_QUEUES];
++ u32 wpdma_rx_pg;
+
+ u8 tx_tbit[MTK_WED_TX_QUEUES];
+ u8 rx_tbit[MTK_WED_RX_QUEUES];
++ u8 rro_rx_tbit[MTK_WED_RX_QUEUES];
++ u8 rx_pg_tbit[MTK_WED_RX_PAGE_QUEUES];
+ u8 txfree_tbit;
+
+ u16 token_start;
+@@ -154,12 +179,26 @@ struct mtk_wed_device {
+ unsigned int rx_size;
+
+ bool wcid_512;
+-
++ bool hwrro;
++ bool msi;
++
++ u8 max_amsdu_nums;
++ u32 max_amsdu_len;
++
++ struct {
++ u8 se_group_nums;
++ u16 win_size;
++ u16 particular_sid;
++ u32 ack_sn_addr;
++ dma_addr_t particular_se_phys;
++ dma_addr_t addr_elem_phys[1024];
++ } ind_cmd;
++
++ u32 chip_id;
+ u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
+ int (*offload_enable)(struct mtk_wed_device *wed);
+ void (*offload_disable)(struct mtk_wed_device *wed);
+- u32 (*init_rx_buf)(struct mtk_wed_device *wed,
+- int pkt_num);
++ u32 (*init_rx_buf)(struct mtk_wed_device *wed, int size);
+ void (*release_rx_buf)(struct mtk_wed_device *wed);
+ void (*update_wo_rx_stats)(struct mtk_wed_device *wed,
+ struct mtk_wed_wo_rx_stats *stats);
+@@ -180,6 +219,11 @@ struct mtk_wed_ops {
+ void __iomem *regs);
+ int (*rx_ring_setup)(struct mtk_wed_device *dev, int ring,
+ void __iomem *regs, bool reset);
++ int (*rro_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
++ void __iomem *regs);
++ int (*msdu_pg_rx_ring_setup)(struct mtk_wed_device *dev, int ring,
++ void __iomem *regs);
++ int (*ind_rx_ring_setup)(struct mtk_wed_device *dev, void __iomem *regs);
+ int (*msg_update)(struct mtk_wed_device *dev, int cmd_id,
+ void *data, int len);
+ void (*detach)(struct mtk_wed_device *dev);
+@@ -196,6 +240,7 @@ struct mtk_wed_ops {
+ void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
+ u32 reason, u32 hash);
++ void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask);
+ };
+
+ extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
+@@ -224,12 +269,21 @@ static inline bool
+ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+ {
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
++ if (dev->ver == 3 && !dev->wlan.hwrro)
++ return false;
++
+ return dev->ver != 1;
+ #else
+ return false;
+ #endif
+ }
+
++static inline bool
++mtk_wed_device_support_pao(struct mtk_wed_device *dev)
++{
++ return dev->ver == 3;
++}
++
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ #define mtk_wed_device_active(_dev) !!(_dev)->ops
+ #define mtk_wed_device_detach(_dev) (_dev)->ops->detach(_dev)
+@@ -243,6 +297,12 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+ (_dev)->ops->txfree_ring_setup(_dev, _regs)
+ #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) \
+ (_dev)->ops->rx_ring_setup(_dev, _ring, _regs, _reset)
++#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) \
++ (_dev)->ops->rro_rx_ring_setup(_dev, _ring, _regs)
++#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) \
++ (_dev)->ops->msdu_pg_rx_ring_setup(_dev, _ring, _regs)
++#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) \
++ (_dev)->ops->ind_rx_ring_setup(_dev, _regs)
+ #define mtk_wed_device_update_msg(_dev, _id, _msg, _len) \
+ (_dev)->ops->msg_update(_dev, _id, _msg, _len)
+ #define mtk_wed_device_reg_read(_dev, _reg) \
+@@ -257,6 +317,9 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev)
+ (_dev)->ops->reset_dma(_dev)
+ #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
++#define mtk_wed_device_start_hwrro(_dev, _mask) \
++ (_dev)->ops->start_hwrro(_dev, _mask)
++
+ #else
+ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ {
+@@ -268,6 +331,9 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ #define mtk_wed_device_tx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
+ #define mtk_wed_device_txfree_ring_setup(_dev, _ring, _regs) -ENODEV
+ #define mtk_wed_device_rx_ring_setup(_dev, _ring, _regs, _reset) -ENODEV
++#define mtk_wed_device_rro_rx_ring_setup(_dev, _ring, _regs) -ENODEV
++#define mtk_wed_device_msdu_pg_rx_ring_setup(_dev, _ring, _regs) -ENODEV
++#define mtk_wed_device_ind_rx_ring_setup(_dev, _regs) -ENODEV
+ #define mtk_wed_device_reg_read(_dev, _reg) 0
+ #define mtk_wed_device_reg_write(_dev, _reg, _val) do {} while (0)
+ #define mtk_wed_device_irq_get(_dev, _mask) 0
+@@ -275,6 +341,7 @@ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+ #define mtk_wed_device_dma_reset(_dev) do {} while (0)
+ #define mtk_wed_device_setup_tc(_dev, _ndev, _type, _data) do {} while (0)
+ #define mtk_wed_device_ppe_check(_dev, _hash) do {} while (0)
++#define mtk_wed_device_start_hwrro(_dev, _mask) do {} while (0)
+ #endif
+
+ #endif
+--
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3022-mtk-wed-add-wed3-ser-support.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3022-mtk-wed-add-wed3-ser-support.patch
new file mode 100644
index 0000000..3837d8d
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/wed3/999-3022-mtk-wed-add-wed3-ser-support.patch
@@ -0,0 +1,611 @@
+From 7304ce8edabcbc34433307b02de429c2d118abaa Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Tue, 23 May 2023 11:19:30 +0800
+Subject: [PATCH] mtk-wed-add-wed3-ser-support
+
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 236 +++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_wed_regs.h | 73 +++++-
+ include/linux/soc/mediatek/mtk_wed.h | 6 +-
+ 3 files changed, 291 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c
+index 6ed1c83..990888d 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -99,11 +99,65 @@ mtk_wdma_rx_reset(struct mtk_wed_device *dev)
+ u32 status;
+ u32 mask = MTK_WDMA_GLO_CFG_RX_DMA_BUSY;
+ int busy, i;
++ u32 value;
+
+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_DMA_EN);
+ busy = readx_poll_timeout(mtk_wdma_read_reset, dev, status,
+- !(status & mask), 0, 10000);
++ !(status & mask), 0, 10000);
+
++ if (dev->hw->version == 3) {
++ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_PREF_TX_CFG);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_PREF_RX_CFG);
++
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_WRBK_TX_CFG);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_WRBK_RX_CFG);
++
++ /* Prefetch FIFO */
++ wdma_w32(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_FIFO_CFG,
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR);
++
++ /* Core FIFO */
++ value = (MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR |
++ MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR);
++
++ wdma_w32(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, value);
++ wdma_clr(dev, MTK_WDMA_XDMA_RX_FIFO_CFG, value);
++
++ /* Writeback FIFO */
++ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++ wdma_w32(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(0), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_FIFO_CFG(1), MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR);
++
++ /* Prefetch ring status */
++ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR);
++ /* Writeback ring status */
++ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR);
++ }
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_RX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+
+@@ -121,13 +175,62 @@ mtk_wdma_tx_reset(struct mtk_wed_device *dev)
+ {
+ u32 status;
+ u32 mask = MTK_WDMA_GLO_CFG_TX_DMA_BUSY;
+- int i;
++ int busy, i;
++ u32 value;
+
+ wdma_clr(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_TX_DMA_EN);
+ if (readx_poll_timeout(mtk_wdma_read_reset, dev, status,
+ !(status & mask), 0, 10000))
+ WARN_ON_ONCE(1);
+
++ if (dev->hw->version == 3) {
++ wdma_clr(dev, MTK_WDMA_PREF_TX_CFG, MTK_WDMA_PREF_TX_CFG_PREF_EN);
++ wdma_clr(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_TX_CFG_PREF_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_PREF_TX_CFG);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_PREF_RX_CFG_PREF_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_PREF_RX_CFG);
++
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_CFG, MTK_WDMA_WRBK_TX_CFG_WRBK_EN);
++ wdma_clr(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_WRBK_TX_CFG);
++ busy = read_poll_timeout(wdma_r32, status,
++ !(status & MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY), 0, 10000,
++ false, dev, MTK_WDMA_WRBK_RX_CFG);
++
++ /* Prefetch FIFO */
++ wdma_w32(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_TX_FIFO_CFG,
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR |
++ MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR);
++ /* Core FIFO */
++ value = (MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR |
++ MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR);
++
++ wdma_w32(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, value);
++ wdma_clr(dev, MTK_WDMA_XDMA_TX_FIFO_CFG, value);
++ /* Writeback FIFO */
++ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++ wdma_w32(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(0), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_TX_FIFO_CFG(1), MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR);
++
++ /* Prefetch ring status */
++ wdma_w32(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_PREF_SIDX_CFG, MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR);
++ /* Writeback ring status */
++ wdma_w32(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
++ wdma_clr(dev, MTK_WDMA_WRBK_SIDX_CFG, MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR);
++ }
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, MTK_WDMA_RESET_IDX_TX);
+ wdma_w32(dev, MTK_WDMA_RESET_IDX, 0);
+ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+@@ -903,7 +1006,7 @@ mtk_wed_dma_enable(struct mtk_wed_device *dev)
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_UNS_VER_FORCE_4);
+
+ wdma_set(dev, MTK_WDMA_PREF_RX_CFG, MTK_WDMA_PREF_RX_CFG_PREF_EN);
+- //wdma_w32(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
++ wdma_set(dev, MTK_WDMA_WRBK_RX_CFG, MTK_WDMA_WRBK_RX_CFG_WRBK_EN);
+ if (mtk_wed_get_rx_capa(dev)) {
+ wed_set(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
+ MTK_WED_WPDMA_RX_D_PREF_EN |
+@@ -1477,13 +1580,30 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
+ &state, sizeof(state), true);
+
++ if (dev->wlan.hwrro) {
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_IND_CMD_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_HW_STS,
++ MTK_WED_RX_IND_CMD_BUSY);
++ mtk_wed_reset(dev, MTK_WED_RESET_RRO_RX_TO_PG);
++ }
+ wed_clr(dev, MTK_WED_WPDMA_RX_D_GLO_CFG, MTK_WED_WPDMA_RX_D_RX_DRV_EN);
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_GLO_CFG,
+ MTK_WED_WPDMA_RX_D_RX_DRV_BUSY);
++ if (dev->hw->version == 3)
++ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_BUSY);
+ if (busy) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_D_DRV);
+ } else {
++ if (dev->hw->version == 3) {
++ /*1.a. Disable Prefetch HW*/
++ wed_clr(dev, MTK_WED_WPDMA_RX_D_PREF_CFG, MTK_WED_WPDMA_RX_D_PREF_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_RX_D_PREF_CFG,
++ MTK_WED_WPDMA_RX_D_PREF_BUSY);
++ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
++ MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL);
++ }
+ wed_w32(dev, MTK_WED_WPDMA_RX_D_RST_IDX,
+ MTK_WED_WPDMA_RX_D_RST_CRX_IDX |
+ MTK_WED_WPDMA_RX_D_RST_DRV_IDX);
+@@ -1511,6 +1631,24 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ wed_w32(dev, MTK_WED_RROQM_RST_IDX, 0);
+ }
+
++ if (dev->wlan.hwrro) {
++ /* Disable RRO MSDU Page Drv */
++ wed_clr(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
++
++ /* Disable RRO Data Drv */
++ wed_clr(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_EN);
++
++ /* RRO MSDU Page Drv Reset */
++ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
++ mtk_wed_poll_busy(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG,
++ MTK_WED_RRO_MSDU_PG_DRV_CLR);
++
++ /* RRO Data Drv Reset */
++ wed_w32(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_RX_D_DRV_CLR);
++ mtk_wed_poll_busy(dev, MTK_WED_RRO_RX_D_CFG(2),
++ MTK_WED_RRO_RX_D_DRV_CLR);
++ }
++
+ /* reset route qm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_RX_ROUTE_QM_EN);
+ busy = mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+@@ -1518,8 +1656,13 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ if (busy) {
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
+ } else {
+- wed_set(dev, MTK_WED_RTQM_GLO_CFG,
+- MTK_WED_RTQM_Q_RST);
++ if (dev->hw->version == 3) {
++ wed_set(dev, MTK_WED_RTQM_RST, BIT(0));
++ wed_clr(dev, MTK_WED_RTQM_RST, BIT(0));
++ mtk_wed_reset(dev, MTK_WED_RESET_RX_ROUTE_QM);
++ } else
++ wed_set(dev, MTK_WED_RTQM_GLO_CFG,
++ MTK_WED_RTQM_Q_RST);
+ }
+
+ /* reset tx wdma */
+@@ -1527,8 +1670,13 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+
+ /* reset tx wdma drv */
+ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_TX_DRV_EN);
+- mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+- MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
++ if (dev->hw->version == 3)
++ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_STATUS,
++ MTK_WED_WPDMA_STATUS_TX_DRV);
++ else
++ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
++ MTK_WED_CTRL_WDMA_INT_AGENT_BUSY);
++
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_TX_DRV);
+
+ /* reset wed rx dma */
+@@ -1546,9 +1694,17 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ /* reset rx bm */
+ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_BM_EN);
+ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
+- MTK_WED_CTRL_WED_RX_BM_BUSY);
++ MTK_WED_CTRL_WED_RX_BM_BUSY);
+ mtk_wed_reset(dev, MTK_WED_RESET_RX_BM);
+
++ if (dev->wlan.hwrro) {
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_WED_RX_PG_BM_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_CTRL,
++ MTK_WED_CTRL_WED_RX_PG_BM_BUSY);
++ wed_set(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
++ wed_clr(dev, MTK_WED_RESET, MTK_WED_RESET_RX_PG_BM);
++ }
++
+ /* wo change to enable state */
+ state = WO_STATE_ENABLE;
+ mtk_wed_mcu_send_msg(wo, MODULE_ID_WO, MTK_WED_WO_CMD_CHANGE_STATE,
+@@ -1565,6 +1721,9 @@ mtk_wed_rx_reset(struct mtk_wed_device *dev)
+ }
+
+ mtk_wed_free_rx_buffer(dev);
++
++ if (dev->wlan.hwrro)
++ mtk_wed_rx_page_free_buffer(dev);
+ }
+
+
+@@ -1598,18 +1757,40 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+
+ /* 2. Reset WDMA Rx DMA/Driver_Engine */
+ busy = !!mtk_wdma_rx_reset(dev);
++ if (dev->hw->version == 3) {
++ val = wed_r32(dev, MTK_WED_WDMA_GLO_CFG);
++ val |= MTK_WED_WDMA_GLO_CFG_RX_DIS_FSM_AUTO_IDLE;
++ val &= ~MTK_WED_WDMA_GLO_CFG_RX_DRV_EN;
++ wed_w32(dev, MTK_WED_WDMA_GLO_CFG, val);
++ } else
++ wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+
+- wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+ busy = !!(busy ||
+ mtk_wed_poll_busy(dev, MTK_WED_WDMA_GLO_CFG,
+- MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY));
++ MTK_WED_WDMA_GLO_CFG_RX_DRV_BUSY));
++ if (dev->hw->version == 3)
++ busy = !!(busy ||
++ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_BUSY));
+
+ if (busy) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WDMA_RX_DRV);
+ } else {
++ if (dev->hw->version == 3) {
++ /*1.a. Disable Prefetch HW*/
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN);
++ mtk_wed_poll_busy(dev, MTK_WED_WDMA_RX_PREF_CFG,
++ MTK_WED_WDMA_RX_PREF_BUSY);
++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_DDONE2_EN);
++
++ /*2. Reset dma index*/
++ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
++ MTK_WED_WDMA_RESET_IDX_RX_ALL);
++ }
+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX,
+- MTK_WED_WDMA_RESET_IDX_RX | MTK_WED_WDMA_RESET_IDX_DRV);
++ MTK_WED_WDMA_RESET_IDX_RX |
++ MTK_WED_WDMA_RESET_IDX_DRV);
+ wed_w32(dev, MTK_WED_WDMA_RESET_IDX, 0);
+
+ wed_set(dev, MTK_WED_WDMA_GLO_CFG,
+@@ -1624,9 +1805,15 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
+
+ for (i = 0; i < 100; i++) {
+- val = wed_r32(dev, MTK_WED_TX_BM_INTF);
+- if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
+- break;
++ if (dev->ver > MTK_WED_V1) {
++ val = wed_r32(dev, MTK_WED_TX_TKID_INTF);
++ if (FIELD_GET(MTK_WED_TX_TKID_INTF_TKFIFO_FDEP, val) == 0x40)
++ break;
++ } else {
++ val = wed_r32(dev, MTK_WED_TX_BM_INTF);
++ if (FIELD_GET(MTK_WED_TX_BM_INTF_TKFIFO_FDEP, val) == 0x40)
++ break;
++ }
+ }
+ mtk_wed_reset(dev, MTK_WED_RESET_TX_FREE_AGENT);
+
+@@ -1635,18 +1822,20 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+
+ /* 4. Reset WED WPDMA Tx Driver Engine */
+ busy = mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
+- MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
++ MTK_WED_WPDMA_GLO_CFG_TX_DRV_BUSY);
+ wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
+ MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+ MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
+
+ busy = !!(busy ||
+ mtk_wed_poll_busy(dev, MTK_WED_WPDMA_GLO_CFG,
+- MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY));
++ MTK_WED_WPDMA_GLO_CFG_RX_DRV_BUSY));
+ if (busy) {
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_INT_AGENT);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_TX_DRV);
+ mtk_wed_reset(dev, MTK_WED_RESET_WPDMA_RX_DRV);
++ if (dev->hw->version == 3)
++ wed_w32(dev, MTK_WED_RX1_CTRL2, 0);
+ } else {
+ wed_w32(dev, MTK_WED_WPDMA_RESET_IDX,
+ MTK_WED_WPDMA_RESET_IDX_TX |
+@@ -1659,7 +1848,13 @@ mtk_wed_reset_dma(struct mtk_wed_device *dev)
+ }
+ }
+
+- if (dev->ver > MTK_WED_V1) {
++ if (dev->hw->version == 3) {
++ /*reset wed pao*/
++ wed_clr(dev, MTK_WED_CTRL, MTK_WED_CTRL_TX_PAO_EN);
++ mtk_wed_reset(dev, MTK_WED_RESET_TX_PAO);
++ }
++
++ if (mtk_wed_get_rx_capa(dev)) {
+ dev->init_done = false;
+ mtk_wed_rx_reset(dev);
+ }
+@@ -1874,7 +2069,7 @@ mtk_wed_ppe_check(struct mtk_wed_device *dev, struct sk_buff *skb,
+ }
+
+ static void
+-mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask)
++mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask, bool reset)
+ {
+ int idx, ret;
+
+@@ -1884,6 +2079,11 @@ mtk_wed_start_hwrro(struct mtk_wed_device *dev, u32 irq_mask)
+ if (!mtk_wed_get_rx_capa(dev) || !dev->wlan.hwrro)
+ return;
+
++ if (reset) {
++ wed_set(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_EN);
++ return;
++ }
++
+ wed_set(dev, MTK_WED_RRO_RX_D_CFG(2), MTK_WED_RRO_MSDU_PG_DRV_CLR);
+ wed_w32(dev, MTK_WED_RRO_MSDU_PG_RING2_CFG, MTK_WED_RRO_MSDU_PG_DRV_CLR);
+
+diff --git a/drivers/net/ethernet/mediatek/mtk_wed_regs.h b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+index 25be547..4379dc4 100644
+--- a/drivers/net/ethernet/mediatek/mtk_wed_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_regs.h
+@@ -42,6 +42,8 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RESET 0x008
+ #define MTK_WED_RESET_TX_BM BIT(0)
+ #define MTK_WED_RESET_RX_BM BIT(1)
++#define MTK_WED_RESET_RX_PG_BM BIT(2)
++#define MTK_WED_RESET_RRO_RX_TO_PG BIT(3)
+ #define MTK_WED_RESET_TX_FREE_AGENT BIT(4)
+ #define MTK_WED_RESET_WPDMA_TX_DRV BIT(8)
+ #define MTK_WED_RESET_WPDMA_RX_DRV BIT(9)
+@@ -64,7 +66,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_CTRL_WDMA_INT_AGENT_BUSY BIT(3)
+ #define MTK_WED_CTRL_WED_RX_IND_CMD_EN BIT(5)
+ #define MTK_WED_CTRL_WED_RX_PG_BM_EN BIT(6)
+-#define MTK_WED_CTRL_WED_RX_PG_BM_BUSU BIT(7)
++#define MTK_WED_CTRL_WED_RX_PG_BM_BUSY BIT(7)
+ #define MTK_WED_CTRL_WED_TX_BM_EN BIT(8)
+ #define MTK_WED_CTRL_WED_TX_BM_BUSY BIT(9)
+ #define MTK_WED_CTRL_WED_TX_FREE_AGENT_EN BIT(10)
+@@ -123,6 +125,10 @@ struct mtk_wdma_desc {
+ #define MTK_WED_STATUS 0x060
+ #define MTK_WED_STATUS_TX GENMASK(15, 8)
+
++#define MTK_WED_WPDMA_STATUS 0x068
++#define MTK_WED_WPDMA_STATUS_TX_DRV GENMASK(15, 8)
++
++
+ #define MTK_WED_TX_BM_CTRL 0x080
+ #define MTK_WED_TX_BM_CTRL_VLD_GRP_NUM GENMASK(6, 0)
+ #define MTK_WED_TX_BM_CTRL_RSV_GRP_NUM GENMASK(22, 16)
+@@ -167,6 +173,9 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_TX_TKID_CTRL_PAUSE BIT(28)
+
++#define MTK_WED_TX_TKID_INTF 0x0dc
++#define MTK_WED_TX_TKID_INTF_TKFIFO_FDEP GENMASK(25, 16)
++
+ #define MTK_WED_TX_TKID_DYN_THR 0x0e0
+ #define MTK_WED_TX_TKID_DYN_THR_LO GENMASK(6, 0)
+ #define MTK_WED_TX_TKID_DYN_THR_HI GENMASK(22, 16)
+@@ -203,10 +212,11 @@ struct mtk_wdma_desc {
+ #define MTK_WED_GLO_CFG_RX_2B_OFFSET BIT(31)
+
+ #define MTK_WED_RESET_IDX 0x20c
+-#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
+-#if defined(CONFIG_MEDIATEK_NETSYS_V2)
++#if defined(CONFIG_MEDIATEK_NETSYS_V2) || defined(CONFIG_MEDIATEK_NETSYS_V3)
++#define MTK_WED_RESET_IDX_TX GENMASK(1, 0)
+ #define MTK_WED_RESET_IDX_RX GENMASK(7, 6)
+ #else
++#define MTK_WED_RESET_IDX_TX GENMASK(3, 0)
+ #define MTK_WED_RESET_IDX_RX GENMASK(17, 16)
+ #endif
+ #define MTK_WED_RESET_WPDMA_IDX_RX GENMASK(31, 30)
+@@ -221,6 +231,7 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RING_RX_DATA(_n) (0x420 + (_n) * 0x10)
+
+ #define MTK_WED_SCR0 0x3c0
++#define MTK_WED_RX1_CTRL2 0x418
+ #define MTK_WED_WPDMA_INT_TRIGGER 0x504
+ #define MTK_WED_WPDMA_INT_TRIGGER_RX_DONE BIT(1)
+ #define MTK_WED_WPDMA_INT_TRIGGER_TX_DONE GENMASK(5, 4)
+@@ -336,6 +347,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WPDMA_RX_D_RST_IDX 0x760
+ #define MTK_WED_WPDMA_RX_D_RST_CRX_IDX GENMASK(17, 16)
++#define MTK_WED_WPDMA_RX_D_RST_DRV_IDX_ALL BIT(20)
+ #define MTK_WED_WPDMA_RX_D_RST_DRV_IDX GENMASK(25, 24)
+
+ #define MTK_WED_WPDMA_RX_GLO_CFG 0x76c
+@@ -352,6 +364,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WPDMA_RX_D_PREF_CFG 0x7b4
+ #define MTK_WED_WPDMA_RX_D_PREF_EN BIT(0)
++#define MTK_WED_WPDMA_RX_D_PREF_BUSY BIT(1)
+ #define MTK_WED_WPDMA_RX_D_PREF_BURST_SIZE GENMASK(12, 8)
+ #define MTK_WED_WPDMA_RX_D_PREF_LOW_THRES GENMASK(21, 16)
+
+@@ -373,11 +386,13 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WDMA_RX_PREF_CFG 0x950
+ #define MTK_WED_WDMA_RX_PREF_EN BIT(0)
++#define MTK_WED_WDMA_RX_PREF_BUSY BIT(1)
+ #define MTK_WED_WDMA_RX_PREF_BURST_SIZE GENMASK(12, 8)
+ #define MTK_WED_WDMA_RX_PREF_LOW_THRES GENMASK(21, 16)
+ #define MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR BIT(24)
+ #define MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR BIT(25)
+ #define MTK_WED_WDMA_RX_PREF_DDONE2_EN BIT(26)
++#define MTK_WED_WDMA_RX_PREF_DDONE2_BUSY BIT(27)
+
+ #define MTK_WED_WDMA_RX_PREF_FIFO_CFG 0x95C
+ #define MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR BIT(0)
+@@ -406,6 +421,7 @@ struct mtk_wdma_desc {
+
+ #define MTK_WED_WDMA_RESET_IDX 0xa08
+ #define MTK_WED_WDMA_RESET_IDX_RX GENMASK(17, 16)
++#define MTK_WED_WDMA_RESET_IDX_RX_ALL BIT(20)
+ #define MTK_WED_WDMA_RESET_IDX_DRV GENMASK(25, 24)
+
+ #define MTK_WED_WDMA_INT_CLR 0xa24
+@@ -474,21 +490,66 @@ struct mtk_wdma_desc {
+ #define MTK_WDMA_INT_MASK_RX_DELAY BIT(30)
+ #define MTK_WDMA_INT_MASK_RX_COHERENT BIT(31)
+
++#define MTK_WDMA_XDMA_TX_FIFO_CFG 0x238
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_PAR_FIFO_CLEAR BIT(0)
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_CMD_FIFO_CLEAR BIT(4)
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_DMAD_FIFO_CLEAR BIT(8)
++#define MTK_WDMA_XDMA_TX_FIFO_CFG_TX_ARR_FIFO_CLEAR BIT(12)
++
++#define MTK_WDMA_XDMA_RX_FIFO_CFG 0x23c
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_PAR_FIFO_CLEAR BIT(0)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_CMD_FIFO_CLEAR BIT(4)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_DMAD_FIFO_CLEAR BIT(8)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_ARR_FIFO_CLEAR BIT(12)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_LEN_FIFO_CLEAR BIT(15)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_WID_FIFO_CLEAR BIT(18)
++#define MTK_WDMA_XDMA_RX_FIFO_CFG_RX_BID_FIFO_CLEAR BIT(21)
++
++
++
+ #define MTK_WDMA_INT_GRP1 0x250
+ #define MTK_WDMA_INT_GRP2 0x254
+
+ #define MTK_WDMA_PREF_TX_CFG 0x2d0
+ #define MTK_WDMA_PREF_TX_CFG_PREF_EN BIT(0)
++#define MTK_WDMA_PREF_TX_CFG_PREF_BUSY BIT(1)
+
+ #define MTK_WDMA_PREF_RX_CFG 0x2dc
+ #define MTK_WDMA_PREF_RX_CFG_PREF_EN BIT(0)
++#define MTK_WDMA_PREF_RX_CFG_PREF_BUSY BIT(1)
++
++#define MTK_WDMA_PREF_RX_FIFO_CFG 0x2e0
++#define MTK_WDMA_PREF_RX_FIFO_CFG_RING0_CLEAR BIT(0)
++#define MTK_WDMA_PREF_RX_FIFO_CFG_RING1_CLEAR BIT(16)
++
++#define MTK_WDMA_PREF_TX_FIFO_CFG 0x2d4
++#define MTK_WDMA_PREF_TX_FIFO_CFG_RING0_CLEAR BIT(0)
++#define MTK_WDMA_PREF_TX_FIFO_CFG_RING1_CLEAR BIT(16)
++
++#define MTK_WDMA_PREF_SIDX_CFG 0x2e4
++#define MTK_WDMA_PREF_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
++#define MTK_WDMA_PREF_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
+
+ #define MTK_WDMA_WRBK_TX_CFG 0x300
++#define MTK_WDMA_WRBK_TX_CFG_WRBK_BUSY BIT(0)
+ #define MTK_WDMA_WRBK_TX_CFG_WRBK_EN BIT(30)
+
++#define MTK_WDMA_WRBK_TX_FIFO_CFG(_n) (0x304 + (_n) * 0x4)
++#define MTK_WDMA_WRBK_TX_FIFO_CFG_RING_CLEAR BIT(0)
++
++
+ #define MTK_WDMA_WRBK_RX_CFG 0x344
++#define MTK_WDMA_WRBK_RX_CFG_WRBK_BUSY BIT(0)
+ #define MTK_WDMA_WRBK_RX_CFG_WRBK_EN BIT(30)
+
++#define MTK_WDMA_WRBK_RX_FIFO_CFG(_n) (0x348 + (_n) * 0x4)
++#define MTK_WDMA_WRBK_RX_FIFO_CFG_RING_CLEAR BIT(0)
++
++
++#define MTK_WDMA_WRBK_SIDX_CFG 0x388
++#define MTK_WDMA_WRBK_SIDX_CFG_TX_RING_CLEAR GENMASK(3, 0)
++#define MTK_WDMA_WRBK_SIDX_CFG_RX_RING_CLEAR GENMASK(5, 4)
++
+ #define MTK_PCIE_MIRROR_MAP(n) ((n) ? 0x4 : 0x0)
+ #define MTK_PCIE_MIRROR_MAP_EN BIT(0)
+ #define MTK_PCIE_MIRROR_MAP_WED_ID BIT(1)
+@@ -502,6 +563,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_RTQM_Q_DBG_BYPASS BIT(5)
+ #define MTK_WED_RTQM_TXDMAD_FPORT GENMASK(23, 20)
+
++#define MTK_WED_RTQM_RST 0xb04
++
++
+ #define MTK_WED_RTQM_IGRS0_I2HW_DMAD_CNT 0xb1c
+ #define MTK_WED_RTQM_IGRS0_I2H_DMAD_CNT(_n) (0xb20 + (_n) * 0x4)
+ #define MTK_WED_RTQM_IGRS0_I2HW_PKT_CNT 0xb28
+@@ -691,6 +755,9 @@ struct mtk_wdma_desc {
+ #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_CLR BIT(17)
+ #define MTK_WED_WPDMA_INT_CTRL_RRO_PG2_DONE_TRIG GENMASK(22, 18)
+
++#define MTK_WED_RRO_RX_HW_STS 0xf00
++#define MTK_WED_RX_IND_CMD_BUSY GENMASK(31, 0)
++
+ #define MTK_WED_RX_IND_CMD_CNT0 0xf20
+ #define MTK_WED_RX_IND_CMD_DBG_CNT_EN BIT(31)
+
+diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h
+index 2b389e8..bb02ba5 100644
+--- a/include/linux/soc/mediatek/mtk_wed.h
++++ b/include/linux/soc/mediatek/mtk_wed.h
+@@ -240,7 +240,7 @@ struct mtk_wed_ops {
+ void (*irq_set_mask)(struct mtk_wed_device *dev, u32 mask);
+ void (*ppe_check)(struct mtk_wed_device *dev, struct sk_buff *skb,
+ u32 reason, u32 hash);
+- void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask);
++ void (*start_hwrro)(struct mtk_wed_device *dev, u32 irq_mask, bool reset);
+ };
+
+ extern const struct mtk_wed_ops __rcu *mtk_soc_wed_ops;
+@@ -317,8 +317,8 @@ mtk_wed_device_support_pao(struct mtk_wed_device *dev)
+ (_dev)->ops->reset_dma(_dev)
+ #define mtk_wed_device_ppe_check(_dev, _skb, _reason, _hash) \
+ (_dev)->ops->ppe_check(_dev, _skb, _reason, _hash)
+-#define mtk_wed_device_start_hwrro(_dev, _mask) \
+- (_dev)->ops->start_hwrro(_dev, _mask)
++#define mtk_wed_device_start_hwrro(_dev, _mask, _reset) \
++ (_dev)->ops->start_hwrro(_dev, _mask, _reset)
+
+ #else
+ static inline bool mtk_wed_device_active(struct mtk_wed_device *dev)
+--
+2.18.0
+
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/rdkb_cfg/filogic_rdkb.cfg b/recipes-kernel/linux/linux-mediatek-5.4/rdkb_cfg/filogic_rdkb.cfg
index 83d27c8..d8f9ad1 100644
--- a/recipes-kernel/linux/linux-mediatek-5.4/rdkb_cfg/filogic_rdkb.cfg
+++ b/recipes-kernel/linux/linux-mediatek-5.4/rdkb_cfg/filogic_rdkb.cfg
@@ -21,4 +21,6 @@
CONFIG_OID_REGISTRY=m
CONFIG_DEBUG_INFO=y
CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_UNCOMPRESSED=y
\ No newline at end of file
+CONFIG_KALLSYMS_UNCOMPRESSED=y
+CONFIG_IP_MROUTE=y
+CONFIG_IPV6_MROUTE=y
diff --git a/recipes-kernel/linux/linux-mediatek_5.4.bb b/recipes-kernel/linux/linux-mediatek_5.4.bb
index 8728f3f..f6e8bc0 100644
--- a/recipes-kernel/linux/linux-mediatek_5.4.bb
+++ b/recipes-kernel/linux/linux-mediatek_5.4.bb
@@ -5,6 +5,7 @@
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}/mediatek/patches-5.4:"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}/mediatek/flow_patch:"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}/mediatek/nf_hnat:"
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}/mediatek/wed3:"
KBRANCH ?= "linux-5.4.y"
@@ -46,7 +47,7 @@
${@bb.utils.contains('DISTRO_FEATURES','emmc','file://rdkb_cfg/emmc.cfg','',d)} \
"
-SRC_URI_append_mt7986 += " \
+SRC_URI_append += " \
${@bb.utils.contains('DISTRO_FEATURES','flow_offload','file://rdkb_cfg/bridge_netfilter.cfg','',d)} \
"
@@ -63,7 +64,7 @@
require ${PN}-${PV}/mediatek/patches-5.4/patches-5.4.inc
SRC_URI_remove_mt7986-32bit = " \
- file://401-pinctrl-add-mt7986-driver.patch \
+ file://999-2020-pinctrl-add-mt7986-driver.patch \
"
SRC_URI_append_secureboot += " \
file://0404-mtdsplit-dm-verity.patch;apply=no \
@@ -88,12 +89,13 @@
patch -p1 < ${WORKDIR}/001-rdkb-eth-mtk-change-ifname-for.patch
patch -p1 < ${WORKDIR}/003-rdkb-mtd-kernel-ubi-relayout.patch
patch -p1 < ${WORKDIR}/0600-net-phylink-propagate-resolved-link-config-via-mac_l.patch
- patch -p1 < ${WORKDIR}/738-mt7531-gsw-internal_phy_calibration.patch
- patch -p1 < ${WORKDIR}/739-mt7531-gsw-port5_external_phy_init.patch
- patch -p1 < ${WORKDIR}/753-net-mt753x-phy-coverity-scan.patch
- patch -p1 < ${WORKDIR}/757-net-phy-add-phylink-pcs-support.patch
- patch -p1 < ${WORKDIR}/792-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch
- patch -p1 < ${WORKDIR}/9010-iwconfig-wireless-rate-fix.patch
+ patch -p1 < ${WORKDIR}/999-2713-mt7531-gsw-internal_phy_calibration.patch
+ patch -p1 < ${WORKDIR}/999-2714-mt7531-gsw-port5_external_phy_init.patch
+ patch -p1 < ${WORKDIR}/999-2721-net-mt753x-phy-coverity-scan.patch
+ patch -p1 < ${WORKDIR}/999-1710-net-phy-add-phylink-pcs-support.patch
+ patch -p1 < ${WORKDIR}/999-1712-net-phy-add-phylink-rate-matching-support.patch
+ patch -p1 < ${WORKDIR}/999-2702-v5.9-net-phy-add-support-for-a-common-probe-between-shared-PHYs.patch
+ patch -p1 < ${WORKDIR}/999-2725-iwconfig-wireless-rate-fix.patch
if [ $DISTRO_secure_boot_ENABLED = 'true' ]; then
patch -p1 < ${WORKDIR}/0404-mtdsplit-dm-verity.patch
patch -p1 < ${WORKDIR}/0800-dm-verity-redo-hash-for-safexel-sha256.patch
@@ -105,13 +107,21 @@
fi
if [ $DISTRO_logan_ENABLED = 'true' ]; then
for i in ${WORKDIR}/mediatek/nf_hnat/6*.patch; do patch -p1 < $i; done
- for i in ${WORKDIR}/mediatek/nf_hnat/10*.patch; do patch -p1 < $i; done
+ for i in ${WORKDIR}/mediatek/nf_hnat/9*.patch; do patch -p1 < $i; done
patch -p1 < ${WORKDIR}/004-rdkb-hnat-bind-ifname.patch
fi
touch patch_applied
fi
}
+do_filogic_patches_append_mt7988() {
+ if [ ! -e wed3_patch_applied ]; then
+ if [ $DISTRO_FlowBlock_ENABLED = 'true' ]; then
+ for i in ${WORKDIR}/mediatek/wed3/*.patch; do patch -p1 < $i; done
+ fi
+ touch wed3_patch_applied
+ fi
+}
addtask filogic_patches after do_patch before do_compile
KERNEL_MODULE_AUTOLOAD += "${@bb.utils.contains('DISTRO_FEATURES','logan','mtkhnat nf_flow_table_hw','',d)}"
\ No newline at end of file
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/432-missing-typedef.patch b/recipes-wifi/hostapd/files/patches-2.10.3/432-missing-typedef.patch
deleted file mode 100644
index 7a100f1..0000000
--- a/recipes-wifi/hostapd/files/patches-2.10.3/432-missing-typedef.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/src/drivers/linux_wext.h
-+++ b/src/drivers/linux_wext.h
-@@ -26,6 +26,7 @@ typedef int32_t __s32;
- typedef uint16_t __u16;
- typedef int16_t __s16;
- typedef uint8_t __u8;
-+typedef int8_t __s8;
- #ifndef __user
- #define __user
- #endif /* __user */
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
index a79555a..0892d3f 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
@@ -1,7 +1,7 @@
-From fd2df638591cc86c21153e94abe8fc00451703b8 Mon Sep 17 00:00:00 2001
+From ee34d2ccb27863f0eaa7abb0f65477ab9a0dd92f Mon Sep 17 00:00:00 2001
From: TomLiu <tomml.liu@mediatek.com>
Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/28] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH 06/32] hostapd: mtk: Add hostapd MU SET/GET control
---
hostapd/config_file.c | 9 +++
@@ -156,14 +156,14 @@
{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
"report a scanned DPP URI from a QR Code" },
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 55c35c7..1cad303 100644
+index 55c35c7..afa19ec 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -280,6 +280,7 @@ struct hostapd_config * hostapd_config_defaults(void)
conf->he_6ghz_max_ampdu_len_exp = 7;
conf->he_6ghz_rx_ant_pat = 1;
conf->he_6ghz_tx_ant_pat = 1;
-+ conf->mu_onoff = 13;
++ conf->mu_onoff = 15;
#endif /* CONFIG_IEEE80211AX */
/* The third octet of the country string uses an ASCII space character
@@ -446,5 +446,5 @@
}
--
-2.18.0
+2.39.0
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
index c53b55a..bf91686 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
@@ -1,19 +1,18 @@
-From 3237a993233da052219018eec10ca82d79225fdb Mon Sep 17 00:00:00 2001
+From 705e1a59381e7bbd92043ad4338834aad504f232 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 20 Feb 2023 16:58:20 +0800
-Subject: [PATCH 18/28] hostapd: mtk: Fix auto ht issue when switching to DFS
- channel
+Subject: [PATCH] hostapd: mtk: Fix auto ht issue when switching to DFS channel
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
- hostapd/ctrl_iface.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
+ hostapd/ctrl_iface.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 07de0ad..be86f6c 100644
+index 07de0ad..3c38df5 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
-@@ -2773,6 +2773,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2773,6 +2773,13 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
break;
}
@@ -21,12 +20,13 @@
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
++ settings.freq_params.eht_enabled = iface->conf->ieee80211be;
+ }
+
if (settings.freq_params.center_freq1)
dfs_range += hostapd_is_dfs_overlap(
iface, bandwidth, settings.freq_params.center_freq1);
-@@ -2810,12 +2816,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2810,12 +2817,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
return 0;
}
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0101-hostapd-mtk-Fix-CCA-issue.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Fix-CCA-issue.patch
similarity index 88%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0101-hostapd-mtk-Fix-CCA-issue.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Fix-CCA-issue.patch
index 9b46d70..e4667e4 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0101-hostapd-mtk-Fix-CCA-issue.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0029-hostapd-mtk-Fix-CCA-issue.patch
@@ -1,12 +1,12 @@
-From 39a0dd44653f12ce13af68de81bfae683669623a Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Thu, 11 May 2023 14:08:59 +0800
-Subject: [PATCH 101/103] hostapd: mtk: Fix CCA issue
+From c92a1e50abdad2bf3e961c9d5aa34baea81f025b Mon Sep 17 00:00:00 2001
+From: Michael Lee <michael-cy.lee@mediatek.com>
+Date: Wed, 3 May 2023 14:55:18 +0800
+Subject: [PATCH] hostapd: mtk: Fix CCA issue
-When receiving CCA related nl80211 command, hostapd used to work on
+When receiving CCA-related nl80211 commands, hostapd used to work on
struct wpa_driver_nl80211_data, whose ctx always points to
-hostpad_iface->bss[0]. However, CCA command is sent on per-BSS based.
-This patch makes hostapd handle CCA related commands on per-BSS based.
+hostpad_iface->bss[0]. However, CCA commands are sent on a per-BSS based.
+This patch makes hostapd handle CCA-related commands on a per-BSS based.
Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
---
@@ -93,5 +93,5 @@
#endif /* CONFIG_IEEE80211AX */
default:
--
-2.18.0
+2.25.1
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
similarity index 66%
rename from recipes-wifi/hostapd/files/patches-2.10.3/mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
rename to recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
index 4075531..f9c4714 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
@@ -1,15 +1,14 @@
-From 097b204ffed838a4bbf7649fb23310f64ace22ad Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Thu, 11 May 2023 14:12:44 +0800
-Subject: [PATCH 102/103] hostapd: mtk: Fix unexpected AP beacon state
- transition
+From c4d3890bbf1bd8c8ac8bfaa56fd16e2391e05181 Mon Sep 17 00:00:00 2001
+From: Michael Lee <michael-cy.lee@mediatek.com>
+Date: Wed, 3 May 2023 16:10:57 +0800
+Subject: [PATCH] hostapd: mtk: Fix unexpected AP beacon state transition
-When AP fails setting the beacon, it assigns bss->beacon_set to 0 no
+When AP fails to set the beacon, it assigns bss->beacon_set to 0 no
matter what the error number is.
However, in the case that the error number is -EBUSY, the driver might
not free the beacon and expect a later beacon re-setting. If hostapd set
-a new beacon under this case, driver will return -EALREADY.
-This patch checks the error number after hostapd fails setting the
+a new beacon under this case, the driver will return -EALREADY.
+This patch checks the error number after hostapd fails to set the
beacon. If the error number is -EBUSY, bss->beacon_set will not be
assigned to 0.
@@ -19,7 +18,7 @@
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 8400e57..ccfc2d0 100644
+index 8400e57..5013207 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5126,7 +5126,8 @@ static int wpa_driver_nl80211_set_ap(void *priv,
@@ -33,5 +32,5 @@
bss->flink->beacon_set = 1;
nl80211_set_bss(bss, params->cts_protect, params->preamble,
--
-2.18.0
+2.25.1
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch
new file mode 100644
index 0000000..1c5cacc
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch
@@ -0,0 +1,53 @@
+From 43c8934074a4f6fd1e98143b3bd011e71fe69fdb Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Fri Jun 9 09:03:05 2023 +0800
+Subject: hostapd: mtk: Add HE capabilities check
+
+Add HE capabilities check.
+Since "HE capabilities" check has been removed by driver,
+add the support for "HE capabilities" check in hostapd.
+
+---
+ src/ap/hw_features.c | 26 ++++++++++++++++++++++++++
+ 1 files changed, 26 insertions(+)
+
+diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
+index 9967494..309f2d5 100644
+--- a/src/ap/hw_features.c
++++ b/src/ap/hw_features.c
+@@ -680,6 +680,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
+ #ifdef CONFIG_IEEE80211AX
+ static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface)
+ {
++ struct hostapd_hw_modes *mode = iface->current_mode;
++ struct he_capabilities *he_cap = &mode->he_capab[IEEE80211_MODE_AP];
++ struct hostapd_config *conf = iface->conf;
++
++#define HE_CAP_CHECK(hw_cap, field, phy_idx, cfg_cap) \
++ do { \
++ if (cfg_cap && !(hw_cap[phy_idx] & field)) { \
++ wpa_printf(MSG_ERROR, "Driver does not support configured" \
++ " HE capability [%s]", #field); \
++ return 0; \
++ } \
++ } while (0)
++
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_LDPC_CODING_IN_PAYLOAD,
++ HE_PHYCAP_LDPC_CODING_IN_PAYLOAD_IDX,
++ conf->he_phy_capab.he_ldpc);
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_SU_BEAMFORMER_CAPAB,
++ HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX,
++ conf->he_phy_capab.he_su_beamformer);
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_SU_BEAMFORMEE_CAPAB,
++ HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX,
++ conf->he_phy_capab.he_su_beamformee);
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_MU_BEAMFORMER_CAPAB,
++ HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX,
++ conf->he_phy_capab.he_mu_beamformer);
++
+ return 1;
+ }
+ #endif /* CONFIG_IEEE80211AX */
+--
+2.39.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
new file mode 100644
index 0000000..01a134e
--- /dev/null
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
@@ -0,0 +1,44 @@
+From 0aaec4ebc72e40da76a279d817763f4655f45d21 Mon Sep 17 00:00:00 2001
+From: mtk23510 <rudra.shahi@mediatek.com>
+Date: Fri, 26 May 2023 14:52:35 +0800
+Subject: [PATCH] hostapd: mtk: Add support for gtk rekeying in hostapd cli
+
+Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
+---
+ hostapd/hostapd_cli.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
+index 02f8546..d529bbc 100644
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -1256,6 +1256,15 @@ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
+ }
+
+
++#ifdef CONFIG_TESTING_OPTIONS
++static int hostapd_cli_cmd_rekey_gtk(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "REKEY_GTK");
++}
++#endif
++
++
+ static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
+ {
+ char cmd[256];
+@@ -1761,6 +1770,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
+ "= disable hostapd on current interface" },
+ { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
+ "= update Beacon frame contents\n"},
++#ifdef CONFIG_TESTING_OPTIONS
++ { "rekey_gtk", hostapd_cli_cmd_rekey_gtk, NULL,
++ "= rekey gtk\n"},
++#endif
+ { "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
+ "= drop all ERP keys"},
+ { "log_level", hostapd_cli_cmd_log_level, NULL,
+--
+2.18.0
+
diff --git a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
index a71c43f..a0c06b1 100644
--- a/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
+++ b/recipes-wifi/hostapd/files/patches-2.10.3/patches.inc
@@ -36,7 +36,6 @@
file://420-indicate-features.patch \
file://430-hostapd_cli_ifdef.patch \
file://431-wpa_cli_ifdef.patch \
- file://432-missing-typedef.patch \
file://450-scan_wait.patch;apply=no \
file://460-wpa_supplicant-add-new-config-params-to-be-used-with.patch \
file://463-add-mcast_rate-to-11s.patch \
@@ -87,8 +86,10 @@
file://mtk-0026-hostapd-mtk-avoid-setting-beacon-after-wpa_supplican.patch \
file://mtk-0027-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch \
file://mtk-0028-hostapd-mtk-Add-muru-user-number-debug-command.patch \
+ file://mtk-0029-hostapd-mtk-Fix-CCA-issue.patch \
+ file://mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch \
+ file://mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch \
file://mtk-0100-hostapd-mtk-update-eht-operation-element.patch \
- file://mtk-0101-hostapd-mtk-Fix-CCA-issue.patch \
- file://mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch \
file://mtk-0103-hostapd-mtk-Add-BW320-channel-switch-command.patch \
+ file://mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch \
"
diff --git a/recipes-wifi/hostapd/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch b/recipes-wifi/hostapd/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
index f89da87..d5f0dac 100644
--- a/recipes-wifi/hostapd/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
+++ b/recipes-wifi/hostapd/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
@@ -1,19 +1,18 @@
-From 0aa1200534c41279f5f05e1919040a86f003ca0a Mon Sep 17 00:00:00 2001
+From a71a78bc51b74d331aeb3f900c03480d058d5233 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 20 Feb 2023 16:58:20 +0800
-Subject: [PATCH 19/29] hostapd: mtk: Fix auto ht issue when switching to DFS
- channel
+Subject: [PATCH] hostapd: mtk: Fix auto ht issue when switching to DFS channel
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
- hostapd/ctrl_iface.c | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
+ hostapd/ctrl_iface.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 61c9e80..06cbea1 100644
+index 61c9e80..c33b7a4 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
-@@ -2698,6 +2698,13 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2698,6 +2698,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
break;
}
@@ -21,13 +20,12 @@
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
-+ settings.freq_params.eht_enabled = iface->conf->ieee80211be;
+ }
+
if (settings.freq_params.center_freq1)
dfs_range += hostapd_is_dfs_overlap(
iface, bandwidth, settings.freq_params.center_freq1);
-@@ -2735,12 +2742,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2735,12 +2741,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
return 0;
}
diff --git a/recipes-wifi/hostapd/hostapd_2.10.3.bb b/recipes-wifi/hostapd/hostapd_2.10.3.bb
index 68cb4c2..06874d3 100644
--- a/recipes-wifi/hostapd/hostapd_2.10.3.bb
+++ b/recipes-wifi/hostapd/hostapd_2.10.3.bb
@@ -68,6 +68,7 @@
echo "CONFIG_WEP=y" >> ${B}/.config
echo "CONFIG_FILS=y" >> ${B}/.config
echo "CONFIG_IEEE80211BE=y" >> ${B}/.config
+ echo "CONFIG_TESTING_OPTIONS=y" >> ${B}/.config
}
do_filogic_patches() {
diff --git a/recipes-wifi/hostapd/hostapd_2.10.bb b/recipes-wifi/hostapd/hostapd_2.10.bb
index 8f54916..e83d34e 100644
--- a/recipes-wifi/hostapd/hostapd_2.10.bb
+++ b/recipes-wifi/hostapd/hostapd_2.10.bb
@@ -67,6 +67,7 @@
echo "CONFIG_MESH=y" >> ${B}/.config
echo "CONFIG_WEP=y" >> ${B}/.config
echo "CONFIG_FILS=y" >> ${B}/.config
+ echo "CONFIG_TESTING_OPTIONS=y" >> ${B}/.config
}
do_filogic_patches() {
diff --git a/recipes-wifi/libubox/libubox_git.bbappend b/recipes-wifi/libubox/libubox_git.bbappend
index 11a4d90..5bc09d3 100644
--- a/recipes-wifi/libubox/libubox_git.bbappend
+++ b/recipes-wifi/libubox/libubox_git.bbappend
@@ -1,3 +1,3 @@
SRC_URI_remove = "file://0001-blobmsg-fix-array-out-of-bounds-GCC-10-warning.patch"
-SRCREV = "ea56013409d5823001b47a9bba6f74055a6d76a5"
+SRCREV = "75a3b870cace1171faf57bd55e5a9a2f1564f757"
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/050-lib80211_option.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/build/050-lib80211_option.patch
deleted file mode 100644
index c1b1bc7..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/build/050-lib80211_option.patch
+++ /dev/null
@@ -1,34 +0,0 @@
---- a/net/wireless/Kconfig
-+++ b/net/wireless/Kconfig
-@@ -188,7 +188,7 @@ config CFG80211_WEXT_EXPORT
- endif # CFG80211
-
- config LIB80211
-- tristate
-+ tristate "lib80211"
- depends on m
- default n
- help
-@@ -198,19 +198,19 @@ config LIB80211
- Drivers should select this themselves if needed.
-
- config LIB80211_CRYPT_WEP
-- tristate
-+ tristate "lib80211 WEP support"
- depends on m
- select BPAUTO_CRYPTO_LIB_ARC4
-
- config LIB80211_CRYPT_CCMP
-- tristate
-+ tristate "lib80211 CCMP support"
- depends on m
- depends on CRYPTO
- depends on CRYPTO_AES
- depends on CRYPTO_CCM
-
- config LIB80211_CRYPT_TKIP
-- tristate
-+ tristate "lib80211 TKIP support"
- depends on m
- select BPAUTO_CRYPTO_LIB_ARC4
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc b/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc
index c0e4215..dbdb7b7 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/build/build.inc
@@ -5,7 +5,6 @@
file://002-change_allconfig.patch \
file://003-remove_bogus_modparams.patch \
file://012-kernel_build_check.patch \
- file://050-lib80211_option.patch \
file://060-no_local_ssb_bcma.patch \
file://070-remove-broken-wext-select.patch \
file://080-resv_start_op.patch \
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch
index 6aec9bc..59b799b 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch
@@ -1,5 +1,6 @@
+From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
-Date: Tue, 6 Dec 2022 11:15:02 +0100
+Date: Mon, 13 Feb 2023 11:08:54 +0100
Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh
interfaces
@@ -33,7 +34,15 @@
For forwarded packets, a new 802.11 header gets added.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name
+[fix fortify build error]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
+ .../wireless/marvell/mwifiex/11n_rxreorder.c | 2 +-
+ include/net/cfg80211.h | 27 +-
+ net/mac80211/rx.c | 350 ++++++++++--------
+ net/wireless/util.c | 120 +++---
+ 4 files changed, 297 insertions(+), 202 deletions(-)
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
@@ -557,7 +566,7 @@
+ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN);
+ break;
+ case MESH_FLAGS_AE_A5_A6:
-+ memcpy(&payload.eth.h_dest, mesh_addr, 2 * ETH_ALEN);
++ memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN);
+ break;
+ default:
+ break;
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch
new file mode 100644
index 0000000..088f468
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch
@@ -0,0 +1,372 @@
+From bd54f3c29077f23dad92ef82a78061b40be30c65 Mon Sep 17 00:00:00 2001
+From: Aloka Dixit <quic_alokad@quicinc.com>
+Date: Mon, 5 Dec 2022 16:50:37 -0800
+Subject: [PATCH] wifi: mac80211: generate EMA beacons in AP mode
+
+Add APIs to generate an array of beacons for an EMA AP (enhanced
+multiple BSSID advertisements), each including a single MBSSID element.
+EMA profile periodicity equals the count of elements.
+
+- ieee80211_beacon_get_template_ema_list() - Generate and return all
+EMA beacon templates. Drivers must call ieee80211_beacon_free_ema_list()
+to free the memory. No change in the prototype for the existing API,
+ieee80211_beacon_get_template(), which should be used for non-EMA AP.
+
+- ieee80211_beacon_get_template_ema_index() - Generate a beacon which
+includes the multiple BSSID element at the given index. Drivers can use
+this function in a loop until NULL is returned which indicates end of
+available MBSSID elements.
+
+- ieee80211_beacon_free_ema_list() - free the memory allocated for the
+list of EMA beacon templates.
+
+Modify existing functions ieee80211_beacon_get_ap(),
+ieee80211_get_mbssid_beacon_len() and ieee80211_beacon_add_mbssid()
+to accept a new parameter for EMA index.
+
+Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
+Co-developed-by: John Crispin <john@phrozen.org>
+Signed-off-by: John Crispin <john@phrozen.org>
+Link: https://lore.kernel.org/r/20221206005040.3177-2-quic_alokad@quicinc.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+ include/net/mac80211.h | 68 +++++++++++++++++++
+ net/mac80211/cfg.c | 11 +--
+ net/mac80211/ieee80211_i.h | 10 ++-
+ net/mac80211/tx.c | 134 ++++++++++++++++++++++++++++++++++---
+ 4 files changed, 205 insertions(+), 18 deletions(-)
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -5252,6 +5252,74 @@ ieee80211_beacon_get_template(struct iee
+ unsigned int link_id);
+
+ /**
++ * ieee80211_beacon_get_template_ema_index - EMA beacon template generation
++ * @hw: pointer obtained from ieee80211_alloc_hw().
++ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
++ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will
++ * receive the offsets that may be updated by the driver.
++ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP).
++ * @ema_index: index of the beacon in the EMA set.
++ *
++ * This function follows the same rules as ieee80211_beacon_get_template()
++ * but returns a beacon template which includes multiple BSSID element at the
++ * requested index.
++ *
++ * Return: The beacon template. %NULL indicates the end of EMA templates.
++ */
++struct sk_buff *
++ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_mutable_offsets *offs,
++ unsigned int link_id, u8 ema_index);
++
++/**
++ * struct ieee80211_ema_beacons - List of EMA beacons
++ * @cnt: count of EMA beacons.
++ *
++ * @bcn: array of EMA beacons.
++ * @bcn.skb: the skb containing this specific beacon
++ * @bcn.offs: &struct ieee80211_mutable_offsets pointer to struct that will
++ * receive the offsets that may be updated by the driver.
++ */
++struct ieee80211_ema_beacons {
++ u8 cnt;
++ struct {
++ struct sk_buff *skb;
++ struct ieee80211_mutable_offsets offs;
++ } bcn[];
++};
++
++/**
++ * ieee80211_beacon_get_template_ema_list - EMA beacon template generation
++ * @hw: pointer obtained from ieee80211_alloc_hw().
++ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
++ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP)
++ *
++ * This function follows the same rules as ieee80211_beacon_get_template()
++ * but allocates and returns a pointer to list of all beacon templates required
++ * to cover all profiles in the multiple BSSID set. Each template includes only
++ * one multiple BSSID element.
++ *
++ * Driver must call ieee80211_beacon_free_ema_list() to free the memory.
++ *
++ * Return: EMA beacon templates of type struct ieee80211_ema_beacons *.
++ * %NULL on error.
++ */
++struct ieee80211_ema_beacons *
++ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ unsigned int link_id);
++
++/**
++ * ieee80211_beacon_free_ema_list - free an EMA beacon template list
++ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons pointers.
++ *
++ * This function will free a list previously acquired by calling
++ * ieee80211_beacon_get_template_ema_list()
++ */
++void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons);
++
++/**
+ * ieee80211_beacon_get_tim - beacon generation function
+ * @hw: pointer obtained from ieee80211_alloc_hw().
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1122,11 +1122,11 @@ static int ieee80211_assign_beacon(struc
+ if (params->mbssid_ies) {
+ mbssid = params->mbssid_ies;
+ size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
+- size += ieee80211_get_mbssid_beacon_len(mbssid);
++ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt);
+ } else if (old && old->mbssid_ies) {
+ mbssid = old->mbssid_ies;
+ size += struct_size(new->mbssid_ies, elem, mbssid->cnt);
+- size += ieee80211_get_mbssid_beacon_len(mbssid);
++ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt);
+ }
+
+ new = kzalloc(size, GFP_KERNEL);
+@@ -3384,8 +3384,11 @@ cfg80211_beacon_dup(struct cfg80211_beac
+
+ len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len +
+ beacon->proberesp_ies_len + beacon->assocresp_ies_len +
+- beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len +
+- ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
++ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len;
++
++ if (beacon->mbssid_ies)
++ len += ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
++ beacon->mbssid_ies->cnt);
+
+ new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL);
+ if (!new_beacon)
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1182,13 +1182,17 @@ ieee80211_vif_get_shift(struct ieee80211
+ }
+
+ static inline int
+-ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems)
++ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, u8 i)
+ {
+- int i, len = 0;
++ int len = 0;
+
+- if (!elems)
++ if (!elems || !elems->cnt || i > elems->cnt)
+ return 0;
+
++ if (i < elems->cnt)
++ return elems->elem[i].len;
++
++ /* i == elems->cnt, calculate total length of all MBSSID elements */
+ for (i = 0; i < elems->cnt; i++)
+ len += elems->elem[i].len;
+
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -5205,13 +5205,20 @@ ieee80211_beacon_get_finish(struct ieee8
+ }
+
+ static void
+-ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon)
++ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon,
++ u8 i)
+ {
+- int i;
++ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt ||
++ i > beacon->mbssid_ies->cnt)
++ return;
+
+- if (!beacon->mbssid_ies)
++ if (i < beacon->mbssid_ies->cnt) {
++ skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
++ beacon->mbssid_ies->elem[i].len);
+ return;
++ }
+
++ /* i == beacon->mbssid_ies->cnt, include all MBSSID elements */
+ for (i = 0; i < beacon->mbssid_ies->cnt; i++)
+ skb_put_data(skb, beacon->mbssid_ies->elem[i].data,
+ beacon->mbssid_ies->elem[i].len);
+@@ -5224,7 +5231,8 @@ ieee80211_beacon_get_ap(struct ieee80211
+ struct ieee80211_mutable_offsets *offs,
+ bool is_template,
+ struct beacon_data *beacon,
+- struct ieee80211_chanctx_conf *chanctx_conf)
++ struct ieee80211_chanctx_conf *chanctx_conf,
++ u8 ema_index)
+ {
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+@@ -5243,7 +5251,9 @@ ieee80211_beacon_get_ap(struct ieee80211
+ /* headroom, head length,
+ * tail length, maximum TIM length and multiple BSSID length
+ */
+- mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies);
++ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies,
++ ema_index);
++
+ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
+ beacon->tail_len + 256 +
+ local->hw.extra_beacon_tailroom + mbssid_len);
+@@ -5261,7 +5271,7 @@ ieee80211_beacon_get_ap(struct ieee80211
+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
+
+ if (mbssid_len) {
+- ieee80211_beacon_add_mbssid(skb, beacon);
++ ieee80211_beacon_add_mbssid(skb, beacon, ema_index);
+ offs->mbssid_off = skb->len - mbssid_len;
+ }
+
+@@ -5280,12 +5290,51 @@ ieee80211_beacon_get_ap(struct ieee80211
+ return skb;
+ }
+
++static struct ieee80211_ema_beacons *
++ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_link_data *link,
++ struct ieee80211_mutable_offsets *offs,
++ bool is_template, struct beacon_data *beacon,
++ struct ieee80211_chanctx_conf *chanctx_conf)
++{
++ struct ieee80211_ema_beacons *ema = NULL;
++
++ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt)
++ return NULL;
++
++ ema = kzalloc(struct_size(ema, bcn, beacon->mbssid_ies->cnt),
++ GFP_ATOMIC);
++ if (!ema)
++ return NULL;
++
++ for (ema->cnt = 0; ema->cnt < beacon->mbssid_ies->cnt; ema->cnt++) {
++ ema->bcn[ema->cnt].skb =
++ ieee80211_beacon_get_ap(hw, vif, link,
++ &ema->bcn[ema->cnt].offs,
++ is_template, beacon,
++ chanctx_conf, ema->cnt);
++ if (!ema->bcn[ema->cnt].skb)
++ break;
++ }
++
++ if (ema->cnt == beacon->mbssid_ies->cnt)
++ return ema;
++
++ ieee80211_beacon_free_ema_list(ema);
++ return NULL;
++}
++
++#define IEEE80211_INCLUDE_ALL_MBSSID_ELEMS -1
++
+ static struct sk_buff *
+ __ieee80211_beacon_get(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_mutable_offsets *offs,
+ bool is_template,
+- unsigned int link_id)
++ unsigned int link_id,
++ int ema_index,
++ struct ieee80211_ema_beacons **ema_beacons)
+ {
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct beacon_data *beacon = NULL;
+@@ -5314,8 +5363,29 @@ __ieee80211_beacon_get(struct ieee80211_
+ if (!beacon)
+ goto out;
+
+- skb = ieee80211_beacon_get_ap(hw, vif, link, offs, is_template,
+- beacon, chanctx_conf);
++ if (ema_beacons) {
++ *ema_beacons =
++ ieee80211_beacon_get_ap_ema_list(hw, vif, link,
++ offs,
++ is_template,
++ beacon,
++ chanctx_conf);
++ } else {
++ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) {
++ if (ema_index >= beacon->mbssid_ies->cnt)
++ goto out; /* End of MBSSID elements */
++
++ if (ema_index <= IEEE80211_INCLUDE_ALL_MBSSID_ELEMS)
++ ema_index = beacon->mbssid_ies->cnt;
++ } else {
++ ema_index = 0;
++ }
++
++ skb = ieee80211_beacon_get_ap(hw, vif, link, offs,
++ is_template, beacon,
++ chanctx_conf,
++ ema_index);
++ }
+ } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+ struct ieee80211_hdr *hdr;
+@@ -5403,10 +5473,50 @@ ieee80211_beacon_get_template(struct iee
+ struct ieee80211_mutable_offsets *offs,
+ unsigned int link_id)
+ {
+- return __ieee80211_beacon_get(hw, vif, offs, true, link_id);
++ return __ieee80211_beacon_get(hw, vif, offs, true, link_id,
++ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, NULL);
+ }
+ EXPORT_SYMBOL(ieee80211_beacon_get_template);
+
++struct sk_buff *
++ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_mutable_offsets *offs,
++ unsigned int link_id, u8 ema_index)
++{
++ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, ema_index,
++ NULL);
++}
++EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index);
++
++void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons)
++{
++ u8 i;
++
++ if (!ema_beacons)
++ return;
++
++ for (i = 0; i < ema_beacons->cnt; i++)
++ kfree_skb(ema_beacons->bcn[i].skb);
++
++ kfree(ema_beacons);
++}
++EXPORT_SYMBOL(ieee80211_beacon_free_ema_list);
++
++struct ieee80211_ema_beacons *
++ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ unsigned int link_id)
++{
++ struct ieee80211_ema_beacons *ema_beacons = NULL;
++
++ WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, false, link_id, 0,
++ &ema_beacons));
++
++ return ema_beacons;
++}
++EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list);
++
+ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ u16 *tim_offset, u16 *tim_length,
+@@ -5414,7 +5524,9 @@ struct sk_buff *ieee80211_beacon_get_tim
+ {
+ struct ieee80211_mutable_offsets offs = {};
+ struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false,
+- link_id);
++ link_id,
++ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS,
++ NULL);
+ struct sk_buff *copy;
+ int shift;
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/500-mac80211_configure_antenna_gain.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/500-mac80211_configure_antenna_gain.patch
index b1e84e2..4a3984f 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/500-mac80211_configure_antenna_gain.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/500-mac80211_configure_antenna_gain.patch
@@ -77,7 +77,7 @@
static void ieee80211_rfkill_poll(struct wiphy *wiphy)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
-@@ -4953,6 +4966,7 @@ const struct cfg80211_ops mac80211_confi
+@@ -4956,6 +4969,7 @@ const struct cfg80211_ops mac80211_confi
.set_wiphy_params = ieee80211_set_wiphy_params,
.set_tx_power = ieee80211_set_tx_power,
.get_tx_power = ieee80211_get_tx_power,
@@ -87,7 +87,7 @@
CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
-@@ -1538,6 +1538,7 @@ struct ieee80211_local {
+@@ -1542,6 +1542,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
new file mode 100644
index 0000000..c0f4c01
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
@@ -0,0 +1,59 @@
+From 7097dfcbf442fde86cfb34f8e91fb5c0e6546630 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Tue, 29 Mar 2022 16:06:30 +0800
+Subject: [PATCH] cfg80211: mtk: extend CAC time for weather radar channels
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h | 1 +
+ net/wireless/chan.c | 6 ++++++
+ net/wireless/nl80211.c | 3 +++
+ 3 files changed, 10 insertions(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 8d72357..a6bf255 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -149,6 +149,7 @@ enum ieee80211_channel_flags {
+ (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+
+ #define IEEE80211_DFS_MIN_CAC_TIME_MS 60000
++#define IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS 600000
+ #define IEEE80211_DFS_MIN_NOP_TIME_MS (30 * 60 * 1000)
+
+ /**
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index d5ed976..fef0ba5 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -931,6 +931,12 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
+ if (!(c->flags & IEEE80211_CHAN_RADAR))
+ continue;
+
++ /* weather radar in ETSI */
++ if (reg_get_dfs_region(wiphy) == NL80211_DFS_ETSI &&
++ freq >= MHZ_TO_KHZ(5590) && freq <= MHZ_TO_KHZ(5650) &&
++ dfs_cac_ms < IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS)
++ dfs_cac_ms = IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS;
++
+ if (c->dfs_cac_ms > dfs_cac_ms)
+ dfs_cac_ms = c->dfs_cac_ms;
+ }
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index f3b2fc4..215a603 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -9817,6 +9817,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ if (WARN_ON(!cac_time_ms))
+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+
++ pr_info("%s: region = %u, center freq1 = %u, center freq2 = %u, cac time ms = %u\n",
++ __func__, dfs_region, chandef.center_freq1, chandef.center_freq2, cac_time_ms);
++
+ err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
+ if (!err) {
+ wdev->links[0].ap.chandef = chandef;
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch
deleted file mode 100644
index cfd0e09..0000000
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From dacd08119ef3964c826d1949b35c5b926b40eb2b Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 29 Mar 2022 16:06:30 +0800
-Subject: [PATCH 02/14] nl80211: mtk: extend CAC time for weather radar
- channels
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- net/wireless/nl80211.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index f3b2fc4..0430bbe 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -9817,6 +9817,13 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- if (WARN_ON(!cac_time_ms))
- cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
-
-+ if ((dfs_region == NL80211_DFS_ETSI) &&
-+ (((chandef.width == NL80211_CHAN_WIDTH_160) &&
-+ (chandef.center_freq2 >= 5580 && chandef.center_freq2 <= 5640)) ||
-+ (chandef.center_freq1 >= 5580 && chandef.center_freq1 <= 5640)))
-+ cac_time_ms = 600000;
-+ pr_info("%s: region = %u, cetner freq1 = %u, center freq2 = %u, cac time ms = %u\n", __func__, dfs_region, chandef.center_freq1, chandef.center_freq2, cac_time_ms);
-+
- err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
- if (!err) {
- wdev->links[0].ap.chandef = chandef;
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mac80211-support-configurable-addba-resp-time.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mac80211-support-configurable-addba-resp-time.patch
new file mode 100644
index 0000000..759d36b
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0015-mac80211-support-configurable-addba-resp-time.patch
@@ -0,0 +1,42 @@
+From 0236a4a01f3f3ed932ab326de0deef6911519dab Mon Sep 17 00:00:00 2001
+From: Lian Chen <lian.chen@mediatek.com>
+Date: Wed, 7 Jun 2023 15:30:34 +0800
+Subject: [PATCH] support configurable addba resp time.
+
+---
+ net/mac80211/agg-tx.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
+index 6992c1f..ad0c0d6 100644
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -16,10 +16,16 @@
+ #include <linux/slab.h>
+ #include <linux/export.h>
+ #include <net/mac80211.h>
++#include <linux/moduleparam.h>
+ #include "ieee80211_i.h"
+ #include "driver-ops.h"
+ #include "wme.h"
+
++static int addba_resp_wait_count = 2;
++module_param(addba_resp_wait_count, int, 0644);
++MODULE_PARM_DESC(addba_resp_wait_count,
++ "Number of ADDBA_RESP_INTERVAL to wait for addba response");
++
+ /**
+ * DOC: TX A-MPDU aggregation
+ *
+@@ -460,7 +466,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
+ u16 buf_size;
+
+ /* activate the timer for the recipient's addBA response */
+- mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
++ mod_timer(&tid_tx->addba_resp_timer, jiffies + addba_resp_wait_count * ADDBA_RESP_INTERVAL);
+ ht_dbg(sdata, "activated addBA response timer on %pM tid %d\n",
+ sta->sta.addr, tid);
+
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch
new file mode 100644
index 0000000..f14111c
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch
@@ -0,0 +1,180 @@
+From e545285e24de95d0d620bb7e9c97abba39e363b9 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Mon, 20 Feb 2023 14:25:24 +0800
+Subject: [PATCH] mac80211: mtk: add sta-assisted DFS state update mechanism
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h | 14 +++++++++
+ include/uapi/linux/nl80211.h | 6 ++++
+ net/mac80211/mlme.c | 12 ++++++++
+ net/wireless/chan.c | 60 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 92 insertions(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 84564bd..06d1567 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -8180,6 +8180,20 @@ void cfg80211_cac_event(struct net_device *netdev,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_radar_event event, gfp_t gfp);
+
++/**
++ * cfg80211_sta_update_dfs_state - Update channel's DFS state during STA channel switch,
++ * association, and disassociation
++ * @wdev: the wireless device
++ * @bss_chandef: the current BSS channel definition
++ * @csa_chandef: the CSA channel definition
++ * @associated: whether STA is during association or disassociation process
++ *
++ */
++void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
++ const struct cfg80211_chan_def *bss_chandef,
++ const struct cfg80211_chan_def *csa_chandef,
++ bool associated);
++
+ /**
+ * cfg80211_background_cac_abort - Channel Availability Check offchan abort event
+ * @wiphy: the wiphy
+diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
+index bd26a06..e453d64 100644
+--- a/include/uapi/linux/nl80211.h
++++ b/include/uapi/linux/nl80211.h
+@@ -6565,6 +6565,10 @@ enum nl80211_smps_mode {
+ * applicable for ETSI dfs domain where pre-CAC is valid for ever.
+ * @NL80211_RADAR_CAC_STARTED: Channel Availability Check has been started,
+ * should be generated by HW if NL80211_EXT_FEATURE_DFS_OFFLOAD is enabled.
++ * @NL80211_RADAR_STA_CAC_SKIPPED: STA set the DFS state to available
++ * when receiving CSA/assoc resp
++ * @NL80211_RADAR_STA_CAC_EXPIRED: STA set the DFS state to usable
++ * when STA is disconnected or leaving the channel
+ */
+ enum nl80211_radar_event {
+ NL80211_RADAR_DETECTED,
+@@ -6573,6 +6577,8 @@ enum nl80211_radar_event {
+ NL80211_RADAR_NOP_FINISHED,
+ NL80211_RADAR_PRE_CAC_EXPIRED,
+ NL80211_RADAR_CAC_STARTED,
++ NL80211_RADAR_STA_CAC_SKIPPED,
++ NL80211_RADAR_STA_CAC_EXPIRED,
+ };
+
+ /**
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 72d153f..5a3dd31 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -1987,6 +1987,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
+ mutex_unlock(&local->mtx);
+
++ cfg80211_sta_update_dfs_state(&sdata->wdev,
++ &sdata->vif.bss_conf.chandef,
++ &link->csa_chandef,
++ sdata->vif.cfg.assoc);
++
+ cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef, 0,
+ csa_ie.count, csa_ie.mode, 0);
+
+@@ -3072,6 +3077,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
+ sizeof(sdata->vif.bss_conf.tx_pwr_env));
+
+ ieee80211_vif_set_links(sdata, 0);
++
++ cfg80211_sta_update_dfs_state(&sdata->wdev,
++ &sdata->vif.bss_conf.chandef,
++ NULL, sdata->vif.cfg.assoc);
+ }
+
+ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
+@@ -5276,6 +5285,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ event.u.mlme.status = MLME_SUCCESS;
+ drv_event_callback(sdata->local, sdata, &event);
+ sdata_info(sdata, "associated\n");
++ cfg80211_sta_update_dfs_state(&sdata->wdev,
++ &sdata->vif.bss_conf.chandef,
++ NULL, sdata->vif.cfg.assoc);
+
+ info.success = 1;
+ }
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index fef0ba5..13276bc 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -14,6 +14,7 @@
+ #include <net/cfg80211.h>
+ #include "core.h"
+ #include "rdev-ops.h"
++#include "nl80211.h"
+
+ static bool cfg80211_valid_60g_freq(u32 freq)
+ {
+@@ -1436,6 +1437,65 @@ bool cfg80211_any_usable_channels(struct wiphy *wiphy,
+ }
+ EXPORT_SYMBOL(cfg80211_any_usable_channels);
+
++static void cfg80211_sta_radar_notify(struct wiphy *wiphy,
++ const struct cfg80211_chan_def *chandef,
++ enum nl80211_radar_event event)
++{
++ struct wireless_dev *wdev;
++
++ list_for_each_entry(wdev, &wiphy->wdev_list, list) {
++ if (cfg80211_chandef_dfs_required(wiphy, chandef, wdev->iftype) > 0) {
++ nl80211_radar_notify(wiphy_to_rdev(wiphy), chandef,
++ event, wdev->netdev, GFP_KERNEL);
++ return;
++ }
++ }
++}
++
++void cfg80211_sta_update_dfs_state(struct wireless_dev *wdev,
++ const struct cfg80211_chan_def *bss_chandef,
++ const struct cfg80211_chan_def *csa_chandef,
++ bool associated)
++{
++ bool csa_active = !!csa_chandef;
++ enum nl80211_dfs_state dfs_state = NL80211_DFS_USABLE;
++ enum nl80211_radar_event event = NL80211_RADAR_STA_CAC_EXPIRED;
++
++ if (!bss_chandef)
++ return;
++
++ /* assume csa channel is cac completed */
++ if (csa_active &&
++ (cfg80211_chandef_dfs_usable(wdev->wiphy, csa_chandef) ||
++ cfg80211_chandef_dfs_available(wdev->wiphy, csa_chandef))) {
++ cfg80211_set_dfs_state(wdev->wiphy, csa_chandef, NL80211_DFS_AVAILABLE);
++ cfg80211_sta_radar_notify(wdev->wiphy, csa_chandef,
++ NL80211_RADAR_STA_CAC_SKIPPED);
++ netdev_info(wdev->netdev, "Set CSA channel's DFS state to available\n");
++ }
++
++ /* avoid updating the dfs state during nop */
++ if (!cfg80211_chandef_dfs_usable(wdev->wiphy, bss_chandef) &&
++ !cfg80211_chandef_dfs_available(wdev->wiphy, bss_chandef))
++ return;
++
++ if (associated && !csa_active) {
++ dfs_state = NL80211_DFS_AVAILABLE;
++ event = NL80211_RADAR_STA_CAC_SKIPPED;
++ }
++
++ cfg80211_set_dfs_state(wdev->wiphy, bss_chandef, dfs_state);
++ cfg80211_sta_radar_notify(wdev->wiphy, bss_chandef, event);
++
++ if (csa_active)
++ netdev_info(wdev->netdev, "Set origin channel's DFS state to usable\n");
++ else
++ netdev_info(wdev->netdev, "Set BSS channel's DFS state to %s due to %s\n",
++ (dfs_state == NL80211_DFS_USABLE) ? "usable" : "available",
++ associated ? "association" : "disassociation");
++}
++EXPORT_SYMBOL(cfg80211_sta_update_dfs_state);
++
+ struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev,
+ unsigned int link_id)
+ {
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch
new file mode 100644
index 0000000..cdc6290
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch
@@ -0,0 +1,28 @@
+From 4c78e6469da8de9c4584d029231938063545b031 Mon Sep 17 00:00:00 2001
+From: "himanshu.goyal" <himanshu.goyal@mediatek.com>
+Date: Fri, 17 Mar 2023 17:36:01 +0800
+Subject: [PATCH] nl80211: mtk: Mark DFS channel as available for CSA.
+
+---
+ net/wireless/nl80211.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index af43c22..53f32c6 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -10079,6 +10079,11 @@ skip_beacons:
+ if (err)
+ goto free;
+
++ /* Use RADAR_BACKGROUND attribute here for skipping CAC */
++ if (info->attrs[NL80211_ATTR_RADAR_BACKGROUND]) {
++ cfg80211_set_dfs_state(&rdev->wiphy, ¶ms.chandef, NL80211_DFS_AVAILABLE);
++ }
++
+ if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, ¶ms.chandef,
+ wdev->iftype)) {
+ err = -EINVAL;
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0100-mac80211-mtk-add-EHT-BA1024-support.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch
similarity index 92%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0100-mac80211-mtk-add-EHT-BA1024-support.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch
index 5493895..fe7b1af 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0100-mac80211-mtk-add-EHT-BA1024-support.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch
@@ -1,7 +1,7 @@
-From 21b39d41faf3a67127778d85a79029002ed65291 Mon Sep 17 00:00:00 2001
+From 5a82834ed7eb4cbf0f4f5abc8665eeef023b67ff Mon Sep 17 00:00:00 2001
From: MeiChia Chiu <meichia.chiu@mediatek.com>
Date: Sun, 25 Dec 2022 22:43:46 +0800
-Subject: [PATCH 100/102] mac80211: mtk: add EHT BA1024 support
+Subject: [PATCH 1000/1003] mac80211: mtk: add EHT BA1024 support
---
include/linux/ieee80211.h | 2 ++
@@ -9,10 +9,10 @@
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
-index 6f70394..27321f2 100644
+index 00d381e..0781b76 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
-@@ -1270,6 +1270,8 @@ struct ieee80211_mgmt {
+@@ -1256,6 +1256,8 @@ struct ieee80211_mgmt {
__le16 status;
__le16 capab;
__le16 timeout;
@@ -22,7 +22,7 @@
struct{
u8 action_code;
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-index 56cd1fc..8daf292 100644
+index 752ad09..7f0e72a 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -66,10 +66,17 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
@@ -73,7 +73,7 @@
} else {
/*
* We really should use what the driver told us it will
-@@ -978,13 +997,35 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
+@@ -980,13 +999,35 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
{
struct tid_ampdu_tx *tid_tx;
struct ieee80211_txq *txq;
@@ -110,5 +110,5 @@
txq = sta->sta.txq[tid];
--
-2.18.0
+2.39.2
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0101-mac80211-mtk-add-rate-duration-for-EHT-rate.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
similarity index 98%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0101-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
index 27ed002..f20cb61 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0101-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch
@@ -1,7 +1,7 @@
-From a1d426d8bb909612b66c31d450fd717177862d2f Mon Sep 17 00:00:00 2001
+From 857debd24af093da4e85f148767fd16fb9eaf975 Mon Sep 17 00:00:00 2001
From: Bo Jiao <Bo.Jiao@mediatek.com>
Date: Sun, 25 Dec 2022 22:43:46 +0800
-Subject: [PATCH 101/102] mac80211: mtk: add rate duration for EHT rate.
+Subject: [PATCH 1001/1003] mac80211: mtk: add rate duration for EHT rate.
---
net/mac80211/airtime.c | 349 ++++++++++++++++++++++++++++++++++++++++-
@@ -436,5 +436,5 @@
if (stat->encoding != RX_ENC_LEGACY)
return true;
--
-2.18.0
+2.39.2
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0103-mac80211-mtk-add-send-bar-on-addbarsp_handle.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
similarity index 68%
rename from recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0103-mac80211-mtk-add-send-bar-on-addbarsp_handle.patch
rename to recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
index 054d623..099071c 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-0103-mac80211-mtk-add-send-bar-on-addbarsp_handle.patch
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch
@@ -1,21 +1,19 @@
-From 64b7f68018adbbbe33c6edb602c05dc19f8c5ea8 Mon Sep 17 00:00:00 2001
+From a9b8e0e62b19fbd7c1dd865330ceb5a943e5cbb2 Mon Sep 17 00:00:00 2001
From: ye he <ye.he@mediatek.com>
Date: Wed, 22 Feb 2023 16:09:32 +0800
-Subject: [PATCH] add send bar action when recieve addba rsp
+Subject: [PATCH 1002/1003] mac80211: mtk: add send bar action when recieve
+ addba rsp
Signed-off-by: ye he <ye.he@mediatek.com>
---
net/mac80211/agg-tx.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
- mode change 100755 => 100644 net/mac80211/agg-tx.c
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
-old mode 100755
-new mode 100644
-index 7f750c1..4292258
+index 7f0e72a..3ce2226 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
-@@ -1060,7 +1060,8 @@ next:
+@@ -1080,7 +1080,8 @@ next:
tid_tx->buf_size = buf_size;
tid_tx->amsdu = amsdu;
@@ -26,5 +24,5 @@
ieee80211_agg_tx_operational(local, sta, tid);
--
-2.18.0
+2.39.2
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch
new file mode 100644
index 0000000..1def860
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch
@@ -0,0 +1,33 @@
+From 8175f5cdf45728cdfcf34893696f994c6f1e6cc1 Mon Sep 17 00:00:00 2001
+From: Amit Khatri <amit.khatri@mediatek.com>
+Date: Thu, 6 Apr 2023 21:37:33 +0800
+Subject: [PATCH 1003/1003] mac80211: mtk: inrease beacon loss count
+
+as per eagle code beacone loss time out is
+4 seconds.
+in 2G connection getting beacon loss logs in routed client
+scenario.
+
+so increasing beacon loss count from 7 to 20
+
+Signed-off-by: Amit Khatri <amit.khatri@mediatek.com>
+---
+ net/mac80211/mlme.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 72d153f..458609c 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -61,7 +61,7 @@ MODULE_PARM_DESC(max_probe_tries,
+ * probe on beacon miss before declaring the connection lost
+ * default to what we want.
+ */
+-static int beacon_loss_count = 7;
++static int beacon_loss_count = 20;
+ module_param(beacon_loss_count, int, 0644);
+ MODULE_PARM_DESC(beacon_loss_count,
+ "Number of beacon intervals before we decide beacon was lost.");
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch
new file mode 100644
index 0000000..c8fc398
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch
@@ -0,0 +1,24 @@
+From 79837bcb22a80a4c95cbba77b23f16352d4e791d Mon Sep 17 00:00:00 2001
+From: Michael Lee <michael-cy.lee@mediatek.com>
+Date: Mon, 24 Apr 2023 09:59:24 +0800
+Subject: [PATCH] mac80211: mtk: add disabling cca when stopping AP.
+
+---
+ net/mac80211/cfg.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 343ce2b..611c29e 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1540,6 +1540,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
+ /* abort any running channel switch */
+ mutex_lock(&local->mtx);
+ link_conf->csa_active = false;
++ link_conf->color_change_active = false;
+ if (link->csa_block_tx) {
+ ieee80211_wake_vif_queues(local, sdata,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
+--
+2.25.1
+
diff --git a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc
index 9da26b5..cea85f7 100644
--- a/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc
+++ b/recipes-wifi/linux-mac80211/files/patches-6.x/subsys/subsys.inc
@@ -36,6 +36,7 @@
file://333-wifi-mac80211-add-flush_sta-method.patch \
file://334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch \
file://335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch \
+ file://336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch \
file://400-allow-ibss-mixed.patch \
file://500-mac80211_configure_antenna_gain.patch \
file://782-net-next-1-of-net-pass-the-dst-buffer-to-of_get_mac_address.patch \
@@ -49,7 +50,7 @@
file://bp-0008-wifi-mac80211-configure-puncturing-bitmap.patch \
file://bp-0009-wifi-mac80211-add-EHT-MU-MIMO-related-flags-in-ieee8.patch \
file://mtk-0001-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch \
- file://mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch \
+ file://mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch \
file://mtk-0003-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch \
file://mtk-0004-mac80211-mtk-airtime_flags-depends-on-NL80211_EXT_FE.patch \
file://mtk-0005-mac80211-mtk-add-support-for-runtime-set-inband-disc.patch \
@@ -62,7 +63,12 @@
file://mtk-0012-mac80211-mtk-track-obss-color-bitmap.patch \
file://mtk-0013-mac80211-mtk-ageout-color-bitmap.patch \
file://mtk-0014-mac80211-mtk-update-max_bssid_indicator-based-on-rea.patch \
- file://mtk-0100-mac80211-mtk-add-EHT-BA1024-support.patch \
- file://mtk-0101-mac80211-mtk-add-rate-duration-for-EHT-rate.patch \
- file://mtk-0103-mac80211-mtk-add-send-bar-on-addbarsp_handle.patch \
+ file://mtk-0015-mac80211-support-configurable-addba-resp-time.patch \
+ file://mtk-0016-mac80211-mtk-add-sta-assisted-DFS-state-update-mecha.patch \
+ file://mtk-0017-nl80211-mtk-Mark-DFS-channel-as-available-for-CSA.patch \
+ file://mtk-1000-mac80211-mtk-add-EHT-BA1024-support.patch \
+ file://mtk-1001-mac80211-mtk-add-rate-duration-for-EHT-rate.patch \
+ file://mtk-1002-mac80211-mtk-add-send-bar-action-when-recieve-addba-.patch \
+ file://mtk-1003-mac80211-mtk-inrease-beacon-loss-count.patch \
+ file://mtk-1004-mac80211-mtk-add-disabling-cca-when-stopping-AP.patch \
"
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
new file mode 100644
index 0000000..f5b52c4
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch
@@ -0,0 +1,59 @@
+From b6a99ac9380eb282d251a349709483579186bc51 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Tue, 29 Mar 2022 16:06:30 +0800
+Subject: [PATCH] cfg80211: mtk: extend CAC time for weather radar channels
+
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ include/net/cfg80211.h | 1 +
+ net/wireless/chan.c | 6 ++++++
+ net/wireless/nl80211.c | 3 +++
+ 3 files changed, 10 insertions(+)
+
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index 8e05f55..585d934 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -142,6 +142,7 @@ enum ieee80211_channel_flags {
+ (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+
+ #define IEEE80211_DFS_MIN_CAC_TIME_MS 60000
++#define IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS 600000
+ #define IEEE80211_DFS_MIN_NOP_TIME_MS (30 * 60 * 1000)
+
+ /**
+diff --git a/net/wireless/chan.c b/net/wireless/chan.c
+index 5f50ac4..6b42040 100644
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -843,6 +843,12 @@ static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
+ if (!(c->flags & IEEE80211_CHAN_RADAR))
+ continue;
+
++ /* weather radar in ETSI */
++ if (reg_get_dfs_region(wiphy) == NL80211_DFS_ETSI &&
++ freq >= MHZ_TO_KHZ(5590) && freq <= MHZ_TO_KHZ(5650) &&
++ dfs_cac_ms < IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS)
++ dfs_cac_ms = IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS;
++
+ if (c->dfs_cac_ms > dfs_cac_ms)
+ dfs_cac_ms = c->dfs_cac_ms;
+ }
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index bc6b5ac..bc07fe8 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -9354,6 +9354,9 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
+ if (WARN_ON(!cac_time_ms))
+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+
++ pr_info("%s: region = %u, center freq1 = %u, center freq2 = %u, cac time ms = %u\n",
++ __func__, dfs_region, chandef.center_freq1, chandef.center_freq2, cac_time_ms);
++
+ err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
+ if (!err) {
+ wdev->chandef = chandef;
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch
deleted file mode 100644
index e281cdd..0000000
--- a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 90338d1909357f0fac0ec1f0ead5f4a9b47524b9 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Tue, 29 Mar 2022 16:06:30 +0800
-Subject: [PATCH 02/17] nl80211: mtk: extend CAC time for weather radar
- channels
-
-Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
----
- net/wireless/nl80211.c | 7 +++++++
- 1 file changed, 7 insertions(+)
-
-diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
-index bc6b5ac..3c6c1df 100644
---- a/net/wireless/nl80211.c
-+++ b/net/wireless/nl80211.c
-@@ -9354,6 +9354,13 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
- if (WARN_ON(!cac_time_ms))
- cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
-
-+ if ((dfs_region == NL80211_DFS_ETSI) &&
-+ (((chandef.width == NL80211_CHAN_WIDTH_160) &&
-+ (chandef.center_freq2 >= 5580 && chandef.center_freq2 <= 5640)) ||
-+ (chandef.center_freq1 >= 5580 && chandef.center_freq1 <= 5640)))
-+ cac_time_ms = 600000;
-+ pr_info("%s: region = %u, cetner freq1 = %u, center freq2 = %u, cac time ms = %u\n", __func__, dfs_region, chandef.center_freq1, chandef.center_freq2, cac_time_ms);
-+
- err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
- if (!err) {
- wdev->chandef = chandef;
---
-2.18.0
-
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0018-mac80211-support-configurable-addba-resp-time.patch b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0018-mac80211-support-configurable-addba-resp-time.patch
new file mode 100644
index 0000000..759d36b
--- /dev/null
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/mtk-0018-mac80211-support-configurable-addba-resp-time.patch
@@ -0,0 +1,42 @@
+From 0236a4a01f3f3ed932ab326de0deef6911519dab Mon Sep 17 00:00:00 2001
+From: Lian Chen <lian.chen@mediatek.com>
+Date: Wed, 7 Jun 2023 15:30:34 +0800
+Subject: [PATCH] support configurable addba resp time.
+
+---
+ net/mac80211/agg-tx.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
+index 6992c1f..ad0c0d6 100644
+--- a/net/mac80211/agg-tx.c
++++ b/net/mac80211/agg-tx.c
+@@ -16,10 +16,16 @@
+ #include <linux/slab.h>
+ #include <linux/export.h>
+ #include <net/mac80211.h>
++#include <linux/moduleparam.h>
+ #include "ieee80211_i.h"
+ #include "driver-ops.h"
+ #include "wme.h"
+
++static int addba_resp_wait_count = 2;
++module_param(addba_resp_wait_count, int, 0644);
++MODULE_PARM_DESC(addba_resp_wait_count,
++ "Number of ADDBA_RESP_INTERVAL to wait for addba response");
++
+ /**
+ * DOC: TX A-MPDU aggregation
+ *
+@@ -460,7 +466,7 @@ static void ieee80211_send_addba_with_timeout(struct sta_info *sta,
+ u16 buf_size;
+
+ /* activate the timer for the recipient's addBA response */
+- mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL);
++ mod_timer(&tid_tx->addba_resp_timer, jiffies + addba_resp_wait_count * ADDBA_RESP_INTERVAL);
+ ht_dbg(sdata, "activated addBA response timer on %pM tid %d\n",
+ sta->sta.addr, tid);
+
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc b/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
index 3a7ae6b..fd7f151 100644
--- a/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
+++ b/recipes-wifi/linux-mac80211/files/patches/subsys/subsys.inc
@@ -56,7 +56,7 @@
file://783-sync-nl80211.patch \
file://800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch \
file://mtk-0001-mac80211-mtk-do-not-setup-twt-when-twt-responder-is-.patch \
- file://mtk-0002-nl80211-mtk-extend-CAC-time-for-weather-radar-channe.patch \
+ file://mtk-0002-cfg80211-mtk-extend-CAC-time-for-weather-radar-chann.patch \
file://mtk-0003-mac80211-mtk-it-s-invalid-case-when-frag_threshold-i.patch \
file://mtk-0004-mac80211-mtk-correct-legacy-rates-check-in-ieee80211.patch \
file://mtk-0005-mac80211-mtk-airtime_flags-depends-on-NL80211_EXT_FE.patch \
@@ -72,6 +72,7 @@
file://mtk-0015-mac80211-mtk-track-obss-color-bitmap.patch \
file://mtk-0016-mac80211-mtk-ageout-color-bitmap.patch \
file://mtk-0017-mac80211-mtk-update-max_bssid_indicator-based-on-rea.patch \
+ file://mtk-0018-mac80211-support-configurable-addba-resp-time.patch \
file://mtk-9900-mac80211-mtk-mask-kernel-version-limitation-and-fill.patch \
file://mtk-9901-mac80211-mtk-add-fill-receive-path-ops-to-get-wed-id.patch \
file://mtk-9902-mac80211-mtk-add-support-for-letting-drivers-registe.patch \
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch
index c927e1a..91d65d7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch
@@ -1,7 +1,7 @@
-From 31a7471ec1e183deafd9b28fd62cca3c25f79633 Mon Sep 17 00:00:00 2001
+From 15d734c77b25451efdf3bb1bcd5e687bc429a852 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Fri, 10 Feb 2023 17:39:23 +0800
-Subject: [PATCH 01/22] wifi: mt76: mt7996: add eht rx rate support
+Subject: [PATCH 01/11] wifi: mt76: mt7996: add eht rx rate support
Add support to report eht rx rate.
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-move-radio-enable-command-to-mt7996.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch
similarity index 77%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-move-radio-enable-command-to-mt7996.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch
index d723e62..8ab501f 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-mt7996-move-radio-enable-command-to-mt7996.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch
@@ -1,20 +1,19 @@
-From 61c13ad2aacdc077bc3729090702821d4777530a Mon Sep 17 00:00:00 2001
+From 83d30a89d61ee914b23d77256e993e9521de5cbc Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Wed, 15 Feb 2023 18:38:04 +0800
-Subject: [PATCH 03/22] wifi: mt76: mt7996: move radio enable command to
- mt7996_start()
+Subject: [PATCH 02/11] wifi: mt76: mt7996: move radio ctrl commands to proper
+ functions
-The radio enable and disable commands are used for per-phy radio, so
-move them into mt7996_start() and mt7996_stop(), respectively.
+Move radio enable/disable commands into functions for configuring
+per-phy radio.
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I610b170f5198e085eb86dbd371ee0745ac6ff50f
---
mt7996/main.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/mt7996/main.c b/mt7996/main.c
-index 136a0c28..28b63d44 100644
+index f306e9c5..e7c97d2f 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -43,6 +43,10 @@ int mt7996_run(struct ieee80211_hw *hw)
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch
new file mode 100644
index 0000000..4342d73
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch
@@ -0,0 +1,198 @@
+From 20c8d7bfeb91be51129e7e98213db441a62d6d95 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 31 May 2023 18:31:41 +0800
+Subject: [PATCH 03/11] wifi: mt76: connac: add support for dsp firmware
+ download
+
+Add FW_START_WORKING_PDA_DSP for the indication of starting DSP
+firmware download, which is for phy-related control.
+The firmware is transparent to the driver, but it's necessary for the
+firmware download process.
+
+Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Change-Id: I35666504cfe7bf213c8f8f0c0223b3089372f2ab
+---
+v2:
+ - merge two commits
+ - move main load ram code to a regular function
+v3:
+ - remove all macros to directly call __mt7996_load_ram()
+ - add back missing code which records fw_version to wiphy
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/mcu.c | 67 +++++++++++++++++++++++------------------------
+ mt7996/mt7996.h | 7 +++++
+ mt7996/pci.c | 1 +
+ 4 files changed, 42 insertions(+), 34 deletions(-)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 91d98eff..d2a3d56b 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -22,6 +22,7 @@
+
+ #define FW_START_OVERRIDE BIT(0)
+ #define FW_START_WORKING_PDA_CR4 BIT(2)
++#define FW_START_WORKING_PDA_DSP BIT(3)
+
+ #define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0)
+ #define PATCH_SEC_TYPE_MASK GENMASK(15, 0)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 88e2f9d0..545cc987 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2155,7 +2155,7 @@ out:
+ static int
+ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
+ const struct mt7996_fw_trailer *hdr,
+- const u8 *data, bool is_wa)
++ const u8 *data, enum mt7996_ram_type type)
+ {
+ int i, offset = 0;
+ u32 override = 0, option = 0;
+@@ -2167,8 +2167,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
+
+ region = (const struct mt7996_fw_region *)((const u8 *)hdr -
+ (hdr->n_region - i) * sizeof(*region));
++ /* DSP and WA use same mode */
+ mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
+- region->feature_set, is_wa);
++ region->feature_set,
++ type != MT7996_RAM_TYPE_WM);
+ len = le32_to_cpu(region->len);
+ addr = le32_to_cpu(region->addr);
+
+@@ -2195,19 +2197,22 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
+ if (override)
+ option |= FW_START_OVERRIDE;
+
+- if (is_wa)
++ if (type == MT7996_RAM_TYPE_WA)
+ option |= FW_START_WORKING_PDA_CR4;
++ else if (type == MT7996_RAM_TYPE_DSP)
++ option |= FW_START_WORKING_PDA_DSP;
+
+ return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
+ }
+
+-static int mt7996_load_ram(struct mt7996_dev *dev)
++static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
++ const char *fw_file, enum mt7996_ram_type ram_type)
+ {
+ const struct mt7996_fw_trailer *hdr;
+ const struct firmware *fw;
+ int ret;
+
+- ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev);
++ ret = request_firmware(&fw, fw_file, dev->mt76.dev);
+ if (ret)
+ return ret;
+
+@@ -2217,37 +2222,13 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+ goto out;
+ }
+
+- hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
+-
+- dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
+- hdr->fw_ver, hdr->build_date);
++ hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
++ dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n",
++ fw_type, hdr->fw_ver, hdr->build_date);
+
+- ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false);
++ ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, ram_type);
+ if (ret) {
+- dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
+- goto out;
+- }
+-
+- release_firmware(fw);
+-
+- ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev);
+- if (ret)
+- return ret;
+-
+- if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
+- dev_err(dev->mt76.dev, "Invalid firmware\n");
+- ret = -EINVAL;
+- goto out;
+- }
+-
+- hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
+-
+- dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
+- hdr->fw_ver, hdr->build_date);
+-
+- ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true);
+- if (ret) {
+- dev_err(dev->mt76.dev, "Failed to start WA firmware\n");
++ dev_err(dev->mt76.dev, "Failed to start %s firmware\n", fw_type);
+ goto out;
+ }
+
+@@ -2261,6 +2242,24 @@ out:
+ return ret;
+ }
+
++static int mt7996_load_ram(struct mt7996_dev *dev)
++{
++ int ret;
++
++ ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
++ MT7996_RAM_TYPE_WM);
++ if (ret)
++ return ret;
++
++ ret = __mt7996_load_ram(dev, "DSP", MT7996_FIRMWARE_DSP,
++ MT7996_RAM_TYPE_DSP);
++ if (ret)
++ return ret;
++
++ return __mt7996_load_ram(dev, "WA", MT7996_FIRMWARE_WA,
++ MT7996_RAM_TYPE_WA);
++}
++
+ static int
+ mt7996_firmware_state(struct mt7996_dev *dev, bool wa)
+ {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 4d7dcb95..7dfdc738 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -29,6 +29,7 @@
+
+ #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
+ #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
++#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin"
+ #define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin"
+
+ #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin"
+@@ -52,6 +53,12 @@ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+ struct mt7996_dfs_pattern;
+
++enum mt7996_ram_type {
++ MT7996_RAM_TYPE_WM,
++ MT7996_RAM_TYPE_WA,
++ MT7996_RAM_TYPE_DSP,
++};
++
+ enum mt7996_txq_id {
+ MT7996_TXQ_FWDL = 16,
+ MT7996_TXQ_MCU_WM,
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index 64aee3fb..c5301050 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);
+ MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);
+ MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
+ MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
++MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
+ MODULE_FIRMWARE(MT7996_ROM_PATCH);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch
new file mode 100644
index 0000000..a4e17a9
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch
@@ -0,0 +1,51 @@
+From 3c7a5592ea211f5ddb2f6bbd6ba8720c74faf459 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Thu, 2 Mar 2023 15:44:52 +0800
+Subject: [PATCH 04/11] wifi: mt76: mt7996: fix bss wlan_idx when sending
+ bss_info command
+
+The bmc_tx_wlan_idx should be the wlan_idx of the current bss rather
+than peer AP's wlan_idx, otherwise there will appear some frame
+decryption problems on station mode.
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/mcu.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 545cc987..6706d38c 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -712,6 +712,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ struct cfg80211_chan_def *chandef = &phy->chandef;
+ struct mt76_connac_bss_basic_tlv *bss;
+ u32 type = CONNECTION_INFRA_AP;
++ u16 sta_wlan_idx = wlan_idx;
+ struct tlv *tlv;
+ int idx;
+
+@@ -731,7 +732,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ struct mt76_wcid *wcid;
+
+ wcid = (struct mt76_wcid *)sta->drv_priv;
+- wlan_idx = wcid->idx;
++ sta_wlan_idx = wcid->idx;
+ }
+ rcu_read_unlock();
+ }
+@@ -751,7 +752,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
+ bss->dtim_period = vif->bss_conf.dtim_period;
+ bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
+- bss->sta_idx = cpu_to_le16(wlan_idx);
++ bss->sta_idx = cpu_to_le16(sta_wlan_idx);
+ bss->conn_type = cpu_to_le32(type);
+ bss->omac_idx = mvif->omac_idx;
+ bss->band_idx = mvif->band_idx;
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch
new file mode 100644
index 0000000..d4968dd
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch
@@ -0,0 +1,29 @@
+From 56d84272851f6c77cf68186bc8906de0558d2e5b Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Fri, 17 Mar 2023 11:08:04 +0800
+Subject: [PATCH 05/11] wifi: mt76: mt7996: init he and eht cap for AP_VLAN
+
+Init he and eht capabilities for AP_VLAN type. Without this patch, the
+BA response from AP_VLAN will not include the ADDBA extension tag.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/init.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index f1b48cdd..004575a0 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -808,6 +808,7 @@ __mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy,
+ switch (i) {
+ case NL80211_IFTYPE_STATION:
+ case NL80211_IFTYPE_AP:
++ case NL80211_IFTYPE_AP_VLAN:
+ #ifdef CONFIG_MAC80211_MESH
+ case NL80211_IFTYPE_MESH_POINT:
+ #endif
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch
new file mode 100644
index 0000000..348a04a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch
@@ -0,0 +1,30 @@
+From 1e7bbf8c04d60eb6cd234990f94da73bccd73118 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Mon, 27 Mar 2023 14:30:25 +0800
+Subject: [PATCH 06/11] wifi: mt76: mt7996: enable VHT extended NSS BW feature
+
+Set SUPPORTS_VHT_EXT_NSS_BW to let the max BW capability correctly be
+parsed by different devices.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/init.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 004575a0..8247153d 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -217,6 +217,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
+ phy->mt76->sband_5g.sband.ht_cap.ampdu_density =
+ IEEE80211_HT_MPDU_DENSITY_1;
++
++ ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
+ }
+
+ mt76_set_stream_caps(phy->mt76, true);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-set-txd-v1.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-set-txd-v1.patch
deleted file mode 100644
index f9cdd1a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0006-wifi-mt76-mt7996-set-txd-v1.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From a25714fa7b610430f9aa3d4ec24647eaea505d35 Mon Sep 17 00:00:00 2001
-From: Bo Jiao <Bo.Jiao@mediatek.com>
-Date: Mon, 6 Feb 2023 10:40:33 +0800
-Subject: [PATCH 06/22] wifi: mt76: mt7996: set txd v1
-
----
- mt7996/mac.c | 3 +++
- mt7996/mac.h | 3 ++-
- 2 files changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 23cbfdde..420c7403 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1110,6 +1110,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct mt76_txwi_cache *t;
- int id, i, pid, nbuf = tx_info->nbuf - 1;
- bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
-+ __le32 *txd = (__le32 *)txwi_ptr;
- u8 *txwi = (u8 *)txwi_ptr;
-
- if (unlikely(tx_info->skb->len <= ETH_HLEN))
-@@ -1141,6 +1142,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
- pid, qid, 0);
-
-+ txd[0] |= le32_encode_bits(1, MT_TXD0_VER);
-+
- txp = (struct mt76_connac_txp_common *)(txwi + MT_TXD_SIZE);
- for (i = 0; i < nbuf; i++) {
- txp->fw.buf[i] = cpu_to_le32(tx_info->buf[i + 1].addr);
-diff --git a/mt7996/mac.h b/mt7996/mac.h
-index bc4e6c55..9ab8e8d2 100644
---- a/mt7996/mac.h
-+++ b/mt7996/mac.h
-@@ -173,7 +173,8 @@ enum tx_mgnt_type {
-
- #define MT_TXD0_Q_IDX GENMASK(31, 25)
- #define MT_TXD0_PKT_FMT GENMASK(24, 23)
--#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16)
-+#define MT_TXD0_VER GENMASK(22, 19)
-+#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(18, 16)
- #define MT_TXD0_TX_BYTES GENMASK(15, 0)
-
- #define MT_TXD1_FIXED_RATE BIT(31)
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch
new file mode 100644
index 0000000..8021427
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch
@@ -0,0 +1,261 @@
+From edca876e34fc2696e8f855c2d05036fa79a05f8f Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Thu, 1 Jun 2023 12:01:10 +0800
+Subject: [PATCH 07/11] wifi: mt76: connac: add support to set ifs time by mcu
+ command
+
+There's a race between driver and fw on some tx/rx control registers
+when setting ifs, which will cause accidental hw queue pause problems.
+Avoid this by setting ifs time with bss_info mcu command.
+
+Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+Change-Id: Ib6477462a35df84a89f113a4db0e6aef5154c6a8
+---
+v2:
+ - merge two commits
+ - change bool a_band to use is_2ghz
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/mac.c | 27 ++-------------------------
+ mt7996/main.c | 5 ++---
+ mt7996/mcu.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.h | 17 +++++++++++++++++
+ mt7996/mt7996.h | 3 ++-
+ 6 files changed, 70 insertions(+), 29 deletions(-)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index d2a3d56b..b91262ee 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1288,6 +1288,7 @@ enum {
+ UNI_BSS_INFO_UAPSD = 19,
+ UNI_BSS_INFO_PS = 21,
+ UNI_BSS_INFO_BCNFT = 22,
++ UNI_BSS_INFO_IFS_TIME = 23,
+ UNI_BSS_INFO_OFFLOAD = 25,
+ UNI_BSS_INFO_MLD = 26,
+ };
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 23cbfdde..2da61d2e 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1612,20 +1612,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy)
+ mt7996_mcu_get_chan_mib_info(phy, true);
+ }
+
+-void mt7996_mac_set_timing(struct mt7996_phy *phy)
++void mt7996_mac_set_coverage_class(struct mt7996_phy *phy)
+ {
+ s16 coverage_class = phy->coverage_class;
+ struct mt7996_dev *dev = phy->dev;
+ struct mt7996_phy *phy2 = mt7996_phy2(dev);
+ struct mt7996_phy *phy3 = mt7996_phy3(dev);
+- u32 val, reg_offset;
++ u32 reg_offset;
+ u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) |
+ FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48);
+ u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) |
+ FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28);
+ u8 band_idx = phy->mt76->band_idx;
+ int offset;
+- bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ);
+
+ if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
+ return;
+@@ -1638,34 +1637,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy)
+ coverage_class = max_t(s16, coverage_class,
+ phy3->coverage_class);
+
+- mt76_set(dev, MT_ARB_SCR(band_idx),
+- MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
+- udelay(1);
+-
+ offset = 3 * coverage_class;
+ reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) |
+ FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset);
+
+ mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset);
+ mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset);
+- mt76_wr(dev, MT_TMAC_ICR0(band_idx),
+- FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) |
+- FIELD_PREP(MT_IFS_RIFS, 2) |
+- FIELD_PREP(MT_IFS_SIFS, 10) |
+- FIELD_PREP(MT_IFS_SLOT, phy->slottime));
+-
+- if (!a_band)
+- mt76_wr(dev, MT_TMAC_ICR1(band_idx),
+- FIELD_PREP(MT_IFS_EIFS_CCK, 314));
+-
+- if (phy->slottime < 20 || a_band)
+- val = MT7996_CFEND_RATE_DEFAULT;
+- else
+- val = MT7996_CFEND_RATE_11B;
+-
+- mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val);
+- mt76_clear(dev, MT_ARB_SCR(band_idx),
+- MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE);
+ }
+
+ void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band)
+diff --git a/mt7996/main.c b/mt7996/main.c
+index e7c97d2f..786c3fbc 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -287,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy)
+ if (ret)
+ goto out;
+
+- mt7996_mac_set_timing(phy);
+ ret = mt7996_dfs_init_radar_detector(phy);
+ mt7996_mac_cca_stats_reset(phy);
+
+@@ -564,7 +563,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
+
+ if (slottime != phy->slottime) {
+ phy->slottime = slottime;
+- mt7996_mac_set_timing(phy);
++ mt7996_mcu_set_timing(phy, vif);
+ }
+ }
+
+@@ -904,7 +903,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
+
+ mutex_lock(&dev->mt76.mutex);
+ phy->coverage_class = max_t(s16, coverage_class, 0);
+- mt7996_mac_set_timing(phy);
++ mt7996_mac_set_coverage_class(phy);
+ mutex_unlock(&dev->mt76.mutex);
+ }
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 6706d38c..0ede9769 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -701,6 +701,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif,
+ sizeof(req), true);
+ }
+
++static void
++mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
++{
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ struct mt7996_phy *phy = mvif->phy;
++ struct bss_ifs_time_tlv *ifs_time;
++ struct tlv *tlv;
++ bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ;
++
++ tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
++
++ ifs_time = (struct bss_ifs_time_tlv *)tlv;
++ ifs_time->slot_valid = true;
++ ifs_time->sifs_valid = true;
++ ifs_time->rifs_valid = true;
++ ifs_time->eifs_valid = true;
++
++ ifs_time->slot_time = cpu_to_le16(phy->slottime);
++ ifs_time->sifs_time = cpu_to_le16(10);
++ ifs_time->rifs_time = cpu_to_le16(2);
++ ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84);
++
++ if (is_2ghz) {
++ ifs_time->eifs_cck_valid = true;
++ ifs_time->eifs_cck_time = cpu_to_le16(314);
++ }
++}
++
+ static int
+ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
+ struct ieee80211_vif *vif,
+@@ -826,6 +854,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
+ mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
+ mt7996_mcu_bss_ra_tlv(skb, vif, phy);
+ mt7996_mcu_bss_txcmd_tlv(skb, true);
++ mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
+
+ if (vif->bss_conf.he_support)
+ mt7996_mcu_bss_he_tlv(skb, vif, phy);
+@@ -838,6 +867,23 @@ out:
+ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
+ }
+
++int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
++{
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ struct mt7996_dev *dev = phy->dev;
++ struct sk_buff *skb;
++
++ skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
++ MT7996_BSS_UPDATE_MAX_SIZE);
++ if (IS_ERR(skb))
++ return PTR_ERR(skb);
++
++ mt7996_mcu_bss_ifs_timing_tlv(skb, vif);
++
++ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
++ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
++}
++
+ static int
+ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+ struct ieee80211_ampdu_params *params,
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index d7075a4d..078f8285 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -317,6 +317,22 @@ struct bss_sec_tlv {
+ u8 __rsv2[1];
+ } __packed;
+
++struct bss_ifs_time_tlv {
++ __le16 tag;
++ __le16 len;
++ u8 slot_valid;
++ u8 sifs_valid;
++ u8 rifs_valid;
++ u8 eifs_valid;
++ __le16 slot_time;
++ __le16 sifs_time;
++ __le16 rifs_time;
++ __le16 eifs_time;
++ u8 eifs_cck_valid;
++ u8 rsv;
++ __le16 eifs_cck_time;
++} __packed;
++
+ struct bss_power_save {
+ __le16 tag;
+ __le16 len;
+@@ -552,6 +568,7 @@ enum {
+ sizeof(struct bss_txcmd_tlv) + \
+ sizeof(struct bss_power_save) + \
+ sizeof(struct bss_sec_tlv) + \
++ sizeof(struct bss_ifs_time_tlv) + \
+ sizeof(struct bss_mld_tlv))
+
+ #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 7dfdc738..42892f06 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -463,6 +463,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
+ const struct mt7996_dfs_pattern *pattern);
+ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
+ int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
++int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
+ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
+ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ u8 rx_sel, u8 val);
+@@ -526,7 +527,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid,
+ struct ieee80211_key_conf *key, int pid,
+ enum mt76_txq_id qid, u32 changed);
+-void mt7996_mac_set_timing(struct mt7996_phy *phy);
++void mt7996_mac_set_coverage_class(struct mt7996_phy *phy);
+ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch
new file mode 100644
index 0000000..24d2bfd
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch
@@ -0,0 +1,37 @@
+From 9cf96fa56a20d30f7e46e96d9c48c3568fbf11af Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 7 Mar 2023 17:05:01 +0800
+Subject: [PATCH 08/11] wifi: mt76: mt7996: use correct phy for background
+ radar event
+
+If driver directly uses the band_idx reported from the radar event to
+access mt76_phy array, it will get the wrong phy for background radar.
+Fix this by adjusting the statement.
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/mcu.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 0ede9769..20519bff 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
+ if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
+ return;
+
+- mphy = dev->mt76.phys[r->band_idx];
++ if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2)
++ mphy = dev->rdd2_phy->mt76;
++ else
++ mphy = dev->mt76.phys[r->band_idx];
++
+ if (!mphy)
+ return;
+
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-add-dsp-firmware-download.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-add-dsp-firmware-download.patch
deleted file mode 100644
index eb65330..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-add-dsp-firmware-download.patch
+++ /dev/null
@@ -1,194 +0,0 @@
-From 9b6e04ff1ac32161c6aacb939b2ff51bdced9629 Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 17 Feb 2023 14:13:38 +0800
-Subject: [PATCH 09/22] wifi: mt76: mt7996: add dsp firmware download
-
-Add DSP firmware for phy related control. Without this patch,the
-firmware state would not be ready.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt76_connac_mcu.h | 1 +
- mt7996/mcu.c | 94 +++++++++++++++++++++--------------------------
- mt7996/mt7996.h | 7 ++++
- mt7996/pci.c | 1 +
- 4 files changed, 50 insertions(+), 53 deletions(-)
-
-diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index c5c48349..fbb1206f 100644
---- a/mt76_connac_mcu.h
-+++ b/mt76_connac_mcu.h
-@@ -22,6 +22,7 @@
-
- #define FW_START_OVERRIDE BIT(0)
- #define FW_START_WORKING_PDA_CR4 BIT(2)
-+#define FW_START_WORKING_PDA_DSP BIT(3)
-
- #define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0)
- #define PATCH_SEC_TYPE_MASK GENMASK(15, 0)
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index f3fd2fd4..73d5dedf 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2241,7 +2241,7 @@ out:
- static int
- mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- const struct mt7996_fw_trailer *hdr,
-- const u8 *data, bool is_wa)
-+ const u8 *data, enum mt7996_ram_type type)
- {
- int i, offset = 0;
- u32 override = 0, option = 0;
-@@ -2253,8 +2253,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
-
- region = (const struct mt7996_fw_region *)((const u8 *)hdr -
- (hdr->n_region - i) * sizeof(*region));
-+ /* DSP and WA use same mode */
- mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76,
-- region->feature_set, is_wa);
-+ region->feature_set,
-+ type != MT7996_RAM_TYPE_WM);
- len = le32_to_cpu(region->len);
- addr = le32_to_cpu(region->addr);
-
-@@ -2281,8 +2283,10 @@ mt7996_mcu_send_ram_firmware(struct mt7996_dev *dev,
- if (override)
- option |= FW_START_OVERRIDE;
-
-- if (is_wa)
-+ if (type == MT7996_RAM_TYPE_WA)
- option |= FW_START_WORKING_PDA_CR4;
-+ else if (type == MT7996_RAM_TYPE_DSP)
-+ option |= FW_START_WORKING_PDA_DSP;
-
- return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
- }
-@@ -2293,56 +2297,40 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
- const struct firmware *fw;
- int ret;
-
-- ret = request_firmware(&fw, MT7996_FIRMWARE_WM, dev->mt76.dev);
-- if (ret)
-- return ret;
--
-- if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
-- dev_err(dev->mt76.dev, "Invalid firmware\n");
-- ret = -EINVAL;
-- goto out;
-- }
--
-- hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
--
-- dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
-- hdr->fw_ver, hdr->build_date);
--
-- ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, false);
-- if (ret) {
-- dev_err(dev->mt76.dev, "Failed to start WM firmware\n");
-- goto out;
-- }
--
-- release_firmware(fw);
--
-- ret = request_firmware(&fw, MT7996_FIRMWARE_WA, dev->mt76.dev);
-- if (ret)
-- return ret;
--
-- if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
-- dev_err(dev->mt76.dev, "Invalid firmware\n");
-- ret = -EINVAL;
-- goto out;
-- }
--
-- hdr = (const struct mt7996_fw_trailer *)(fw->data + fw->size - sizeof(*hdr));
--
-- dev_info(dev->mt76.dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
-- hdr->fw_ver, hdr->build_date);
--
-- ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, true);
-- if (ret) {
-- dev_err(dev->mt76.dev, "Failed to start WA firmware\n");
-- goto out;
-- }
--
-- snprintf(dev->mt76.hw->wiphy->fw_version,
-- sizeof(dev->mt76.hw->wiphy->fw_version),
-- "%.10s-%.15s", hdr->fw_ver, hdr->build_date);
--
--out:
-- release_firmware(fw);
-+#define LOAD_RAM(_type) \
-+ do { \
-+ ret = request_firmware(&fw, MT7996_FIRMWARE_##_type, dev->mt76.dev); \
-+ if (ret) \
-+ return ret; \
-+ \
-+ if (!fw || !fw->data || fw->size < sizeof(*hdr)) { \
-+ dev_err(dev->mt76.dev, "Invalid firmware\n"); \
-+ release_firmware(fw); \
-+ return -EINVAL; \
-+ } \
-+ \
-+ hdr = (const struct mt7996_fw_trailer *) \
-+ (fw->data + fw->size - sizeof(*hdr)); \
-+ \
-+ dev_info(dev->mt76.dev, \
-+ "%s Firmware Version: %.10s, Build Time: %.15s\n", \
-+ #_type, hdr->fw_ver, hdr->build_date); \
-+ \
-+ ret = mt7996_mcu_send_ram_firmware(dev, hdr, fw->data, \
-+ MT7996_RAM_TYPE_##_type); \
-+ if (ret) { \
-+ dev_err(dev->mt76.dev, "Failed to start %s firmware\n", #_type);\
-+ release_firmware(fw); \
-+ return ret; \
-+ } \
-+ \
-+ release_firmware(fw); \
-+ } while (0)
-+
-+ LOAD_RAM(WM);
-+ LOAD_RAM(DSP);
-+ LOAD_RAM(WA);
-+#undef LOAD_RAM
-
- return ret;
- }
-diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 36337808..ab4521a4 100644
---- a/mt7996/mt7996.h
-+++ b/mt7996/mt7996.h
-@@ -29,6 +29,7 @@
-
- #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
- #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
-+#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin"
- #define MT7996_ROM_PATCH "mediatek/mt7996/mt7996_rom_patch.bin"
-
- #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin"
-@@ -59,6 +60,12 @@ struct mt7996_sta;
- struct mt7996_dfs_pulse;
- struct mt7996_dfs_pattern;
-
-+enum mt7996_ram_type {
-+ MT7996_RAM_TYPE_WM = 0,
-+ MT7996_RAM_TYPE_WA,
-+ MT7996_RAM_TYPE_DSP,
-+};
-+
- enum mt7996_txq_id {
- MT7996_TXQ_FWDL = 16,
- MT7996_TXQ_MCU_WM,
-diff --git a/mt7996/pci.c b/mt7996/pci.c
-index 64aee3fb..c5301050 100644
---- a/mt7996/pci.c
-+++ b/mt7996/pci.c
-@@ -219,4 +219,5 @@ MODULE_DEVICE_TABLE(pci, mt7996_pci_device_table);
- MODULE_DEVICE_TABLE(pci, mt7996_hif_device_table);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WA);
- MODULE_FIRMWARE(MT7996_FIRMWARE_WM);
-+MODULE_FIRMWARE(MT7996_FIRMWARE_DSP);
- MODULE_FIRMWARE(MT7996_ROM_PATCH);
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch
new file mode 100644
index 0000000..6ffa018
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch
@@ -0,0 +1,44 @@
+From f9ac23ac488c0dafceab97c8d39a22904cf78f77 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 23 Mar 2023 15:16:14 +0800
+Subject: [PATCH 09/11] wifi: mt76: mt7996: fix WA event ring size
+
+Fix rx ring size of WA event to get rid of event loss and queue overflow
+problems.
+
+Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/dma.c | 2 +-
+ mt7996/mt7996.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 53414346..fbedaacf 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -293,7 +293,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ /* event from WA */
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
+ MT_RXQ_ID(MT_RXQ_MCU_WA),
+- MT7996_RX_MCU_RING_SIZE,
++ MT7996_RX_MCU_RING_SIZE_WA,
+ MT_RX_BUF_SIZE,
+ MT_RXQ_RING_BASE(MT_RXQ_MCU_WA));
+ if (ret)
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 42892f06..a3bd85d3 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -26,6 +26,7 @@
+
+ #define MT7996_RX_RING_SIZE 1536
+ #define MT7996_RX_MCU_RING_SIZE 512
++#define MT7996_RX_MCU_RING_SIZE_WA 1024
+
+ #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
+ #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-muru-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-add-muru-support.patch
similarity index 83%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-muru-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-add-muru-support.patch
index 1854421..c0f61b7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0005-wifi-mt76-mt7996-add-muru-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-add-muru-support.patch
@@ -1,23 +1,22 @@
-From 85fb9bc9f85a5e64d88db85fbfdef968d037fada Mon Sep 17 00:00:00 2001
+From 8a284ffc268754a8e941888ce6f1b506f3c7564c Mon Sep 17 00:00:00 2001
From: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
Date: Mon, 28 Nov 2022 14:36:09 +0800
-Subject: [PATCH 05/22] wifi: mt76: mt7996: add muru support
+Subject: [PATCH 10/11] wifi: mt76: mt7996: add muru support
-Add sta_rec_muru() and related phy cap for MU and RU support.
+Add sta_rec_muru() fw command to support MU-MIMO and OFDMA features.
Signed-off-by: MeiChia Chiu <meichia.chiu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
-Change-Id: I2206a9bb6fd6e50f4bf1380a8bea19920f1b7bfd
---
mt76_connac_mcu.h | 3 ++-
- mt7996/mcu.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-
- 2 files changed, 58 insertions(+), 2 deletions(-)
+ mt7996/mcu.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 91d98eff..8580ca59 100644
+index b91262ee..6249de57 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
-@@ -518,7 +518,8 @@ struct sta_rec_muru {
+@@ -519,7 +519,8 @@ struct sta_rec_muru {
u8 uo_ra;
u8 he_2x996_tone;
u8 rx_t_frame_11ac;
@@ -28,10 +27,10 @@
struct {
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 88e2f9d0..6812a47b 100644
+index 20519bff..611f6450 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -1050,6 +1050,60 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+@@ -1101,6 +1101,59 @@ mt7996_mcu_sta_amsdu_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
}
}
@@ -50,7 +49,6 @@
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
+
+ muru = (struct sta_rec_muru *)tlv;
-+
+ muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer ||
+ vif->bss_conf.he_mu_beamformer ||
+ vif->bss_conf.vht_mu_beamformer ||
@@ -92,7 +90,7 @@
static inline bool
mt7996_is_ebf_supported(struct mt7996_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool bfee)
-@@ -1727,7 +1781,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -1778,7 +1831,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
mt7996_mcu_sta_he_6g_tlv(skb, sta);
/* starec eht */
mt7996_mcu_sta_eht_tlv(skb, sta);
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-fix-icv-error-when-enable-AP-and-ST.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-fix-icv-error-when-enable-AP-and-ST.patch
deleted file mode 100644
index caa9b1a..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0010-wifi-mt76-mt7996-fix-icv-error-when-enable-AP-and-ST.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From ee3a2aa33145d17d3be17af85583437f079e91fb Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Thu, 2 Mar 2023 15:44:52 +0800
-Subject: [PATCH 10/22] wifi: mt76: mt7996: fix icv error when enable AP and
- STA simultaneously
-
-Fix mcu command content to prevent ICV error
-The bmc_tx_wlan_idx needs to be the vif index rather
-than peer AP's index.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/mcu.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 73d5dedf..6d11bc1a 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -743,6 +743,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- struct cfg80211_chan_def *chandef = &phy->chandef;
- struct mt76_connac_bss_basic_tlv *bss;
- u32 type = CONNECTION_INFRA_AP;
-+ u16 sta_wlan_idx = wlan_idx;
- struct tlv *tlv;
- int idx;
-
-@@ -762,7 +763,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- struct mt76_wcid *wcid;
-
- wcid = (struct mt76_wcid *)sta->drv_priv;
-- wlan_idx = wcid->idx;
-+ sta_wlan_idx = wcid->idx;
- }
- rcu_read_unlock();
- }
-@@ -782,7 +783,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb,
- bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
- bss->dtim_period = vif->bss_conf.dtim_period;
- bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx);
-- bss->sta_idx = cpu_to_le16(wlan_idx);
-+ bss->sta_idx = cpu_to_le16(sta_wlan_idx);
- bss->conn_type = cpu_to_le32(type);
- bss->omac_idx = mvif->omac_idx;
- bss->band_idx = mvif->band_idx;
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-increase-tx-token-size.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-increase-tx-token-size.patch
new file mode 100644
index 0000000..aa039ce
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-increase-tx-token-size.patch
@@ -0,0 +1,30 @@
+From 0cc8d7827510e36978175d84d63cced5f842ff61 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Mon, 17 Apr 2023 09:49:53 +0800
+Subject: [PATCH 11/11] wifi: mt76: mt7996: increase tx token size
+
+Align tx token size to proprietary driver, which can improve peak
+throughput under MU performance tests.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/mt7996.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index a3bd85d3..651f53aa 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -36,7 +36,7 @@
+ #define MT7996_EEPROM_DEFAULT "mediatek/mt7996/mt7996_eeprom.bin"
+ #define MT7996_EEPROM_SIZE 7680
+ #define MT7996_EEPROM_BLOCK_SIZE 16
+-#define MT7996_TOKEN_SIZE 8192
++#define MT7996_TOKEN_SIZE 16384
+
+ #define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
+ #define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch
deleted file mode 100644
index f05fe30..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0012-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 9af2057cec3d77aafb4f92b8d1542d88c8ac5efc Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 17 Mar 2023 11:08:04 +0800
-Subject: [PATCH 12/22] wifi: mt76: mt7996: init he and eht cap for AP_VLAN
-
-Add AP_VLAN types in __mt7996_set_stream_he_eht_caps to
-initialize the ht and eht caps. Without this patch, the
-BA response from VLAN AP would not include the ADDBA
-extension tag.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/init.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/mt7996/init.c b/mt7996/init.c
-index 9c5d20ad..d44e3ae9 100644
---- a/mt7996/init.c
-+++ b/mt7996/init.c
-@@ -993,6 +993,7 @@ __mt7996_set_stream_he_eht_caps(struct mt7996_phy *phy,
- switch (i) {
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_AP:
-+ case NL80211_IFTYPE_AP_VLAN:
- #ifdef CONFIG_MAC80211_MESH
- case NL80211_IFTYPE_MESH_POINT:
- #endif
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-Fix-using-the-wrong-phy-for-backgro.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-Fix-using-the-wrong-phy-for-backgro.patch
deleted file mode 100644
index 461236e..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-Fix-using-the-wrong-phy-for-backgro.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From b1296ffe7596adf514bc2b5397c946e276e30176 Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Tue, 7 Mar 2023 17:05:01 +0800
-Subject: [PATCH 14/22] wifi: mt76: mt7996: Fix using the wrong phy for
- background radar event
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/mcu.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index df1ae639..cd86209b 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -339,7 +339,11 @@ mt7996_mcu_rx_radar_detected(struct mt7996_dev *dev, struct sk_buff *skb)
- if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys))
- return;
-
-- mphy = dev->mt76.phys[r->band_idx];
-+ if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2)
-+ mphy = dev->rdd2_phy->mt76;
-+ else
-+ mphy = dev->mt76.phys[r->band_idx];
-+
- if (!mphy)
- return;
-
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-set-wcid-in-txp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-set-wcid-in-txp.patch
similarity index 70%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-set-wcid-in-txp.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-set-wcid-in-txp.patch
index d612bdf..8103127 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0011-wifi-mt76-mt7996-set-wcid-in-txp.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0014-wifi-mt76-mt7996-set-wcid-in-txp.patch
@@ -1,20 +1,21 @@
-From 952869c0b481651e9c125d5cd7c4ea2b255521c5 Mon Sep 17 00:00:00 2001
+From 5e2177e77b9609185f748708332aa6a6fdf4d1f9 Mon Sep 17 00:00:00 2001
From: Peter Chiu <chui-hao.chiu@mediatek.com>
Date: Mon, 6 Mar 2023 15:52:26 +0800
-Subject: [PATCH 11/22] wifi: mt76: mt7996: set wcid in txp
+Subject: [PATCH 14/39] wifi: mt76: mt7996: set wcid in txp
Set correct wcid in txp for SDO to get wtbl.
Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Change-Id: Ie715a659ff52f2d85332158f273d0ee4fe9f4051
---
mt7996/mac.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/mt7996/mac.c b/mt7996/mac.c
-index 420c7403..ca163969 100644
+index 2da61d2..bddb84f 100644
--- a/mt7996/mac.c
+++ b/mt7996/mac.c
-@@ -1169,10 +1169,12 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+@@ -1166,10 +1166,12 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
}
txp->fw.token = cpu_to_le16(id);
@@ -22,7 +23,7 @@
- txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
- else
+ if ((is_8023 && is_multicast_ether_addr(tx_info->skb->data)) ||
-+ is_multicast_ether_addr(hdr->addr1))
++ (!is_8023 && is_multicast_ether_addr(hdr->addr1)))
txp->fw.rept_wds_wcid = cpu_to_le16(0xfff);
+ else
+ txp->fw.rept_wds_wcid = cpu_to_le16(wcid->idx);
@@ -31,5 +32,5 @@
/* pass partial skb header to fw */
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
index 50f83e7..ea01cf0 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0002-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch
@@ -1,7 +1,7 @@
-From 1a55033a534847f9c10ffd52e277378c1ba3e45a Mon Sep 17 00:00:00 2001
+From 5580f05c864aadfad4092fc97a937869dc08eca8 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 16 Feb 2023 00:39:01 +0800
-Subject: [PATCH 02/22] wifi: mt76: mt7996: reduce repeated bss_info and
+Subject: [PATCH 15/39] wifi: mt76: mt7996: reduce repeated bss_info and
sta_rec commands
Refine the flow of setting bss_info and sta_rec commands to prevent from
@@ -14,10 +14,10 @@
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/mt7996/main.c b/mt7996/main.c
-index f306e9c5..136a0c28 100644
+index 786c3fb..02a33b8 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
-@@ -246,8 +246,8 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
+@@ -248,8 +248,8 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
struct mt7996_phy *phy = mt7996_hw_phy(hw);
int idx = msta->wcid.idx;
@@ -63,5 +63,5 @@
if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
mt7996_mcu_set_tx(dev, vif);
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
similarity index 86%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
index 3f55f11..e6a4f75 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0004-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch
@@ -1,7 +1,7 @@
-From fb2659a8aa12346cdda4010737f63178040fa513 Mon Sep 17 00:00:00 2001
+From eec83d4410d7c669d9a05bba1a69a742a6ccd490 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 16 Feb 2023 13:53:14 +0800
-Subject: [PATCH 04/22] wifi: mt76: connac: set correct muar_idx for connac3
+Subject: [PATCH 16/39] wifi: mt76: connac: set correct muar_idx for connac3
chipset
Set the muar_idx to 0xe for the hw bcast/mcast station entry of connac3
@@ -15,7 +15,7 @@
2 files changed, 8 insertions(+)
diff --git a/mt76_connac.h b/mt76_connac.h
-index 77ca8f05..02acac64 100644
+index 77ca8f0..02acac6 100644
--- a/mt76_connac.h
+++ b/mt76_connac.h
@@ -240,6 +240,11 @@ static inline bool is_connac_v1(struct mt76_dev *dev)
@@ -31,7 +31,7 @@
{
switch (mt76_chip(dev)) {
diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index 46f69aa8..5fab6772 100644
+index 46f69aa..5fab677 100644
--- a/mt76_connac_mcu.c
+++ b/mt76_connac_mcu.c
@@ -281,6 +281,9 @@ __mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
@@ -45,5 +45,5 @@
&hdr.wlan_idx_hi);
skb = mt76_mcu_msg_alloc(dev, NULL, len);
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-fill-txwi-by-SW-temporarily.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-fill-txwi-by-SW-temporarily.patch
deleted file mode 100644
index c756ccd..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0016-wifi-mt76-mt7996-fill-txwi-by-SW-temporarily.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From aa539aaae8a95f3e970ad8e1f5a7381bb249ad7e Mon Sep 17 00:00:00 2001
-From: Peter Chiu <chui-hao.chiu@mediatek.com>
-Date: Fri, 17 Mar 2023 11:16:44 +0800
-Subject: [PATCH 16/22] wifi: mt76: mt7996: fill txwi by SW temporarily
-
-If use WA to fill TXD, it cannot ping pass.
-Remove this patch after bug fix.
-
-Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
----
- mt7996/mac.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
-
-diff --git a/mt7996/mac.c b/mt7996/mac.c
-index ca163969..7059a4e1 100644
---- a/mt7996/mac.c
-+++ b/mt7996/mac.c
-@@ -1138,9 +1138,8 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
- memset(txwi_ptr, 0, MT_TXD_SIZE);
- /* Transmit non qos data by 802.11 header and need to fill txd by host*/
-- if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
-- mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
-- pid, qid, 0);
-+ mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
-+ pid, qid, 0);
-
- txd[0] |= le32_encode_bits(1, MT_TXD0_VER);
-
-@@ -1153,8 +1152,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
-
- txp->fw.flags = cpu_to_le16(MT_CT_INFO_FROM_HOST);
-
-- if (!is_8023 || pid >= MT_PACKET_ID_FIRST)
-- txp->fw.flags |= cpu_to_le16(MT_CT_INFO_APPLY_TXD);
-+ txp->fw.flags |= cpu_to_le16(MT_CT_INFO_APPLY_TXD);
-
- if (!key)
- txp->fw.flags |= cpu_to_le16(MT_CT_INFO_NONE_CIPHER_FRAME);
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-add-thermal-protection-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-add-thermal-protection-support.patch
similarity index 91%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-add-thermal-protection-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-add-thermal-protection-support.patch
index 526edc7..bcc5d51 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0007-wifi-mt76-mt7996-add-thermal-protection-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-add-thermal-protection-support.patch
@@ -1,7 +1,7 @@
-From 7d85212987815786ceff28379015a6bb23012dc3 Mon Sep 17 00:00:00 2001
+From 1fa1645ef7621981c7e87d27b9a7816f3485d3db Mon Sep 17 00:00:00 2001
From: Howard Hsu <howard-yh.hsu@mediatek.com>
Date: Thu, 2 Feb 2023 21:20:31 +0800
-Subject: [PATCH 07/22] wifi: mt76: mt7996: add thermal protection support
+Subject: [PATCH 17/39] wifi: mt76: mt7996: add thermal protection support
This commit includes the following changes:
1. implement MTK thermal protection driver API
@@ -18,10 +18,10 @@
6 files changed, 277 insertions(+)
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index 8580ca59..c5c48349 100644
+index 6249de5..30c9a5d 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
-@@ -1009,6 +1009,7 @@ enum {
+@@ -1010,6 +1010,7 @@ enum {
MCU_UNI_EVENT_FW_LOG_2_HOST = 0x04,
MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
MCU_UNI_EVENT_RDD_REPORT = 0x11,
@@ -30,7 +30,7 @@
#define MCU_UNI_CMD_EVENT BIT(1)
diff --git a/mt7996/init.c b/mt7996/init.c
-index f1b48cdd..53852ffc 100644
+index 8247153..c072b09 100644
--- a/mt7996/init.c
+++ b/mt7996/init.c
@@ -42,6 +42,98 @@ static const struct ieee80211_iface_combination if_comb[] = {
@@ -132,7 +132,7 @@
static void mt7996_led_set_config(struct led_classdev *led_cdev,
u8 delay_on, u8 delay_off)
{
-@@ -389,6 +481,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+@@ -391,6 +483,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
if (ret)
goto error;
@@ -143,7 +143,7 @@
ret = mt7996_init_debugfs(phy);
if (ret)
goto error;
-@@ -409,6 +505,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
+@@ -411,6 +507,8 @@ mt7996_unregister_phy(struct mt7996_phy *phy, enum mt76_band_id band)
if (!phy)
return;
@@ -152,7 +152,7 @@
mphy = phy->dev->mt76.phys[band];
mt76_unregister_phy(mphy);
ieee80211_free_hw(mphy->hw);
-@@ -879,6 +977,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -882,6 +980,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
if (ret)
return ret;
@@ -163,7 +163,7 @@
ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
-@@ -902,6 +1004,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
+@@ -905,6 +1007,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)
{
mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
@@ -172,7 +172,7 @@
mt76_unregister_device(&dev->mt76);
mt7996_mcu_exit(dev);
diff --git a/mt7996/main.c b/mt7996/main.c
-index 28b63d44..fbb7270d 100644
+index 02a33b8..9c80839 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -51,6 +51,14 @@ int mt7996_run(struct ieee80211_hw *hw)
@@ -191,10 +191,10 @@
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6812a47b..325051bd 100644
+index c50dcce..c308d86 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -443,6 +443,34 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -447,6 +447,34 @@ mt7996_mcu_ie_countdown(struct mt7996_dev *dev, struct sk_buff *skb)
}
}
@@ -229,7 +229,7 @@
static void
mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
{
-@@ -487,6 +515,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+@@ -491,6 +519,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
case MCU_UNI_EVENT_RDD_REPORT:
mt7996_mcu_rx_radar_detected(dev, skb);
break;
@@ -239,7 +239,7 @@
default:
break;
}
-@@ -3178,6 +3209,81 @@ out:
+@@ -3217,6 +3248,81 @@ out:
return 0;
}
@@ -322,7 +322,7 @@
{
struct {
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index d7075a4d..778deedf 100644
+index 078f828..f235175 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
@@ -30,6 +30,28 @@ struct mt7996_mcu_uni_event {
@@ -377,7 +377,7 @@
enum mt7996_chan_mib_offs {
UNI_MIB_OBSS_AIRTIME = 26,
UNI_MIB_NON_WIFI_TIME = 27,
-@@ -642,6 +680,12 @@ enum{
+@@ -659,6 +697,12 @@ enum{
UNI_CMD_SR_SET_SIGA = 0xd0,
};
@@ -391,10 +391,10 @@
UNI_CMD_ACCESS_REG_BASIC = 0x0,
UNI_CMD_ACCESS_RF_REG_BASIC,
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 4d7dcb95..36337808 100644
+index 651f53a..071031b 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
-@@ -47,6 +47,13 @@
+@@ -49,6 +49,13 @@
#define MT7996_BASIC_RATES_TBL 11
#define MT7996_BEACON_RATES_TBL 25
@@ -408,7 +408,7 @@
struct mt7996_vif;
struct mt7996_sta;
struct mt7996_dfs_pulse;
-@@ -209,6 +216,11 @@ struct mt7996_phy {
+@@ -217,6 +224,11 @@ struct mt7996_phy {
struct ieee80211_vif *monitor_vif;
@@ -420,9 +420,9 @@
u32 rxfilter;
u64 omac_mask;
-@@ -457,6 +469,9 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index,
- int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
+@@ -466,6 +478,9 @@ int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable);
int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val);
+ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif);
int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch);
+int mt7996_mcu_get_temperature(struct mt7996_phy *phy);
+int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state);
@@ -431,5 +431,5 @@
u8 rx_sel, u8 val);
int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
similarity index 95%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
index 9e0668a..effc63b 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0008-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
@@ -1,7 +1,7 @@
-From 72f33a06b35ae981db88d12cd8db267ce68b9e08 Mon Sep 17 00:00:00 2001
+From db282c765c1d9cd2a5eec6a095069fd4bcf627b4 Mon Sep 17 00:00:00 2001
From: Howard Hsu <howard-yh.hsu@mediatek.com>
Date: Thu, 2 Feb 2023 20:53:42 +0800
-Subject: [PATCH 08/22] wifi: mt76: mt7996: add thermal sensor device support
+Subject: [PATCH 18/39] wifi: mt76: mt7996: add thermal sensor device support
---
mt7996/init.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -9,7 +9,7 @@
2 files changed, 128 insertions(+)
diff --git a/mt7996/init.c b/mt7996/init.c
-index 53852ffc..9c5d20ad 100644
+index c072b09..0319e7f 100644
--- a/mt7996/init.c
+++ b/mt7996/init.c
@@ -4,6 +4,8 @@
@@ -128,10 +128,10 @@
}
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 325051bd..f3fd2fd4 100644
+index c308d86..349c20e 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -3209,6 +3209,47 @@ out:
+@@ -3248,6 +3248,47 @@ out:
return 0;
}
@@ -180,5 +180,5 @@
int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)
{
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
similarity index 75%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
index b2ed6a1..1fef46a 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0013-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch
@@ -1,7 +1,7 @@
-From 854db11781bd8f9fa7cb45ed529223a4784de9d9 Mon Sep 17 00:00:00 2001
+From 2fe477b8db9ab494a975a565a28e35fff76505d1 Mon Sep 17 00:00:00 2001
From: Howard Hsu <howard-yh.hsu@mediatek.com>
Date: Thu, 16 Mar 2023 16:09:51 +0800
-Subject: [PATCH 13/22] wifi: mt76: mt7996: fix beamform mcu cmd configuration
+Subject: [PATCH 19/39] wifi: mt76: mt7996: fix beamform mcu cmd configuration
bf_num means how many band can support beamform, so the value shall be 3.
bf_bitmap represents which band can support beamform.
@@ -10,10 +10,10 @@
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 6d11bc1a..df1ae639 100644
+index 349c20e..62e4869 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -3394,8 +3394,8 @@ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action)
+@@ -3444,8 +3444,8 @@ int mt7996_mcu_set_txbf(struct mt7996_dev *dev, u8 action)
tlv = mt7996_mcu_add_uni_tlv(skb, action, sizeof(*req_mod_en));
req_mod_en = (struct bf_mod_en_ctrl *)tlv;
@@ -25,5 +25,5 @@
}
default:
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
index 1e2ec3b..14855c7 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0015-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch
@@ -1,21 +1,26 @@
-From c1d0d0a15d4cdafa1ed0a61606fd5fefa85a6bb7 Mon Sep 17 00:00:00 2001
+From bfb2498bbef4bcfd44658fad8acf82730c56ede6 Mon Sep 17 00:00:00 2001
From: Howard Hsu <howard-yh.hsu@mediatek.com>
Date: Tue, 20 Dec 2022 09:47:31 +0800
-Subject: [PATCH 15/22] wifi: mt76: mt7996: support more options in
+Subject: [PATCH] wifi: mt76: mt7996: support more options in
.set_bitrate_mask()
With this patch, driver can support runtime configuration for single
rate, (HE)GI and HE_Ltf through .set_bitrate_mask(). Please noted that
currently we do not support to fix any single parameter for EHT mode.
+
+Co-developed-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+Co-developed-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
---
- mt7996/mcu.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 137 insertions(+), 2 deletions(-)
+ mt7996/mcu.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 135 insertions(+), 2 deletions(-)
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index cd86209b..8a7487ba 100644
+index 62e4869..b7f378a 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -1610,6 +1610,136 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
+@@ -1656,6 +1656,134 @@ int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev,
MCU_WM_UNI_CMD(RA), true);
}
@@ -75,10 +80,8 @@
+ do { \
+ u8 i, gi = mask->control[band]._gi; \
+ gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \
-+ for (i = 0; i <= sta->deflink.bandwidth; i++) { \
-+ phy.sgi |= gi << (i << (_he)); \
-+ phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\
-+ } \
++ phy.sgi = gi; \
++ phy.he_ltf = mask->control[band].he_ltf; \
+ for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) { \
+ if (!mask->control[band]._mcs[i]) \
+ continue; \
@@ -152,7 +155,7 @@
static void
mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev,
struct ieee80211_vif *vif, struct ieee80211_sta *sta)
-@@ -1719,6 +1849,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -1765,6 +1893,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct sk_buff *skb;
@@ -160,7 +163,7 @@
skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
&msta->wcid,
-@@ -1738,8 +1869,12 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+@@ -1784,8 +1913,12 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif,
*/
mt7996_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);
@@ -176,5 +179,5 @@
static int
--
-2.39.2
+2.39.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0021-mt76-testmode-add-chainmask-hacking-for-eagle-band-2.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0021-mt76-testmode-add-chainmask-hacking-for-eagle-band-2.patch
deleted file mode 100644
index a3a0633..0000000
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0021-mt76-testmode-add-chainmask-hacking-for-eagle-band-2.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From 59c4b77798c213a1766b3dac36a9de08145f063e Mon Sep 17 00:00:00 2001
-From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Date: Thu, 9 Mar 2023 18:45:04 +0800
-Subject: [PATCH 21/22] mt76: testmode: add chainmask hacking for eagle band 2
- 4T5R
-
-Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
----
- mt7996/testmode.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/mt7996/testmode.c b/mt7996/testmode.c
-index 6d7cdbd5..0d4d9138 100644
---- a/mt7996/testmode.c
-+++ b/mt7996/testmode.c
-@@ -463,6 +463,7 @@ mt7996_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
- return 0;
-
- chainmask = chainmask >> dev->chainshift[band_idx];
-+ chainmask = 0x1f; /* hacking for eagle band2 4T5R */
- if (td->tx_antenna_mask > chainmask)
- return -EINVAL;
-
---
-2.39.2
-
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-update-wmm-queue-mapping.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
similarity index 83%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
index 659e580..6b1d684 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0017-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch
@@ -1,7 +1,7 @@
-From c3611ca1b4d8260dee8893cb922ad2ad0a8eb8d7 Mon Sep 17 00:00:00 2001
+From 88577bcf928a15c2e8e78b7684ccb75dfc693eac Mon Sep 17 00:00:00 2001
From: Peter Chiu <chui-hao.chiu@mediatek.com>
Date: Mon, 20 Mar 2023 19:09:59 +0800
-Subject: [PATCH 17/22] wifi: mt76: mt7996: update wmm queue mapping
+Subject: [PATCH 21/39] wifi: mt76: mt7996: update wmm queue mapping
The mac80211 use mac80211 queue (MQ) and the firmware
use access class index (ACI) so convert the MQ to ACI
@@ -14,7 +14,7 @@
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/mt7996/main.c b/mt7996/main.c
-index fbb7270d..059cc420 100644
+index 9c80839..8e38ebc 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
@@ -198,7 +198,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
@@ -26,7 +26,7 @@
ret = mt7996_mcu_add_dev_info(phy, vif, true);
if (ret)
-@@ -423,9 +423,16 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -422,9 +422,16 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct ieee80211_tx_queue_params *params)
{
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
@@ -45,10 +45,10 @@
return 0;
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 8a7487ba..43a4f939 100644
+index b27b88c..4359ede 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -2789,7 +2789,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif)
+@@ -2835,7 +2835,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif)
e = (struct edca *)tlv;
e->set = WMM_PARAM_SET;
@@ -58,5 +58,5 @@
e->txop = cpu_to_le16(q->txop);
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-enable-IDS-debug-log.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch
similarity index 84%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-enable-IDS-debug-log.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch
index ca2e812..659edd4 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0018-wifi-mt76-mt7996-enable-IDS-debug-log.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch
@@ -1,14 +1,14 @@
-From 6e972b77bd615df709c8ce4401ea6e120ccdf758 Mon Sep 17 00:00:00 2001
+From 7e3ab3b90fc75ff41a503f4632a669c8cba2ae90 Mon Sep 17 00:00:00 2001
From: Peter Chiu <chui-hao.chiu@mediatek.com>
Date: Tue, 21 Mar 2023 15:04:45 +0800
-Subject: [PATCH 18/22] wifi: mt76: mt7996: enable IDS debug log
+Subject: [PATCH 22/39] wifi: mt76: mt7996: enable IDS debug log
---
mt7996/debugfs.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 513ab4ba..04220180 100644
+index 513ab4b..0422018 100644
--- a/mt7996/debugfs.c
+++ b/mt7996/debugfs.c
@@ -290,6 +290,12 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
@@ -36,5 +36,5 @@
if (debug == DEBUG_RPT_RX)
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0019-mt76-testmode-add-atenl-support-in-mt7996.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
similarity index 87%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0019-mt76-testmode-add-atenl-support-in-mt7996.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
index 1cbaf0e..686576d 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0019-mt76-testmode-add-atenl-support-in-mt7996.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch
@@ -1,7 +1,7 @@
-From e119dd8edebc8baa1e30945db3d0a7bc192bfc4b Mon Sep 17 00:00:00 2001
+From 33211d380fbf3b0892e560db99ac8dbc5c4e8cd5 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Wed, 28 Dec 2022 22:24:25 +0800
-Subject: [PATCH 19/22] mt76: testmode: add atenl support in mt7996
+Subject: [PATCH 23/39] wifi: mt76: testmode: add atenl support in mt7996
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
@@ -10,7 +10,7 @@
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/testmode.c b/testmode.c
-index 0accc71a..0d2bae9f 100644
+index 0accc71..0d2bae9 100644
--- a/testmode.c
+++ b/testmode.c
@@ -612,7 +612,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
@@ -24,7 +24,7 @@
if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
diff --git a/testmode.h b/testmode.h
-index 5e2792d8..a40cd74b 100644
+index 5e2792d..a40cd74 100644
--- a/testmode.h
+++ b/testmode.h
@@ -17,6 +17,7 @@
@@ -44,5 +44,5 @@
MT76_TM_ATTR_TX_COUNT,
MT76_TM_ATTR_TX_LENGTH,
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0020-mt76-testmode-add-basic-testmode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-testmode-add-basic-testmode-support.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0020-mt76-testmode-add-basic-testmode-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-testmode-add-basic-testmode-support.patch
index 30eef7a..6facdc3 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0020-mt76-testmode-add-basic-testmode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0024-wifi-mt76-testmode-add-basic-testmode-support.patch
@@ -1,7 +1,7 @@
-From 058747d35c83a796712bec098cf6509965cf28cc Mon Sep 17 00:00:00 2001
+From 826ab7312fa42110844329a333df76dec614e48f Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Wed, 1 Mar 2023 11:59:16 +0800
-Subject: [PATCH 20/22] mt76: testmode: add basic testmode support
+Subject: [PATCH] wifi: mt76: testmode: add basic testmode support
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
@@ -13,21 +13,21 @@
mt7996/eeprom.c | 35 ++-
mt7996/eeprom.h | 1 +
mt7996/init.c | 7 +
- mt7996/main.c | 15 ++
- mt7996/mcu.c | 39 ++-
+ mt7996/main.c | 16 ++
+ mt7996/mcu.c | 42 ++-
mt7996/mcu.h | 27 ++
mt7996/mt7996.h | 22 ++
- mt7996/testmode.c | 632 ++++++++++++++++++++++++++++++++++++++++++++++
- mt7996/testmode.h | 295 ++++++++++++++++++++++
- testmode.c | 73 ++++--
+ mt7996/testmode.c | 658 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/testmode.h | 295 +++++++++++++++++++++
+ testmode.c | 73 +++--
testmode.h | 60 +++++
tools/fields.c | 92 +++++++
- 17 files changed, 1315 insertions(+), 29 deletions(-)
+ 17 files changed, 1344 insertions(+), 30 deletions(-)
create mode 100644 mt7996/testmode.c
create mode 100644 mt7996/testmode.h
diff --git a/eeprom.c b/eeprom.c
-index ea54b7af..263e5089 100644
+index ea54b7a..263e508 100644
--- a/eeprom.c
+++ b/eeprom.c
@@ -89,8 +89,10 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
@@ -44,7 +44,7 @@
out_put_node:
diff --git a/mac80211.c b/mac80211.c
-index 467afef9..d1cdaee8 100644
+index 467afef..d1cdaee 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -826,7 +826,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
@@ -58,7 +58,7 @@
if (status->flag & RX_FLAG_FAILED_FCS_CRC)
phy->test.rx_stats.fcs_error[q]++;
diff --git a/mt76.h b/mt76.h
-index 6b07b8fa..31d5dc37 100644
+index 6b07b8f..31d5dc3 100644
--- a/mt76.h
+++ b/mt76.h
@@ -652,8 +652,12 @@ struct mt76_testmode_ops {
@@ -133,7 +133,7 @@
{
#ifdef CONFIG_NL80211_TESTMODE
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
-index fbb1206f..17cb8128 100644
+index 30c9a5d..724a48a 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
@@ -1218,10 +1218,12 @@ enum {
@@ -150,7 +150,7 @@
MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
diff --git a/mt7996/Makefile b/mt7996/Makefile
-index 07c8b555..bed9efd6 100644
+index 07c8b55..bed9efd 100644
--- a/mt7996/Makefile
+++ b/mt7996/Makefile
@@ -6,3 +6,5 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
@@ -160,7 +160,7 @@
+
+mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 544b6c6f..f5e95460 100644
+index 544b6c6..f5e9546 100644
--- a/mt7996/eeprom.c
+++ b/mt7996/eeprom.c
@@ -6,6 +6,11 @@
@@ -230,7 +230,7 @@
if (ret < 0)
return ret;
diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 0c749774..0f8f0cd8 100644
+index 0c74977..0f8f0cd 100644
--- a/mt7996/eeprom.h
+++ b/mt7996/eeprom.h
@@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
@@ -242,10 +242,10 @@
MT_EE_RATE_DELTA_2G = 0x1400,
MT_EE_RATE_DELTA_5G = 0x147d,
diff --git a/mt7996/init.c b/mt7996/init.c
-index d44e3ae9..36ead6db 100644
+index 0319e7f..fecd0d3 100644
--- a/mt7996/init.c
+++ b/mt7996/init.c
-@@ -639,6 +639,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+@@ -641,6 +641,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
@@ -256,7 +256,7 @@
ret = mt7996_mcu_init(dev);
if (ret)
return ret;
-@@ -1054,6 +1058,9 @@ int mt7996_register_device(struct mt7996_dev *dev)
+@@ -1056,6 +1060,9 @@ int mt7996_register_device(struct mt7996_dev *dev)
mt7996_init_wiphy(hw);
@@ -267,10 +267,10 @@
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
dev->mphy.leds.cdev.brightness_set = mt7996_led_set_brightness;
diff --git a/mt7996/main.c b/mt7996/main.c
-index 059cc420..3820b235 100644
+index 8e38ebc..6c38993 100644
--- a/mt7996/main.c
+++ b/mt7996/main.c
-@@ -23,6 +23,17 @@ static bool mt7996_dev_running(struct mt7996_dev *dev)
+@@ -23,6 +23,18 @@ static bool mt7996_dev_running(struct mt7996_dev *dev)
return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);
}
@@ -281,14 +281,15 @@
+
+ for (i = 0; i < __MT_MAX_BAND; i++) {
+ phy = __mt7996_phy(dev, i);
-+ mt76_testmode_set_state(phy->mt76, MT76_TM_STATE_OFF);
++ if (phy)
++ mt76_testmode_set_state(phy->mt76, MT76_TM_STATE_OFF);
+ }
+}
+
int mt7996_run(struct ieee80211_hw *hw)
{
struct mt7996_dev *dev = mt7996_hw_dev(hw);
-@@ -37,6 +48,8 @@ int mt7996_run(struct ieee80211_hw *hw)
+@@ -37,6 +49,8 @@ int mt7996_run(struct ieee80211_hw *hw)
goto out;
}
@@ -297,7 +298,7 @@
mt7996_mac_enable_nf(dev, phy->mt76->band_idx);
ret = mt7996_mcu_set_rts_thresh(phy, 0x92b);
-@@ -1390,6 +1403,8 @@ const struct ieee80211_ops mt7996_ops = {
+@@ -1389,6 +1403,8 @@ const struct ieee80211_ops mt7996_ops = {
.sta_set_decap_offload = mt7996_sta_set_decap_offload,
.add_twt_setup = mt7996_mac_add_twt_setup,
.twt_teardown_request = mt7996_twt_teardown_request,
@@ -307,22 +308,25 @@
.sta_add_debugfs = mt7996_sta_add_debugfs,
#endif
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 43a4f939..24adeb12 100644
+index 665457a..0d2053c 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
-@@ -2467,7 +2467,10 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
- release_firmware(fw); \
- } while (0)
+@@ -2515,8 +2515,12 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
+ {
+ int ret;
-- LOAD_RAM(WM);
+- ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
+- MT7996_RAM_TYPE_WM);
+ if (dev->testmode_enable)
-+ LOAD_RAM(WM_TM);
++ ret = __mt7996_load_ram(dev, "WM_TM", MT7996_FIRMWARE_WM_TM,
++ MT7996_RAM_TYPE_WM_TM);
+ else
-+ LOAD_RAM(WM);
- LOAD_RAM(DSP);
- LOAD_RAM(WA);
- #undef LOAD_RAM
-@@ -4012,3 +4015,37 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
++ ret = __mt7996_load_ram(dev, "WM", MT7996_FIRMWARE_WM,
++ MT7996_RAM_TYPE_WM);
+ if (ret)
+ return ret;
+
+@@ -4066,3 +4070,37 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(RRO), &req,
sizeof(req), true);
}
@@ -361,10 +365,10 @@
+ &req, sizeof(req), false);
+}
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index 778deedf..ebc62713 100644
+index f235175..4ba06d9 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
-@@ -686,6 +686,33 @@ enum {
+@@ -703,6 +703,33 @@ enum {
UNI_CMD_THERMAL_PROTECT_DUTY_CONFIG,
};
@@ -399,10 +403,10 @@
UNI_CMD_ACCESS_REG_BASIC = 0x0,
UNI_CMD_ACCESS_RF_REG_BASIC,
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index ab4521a4..9bf3bf1a 100644
+index 071031b..f7d6580 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
-@@ -30,9 +30,11 @@
+@@ -31,9 +31,11 @@
#define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin"
#define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin"
#define MT7996_FIRMWARE_DSP "mediatek/mt7996/mt7996_dsp.bin"
@@ -413,16 +417,16 @@
+#define MT7996_EEPROM_DEFAULT_TM "mediatek/mt7996/mt7996_eeprom_tm.bin"
#define MT7996_EEPROM_SIZE 7680
#define MT7996_EEPROM_BLOCK_SIZE 16
- #define MT7996_TOKEN_SIZE 8192
-@@ -62,6 +64,7 @@ struct mt7996_dfs_pattern;
+ #define MT7996_TOKEN_SIZE 16384
+@@ -63,6 +65,7 @@ struct mt7996_dfs_pattern;
enum mt7996_ram_type {
- MT7996_RAM_TYPE_WM = 0,
+ MT7996_RAM_TYPE_WM,
+ MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
MT7996_RAM_TYPE_WA,
MT7996_RAM_TYPE_DSP,
};
-@@ -243,6 +246,20 @@ struct mt7996_phy {
+@@ -244,6 +247,20 @@ struct mt7996_phy {
struct mib_stats mib;
struct mt76_channel_state state_ts;
@@ -443,7 +447,7 @@
};
struct mt7996_dev {
-@@ -302,6 +319,8 @@ struct mt7996_dev {
+@@ -303,6 +320,8 @@ struct mt7996_dev {
bool flash_mode:1;
bool has_eht:1;
@@ -452,7 +456,7 @@
bool ibf;
u8 fw_debug_wm;
u8 fw_debug_wa;
-@@ -407,6 +426,7 @@ mt7996_phy3(struct mt7996_dev *dev)
+@@ -408,6 +427,7 @@ mt7996_phy3(struct mt7996_dev *dev)
extern const struct ieee80211_ops mt7996_ops;
extern struct pci_driver mt7996_pci_driver;
extern struct pci_driver mt7996_hif_driver;
@@ -460,7 +464,7 @@
struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
void __iomem *mem_base, u32 device_id);
-@@ -416,6 +436,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+@@ -417,6 +437,7 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
int mt7996_register_device(struct mt7996_dev *dev);
void mt7996_unregister_device(struct mt7996_dev *dev);
int mt7996_eeprom_init(struct mt7996_dev *dev);
@@ -468,7 +472,7 @@
int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
struct ieee80211_channel *chan);
-@@ -492,6 +513,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
+@@ -494,6 +515,7 @@ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
void mt7996_mcu_exit(struct mt7996_dev *dev);
@@ -478,10 +482,10 @@
{
diff --git a/mt7996/testmode.c b/mt7996/testmode.c
new file mode 100644
-index 00000000..6d7cdbd5
+index 0000000..43eca4e
--- /dev/null
+++ b/mt7996/testmode.c
-@@ -0,0 +1,632 @@
+@@ -0,0 +1,658 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (C) 2022 MediaTek Inc.
@@ -554,6 +558,27 @@
+}
+
+static int
++mt7996_tm_check_antenna(struct mt7996_phy *phy)
++{
++ struct mt76_testmode_data *td = &phy->mt76->test;
++ struct mt7996_dev *dev = phy->dev;
++ u8 band_idx = phy->mt76->band_idx;
++ u32 chainmask = phy->mt76->chainmask;
++ u32 aux_rx_mask;
++
++ chainmask = chainmask >> dev->chainshift[band_idx];
++ aux_rx_mask = BIT(fls(chainmask)) * phy->has_aux_rx;
++ if (td->tx_antenna_mask & ~(chainmask | aux_rx_mask)) {
++ dev_err(dev->mt76.dev,
++ "tx antenna mask 0x%x exceeds hw limit (chainmask 0x%x, has aux rx: %s)\n",
++ td->tx_antenna_mask, chainmask, phy->has_aux_rx ? "yes" : "no");
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int
+mt7996_tm_set(struct mt7996_dev *dev, u32 func_idx, u32 data)
+{
+ struct mt7996_tm_req req = {
@@ -603,6 +628,7 @@
+mt7996_tm_set_antenna(struct mt7996_phy *phy, u32 func_idx)
+{
+#define SPE_INDEX_MASK BIT(31)
++#define TX_ANTENNA_MASK GENMASK(3, 0)
+#define RX_ANTENNA_MASK GENMASK(20, 16) /* RX antenna mask at most 5 bit */
+ struct mt7996_dev *dev = phy->dev;
+ struct mt76_testmode_data *td = &phy->mt76->test;
@@ -613,7 +639,7 @@
+
+ if (func_idx == SET_ID(TX_PATH))
+ antenna_mask = td->tx_spe_idx ? (SPE_INDEX_MASK | td->tx_spe_idx) :
-+ td->tx_antenna_mask;
++ td->tx_antenna_mask & TX_ANTENNA_MASK;
+ else if (func_idx == SET_ID(RX_PATH))
+ antenna_mask = u32_encode_bits(td->tx_antenna_mask, RX_ANTENNA_MASK);
+ else
@@ -758,6 +784,7 @@
+ }
+
+ mt7996_tm_set_antenna(phy, SET_ID(TX_PATH));
++ mt7996_tm_set_antenna(phy, SET_ID(RX_PATH));
+ mt7996_tm_set(dev, SET_ID(STBC), td->tx_rate_stbc);
+ mt7996_tm_set(dev, SET_ID(ENCODE_MODE), td->tx_rate_ldpc);
+ mt7996_tm_set(dev, SET_ID(IBF_ENABLE), td->ibf);
@@ -914,7 +941,7 @@
+ (state == MT76_TM_STATE_OFF &&
+ prev_state == MT76_TM_STATE_IDLE)) {
+ u32 changed = 0;
-+ int i;
++ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
+ u16 cur = tm_change_map[i];
@@ -923,6 +950,10 @@
+ changed |= BIT(i);
+ }
+
++ ret = mt7996_tm_check_antenna(phy);
++ if (ret)
++ return ret;
++
+ mt7996_tm_update_params(phy, changed);
+ }
+
@@ -936,9 +967,8 @@
+ struct mt76_testmode_data *td = &mphy->test;
+ struct mt7996_phy *phy = mphy->priv;
+ struct mt7996_dev *dev = phy->dev;
-+ u32 chainmask = mphy->chainmask, changed = 0;
-+ u8 band_idx = phy->mt76->band_idx;
-+ int i;
++ u32 changed = 0;
++ int i, ret;
+
+ BUILD_BUG_ON(NUM_TM_CHANGED >= 32);
+
@@ -946,9 +976,9 @@
+ td->state == MT76_TM_STATE_OFF)
+ return 0;
+
-+ chainmask = chainmask >> dev->chainshift[band_idx];
-+ if (td->tx_antenna_mask > chainmask)
-+ return -EINVAL;
++ ret = mt7996_tm_check_antenna(phy);
++ if (ret)
++ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
+ if (tb[tm_change_map[i]])
@@ -1116,7 +1146,7 @@
+};
diff --git a/mt7996/testmode.h b/mt7996/testmode.h
new file mode 100644
-index 00000000..f00e51f4
+index 0000000..f00e51f
--- /dev/null
+++ b/mt7996/testmode.h
@@ -0,0 +1,295 @@
@@ -1416,7 +1446,7 @@
+
+#endif
diff --git a/testmode.c b/testmode.c
-index 0d2bae9f..fc68c2af 100644
+index 0d2bae9..fc68c2a 100644
--- a/testmode.c
+++ b/testmode.c
@@ -2,6 +2,7 @@
@@ -1590,7 +1620,7 @@
nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
diff --git a/testmode.h b/testmode.h
-index a40cd74b..8d0b9702 100644
+index a40cd74..8d0b970 100644
--- a/testmode.h
+++ b/testmode.h
@@ -39,6 +39,11 @@
@@ -1710,7 +1740,7 @@
/* keep last */
NUM_MT76_TM_TX_MODES,
diff --git a/tools/fields.c b/tools/fields.c
-index e3f69089..e5cf7c53 100644
+index e3f6908..e5cf7c5 100644
--- a/tools/fields.c
+++ b/tools/fields.c
@@ -10,6 +10,7 @@ static const char * const testmode_state[] = {
@@ -1872,5 +1902,5 @@
const struct tm_field msg_field = {
--
-2.39.2
+2.18.0
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-add-led-feature-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-add-led-feature-support.patch
new file mode 100644
index 0000000..06e273a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0026-wifi-mt76-mt7996-add-led-feature-support.patch
@@ -0,0 +1,105 @@
+From 030159528eff349db01b6b47b6fff8112b4282a4 Mon Sep 17 00:00:00 2001
+From: mtk25577 <jen-hao.cheng@mediatek.com>
+Date: Tue, 28 Mar 2023 18:23:00 +0800
+Subject: [PATCH 26/39] wifi: mt76: mt7996: add led feature support
+
+Signed-off-by: mtk25577 <jen-hao.cheng@mediatek.com>
+---
+ mt7996/Makefile | 1 +
+ mt7996/init.c | 33 +++++++++++++++++++++------------
+ mt7996/regs.h | 1 +
+ 3 files changed, 23 insertions(+), 12 deletions(-)
+
+diff --git a/mt7996/Makefile b/mt7996/Makefile
+index bed9efd..7c2514a 100644
+--- a/mt7996/Makefile
++++ b/mt7996/Makefile
+@@ -1,4 +1,5 @@
+ # SPDX-License-Identifier: ISC
++EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
+
+ obj-$(CONFIG_MT7996E) += mt7996e.o
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index fecd0d3..192af3f 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -232,23 +232,31 @@ static void mt7996_led_set_config(struct led_classdev *led_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);
++ mt76_rmw_field(dev, MT_TMAC_TCR0(mphy->band_idx), MT_TMAC_TCR0_TX_BLINK, 2);
+
+ /* enable LED */
+- mt76_wr(dev, MT_LED_EN(0), 1);
++ mt76_wr(dev, MT_LED_EN(mphy->band_idx), 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_TX_BLINK(mphy->band_idx), val);
++
++ /* turn LED off */
++ if (delay_off == 0xff && delay_on == 0x0)
++ val = MT_LED_CTRL_POLARITY | MT_LED_CTRL_KICK;
++ else {
++ /* control LED */
++ val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
++ if (mphy->band_idx == MT_BAND1)
++ val |= MT_LED_CTRL_BLINK_BAND_SEL;
++ }
+
+- /* control LED */
+- val = MT_LED_CTRL_BLINK_MODE | MT_LED_CTRL_KICK;
+ if (mphy->leds.al)
+ val |= MT_LED_CTRL_POLARITY;
+
+- 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 mt7996_led_set_blink(struct led_classdev *led_cdev,
+@@ -400,6 +408,12 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
+ }
+
++ /* init led callbacks */
++ if (IS_ENABLED(CONFIG_MT76_LEDS)) {
++ phy->mt76->leds.cdev.brightness_set = mt7996_led_set_brightness;
++ phy->mt76->leds.cdev.blink_set = mt7996_led_set_blink;
++ }
++
+ mt76_set_stream_caps(phy->mt76, true);
+ mt7996_set_stream_vht_txbf_caps(phy);
+ mt7996_set_stream_he_eht_caps(phy);
+@@ -1063,11 +1077,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ #ifdef CONFIG_NL80211_TESTMODE
+ dev->mt76.test_ops = &mt7996_testmode_ops;
+ #endif
+- /* init led callbacks */
+- if (IS_ENABLED(CONFIG_MT76_LEDS)) {
+- 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,
+ ARRAY_SIZE(mt76_rates));
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index d1d3d15..86da1bf 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -509,6 +509,7 @@ enum base_rev {
+
+ #define MT_LED_CTRL(_n) MT_LED_PHYS(0x00 + ((_n) * 4))
+ #define MT_LED_CTRL_KICK BIT(7)
++#define MT_LED_CTRL_BLINK_BAND_SEL BIT(4)
+ #define MT_LED_CTRL_BLINK_MODE BIT(2)
+ #define MT_LED_CTRL_POLARITY BIT(1)
+
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch
new file mode 100644
index 0000000..2e938b7
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch
@@ -0,0 +1,60 @@
+From e503dbe84bc2b46907a792e11c196018b274647a Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Tue, 28 Mar 2023 20:20:57 +0800
+Subject: [PATCH 27/39] wifi: mt76: mt7996: fix twt mcu command
+
+Update unified command for twt.
+
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+---
+ mt7915/mcu.h | 1 -
+ mt7996/mcu.c | 7 +++++--
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index b9ea297..e7a5395 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -264,7 +264,6 @@ enum {
+ MCU_TWT_AGRT_MODIFY,
+ MCU_TWT_AGRT_DELETE,
+ MCU_TWT_AGRT_TEARDOWN,
+- MCU_TWT_AGRT_GET_TSF,
+ };
+
+ enum {
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index a6d8235..6bcb33e 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3823,7 +3823,9 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
+ int cmd)
+ {
+ struct {
+- u8 _rsv[4];
++ /* fixed field */
++ u8 bss;
++ u8 _rsv[3];
+
+ __le16 tag;
+ __le16 len;
+@@ -3841,7 +3843,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
+ u8 exponent;
+ u8 is_ap;
+ u8 agrt_params;
+- u8 __rsv2[135];
++ u8 __rsv2[23];
+ } __packed req = {
+ .tag = cpu_to_le16(UNI_CMD_TWT_ARGT_UPDATE),
+ .len = cpu_to_le16(sizeof(req) - 4),
+@@ -3851,6 +3853,7 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev,
+ .flowid = flow->id,
+ .peer_id = cpu_to_le16(flow->wcid),
+ .duration = flow->duration,
++ .bss = mvif->mt76.idx,
+ .bss_idx = mvif->mt76.idx,
+ .start_tsf = cpu_to_le64(flow->tsf),
+ .mantissa = flow->mantissa,
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch
new file mode 100644
index 0000000..bf724c8
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch
@@ -0,0 +1,181 @@
+From 0449694e4e963d0b48354ae2c52016c34899fba6 Mon Sep 17 00:00:00 2001
+From: mtk20656 <chank.chen@mediatek.com>
+Date: Wed, 8 Mar 2023 14:18:29 +0800
+Subject: [PATCH 28/39] wifi: mt76: mt7996: add 11v mbss support for mt76
+
+Signed-off-by: mtk20656 <chank.chen@mediatek.com>
+---
+ mt76_connac_mcu.h | 10 ++++++
+ mt7996/init.c | 2 ++
+ mt7996/mcu.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++-
+ 3 files changed, 90 insertions(+), 1 deletion(-)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 724a48a..97f874b 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1281,6 +1281,7 @@ enum {
+ UNI_BSS_INFO_RLM = 2,
+ UNI_BSS_INFO_BSS_COLOR = 4,
+ UNI_BSS_INFO_HE_BASIC = 5,
++ UNI_BSS_INFO_11V_MBSSID = 6,
+ UNI_BSS_INFO_BCN_CONTENT = 7,
+ UNI_BSS_INFO_BCN_CSA = 8,
+ UNI_BSS_INFO_BCN_BCC = 9,
+@@ -1551,6 +1552,15 @@ struct bss_info_uni_he {
+ u8 rsv[2];
+ } __packed;
+
++struct bss_info_uni_mbssid {
++ __le16 tag;
++ __le16 len;
++ u8 max_indicator;
++ u8 mbss_idx;
++ u8 tx_bss_omac_idx;
++ u8 rsv[1];
++} __packed;
++
+ struct mt76_connac_gtk_rekey_tlv {
+ __le16 tag;
+ __le16 len;
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 192af3f..0562439 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -359,6 +359,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
+ wiphy->reg_notifier = mt7996_regd_notifier;
+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
++ wiphy->mbssid_max_interfaces = 16;
+
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BSS_COLOR);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+@@ -381,6 +382,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
+ ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD);
+ ieee80211_hw_set(hw, WANT_MONITOR_VIF);
++ ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
+
+ hw->max_tx_fragments = 4;
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 6bcb33e..a369a08 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -631,6 +631,24 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
+ he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
+ }
+
++static void
++mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
++ struct mt7996_phy *phy)
++{
++ struct bss_info_uni_mbssid *mbssid;
++ struct tlv *tlv;
++
++ tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_11V_MBSSID, sizeof(*mbssid));
++
++ mbssid = (struct bss_info_uni_mbssid *)tlv;
++
++ mbssid->max_indicator = vif->bss_conf.bssid_indicator;
++ mbssid->mbss_idx = vif->bss_conf.bssid_index;
++ mbssid->tx_bss_omac_idx = 0;
++
++ return;
++}
++
+ static void
+ mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
+ struct mt7996_phy *phy)
+@@ -895,6 +913,9 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
+ if (vif->bss_conf.he_support)
+ mt7996_mcu_bss_he_tlv(skb, vif, phy);
+
++ if (vif->bss_conf.bssid_indicator)
++ mt7996_mcu_bss_mbssid_tlv(skb, vif, phy);
++
+ /* this tag is necessary no matter if the vif is MLD */
+ mt7996_mcu_bss_mld_tlv(skb, vif);
+ }
+@@ -2162,6 +2183,59 @@ mt7996_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb,
+ info->cnt = skb->data[offs->cntdwn_counter_offs[0]];
+ }
+
++static void
++mt7996_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb,
++ struct ieee80211_vif *vif, struct bss_bcn_content_tlv *bcn,
++ struct ieee80211_mutable_offsets *offs)
++{
++ struct bss_bcn_mbss_tlv *mbss;
++ const struct element *elem;
++ struct tlv *tlv;
++
++ if (!vif->bss_conf.bssid_indicator)
++ return;
++
++ tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_MBSSID, sizeof(*mbss));
++
++ mbss = (struct bss_bcn_mbss_tlv *)tlv;
++ mbss->offset[0] = cpu_to_le16(offs->tim_offset);
++ mbss->bitmap = cpu_to_le32(1);
++
++ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID,
++ &skb->data[offs->mbssid_off],
++ skb->len - offs->mbssid_off) {
++ const struct element *sub_elem;
++
++ if (elem->datalen < 2)
++ continue;
++
++ for_each_element(sub_elem, elem->data + 1, elem->datalen - 1) {
++ const struct ieee80211_bssid_index *idx;
++ const u8 *idx_ie;
++
++ if (sub_elem->id || sub_elem->datalen < 4)
++ continue; /* not a valid BSS profile */
++
++ /* Find WLAN_EID_MULTI_BSSID_IDX
++ * in the merged nontransmitted profile
++ */
++ idx_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
++ sub_elem->data,
++ sub_elem->datalen);
++ if (!idx_ie || idx_ie[1] < sizeof(*idx))
++ continue;
++
++ idx = (void *)(idx_ie + 2);
++ if (!idx->bssid_index || idx->bssid_index > 31)
++ continue;
++
++ mbss->offset[idx->bssid_index] =
++ cpu_to_le16(idx_ie - skb->data);
++ mbss->bitmap |= cpu_to_le32(BIT(idx->bssid_index));
++ }
++ }
++}
++
+ static void
+ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ struct sk_buff *rskb, struct sk_buff *skb,
+@@ -2202,6 +2276,9 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
+ struct tlv *tlv;
+ struct bss_bcn_content_tlv *bcn;
+
++ if (vif->bss_conf.nontransmitted)
++ return 0;
++
+ rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
+ MT7996_BEACON_UPDATE_SIZE);
+ if (IS_ERR(rskb))
+@@ -2229,7 +2306,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
+ info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
+
+ mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
+- /* TODO: subtag - 11v MBSSID */
++ mt7996_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);
+ mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs);
+ dev_kfree_skb(skb);
+ out:
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch
new file mode 100644
index 0000000..67e5c6c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch
@@ -0,0 +1,188 @@
+From 8b591f425b1bb71ebde4a1eb9c926f0c9017fe28 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Mon, 27 Mar 2023 09:47:44 +0800
+Subject: [PATCH 29/39] wifi: mt76: mt7996: Update beacon size limitation for
+ 11v
+
+The TLV size limitation for these two has been expanded to
+accommodate 11v MBSSID IE.
+
+Co-developed-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
+Co-developed-by: Money Wang <Money.Wang@mediatek.com>
+Signed-off-by: Money Wang <Money.Wang@mediatek.com>
+Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+---
+ mt7996/main.c | 4 ++--
+ mt7996/mcu.c | 39 +++++++++++++++++++++++----------------
+ mt7996/mcu.h | 11 ++++-------
+ 3 files changed, 29 insertions(+), 25 deletions(-)
+
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 6c38993..520f250 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -618,8 +618,8 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
+ mt7996_mcu_add_beacon(hw, vif, info->enable_beacon);
+ }
+
+- if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
+- changed & BSS_CHANGED_FILS_DISCOVERY)
++ if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
++ BSS_CHANGED_FILS_DISCOVERY))
+ mt7996_mcu_beacon_inband_discov(dev, vif, changed);
+
+ mutex_unlock(&dev->mt76.mutex);
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index a369a08..7b8f883 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2257,7 +2257,7 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif,
+ bcn->bcc_ie_pos = cpu_to_le16(offset - 3);
+ }
+
+- buf = (u8 *)bcn + sizeof(*bcn) - MAX_BEACON_SIZE;
++ buf = (u8 *)bcn + sizeof(*bcn);
+ mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0,
+ BSS_CHANGED_BEACON);
+
+@@ -2275,28 +2275,21 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
+ struct sk_buff *skb, *rskb;
+ struct tlv *tlv;
+ struct bss_bcn_content_tlv *bcn;
++ int len;
+
+ if (vif->bss_conf.nontransmitted)
+ return 0;
+
+ rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
+- MT7996_BEACON_UPDATE_SIZE);
++ MT7996_MAX_BSS_OFFLOAD_SIZE);
+ if (IS_ERR(rskb))
+ return PTR_ERR(rskb);
+
+- tlv = mt7996_mcu_add_uni_tlv(rskb,
+- UNI_BSS_INFO_BCN_CONTENT, sizeof(*bcn));
+- bcn = (struct bss_bcn_content_tlv *)tlv;
+- bcn->enable = en;
+-
+- if (!en)
+- goto out;
+-
+ skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
+ if (!skb)
+ return -EINVAL;
+
+- if (skb->len > MAX_BEACON_SIZE - MT_TXD_SIZE) {
++ if (skb->len > MT7996_MAX_BEACON_SIZE) {
+ dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
+ dev_kfree_skb(skb);
+ return -EINVAL;
+@@ -2305,11 +2298,19 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
+ info = IEEE80211_SKB_CB(skb);
+ info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
+
++ len = sizeof(*bcn) + MT_TXD_SIZE + skb->len;
++ tlv = mt7996_mcu_add_uni_tlv(rskb,
++ UNI_BSS_INFO_BCN_CONTENT, len);
++ bcn = (struct bss_bcn_content_tlv *)tlv;
++ bcn->enable = en;
++ if (!en)
++ goto out;
++
+ mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
+ mt7996_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs);
+ mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs);
+- dev_kfree_skb(skb);
+ out:
++ dev_kfree_skb(skb);
+ return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
+ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
+ }
+@@ -2330,9 +2331,13 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ struct sk_buff *rskb, *skb = NULL;
+ struct tlv *tlv;
+ u8 *buf, interval;
++ int len;
++
++ if (vif->bss_conf.nontransmitted)
++ return 0;
+
+ rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
+- MT7996_INBAND_FRAME_SIZE);
++ MT7996_MAX_BSS_OFFLOAD_SIZE);
+ if (IS_ERR(rskb))
+ return PTR_ERR(rskb);
+
+@@ -2349,7 +2354,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ if (!skb)
+ return -EINVAL;
+
+- if (skb->len > MAX_INBAND_FRAME_SIZE - MT_TXD_SIZE) {
++ if (skb->len > MT7996_MAX_BEACON_SIZE) {
+ dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
+ dev_kfree_skb(skb);
+ return -EINVAL;
+@@ -2360,7 +2365,9 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ info->band = band;
+ info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx);
+
+- tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, sizeof(*discov));
++ len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
++
++ tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_OFFLOAD, len);
+
+ discov = (struct bss_inband_discovery_tlv *)tlv;
+ discov->tx_mode = OFFLOAD_TX_MODE_SU;
+@@ -2371,7 +2378,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ discov->enable = true;
+ discov->wcid = cpu_to_le16(MT7996_WTBL_RESERVED);
+
+- buf = (u8 *)tlv + sizeof(*discov) - MAX_INBAND_FRAME_SIZE;
++ buf = (u8 *)tlv + sizeof(*discov);
+
+ mt7996_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, NULL, 0, 0, changed);
+
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 4ba06d9..eed7371 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -308,8 +308,6 @@ struct bss_inband_discovery_tlv {
+ u8 enable;
+ __le16 wcid;
+ __le16 prob_rsp_len;
+-#define MAX_INBAND_FRAME_SIZE 512
+- u8 pkt[MAX_INBAND_FRAME_SIZE];
+ } __packed;
+
+ struct bss_bcn_content_tlv {
+@@ -321,8 +319,6 @@ struct bss_bcn_content_tlv {
+ u8 enable;
+ u8 type;
+ __le16 pkt_len;
+-#define MAX_BEACON_SIZE 512
+- u8 pkt[MAX_BEACON_SIZE];
+ } __packed;
+
+ struct bss_bcn_cntdwn_tlv {
+@@ -629,13 +625,14 @@ enum {
+ sizeof(struct sta_rec_hdr_trans) + \
+ sizeof(struct tlv))
+
++#define MT7996_MAX_BEACON_SIZE 1342
+ #define MT7996_BEACON_UPDATE_SIZE (sizeof(struct bss_req_hdr) + \
+ sizeof(struct bss_bcn_content_tlv) + \
++ MT_TXD_SIZE + \
+ sizeof(struct bss_bcn_cntdwn_tlv) + \
+ sizeof(struct bss_bcn_mbss_tlv))
+-
+-#define MT7996_INBAND_FRAME_SIZE (sizeof(struct bss_req_hdr) + \
+- sizeof(struct bss_inband_discovery_tlv))
++#define MT7996_MAX_BSS_OFFLOAD_SIZE (MT7996_MAX_BEACON_SIZE + \
++ MT7996_BEACON_UPDATE_SIZE)
+
+ enum {
+ UNI_BAND_CONFIG_RADIO_ENABLE,
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
new file mode 100644
index 0000000..798eb69
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0030-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch
@@ -0,0 +1,138 @@
+From 7390e5db3745febd580026e723b2ca806e308008 Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Fri, 14 Apr 2023 16:51:59 +0800
+Subject: [PATCH 30/39] wifi: mt76: mt7996: add support for auxiliary path
+
+Add support to correctly configure the setting of variants that have
+additional TX or RX path.
+
+Change-Id: I1312c193beab5e16aae7161a7e3bdda100b72f8d
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/eeprom.c | 21 +++++++++++++++++----
+ mt7996/eeprom.h | 3 +++
+ mt7996/mcu.c | 2 +-
+ mt7996/mt7996.h | 14 ++++++++++++++
+ 4 files changed, 35 insertions(+), 5 deletions(-)
+
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index f5e9546..9840c77 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -171,36 +171,49 @@ static int mt7996_eeprom_parse_band_config(struct mt7996_phy *phy)
+
+ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
+ {
+- u8 path, nss, band_idx = phy->mt76->band_idx;
++ u8 path, rx_path, nss, band_idx = phy->mt76->band_idx;
+ u8 *eeprom = dev->mt76.eeprom.data;
+ struct mt76_phy *mphy = phy->mt76;
++ int max_path = 5, max_nss = 4;
+ int ret;
+
+ switch (band_idx) {
+ case MT_BAND1:
+ path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND1,
+ eeprom[MT_EE_WIFI_CONF + 2]);
++ rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND1,
++ eeprom[MT_EE_WIFI_CONF + 3]);
+ nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND1,
+ eeprom[MT_EE_WIFI_CONF + 5]);
+ break;
+ case MT_BAND2:
+ path = FIELD_GET(MT_EE_WIFI_CONF2_TX_PATH_BAND2,
+ eeprom[MT_EE_WIFI_CONF + 2]);
++ rx_path = FIELD_GET(MT_EE_WIFI_CONF4_RX_PATH_BAND2,
++ eeprom[MT_EE_WIFI_CONF + 4]);
+ nss = FIELD_GET(MT_EE_WIFI_CONF5_STREAM_NUM_BAND2,
+ eeprom[MT_EE_WIFI_CONF + 5]);
+ break;
+ default:
+ path = FIELD_GET(MT_EE_WIFI_CONF1_TX_PATH_BAND0,
+ eeprom[MT_EE_WIFI_CONF + 1]);
++ rx_path = FIELD_GET(MT_EE_WIFI_CONF3_RX_PATH_BAND0,
++ eeprom[MT_EE_WIFI_CONF + 3]);
+ nss = FIELD_GET(MT_EE_WIFI_CONF4_STREAM_NUM_BAND0,
+ eeprom[MT_EE_WIFI_CONF + 4]);
+ break;
+ }
+
+- if (!path || path > 4)
+- path = 4;
++ if (!path || path > max_path)
++ path = max_path;
+
+- nss = min_t(u8, min_t(u8, 4, nss), path);
++ if (!nss || nss > max_nss)
++ nss = max_nss;
++
++ nss = min_t(u8, nss, path);
++
++ if (path != rx_path)
++ phy->has_aux_rx = true;
+
+ mphy->antenna_mask = BIT(nss) - 1;
+ mphy->chainmask = (BIT(path) - 1) << dev->chainshift[band_idx];
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 0f8f0cd..9ea3667 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -34,6 +34,9 @@ enum mt7996_eeprom_field {
+ #define MT_EE_WIFI_CONF1_TX_PATH_BAND0 GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(2, 0)
+ #define MT_EE_WIFI_CONF2_TX_PATH_BAND2 GENMASK(5, 3)
++#define MT_EE_WIFI_CONF3_RX_PATH_BAND0 GENMASK(2, 0)
++#define MT_EE_WIFI_CONF3_RX_PATH_BAND1 GENMASK(5, 3)
++#define MT_EE_WIFI_CONF4_RX_PATH_BAND2 GENMASK(2, 0)
+ #define MT_EE_WIFI_CONF4_STREAM_NUM_BAND0 GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF5_STREAM_NUM_BAND1 GENMASK(2, 0)
+ #define MT_EE_WIFI_CONF5_STREAM_NUM_BAND2 GENMASK(5, 3)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 7b8f883..a2c1e43 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3198,7 +3198,7 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
+ .center_ch = ieee80211_frequency_to_channel(freq1),
+ .bw = mt76_connac_chan_bw(chandef),
+ .tx_path_num = hweight16(phy->mt76->chainmask),
+- .rx_path = phy->mt76->chainmask >> dev->chainshift[band_idx],
++ .rx_path = mt7996_rx_chainmask(phy) >> dev->chainshift[band_idx],
+ .band_idx = band_idx,
+ .channel_band = ch_band[chandef->chan->band],
+ };
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index f7d6580..8e5b3c3 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -248,6 +248,8 @@ struct mt7996_phy {
+ struct mib_stats mib;
+ struct mt76_channel_state state_ts;
+
++ bool has_aux_rx;
++
+ #ifdef CONFIG_NL80211_TESTMODE
+ struct {
+ u32 *reg_backup;
+@@ -551,6 +553,18 @@ static inline void mt7996_irq_disable(struct mt7996_dev *dev, u32 mask)
+ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset,
+ size_t len);
+
++static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy)
++{
++ int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx);
++ int cur_nss = hweight8(phy->mt76->antenna_mask);
++ u16 tx_chainmask = phy->mt76->chainmask;
++
++ if (cur_nss != max_nss)
++ return tx_chainmask;
++
++ return tx_chainmask | (BIT(fls(tx_chainmask)) * phy->has_aux_rx);
++}
++
+ void mt7996_mac_init(struct mt7996_dev *dev);
+ u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw);
+ bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask);
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-fix-memory-leak.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-fix-memory-leak.patch
new file mode 100644
index 0000000..0669836
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0031-wifi-mt76-mt7996-fix-memory-leak.patch
@@ -0,0 +1,49 @@
+From 80a4f15fa3077ef5a340a4af5b12fda8d958c337 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Tue, 18 Apr 2023 19:49:45 +0800
+Subject: [PATCH 31/39] wifi: mt76: mt7996: fix memory leak.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ mt7996/mcu.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index a2c1e43..f98a48d 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2286,11 +2286,14 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw,
+ return PTR_ERR(rskb);
+
+ skb = ieee80211_beacon_get_template(hw, vif, &offs, 0);
+- if (!skb)
++ if (!skb) {
++ dev_kfree_skb(rskb);
+ return -EINVAL;
++ }
+
+ if (skb->len > MT7996_MAX_BEACON_SIZE) {
+ dev_err(dev->mt76.dev, "Bcn size limit exceed\n");
++ dev_kfree_skb(rskb);
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+@@ -2351,11 +2354,14 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
+ }
+
+- if (!skb)
++ if (!skb) {
++ dev_kfree_skb(rskb);
+ return -EINVAL;
++ }
+
+ if (skb->len > MT7996_MAX_BEACON_SIZE) {
+ dev_err(dev->mt76.dev, "inband discovery size limit exceed\n");
++ dev_kfree_skb(rskb);
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0032-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0032-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
new file mode 100644
index 0000000..ba0e378
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0032-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch
@@ -0,0 +1,39 @@
+From fd7730026ccef8b0d5a52ac07ddb21af48def17d Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Thu, 20 Apr 2023 16:34:47 +0800
+Subject: [PATCH 32/39] wifi: mt76: mt7996: add eht mode tx stats
+
+Add eht mode bf fbk stats and bw320 through debugfs tx_stats command
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt7996/debugfs.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index 0422018..ca4d615 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -481,7 +481,7 @@ static void
+ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
+ {
+ static const char * const bw[] = {
+- "BW20", "BW40", "BW80", "BW160"
++ "BW20", "BW40", "BW80", "BW160", "BW320"
+ };
+ struct mib_stats *mib = &phy->mib;
+
+@@ -495,8 +495,9 @@ mt7996_txbf_stat_read_phy(struct mt7996_phy *phy, struct seq_file *s)
+ /* Tx Beamformer Rx feedback monitor */
+ seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
+
+- seq_printf(s, "All: %d, HE: %d, VHT: %d, HT: %d, ",
++ seq_printf(s, "All: %d, EHT: %d, HE: %d, VHT: %d, HT: %d, ",
+ mib->tx_bf_rx_fb_all_cnt,
++ mib->tx_bf_rx_fb_eht_cnt,
+ mib->tx_bf_rx_fb_he_cnt,
+ mib->tx_bf_rx_fb_vht_cnt,
+ mib->tx_bf_rx_fb_ht_cnt);
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch
new file mode 100644
index 0000000..a88d36a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch
@@ -0,0 +1,219 @@
+From d246d8300bcbf7dea19919d61df9d7553e21bd1b Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Wed, 26 Apr 2023 15:37:23 +0800
+Subject: [PATCH 33/39] wifi: mt76: mt7996: disable wfdma tx/rx during SER
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ dma.c | 6 ++++
+ mt7996/dma.c | 79 ++++++++++++++++++++++++++++++-------------------
+ mt7996/mac.c | 13 ++++++--
+ mt7996/mt7996.h | 1 +
+ 4 files changed, 65 insertions(+), 34 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 465190e..f2b1b2a 100644
+--- a/dma.c
++++ b/dma.c
+@@ -466,6 +466,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;
+
+@@ -507,6 +510,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+ dma_addr_t addr;
+ u8 *txwi;
+
++ if (test_bit(MT76_MCU_RESET, &dev->phy.state))
++ goto free_skb;
++
+ t = mt76_get_txwi(dev);
+ if (!t)
+ goto free_skb;
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index fbedaac..6a21e3e 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -128,11 +128,55 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
+ }
+ }
+
+-static int mt7996_dma_enable(struct mt7996_dev *dev)
++void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ {
+ u32 hif1_ofs = 0;
+ u32 irq_mask;
+
++ if (dev->hif2)
++ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++ /* enable wpdma tx/rx */
++ if (!reset) {
++ mt76_set(dev, MT_WFDMA0_GLO_CFG,
++ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++
++ if (dev->hif2)
++ mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
++ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++ }
++
++ /* enable interrupts for TX/RX rings */
++ irq_mask = MT_INT_MCU_CMD;
++ if (reset)
++ goto done;
++
++ irq_mask |= (MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU);
++
++ if (!dev->mphy.band_idx)
++ irq_mask |= MT_INT_BAND0_RX_DONE;
++
++ if (dev->dbdc_support)
++ irq_mask |= MT_INT_BAND1_RX_DONE;
++
++ if (dev->tbtc_support)
++ irq_mask |= MT_INT_BAND2_RX_DONE;
++
++done:
++ mt7996_irq_enable(dev, irq_mask);
++ mt7996_irq_disable(dev, 0);
++}
++
++static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
++{
++ u32 hif1_ofs = 0;
++
+ if (dev->hif2)
+ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
+
+@@ -170,13 +214,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
+ mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
+ MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
+
+- /* set WFDMA Tx/Rx */
+- mt76_set(dev, MT_WFDMA0_GLO_CFG,
+- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+ /* GLO_CFG_EXT0 */
+ mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0,
+ WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
+@@ -187,12 +224,6 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
+ WF_WFDMA0_GLO_CFG_EXT1_TX_FCTRL_MODE);
+
+ if (dev->hif2) {
+- mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
+- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+-
+ /* GLO_CFG_EXT0 */
+ mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT0 + hif1_ofs,
+ WF_WFDMA0_GLO_CFG_EXT0_RX_WB_RXD |
+@@ -216,21 +247,7 @@ static int mt7996_dma_enable(struct mt7996_dev *dev)
+ /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
+ }
+
+- /* enable interrupts for TX/RX rings */
+- irq_mask = MT_INT_RX_DONE_MCU |
+- MT_INT_TX_DONE_MCU |
+- MT_INT_MCU_CMD;
+-
+- if (!dev->mphy.band_idx)
+- irq_mask |= MT_INT_BAND0_RX_DONE;
+-
+- if (dev->dbdc_support)
+- irq_mask |= MT_INT_BAND1_RX_DONE;
+-
+- if (dev->tbtc_support)
+- irq_mask |= MT_INT_BAND2_RX_DONE;
+-
+- mt7996_irq_enable(dev, irq_mask);
++ __mt7996_dma_enable(dev, reset);
+
+ return 0;
+ }
+@@ -347,7 +364,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ mt7996_poll_tx);
+ napi_enable(&dev->mt76.tx_napi);
+
+- mt7996_dma_enable(dev);
++ mt7996_dma_enable(dev, false);
+
+ return 0;
+ }
+@@ -413,7 +430,7 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+ mt76_for_each_q_rx(&dev->mt76, i)
+ mt76_queue_rx_reset(dev, i);
+
+- mt7996_dma_enable(dev);
++ mt7996_dma_enable(dev, !force);
+ }
+
+ void mt7996_dma_cleanup(struct mt7996_dev *dev)
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index bddb84f..986031f 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -2028,6 +2028,12 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ mt7996_wait_reset_state(dev, MT_MCU_CMD_RECOVERY_DONE);
+ }
+
++ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
++ mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
++
++ /* enable dma tx/rx and interrupt */
++ __mt7996_dma_enable(dev, false);
++
+ clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ clear_bit(MT76_RESET, &dev->mphy.state);
+ if (phy2)
+@@ -2044,9 +2050,6 @@ void mt7996_mac_reset_work(struct work_struct *work)
+
+ tasklet_schedule(&dev->mt76.irq_tasklet);
+
+- mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
+- mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+-
+ mt76_worker_enable(&dev->mt76.tx_worker);
+
+ local_bh_disable();
+@@ -2149,6 +2152,10 @@ skip_coredump:
+
+ void mt7996_reset(struct mt7996_dev *dev)
+ {
++ dev_info(dev->mt76.dev, "%s SER recovery state: 0x%08x\n",
++ wiphy_name(dev->mt76.hw->wiphy),
++ READ_ONCE(dev->recovery.state));
++
+ if (!dev->recovery.hw_init_done)
+ return;
+
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 8e5b3c3..561c1cd 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -448,6 +448,7 @@ int mt7996_dma_init(struct mt7996_dev *dev);
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
+ void mt7996_dma_prefetch(struct mt7996_dev *dev);
+ void mt7996_dma_cleanup(struct mt7996_dev *dev);
++void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset);
+ void mt7996_init_txpower(struct mt7996_dev *dev,
+ struct ieee80211_supported_band *sband);
+ int mt7996_txbf_init(struct mt7996_dev *dev);
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
new file mode 100644
index 0000000..3d4d1c0
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch
@@ -0,0 +1,598 @@
+From cf66e6fc90e7a12209bd0a3d9b687b37f7324718 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Fri, 19 May 2023 14:16:50 +0800
+Subject: [PATCH] wifi: mt76: mt7996: add firmware WA's coredump.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Change-Id: I51f115b4ae15bc0f871f93652570d72511dbf880
+---
+ mt7996/coredump.c | 180 ++++++++++++++++++++++++++++++----------------
+ mt7996/coredump.h | 35 ++++++---
+ mt7996/mac.c | 31 +++++---
+ mt7996/mcu.c | 5 ++
+ mt7996/mt7996.h | 7 +-
+ mt7996/regs.h | 7 +-
+ 6 files changed, 182 insertions(+), 83 deletions(-)
+
+diff --git a/mt7996/coredump.c b/mt7996/coredump.c
+index ccab0d7b..60b88085 100644
+--- a/mt7996/coredump.c
++++ b/mt7996/coredump.c
+@@ -7,11 +7,11 @@
+ #include <linux/utsname.h>
+ #include "coredump.h"
+
+-static bool coredump_memdump;
++static bool coredump_memdump = true;
+ module_param(coredump_memdump, bool, 0644);
+ MODULE_PARM_DESC(coredump_memdump, "Optional ability to dump firmware memory");
+
+-static const struct mt7996_mem_region mt7996_mem_regions[] = {
++static const struct mt7996_mem_region mt7996_wm_mem_regions[] = {
+ {
+ .start = 0x00800000,
+ .len = 0x0004ffff,
+@@ -44,27 +44,55 @@ static const struct mt7996_mem_region mt7996_mem_regions[] = {
+ },
+ };
+
++static const struct mt7996_mem_region mt7996_wa_mem_regions[] = {
++ {
++ .start = 0xE0000000,
++ .len = 0x0000ffff,
++ .name = "CRAM",
++ },
++ {
++ .start = 0xE0010000,
++ .len = 0x000117ff,
++ .name = "CRAM2",
++ },
++ {
++ .start = 0x10000000,
++ .len = 0x0001bfff,
++ .name = "ILM",
++ },
++ {
++ .start = 0x10200000,
++ .len = 0x00063fff,
++ .name = "DLM",
++ },
++};
++
+ const struct mt7996_mem_region*
+-mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u32 *num)
++mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u8 type, u32 *num)
+ {
+ switch (mt76_chip(&dev->mt76)) {
+ case 0x7990:
+ case 0x7991:
+- *num = ARRAY_SIZE(mt7996_mem_regions);
+- return &mt7996_mem_regions[0];
++ if (type == MT7996_RAM_TYPE_WA) {
++ *num = ARRAY_SIZE(mt7996_wa_mem_regions);
++ return &mt7996_wa_mem_regions[0];
++ }
++
++ *num = ARRAY_SIZE(mt7996_wm_mem_regions);
++ return &mt7996_wm_mem_regions[0];
+ default:
+ return NULL;
+ }
+ }
+
+-static int mt7996_coredump_get_mem_size(struct mt7996_dev *dev)
++static int mt7996_coredump_get_mem_size(struct mt7996_dev *dev, u8 type)
+ {
+ const struct mt7996_mem_region *mem_region;
+ size_t size = 0;
+ u32 num;
+ int i;
+
+- mem_region = mt7996_coredump_get_mem_layout(dev, &num);
++ mem_region = mt7996_coredump_get_mem_layout(dev, type, &num);
+ if (!mem_region)
+ return 0;
+
+@@ -81,14 +109,13 @@ static int mt7996_coredump_get_mem_size(struct mt7996_dev *dev)
+ return size;
+ }
+
+-struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev)
++struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
+ {
+- struct mt7996_crash_data *crash_data = dev->coredump.crash_data;
++ struct mt7996_crash_data *crash_data = dev->coredump.crash_data[type];
+
+ lockdep_assert_held(&dev->dump_mutex);
+
+- if (coredump_memdump &&
+- !mt76_poll_msec(dev, MT_FW_DUMP_STATE, 0x3, 0x2, 500))
++ if (!coredump_memdump)
+ return NULL;
+
+ guid_gen(&crash_data->guid);
+@@ -98,12 +125,15 @@ struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev)
+ }
+
+ static void
+-mt7996_coredump_fw_state(struct mt7996_dev *dev, struct mt7996_coredump *dump,
++mt7996_coredump_fw_state(struct mt7996_dev *dev, u8 type, struct mt7996_coredump *dump,
+ bool *exception)
+ {
+- u32 count;
++ u32 count, reg = MT_FW_WM_DUMP_STATE;
++
++ if (type == MT7996_RAM_TYPE_WA)
++ reg = MT_FW_WA_DUMP_STATE;
+
+- count = mt76_rr(dev, MT_FW_ASSERT_CNT);
++ count = mt76_rr(dev, reg);
+
+ /* normal mode: driver can manually trigger assert for detail info */
+ if (!count)
+@@ -115,53 +145,59 @@ mt7996_coredump_fw_state(struct mt7996_dev *dev, struct mt7996_coredump *dump,
+ }
+
+ static void
+-mt7996_coredump_fw_stack(struct mt7996_dev *dev, struct mt7996_coredump *dump,
++mt7996_coredump_fw_stack(struct mt7996_dev *dev, u8 type, struct mt7996_coredump *dump,
+ bool exception)
+ {
+- u32 oldest, i, idx;
++ u32 reg, i, offset = 0, val = MT7996_RAM_TYPE_WM;
+
+- strscpy(dump->pc_current, "program counter", sizeof(dump->pc_current));
++ if (type == MT7996_RAM_TYPE_WA) {
++ offset = MT_MCU_WA_EXCP_BASE - MT_MCU_WM_EXCP_BASE;
++ val = MT7996_RAM_TYPE_WA;
++ }
+
+- /* 0: WM PC log output */
+- mt76_wr(dev, MT_CONN_DBG_CTL_OUT_SEL, 0);
++ /* 0: WM PC log output, 1: WA PC log output */
++ mt76_wr(dev, MT_CONN_DBG_CTL_OUT_SEL, val);
+ /* choose 33th PC log buffer to read current PC index */
+ mt76_wr(dev, MT_CONN_DBG_CTL_PC_LOG_SEL, 0x3f);
+
+ /* read current PC */
+- dump->pc_stack[0] = mt76_rr(dev, MT_CONN_DBG_CTL_PC_LOG);
++ for (i = 0; i < 10; i++)
++ dump->pc_cur[i] = mt76_rr(dev, MT_CONN_DBG_CTL_PC_LOG);
+
+ /* stop call stack record */
+ if (!exception) {
+- mt76_clear(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
+- mt76_clear(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
++ mt76_clear(dev, MT_MCU_WM_EXCP_PC_CTRL + offset, BIT(0));
++ mt76_clear(dev, MT_MCU_WM_EXCP_LR_CTRL + offset, BIT(0));
+ }
+
+- oldest = (u32)mt76_get_field(dev, MT_MCU_WM_EXCP_PC_CTRL,
+- GENMASK(20, 16)) + 2;
+- for (i = 0; i < 16; i++) {
+- idx = ((oldest + 2 * i + 1) % 32);
+- dump->pc_stack[i + 1] =
+- mt76_rr(dev, MT_MCU_WM_EXCP_PC_LOG + idx * 4);
++ /* read PC log */
++ dump->pc_dbg_ctrl = mt76_rr(dev, MT_MCU_WM_EXCP_PC_CTRL + offset);
++ dump->pc_cur_idx = FIELD_GET(MT_MCU_WM_EXCP_PC_CTRL_IDX_STATUS,
++ dump->pc_dbg_ctrl);
++ for (i = 0; i < 32; i++) {
++ reg = MT_MCU_WM_EXCP_PC_LOG + i * 4 + offset;
++ dump->pc_stack[i] = mt76_rr(dev, reg);
+ }
+
+- oldest = (u32)mt76_get_field(dev, MT_MCU_WM_EXCP_LR_CTRL,
+- GENMASK(20, 16)) + 2;
+- for (i = 0; i < 16; i++) {
+- idx = ((oldest + 2 * i + 1) % 32);
+- dump->lr_stack[i] =
+- mt76_rr(dev, MT_MCU_WM_EXCP_LR_LOG + idx * 4);
++ /* read LR log */
++ dump->lr_dbg_ctrl = mt76_rr(dev, MT_MCU_WM_EXCP_LR_CTRL + offset);
++ dump->lr_cur_idx = FIELD_GET(MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS,
++ dump->lr_dbg_ctrl);
++ for (i = 0; i < 32; i++) {
++ reg = MT_MCU_WM_EXCP_LR_LOG + i * 4 + offset;
++ dump->lr_stack[i] = mt76_rr(dev, reg);
+ }
+
+ /* start call stack record */
+ if (!exception) {
+- mt76_set(dev, MT_MCU_WM_EXCP_PC_CTRL, BIT(0));
+- mt76_set(dev, MT_MCU_WM_EXCP_LR_CTRL, BIT(0));
++ mt76_set(dev, MT_MCU_WM_EXCP_PC_CTRL + offset, BIT(0));
++ mt76_set(dev, MT_MCU_WM_EXCP_LR_CTRL + offset, BIT(0));
+ }
+ }
+
+-static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev)
++static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8 type)
+ {
+- struct mt7996_crash_data *crash_data = dev->coredump.crash_data;
++ struct mt7996_crash_data *crash_data = dev->coredump.crash_data[type];
+ struct mt7996_coredump *dump;
+ struct mt7996_coredump_mem *dump_mem;
+ size_t len, sofar = 0, hdr_len = sizeof(*dump);
+@@ -186,20 +222,31 @@ static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev)
+
+ dump = (struct mt7996_coredump *)(buf);
+ dump->len = len;
++ dump->hdr_len = hdr_len;
+
+ /* plain text */
+ strscpy(dump->magic, "mt76-crash-dump", sizeof(dump->magic));
+ strscpy(dump->kernel, init_utsname()->release, sizeof(dump->kernel));
++ strscpy(dump->fw_type, ((type == MT7996_RAM_TYPE_WA) ? "WA" : "WM"),
++ sizeof(dump->fw_type));
+ strscpy(dump->fw_ver, dev->mt76.hw->wiphy->fw_version,
+ sizeof(dump->fw_ver));
++ strscpy(dump->fw_patch_date, dev->patch_build_date,
++ sizeof(dump->fw_patch_date));
++ strscpy(dump->fw_ram_date[MT7996_RAM_TYPE_WM],
++ dev->ram_build_date[MT7996_RAM_TYPE_WM],
++ MT7996_BUILD_TIME_LEN);
++ strscpy(dump->fw_ram_date[MT7996_RAM_TYPE_WA],
++ dev->ram_build_date[MT7996_RAM_TYPE_WA],
++ MT7996_BUILD_TIME_LEN);
+
+ guid_copy(&dump->guid, &crash_data->guid);
+ dump->tv_sec = crash_data->timestamp.tv_sec;
+ dump->tv_nsec = crash_data->timestamp.tv_nsec;
+ dump->device_id = mt76_chip(&dev->mt76);
+
+- mt7996_coredump_fw_state(dev, dump, &exception);
+- mt7996_coredump_fw_stack(dev, dump, exception);
++ mt7996_coredump_fw_state(dev, type, dump, &exception);
++ mt7996_coredump_fw_stack(dev, type, dump, exception);
+
+ /* gather memory content */
+ dump_mem = (struct mt7996_coredump_mem *)(buf + sofar);
+@@ -213,17 +260,19 @@ static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev)
+ return dump;
+ }
+
+-int mt7996_coredump_submit(struct mt7996_dev *dev)
++int mt7996_coredump_submit(struct mt7996_dev *dev, u8 type)
+ {
+ struct mt7996_coredump *dump;
+
+- dump = mt7996_coredump_build(dev);
++ dump = mt7996_coredump_build(dev, type);
+ if (!dump) {
+ dev_warn(dev->mt76.dev, "no crash dump data found\n");
+ return -ENODATA;
+ }
+
+ dev_coredumpv(dev->mt76.dev, dump, dump->len, GFP_KERNEL);
++ dev_info(dev->mt76.dev, "%s coredump completed\n",
++ wiphy_name(dev->mt76.hw->wiphy));
+
+ return 0;
+ }
+@@ -231,23 +280,26 @@ int mt7996_coredump_submit(struct mt7996_dev *dev)
+ int mt7996_coredump_register(struct mt7996_dev *dev)
+ {
+ struct mt7996_crash_data *crash_data;
++ int i;
+
+- crash_data = vzalloc(sizeof(*dev->coredump.crash_data));
+- if (!crash_data)
+- return -ENOMEM;
++ for (i = 0; i < MT7996_COREDUMP_MAX; i++) {
++ crash_data = vzalloc(sizeof(*dev->coredump.crash_data[i]));
++ if (!crash_data)
++ return -ENOMEM;
+
+- dev->coredump.crash_data = crash_data;
++ dev->coredump.crash_data[i] = crash_data;
+
+- if (coredump_memdump) {
+- crash_data->memdump_buf_len = mt7996_coredump_get_mem_size(dev);
+- if (!crash_data->memdump_buf_len)
+- /* no memory content */
+- return 0;
++ if (coredump_memdump) {
++ crash_data->memdump_buf_len = mt7996_coredump_get_mem_size(dev, i);
++ if (!crash_data->memdump_buf_len)
++ /* no memory content */
++ return 0;
+
+- crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
+- if (!crash_data->memdump_buf) {
+- vfree(crash_data);
+- return -ENOMEM;
++ crash_data->memdump_buf = vzalloc(crash_data->memdump_buf_len);
++ if (!crash_data->memdump_buf) {
++ vfree(crash_data);
++ return -ENOMEM;
++ }
+ }
+ }
+
+@@ -256,13 +308,17 @@ int mt7996_coredump_register(struct mt7996_dev *dev)
+
+ void mt7996_coredump_unregister(struct mt7996_dev *dev)
+ {
+- if (dev->coredump.crash_data->memdump_buf) {
+- vfree(dev->coredump.crash_data->memdump_buf);
+- dev->coredump.crash_data->memdump_buf = NULL;
+- dev->coredump.crash_data->memdump_buf_len = 0;
+- }
++ int i;
+
+- vfree(dev->coredump.crash_data);
+- dev->coredump.crash_data = NULL;
++ for (i = 0; i < MT7996_COREDUMP_MAX; i++) {
++ if (dev->coredump.crash_data[i]->memdump_buf) {
++ vfree(dev->coredump.crash_data[i]->memdump_buf);
++ dev->coredump.crash_data[i]->memdump_buf = NULL;
++ dev->coredump.crash_data[i]->memdump_buf_len = 0;
++ }
++
++ vfree(dev->coredump.crash_data[i]);
++ dev->coredump.crash_data[i] = NULL;
++ }
+ }
+
+diff --git a/mt7996/coredump.h b/mt7996/coredump.h
+index af2ba219..01ed3731 100644
+--- a/mt7996/coredump.h
++++ b/mt7996/coredump.h
+@@ -6,10 +6,13 @@
+
+ #include "mt7996.h"
+
++#define MT7996_COREDUMP_MAX (MT7996_RAM_TYPE_WA + 1)
++
+ struct mt7996_coredump {
+ char magic[16];
+
+ u32 len;
++ u32 hdr_len;
+
+ guid_t guid;
+
+@@ -21,17 +24,28 @@ struct mt7996_coredump {
+ char kernel[64];
+ /* firmware version */
+ char fw_ver[ETHTOOL_FWVERS_LEN];
++ char fw_patch_date[MT7996_BUILD_TIME_LEN];
++ char fw_ram_date[MT7996_COREDUMP_MAX][MT7996_BUILD_TIME_LEN];
+
+ u32 device_id;
+
++ /* fw type */
++ char fw_type[8];
++
+ /* exception state */
+ char fw_state[12];
+
+ /* program counters */
+- char pc_current[16];
+- u32 pc_stack[17];
+- /* link registers */
+- u32 lr_stack[16];
++ u32 pc_dbg_ctrl;
++ u32 pc_cur_idx;
++ u32 pc_cur[10];
++ /* PC registers */
++ u32 pc_stack[32];
++
++ u32 lr_dbg_ctrl;
++ u32 lr_cur_idx;
++ /* LR registers */
++ u32 lr_stack[32];
+
+ /* memory content */
+ u8 data[];
+@@ -43,6 +57,7 @@ struct mt7996_coredump_mem {
+ } __packed;
+
+ struct mt7996_mem_hdr {
++ char name[64];
+ u32 start;
+ u32 len;
+ u8 data[];
+@@ -58,27 +73,27 @@ struct mt7996_mem_region {
+ #ifdef CONFIG_DEV_COREDUMP
+
+ const struct mt7996_mem_region *
+-mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u32 *num);
+-struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev);
+-int mt7996_coredump_submit(struct mt7996_dev *dev);
++mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u8 type, u32 *num);
++struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type);
++int mt7996_coredump_submit(struct mt7996_dev *dev, u8 type);
+ int mt7996_coredump_register(struct mt7996_dev *dev);
+ void mt7996_coredump_unregister(struct mt7996_dev *dev);
+
+ #else /* CONFIG_DEV_COREDUMP */
+
+ static inline const struct mt7996_mem_region *
+-mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u32 *num)
++mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u8 type, u32 *num)
+ {
+ return NULL;
+ }
+
+-static inline int mt7996_coredump_submit(struct mt7996_dev *dev)
++static inline int mt7996_coredump_submit(struct mt7996_dev *dev, u8 type)
+ {
+ return 0;
+ }
+
+ static inline struct
+-mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev)
++mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
+ {
+ return NULL;
+ }
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 986031f5..724af82a 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -2082,28 +2082,25 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ }
+
+ /* firmware coredump */
+-void mt7996_mac_dump_work(struct work_struct *work)
++void mt7996_mac_fw_coredump(struct mt7996_dev *dev, u8 type)
+ {
+ const struct mt7996_mem_region *mem_region;
+ struct mt7996_crash_data *crash_data;
+- struct mt7996_dev *dev;
+ struct mt7996_mem_hdr *hdr;
+ size_t buf_len;
+ int i;
+ u32 num;
+ u8 *buf;
+
+- dev = container_of(work, struct mt7996_dev, dump_work);
+-
+ mutex_lock(&dev->dump_mutex);
+
+- crash_data = mt7996_coredump_new(dev);
++ crash_data = mt7996_coredump_new(dev, type);
+ if (!crash_data) {
+ mutex_unlock(&dev->dump_mutex);
+- goto skip_coredump;
++ return;
+ }
+
+- mem_region = mt7996_coredump_get_mem_layout(dev, &num);
++ mem_region = mt7996_coredump_get_mem_layout(dev, type, &num);
+ if (!mem_region || !crash_data->memdump_buf_len) {
+ mutex_unlock(&dev->dump_mutex);
+ goto skip_memdump;
+@@ -2113,6 +2110,9 @@ void mt7996_mac_dump_work(struct work_struct *work)
+ buf_len = crash_data->memdump_buf_len;
+
+ /* dumping memory content... */
++ dev_info(dev->mt76.dev, "%s start coredump for %s\n",
++ wiphy_name(dev->mt76.hw->wiphy),
++ ((type == MT7996_RAM_TYPE_WA) ? "WA" : "WM"));
+ memset(buf, 0, buf_len);
+ for (i = 0; i < num; i++) {
+ if (mem_region->len > buf_len) {
+@@ -2129,6 +2129,7 @@ void mt7996_mac_dump_work(struct work_struct *work)
+ mt7996_memcpy_fromio(dev, buf, mem_region->start,
+ mem_region->len);
+
++ strscpy(hdr->name, mem_region->name, sizeof(mem_region->name));
+ hdr->start = mem_region->start;
+ hdr->len = mem_region->len;
+
+@@ -2145,8 +2146,20 @@ void mt7996_mac_dump_work(struct work_struct *work)
+ mutex_unlock(&dev->dump_mutex);
+
+ skip_memdump:
+- mt7996_coredump_submit(dev);
+-skip_coredump:
++ mt7996_coredump_submit(dev, type);
++}
++
++void mt7996_mac_dump_work(struct work_struct *work)
++{
++ struct mt7996_dev *dev;
++
++ dev = container_of(work, struct mt7996_dev, dump_work);
++ if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WA_WDT)
++ mt7996_mac_fw_coredump(dev, MT7996_RAM_TYPE_WA);
++
++ if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WM_WDT)
++ mt7996_mac_fw_coredump(dev, MT7996_RAM_TYPE_WM);
++
+ queue_work(dev->mt76.wq, &dev->reset_work);
+ }
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 38292da3..14f7a43f 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2458,6 +2458,8 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
+
+ dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
+ be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
++ memcpy(dev->patch_build_date, hdr->build_date,
++ sizeof(dev->patch_build_date));
+
+ for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
+ struct mt7996_patch_sec *sec;
+@@ -2584,6 +2586,9 @@ static int __mt7996_load_ram(struct mt7996_dev *dev, const char *fw_type,
+ }
+
+ hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
++ memcpy(dev->ram_build_date[ram_type],
++ hdr->build_date,
++ sizeof(dev->ram_build_date[ram_type]));
+ dev_info(dev->mt76.dev, "%s Firmware Version: %.10s, Build Time: %.15s\n",
+ fw_type, hdr->fw_ver, hdr->build_date);
+
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 561c1cdc..f59dce77 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -58,6 +58,8 @@
+ #define MT7996_CRIT_TEMP 110
+ #define MT7996_MAX_TEMP 120
+
++#define MT7996_BUILD_TIME_LEN 24
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -68,6 +70,7 @@ enum mt7996_ram_type {
+ MT7996_RAM_TYPE_WM_TM = MT7996_RAM_TYPE_WM,
+ MT7996_RAM_TYPE_WA,
+ MT7996_RAM_TYPE_DSP,
++ __MT7996_RAM_TYPE_MAX,
+ };
+
+ enum mt7996_txq_id {
+@@ -306,9 +309,11 @@ struct mt7996_dev {
+ struct mutex dump_mutex;
+ #ifdef CONFIG_DEV_COREDUMP
+ struct {
+- struct mt7996_crash_data *crash_data;
++ struct mt7996_crash_data *crash_data[__MT7996_RAM_TYPE_MAX];
+ } coredump;
+ #endif
++ char patch_build_date[MT7996_BUILD_TIME_LEN];
++ char ram_build_date[__MT7996_RAM_TYPE_MAX][MT7996_BUILD_TIME_LEN];
+
+ struct list_head sta_rc_list;
+ struct list_head sta_poll_list;
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 86da1bf8..c054586d 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -482,7 +482,8 @@ enum base_rev {
+
+ /* FW MODE SYNC */
+ #define MT_FW_ASSERT_CNT 0x02208274
+-#define MT_FW_DUMP_STATE 0x02209e90
++#define MT_FW_WM_DUMP_STATE 0x02209e90
++#define MT_FW_WA_DUMP_STATE 0x7C05B080
+
+ #define MT_SWDEF_BASE 0x00401400
+
+@@ -580,11 +581,15 @@ enum base_rev {
+ #define MT_WF_PHYRX_CSD_BAND_RXTD12_IRPI_SW_CLR BIT(29)
+
+ /* CONN MCU EXCP CON */
++#define MT_MCU_WA_EXCP_BASE 0x890d0000
+ #define MT_MCU_WM_EXCP_BASE 0x89050000
++
+ #define MT_MCU_WM_EXCP(ofs) (MT_MCU_WM_EXCP_BASE + (ofs))
+ #define MT_MCU_WM_EXCP_PC_CTRL MT_MCU_WM_EXCP(0x100)
++#define MT_MCU_WM_EXCP_PC_CTRL_IDX_STATUS GENMASK(20, 16)
+ #define MT_MCU_WM_EXCP_PC_LOG MT_MCU_WM_EXCP(0x104)
+ #define MT_MCU_WM_EXCP_LR_CTRL MT_MCU_WM_EXCP(0x200)
++#define MT_MCU_WM_EXCP_LR_CTRL_IDX_STATUS GENMASK(20, 16)
+ #define MT_MCU_WM_EXCP_LR_LOG MT_MCU_WM_EXCP(0x204)
+
+ #endif
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0035-wifi-mt76-mt7996-make-band-capability-init-flexible.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0035-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
new file mode 100644
index 0000000..6864e26
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0035-wifi-mt76-mt7996-make-band-capability-init-flexible.patch
@@ -0,0 +1,184 @@
+From 18ed969cf7bfdaa059ed946f5bacd62a2ebf9ffe Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Tue, 23 May 2023 15:49:03 +0800
+Subject: [PATCH 35/39] wifi: mt76: mt7996: make band capability init flexible
+
+There're some variations of mt7996 chipset which only support two-band,
+so parse the adie combination to correctly set band capability.
+
+Change-Id: Ifcb49504f02f5cc6a23c626e30b4f0e1360fe157
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ mt7996/dma.c | 8 ++++----
+ mt7996/init.c | 29 ++++++++++++++++++-----------
+ mt7996/mcu.c | 13 +++++--------
+ mt7996/mt7996.h | 11 +++++++++++
+ mt7996/regs.h | 3 +++
+ 5 files changed, 41 insertions(+), 23 deletions(-)
+
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 6a21e3e..f01cea5 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -159,13 +159,13 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+
+ irq_mask |= (MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU);
+
+- if (!dev->mphy.band_idx)
++ if (mt7996_band_valid(dev, MT_BAND0))
+ irq_mask |= MT_INT_BAND0_RX_DONE;
+
+- if (dev->dbdc_support)
++ if (mt7996_band_valid(dev, MT_BAND1))
+ irq_mask |= MT_INT_BAND1_RX_DONE;
+
+- if (dev->tbtc_support)
++ if (mt7996_band_valid(dev, MT_BAND2))
+ irq_mask |= MT_INT_BAND2_RX_DONE;
+
+ done:
+@@ -334,7 +334,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ if (ret)
+ return ret;
+
+- if (dev->tbtc_support || dev->mphy.band_idx == MT_BAND2) {
++ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx data queue for band2 */
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ MT_RXQ_ID(MT_RXQ_BAND2),
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 0562439..0825e0b 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -529,11 +529,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ u32 mac_ofs, hif1_ofs = 0;
+ int ret;
+
+- if (band != MT_BAND1 && band != MT_BAND2)
+- return 0;
+-
+- if ((band == MT_BAND1 && !dev->dbdc_support) ||
+- (band == MT_BAND2 && !dev->tbtc_support))
++ if (!mt7996_band_valid(dev, band) || band == MT_BAND0)
+ return 0;
+
+ if (phy)
+@@ -648,8 +644,10 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+
+ INIT_WORK(&dev->init_work, mt7996_init_work);
+
+- dev->dbdc_support = true;
+- dev->tbtc_support = true;
++ dev->dbdc_support = mt7996_band_valid(dev, MT_BAND1) ||
++ mt7996_band_valid(dev, MT_BAND2);
++ dev->tbtc_support = mt7996_band_valid(dev, MT_BAND1) &&
++ mt7996_band_valid(dev, MT_BAND2);
+
+ ret = mt7996_dma_init(dev);
+ if (ret)
+@@ -1089,8 +1087,6 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ if (ret)
+ return ret;
+
+- ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
+-
+ ret = mt7996_register_phy(dev, mt7996_phy2(dev), MT_BAND1);
+ if (ret)
+ return ret;
+@@ -1099,13 +1095,24 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ if (ret)
+ return ret;
+
++ ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
++
+ dev->recovery.hw_init_done = true;
+
+ ret = mt7996_init_debugfs(&dev->phy);
+ if (ret)
+- return ret;
++ goto error;
+
+- return mt7996_coredump_register(dev);
++ ret = mt7996_coredump_register(dev);
++ if (ret)
++ goto error;
++
++ return 0;
++
++error:
++ cancel_work_sync(&dev->init_work);
++
++ return ret;
+ }
+
+ void mt7996_unregister_device(struct mt7996_dev *dev)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index c647979..9fb800a 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2767,7 +2767,7 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
+ {
+ struct uni_header hdr = {};
+ struct sk_buff *skb;
+- int len, num;
++ int len, num, i;
+
+ num = 2 + 2 * (dev->dbdc_support + dev->tbtc_support);
+ len = sizeof(hdr) + num * sizeof(struct vow_rx_airtime);
+@@ -2777,13 +2777,10 @@ mt7996_mcu_init_rx_airtime(struct mt7996_dev *dev)
+
+ skb_put_data(skb, &hdr, sizeof(hdr));
+
+- mt7996_add_rx_airtime_tlv(skb, dev->mt76.phy.band_idx);
+-
+- if (dev->dbdc_support)
+- mt7996_add_rx_airtime_tlv(skb, MT_BAND1);
+-
+- if (dev->tbtc_support)
+- mt7996_add_rx_airtime_tlv(skb, MT_BAND2);
++ for (i = 0; i < __MT_MAX_BAND; i++) {
++ if (mt7996_band_valid(dev, i))
++ mt7996_add_rx_airtime_tlv(skb, i);
++ }
+
+ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_WM_UNI_CMD(VOW), true);
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index f59dce7..488f59c 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -431,6 +431,17 @@ mt7996_phy3(struct mt7996_dev *dev)
+ return __mt7996_phy(dev, MT_BAND2);
+ }
+
++static inline bool
++mt7996_band_valid(struct mt7996_dev *dev, u8 band)
++{
++ /* tri-band support */
++ if (band <= MT_BAND2 &&
++ mt76_get_field(dev, MT_PAD_GPIO, MT_PAD_GPIO_ADIE_COMB) <= 1)
++ return true;
++
++ return band == MT_BAND0 || band == MT_BAND2;
++}
++
+ extern const struct ieee80211_ops mt7996_ops;
+ extern struct pci_driver mt7996_pci_driver;
+ extern struct pci_driver mt7996_hif_driver;
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index c054586..3a5914c 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -546,6 +546,9 @@ enum base_rev {
+ #define MT_TOP_MISC MT_TOP(0xf0)
+ #define MT_TOP_MISC_FW_STATE GENMASK(2, 0)
+
++#define MT_PAD_GPIO 0x700056f0
++#define MT_PAD_GPIO_ADIE_COMB GENMASK(16, 15)
++
+ #define MT_HW_REV 0x70010204
+ #define MT_WF_SUBSYS_RST 0x70028600
+
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
new file mode 100644
index 0000000..c0ce85d
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch
@@ -0,0 +1,272 @@
+From 18f990de206c3301d3ae72cfeef40dfb3b361fb0 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Mon, 8 May 2023 09:03:50 +0800
+Subject: [PATCH 36/39] wifi: mt76: mt7996: enable SCS feature for mt7996
+ driver
+
+Enable Smart Carrier Sense algorithn by default to improve performance
+in a noisy environment.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/init.c | 1 +
+ mt7996/main.c | 7 +++
+ mt7996/mcu.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.h | 6 +++
+ mt7996/mt7996.h | 16 ++++++
+ 6 files changed, 154 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 97f874b..bfec420 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1213,6 +1213,7 @@ enum {
+ MCU_UNI_CMD_GET_MIB_INFO = 0x22,
+ MCU_UNI_CMD_SNIFFER = 0x24,
+ MCU_UNI_CMD_SR = 0x25,
++ MCU_UNI_CMD_SCS = 0x26,
+ MCU_UNI_CMD_ROC = 0x27,
+ MCU_UNI_CMD_TXPOWER = 0x2b,
+ MCU_UNI_CMD_EFUSE_CTRL = 0x2d,
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 0825e0b..1072874 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -1058,6 +1058,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ dev->mt76.phy.priv = &dev->phy;
+ INIT_WORK(&dev->rc_work, mt7996_mac_sta_rc_work);
+ INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7996_mac_work);
++ INIT_DELAYED_WORK(&dev->scs_work, mt7996_mcu_scs_sta_poll);
+ INIT_LIST_HEAD(&dev->sta_rc_list);
+ INIT_LIST_HEAD(&dev->sta_poll_list);
+ INIT_LIST_HEAD(&dev->twt_list);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 520f250..20b89a7 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -73,11 +73,17 @@ int mt7996_run(struct ieee80211_hw *hw)
+ if (ret)
+ goto out;
+
++ ret = mt7996_mcu_set_scs(phy, SCS_ENABLE);
++ if (ret)
++ goto out;
++
+ set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
+
+ ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
+ MT7996_WATCHDOG_TIME);
+
++ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
++
+ if (!running)
+ mt7996_mac_reset_counters(phy);
+
+@@ -105,6 +111,7 @@ static void mt7996_stop(struct ieee80211_hw *hw)
+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
+
+ cancel_delayed_work_sync(&phy->mt76->mac_work);
++ cancel_delayed_work_sync(&dev->scs_work);
+
+ mutex_lock(&dev->mt76.mutex);
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 9fb800a..a5c473a 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4190,3 +4190,126 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TXPOWER),
+ &req, sizeof(req), false);
+ }
++
++int mt7996_mcu_set_scs_stats(struct mt7996_phy *phy)
++{
++ struct mt7996_scs_ctrl ctrl = phy->scs_ctrl;
++ struct {
++ u8 band_idx;
++ u8 _rsv[3];
++
++ __le16 tag;
++ __le16 len;
++
++ u8 _rsv2[6];
++ s8 min_rssi;
++ u8 _rsv3;
++ } __packed req = {
++ .band_idx = phy->mt76->band_idx,
++ .tag = cpu_to_le16(UNI_CMD_SCS_SEND_DATA),
++ .len = cpu_to_le16(sizeof(req) - 4),
++
++ .min_rssi = ctrl.sta_min_rssi,
++ };
++
++ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
++ &req, sizeof(req), false);
++}
++
++void mt7996_sta_rssi_work(void *data, struct ieee80211_sta *sta)
++{
++ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
++ struct mt7996_dev *dev = (struct mt7996_dev *)data;
++ struct mt7996_phy *poll_phy;
++ u8 band_idx = msta->wcid.phy_idx;
++
++ switch (band_idx) {
++ case MT_BAND0:
++ poll_phy = dev->mphy.priv;
++ break;
++ case MT_BAND1:
++ poll_phy = mt7996_phy2(dev);
++ break;
++ case MT_BAND2:
++ poll_phy = mt7996_phy3(dev);
++ break;
++ default:
++ poll_phy = NULL;
++ break;
++ }
++
++ if (!poll_phy->scs_ctrl.scs_enable)
++ return;
++
++ if (poll_phy->scs_ctrl.sta_min_rssi > msta->ack_signal)
++ poll_phy->scs_ctrl.sta_min_rssi = msta->ack_signal;
++}
++
++void mt7996_mcu_scs_sta_poll(struct work_struct *work)
++{
++ struct mt7996_dev *dev = container_of(work, struct mt7996_dev,
++ scs_work.work);
++ bool scs_enable_flag = false;
++ u8 i;
++
++ ieee80211_iterate_stations_atomic(dev->mphy.hw, mt7996_sta_rssi_work, dev);
++
++ for (i = 0; i < __MT_MAX_BAND; i++) {
++ struct mt7996_phy *phy;
++
++ switch (i) {
++ case MT_BAND0:
++ phy = dev->mphy.priv;
++ break;
++ case MT_BAND1:
++ phy = mt7996_phy2(dev);
++ break;
++ case MT_BAND2:
++ phy = mt7996_phy3(dev);
++ break;
++ default:
++ phy = NULL;
++ break;
++ }
++
++ if (phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state) &&
++ phy->scs_ctrl.scs_enable) {
++ scs_enable_flag = true;
++ if (mt7996_mcu_set_scs_stats(phy))
++ dev_err(dev->mt76.dev, "Failed to send scs mcu cmd\n");
++ phy->scs_ctrl.sta_min_rssi = 0;
++ }
++ }
++
++ if (scs_enable_flag)
++ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
++}
++
++
++int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
++{
++ struct mt7996_dev *dev = phy->dev;
++ struct {
++ u8 band_idx;
++ u8 _rsv[3];
++
++ __le16 tag;
++ __le16 len;
++
++ u8 scs_enable;
++ u8 _rsv2[3];
++ } __packed req = {
++ .band_idx = phy->mt76->band_idx,
++ .tag = cpu_to_le16(UNI_CMD_SCS_ENABLE),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ .scs_enable = enable,
++ };
++
++ phy->scs_ctrl.scs_enable = enable;
++
++ if (enable == SCS_ENABLE)
++ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ);
++
++ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
++ &req, sizeof(req), false);
++}
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index eed7371..eb63441 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -757,6 +757,12 @@ enum {
+ MT7996_SEC_MODE_MAX,
+ };
+
++enum {
++ UNI_CMD_SCS_SEND_DATA,
++ UNI_CMD_SCS_SET_PD_THR_RANGE = 2,
++ UNI_CMD_SCS_ENABLE,
++};
++
+ #define MT7996_PATCH_SEC GENMASK(31, 24)
+ #define MT7996_PATCH_SCRAMBLE_KEY GENMASK(15, 8)
+ #define MT7996_PATCH_AES_KEY GENMASK(7, 0)
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 488f59c..f78f1fd 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -222,6 +222,17 @@ struct mt7996_hif {
+ int irq;
+ };
+
++
++struct mt7996_scs_ctrl {
++ u8 scs_enable;
++ s8 sta_min_rssi;
++};
++
++enum {
++ SCS_DISABLE = 0,
++ SCS_ENABLE,
++};
++
+ struct mt7996_phy {
+ struct mt76_phy *mt76;
+ struct mt7996_dev *dev;
+@@ -253,6 +264,8 @@ struct mt7996_phy {
+
+ bool has_aux_rx;
+
++ struct mt7996_scs_ctrl scs_ctrl;
++
+ #ifdef CONFIG_NL80211_TESTMODE
+ struct {
+ u32 *reg_backup;
+@@ -295,6 +308,7 @@ struct mt7996_dev {
+ struct work_struct rc_work;
+ struct work_struct dump_work;
+ struct work_struct reset_work;
++ struct delayed_work scs_work;
+ wait_queue_head_t reset_wait;
+ struct {
+ u32 state;
+@@ -535,6 +549,8 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
++int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
++void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
+ {
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0037-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0037-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
new file mode 100644
index 0000000..5dc8109
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0037-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch
@@ -0,0 +1,237 @@
+From de92f88f5c00cf1069df00bb89f50281b0b2d05e Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 12 May 2023 16:24:53 +0800
+Subject: [PATCH 37/39] wifi: mt76: mt7996: add beacon duplicate tx mode
+ support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/init.c | 6 ++++--
+ mt7996/mac.c | 11 -----------
+ mt7996/main.c | 18 +++++++++---------
+ mt7996/mcu.c | 30 ++++++++++++++++++++++++++++++
+ mt7996/mcu.h | 20 ++++++++++++++++++++
+ mt7996/mt7996.h | 8 +++++---
+ 7 files changed, 69 insertions(+), 25 deletions(-)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index bfec420..4bb9508 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1224,6 +1224,7 @@ enum {
+ MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
+ MCU_UNI_CMD_THERMAL = 0x35,
+ MCU_UNI_CMD_VOW = 0x37,
++ MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
+ MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
+ MCU_UNI_CMD_RRO = 0x57,
+ MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 1072874..9eba689 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -351,6 +351,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
+
+ phy->slottime = 9;
++ phy->beacon_rate = -1;
+
+ hw->sta_data_size = sizeof(struct mt7996_sta);
+ hw->vif_data_size = sizeof(struct mt7996_vif);
+@@ -459,11 +460,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
+
+ for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
+ u16 rate = mt76_rates[i].hw_value;
+- u16 idx = MT7996_BASIC_RATES_TBL + i;
++ /* odd index for driver, even index for firmware */
++ u16 idx = MT7996_BASIC_RATES_TBL + 2 * i;
+
+ rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
+ FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
+- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
++ mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false);
+ }
+ }
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 724af82..05269e7 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -252,17 +252,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
+ mt76_clear(dev, addr, BIT(5));
+ }
+
+-void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
+- u8 tbl_idx, u16 rate_idx)
+-{
+- u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx;
+-
+- mt76_wr(dev, MT_WTBL_ITDR0, rate_idx);
+- /* use wtbl spe idx */
+- mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL);
+- mt76_wr(dev, MT_WTBL_ITCR, ctrl);
+-}
+-
+ static void
+ mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
+ struct ieee80211_radiotap_he *he,
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 20b89a7..2ed66e6 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -544,24 +544,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt76_phy *mphy = hw->priv;
+ u16 rate;
+- u8 i, idx, ht;
++ u8 i, idx;
+
+ rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast);
+- ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM;
+
+- if (beacon && ht) {
+- struct mt7996_dev *dev = mt7996_hw_dev(hw);
++ if (beacon) {
++ struct mt7996_phy *phy = mt7996_hw_phy(hw);
++
++ /* odd index for driver, even index for firmware */
++ idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx;
++ if (phy->beacon_rate != rate)
++ mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon);
+
+- /* must odd index */
+- idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20);
+- mt7996_mac_set_fixed_rate_table(dev, idx, rate);
+ return idx;
+ }
+
+ idx = FIELD_GET(MT_TX_RATE_IDX, rate);
+ for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
+ if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)
+- return MT7996_BASIC_RATES_TBL + i;
++ return MT7996_BASIC_RATES_TBL + 2 * i;
+
+ return mvif->basic_rates_idx;
+ }
+@@ -965,7 +966,6 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+ mt7996_set_stream_vht_txbf_caps(phy);
+ mt7996_set_stream_he_eht_caps(phy);
+
+- /* TODO: update bmc_wtbl spe_idx when antenna changes */
+ mutex_unlock(&dev->mt76.mutex);
+
+ return 0;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index a5c473a..b34c6b7 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4056,6 +4056,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
+ }
+
++int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
++ u16 rate_idx, bool beacon)
++{
++#define UNI_FIXED_RATE_TABLE_SET 0
++#define SPE_IXD_SELECT_TXD 0
++#define SPE_IXD_SELECT_BMC_WTBL 1
++ struct mt7996_dev *dev = phy->dev;
++ struct fixed_rate_table_ctrl req = {
++ .tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ .table_idx = table_idx,
++ .rate_idx = cpu_to_le16(rate_idx),
++ .gi = 1,
++ .he_ltf = 1,
++ };
++ u8 band_idx = phy->mt76->band_idx;
++
++ if (beacon) {
++ req.spe_idx_sel = SPE_IXD_SELECT_TXD;
++ req.spe_idx = 24 + band_idx;
++ phy->beacon_rate = rate_idx;
++ } else {
++ req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL;
++ req.spe_idx = 0;
++ }
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE),
++ &req, sizeof(req), false);
++}
++
+ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
+ {
+ struct {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index eb63441..e32767e 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -771,4 +771,24 @@ enum {
+ #define MT7996_SEC_KEY_IDX GENMASK(2, 1)
+ #define MT7996_SEC_IV BIT(3)
+
++struct fixed_rate_table_ctrl {
++ u8 _rsv[4];
++
++ __le16 tag;
++ __le16 len;
++
++ u8 table_idx;
++ u8 antenna_idx;
++ __le16 rate_idx;
++ u8 spe_idx_sel;
++ u8 spe_idx;
++ u8 gi;
++ u8 he_ltf;
++ bool ldpc;
++ bool txbf;
++ bool dynamic_bw;
++
++ u8 rsv[1];
++} __packed;
++
+ #endif
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index f78f1fd..286fc1e 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -48,7 +48,7 @@
+ #define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3)
+
+ /* NOTE: used to map mt76_rates. idx may change if firmware expands table */
+-#define MT7996_BASIC_RATES_TBL 11
++#define MT7996_BASIC_RATES_TBL 31
+ #define MT7996_BEACON_RATES_TBL 25
+
+ #define MT7996_THERMAL_THROTTLE_MAX 100
+@@ -256,6 +256,8 @@ struct mt7996_phy {
+
+ u8 rdd_state;
+
++ u16 beacon_rate;
++
+ u32 rx_ampdu_ts;
+ u32 ampdu_ref;
+
+@@ -539,6 +541,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index,
+ u8 rx_sel, u8 val);
+ int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy,
+ struct cfg80211_chan_def *chandef);
++int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
++ u16 rate_idx, bool beacon);
+ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
+ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
+@@ -606,8 +610,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
+ void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
+ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
+ struct ieee80211_vif *vif, bool enable);
+-void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
+- u8 tbl_idx, u16 rate_idx);
+ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
+ struct sk_buff *skb, struct mt76_wcid *wcid,
+ struct ieee80211_key_conf *key, int pid,
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch
new file mode 100644
index 0000000..10bbe3a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch
@@ -0,0 +1,40 @@
+From 39893cc863213984a9ab0ae279dbfe433a6fe90e Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Tue, 23 May 2023 21:18:59 +0800
+Subject: [PATCH 38/39] wifi: mt76: mt7996: fix DFS CAC tx emission issue after
+ 2nd interface up
+
+FW's channel state is set during the first wifi interface setup. If the switch reason for
+setting the tx/rx path during second-time wifi interface setup is CH_SWITCH_NORMAL,
+then the FW would perform runtime dpd channel calibration during DFS CAC, which leads to
+tx emission. Therefore, in order to bypass tx calibration during DFS CAC, set the switch reason
+to CH_SWITCH_DFS whenever chandef is set to DFS channel.
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt7996/mcu.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index b34c6b7..be5c908 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3211,12 +3211,12 @@ int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag)
+ .channel_band = ch_band[chandef->chan->band],
+ };
+
+- if (tag == UNI_CHANNEL_RX_PATH ||
+- dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
++ if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+ req.switch_reason = CH_SWITCH_NORMAL;
+ else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+ req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
+- else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
++ else if (cfg80211_chandef_valid(chandef) &&
++ !cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
+ NL80211_IFTYPE_AP))
+ req.switch_reason = CH_SWITCH_DFS;
+ else
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
new file mode 100644
index 0000000..c2fed58
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch
@@ -0,0 +1,27 @@
+From affb48f4b09fca1e4df1e2291c78ee01b877e40f Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Tue, 30 May 2023 11:27:01 +0800
+Subject: [PATCH 39/39] wifi: mt76: mt7996: fix bss rate tlv to sync firmware
+ change
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ mt7996/mcu.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index e32767e..549007f 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -259,7 +259,7 @@ struct bss_rate_tlv {
+ u8 short_preamble;
+ u8 bc_fixed_rate;
+ u8 mc_fixed_rate;
+- u8 __rsv2[1];
++ u8 __rsv2[9];
+ } __packed;
+
+ struct bss_ra_tlv {
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch
new file mode 100644
index 0000000..b5a49a5
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch
@@ -0,0 +1,43 @@
+From da1c93b8c6480cfcd605cd8c19111a6df8c9f8b4 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Fri, 2 Jun 2023 15:12:34 +0800
+Subject: [PATCH] wifi: mt76: mt7996: fix beamformee ss subfield in EHT PHY
+ caps IE
+
+According to P802.11be_D2.1 Table 9-401I, the minimum value of Beamformee SS shall
+be 3. Fix it to ensure that the value of Beamformee SS subfield is at least 3.
+
+Signed-off-by: Howard Hsu <howard-yh.hsu@mediatek.com>
+---
+ mt7996/init.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 9eba689a..96c4bb01 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -936,16 +936,17 @@ mt7996_init_eht_caps(struct mt7996_phy *phy, enum nl80211_band band,
+ IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
+ IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
+
++ val = max_t(u8, sts - 1, 3);
+ eht_cap_elem->phy_cap_info[0] |=
+- u8_encode_bits(u8_get_bits(sts - 1, BIT(0)),
++ u8_encode_bits(u8_get_bits(val, BIT(0)),
+ IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);
+
+ eht_cap_elem->phy_cap_info[1] =
+- u8_encode_bits(u8_get_bits(sts - 1, GENMASK(2, 1)),
++ u8_encode_bits(u8_get_bits(val, GENMASK(2, 1)),
+ IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK) |
+- u8_encode_bits(sts - 1,
++ u8_encode_bits(val,
+ IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK) |
+- u8_encode_bits(sts - 1,
++ u8_encode_bits(val,
+ IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);
+
+ eht_cap_elem->phy_cap_info[2] =
+--
+2.18.0
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0999-mt76-mt7996-for-build-pass.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0999-wifi-mt76-mt7996-for-build-pass.patch
similarity index 90%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0999-mt76-mt7996-for-build-pass.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/0999-wifi-mt76-mt7996-for-build-pass.patch
index 89d1cdd..cb5d3bb 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0999-mt76-mt7996-for-build-pass.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0999-wifi-mt76-mt7996-for-build-pass.patch
@@ -1,7 +1,7 @@
-From c187058bfc83a80b3cfbfed4ce0c73ece6efb1fe Mon Sep 17 00:00:00 2001
+From 83bb8ec37f85161b08f4eb2abf6a9a0530cfc189 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 3 Nov 2022 00:27:17 +0800
-Subject: [PATCH 0999/1001] mt76: mt7996: for build pass
+Subject: [PATCH 0999/1015] wifi: mt76: mt7996: for build pass
Change-Id: Ieb44c33ee6e6a2e6058c1ef528404c1a1cbcfdaf
---
@@ -34,10 +34,10 @@
return 0;
}
diff --git a/dma.c b/dma.c
-index f560d37d..ffc5b553 100644
+index f2b1b2ac..e1e9062b 100644
--- a/dma.c
+++ b/dma.c
-@@ -858,7 +858,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -859,7 +859,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
!(dev->drv->rx_check(dev, data, len)))
goto free_frag;
@@ -116,10 +116,10 @@
#define fw_name(_dev, name, ...) ({ \
char *_fw; \
diff --git a/mt7996/dma.c b/mt7996/dma.c
-index 53414346..733d1228 100644
+index f01cea5e..b8f253d0 100644
--- a/mt7996/dma.c
+++ b/mt7996/dma.c
-@@ -343,8 +343,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+@@ -360,8 +360,8 @@ int mt7996_dma_init(struct mt7996_dev *dev)
if (ret < 0)
return ret;
@@ -129,9 +129,9 @@
+ mt7996_poll_tx, NAPI_POLL_WEIGHT);
napi_enable(&dev->mt76.tx_napi);
- mt7996_dma_enable(dev);
+ mt7996_dma_enable(dev, false);
diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index f5e95460..50f2227f 100644
+index 9840c77d..b81ed64c 100644
--- a/mt7996/eeprom.c
+++ b/mt7996/eeprom.c
@@ -121,6 +121,7 @@ static int mt7996_eeprom_parse_efuse_hw_cap(struct mt7996_dev *dev)
@@ -143,7 +143,7 @@
dev->has_eht = !(cap & MODE_HE_ONLY);
dev->wtbl_size_group = u32_get_bits(cap, WTBL_SIZE_GROUP);
diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index 24adeb12..f2bfbd8a 100644
+index 871d32a4..58893348 100644
--- a/mt7996/mcu.c
+++ b/mt7996/mcu.c
@@ -5,6 +5,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1000-mt76-mt7996-add-debug-tool.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
similarity index 97%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1000-mt76-mt7996-add-debug-tool.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
index 018c7b9..7179a65 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1000-mt76-mt7996-add-debug-tool.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1000-wifi-mt76-mt7996-add-debug-tool.patch
@@ -1,43 +1,119 @@
-From 9cf11ae2bfdf56babbdfe4fe03f61f492c06ce1a Mon Sep 17 00:00:00 2001
+From e7b3aa46df08dc89f0ed30c36d56ee4acf50d982 Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Fri, 24 Mar 2023 14:02:32 +0800
-Subject: [PATCH 1000/1001] mt76: mt7996: add debug tool
+Subject: [PATCH 1000/1015] wifi: mt76: mt7996: add debug tool
Change-Id: Ie10390b01f17db893dbfbf3221bf63a4bd1fe38f
---
mt7996/Makefile | 3 +
- mt7996/debugfs.c | 31 +-
- mt7996/mcu.c | 4 +
- mt7996/mt7996.h | 15 +
- mt7996/mtk_debug.h | 2166 ++++++++++++++++++++++++++++++++++++++
- mt7996/mtk_debugfs.c | 2344 ++++++++++++++++++++++++++++++++++++++++++
+ mt7996/coredump.c | 10 +-
+ mt7996/coredump.h | 7 +
+ mt7996/debugfs.c | 29 +-
+ mt7996/mt7996.h | 14 +
+ mt7996/mtk_debug.h | 2165 ++++++++++++++++++++++++++++++++++++++
+ mt7996/mtk_debugfs.c | 2353 ++++++++++++++++++++++++++++++++++++++++++
mt7996/mtk_mcu.c | 18 +
mt7996/mtk_mcu.h | 16 +
tools/fwlog.c | 25 +-
- 9 files changed, 4606 insertions(+), 16 deletions(-)
+ 10 files changed, 4622 insertions(+), 18 deletions(-)
create mode 100644 mt7996/mtk_debug.h
create mode 100644 mt7996/mtk_debugfs.c
create mode 100644 mt7996/mtk_mcu.c
create mode 100644 mt7996/mtk_mcu.h
diff --git a/mt7996/Makefile b/mt7996/Makefile
-index bed9efd6..9ef0b824 100644
+index 7c2514a6..df131869 100644
--- a/mt7996/Makefile
+++ b/mt7996/Makefile
-@@ -1,4 +1,5 @@
+@@ -1,5 +1,6 @@
# SPDX-License-Identifier: ISC
+ EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
+EXTRA_CFLAGS += -DCONFIG_MTK_DEBUG
obj-$(CONFIG_MT7996E) += mt7996e.o
-@@ -8,3 +9,5 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
+@@ -9,3 +10,5 @@ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
mt7996e-$(CONFIG_NL80211_TESTMODE) += testmode.o
+
+mt7996e-y += mtk_debugfs.o mtk_mcu.o
+diff --git a/mt7996/coredump.c b/mt7996/coredump.c
+index 60b88085..a7f91b56 100644
+--- a/mt7996/coredump.c
++++ b/mt7996/coredump.c
+@@ -195,7 +195,7 @@ mt7996_coredump_fw_stack(struct mt7996_dev *dev, u8 type, struct mt7996_coredump
+ }
+ }
+
+-static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8 type)
++struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8 type, bool full_dump)
+ {
+ struct mt7996_crash_data *crash_data = dev->coredump.crash_data[type];
+ struct mt7996_coredump *dump;
+@@ -206,7 +206,7 @@ static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8
+
+ len = hdr_len;
+
+- if (coredump_memdump && crash_data->memdump_buf_len)
++ if (full_dump && coredump_memdump && crash_data->memdump_buf_len)
+ len += sizeof(*dump_mem) + crash_data->memdump_buf_len;
+
+ sofar += hdr_len;
+@@ -248,6 +248,9 @@ static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8
+ mt7996_coredump_fw_state(dev, type, dump, &exception);
+ mt7996_coredump_fw_stack(dev, type, dump, exception);
+
++ if (!full_dump)
++ goto skip_dump_mem;
++
+ /* gather memory content */
+ dump_mem = (struct mt7996_coredump_mem *)(buf + sofar);
+ dump_mem->len = crash_data->memdump_buf_len;
+@@ -255,6 +258,7 @@ static struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8
+ memcpy(dump_mem->data, crash_data->memdump_buf,
+ crash_data->memdump_buf_len);
+
++skip_dump_mem:
+ mutex_unlock(&dev->dump_mutex);
+
+ return dump;
+@@ -264,7 +268,7 @@ int mt7996_coredump_submit(struct mt7996_dev *dev, u8 type)
+ {
+ struct mt7996_coredump *dump;
+
+- dump = mt7996_coredump_build(dev, type);
++ dump = mt7996_coredump_build(dev, type, true);
+ if (!dump) {
+ dev_warn(dev->mt76.dev, "no crash dump data found\n");
+ return -ENODATA;
+diff --git a/mt7996/coredump.h b/mt7996/coredump.h
+index 01ed3731..93cd84a0 100644
+--- a/mt7996/coredump.h
++++ b/mt7996/coredump.h
+@@ -75,6 +75,7 @@ struct mt7996_mem_region {
+ const struct mt7996_mem_region *
+ mt7996_coredump_get_mem_layout(struct mt7996_dev *dev, u8 type, u32 *num);
+ struct mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type);
++struct mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8 type, bool full_dump);
+ int mt7996_coredump_submit(struct mt7996_dev *dev, u8 type);
+ int mt7996_coredump_register(struct mt7996_dev *dev);
+ void mt7996_coredump_unregister(struct mt7996_dev *dev);
+@@ -92,6 +93,12 @@ static inline int mt7996_coredump_submit(struct mt7996_dev *dev, u8 type)
+ return 0;
+ }
+
++static inline struct
++mt7996_coredump *mt7996_coredump_build(struct mt7996_dev *dev, u8 type, bool full_dump)
++{
++ return NULL;
++}
++
+ static inline struct
+ mt7996_crash_data *mt7996_coredump_new(struct mt7996_dev *dev, u8 type)
+ {
diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
-index 04220180..0bfded17 100644
+index ca4d615d..8a513f46 100644
--- a/mt7996/debugfs.c
+++ b/mt7996/debugfs.c
@@ -301,6 +301,9 @@ mt7996_fw_debug_wm_set(void *data, u64 val)
@@ -76,22 +152,19 @@
return mt7996_fw_debug_wm_set(dev, dev->fw_debug_wm);
}
-@@ -821,8 +830,13 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
- mt7996_rdd_monitor);
- }
-
-- if (phy == &dev->phy)
-+ if (phy == &dev->phy) {
+@@ -825,6 +834,11 @@ int mt7996_init_debugfs(struct mt7996_phy *phy)
+ if (phy == &dev->phy)
dev->debugfs_dir = dir;
+
+#ifdef CONFIG_MTK_DEBUG
-+ debugfs_create_u16("wlan_idx", 0600, dir, &dev->wlan_idx);
-+ mt7996_mtk_init_debugfs(phy, dir);
++ debugfs_create_u16("wlan_idx", 0600, dir, &dev->wlan_idx);
++ mt7996_mtk_init_debugfs(phy, dir);
+#endif
-+ }
-
++
return 0;
}
-@@ -836,6 +850,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
+
+@@ -837,6 +851,12 @@ mt7996_debugfs_write_fwlog(struct mt7996_dev *dev, const void *hdr, int hdrlen,
void *dest;
spin_lock_irqsave(&lock, flags);
@@ -104,7 +177,7 @@
dest = relay_reserve(dev->relay_fwlog, hdrlen + len + 4);
if (dest) {
*(u32 *)dest = hdrlen + len;
-@@ -868,9 +888,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
+@@ -869,9 +889,6 @@ void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int
.msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR),
};
@@ -114,33 +187,11 @@
hdr.serial_id = cpu_to_le16(dev->fw_debug_seq++);
hdr.timestamp = cpu_to_le32(mt76_rr(dev, MT_LPON_FRCR(0)));
hdr.len = *(__le16 *)data;
-diff --git a/mt7996/mcu.c b/mt7996/mcu.c
-index f2bfbd8a..ef779cf9 100644
---- a/mt7996/mcu.c
-+++ b/mt7996/mcu.c
-@@ -2324,6 +2324,7 @@ static int mt7996_load_patch(struct mt7996_dev *dev)
-
- dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
- be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
-+ memcpy(dev->dbg.patch_build_date, hdr->build_date, sizeof(dev->dbg.patch_build_date));
-
- for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
- struct mt7996_patch_sec *sec;
-@@ -2453,6 +2454,9 @@ static int mt7996_load_ram(struct mt7996_dev *dev)
- hdr = (const struct mt7996_fw_trailer *) \
- (fw->data + fw->size - sizeof(*hdr)); \
- \
-+ memcpy(dev->dbg.ram_build_date[MT7996_RAM_TYPE_##_type], \
-+ hdr->build_date, \
-+ sizeof(dev->dbg.ram_build_date[MT7996_RAM_TYPE_##_type]));\
- dev_info(dev->mt76.dev, \
- "%s Firmware Version: %.10s, Build Time: %.15s\n", \
- #_type, hdr->fw_ver, hdr->build_date); \
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 9bf3bf1a..1ac54520 100644
+index 286fc1eb..6c76ec20 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
-@@ -339,6 +339,17 @@ struct mt7996_dev {
+@@ -363,6 +363,16 @@ struct mt7996_dev {
u32 reg_l2_backup;
u8 wtbl_size_group;
@@ -148,8 +199,7 @@
+#ifdef CONFIG_MTK_DEBUG
+ u16 wlan_idx;
+ struct {
-+ char patch_build_date[16];
-+ char ram_build_date[3][15];
++ u8 sku_disable;
+ u32 fw_dbg_module;
+ u8 fw_dbg_lv;
+ u32 bcn_total_cnt[__MT_MAX_BAND];
@@ -158,7 +208,7 @@
};
enum {
-@@ -608,4 +619,8 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+@@ -659,4 +669,8 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct dentry *dir);
#endif
@@ -169,10 +219,10 @@
#endif
diff --git a/mt7996/mtk_debug.h b/mt7996/mtk_debug.h
new file mode 100644
-index 00000000..a48bac50
+index 00000000..eb40f9cb
--- /dev/null
+++ b/mt7996/mtk_debug.h
-@@ -0,0 +1,2166 @@
+@@ -0,0 +1,2165 @@
+#ifndef __MTK_DEBUG_H
+#define __MTK_DEBUG_H
+
@@ -342,9 +392,8 @@
+ u16 ring_size;
+ char *const ring_info;
+};
++
+// HOST DMA
-+//#define CONN_INFRA_REMAPPING_OFFSET 0x64000000
-+//#define WF_WFDMA_HOST_DMA0_BASE (0x18024000 + CONN_INFRA_REMAPPING_OFFSET)
+#define WF_WFDMA_HOST_DMA0_BASE 0xd4000
+
+#define WF_WFDMA_HOST_DMA0_HOST_INT_STA_ADDR \
@@ -2341,10 +2390,10 @@
+#endif
diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
new file mode 100644
-index 00000000..080f756e
+index 00000000..f04c300f
--- /dev/null
+++ b/mt7996/mtk_debugfs.c
-@@ -0,0 +1,2344 @@
+@@ -0,0 +1,2353 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (C) 2023 MediaTek Inc.
@@ -2356,6 +2405,7 @@
+#include "eeprom.h"
+#include "mtk_debug.h"
+#include "mtk_mcu.h"
++#include "coredump.h"
+
+#ifdef CONFIG_MTK_DEBUG
+
@@ -2690,83 +2740,85 @@
+ if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
+ return 0;
+
-+ seq_printf(s, "Rom Patch Build Time: %.16s\n", dev->dbg.patch_build_date);
-+ seq_printf(s, "WM Patch Build Time: %.15s\n",
-+ dev->dbg.ram_build_date[MT7996_RAM_TYPE_WM]);
++ seq_printf(s, "Rom Patch Build Time: %.16s\n", dev->patch_build_date);
++ seq_printf(s, "WM Patch Build Time: %.15s, Mode: %s\n",
++ dev->ram_build_date[MT7996_RAM_TYPE_WM],
++ dev->testmode_enable ? "Testmode" : "Normal mode");
+ seq_printf(s, "WA Patch Build Time: %.15s\n",
-+ dev->dbg.ram_build_date[MT7996_RAM_TYPE_WA]);
++ dev->ram_build_date[MT7996_RAM_TYPE_WA]);
+ seq_printf(s, "DSP Patch Build Time: %.15s\n",
-+ dev->dbg.ram_build_date[MT7996_RAM_TYPE_DSP]);
++ dev->ram_build_date[MT7996_RAM_TYPE_DSP]);
+ return 0;
+}
+
-+/* dma info dump */
-+const struct queue_desc mt7902_tx_ring_layout[] = {
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING18_CTRL0_ADDR,
-+ .ring_size = 2048,
-+ .ring_info = "band0 TXD"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING19_CTRL0_ADDR,
-+ .ring_size = 2048,
-+ .ring_info = "band1 TXD"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING21_CTRL0_ADDR,
-+ .ring_size = 2048,
-+ .ring_info = "band2 TXD"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING16_CTRL0_ADDR,
-+ .ring_size = 128,
-+ .ring_info = "FWDL"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING17_CTRL0_ADDR,
-+ .ring_size = 256,
-+ .ring_info = "cmd to WM"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_TX_RING20_CTRL0_ADDR,
-+ .ring_size = 256,
-+ .ring_info = "cmd to WA"
++/* fw wm call trace info dump */
++void mt7996_show_lp_history(struct seq_file *s, u32 type)
++{
++ struct mt7996_dev *dev = dev_get_drvdata(s->private);
++ struct mt7996_crash_data *crash_data;
++ struct mt7996_coredump *dump;
++ u64 now = 0;
++ int i = 0;
++ u8 fw_type = !!type;
++
++ mutex_lock(&dev->dump_mutex);
++
++ crash_data = mt7996_coredump_new(dev, fw_type);
++ if (!crash_data) {
++ mutex_unlock(&dev->dump_mutex);
++ seq_printf(s, "the coredump is disable!\n");
++ return;
+ }
-+};
++ mutex_unlock(&dev->dump_mutex);
+
-+const struct queue_desc mt7902_rx_ring_layout[] = {
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING4_CTRL0_ADDR,
-+ .ring_size = 1536,
-+ .ring_info = "band0 RX data"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING5_CTRL0_ADDR,
-+ .ring_size = 1536,
-+ .ring_info = "band1 RX data"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING8_CTRL0_ADDR,
-+ .ring_size = 1536,
-+ .ring_info = "band2 RX data"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING0_CTRL0_ADDR,
-+ .ring_size = 512,
-+ .ring_info = "event from WM"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING1_CTRL0_ADDR,
-+ .ring_size = 1024,
-+ .ring_info = "event from WA"
-+ },
-+ {
-+ .hw_desc_base = WF_WFDMA_HOST_DMA0_WPDMA_RX_RING2_CTRL0_ADDR,
-+ .ring_size = 1024,
-+ .ring_info = "band0/1/2 tx free done"
-+ },
-+};
++ dump = mt7996_coredump_build(dev, fw_type, false);
++ if (!dump) {
++ seq_printf(s, "no call stack data found!\n");
++ return;
++ }
++
++ seq_printf(s, "\x1b[32m%s log output\x1b[0m\n", dump->fw_type);
++ seq_printf(s, "\x1b[32mfw status: %s\n", dump->fw_state);
++ mt7996_dump_version(s, NULL);
++ /* PC log */
++ now = jiffies;
++ for (i = 0; i < 10; i++)
++ seq_printf(s, "\tCurrent PC=%x\n", dump->pc_cur[i]);
+
++ seq_printf(s, "PC log contorl=0x%x(T=%llu)(latest PC index = 0x%x)\n",
++ dump->pc_dbg_ctrl, now, dump->pc_cur_idx);
++ for (i = 0; i < 32; i++)
++ seq_printf(s, "\tPC log(%d)=0x%08x\n", i, dump->pc_stack[i]);
++
++ /* LR log */
++ now = jiffies;
++ seq_printf(s, "\nLR log contorl=0x%x(T=%llu)(latest LR index = 0x%x)\n",
++ dump->lr_dbg_ctrl, now, dump->lr_cur_idx);
++ for (i = 0; i < 32; i++)
++ seq_printf(s, "\tLR log(%d)=0x%08x\n", i, dump->lr_stack[i]);
++
++ vfree(dump);
++}
++
++static int mt7996_fw_wa_info_read(struct seq_file *s, void *data)
++{
++ seq_printf(s, "======[ShowPcLpHistory]======\n");
++ mt7996_show_lp_history(s, MT7996_RAM_TYPE_WA);
++ seq_printf(s, "======[End ShowPcLpHistory]==\n");
++
++ return 0;
++}
++
++static int mt7996_fw_wm_info_read(struct seq_file *s, void *data)
++{
++ seq_printf(s, "======[ShowPcLpHistory]======\n");
++ mt7996_show_lp_history(s, MT7996_RAM_TYPE_WM);
++ seq_printf(s, "======[End ShowPcLpHistory]==\n");
++
++ return 0;
++}
++
++/* dma info dump */
+static void
+dump_dma_tx_ring_info(struct seq_file *s, struct mt7996_dev *dev, char *str1, char *str2, u32 ring_base)
+{
@@ -4668,6 +4720,10 @@
+ debugfs_create_file("fw_wa_set", 0600, dir, dev, &fops_wa_set);
+ debugfs_create_devm_seqfile(dev->mt76.dev, "fw_version", dir,
+ mt7996_dump_version);
++ debugfs_create_devm_seqfile(dev->mt76.dev, "fw_wa_info", dir,
++ mt7996_fw_wa_info_read);
++ debugfs_create_devm_seqfile(dev->mt76.dev, "fw_wm_info", dir,
++ mt7996_fw_wm_info_read);
+
+ debugfs_create_devm_seqfile(dev->mt76.dev, "mib_info0", dir,
+ mt7996_mibinfo_band0);
@@ -4685,6 +4741,8 @@
+ debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
+ mt7996_wtbl_read);
+
++ debugfs_create_u8("sku_disable", 0600, dir, &dev->dbg.sku_disable);
++
+ return 0;
+}
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1001-mt76-mt7996-add-txpower-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-txpower-support.patch
similarity index 94%
rename from recipes-wifi/linux-mt76/files/patches-3.x/1001-mt76-mt7996-add-txpower-support.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-txpower-support.patch
index a9a371d..75fa826 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/1001-mt76-mt7996-add-txpower-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1001-wifi-mt76-mt7996-add-txpower-support.patch
@@ -1,7 +1,7 @@
-From 0169bc58ed8089fc7ca07d08a0ce90a02db4a3dd Mon Sep 17 00:00:00 2001
+From b729a28ee5895d921e8df1a371e114dee7724595 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Fri, 24 Mar 2023 23:35:30 +0800
-Subject: [PATCH 1001/1001] mt76: mt7996: add txpower support
+Subject: [PATCH 1001/1015] wifi: mt76: mt7996: add txpower support
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Change-Id: Ic3e7b17f3664fa7f774137572f885359fa2ec93b
@@ -17,10 +17,10 @@
8 files changed, 423 insertions(+), 5 deletions(-)
diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
-index 50f2227f..c8f65b98 100644
+index b81ed64c..be0a34ae 100644
--- a/mt7996/eeprom.c
+++ b/mt7996/eeprom.c
-@@ -280,3 +280,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
+@@ -293,3 +293,37 @@ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band)
return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
}
@@ -59,10 +59,10 @@
+ [SKU_EHT3x996_484] = 16,
+};
diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
-index 0f8f0cd8..54e180fb 100644
+index 9ea3667f..343e65e1 100644
--- a/mt7996/eeprom.h
+++ b/mt7996/eeprom.h
-@@ -72,4 +72,46 @@ mt7996_get_channel_group_6g(int channel)
+@@ -75,4 +75,46 @@ mt7996_get_channel_group_6g(int channel)
return DIV_ROUND_UP(channel - 29, 32);
}
@@ -110,10 +110,10 @@
+
#endif
diff --git a/mt7996/mcu.h b/mt7996/mcu.h
-index ebc62713..476e007b 100644
+index 549007f9..5d52b0b7 100644
--- a/mt7996/mcu.h
+++ b/mt7996/mcu.h
-@@ -698,6 +698,7 @@ struct tx_power_ctrl {
+@@ -712,6 +712,7 @@ struct tx_power_ctrl {
bool ate_mode_enable;
bool percentage_ctrl_enable;
bool bf_backoff_enable;
@@ -121,7 +121,7 @@
u8 power_drop_level;
};
u8 band_idx;
-@@ -711,6 +712,7 @@ enum {
+@@ -725,6 +726,7 @@ enum {
UNI_TXPOWER_BACKOFF_POWER_LIMIT_CTRL = 3,
UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL = 4,
UNI_TXPOWER_ATE_MODE_CTRL = 6,
@@ -130,31 +130,31 @@
enum {
diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
-index 1ac54520..9bed13a1 100644
+index 6c76ec20..085307ab 100644
--- a/mt7996/mt7996.h
+++ b/mt7996/mt7996.h
-@@ -57,6 +57,8 @@
- #define MT7996_CRIT_TEMP 110
- #define MT7996_MAX_TEMP 120
+@@ -60,6 +60,8 @@
+
+ #define MT7996_BUILD_TIME_LEN 24
+#define MT7996_SKU_RATE_NUM 417
+
struct mt7996_vif;
struct mt7996_sta;
struct mt7996_dfs_pulse;
-@@ -525,6 +527,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+@@ -563,6 +565,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
void mt7996_mcu_exit(struct mt7996_dev *dev);
int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
+int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
- static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
- {
diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
-index 080f756e..c05f8465 100644
+index f04c300f..2aee3ab0 100644
--- a/mt7996/mtk_debugfs.c
+++ b/mt7996/mtk_debugfs.c
-@@ -2296,6 +2296,232 @@ static int mt7996_sta_info(struct seq_file *s, void *data)
+@@ -2299,6 +2299,232 @@ static int mt7996_sta_info(struct seq_file *s, void *data)
return 0;
}
@@ -387,7 +387,7 @@
int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
{
struct mt7996_dev *dev = phy->dev;
-@@ -2334,6 +2560,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+@@ -2341,6 +2567,9 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
debugfs_create_devm_seqfile(dev->mt76.dev, "tr_info", dir,
mt7996_trinfo_read);
@@ -522,10 +522,10 @@
#endif
diff --git a/mt7996/regs.h b/mt7996/regs.h
-index d1d3d154..d01cc8c9 100644
+index 3a5914c4..6ef905a9 100644
--- a/mt7996/regs.h
+++ b/mt7996/regs.h
-@@ -557,15 +557,22 @@ enum base_rev {
+@@ -562,15 +562,22 @@ enum base_rev {
#define MT_PCIE1_MAC_INT_ENABLE MT_PCIE1_MAC(0x188)
@@ -552,7 +552,7 @@
/* PHYRX CSD */
#define MT_WF_PHYRX_CSD_BASE 0x83000000
#define MT_WF_PHYRX_CSD(_band, _wf, ofs) (MT_WF_PHYRX_CSD_BASE + \
-@@ -574,7 +581,7 @@ enum base_rev {
+@@ -579,7 +586,7 @@ enum base_rev {
#define MT_WF_PHYRX_CSD_IRPI(_band, _wf) MT_WF_PHYRX_CSD(_band, _wf, 0x1000)
/* PHYRX CSD BAND */
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
new file mode 100644
index 0000000..fe75034
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch
@@ -0,0 +1,292 @@
+From 55619fa44187b6ed841f94c2bedbc4779457e3f9 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Tue, 13 Dec 2022 15:17:43 +0800
+Subject: [PATCH 1002/1015] wifi: mt76: mt7996: add mu vendor command support
+
+Change-Id: I4599bd97917651aaea51d7ff186ffff73a07e4ce
+---
+ mt7996/Makefile | 3 +-
+ mt7996/init.c | 8 +++++
+ mt7996/mcu.c | 37 +++++++++++++++++++---
+ mt7996/mcu.h | 12 +++++++
+ mt7996/mt7996.h | 7 +++++
+ mt7996/vendor.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 22 +++++++++++++
+ 7 files changed, 167 insertions(+), 6 deletions(-)
+ create mode 100644 mt7996/vendor.c
+ create mode 100644 mt7996/vendor.h
+
+diff --git a/mt7996/Makefile b/mt7996/Makefile
+index df131869..8dbbc34c 100644
+--- a/mt7996/Makefile
++++ b/mt7996/Makefile
+@@ -1,11 +1,12 @@
+ # SPDX-License-Identifier: ISC
+ EXTRA_CFLAGS += -DCONFIG_MT76_LEDS
+ EXTRA_CFLAGS += -DCONFIG_MTK_DEBUG
++EXTRA_CFLAGS += -DCONFIG_MTK_VENDOR
+
+ obj-$(CONFIG_MT7996E) += mt7996e.o
+
+ mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
+- debugfs.o mmio.o
++ debugfs.o mmio.o vendor.o
+
+ mt7996e-$(CONFIG_DEV_COREDUMP) += coredump.o
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 96c4bb01..1d4359f0 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -579,6 +579,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ if (ret)
+ goto error;
+
++#ifdef CONFIG_MTK_VENDOR
++ mt7996_vendor_register(phy);
++#endif
++
+ ret = mt76_register_phy(mphy, true, mt76_rates,
+ ARRAY_SIZE(mt76_rates));
+ if (ret)
+@@ -1082,6 +1086,10 @@ int mt7996_register_device(struct mt7996_dev *dev)
+ dev->mt76.test_ops = &mt7996_testmode_ops;
+ #endif
+
++#ifdef CONFIG_MTK_VENDOR
++ mt7996_vendor_register(&dev->phy);
++#endif
++
+ ret = mt76_register_device(&dev->mt76, true, mt76_rates,
+ ARRAY_SIZE(mt76_rates));
+ if (ret)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 58893348..91f3103a 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -1158,6 +1158,8 @@ static void
+ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ struct ieee80211_vif *vif, struct ieee80211_sta *sta)
+ {
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ struct mt7996_phy *phy = mvif->phy;
+ struct ieee80211_he_cap_elem *elem = &sta->deflink.he_cap.he_cap_elem;
+ struct sta_rec_muru *muru;
+ struct tlv *tlv;
+@@ -1169,11 +1171,14 @@ mt7996_mcu_sta_muru_tlv(struct mt7996_dev *dev, struct sk_buff *skb,
+ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_MURU, sizeof(*muru));
+
+ muru = (struct sta_rec_muru *)tlv;
+- muru->cfg.mimo_dl_en = vif->bss_conf.eht_mu_beamformer ||
+- vif->bss_conf.he_mu_beamformer ||
+- vif->bss_conf.vht_mu_beamformer ||
+- vif->bss_conf.vht_mu_beamformee;
+- muru->cfg.ofdma_dl_en = true;
++ muru->cfg.mimo_dl_en = (vif->bss_conf.eht_mu_beamformer ||
++ vif->bss_conf.he_mu_beamformer ||
++ vif->bss_conf.vht_mu_beamformer ||
++ vif->bss_conf.vht_mu_beamformee) &&
++ !!(phy->muru_onoff & MUMIMO_DL);
++ muru->cfg.mimo_ul_en = !!(phy->muru_onoff & MUMIMO_UL);
++ muru->cfg.ofdma_dl_en = !!(phy->muru_onoff & OFDMA_DL);
++ muru->cfg.ofdma_ul_en = !!(phy->muru_onoff & OFDMA_UL);
+
+ if (sta->deflink.vht_cap.vht_supported)
+ muru->mimo_dl.vht_mu_bfee =
+@@ -4353,3 +4358,25 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+ return mt76_mcu_send_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(SCS),
+ &req, sizeof(req), false);
+ }
++
++#ifdef CONFIG_MTK_VENDOR
++void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
++{
++ u8 mode, val;
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ struct mt7996_phy *phy = mvif->phy;
++
++ mode = FIELD_GET(RATE_CFG_MODE, *((u32 *)data));
++ val = FIELD_GET(RATE_CFG_VAL, *((u32 *)data));
++
++ switch (mode) {
++ case RATE_PARAM_AUTO_MU:
++ if (val < 0 || val > 15) {
++ printk("Wrong value! The value is between 0-15.\n");
++ break;
++ }
++ phy->muru_onoff = val;
++ break;
++ }
++}
++#endif
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 5d52b0b7..baffbcd7 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -568,8 +568,20 @@ enum {
+ RATE_PARAM_FIXED_MCS,
+ RATE_PARAM_FIXED_GI = 11,
+ RATE_PARAM_AUTO = 20,
++#ifdef CONFIG_MTK_VENDOR
++ RATE_PARAM_AUTO_MU = 32,
++#endif
+ };
+
++#define RATE_CFG_MODE GENMASK(15, 8)
++#define RATE_CFG_VAL GENMASK(7, 0)
++
++/* MURU */
++#define OFDMA_DL BIT(0)
++#define OFDMA_UL BIT(1)
++#define MUMIMO_DL BIT(2)
++#define MUMIMO_UL BIT(3)
++
+ enum {
+ BF_SOUNDING_ON = 1,
+ BF_HW_EN_UPDATE = 17,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 085307ab..b9f3dd8e 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -263,6 +263,8 @@ struct mt7996_phy {
+ u32 rx_ampdu_ts;
+ u32 ampdu_ref;
+
++ u8 muru_onoff;
++
+ struct mib_stats mib;
+ struct mt76_channel_state state_ts;
+
+@@ -672,6 +674,11 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, struct dentry *dir);
+ #endif
+
++#ifdef CONFIG_MTK_VENDOR
++void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
++void mt7996_vendor_register(struct mt7996_phy *phy);
++#endif
++
+ #ifdef CONFIG_MTK_DEBUG
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir);
+ #endif
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+new file mode 100644
+index 00000000..08ecc2b3
+--- /dev/null
++++ b/mt7996/vendor.c
+@@ -0,0 +1,84 @@
++// SPDX-License-Identifier: ISC
++/*
++ * Copyright (C) 2020, MediaTek Inc. All rights reserved.
++ */
++
++#include <net/netlink.h>
++
++#include "mt7996.h"
++#include "mcu.h"
++#include "vendor.h"
++
++static const struct nla_policy
++mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
++ [MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 },
++ [MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
++};
++
++static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
++ struct wireless_dev *wdev,
++ const void *data,
++ int data_len)
++{
++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_MU_CTRL];
++ int err;
++ u8 val8;
++ u32 val32 = 0;
++
++ err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len,
++ mu_ctrl_policy, NULL);
++ if (err)
++ return err;
++
++ if (tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]) {
++ val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_MU_CTRL_ONOFF]);
++ val32 |= FIELD_PREP(RATE_CFG_MODE, RATE_PARAM_AUTO_MU) |
++ FIELD_PREP(RATE_CFG_VAL, val8);
++ ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL,
++ mt7996_set_wireless_vif, &val32);
++ }
++
++ return 0;
++}
++
++static int
++mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
++ struct sk_buff *skb, const void *data, int data_len,
++ unsigned long *storage)
++{
++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct mt7996_phy *phy = mt7996_hw_phy(hw);
++ int len = 0;
++
++ if (*storage == 1)
++ return -ENOENT;
++ *storage = 1;
++
++ if (nla_put_u8(skb, MTK_VENDOR_ATTR_MU_CTRL_DUMP, phy->muru_onoff))
++ return -ENOMEM;
++ len += 1;
++
++ return len;
++}
++
++static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
++ {
++ .info = {
++ .vendor_id = MTK_NL80211_VENDOR_ID,
++ .subcmd = MTK_NL80211_VENDOR_SUBCMD_MU_CTRL,
++ },
++ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++ WIPHY_VENDOR_CMD_NEED_RUNNING,
++ .doit = mt7996_vendor_mu_ctrl,
++ .dumpit = mt7996_vendor_mu_ctrl_dump,
++ .policy = mu_ctrl_policy,
++ .maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
++ },
++};
++
++void mt7996_vendor_register(struct mt7996_phy *phy)
++{
++ phy->mt76->hw->wiphy->vendor_commands = mt7996_vendor_commands;
++ phy->mt76->hw->wiphy->n_vendor_commands = ARRAY_SIZE(mt7996_vendor_commands);
++}
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+new file mode 100644
+index 00000000..8ac3ba8e
+--- /dev/null
++++ b/mt7996/vendor.h
+@@ -0,0 +1,22 @@
++#ifndef __MT7996_VENDOR_H
++#define __MT7996_VENDOR_H
++
++#define MTK_NL80211_VENDOR_ID 0x0ce7
++
++enum mtk_nl80211_vendor_subcmds {
++ MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
++};
++
++enum mtk_vendor_attr_mu_ctrl {
++ MTK_VENDOR_ATTR_MU_CTRL_UNSPEC,
++
++ MTK_VENDOR_ATTR_MU_CTRL_ONOFF,
++ MTK_VENDOR_ATTR_MU_CTRL_DUMP,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_MU_CTRL,
++ MTK_VENDOR_ATTR_MU_CTRL_MAX =
++ NUM_MTK_VENDOR_ATTRS_MU_CTRL - 1
++};
++
++#endif
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-mt7996-Add-air-monitor-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-mt7996-Add-air-monitor-support.patch
new file mode 100644
index 0000000..d83c3f9
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1003-wifi-mt76-mt7996-Add-air-monitor-support.patch
@@ -0,0 +1,565 @@
+From 2637da59e92d101889cf3680e57f0594c6b349ec Mon Sep 17 00:00:00 2001
+From: Evelyn Tsai <evelyn.tsai@mediatek.com>
+Date: Wed, 26 Apr 2023 04:40:05 +0800
+Subject: [PATCH 1003/1015] wifi: mt76: mt7996: Add air monitor support
+
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/mac.c | 4 +
+ mt7996/main.c | 4 +
+ mt7996/mt7996.h | 35 +++++
+ mt7996/vendor.c | 362 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 39 +++++
+ 6 files changed, 445 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 4bb9508a..e62f17ad 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1206,6 +1206,7 @@ enum {
+ MCU_UNI_CMD_REG_ACCESS = 0x0d,
+ MCU_UNI_CMD_CHIP_CONFIG = 0x0e,
+ MCU_UNI_CMD_POWER_CTRL = 0x0f,
++ MCU_UNI_CMD_CFG_SMESH = 0x10,
+ MCU_UNI_CMD_RX_HDR_TRANS = 0x12,
+ MCU_UNI_CMD_SER = 0x13,
+ MCU_UNI_CMD_TWT = 0x14,
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 05269e7f..3dc5cdae 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -865,6 +865,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ if (ieee80211_has_a4(fc) && is_mesh && status->amsdu)
+ *qos &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
+ }
++#ifdef CONFIG_MTK_VENDOR
++ if (phy->amnt_ctrl.enable && !ieee80211_is_beacon(fc))
++ mt7996_vendor_amnt_fill_rx(phy, skb);
++#endif
+ } else {
+ status->flag |= RX_FLAG_8023;
+ }
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 2ed66e6c..e5627c96 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -672,6 +672,10 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
+ mt7996_mac_wtbl_update(dev, idx,
+ MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
+
++#ifdef CONFIG_MTK_VENDOR
++ mt7996_vendor_amnt_sta_remove(mvif->phy, sta);
++#endif
++
+ ret = mt7996_mcu_add_sta(dev, vif, sta, true);
+ if (ret)
+ return ret;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index b9f3dd8e..dc44edc1 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -235,6 +235,34 @@ enum {
+ SCS_ENABLE,
+ };
+
++#ifdef CONFIG_MTK_VENDOR
++#define MT7996_AIR_MONITOR_MAX_ENTRY 16
++#define MT7996_AIR_MONITOR_MAX_GROUP (MT7996_AIR_MONITOR_MAX_ENTRY >> 1)
++
++struct mt7996_air_monitor_group {
++ bool enable;
++ bool used[2];
++};
++
++struct mt7996_air_monitor_entry {
++ bool enable;
++
++ u8 group_idx;
++ u8 group_used_idx;
++ u8 muar_idx;
++ u8 addr[ETH_ALEN];
++ u32 last_seen;
++ s8 rssi[4];
++ struct ieee80211_sta *sta;
++};
++
++struct mt7996_air_monitor_ctrl {
++ u8 enable;
++ struct mt7996_air_monitor_group group[MT7996_AIR_MONITOR_MAX_GROUP];
++ struct mt7996_air_monitor_entry entry[MT7996_AIR_MONITOR_MAX_ENTRY];
++};
++#endif
++
+ struct mt7996_phy {
+ struct mt76_phy *mt76;
+ struct mt7996_dev *dev;
+@@ -285,6 +313,10 @@ struct mt7996_phy {
+ u8 spe_idx;
+ } test;
+ #endif
++#ifdef CONFIG_MTK_VENDOR
++ spinlock_t amnt_lock;
++ struct mt7996_air_monitor_ctrl amnt_ctrl;
++#endif
+ };
+
+ struct mt7996_dev {
+@@ -677,6 +709,9 @@ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ #ifdef CONFIG_MTK_VENDOR
+ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
+ void mt7996_vendor_register(struct mt7996_phy *phy);
++void mt7996_vendor_amnt_fill_rx(struct mt7996_phy *phy, struct sk_buff *skb);
++int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
++ struct ieee80211_sta *sta);
+ #endif
+
+ #ifdef CONFIG_MTK_DEBUG
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 08ecc2b3..8a021324 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -15,6 +15,32 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = {
+ [MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 },
+ };
+
++static const struct nla_policy
++amnt_ctrl_policy[NUM_MTK_VENDOR_ATTRS_AMNT_CTRL] = {
++ [MTK_VENDOR_ATTR_AMNT_CTRL_SET] = {.type = NLA_NESTED },
++ [MTK_VENDOR_ATTR_AMNT_CTRL_DUMP] = { .type = NLA_NESTED },
++};
++
++static const struct nla_policy
++amnt_set_policy[NUM_MTK_VENDOR_ATTRS_AMNT_SET] = {
++ [MTK_VENDOR_ATTR_AMNT_SET_INDEX] = {.type = NLA_U8 },
++ [MTK_VENDOR_ATTR_AMNT_SET_MACADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
++};
++
++static const struct nla_policy
++amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
++ [MTK_VENDOR_ATTR_AMNT_DUMP_INDEX] = {.type = NLA_U8 },
++ [MTK_VENDOR_ATTR_AMNT_DUMP_LEN] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
++};
++
++struct mt7996_amnt_data {
++ u8 idx;
++ u8 addr[ETH_ALEN];
++ s8 rssi[4];
++ u32 last_seen;
++};
++
+ static int mt7996_vendor_mu_ctrl(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data,
+@@ -62,6 +88,328 @@ mt7996_vendor_mu_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ return len;
+ }
+
++void mt7996_vendor_amnt_fill_rx(struct mt7996_phy *phy, struct sk_buff *skb)
++{
++ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
++ struct mt7996_air_monitor_ctrl *ctrl = &phy->amnt_ctrl;
++ struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb);
++ __le16 fc = hdr->frame_control;
++ u8 addr[ETH_ALEN];
++ int i;
++
++ if (!ieee80211_has_fromds(fc))
++ ether_addr_copy(addr, hdr->addr2);
++ else if (ieee80211_has_tods(fc))
++ ether_addr_copy(addr, hdr->addr4);
++ else
++ ether_addr_copy(addr, hdr->addr3);
++
++ spin_lock_bh(&phy->amnt_lock);
++ for (i = 0; i < MT7996_AIR_MONITOR_MAX_ENTRY; i++) {
++ struct mt7996_air_monitor_entry *entry;
++
++ if (ether_addr_equal(addr, ctrl->entry[i].addr)) {
++ entry = &ctrl->entry[i];
++ entry->rssi[0] = status->chain_signal[0];
++ entry->rssi[1] = status->chain_signal[1];
++ entry->rssi[2] = status->chain_signal[2];
++ entry->rssi[3] = status->chain_signal[3];
++ entry->last_seen = jiffies;
++ break;
++ }
++ }
++ spin_unlock_bh(&phy->amnt_lock);
++}
++
++static int
++mt7996_vendor_smesh_ctrl(struct mt7996_phy *phy, u8 write,
++ u8 enable, u8 *value)
++{
++#define UNI_CMD_SMESH_PARAM 0
++ struct mt7996_dev *dev = phy->dev;
++ struct smesh_param {
++ __le16 tag;
++ __le16 length;
++
++ u8 enable;
++ bool a2;
++ bool a1;
++ bool data;
++ bool mgnt;
++ bool ctrl;
++ u8 padding[2];
++ } req = {
++ .tag = cpu_to_le16(UNI_CMD_SMESH_PARAM),
++ .length = cpu_to_le16(sizeof(req) - 4),
++
++ .enable = enable,
++ .a2 = true,
++ .a1 = true,
++ .data = true,
++ .mgnt = false,
++ .ctrl = false,
++ };
++ struct smesh_param *res;
++ struct sk_buff *skb;
++ int ret = 0;
++
++ if (!value)
++ return -EINVAL;
++
++ ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WM_UNI_CMD(CFG_SMESH),
++ &req, sizeof(req), !write, &skb);
++
++ if (ret || write)
++ return ret;
++
++ res = (struct smesh_param *) skb->data;
++
++ *value = res->enable;
++
++ dev_kfree_skb(skb);
++
++ return 0;
++}
++
++static int
++mt7996_vendor_amnt_muar(struct mt7996_phy *phy, u8 muar_idx, u8 *addr)
++{
++#define UNI_CMD_MUAR_ENTRY 2
++ struct mt7996_dev *dev = phy->dev;
++ struct muar_entry {
++ __le16 tag;
++ __le16 length;
++
++ bool smesh;
++ u8 hw_bss_index;
++ u8 muar_idx;
++ u8 entry_add;
++ u8 mac_addr[6];
++ u8 padding[2];
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_CMD_MUAR_ENTRY),
++ .length = cpu_to_le16(sizeof(req) - 4),
++
++ .smesh = true,
++ .hw_bss_index = phy != &dev->phy,
++ .muar_idx = muar_idx,
++ .entry_add = 1,
++ };
++
++ ether_addr_copy(req.mac_addr, addr);
++ return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(REPT_MUAR), &req,
++ sizeof(req), true);
++}
++
++static int
++mt7996_vendor_amnt_set_en(struct mt7996_phy *phy, u8 enable)
++{
++ u8 status;
++ int ret;
++
++ ret = mt7996_vendor_smesh_ctrl(phy, 0, enable, &status);
++ if (ret)
++ return ret;
++
++ if (status == enable)
++ return 0;
++
++ ret = mt7996_vendor_smesh_ctrl(phy, 1, enable, &status);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++
++static int
++mt7996_vendor_amnt_set_addr(struct mt7996_phy *phy, u8 index, u8 *addr)
++{
++ struct mt7996_air_monitor_ctrl *amnt_ctrl = &phy->amnt_ctrl;
++ struct mt7996_air_monitor_group *group;
++ struct mt7996_air_monitor_entry *entry;
++ int ret, i, j;
++
++ if (index >= MT7996_AIR_MONITOR_MAX_ENTRY)
++ return -1;
++
++ spin_lock_bh(&phy->amnt_lock);
++ entry = &amnt_ctrl->entry[index];
++ if (!is_zero_ether_addr(addr)) {
++ if (entry->enable == false) {
++ for (i = 0; i < MT7996_AIR_MONITOR_MAX_GROUP; i++) {
++ group = &(amnt_ctrl->group[i]);
++ if (group->used[0] == false)
++ j = 0;
++ else if (group->used[1] == false)
++ j = 1;
++ else
++ continue;
++
++ group->enable = true;
++ group->used[j] = true;
++ entry->enable = true;
++ entry->group_idx = i;
++ entry->group_used_idx = j;
++ entry->muar_idx = 32 + 4 * i + 2 * j;
++ break;
++ }
++ }
++ } else {
++ group = &(amnt_ctrl->group[entry->group_idx]);
++
++ group->used[entry->group_used_idx] = false;
++ if (group->used[0] == false && group->used[1] == false)
++ group->enable = false;
++
++ entry->enable = false;
++ }
++ ether_addr_copy(entry->addr, addr);
++ amnt_ctrl->enable &= ~(1 << entry->group_idx);
++ amnt_ctrl->enable |= entry->enable << entry->group_idx;
++ spin_unlock_bh(&phy->amnt_lock);
++
++ ret = mt7996_vendor_amnt_muar(phy, entry->muar_idx, addr);
++ if (ret)
++ return ret;
++
++ return mt7996_vendor_amnt_set_en(phy, amnt_ctrl->enable);
++}
++
++static int
++mt7966_vendor_amnt_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev,
++ const void *data, int data_len)
++{
++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct mt7996_phy *phy = mt7996_hw_phy(hw);
++ struct nlattr *tb1[NUM_MTK_VENDOR_ATTRS_AMNT_CTRL];
++ struct nlattr *tb2[NUM_MTK_VENDOR_ATTRS_AMNT_SET];
++ u8 index = 0;
++ u8 mac_addr[ETH_ALEN];
++ int err;
++
++ err = nla_parse(tb1, MTK_VENDOR_ATTR_AMNT_CTRL_MAX, data, data_len,
++ amnt_ctrl_policy, NULL);
++ if (err)
++ return err;
++
++ if (!tb1[MTK_VENDOR_ATTR_AMNT_CTRL_SET])
++ return -EINVAL;
++
++ err = nla_parse_nested(tb2, MTK_VENDOR_ATTR_AMNT_SET_MAX,
++ tb1[MTK_VENDOR_ATTR_AMNT_CTRL_SET], amnt_set_policy, NULL);
++
++ if (!tb2[MTK_VENDOR_ATTR_AMNT_SET_INDEX] ||
++ !tb2[MTK_VENDOR_ATTR_AMNT_SET_MACADDR])
++ return -EINVAL;
++
++ index = nla_get_u8(tb2[MTK_VENDOR_ATTR_AMNT_SET_INDEX]);
++ memcpy(mac_addr, nla_data(tb2[MTK_VENDOR_ATTR_AMNT_SET_MACADDR]), ETH_ALEN);
++
++ return mt7996_vendor_amnt_set_addr(phy, index, mac_addr);
++}
++
++int mt7996_vendor_amnt_sta_remove(struct mt7996_phy *phy,
++ struct ieee80211_sta *sta)
++{
++ u8 zero[ETH_ALEN] = {};
++ int i;
++
++ if (!phy->amnt_ctrl.enable)
++ return 0;
++
++ for (i = 0; i < MT7996_AIR_MONITOR_MAX_ENTRY; i++)
++ if (ether_addr_equal(sta->addr, phy->amnt_ctrl.entry[i].addr))
++ return mt7996_vendor_amnt_set_addr(phy, i, zero);
++ return 0;
++}
++
++static int
++mt7996_amnt_dump(struct mt7996_phy *phy, struct sk_buff *skb,
++ u8 amnt_idx, int *attrtype)
++{
++ struct mt7996_air_monitor_entry *entry;
++ struct mt7996_amnt_data data;
++ u32 last_seen = 0;
++
++ spin_lock_bh(&phy->amnt_lock);
++ entry = &phy->amnt_ctrl.entry[amnt_idx];
++ if (entry->enable == 0) {
++ spin_unlock_bh(&phy->amnt_lock);
++ return 0;
++ }
++
++ last_seen = jiffies_to_msecs(jiffies - entry->last_seen);
++ ether_addr_copy(data.addr, entry->addr);
++ data.rssi[0] = entry->rssi[0];
++ data.rssi[1] = entry->rssi[1];
++ data.rssi[2] = entry->rssi[2];
++ data.rssi[3] = entry->rssi[3];
++ spin_unlock_bh(&phy->amnt_lock);
++
++ data.idx = amnt_idx;
++ data.last_seen = last_seen;
++
++ nla_put(skb, (*attrtype)++, sizeof(struct mt7996_amnt_data), &data);
++
++ return 1;
++}
++
++static int
++mt7966_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
++ struct sk_buff *skb, const void *data, int data_len,
++ unsigned long *storage)
++{
++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct mt7996_phy *phy = mt7996_hw_phy(hw);
++ struct nlattr *tb1[NUM_MTK_VENDOR_ATTRS_AMNT_CTRL];
++ struct nlattr *tb2[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP];
++ void *a, *b;
++ int err = 0, attrtype = 0, i, len = 0;
++ u8 amnt_idx;
++
++ if (*storage == 1)
++ return -ENOENT;
++ *storage = 1;
++
++ err = nla_parse(tb1, MTK_VENDOR_ATTR_AMNT_CTRL_MAX, data, data_len,
++ amnt_ctrl_policy, NULL);
++ if (err)
++ return err;
++
++ if (!tb1[MTK_VENDOR_ATTR_AMNT_CTRL_DUMP])
++ return -EINVAL;
++
++ err = nla_parse_nested(tb2, MTK_VENDOR_ATTR_AMNT_DUMP_MAX,
++ tb1[MTK_VENDOR_ATTR_AMNT_CTRL_DUMP],
++ amnt_dump_policy, NULL);
++ if (err)
++ return err;
++
++ if (!tb2[MTK_VENDOR_ATTR_AMNT_DUMP_INDEX])
++ return -EINVAL;
++
++ amnt_idx = nla_get_u8(tb2[MTK_VENDOR_ATTR_AMNT_DUMP_INDEX]);
++
++ a = nla_nest_start(skb, MTK_VENDOR_ATTR_AMNT_CTRL_DUMP);
++ b = nla_nest_start(skb, MTK_VENDOR_ATTR_AMNT_DUMP_RESULT);
++
++ if (amnt_idx != 0xff) {
++ len += mt7996_amnt_dump(phy, skb, amnt_idx, &attrtype);
++ } else {
++ for (i = 0; i < MT7996_AIR_MONITOR_MAX_ENTRY; i++)
++ len += mt7996_amnt_dump(phy, skb, i, &attrtype);
++ }
++
++ nla_nest_end(skb, b);
++
++ nla_put_u8(skb, MTK_VENDOR_ATTR_AMNT_DUMP_LEN, len);
++
++ nla_nest_end(skb, a);
++
++ return len + 1;
++}
++
++
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ {
+ .info = {
+@@ -75,10 +423,24 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ .policy = mu_ctrl_policy,
+ .maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX,
+ },
++ {
++ .info = {
++ .vendor_id = MTK_NL80211_VENDOR_ID,
++ .subcmd = MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL,
++ },
++ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++ WIPHY_VENDOR_CMD_NEED_RUNNING,
++ .doit = mt7966_vendor_amnt_ctrl,
++ .dumpit = mt7966_vendor_amnt_ctrl_dump,
++ .policy = amnt_ctrl_policy,
++ .maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
++ },
+ };
+
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+ {
+ phy->mt76->hw->wiphy->vendor_commands = mt7996_vendor_commands;
+ phy->mt76->hw->wiphy->n_vendor_commands = ARRAY_SIZE(mt7996_vendor_commands);
++
++ spin_lock_init(&phy->amnt_lock);
+ }
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 8ac3ba8e..2078cafa 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -4,6 +4,7 @@
+ #define MTK_NL80211_VENDOR_ID 0x0ce7
+
+ enum mtk_nl80211_vendor_subcmds {
++ MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
+ MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
+ };
+
+@@ -19,4 +20,42 @@ enum mtk_vendor_attr_mu_ctrl {
+ NUM_MTK_VENDOR_ATTRS_MU_CTRL - 1
+ };
+
++enum mtk_vendor_attr_mnt_ctrl {
++ MTK_VENDOR_ATTR_AMNT_CTRL_UNSPEC,
++
++ MTK_VENDOR_ATTR_AMNT_CTRL_SET,
++ MTK_VENDOR_ATTR_AMNT_CTRL_DUMP,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_AMNT_CTRL,
++ MTK_VENDOR_ATTR_AMNT_CTRL_MAX =
++ NUM_MTK_VENDOR_ATTRS_AMNT_CTRL - 1
++};
++
++enum mtk_vendor_attr_mnt_set {
++ MTK_VENDOR_ATTR_AMNT_SET_UNSPEC,
++
++ MTK_VENDOR_ATTR_AMNT_SET_INDEX,
++ MTK_VENDOR_ATTR_AMNT_SET_MACADDR,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_AMNT_SET,
++ MTK_VENDOR_ATTR_AMNT_SET_MAX =
++ NUM_MTK_VENDOR_ATTRS_AMNT_SET - 1
++};
++
++enum mtk_vendor_attr_mnt_dump {
++ MTK_VENDOR_ATTR_AMNT_DUMP_UNSPEC,
++
++ MTK_VENDOR_ATTR_AMNT_DUMP_INDEX,
++ MTK_VENDOR_ATTR_AMNT_DUMP_LEN,
++ MTK_VENDOR_ATTR_AMNT_DUMP_RESULT,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_AMNT_DUMP,
++ MTK_VENDOR_ATTR_AMNT_DUMP_MAX =
++ NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1
++};
++
++
+ #endif
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
new file mode 100644
index 0000000..50db576
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch
@@ -0,0 +1,27 @@
+From 75b684d04d569b5e83780d2296bed12d3785836c Mon Sep 17 00:00:00 2001
+From: mtk23510 <rudra.shahi@mediatek.com>
+Date: Fri, 24 Mar 2023 19:18:53 +0800
+Subject: [PATCH 1004/1015] wifi: mt76: mt7996: add driver support for wpa3 ocv
+ and bp mt76
+
+Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
+---
+ mt7996/init.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 1d4359f0..40d610ae 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -373,6 +373,8 @@ mt7996_init_wiphy(struct ieee80211_hw *hw)
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT);
+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
+
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION);
++ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_PROTECTION);
+ if (!mdev->dev->of_node ||
+ !of_property_read_bool(mdev->dev->of_node,
+ "mediatek,disable-radar-background"))
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-add-U-NII-4-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-add-U-NII-4-support.patch
new file mode 100644
index 0000000..8eaf2d5
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1005-wifi-mt76-mt7996-add-U-NII-4-support.patch
@@ -0,0 +1,25 @@
+From 09b50cf201ede70688619366c31aa2ddd57d5cb2 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 31 Mar 2023 11:26:27 +0800
+Subject: [PATCH 1005/1015] wifi: mt76: mt7996: add U-NII-4 support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mac80211.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mac80211.c b/mac80211.c
+index d1cdaee8..501325e9 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -76,6 +76,7 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = {
+ CHAN5G(165, 5825),
+ CHAN5G(169, 5845),
+ CHAN5G(173, 5865),
++ CHAN5G(177, 5885),
+ };
+
+ static const struct ieee80211_channel mt76_channels_6ghz[] = {
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
new file mode 100644
index 0000000..e185c11
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch
@@ -0,0 +1,898 @@
+From 47c64d6cac5ed78fab15cd4173ae8935605a3fca Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 31 Mar 2023 11:27:24 +0800
+Subject: [PATCH 1006/1015] wifi: mt76: testmode: add testmode pre-calibration
+ support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Change-Id: If8a6cc02fa20e35f079c826e0571e8c04c3f9c7e
+---
+ mac80211.c | 21 ---
+ mt76.h | 22 +++
+ mt76_connac_mcu.h | 2 +
+ mt7996/eeprom.c | 66 +++++++
+ mt7996/eeprom.h | 47 +++++
+ mt7996/mcu.c | 5 +
+ mt7996/mt7996.h | 7 +
+ mt7996/testmode.c | 437 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/testmode.h | 20 ++-
+ testmode.c | 12 ++
+ testmode.h | 8 +
+ tools/fields.c | 8 +
+ 12 files changed, 632 insertions(+), 23 deletions(-)
+
+diff --git a/mac80211.c b/mac80211.c
+index 501325e9..6430e6ee 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -7,27 +7,6 @@
+ #include <net/page_pool.h>
+ #include "mt76.h"
+
+-#define CHAN2G(_idx, _freq) { \
+- .band = NL80211_BAND_2GHZ, \
+- .center_freq = (_freq), \
+- .hw_value = (_idx), \
+- .max_power = 30, \
+-}
+-
+-#define CHAN5G(_idx, _freq) { \
+- .band = NL80211_BAND_5GHZ, \
+- .center_freq = (_freq), \
+- .hw_value = (_idx), \
+- .max_power = 30, \
+-}
+-
+-#define CHAN6G(_idx, _freq) { \
+- .band = NL80211_BAND_6GHZ, \
+- .center_freq = (_freq), \
+- .hw_value = (_idx), \
+- .max_power = 30, \
+-}
+-
+ static const struct ieee80211_channel mt76_channels_2ghz[] = {
+ CHAN2G(1, 2412),
+ CHAN2G(2, 2417),
+diff --git a/mt76.h b/mt76.h
+index 31d5dc37..3341720c 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -18,6 +18,27 @@
+ #include "util.h"
+ #include "testmode.h"
+
++#define CHAN2G(_idx, _freq) { \
++ .band = NL80211_BAND_2GHZ, \
++ .center_freq = (_freq), \
++ .hw_value = (_idx), \
++ .max_power = 30, \
++}
++
++#define CHAN5G(_idx, _freq) { \
++ .band = NL80211_BAND_5GHZ, \
++ .center_freq = (_freq), \
++ .hw_value = (_idx), \
++ .max_power = 30, \
++}
++
++#define CHAN6G(_idx, _freq) { \
++ .band = NL80211_BAND_6GHZ, \
++ .center_freq = (_freq), \
++ .hw_value = (_idx), \
++ .max_power = 30, \
++}
++
+ #define MT_MCU_RING_SIZE 32
+ #define MT_RX_BUF_SIZE 2048
+ #define MT_SKB_HEAD_LEN 256
+@@ -654,6 +675,7 @@ struct mt76_testmode_ops {
+ int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
+ void (*reset_rx_stats)(struct mt76_phy *phy);
+ void (*tx_stop)(struct mt76_phy *phy);
++ int (*dump_precal)(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int type);
+ };
+
+ #define MT_TM_FW_RX_COUNT BIT(0)
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index e62f17ad..262abf88 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1011,6 +1011,8 @@ enum {
+ MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
+ MCU_UNI_EVENT_RDD_REPORT = 0x11,
+ MCU_UNI_EVENT_THERMAL = 0x35,
++ MCU_UNI_EVENT_BF = 0x33,
++ MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
+ };
+
+ #define MCU_UNI_CMD_EVENT BIT(1)
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index be0a34ae..60e98463 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -12,6 +12,42 @@ static bool testmode_enable;
+ module_param(testmode_enable, bool, 0644);
+ MODULE_PARM_DESC(testmode_enable, "Enable testmode");
+
++const struct ieee80211_channel dpd_2g_ch_list_bw20[] = {
++ CHAN2G(3, 2422),
++ CHAN2G(7, 2442),
++ CHAN2G(11, 2462)
++};
++
++const struct ieee80211_channel dpd_5g_ch_list_bw160[] = {
++ CHAN5G(50, 5250),
++ CHAN5G(114, 5570),
++ CHAN5G(163, 5815)
++};
++
++const struct ieee80211_channel dpd_6g_ch_list_bw160[] = {
++ CHAN6G(15, 6025),
++ CHAN6G(47, 6185),
++ CHAN6G(79, 6345),
++ CHAN6G(111, 6505),
++ CHAN6G(143, 6665),
++ CHAN6G(175, 6825),
++ CHAN6G(207, 6985)
++};
++
++const struct ieee80211_channel dpd_6g_ch_list_bw320[] = {
++ CHAN6G(31, 6105),
++ CHAN6G(63, 6265),
++ CHAN6G(95, 6425),
++ CHAN6G(127, 6585),
++ CHAN6G(159, 6745),
++ CHAN6G(191, 6905)
++};
++
++const u32 dpd_2g_bw20_ch_num = ARRAY_SIZE(dpd_2g_ch_list_bw20);
++const u32 dpd_5g_bw160_ch_num = ARRAY_SIZE(dpd_5g_ch_list_bw160);
++const u32 dpd_6g_bw160_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw160);
++const u32 dpd_6g_bw320_ch_num = ARRAY_SIZE(dpd_6g_ch_list_bw320);
++
+ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ {
+ u8 *eeprom = dev->mt76.eeprom.data;
+@@ -34,6 +70,36 @@ static char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ return MT7996_EEPROM_DEFAULT;
+ }
+
++int
++mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band)
++{
++ /* handle different sku */
++ static const u8 band_to_idx[] = {
++ [NL80211_BAND_2GHZ] = MT_BAND0,
++ [NL80211_BAND_5GHZ] = MT_BAND1,
++ [NL80211_BAND_6GHZ] = MT_BAND2,
++ };
++ struct mt7996_phy *phy = __mt7996_phy(dev, band_to_idx[band]);
++ struct mt76_phy *mphy;
++ int dpd_size;
++
++ if (!phy)
++ return 0;
++
++ mphy = phy->mt76;
++
++ if (band == NL80211_BAND_2GHZ)
++ dpd_size = dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
++ else if (band == NL80211_BAND_5GHZ)
++ dpd_size = mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
++ dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++ else
++ dpd_size = mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
++ (dpd_6g_bw160_ch_num + dpd_6g_bw320_ch_num) * DPD_PER_CH_GT_BW20_SIZE;
++
++ return dpd_size;
++}
++
+ static int
+ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+ {
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 343e65e1..7ff290f4 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -14,6 +14,7 @@ enum mt7996_eeprom_field {
+ MT_EE_MAC_ADDR = 0x004,
+ MT_EE_MAC_ADDR2 = 0x00a,
+ MT_EE_WIFI_CONF = 0x190,
++ MT_EE_DO_PRE_CAL = 0x1a5,
+ MT_EE_TESTMODE_EN = 0x1af,
+ MT_EE_MAC_ADDR3 = 0x2c0,
+ MT_EE_RATE_DELTA_2G = 0x1400,
+@@ -31,6 +32,52 @@ enum mt7996_eeprom_field {
+ #define MT_EE_WIFI_CONF1_BAND_SEL GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF2_BAND_SEL GENMASK(2, 0)
+
++#define MT_EE_WIFI_CAL_GROUP_2G BIT(0)
++#define MT_EE_WIFI_CAL_GROUP_5G BIT(1)
++#define MT_EE_WIFI_CAL_GROUP_6G BIT(2)
++#define MT_EE_WIFI_CAL_GROUP GENMASK(2, 0)
++#define MT_EE_WIFI_CAL_DPD_2G BIT(3)
++#define MT_EE_WIFI_CAL_DPD_5G BIT(4)
++#define MT_EE_WIFI_CAL_DPD_6G BIT(5)
++#define MT_EE_WIFI_CAL_DPD GENMASK(5, 3)
++
++#define MT_EE_CAL_UNIT 1024
++#define MT_EE_CAL_GROUP_SIZE_2G (4 * MT_EE_CAL_UNIT)
++#define MT_EE_CAL_GROUP_SIZE_5G (45 * MT_EE_CAL_UNIT)
++#define MT_EE_CAL_GROUP_SIZE_6G (125 * MT_EE_CAL_UNIT)
++#define MT_EE_CAL_ADCDCOC_SIZE_2G (4 * 4)
++#define MT_EE_CAL_ADCDCOC_SIZE_5G (4 * 4)
++#define MT_EE_CAL_ADCDCOC_SIZE_6G (4 * 5)
++#define MT_EE_CAL_GROUP_SIZE (MT_EE_CAL_GROUP_SIZE_2G + \
++ MT_EE_CAL_GROUP_SIZE_5G + \
++ MT_EE_CAL_GROUP_SIZE_6G + \
++ MT_EE_CAL_ADCDCOC_SIZE_2G + \
++ MT_EE_CAL_ADCDCOC_SIZE_5G + \
++ MT_EE_CAL_ADCDCOC_SIZE_6G)
++
++#define DPD_PER_CH_LEGACY_SIZE (4 * MT_EE_CAL_UNIT)
++#define DPD_PER_CH_MEM_SIZE (13 * MT_EE_CAL_UNIT)
++#define DPD_PER_CH_OTFG0_SIZE (2 * MT_EE_CAL_UNIT)
++#define DPD_PER_CH_BW20_SIZE (DPD_PER_CH_LEGACY_SIZE + DPD_PER_CH_OTFG0_SIZE)
++#define DPD_PER_CH_GT_BW20_SIZE (DPD_PER_CH_MEM_SIZE + DPD_PER_CH_OTFG0_SIZE)
++#define MT_EE_CAL_DPD_SIZE (780 * MT_EE_CAL_UNIT)
++
++extern const struct ieee80211_channel dpd_2g_ch_list_bw20[];
++extern const u32 dpd_2g_bw20_ch_num;
++extern const struct ieee80211_channel dpd_5g_ch_list_bw160[];
++extern const u32 dpd_5g_bw160_ch_num;
++extern const struct ieee80211_channel dpd_6g_ch_list_bw160[];
++extern const u32 dpd_6g_bw160_ch_num;
++extern const struct ieee80211_channel dpd_6g_ch_list_bw320[];
++extern const u32 dpd_6g_bw320_ch_num;
++
++#define RF_DPD_FLAT_CAL BIT(28)
++#define RF_PRE_CAL BIT(29)
++#define RF_DPD_FLAT_5G_CAL GENMASK(29, 28)
++#define RF_DPD_FLAT_5G_MEM_CAL (BIT(30) | BIT(28))
++#define RF_DPD_FLAT_6G_CAL GENMASK(30, 28)
++#define RF_DPD_FLAT_6G_MEM_CAL (BIT(31) | BIT(28))
++
+ #define MT_EE_WIFI_CONF1_TX_PATH_BAND0 GENMASK(5, 3)
+ #define MT_EE_WIFI_CONF2_TX_PATH_BAND1 GENMASK(2, 0)
+ #define MT_EE_WIFI_CONF2_TX_PATH_BAND2 GENMASK(5, 3)
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 91f3103a..1fb7bae1 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -523,6 +523,11 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ case MCU_UNI_EVENT_THERMAL:
+ mt7996_mcu_rx_thermal_notify(dev, skb);
+ break;
++#ifdef CONFIG_NL80211_TESTMODE
++ case MCU_UNI_EVENT_TESTMODE_CTRL:
++ mt7996_tm_rf_test_event(dev, skb);
++ break;
++#endif
+ default:
+ break;
+ }
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index dc44edc1..9ab86eaf 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -390,6 +390,9 @@ struct mt7996_dev {
+ struct dentry *debugfs_dir;
+ struct rchan *relay_fwlog;
+
++ void *cal;
++ u32 cur_prek_offset;
++
+ struct {
+ u8 table_mask;
+ u8 n_agrt;
+@@ -522,6 +525,7 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+ int mt7996_eeprom_get_target_power(struct mt7996_dev *dev,
+ struct ieee80211_channel *chan);
+ s8 mt7996_eeprom_get_power_delta(struct mt7996_dev *dev, int band);
++int mt7996_get_dpd_per_band_size(struct mt7996_dev *dev, enum nl80211_band band);
+ int mt7996_dma_init(struct mt7996_dev *dev);
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
+ void mt7996_dma_prefetch(struct mt7996_dev *dev);
+@@ -602,6 +606,9 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
++#ifdef CONFIG_NL80211_TESTMODE
++void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb);
++#endif
+
+ static inline u8 mt7996_max_interface_num(struct mt7996_dev *dev)
+ {
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index 43eca4ef..7d36902e 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -7,6 +7,8 @@
+ #include "mac.h"
+ #include "mcu.h"
+ #include "testmode.h"
++#include "eeprom.h"
++#include "mtk_mcu.h"
+
+ enum {
+ TM_CHANGED_TXPOWER,
+@@ -397,6 +399,436 @@ mt7996_tm_set_tx_cont(struct mt7996_phy *phy, bool en)
+ }
+ }
+
++static int
++mt7996_tm_group_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
++{
++ u8 *eeprom;
++ u32 i, group_size, dpd_size, size, offs, *pre_cal;
++ int ret = 0;
++ struct mt7996_dev *dev = phy->dev;
++ struct mt76_dev *mdev = &dev->mt76;
++ struct mt7996_tm_req req = {
++ .rf_test = {
++ .tag = cpu_to_le16(UNI_RF_TEST_CTRL),
++ .len = cpu_to_le16(sizeof(req.rf_test)),
++ .action = RF_ACTION_IN_RF_TEST,
++ .icap_len = RF_TEST_ICAP_LEN,
++ .op.rf.func_idx = cpu_to_le32(RF_TEST_RE_CAL),
++ .op.rf.param.cal_param.func_data = cpu_to_le32(RF_PRE_CAL),
++ .op.rf.param.cal_param.band_idx = phy->mt76->band_idx,
++ },
++ };
++
++ if (!dev->flash_mode) {
++ dev_err(dev->mt76.dev, "Currently not in FLASH or BIN FILE mode, return!\n");
++ return -EOPNOTSUPP;
++ }
++
++ eeprom = mdev->eeprom.data;
++ dev->cur_prek_offset = 0;
++ group_size = MT_EE_CAL_GROUP_SIZE;
++ dpd_size = MT_EE_CAL_DPD_SIZE;
++ size = group_size + dpd_size;
++ offs = MT_EE_DO_PRE_CAL;
++
++ switch (state) {
++ case MT76_TM_STATE_GROUP_PREK:
++ if (!dev->cal) {
++ dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
++ if (!dev->cal)
++ return -ENOMEM;
++ }
++
++ ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TESTMODE_CTRL), &req,
++ sizeof(req), false);
++ wait_event_timeout(mdev->mcu.wait, dev->cur_prek_offset == group_size,
++ 30 * HZ);
++
++ if (ret) {
++ dev_err(dev->mt76.dev, "Group Pre-cal: mcu send msg failed!\n");
++ return ret;
++ }
++
++ if (!ret)
++ eeprom[offs] |= MT_EE_WIFI_CAL_GROUP;
++ break;
++ case MT76_TM_STATE_GROUP_PREK_DUMP:
++ pre_cal = (u32 *)dev->cal;
++ if (!pre_cal) {
++ dev_info(dev->mt76.dev, "Not group pre-cal yet!\n");
++ return ret;
++ }
++ dev_info(dev->mt76.dev, "Group Pre-Cal:\n");
++ for (i = 0; i < (group_size / sizeof(u32)); i += 4) {
++ dev_info(dev->mt76.dev, "[0x%08lx] 0x%8x 0x%8x 0x%8x 0x%8x\n",
++ i * sizeof(u32), pre_cal[i], pre_cal[i + 1],
++ pre_cal[i + 2], pre_cal[i + 3]);
++ }
++ break;
++ case MT76_TM_STATE_GROUP_PREK_CLEAN:
++ pre_cal = (u32 *)dev->cal;
++ if (!pre_cal)
++ return ret;
++ memset(pre_cal, 0, group_size);
++ eeprom[offs] &= ~MT_EE_WIFI_CAL_GROUP;
++ break;
++ default:
++ return -EINVAL;
++ }
++
++ return ret;
++}
++
++static int
++mt7996_tm_dpd_prek_send_req(struct mt7996_phy *phy, struct mt7996_tm_req *req,
++ const struct ieee80211_channel *chan_list, u32 channel_size,
++ enum nl80211_chan_width width, u32 func_data)
++{
++ struct mt7996_dev *dev = phy->dev;
++ struct mt76_phy *mphy = phy->mt76;
++ struct cfg80211_chan_def chandef_backup, *chandef = &mphy->chandef;
++ struct ieee80211_channel chan_backup;
++ int i, ret;
++
++ if (!chan_list)
++ return -EOPNOTSUPP;
++
++ req->rf_test.op.rf.param.cal_param.func_data = cpu_to_le32(func_data);
++
++ memcpy(&chan_backup, chandef->chan, sizeof(struct ieee80211_channel));
++ memcpy(&chandef_backup, chandef, sizeof(struct cfg80211_chan_def));
++
++ for (i = 0; i < channel_size; i++) {
++ memcpy(chandef->chan, &chan_list[i], sizeof(struct ieee80211_channel));
++ chandef->width = width;
++
++ /* set channel switch reason */
++ mphy->hw->conf.flags |= IEEE80211_CONF_OFFCHANNEL;
++ mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
++
++ ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(TESTMODE_CTRL), req,
++ sizeof(*req), false);
++ if (ret) {
++ dev_err(dev->mt76.dev, "DPD Pre-cal: mcu send msg failed!\n");
++ goto out;
++ }
++ }
++
++out:
++ mphy->hw->conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
++ memcpy(chandef, &chandef_backup, sizeof(struct cfg80211_chan_def));
++ memcpy(chandef->chan, &chan_backup, sizeof(struct ieee80211_channel));
++ mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
++
++ return ret;
++}
++
++static int
++mt7996_tm_dpd_prek(struct mt7996_phy *phy, enum mt76_testmode_state state)
++{
++ struct mt7996_dev *dev = phy->dev;
++ struct mt76_dev *mdev = &dev->mt76;
++ struct mt76_phy *mphy = phy->mt76;
++ struct mt7996_tm_req req = {
++ .rf_test = {
++ .tag = cpu_to_le16(UNI_RF_TEST_CTRL),
++ .len = cpu_to_le16(sizeof(req.rf_test)),
++ .action = RF_ACTION_IN_RF_TEST,
++ .icap_len = RF_TEST_ICAP_LEN,
++ .op.rf.func_idx = cpu_to_le32(RF_TEST_RE_CAL),
++ .op.rf.param.cal_param.band_idx = phy->mt76->band_idx,
++ },
++ };
++ u32 i, j, group_size, dpd_size, size, offs, *pre_cal;
++ u32 wait_on_prek_offset = 0;
++ u8 do_precal, *eeprom;
++ int ret = 0;
++
++ if (!dev->flash_mode) {
++ dev_err(dev->mt76.dev, "Currently not in FLASH or BIN FILE mode, return!\n");
++ return -EOPNOTSUPP;
++ }
++
++ eeprom = mdev->eeprom.data;
++ dev->cur_prek_offset = 0;
++ group_size = MT_EE_CAL_GROUP_SIZE;
++ dpd_size = MT_EE_CAL_DPD_SIZE;
++ size = group_size + dpd_size;
++ offs = MT_EE_DO_PRE_CAL;
++
++ if (!dev->cal && state < MT76_TM_STATE_DPD_DUMP) {
++ dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
++ if (!dev->cal)
++ return -ENOMEM;
++ }
++
++ switch (state) {
++ case MT76_TM_STATE_DPD_2G:
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_2g_ch_list_bw20,
++ dpd_2g_bw20_ch_num,
++ NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_CAL);
++ wait_on_prek_offset += dpd_2g_bw20_ch_num * DPD_PER_CH_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait,
++ dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++
++ do_precal = MT_EE_WIFI_CAL_DPD_2G;
++ break;
++ case MT76_TM_STATE_DPD_5G:
++ /* 5g channel bw20 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, mphy->sband_5g.sband.channels,
++ mphy->sband_5g.sband.n_channels,
++ NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_5G_CAL);
++ if (ret)
++ return ret;
++ wait_on_prek_offset += mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait,
++ dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++
++ /* 5g channel bw160 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_5g_ch_list_bw160,
++ dpd_5g_bw160_ch_num,
++ NL80211_CHAN_WIDTH_160, RF_DPD_FLAT_5G_MEM_CAL);
++ wait_on_prek_offset += dpd_5g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait,
++ dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++
++ do_precal = MT_EE_WIFI_CAL_DPD_5G;
++ break;
++ case MT76_TM_STATE_DPD_6G:
++ /* 6g channel bw20 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, mphy->sband_6g.sband.channels,
++ mphy->sband_6g.sband.n_channels,
++ NL80211_CHAN_WIDTH_20, RF_DPD_FLAT_6G_CAL);
++ if (ret)
++ return ret;
++ wait_on_prek_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait,
++ dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++
++ /* 6g channel bw160 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw160,
++ dpd_6g_bw160_ch_num,
++ NL80211_CHAN_WIDTH_160, RF_DPD_FLAT_6G_MEM_CAL);
++ if (ret)
++ return ret;
++ wait_on_prek_offset += dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait,
++ dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++
++ /* 6g channel bw320 calibration */
++ ret = mt7996_tm_dpd_prek_send_req(phy, &req, dpd_6g_ch_list_bw320,
++ dpd_6g_bw320_ch_num,
++ NL80211_CHAN_WIDTH_320, RF_DPD_FLAT_6G_MEM_CAL);
++ wait_on_prek_offset += dpd_6g_bw320_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++ wait_event_timeout(mdev->mcu.wait,
++ dev->cur_prek_offset == wait_on_prek_offset, 30 * HZ);
++
++ do_precal = MT_EE_WIFI_CAL_DPD_6G;
++ break;
++ case MT76_TM_STATE_DPD_DUMP:
++ if (!dev->cal) {
++ dev_info(dev->mt76.dev, "Not DPD pre-cal yet!\n");
++ return ret;
++ }
++ pre_cal = (u32 *)dev->cal;
++ dev_info(dev->mt76.dev, "DPD Pre-Cal:\n");
++ for (i = 0; i < dpd_size / sizeof(u32); i += 4) {
++ j = i + (group_size / sizeof(u32));
++ dev_info(dev->mt76.dev, "[0x%08lx] 0x%8x 0x%8x 0x%8x 0x%8x\n",
++ j * sizeof(u32), pre_cal[j], pre_cal[j + 1],
++ pre_cal[j + 2], pre_cal[j + 3]);
++ }
++ return 0;
++ case MT76_TM_STATE_DPD_CLEAN:
++ pre_cal = (u32 *)dev->cal;
++ if (!pre_cal)
++ return ret;
++ memset(pre_cal + (group_size / sizeof(u32)), 0, dpd_size);
++ do_precal = MT_EE_WIFI_CAL_DPD;
++ eeprom[offs] &= ~do_precal;
++ return 0;
++ default:
++ return -EINVAL;
++ }
++
++ if (!ret)
++ eeprom[offs] |= do_precal;
++
++ return ret;
++}
++
++static int
++mt7996_tm_dump_precal(struct mt76_phy *mphy, struct sk_buff *msg, int flag, int type)
++{
++#define DPD_PER_CHAN_SIZE_MASK GENMASK(31, 30)
++#define DPD_2G_RATIO_MASK GENMASK(29, 20)
++#define DPD_5G_RATIO_MASK GENMASK(19, 10)
++#define DPD_6G_RATIO_MASK GENMASK(9, 0)
++ struct mt7996_phy *phy = mphy->priv;
++ struct mt7996_dev *dev = phy->dev;
++ u32 i, group_size, dpd_size, total_size, size, dpd_info = 0;
++ u32 dpd_size_2g, dpd_size_5g, dpd_size_6g;
++ u32 base, offs, transmit_size = 1000;
++ u8 *pre_cal, *eeprom;
++ void *precal;
++ enum prek_ops {
++ PREK_GET_INFO,
++ PREK_SYNC_ALL,
++ PREK_SYNC_GROUP,
++ PREK_SYNC_DPD_2G,
++ PREK_SYNC_DPD_5G,
++ PREK_SYNC_DPD_6G,
++ PREK_CLEAN_GROUP,
++ PREK_CLEAN_DPD,
++ };
++
++ if (!dev->cal) {
++ dev_info(dev->mt76.dev, "Not pre-cal yet!\n");
++ return 0;
++ }
++
++ group_size = MT_EE_CAL_GROUP_SIZE;
++ dpd_size = MT_EE_CAL_DPD_SIZE;
++ total_size = group_size + dpd_size;
++ pre_cal = dev->cal;
++ eeprom = dev->mt76.eeprom.data;
++ offs = MT_EE_DO_PRE_CAL;
++
++ dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
++ dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
++ dpd_size_6g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_6GHZ);
++
++ switch (type) {
++ case PREK_SYNC_ALL:
++ base = 0;
++ size = total_size;
++ break;
++ case PREK_SYNC_GROUP:
++ base = 0;
++ size = group_size;
++ break;
++ case PREK_SYNC_DPD_2G:
++ base = group_size;
++ size = dpd_size_2g;
++ break;
++ case PREK_SYNC_DPD_5G:
++ base = group_size + dpd_size_2g;
++ size = dpd_size_5g;
++ break;
++ case PREK_SYNC_DPD_6G:
++ base = group_size + dpd_size_2g + dpd_size_5g;
++ size = dpd_size_6g;
++ break;
++ case PREK_GET_INFO:
++ break;
++ default:
++ return 0;
++ }
++
++ if (!flag) {
++ if (eeprom[offs] & MT_EE_WIFI_CAL_DPD) {
++ dpd_info |= u32_encode_bits(1, DPD_PER_CHAN_SIZE_MASK) |
++ u32_encode_bits(dpd_size_2g / MT_EE_CAL_UNIT,
++ DPD_2G_RATIO_MASK) |
++ u32_encode_bits(dpd_size_5g / MT_EE_CAL_UNIT,
++ DPD_5G_RATIO_MASK) |
++ u32_encode_bits(dpd_size_6g / MT_EE_CAL_UNIT,
++ DPD_6G_RATIO_MASK);
++ }
++ dev->cur_prek_offset = 0;
++ precal = nla_nest_start(msg, MT76_TM_ATTR_PRECAL_INFO);
++ if (!precal)
++ return -ENOMEM;
++ nla_put_u32(msg, 0, group_size);
++ nla_put_u32(msg, 1, dpd_size);
++ nla_put_u32(msg, 2, dpd_info);
++ nla_put_u32(msg, 3, transmit_size);
++ nla_put_u32(msg, 4, eeprom[offs]);
++ nla_nest_end(msg, precal);
++ } else {
++ precal = nla_nest_start(msg, MT76_TM_ATTR_PRECAL);
++ if (!precal)
++ return -ENOMEM;
++
++ transmit_size = (dev->cur_prek_offset + transmit_size < size) ?
++ transmit_size : (size - dev->cur_prek_offset);
++ for (i = 0; i < transmit_size; i++) {
++ if (nla_put_u8(msg, i, pre_cal[base + dev->cur_prek_offset + i]))
++ return -ENOMEM;
++ }
++ dev->cur_prek_offset += transmit_size;
++
++ nla_nest_end(msg, precal);
++ }
++
++ return 0;
++}
++
++static void
++mt7996_tm_re_cal_event(struct mt7996_dev *dev, struct mt7996_tm_rf_test_result *result,
++ struct mt7996_tm_rf_test_data *data)
++{
++ u32 base, dpd_size_2g, dpd_size_5g, dpd_size_6g, cal_idx, cal_type, len = 0;
++ u8 *pre_cal;
++
++ pre_cal = dev->cal;
++ dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
++ dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
++ dpd_size_6g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_6GHZ);
++
++ cal_idx = le32_to_cpu(data->cal_idx);
++ cal_type = le32_to_cpu(data->cal_type);
++ len = le32_to_cpu(result->payload_length);
++ len = len - sizeof(struct mt7996_tm_rf_test_data);
++
++ switch (cal_type) {
++ case RF_PRE_CAL:
++ base = 0;
++ break;
++ case RF_DPD_FLAT_CAL:
++ base = MT_EE_CAL_GROUP_SIZE;
++ break;
++ case RF_DPD_FLAT_5G_CAL:
++ case RF_DPD_FLAT_5G_MEM_CAL:
++ base = MT_EE_CAL_GROUP_SIZE + dpd_size_2g;
++ break;
++ case RF_DPD_FLAT_6G_CAL:
++ case RF_DPD_FLAT_6G_MEM_CAL:
++ base = MT_EE_CAL_GROUP_SIZE + dpd_size_2g + dpd_size_5g;
++ break;
++ default:
++ dev_info(dev->mt76.dev, "Unknown calibration type!\n");
++ return;
++ }
++ pre_cal += (base + dev->cur_prek_offset);
++
++ memcpy(pre_cal, data->cal_data, len);
++ dev->cur_prek_offset += len;
++}
++
++void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++ struct mt7996_tm_event *event;
++ struct mt7996_tm_rf_test_result *result;
++ struct mt7996_tm_rf_test_data *data;
++ static u32 event_type;
++
++ skb_pull(skb, sizeof(struct mt7996_mcu_rxd));
++ event = (struct mt7996_tm_event *)skb->data;
++ result = (struct mt7996_tm_rf_test_result *)&event->result;
++ data = (struct mt7996_tm_rf_test_data *)result->data;
++
++ event_type = le32_to_cpu(result->func_idx);
++
++ switch (event_type) {
++ case RF_TEST_RE_CAL:
++ mt7996_tm_re_cal_event(dev, result, data);
++ break;
++ default:
++ break;
++ }
++}
++
+ static void
+ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+ {
+@@ -447,6 +879,10 @@ mt7996_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+ else if (prev_state == MT76_TM_STATE_OFF ||
+ state == MT76_TM_STATE_OFF)
+ mt7996_tm_init(phy, !(state == MT76_TM_STATE_OFF));
++ else if (state >= MT76_TM_STATE_GROUP_PREK && state <= MT76_TM_STATE_GROUP_PREK_CLEAN)
++ return mt7996_tm_group_prek(phy, state);
++ else if (state >= MT76_TM_STATE_DPD_2G && state <= MT76_TM_STATE_DPD_CLEAN)
++ return mt7996_tm_dpd_prek(phy, state);
+
+ if ((state == MT76_TM_STATE_IDLE &&
+ prev_state == MT76_TM_STATE_OFF) ||
+@@ -655,4 +1091,5 @@ const struct mt76_testmode_ops mt7996_testmode_ops = {
+ .dump_stats = mt7996_tm_dump_stats,
+ .reset_rx_stats = mt7996_tm_reset_trx_stats,
+ .tx_stop = mt7996_tm_tx_stop,
++ .dump_precal = mt7996_tm_dump_precal,
+ };
+diff --git a/mt7996/testmode.h b/mt7996/testmode.h
+index f00e51f4..778c9bc6 100644
+--- a/mt7996/testmode.h
++++ b/mt7996/testmode.h
+@@ -34,6 +34,12 @@ enum bw_mapping_method {
+ NUM_BW_MAP,
+ };
+
++struct tm_cal_param {
++ __le32 func_data;
++ u8 band_idx;
++ u8 rsv[3];
++};
++
+ struct mt7996_tm_rf_test {
+ __le16 tag;
+ __le16 len;
+@@ -50,7 +56,7 @@ struct mt7996_tm_rf_test {
+ union {
+ __le32 func_data;
+ __le32 cal_dump;
+-
++ struct tm_cal_param cal_param;
+ u8 _pad[80];
+ } param;
+ } rf;
+@@ -63,10 +69,16 @@ struct mt7996_tm_req {
+ struct mt7996_tm_rf_test rf_test;
+ } __packed;
+
++struct mt7996_tm_rf_test_data {
++ __le32 cal_idx;
++ __le32 cal_type;
++ u8 cal_data[0];
++} __packed;
++
+ struct mt7996_tm_rf_test_result {
+ __le32 func_idx;
+ __le32 payload_length;
+- u8 event[0];
++ u8 data[0];
+ };
+
+ struct mt7996_tm_event {
+@@ -77,6 +89,8 @@ struct mt7996_tm_event {
+ struct mt7996_tm_rf_test_result result;
+ } __packed;
+
++#define RF_TEST_RE_CAL 0x01
++
+ enum {
+ RF_ACTION_SWITCH_TO_RF_TEST,
+ RF_ACTION_IN_RF_TEST,
+@@ -84,6 +98,8 @@ enum {
+ RF_ACTION_GET,
+ };
+
++#define RF_TEST_ICAP_LEN 120
++
+ enum {
+ RF_OPER_NORMAL,
+ RF_OPER_RF_TEST,
+diff --git a/testmode.c b/testmode.c
+index fc68c2af..74bb26fa 100644
+--- a/testmode.c
++++ b/testmode.c
+@@ -626,6 +626,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+
+ mutex_lock(&dev->mutex);
+
++ if (tb[MT76_TM_ATTR_PRECAL] || tb[MT76_TM_ATTR_PRECAL_INFO]) {
++ int flag, type;
++
++ err = -EINVAL;
++ flag = tb[MT76_TM_ATTR_PRECAL] ? 1 : 0;
++ type = flag ? nla_get_u8(tb[MT76_TM_ATTR_PRECAL_INFO]) : 0;
++ if (dev->test_ops->dump_precal)
++ err = dev->test_ops->dump_precal(phy, msg, flag, type);
++
++ goto out;
++ }
++
+ if (tb[MT76_TM_ATTR_STATS]) {
+ err = -EINVAL;
+
+diff --git a/testmode.h b/testmode.h
+index 8d0b9702..0c3b1393 100644
+--- a/testmode.h
++++ b/testmode.h
+@@ -215,6 +215,14 @@ enum mt76_testmode_state {
+ MT76_TM_STATE_TX_FRAMES,
+ MT76_TM_STATE_RX_FRAMES,
+ MT76_TM_STATE_TX_CONT,
++ MT76_TM_STATE_GROUP_PREK,
++ MT76_TM_STATE_GROUP_PREK_DUMP,
++ MT76_TM_STATE_GROUP_PREK_CLEAN,
++ MT76_TM_STATE_DPD_2G,
++ MT76_TM_STATE_DPD_5G,
++ MT76_TM_STATE_DPD_6G,
++ MT76_TM_STATE_DPD_DUMP,
++ MT76_TM_STATE_DPD_CLEAN,
+ MT76_TM_STATE_ON,
+
+ /* keep last */
+diff --git a/tools/fields.c b/tools/fields.c
+index e5cf7c53..b22b3fc8 100644
+--- a/tools/fields.c
++++ b/tools/fields.c
+@@ -11,6 +11,14 @@ static const char * const testmode_state[] = {
+ [MT76_TM_STATE_TX_FRAMES] = "tx_frames",
+ [MT76_TM_STATE_RX_FRAMES] = "rx_frames",
+ [MT76_TM_STATE_TX_CONT] = "tx_cont",
++ [MT76_TM_STATE_GROUP_PREK] = "group_prek",
++ [MT76_TM_STATE_GROUP_PREK_DUMP] = "group_prek_dump",
++ [MT76_TM_STATE_GROUP_PREK_CLEAN] = "group_prek_clean",
++ [MT76_TM_STATE_DPD_2G] = "dpd_2g",
++ [MT76_TM_STATE_DPD_5G] = "dpd_5g",
++ [MT76_TM_STATE_DPD_6G] = "dpd_6g",
++ [MT76_TM_STATE_DPD_DUMP] = "dpd_dump",
++ [MT76_TM_STATE_DPD_CLEAN] = "dpd_clean",
+ };
+
+ static const char * const testmode_tx_mode[] = {
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-binfile-mode-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-binfile-mode-support.patch
new file mode 100644
index 0000000..549344f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1007-wifi-mt76-mt7996-add-binfile-mode-support.patch
@@ -0,0 +1,260 @@
+From 2cf8a9517919b39318eb1e878ca69418a499126a Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Fri, 31 Mar 2023 11:36:34 +0800
+Subject: [PATCH 1007/1015] wifi: mt76: mt7996: add binfile mode support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ eeprom.c | 20 ++++++++++++++++++++
+ mt76.h | 3 +++
+ mt7996/eeprom.c | 42 +++++++++++++++++++++++++++++++++++++++---
+ mt7996/eeprom.h | 7 +++++++
+ mt7996/mt7996.h | 3 +++
+ mt7996/mtk_debugfs.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ 6 files changed, 112 insertions(+), 3 deletions(-)
+
+diff --git a/eeprom.c b/eeprom.c
+index aa889258..412740f0 100644
+--- a/eeprom.c
++++ b/eeprom.c
+@@ -104,6 +104,26 @@ out_put_node:
+ }
+ EXPORT_SYMBOL_GPL(mt76_get_of_eeprom);
+
++bool mt76_check_bin_file_mode(struct mt76_dev *dev)
++{
++ struct device_node *np = dev->dev->of_node;
++ const char *bin_file_name = NULL;
++
++ if (!np)
++ return false;
++
++ of_property_read_string(np, "bin_file_name", &bin_file_name);
++
++ dev->bin_file_name = bin_file_name;
++ if (dev->bin_file_name)
++ dev_info(dev->dev, "Using bin file %s\n", dev->bin_file_name);
++
++ of_node_put(np);
++
++ return dev->bin_file_name ? true : false;
++}
++EXPORT_SYMBOL_GPL(mt76_check_bin_file_mode);
++
+ void
+ mt76_eeprom_override(struct mt76_phy *phy)
+ {
+diff --git a/mt76.h b/mt76.h
+index 3341720c..7d6e3241 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -894,6 +894,8 @@ struct mt76_dev {
+ struct mt76_usb usb;
+ struct mt76_sdio sdio;
+ };
++
++ const char *bin_file_name;
+ };
+
+ struct mt76_power_limits {
+@@ -1030,6 +1032,7 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
+ int mt76_eeprom_init(struct mt76_dev *dev, int len);
+ void mt76_eeprom_override(struct mt76_phy *phy);
+ int mt76_get_of_eeprom(struct mt76_dev *dev, void *data, int offset, int len);
++bool mt76_check_bin_file_mode(struct mt76_dev *dev);
+
+ struct mt76_queue *
+ mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc,
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 60e98463..85d9e057 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -61,8 +61,11 @@ static int mt7996_check_eeprom(struct mt7996_dev *dev)
+ }
+ }
+
+-static char *mt7996_eeprom_name(struct mt7996_dev *dev)
++const char *mt7996_eeprom_name(struct mt7996_dev *dev)
+ {
++ if (dev->bin_file_mode)
++ return dev->mt76.bin_file_name;
++
+ /* reserve for future variants */
+ if (dev->testmode_enable)
+ return MT7996_EEPROM_DEFAULT_TM;
+@@ -112,7 +115,10 @@ mt7996_eeprom_load_default(struct mt7996_dev *dev)
+ return ret;
+
+ if (!fw || !fw->data) {
+- dev_err(dev->mt76.dev, "Invalid default bin\n");
++ if (dev->bin_file_mode)
++ dev_err(dev->mt76.dev, "Invalid bin (bin file mode)\n");
++ else
++ dev_err(dev->mt76.dev, "Invalid default bin\n");
+ ret = -EINVAL;
+ goto out;
+ }
+@@ -126,18 +132,45 @@ out:
+ return ret;
+ }
+
++static int mt7996_eeprom_load_flash(struct mt7996_dev *dev)
++{
++ int ret = 1;
++
++ /* return > 0 for load success, return 0 for load failed, return < 0 for non memory */
++ dev->bin_file_mode = mt76_check_bin_file_mode(&dev->mt76);
++ if (dev->bin_file_mode) {
++ dev->mt76.eeprom.size = MT7996_EEPROM_SIZE;
++ dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev, dev->mt76.eeprom.size,
++ GFP_KERNEL);
++ if (!dev->mt76.eeprom.data)
++ return -ENOMEM;
++
++ if (mt7996_eeprom_load_default(dev))
++ return 0;
++
++ if (mt7996_check_eeprom(dev))
++ return 0;
++ } else {
++ ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
++ }
++
++ return ret;
++}
++
+ int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev)
+ {
+ u8 *eeprom;
+ int ret;
+
+ /* load eeprom in flash or bin file mode to determine fw mode */
+- ret = mt76_eeprom_init(&dev->mt76, MT7996_EEPROM_SIZE);
++ ret = mt7996_eeprom_load_flash(dev);
++
+ if (ret < 0)
+ return ret;
+
+ if (ret) {
+ dev->flash_mode = true;
++ dev->eeprom_mode = dev->bin_file_mode ? BIN_FILE_MODE : FLASH_MODE;
+ eeprom = dev->mt76.eeprom.data;
+ /* testmode enable priority: eeprom field > module parameter */
+ dev->testmode_enable = !mt7996_check_eeprom(dev) ? eeprom[MT_EE_TESTMODE_EN] :
+@@ -171,6 +204,7 @@ static int mt7996_eeprom_load(struct mt7996_dev *dev)
+ if (ret < 0)
+ return ret;
+ }
++ dev->eeprom_mode = EFUSE_MODE;
+ }
+
+ return mt7996_check_eeprom(dev);
+@@ -306,6 +340,8 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ return ret;
+
+ dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
++ dev->bin_file_mode = false;
++ dev->eeprom_mode = DEFAULT_BIN_MODE;
+ ret = mt7996_eeprom_load_default(dev);
+ if (ret)
+ return ret;
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 7ff290f4..20dd8771 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -99,6 +99,13 @@ enum mt7996_eeprom_band {
+ MT_EE_BAND_SEL_6GHZ,
+ };
+
++enum mt7915_eeprom_mode {
++ DEFAULT_BIN_MODE,
++ EFUSE_MODE,
++ FLASH_MODE,
++ BIN_FILE_MODE,
++};
++
+ static inline int
+ mt7996_get_channel_group_5g(int channel)
+ {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 9ab86eaf..6ef6bad9 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -380,6 +380,8 @@ struct mt7996_dev {
+ bool has_eht:1;
+
+ bool testmode_enable;
++ bool bin_file_mode;
++ u8 eeprom_mode;
+
+ bool ibf;
+ u8 fw_debug_wm;
+@@ -519,6 +521,7 @@ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance);
+ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif);
+ int mt7996_register_device(struct mt7996_dev *dev);
+ void mt7996_unregister_device(struct mt7996_dev *dev);
++const char *mt7996_eeprom_name(struct mt7996_dev *dev);
+ int mt7996_eeprom_init(struct mt7996_dev *dev);
+ int mt7996_eeprom_check_fw_mode(struct mt7996_dev *dev);
+ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy);
+diff --git a/mt7996/mtk_debugfs.c b/mt7996/mtk_debugfs.c
+index 2aee3ab0..2ab2a8a8 100644
+--- a/mt7996/mtk_debugfs.c
++++ b/mt7996/mtk_debugfs.c
+@@ -2525,6 +2525,44 @@ static const struct file_operations mt7996_txpower_sku_fops = {
+ .llseek = default_llseek,
+ };
+
++static int mt7996_show_eeprom_mode(struct seq_file *s, void *data)
++{
++ struct mt7996_dev *dev = dev_get_drvdata(s->private);
++ struct mt76_dev *mdev = &dev->mt76;
++#ifdef CONFIG_NL80211_TESTMODE
++ const char *mtd_name = mdev->test_mtd.name;
++ u32 mtd_offset = mdev->test_mtd.offset;
++#else
++ const char *mtd_name = NULL;
++ u32 mtd_offset;
++#endif
++
++ seq_printf(s, "Current eeprom mode:\n");
++
++ switch (dev->eeprom_mode) {
++ case DEFAULT_BIN_MODE:
++ seq_printf(s, " default bin mode\n filename = %s\n", mt7996_eeprom_name(dev));
++ break;
++ case EFUSE_MODE:
++ seq_printf(s, " efuse mode\n");
++ break;
++ case FLASH_MODE:
++ if (mtd_name)
++ seq_printf(s, " flash mode\n mtd name = %s\n flash offset = 0x%x\n",
++ mtd_name, mtd_offset);
++ else
++ seq_printf(s, " flash mode\n");
++ break;
++ case BIN_FILE_MODE:
++ seq_printf(s, " bin file mode\n filename = %s\n", mt7996_eeprom_name(dev));
++ break;
++ default:
++ break;
++ }
++
++ return 0;
++}
++
+ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ {
+ struct mt7996_dev *dev = phy->dev;
+@@ -2570,6 +2608,8 @@ int mt7996_mtk_init_debugfs(struct mt7996_phy *phy, struct dentry *dir)
+ debugfs_create_file("txpower_level", 0600, dir, phy, &fops_txpower_level);
+ debugfs_create_file("txpower_info", 0600, dir, phy, &mt7996_txpower_info_fops);
+ debugfs_create_file("txpower_sku", 0600, dir, phy, &mt7996_txpower_sku_fops);
++ debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir,
++ mt7996_show_eeprom_mode);
+
+ debugfs_create_devm_seqfile(dev->mt76.dev, "wtbl_info", dir,
+ mt7996_wtbl_read);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
new file mode 100644
index 0000000..6b18fb0
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch
@@ -0,0 +1,310 @@
+From f3ff5d5029a0a589e797dd2536070d3a3e4e30a6 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 1 Mar 2023 12:12:51 +0800
+Subject: [PATCH 1008/1015] wifi: mt76: mt7996: add normal mode pre-calibration
+ support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76_connac_mcu.h | 1 +
+ mt7996/eeprom.c | 23 +++++++
+ mt7996/eeprom.h | 2 +
+ mt7996/init.c | 6 ++
+ mt7996/main.c | 6 ++
+ mt7996/mcu.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mt7996.h | 2 +
+ 7 files changed, 206 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 262abf88..42246fb9 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1229,6 +1229,7 @@ enum {
+ MCU_UNI_CMD_VOW = 0x37,
+ MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40,
+ MCU_UNI_CMD_TESTMODE_CTRL = 0x46,
++ MCU_UNI_CMD_PRECAL_RESULT = 0x47,
+ MCU_UNI_CMD_RRO = 0x57,
+ MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
+ MCU_UNI_CMD_ASSERT_DUMP = 0x6f,
+diff --git a/mt7996/eeprom.c b/mt7996/eeprom.c
+index 85d9e057..bee4a4b5 100644
+--- a/mt7996/eeprom.c
++++ b/mt7996/eeprom.c
+@@ -330,6 +330,25 @@ int mt7996_eeprom_parse_hw_cap(struct mt7996_dev *dev, struct mt7996_phy *phy)
+ return mt7996_eeprom_parse_band_config(phy);
+ }
+
++static int mt7996_eeprom_load_precal(struct mt7996_dev *dev)
++{
++ struct mt76_dev *mdev = &dev->mt76;
++ u8 *eeprom = mdev->eeprom.data;
++ u32 offs = MT_EE_DO_PRE_CAL;
++ u32 size, val = eeprom[offs];
++
++ if (!dev->flash_mode || !val)
++ return 0;
++
++ size = MT_EE_CAL_GROUP_SIZE + MT_EE_CAL_DPD_SIZE;
++
++ dev->cal = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
++ if (!dev->cal)
++ return -ENOMEM;
++
++ return mt76_get_of_eeprom(mdev, dev->cal, MT_EE_PRECAL, size);
++}
++
+ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ {
+ int ret;
+@@ -347,6 +366,10 @@ int mt7996_eeprom_init(struct mt7996_dev *dev)
+ return ret;
+ }
+
++ ret = mt7996_eeprom_load_precal(dev);
++ if (ret)
++ return ret;
++
+ ret = mt7996_eeprom_parse_hw_cap(dev, &dev->phy);
+ if (ret < 0)
+ return ret;
+diff --git a/mt7996/eeprom.h b/mt7996/eeprom.h
+index 20dd8771..0f3f31d8 100644
+--- a/mt7996/eeprom.h
++++ b/mt7996/eeprom.h
+@@ -25,6 +25,8 @@ enum mt7996_eeprom_field {
+ MT_EE_TX0_POWER_6G = 0x1310,
+
+ __MT_EE_MAX = 0x1dff,
++ /* 0x1e10 ~ 0x2d644 used to save group cal data */
++ MT_EE_PRECAL = 0x1e10,
+ };
+
+ #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0)
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 40d610ae..31695090 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -675,6 +675,12 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ if (ret < 0)
+ return ret;
+
++ if (dev->flash_mode) {
++ ret = mt7996_mcu_apply_group_cal(dev);
++ if (ret)
++ return ret;
++ }
++
+ /* Beacon and mgmt frames should occupy wcid 0 */
+ idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA);
+ if (idx)
+diff --git a/mt7996/main.c b/mt7996/main.c
+index e5627c96..d40d3047 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -312,6 +312,12 @@ int mt7996_set_channel(struct mt7996_phy *phy)
+
+ mt76_set_channel(phy->mt76);
+
++ if (dev->flash_mode) {
++ ret = mt7996_mcu_apply_tx_dpd(phy);
++ if (ret)
++ goto out;
++ }
++
+ ret = mt7996_mcu_set_chan_info(phy, UNI_CHANNEL_SWITCH);
+ if (ret)
+ goto out;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 1fb7bae1..6add77da 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3386,6 +3386,172 @@ int mt7996_mcu_get_eeprom_free_block(struct mt7996_dev *dev, u8 *block_num)
+ return 0;
+ }
+
++static int mt7996_mcu_set_pre_cal(struct mt7996_dev *dev, u32 idx,
++ u8 *cal, u32 len, u32 cal_id)
++{
++#define PRECAL_CMD_PRE_CAL_RESULT 0x0
++ struct {
++ /* fixed field */
++ u8 action;
++ u8 dest;
++ u8 attribute;
++ u8 tag_num;
++
++ __le16 tag;
++ __le16 len;
++
++ __le32 cal_id;
++ s8 precal;
++ u8 band;
++ u8 rsv[2];
++ __le32 idx;
++ __le32 cal_len;
++ } req = {
++ .tag = cpu_to_le16(PRECAL_CMD_PRE_CAL_RESULT),
++ .len = cpu_to_le16(sizeof(req) - 4 + len),
++ .cal_id = cpu_to_le32(cal_id),
++ .idx = cpu_to_le32(idx),
++ .cal_len = cpu_to_le32(len),
++ };
++ struct sk_buff *skb;
++
++ if (!len)
++ return 0;
++
++ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req) + len);
++ if (!skb)
++ return -ENOMEM;
++
++ skb_put_data(skb, &req, sizeof(req));
++ skb_put_data(skb, cal, len);
++
++ return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_WM_UNI_CMD(PRECAL_RESULT), false);
++}
++
++int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev)
++{
++ u8 *cal = dev->cal, *eeprom = dev->mt76.eeprom.data;
++ u32 idx = 0, total_idx = MT_EE_CAL_GROUP_SIZE / MT_EE_CAL_UNIT;
++ u32 offs = MT_EE_DO_PRE_CAL;
++ int ret = 0;
++
++ if (!(eeprom[offs] & MT_EE_WIFI_CAL_GROUP))
++ return 0;
++
++ for (idx = 0; idx < total_idx; idx++, cal += MT_EE_CAL_UNIT) {
++ ret = mt7996_mcu_set_pre_cal(dev, idx, cal, MT_EE_CAL_UNIT, RF_PRE_CAL);
++ if (ret)
++ goto out;
++ }
++
++ ret = mt7996_mcu_set_pre_cal(dev, total_idx, cal,
++ MT_EE_CAL_GROUP_SIZE % MT_EE_CAL_UNIT, RF_PRE_CAL);
++
++out:
++ return ret;
++}
++
++int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy)
++{
++ struct mt7996_dev *dev = phy->dev;
++ struct mt76_phy *mphy = phy->mt76;
++ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
++ enum nl80211_band band = chandef->chan->band;
++ enum nl80211_chan_width bw = chandef->width;
++ const struct ieee80211_channel *chan_list;
++ u32 cal_id, chan_list_size, base_offset = 0, offs = MT_EE_DO_PRE_CAL;
++ u32 dpd_size_2g, dpd_size_5g, per_chan_size = DPD_PER_CH_BW20_SIZE;
++ u16 channel = ieee80211_frequency_to_channel(chandef->center_freq1);
++ u8 dpd_mask, *cal = dev->cal, *eeprom = dev->mt76.eeprom.data;
++ int idx, i, ret;
++
++ dpd_size_2g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_2GHZ);
++ dpd_size_5g = mt7996_get_dpd_per_band_size(dev, NL80211_BAND_5GHZ);
++
++ switch (band) {
++ case NL80211_BAND_2GHZ:
++ dpd_mask = MT_EE_WIFI_CAL_DPD_2G;
++ /* channel 14 don't need DPD cal */
++ if (channel >= 1 && channel <= 4)
++ channel = 3;
++ else if (channel >= 5 && channel <= 9)
++ channel = 7;
++ else if (channel >= 10 && channel <= 13)
++ channel = 11;
++ else
++ return 0;
++ cal_id = RF_DPD_FLAT_CAL;
++ chan_list = dpd_2g_ch_list_bw20;
++ chan_list_size = dpd_2g_bw20_ch_num;
++ break;
++ case NL80211_BAND_5GHZ:
++ dpd_mask = MT_EE_WIFI_CAL_DPD_5G;
++ cal_id = RF_DPD_FLAT_5G_CAL;
++ chan_list = mphy->sband_5g.sband.channels;
++ chan_list_size = mphy->sband_5g.sband.n_channels;
++ base_offset += dpd_size_2g;
++ if (bw == NL80211_CHAN_WIDTH_160) {
++ base_offset += mphy->sband_5g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++ cal_id = RF_DPD_FLAT_5G_MEM_CAL;
++ chan_list = dpd_5g_ch_list_bw160;
++ chan_list_size = dpd_5g_bw160_ch_num;
++ } else if (bw > NL80211_CHAN_WIDTH_20) {
++ /* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
++ channel -= 2;
++ }
++ break;
++ case NL80211_BAND_6GHZ:
++ dpd_mask = MT_EE_WIFI_CAL_DPD_6G;
++ cal_id = RF_DPD_FLAT_6G_CAL;
++ chan_list = mphy->sband_6g.sband.channels;
++ chan_list_size = mphy->sband_6g.sband.n_channels;
++ base_offset += dpd_size_2g + dpd_size_5g;
++ if (bw == NL80211_CHAN_WIDTH_160) {
++ base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE;
++ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++ cal_id = RF_DPD_FLAT_6G_MEM_CAL;
++ chan_list = dpd_6g_ch_list_bw160;
++ chan_list_size = dpd_6g_bw160_ch_num;
++ } else if (bw == NL80211_CHAN_WIDTH_320) {
++ base_offset += mphy->sband_6g.sband.n_channels * DPD_PER_CH_BW20_SIZE +
++ dpd_6g_bw160_ch_num * DPD_PER_CH_GT_BW20_SIZE;
++ per_chan_size = DPD_PER_CH_GT_BW20_SIZE;
++ cal_id = RF_DPD_FLAT_6G_MEM_CAL;
++ chan_list = dpd_6g_ch_list_bw320;
++ chan_list_size = dpd_6g_bw320_ch_num;
++ } else if (bw > NL80211_CHAN_WIDTH_20) {
++ /* apply (center channel - 2)'s dpd cal data for bw 40/80 channels */
++ channel -= 2;
++ }
++ break;
++ default:
++ dpd_mask = 0;
++ break;
++ }
++
++ if (!(eeprom[offs] & dpd_mask))
++ return 0;
++
++ for (idx = 0; idx < chan_list_size; idx++)
++ if (channel == chan_list[idx].hw_value)
++ break;
++ if (idx == chan_list_size)
++ return -EINVAL;
++
++ cal += MT_EE_CAL_GROUP_SIZE + base_offset + idx * per_chan_size;
++
++ for (i = 0; i < per_chan_size / MT_EE_CAL_UNIT; i++) {
++ ret = mt7996_mcu_set_pre_cal(dev, i, cal, MT_EE_CAL_UNIT, cal_id);
++ if (ret)
++ return ret;
++
++ cal += MT_EE_CAL_UNIT;
++ }
++
++ return ret;
++}
++
+ int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap)
+ {
+ #define NIC_CAP 3
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 6ef6bad9..c16bc8b4 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -607,6 +607,8 @@ void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
+ void mt7996_mcu_exit(struct mt7996_dev *dev);
+ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data);
+ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
++int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
++int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+ #ifdef CONFIG_NL80211_TESTMODE
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
new file mode 100644
index 0000000..7ddc56f
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch
@@ -0,0 +1,220 @@
+From b99c942620576c63baffd687090febea5ab2973d Mon Sep 17 00:00:00 2001
+From: mtk23510 <rudra.shahi@mediatek.com>
+Date: Wed, 26 Apr 2023 20:08:10 +0800
+Subject: [PATCH 1009/1015] wifi: mt76: mt7996: Beacon protection feature added
+
+Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
+Change-Id: I0149a65f71d844fc395c2827a54f9360492d181e
+---
+ mt76_connac_mcu.h | 16 +++++++++
+ mt7996/main.c | 4 +++
+ mt7996/mcu.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.h | 11 ++++++
+ mt7996/mt7996.h | 2 ++
+ 5 files changed, 119 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index 42246fb9..a53fa138 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -415,6 +415,14 @@ struct sta_rec_he_6g_capa {
+ u8 rsv[2];
+ } __packed;
+
++struct sta_rec_pn_info {
++ __le16 tag;
++ __le16 len;
++ u8 pn[6];
++ u8 tsc_type;
++ u8 rsv;
++} __packed;
++
+ struct sec_key {
+ u8 cipher_id;
+ u8 cipher_len;
+@@ -767,6 +775,7 @@ struct wtbl_raw {
+ sizeof(struct sta_rec_sec) + \
+ sizeof(struct sta_rec_ra_fixed) + \
+ sizeof(struct sta_rec_he_6g_capa) + \
++ sizeof(struct sta_rec_pn_info) + \
+ sizeof(struct tlv) + \
+ MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
+
+@@ -796,6 +805,7 @@ enum {
+ STA_REC_HE_6G = 0x17,
+ STA_REC_HE_V2 = 0x19,
+ STA_REC_EHT = 0x22,
++ STA_REC_PN_INFO = 0x26,
+ STA_REC_HDRT = 0x28,
+ STA_REC_HDR_TRANS = 0x2B,
+ STA_REC_MAX_NUM
+@@ -1077,6 +1087,11 @@ enum mcu_cipher_type {
+ MCU_CIPHER_GCMP_256,
+ MCU_CIPHER_WAPI,
+ MCU_CIPHER_BIP_CMAC_128,
++ MCU_CIPHER_BIP_CMAC_256,
++ MCU_CIPHER_BCN_PROT_CMAC_128,
++ MCU_CIPHER_BCN_PROT_CMAC_256,
++ MCU_CIPHER_BCN_PROT_GMAC_128,
++ MCU_CIPHER_BCN_PROT_GMAC_256,
+ };
+
+ enum {
+@@ -1295,6 +1310,7 @@ enum {
+ UNI_BSS_INFO_RATE = 11,
+ UNI_BSS_INFO_QBSS = 15,
+ UNI_BSS_INFO_SEC = 16,
++ UNI_BSS_INFO_BCN_PROT = 17,
+ UNI_BSS_INFO_TXCMD = 18,
+ UNI_BSS_INFO_UAPSD = 19,
+ UNI_BSS_INFO_PS = 21,
+diff --git a/mt7996/main.c b/mt7996/main.c
+index d40d3047..d3d10fab 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -400,6 +400,10 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+ }
+
+ mt76_wcid_key_setup(&dev->mt76, wcid, key);
++
++ if (key->keyidx == 6 || key->keyidx == 7)
++ mt7996_mcu_bcn_prot_enable(dev, vif, key);
++
+ err = mt7996_mcu_add_key(&dev->mt76, vif, &msta->bip,
+ key, MCU_WMWA_UNI_CMD(STA_REC_UPDATE),
+ &msta->wcid, cmd);
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 6add77da..53d2fc73 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2133,6 +2133,92 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
+ return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
+ }
+
++static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif,
++ u8 *pn)
++{
++#define TSC_TYPE_BIGTK_PN 2
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ struct sta_rec_pn_info *pn_info;
++ struct sk_buff *skb, *rskb;
++ struct tlv *tlv;
++ int ret;
++
++ skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid);
++ if (IS_ERR(skb))
++ return PTR_ERR(skb);
++
++ tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PN_INFO, sizeof(*pn_info));
++ pn_info = (struct sta_rec_pn_info *)tlv;
++
++ pn_info->tsc_type = TSC_TYPE_BIGTK_PN;
++ ret = mt76_mcu_skb_send_and_get_msg(&dev->mt76, skb,
++ MCU_WM_UNI_CMD_QUERY(STA_REC_UPDATE), true, &rskb);
++ if (ret)
++ return ret;
++
++ skb_pull(rskb, 4);
++
++ pn_info = (struct sta_rec_pn_info *)rskb->data;
++ if (le16_to_cpu(pn_info->tag) == STA_REC_PN_INFO)
++ memcpy(pn, pn_info->pn, 6);
++
++ dev_kfree_skb(rskb);
++ return 0;
++}
++
++int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
++ struct ieee80211_key_conf *key)
++{
++#define WPA_BIGTK_MAX_LEN 32
++ int len = sizeof(struct bss_req_hdr) + sizeof(struct mt7996_mcu_bcn_prot_tlv);
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ int ret;
++ struct mt7996_mcu_bcn_prot_tlv *bcn_prot;
++ struct sk_buff *skb;
++ struct tlv *tlv;
++ u8 pn[6] = {0};
++
++ skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len);
++ if (IS_ERR(skb))
++ return PTR_ERR(skb);
++
++ tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_BCN_PROT,
++ sizeof(*bcn_prot));
++
++ bcn_prot = (struct mt7996_mcu_bcn_prot_tlv *)tlv;
++
++ ret = mt7996_mcu_get_pn(dev, vif, pn);
++ if (ret) {
++ dev_kfree_skb(skb);
++ return ret;
++ }
++
++ switch(key->cipher){
++ case WLAN_CIPHER_SUITE_AES_CMAC:
++ bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_128;
++ break;
++ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
++ bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_128;
++ break;
++ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
++ bcn_prot->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256;
++ break;
++ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
++ default:
++ dev_err(dev->mt76.dev, "Not supported Bigtk Cipher\n");
++ dev_kfree_skb(skb);
++ return -EOPNOTSUPP;
++ }
++
++ pn[0]++;
++ memcpy(bcn_prot->pn, pn, 6);
++ bcn_prot->enable = 1;
++ memcpy(bcn_prot->key, key->key, WPA_BIGTK_MAX_LEN);
++ bcn_prot->key_id = key->keyidx;
++
++ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
++ MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
++}
+ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy,
+ struct ieee80211_vif *vif, bool enable)
+ {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index baffbcd7..f32ac153 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -262,6 +262,17 @@ struct bss_rate_tlv {
+ u8 __rsv2[9];
+ } __packed;
+
++struct mt7996_mcu_bcn_prot_tlv {
++ __le16 tag;
++ __le16 len;
++ u8 pn[6];
++ u8 enable;
++ u8 cipher_id;
++ u8 key[32];
++ u8 key_id;
++ u8 __rsv[3];
++} __packed;
++
+ struct bss_ra_tlv {
+ __le16 tag;
+ __le16 len;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index c16bc8b4..94b62211 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -710,6 +710,8 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
+ struct mt76_connac_sta_key_conf *sta_key_conf,
+ struct ieee80211_key_conf *key, int mcu_cmd,
+ struct mt76_wcid *wcid, enum set_key_cmd cmd);
++int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif,
++ struct ieee80211_key_conf *key);
+ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
new file mode 100644
index 0000000..999d9ba
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch
@@ -0,0 +1,490 @@
+From 639385416a573ae5ce631a0323c5541dea3e406c Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Wed, 22 Mar 2023 11:19:52 +0800
+Subject: [PATCH 1010/1015] wifi: mt76: testmode: add testmode ZWDFS
+ verification support
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+---
+ mt76.h | 8 ++
+ mt7996/mt7996.h | 1 +
+ mt7996/testmode.c | 248 ++++++++++++++++++++++++++++++++++++++++++++--
+ mt7996/testmode.h | 44 ++++++++
+ testmode.c | 22 +++-
+ tools/fields.c | 15 +++
+ 6 files changed, 326 insertions(+), 12 deletions(-)
+
+diff --git a/mt76.h b/mt76.h
+index 7d6e3241..5b442691 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -732,6 +732,14 @@ struct mt76_testmode_data {
+ } cfg;
+
+ u8 aid;
++
++ u8 offchan_ch;
++ u8 offchan_center_ch;
++ u8 offchan_bw;
++
++ u8 ipi_threshold;
++ u32 ipi_period;
++ u8 ipi_reset;
+ };
+
+ struct mt76_vif {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 94b62211..abdbb1ef 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -295,6 +295,7 @@ struct mt7996_phy {
+
+ struct mib_stats mib;
+ struct mt76_channel_state state_ts;
++ struct delayed_work ipi_work;
+
+ bool has_aux_rx;
+
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index 7d36902e..ba3cd802 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -16,6 +16,12 @@ enum {
+ TM_CHANGED_TX_LENGTH,
+ TM_CHANGED_TX_TIME,
+ TM_CHANGED_CFG,
++ TM_CHANGED_OFF_CHAN_CH,
++ TM_CHANGED_OFF_CHAN_CENTER_CH,
++ TM_CHANGED_OFF_CHAN_BW,
++ TM_CHANGED_IPI_THRESHOLD,
++ TM_CHANGED_IPI_PERIOD,
++ TM_CHANGED_IPI_RESET,
+
+ /* must be last */
+ NUM_TM_CHANGED
+@@ -27,20 +33,31 @@ static const u8 tm_change_map[] = {
+ [TM_CHANGED_TX_LENGTH] = MT76_TM_ATTR_TX_LENGTH,
+ [TM_CHANGED_TX_TIME] = MT76_TM_ATTR_TX_TIME,
+ [TM_CHANGED_CFG] = MT76_TM_ATTR_CFG,
++ [TM_CHANGED_OFF_CHAN_CH] = MT76_TM_ATTR_OFF_CH_SCAN_CH,
++ [TM_CHANGED_OFF_CHAN_CENTER_CH] = MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH,
++ [TM_CHANGED_OFF_CHAN_BW] = MT76_TM_ATTR_OFF_CH_SCAN_BW,
++ [TM_CHANGED_IPI_THRESHOLD] = MT76_TM_ATTR_IPI_THRESHOLD,
++ [TM_CHANGED_IPI_PERIOD] = MT76_TM_ATTR_IPI_PERIOD,
++ [TM_CHANGED_IPI_RESET] = MT76_TM_ATTR_IPI_RESET,
+ };
+
+-static u8 mt7996_tm_bw_mapping(enum nl80211_chan_width width, enum bw_mapping_method method)
++static void mt7996_tm_ipi_work(struct work_struct *work);
++
++static u32 mt7996_tm_bw_mapping(enum nl80211_chan_width width, enum bw_mapping_method method)
+ {
+- static const u8 width_to_bw[][NUM_BW_MAP] = {
+- [NL80211_CHAN_WIDTH_40] = {FW_CDBW_40MHZ, TM_CBW_40MHZ},
+- [NL80211_CHAN_WIDTH_80] = {FW_CDBW_80MHZ, TM_CBW_80MHZ},
+- [NL80211_CHAN_WIDTH_80P80] = {FW_CDBW_8080MHZ, TM_CBW_8080MHZ},
+- [NL80211_CHAN_WIDTH_160] = {FW_CDBW_160MHZ, TM_CBW_160MHZ},
+- [NL80211_CHAN_WIDTH_5] = {FW_CDBW_5MHZ, TM_CBW_5MHZ},
+- [NL80211_CHAN_WIDTH_10] = {FW_CDBW_10MHZ, TM_CBW_10MHZ},
+- [NL80211_CHAN_WIDTH_20] = {FW_CDBW_20MHZ, TM_CBW_20MHZ},
+- [NL80211_CHAN_WIDTH_20_NOHT] = {FW_CDBW_20MHZ, TM_CBW_20MHZ},
+- [NL80211_CHAN_WIDTH_320] = {FW_CDBW_320MHZ, TM_CBW_320MHZ},
++ static const u32 width_to_bw[][NUM_BW_MAP] = {
++ [NL80211_CHAN_WIDTH_40] = {FW_CDBW_40MHZ, TM_CBW_40MHZ, 40,
++ FIRST_CONTROL_CHAN_BITMAP_BW40},
++ [NL80211_CHAN_WIDTH_80] = {FW_CDBW_80MHZ, TM_CBW_80MHZ, 80,
++ FIRST_CONTROL_CHAN_BITMAP_BW80},
++ [NL80211_CHAN_WIDTH_80P80] = {FW_CDBW_8080MHZ, TM_CBW_8080MHZ, 80, 0x0},
++ [NL80211_CHAN_WIDTH_160] = {FW_CDBW_160MHZ, TM_CBW_160MHZ, 160,
++ FIRST_CONTROL_CHAN_BITMAP_BW160},
++ [NL80211_CHAN_WIDTH_5] = {FW_CDBW_5MHZ, TM_CBW_5MHZ, 5, 0x0},
++ [NL80211_CHAN_WIDTH_10] = {FW_CDBW_10MHZ, TM_CBW_10MHZ, 10, 0x0},
++ [NL80211_CHAN_WIDTH_20] = {FW_CDBW_20MHZ, TM_CBW_20MHZ, 20, 0x0},
++ [NL80211_CHAN_WIDTH_20_NOHT] = {FW_CDBW_20MHZ, TM_CBW_20MHZ, 20, 0x0},
++ [NL80211_CHAN_WIDTH_320] = {FW_CDBW_320MHZ, TM_CBW_320MHZ, 320, 0x0},
+ };
+
+ if (width >= ARRAY_SIZE(width_to_bw))
+@@ -217,6 +234,9 @@ mt7996_tm_init(struct mt7996_phy *phy, bool en)
+
+ /* use firmware counter for RX stats */
+ phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
++
++ if (en)
++ INIT_DELAYED_WORK(&phy->ipi_work, mt7996_tm_ipi_work);
+ }
+
+ static void
+@@ -829,6 +849,204 @@ void mt7996_tm_rf_test_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ }
+ }
+
++static u8
++mt7996_tm_get_center_chan(struct mt7996_phy *phy, struct cfg80211_chan_def *chandef)
++{
++ struct mt76_phy *mphy = phy->mt76;
++ const struct ieee80211_channel *chan = mphy->sband_5g.sband.channels;
++ u32 bitmap, i, offset, width_mhz, size = mphy->sband_5g.sband.n_channels;
++ u16 first_control = 0, control_chan = chandef->chan->hw_value;
++
++ bitmap = mt7996_tm_bw_mapping(chandef->width, BW_MAP_NL_TO_CONTROL_BITMAP_5G);
++ if (!bitmap)
++ return control_chan;
++
++ width_mhz = mt7996_tm_bw_mapping(chandef->width, BW_MAP_NL_TO_MHZ);
++ offset = width_mhz / 10 - 2;
++
++ for (i = 0; i < size; i++) {
++ if (!((1 << i) & bitmap))
++ continue;
++
++ if (control_chan >= chan[i].hw_value)
++ first_control = chan[i].hw_value;
++ else
++ break;
++ }
++
++ if (i == size || first_control == 0)
++ return control_chan;
++
++ return first_control + offset;
++}
++
++static int
++mt7996_tm_set_offchan(struct mt7996_phy *phy, bool no_center)
++{
++ struct mt76_phy *mphy = phy->mt76;
++ struct mt7996_dev *dev = phy->dev;
++ struct ieee80211_hw *hw = mphy->hw;
++ struct mt76_testmode_data *td = &phy->mt76->test;
++ struct cfg80211_chan_def chandef = {};
++ struct ieee80211_channel *chan;
++ int ret, freq = ieee80211_channel_to_frequency(td->offchan_ch, NL80211_BAND_5GHZ);
++
++ if (!mphy->cap.has_5ghz || !freq) {
++ ret = -EINVAL;
++ dev_info(dev->mt76.dev, "Failed to set offchan (invalid band or channel)!\n");
++ goto out;
++ }
++
++ chandef.width = td->offchan_bw;
++ chan = ieee80211_get_channel(hw->wiphy, freq);
++ chandef.chan = chan;
++ if (no_center)
++ td->offchan_center_ch = mt7996_tm_get_center_chan(phy, &chandef);
++ chandef.center_freq1 = ieee80211_channel_to_frequency(td->offchan_center_ch,
++ NL80211_BAND_5GHZ);
++ if (!cfg80211_chandef_valid(&chandef)) {
++ ret = -EINVAL;
++ dev_info(dev->mt76.dev, "Failed to set offchan, chandef is invalid!\n");
++ goto out;
++ }
++
++ memset(&dev->rdd2_chandef, 0, sizeof(struct cfg80211_chan_def));
++
++ ret = mt7996_mcu_rdd_background_enable(phy, &chandef);
++
++ if (ret)
++ goto out;
++
++ dev->rdd2_phy = phy;
++ dev->rdd2_chandef = chandef;
++
++ return 0;
++
++out:
++ td->offchan_ch = 0;
++ td->offchan_center_ch = 0;
++ td->offchan_bw = 0;
++
++ return ret;
++}
++
++static void
++mt7996_tm_ipi_hist_ctrl(struct mt7996_phy *phy, struct mt7996_tm_rdd_ipi_ctrl *data, u8 cmd)
++{
++#define MT_IPI_RESET 0x830a5dfc
++#define MT_IPI_RESET_MASK BIT(28)
++#define MT_IPI_COUNTER_BASE 0x83041000
++#define MT_IPI_COUNTER(idx) (MT_IPI_COUNTER_BASE + ((idx) * 4))
++ struct mt7996_dev *dev = phy->dev;
++ bool val;
++ int i;
++
++ if (cmd == RDD_SET_IPI_HIST_RESET) {
++ val = mt76_rr(dev, MT_IPI_RESET) & MT_IPI_RESET_MASK;
++ mt76_rmw_field(dev, MT_IPI_RESET, MT_IPI_RESET_MASK, !val);
++ return;
++ }
++
++ for (i = 0; i < POWER_INDICATE_HIST_MAX; i++)
++ data->ipi_hist_val[i] = mt76_rr(dev, MT_IPI_COUNTER(i));
++}
++
++static void
++mt7996_tm_ipi_work(struct work_struct *work)
++{
++#define PRECISION 100
++ struct mt7996_phy *phy = container_of(work, struct mt7996_phy, ipi_work.work);
++ struct mt7996_dev *dev = phy->dev;
++ struct mt76_testmode_data *td = &phy->mt76->test;
++ struct mt7996_tm_rdd_ipi_ctrl data;
++ u32 ipi_idx, ipi_free_count, ipi_percentage;
++ u32 ipi_hist_count_th = 0, ipi_hist_total_count = 0;
++ u32 self_idle_ratio, ipi_idle_ratio, channel_load;
++ u32 *ipi_hist_data;
++ const char *power_lower_bound, *power_upper_bound;
++ static const char * const ipi_idx_to_power_bound[] = {
++ [RDD_IPI_HIST_0] = "-92",
++ [RDD_IPI_HIST_1] = "-89",
++ [RDD_IPI_HIST_2] = "-86",
++ [RDD_IPI_HIST_3] = "-83",
++ [RDD_IPI_HIST_4] = "-80",
++ [RDD_IPI_HIST_5] = "-75",
++ [RDD_IPI_HIST_6] = "-70",
++ [RDD_IPI_HIST_7] = "-65",
++ [RDD_IPI_HIST_8] = "-60",
++ [RDD_IPI_HIST_9] = "-55",
++ [RDD_IPI_HIST_10] = "inf",
++ };
++
++ memset(&data, 0, sizeof(data));
++ mt7996_tm_ipi_hist_ctrl(phy, &data, RDD_IPI_HIST_ALL_CNT);
++
++ ipi_hist_data = data.ipi_hist_val;
++ for (ipi_idx = 0; ipi_idx < POWER_INDICATE_HIST_MAX; ipi_idx++) {
++ power_lower_bound = ipi_idx ? ipi_idx_to_power_bound[ipi_idx - 1] : "-inf";
++ power_upper_bound = ipi_idx_to_power_bound[ipi_idx];
++
++ dev_info(dev->mt76.dev, "IPI %d (power range: (%s, %s] dBm): ipi count = %d\n",
++ ipi_idx, power_lower_bound, power_upper_bound, ipi_hist_data[ipi_idx]);
++
++ if (td->ipi_threshold <= ipi_idx && ipi_idx <= RDD_IPI_HIST_10)
++ ipi_hist_count_th += ipi_hist_data[ipi_idx];
++
++ ipi_hist_total_count += ipi_hist_data[ipi_idx];
++ }
++
++ ipi_free_count = ipi_hist_data[RDD_IPI_FREE_RUN_CNT];
++
++ dev_info(dev->mt76.dev, "IPI threshold %d: ipi_hist_count_th = %d, ipi_free_count = %d\n",
++ td->ipi_threshold, ipi_hist_count_th, ipi_free_count);
++ dev_info(dev->mt76.dev, "TX assert time = %d [ms]\n", data.tx_assert_time / 1000);
++
++ /* calculate channel load = (self idle ratio - idle ratio) / self idle ratio */
++ if (ipi_hist_count_th >= UINT_MAX / (100 * PRECISION))
++ ipi_percentage = 100 * PRECISION *
++ (ipi_hist_count_th / (100 * PRECISION)) /
++ (ipi_free_count / (100 * PRECISION));
++ else
++ ipi_percentage = PRECISION * 100 * ipi_hist_count_th / ipi_free_count;
++
++ ipi_idle_ratio = ((100 * PRECISION) - ipi_percentage) / PRECISION;
++
++ self_idle_ratio = PRECISION * 100 *
++ (td->ipi_period - (data.tx_assert_time / 1000)) /
++ td->ipi_period / PRECISION;
++
++ if (self_idle_ratio < ipi_idle_ratio)
++ channel_load = 0;
++ else
++ channel_load = self_idle_ratio - ipi_idle_ratio;
++
++ if (self_idle_ratio <= td->ipi_threshold) {
++ dev_info(dev->mt76.dev, "band[%d]: self idle ratio = %d%%, idle ratio = %d%%\n",
++ phy->mt76->band_idx, self_idle_ratio, ipi_idle_ratio);
++ return;
++ }
++
++ channel_load = (100 * channel_load) / self_idle_ratio;
++ dev_info(dev->mt76.dev,
++ "band[%d]: chan load = %d%%, self idle ratio = %d%%, idle ratio = %d%%\n",
++ phy->mt76->band_idx, channel_load, self_idle_ratio, ipi_idle_ratio);
++}
++
++static int
++mt7996_tm_set_ipi(struct mt7996_phy *phy)
++{
++ struct mt76_testmode_data *td = &phy->mt76->test;
++
++ /* reset IPI CR */
++ mt7996_tm_ipi_hist_ctrl(phy, NULL, RDD_SET_IPI_HIST_RESET);
++
++ cancel_delayed_work(&phy->ipi_work);
++ ieee80211_queue_delayed_work(phy->mt76->hw, &phy->ipi_work,
++ msecs_to_jiffies(td->ipi_period));
++
++ return 0;
++}
++
+ static void
+ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+ {
+@@ -853,6 +1071,14 @@ mt7996_tm_update_params(struct mt7996_phy *phy, u32 changed)
+
+ mt7996_tm_set(dev, func_idx, td->cfg.type);
+ }
++ if ((changed & BIT(TM_CHANGED_OFF_CHAN_CH)) &&
++ (changed & BIT(TM_CHANGED_OFF_CHAN_BW)))
++ mt7996_tm_set_offchan(phy, !(changed & BIT(TM_CHANGED_OFF_CHAN_CENTER_CH)));
++ if ((changed & BIT(TM_CHANGED_IPI_THRESHOLD)) &&
++ (changed & BIT(TM_CHANGED_IPI_PERIOD)))
++ mt7996_tm_set_ipi(phy);
++ if (changed & BIT(TM_CHANGED_IPI_RESET))
++ mt7996_tm_ipi_hist_ctrl(phy, NULL, RDD_SET_IPI_HIST_RESET);
+ }
+
+ static int
+diff --git a/mt7996/testmode.h b/mt7996/testmode.h
+index 778c9bc6..09f81d39 100644
+--- a/mt7996/testmode.h
++++ b/mt7996/testmode.h
+@@ -27,9 +27,15 @@ enum {
+ FW_CDBW_8080MHZ,
+ };
+
++#define FIRST_CONTROL_CHAN_BITMAP_BW40 0x5555555
++#define FIRST_CONTROL_CHAN_BITMAP_BW80 0x111111
++#define FIRST_CONTROL_CHAN_BITMAP_BW160 0x100101
++
+ enum bw_mapping_method {
+ BW_MAP_NL_TO_FW,
+ BW_MAP_NL_TO_TM,
++ BW_MAP_NL_TO_MHZ,
++ BW_MAP_NL_TO_CONTROL_BITMAP_5G,
+
+ NUM_BW_MAP,
+ };
+@@ -308,4 +314,42 @@ struct mt7996_tm_rx_event {
+ };
+ } __packed;
+
++enum {
++ RDD_SET_IPI_CR_INIT, /* CR initialization */
++ RDD_SET_IPI_HIST_RESET, /* Reset IPI histogram counter */
++ RDD_SET_IDLE_POWER, /* Idle power info */
++ RDD_SET_IPI_HIST_NUM
++};
++
++enum {
++ RDD_IPI_HIST_0, /* IPI count for power <= -92 (dBm) */
++ RDD_IPI_HIST_1, /* IPI count for -92 < power <= -89 (dBm) */
++ RDD_IPI_HIST_2, /* IPI count for -89 < power <= -86 (dBm) */
++ RDD_IPI_HIST_3, /* IPI count for -86 < power <= -83 (dBm) */
++ RDD_IPI_HIST_4, /* IPI count for -83 < power <= -80 (dBm) */
++ RDD_IPI_HIST_5, /* IPI count for -80 < power <= -75 (dBm) */
++ RDD_IPI_HIST_6, /* IPI count for -75 < power <= -70 (dBm) */
++ RDD_IPI_HIST_7, /* IPI count for -70 < power <= -65 (dBm) */
++ RDD_IPI_HIST_8, /* IPI count for -65 < power <= -60 (dBm) */
++ RDD_IPI_HIST_9, /* IPI count for -60 < power <= -55 (dBm) */
++ RDD_IPI_HIST_10, /* IPI count for -55 < power (dBm) */
++ RDD_IPI_FREE_RUN_CNT, /* IPI count for counter++ per 8 us */
++ RDD_IPI_HIST_ALL_CNT, /* Get all IPI */
++ RDD_IPI_HIST_0_TO_10_CNT, /* Get IPI histogram 0 to 10 */
++ RDD_IPI_HIST_2_TO_10_CNT, /* Get IPI histogram 2 to 10 */
++ RDD_TX_ASSERT_TIME, /* Get band 1 TX assert time */
++ RDD_IPI_HIST_NUM
++};
++
++#define POWER_INDICATE_HIST_MAX RDD_IPI_FREE_RUN_CNT
++#define IPI_HIST_TYPE_NUM (POWER_INDICATE_HIST_MAX + 1)
++
++struct mt7996_tm_rdd_ipi_ctrl {
++ u8 ipi_hist_idx;
++ u8 band_idx;
++ u8 rsv[2];
++ __le32 ipi_hist_val[IPI_HIST_TYPE_NUM];
++ __le32 tx_assert_time; /* unit: us */
++} __packed;
++
+ #endif
+diff --git a/testmode.c b/testmode.c
+index 74bb26fa..22d6afd4 100644
+--- a/testmode.c
++++ b/testmode.c
+@@ -25,6 +25,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+ [MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 },
+ [MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
+ [MT76_TM_ATTR_DRV_DATA] = { .type = NLA_NESTED },
++ [MT76_TM_ATTR_OFF_CH_SCAN_CH] = { .type = NLA_U8 },
++ [MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH] = { .type = NLA_U8 },
++ [MT76_TM_ATTR_OFF_CH_SCAN_BW] = { .type = NLA_U8 },
++ [MT76_TM_ATTR_OFF_CH_SCAN_PATH] = { .type = NLA_U8 },
++ [MT76_TM_ATTR_IPI_THRESHOLD] = { .type = NLA_U8 },
++ [MT76_TM_ATTR_IPI_PERIOD] = { .type = NLA_U32 },
++ [MT76_TM_ATTR_IPI_RESET] = { .type = NLA_U8 },
+ };
+ EXPORT_SYMBOL_GPL(mt76_tm_policy);
+
+@@ -451,6 +458,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ if (tb[MT76_TM_ATTR_TX_RATE_IDX])
+ td->tx_rate_idx = nla_get_u8(tb[MT76_TM_ATTR_TX_RATE_IDX]);
+
++ if (tb[MT76_TM_ATTR_IPI_PERIOD])
++ td->ipi_period = nla_get_u32(tb[MT76_TM_ATTR_IPI_PERIOD]);
++
+ if (mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_MODE], &td->tx_rate_mode,
+ 0, MT76_TM_TX_MODE_MAX) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_NSS], &td->tx_rate_nss,
+@@ -466,7 +476,14 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ &td->tx_duty_cycle, 0, 99) ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
+ &td->tx_power_control, 0, 1) ||
+- mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16))
++ mt76_tm_get_u8(tb[MT76_TM_ATTR_AID], &td->aid, 0, 16) ||
++ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CH], &td->offchan_ch, 36, 196) ||
++ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH], &td->offchan_center_ch,
++ 36, 196) ||
++ mt76_tm_get_u8(tb[MT76_TM_ATTR_OFF_CH_SCAN_BW],
++ &td->offchan_bw, NL80211_CHAN_WIDTH_20_NOHT, NL80211_CHAN_WIDTH_160) ||
++ mt76_tm_get_u8(tb[MT76_TM_ATTR_IPI_THRESHOLD], &td->ipi_threshold, 0, 10) ||
++ mt76_tm_get_u8(tb[MT76_TM_ATTR_IPI_RESET], &td->ipi_reset, 0, 1))
+ goto out;
+
+ if (tb[MT76_TM_ATTR_TX_LENGTH]) {
+@@ -671,6 +688,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_LDPC, td->tx_rate_ldpc) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
+ nla_put_u8(msg, MT76_TM_ATTR_AID, td->aid) ||
++ nla_put_u8(msg, MT76_TM_ATTR_OFF_CH_SCAN_CH, td->offchan_ch) ||
++ nla_put_u8(msg, MT76_TM_ATTR_OFF_CH_SCAN_CENTER_CH, td->offchan_center_ch) ||
++ nla_put_u8(msg, MT76_TM_ATTR_OFF_CH_SCAN_BW, td->offchan_bw) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_LTF) &&
+ nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
+diff --git a/tools/fields.c b/tools/fields.c
+index b22b3fc8..55854a6f 100644
+--- a/tools/fields.c
++++ b/tools/fields.c
+@@ -35,6 +35,15 @@ static const char * const testmode_tx_mode[] = {
+ [MT76_TM_TX_MODE_EHT_MU] = "eht_mu",
+ };
+
++static const char * const testmode_offchan_bw[] = {
++ [NL80211_CHAN_WIDTH_20_NOHT] = "NOHT",
++ [NL80211_CHAN_WIDTH_20] = "20",
++ [NL80211_CHAN_WIDTH_40] = "40",
++ [NL80211_CHAN_WIDTH_80] = "80",
++ [NL80211_CHAN_WIDTH_80P80] = "80p80",
++ [NL80211_CHAN_WIDTH_160] = "160",
++};
++
+ static void print_enum(const struct tm_field *field, struct nlattr *attr)
+ {
+ unsigned int i = nla_get_u8(attr);
+@@ -387,6 +396,12 @@ static const struct tm_field testdata_fields[NUM_MT76_TM_ATTRS] = {
+ FIELD(u8, AID, "aid"),
+ FIELD(u8, RU_ALLOC, "ru_alloc"),
+ FIELD(u8, RU_IDX, "ru_idx"),
++ FIELD(u8, OFF_CH_SCAN_CH, "offchan_ch"),
++ FIELD(u8, OFF_CH_SCAN_CENTER_CH, "offchan_center_ch"),
++ FIELD_ENUM(OFF_CH_SCAN_BW, "offchan_bw", testmode_offchan_bw),
++ FIELD(u8, IPI_THRESHOLD, "ipi_threshold"),
++ FIELD(u32, IPI_PERIOD, "ipi_period"),
++ FIELD(u8, IPI_RESET, "ipi_reset"),
+ FIELD_MAC(MAC_ADDRS, "mac_addrs"),
+ FIELD_NESTED_RO(STATS, stats, "",
+ .print_extra = print_extra_stats),
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-single-sku.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-single-sku.patch
new file mode 100644
index 0000000..0fcae6a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1011-wifi-mt76-mt7996-add-single-sku.patch
@@ -0,0 +1,337 @@
+From 0d9ff0aa7afe37146c6015e416d9b944b4bb16f5 Mon Sep 17 00:00:00 2001
+From: "Allen.Ye" <allen.ye@mediatek.com>
+Date: Tue, 18 Apr 2023 15:56:22 +0800
+Subject: [PATCH 1011/1015] wifi: mt76: mt7996: add single sku
+
+Add single sku and default enable sku.
+
+Signed-off-by: Allen.Ye <allen.ye@mediatek.com>
+---
+ eeprom.c | 38 ++++++++++++++++++--
+ mt76.h | 10 ++++++
+ mt76_connac_mcu.c | 2 +-
+ mt7996/init.c | 2 ++
+ mt7996/main.c | 15 ++++++++
+ mt7996/mcu.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.h | 12 +++++++
+ mt7996/mt7996.h | 2 ++
+ 8 files changed, 169 insertions(+), 4 deletions(-)
+
+diff --git a/eeprom.c b/eeprom.c
+index 412740f0..3abefb5a 100644
+--- a/eeprom.c
++++ b/eeprom.c
+@@ -301,6 +301,7 @@ mt76_apply_multi_array_limit(s8 *pwr, size_t pwr_len, s8 pwr_num,
+ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ struct ieee80211_channel *chan,
+ struct mt76_power_limits *dest,
++ struct mt76_power_path_limits *dest_path,
+ s8 target_power)
+ {
+ struct mt76_dev *dev = phy->dev;
+@@ -308,16 +309,17 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ const __be32 *val;
+ char name[16];
+ u32 mcs_rates = dev->drv->mcs_rates;
+- u32 ru_rates = ARRAY_SIZE(dest->ru[0]);
+ char band;
+ size_t len;
+ s8 max_power = 0;
+ s8 txs_delta;
+
+ if (!mcs_rates)
+- mcs_rates = 10;
++ mcs_rates = 12;
+
+ memset(dest, target_power, sizeof(*dest));
++ if (dest_path != NULL)
++ memset(dest_path, 0, sizeof(*dest_path));
+
+ if (!IS_ENABLED(CONFIG_OF))
+ return target_power;
+@@ -365,11 +367,41 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ ARRAY_SIZE(dest->mcs), val, len,
+ target_power, txs_delta, &max_power);
+
+- val = mt76_get_of_array(np, "rates-ru", &len, ru_rates + 1);
++ val = mt76_get_of_array(np, "rates-ru", &len, ARRAY_SIZE(dest->ru[0]) + 1);
+ mt76_apply_multi_array_limit(dest->ru[0], ARRAY_SIZE(dest->ru[0]),
+ ARRAY_SIZE(dest->ru), val, len,
+ target_power, txs_delta, &max_power);
+
++ val = mt76_get_of_array(np, "rates-eht-ru", &len, ARRAY_SIZE(dest->eht_ru[0]) + 1);
++ mt76_apply_multi_array_limit(dest->eht_ru[0], ARRAY_SIZE(dest->eht_ru[0]),
++ ARRAY_SIZE(dest->eht_ru), val, len,
++ target_power, txs_delta, &max_power);
++
++ if (dest_path == NULL)
++ return max_power;
++
++ val = mt76_get_of_array(np, "paths-cck", &len, ARRAY_SIZE(dest_path->cck));
++ mt76_apply_array_limit(dest_path->cck, ARRAY_SIZE(dest_path->cck), val,
++ target_power, txs_delta, &max_power);
++
++ val = mt76_get_of_array(np, "paths-ofdm", &len, ARRAY_SIZE(dest_path->ofdm));
++ mt76_apply_array_limit(dest_path->ofdm, ARRAY_SIZE(dest_path->ofdm), val,
++ target_power, txs_delta, &max_power);
++
++ val = mt76_get_of_array(np, "paths-ofdm-bf", &len, ARRAY_SIZE(dest_path->ofdm_bf));
++ mt76_apply_array_limit(dest_path->ofdm_bf, ARRAY_SIZE(dest_path->ofdm_bf), val,
++ target_power, txs_delta, &max_power);
++
++ val = mt76_get_of_array(np, "paths-ru", &len, ARRAY_SIZE(dest_path->ru[0]) + 1);
++ mt76_apply_multi_array_limit(dest_path->ru[0], ARRAY_SIZE(dest_path->ru[0]),
++ ARRAY_SIZE(dest_path->ru), val, len,
++ target_power, txs_delta, &max_power);
++
++ val = mt76_get_of_array(np, "paths-ru-bf", &len, ARRAY_SIZE(dest_path->ru_bf[0]) + 1);
++ mt76_apply_multi_array_limit(dest_path->ru_bf[0], ARRAY_SIZE(dest_path->ru_bf[0]),
++ ARRAY_SIZE(dest_path->ru_bf), val, len,
++ target_power, txs_delta, &max_power);
++
+ return max_power;
+ }
+ EXPORT_SYMBOL_GPL(mt76_get_rate_power_limits);
+diff --git a/mt76.h b/mt76.h
+index 5b442691..8abb6f41 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -911,6 +911,15 @@ struct mt76_power_limits {
+ s8 ofdm[8];
+ s8 mcs[4][10];
+ s8 ru[7][12];
++ s8 eht_ru[16][16];
++};
++
++struct mt76_power_path_limits {
++ s8 cck[5];
++ s8 ofdm[5];
++ s8 ofdm_bf[4];
++ s8 ru[16][15];
++ s8 ru_bf[16][15];
+ };
+
+ struct mt76_ethtool_worker_info {
+@@ -1493,6 +1502,7 @@ void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set);
+ s8 mt76_get_rate_power_limits(struct mt76_phy *phy,
+ struct ieee80211_channel *chan,
+ struct mt76_power_limits *dest,
++ struct mt76_power_path_limits *dest_path,
+ s8 target_power);
+
+ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
+index c24dac10..ca7b6a6f 100644
+--- a/mt76_connac_mcu.c
++++ b/mt76_connac_mcu.c
+@@ -2235,7 +2235,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
+ sar_power = mt76_get_sar_power(phy, &chan, reg_power);
+
+ mt76_get_rate_power_limits(phy, &chan, &limits,
+- sar_power);
++ NULL, sar_power);
+
+ tx_power_tlv.last_msg = ch_list[idx] == last_ch;
+ sku_tlbv.channel = ch_list[idx];
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 31695090..a6caf4f1 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -294,6 +294,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+ int nss_delta = mt76_tx_power_nss_delta(nss);
+ int pwr_delta = mt7996_eeprom_get_power_delta(dev, sband->band);
+ struct mt76_power_limits limits;
++ struct mt76_power_path_limits limits_path;
+
+ for (i = 0; i < sband->n_channels; i++) {
+ struct ieee80211_channel *chan = &sband->channels[i];
+@@ -302,6 +303,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+ target_power += pwr_delta;
+ target_power = mt76_get_rate_power_limits(&dev->mphy, chan,
+ &limits,
++ &limits_path,
+ target_power);
+ target_power += nss_delta;
+ target_power = DIV_ROUND_UP(target_power, 2);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index d3d10fab..71c346cb 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -77,6 +77,15 @@ int mt7996_run(struct ieee80211_hw *hw)
+ if (ret)
+ goto out;
+
++#ifdef CONFIG_MTK_DEBUG
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL,
++ !dev->dbg.sku_disable);
++#else
++ ret = mt7996_mcu_set_tx_power_ctrl(phy, UNI_TXPOWER_SKU_POWER_LIMIT_CTRL, true);
++#endif
++ if (ret)
++ goto out;
++
+ set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
+
+ ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
+@@ -427,6 +436,12 @@ static int mt7996_config(struct ieee80211_hw *hw, u32 changed)
+ ieee80211_wake_queues(hw);
+ }
+
++ if (changed & IEEE80211_CONF_CHANGE_POWER) {
++ ret = mt7996_mcu_set_txpower_sku(phy);
++ if (ret)
++ return ret;
++ }
++
+ mutex_lock(&dev->mt76.mutex);
+
+ if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 53d2fc73..aefbdca6 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -4616,6 +4616,98 @@ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable)
+ &req, sizeof(req), false);
+ }
+
++int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy)
++{
++#define TX_POWER_LIMIT_TABLE_RATE 0
++#define TX_POWER_LIMIT_TABLE_PATH 1
++ struct mt7996_dev *dev = phy->dev;
++ struct mt76_phy *mphy = phy->mt76;
++ struct ieee80211_hw *hw = mphy->hw;
++ struct tx_power_limit_table_ctrl {
++ u8 __rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++ u8 power_ctrl_id;
++ u8 power_limit_type;
++ u8 band_idx;
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL),
++ .len = cpu_to_le16(sizeof(req) + MT7996_SKU_PATH_NUM - 4),
++ .power_ctrl_id = UNI_TXPOWER_POWER_LIMIT_TABLE_CTRL,
++ .power_limit_type = TX_POWER_LIMIT_TABLE_RATE,
++ .band_idx = phy->mt76->band_idx,
++ };
++
++ int i, ret, tx_power;
++ const u8 *len = mt7996_sku_group_len;
++ struct mt76_power_limits la = {};
++ struct mt76_power_path_limits la_path = {};
++ struct sk_buff *skb;
++
++ tx_power = mt7996_get_power_bound(phy, hw->conf.power_level);
++ tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
++ &la, &la_path, tx_power);
++ mphy->txpower_cur = tx_power;
++
++ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
++ sizeof(req) + MT7996_SKU_PATH_NUM);
++ if (!skb)
++ return -ENOMEM;
++
++ skb_put_data(skb, &req, sizeof(req));
++ skb_put_data(skb, &la.cck, len[SKU_CCK] + len[SKU_OFDM]);
++
++ skb_put_data(skb, &la.mcs[0], len[SKU_HT20]);
++ skb_put_data(skb, &la.mcs[1], len[SKU_HT40]);
++
++ /* vht */
++ for (i = 0; i < 4; i++) {
++ skb_put_data(skb, &la.mcs[i], sizeof(la.mcs[i]));
++ skb_put_zero(skb, 2); /* padding */
++ }
++
++ /* he */
++ skb_put_data(skb, &la.ru[0], sizeof(la.ru));
++
++ /* eht */
++ skb_put_data(skb, &la.eht_ru[0], sizeof(la.eht_ru));
++
++ /* padding */
++ skb_put_zero(skb, MT7996_SKU_PATH_NUM - MT7996_SKU_RATE_NUM);
++
++ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
++ MCU_WM_UNI_CMD(TXPOWER), true);
++ if (ret)
++ return ret;
++
++ /* only set per-path power table when it's configured */
++ if (!la_path.ofdm[0])
++ return 0;
++
++ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
++ sizeof(req) + MT7996_SKU_PATH_NUM);
++ if (!skb)
++ return -ENOMEM;
++ req.power_limit_type = TX_POWER_LIMIT_TABLE_PATH;
++
++ skb_put_data(skb, &req, sizeof(req));
++ skb_put_data(skb, &la_path.cck, sizeof(la_path.cck));
++ skb_put_data(skb, &la_path.ofdm, sizeof(la_path.ofdm));
++ skb_put_data(skb, &la_path.ofdm_bf, sizeof(la_path.ofdm_bf));
++
++ for (i = 0; i < 32; i++) {
++ bool bf = i % 2;
++ u8 idx = i / 2;
++ s8 *buf = bf ? la_path.ru_bf[idx] : la_path.ru[idx];
++
++ skb_put_data(skb, buf, sizeof(la_path.ru[0]));
++ }
++
++ return mt76_mcu_skb_send_msg(&dev->mt76, skb,
++ MCU_WM_UNI_CMD(TXPOWER), true);
++}
++
+ #ifdef CONFIG_MTK_VENDOR
+ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif)
+ {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index f32ac153..1d2b7c58 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -657,6 +657,18 @@ enum {
+ #define MT7996_MAX_BSS_OFFLOAD_SIZE (MT7996_MAX_BEACON_SIZE + \
+ MT7996_BEACON_UPDATE_SIZE)
+
++static inline s8
++mt7996_get_power_bound(struct mt7996_phy *phy, s8 txpower)
++{
++ struct mt76_phy *mphy = phy->mt76;
++ int n_chains = hweight8(mphy->antenna_mask);
++
++ txpower = mt76_get_sar_power(mphy, mphy->chandef.chan, txpower * 2);
++ txpower -= mt76_tx_power_nss_delta(n_chains);
++
++ return txpower;
++}
++
+ enum {
+ UNI_BAND_CONFIG_RADIO_ENABLE,
+ UNI_BAND_CONFIG_RTS_THRESHOLD = 0x08,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index abdbb1ef..d15bd950 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -61,6 +61,7 @@
+ #define MT7996_BUILD_TIME_LEN 24
+
+ #define MT7996_SKU_RATE_NUM 417
++#define MT7996_SKU_PATH_NUM 494
+
+ struct mt7996_vif;
+ struct mt7996_sta;
+@@ -610,6 +611,7 @@ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 da
+ int mt7996_mcu_get_tx_power_info(struct mt7996_phy *phy, u8 category, void *event);
+ int mt7996_mcu_apply_group_cal(struct mt7996_dev *dev);
+ int mt7996_mcu_apply_tx_dpd(struct mt7996_phy *phy);
++int mt7996_mcu_set_txpower_sku(struct mt7996_phy *phy);
+ int mt7996_mcu_set_scs(struct mt7996_phy *phy, u8 enable);
+ void mt7996_mcu_scs_sta_poll(struct work_struct *work);
+ #ifdef CONFIG_NL80211_TESTMODE
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
new file mode 100644
index 0000000..c5ea448
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch
@@ -0,0 +1,107 @@
+From a048ff567915954ca9cc68ef94c9a7786542b5d9 Mon Sep 17 00:00:00 2001
+From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
+Date: Wed, 3 May 2023 05:08:07 +0800
+Subject: [PATCH 1012/1015] wifi: mt76: mt7996: add vendor cmd to get available
+ color bitmap
+
+Add a vendor cmd to notify user space available color bitmap.
+The OBSS BSS color bitmap is maintained in mac80211, so mt76 will make use of that.
+
+Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
+---
+ mt7996/vendor.c | 36 ++++++++++++++++++++++++++++++++++++
+ mt7996/vendor.h | 11 +++++++++++
+ 2 files changed, 47 insertions(+)
+
+diff --git a/mt7996/vendor.c b/mt7996/vendor.c
+index 8a021324..73f613aa 100644
+--- a/mt7996/vendor.c
++++ b/mt7996/vendor.c
+@@ -34,6 +34,11 @@ amnt_dump_policy[NUM_MTK_VENDOR_ATTRS_AMNT_DUMP] = {
+ [MTK_VENDOR_ATTR_AMNT_DUMP_RESULT] = { .type = NLA_NESTED },
+ };
+
++static struct nla_policy
++bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = {
++ [MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP] = { .type = NLA_U64 },
++};
++
+ struct mt7996_amnt_data {
+ u8 idx;
+ u8 addr[ETH_ALEN];
+@@ -409,6 +414,26 @@ mt7966_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ return len + 1;
+ }
+
++static int
++mt7996_vendor_bss_color_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
++ struct sk_buff *skb, const void *data, int data_len,
++ unsigned long *storage)
++{
++ struct ieee80211_vif *vif = wdev_to_ieee80211_vif(wdev);
++ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
++ int len = 0;
++
++ if (*storage == 1)
++ return -ENOENT;
++ *storage = 1;
++
++ if (nla_put_u64_64bit(skb, MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP,
++ ~bss_conf->used_color_bitmap, NL80211_ATTR_PAD))
++ return -ENOMEM;
++ len += 1;
++
++ return len;
++}
+
+ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ {
+@@ -435,6 +460,17 @@ static const struct wiphy_vendor_command mt7996_vendor_commands[] = {
+ .policy = amnt_ctrl_policy,
+ .maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX,
+ },
++ {
++ .info = {
++ .vendor_id = MTK_NL80211_VENDOR_ID,
++ .subcmd = MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL,
++ },
++ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++ WIPHY_VENDOR_CMD_NEED_RUNNING,
++ .dumpit = mt7996_vendor_bss_color_ctrl_dump,
++ .policy = bss_color_ctrl_policy,
++ .maxattr = MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX,
++ },
+ };
+
+ void mt7996_vendor_register(struct mt7996_phy *phy)
+diff --git a/mt7996/vendor.h b/mt7996/vendor.h
+index 2078cafa..eec9e74a 100644
+--- a/mt7996/vendor.h
++++ b/mt7996/vendor.h
+@@ -6,6 +6,7 @@
+ enum mtk_nl80211_vendor_subcmds {
+ MTK_NL80211_VENDOR_SUBCMD_AMNT_CTRL = 0xae,
+ MTK_NL80211_VENDOR_SUBCMD_MU_CTRL = 0xc5,
++ MTK_NL80211_VENDOR_SUBCMD_BSS_COLOR_CTRL = 0xca,
+ };
+
+ enum mtk_vendor_attr_mu_ctrl {
+@@ -57,5 +58,15 @@ enum mtk_vendor_attr_mnt_dump {
+ NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1
+ };
+
++enum mtk_vendor_attr_bss_color_ctrl {
++ MTK_VENDOR_ATTR_BSS_COLOR_CTRL_UNSPEC,
++
++ MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL,
++ MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX =
++ NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL - 1
++};
+
+ #endif
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch
new file mode 100644
index 0000000..c01b398
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch
@@ -0,0 +1,109 @@
+From 3a58791cef81709963d654d520fab9f1b7987e7b Mon Sep 17 00:00:00 2001
+From: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
+Date: Thu, 11 May 2023 09:14:28 +0800
+Subject: [PATCH 1013/1015] wifi: mt76: mt7996: get tx_retries and tx_fails
+ from txfree
+
+Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com>
+---
+ mt7996/mac.c | 20 +++++++++++++++-----
+ mt7996/mac.h | 6 ++++--
+ mt7996/main.c | 6 ++++++
+ 3 files changed, 25 insertions(+), 7 deletions(-)
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 3dc5cdae..bee4a8ae 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1240,6 +1240,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ struct mt76_phy *phy3 = mdev->phys[MT_BAND2];
+ struct mt76_txwi_cache *txwi;
+ struct ieee80211_sta *sta = NULL;
++ struct mt76_wcid *wcid;
+ LIST_HEAD(free_list);
+ struct sk_buff *skb, *tmp;
+ void *end = data + len;
+@@ -1258,7 +1259,7 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ mt76_queue_tx_cleanup(dev, phy3->q_tx[MT_TXQ_BE], false);
+ }
+
+- if (WARN_ON_ONCE(le32_get_bits(tx_free[1], MT_TXFREE1_VER) < 4))
++ if (WARN_ON_ONCE(le32_get_bits(tx_free[1], MT_TXFREE1_VER) < 5))
+ return;
+
+ total = le32_get_bits(tx_free[0], MT_TXFREE0_MSDU_CNT);
+@@ -1274,10 +1275,9 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ info = le32_to_cpu(*cur_info);
+ if (info & MT_TXFREE_INFO_PAIR) {
+ struct mt7996_sta *msta;
+- struct mt76_wcid *wcid;
+ u16 idx;
+
+- idx = FIELD_GET(MT_TXFREE_INFO_WLAN_ID, info);
++ idx = FIELD_GET(MT_TXFREE_INFO_MLD_ID, info);
+ wcid = rcu_dereference(dev->mt76.wcid[idx]);
+ sta = wcid_to_sta(wcid);
+ if (!sta)
+@@ -1289,10 +1289,20 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
+ list_add_tail(&msta->poll_list, &dev->sta_poll_list);
+ spin_unlock_bh(&dev->sta_poll_lock);
+ continue;
+- }
++ } else if (info & MT_TXFREE_INFO_HEADER) {
++ if (!mtk_wed_device_active(&mdev->mmio.wed) && wcid) {
++ u32 tx_retries = 0, tx_failed = 0;
++
++ tx_retries =
++ FIELD_GET(MT_TXFREE_INFO_TX_COUNT, info) - 1;
++ tx_failed = tx_retries +
++ !!FIELD_GET(MT_TXFREE_INFO_STAT, info);
+
+- if (info & MT_TXFREE_INFO_HEADER)
++ wcid->stats.tx_retries += tx_retries;
++ wcid->stats.tx_failed += tx_failed;
++ }
+ continue;
++ }
+
+ for (i = 0; i < 2; i++) {
+ msdu = (info >> (15 * i)) & MT_TXFREE_INFO_MSDU_ID;
+diff --git a/mt7996/mac.h b/mt7996/mac.h
+index bc4e6c55..74ad1e81 100644
+--- a/mt7996/mac.h
++++ b/mt7996/mac.h
+@@ -256,11 +256,13 @@ enum tx_mgnt_type {
+ #define MT_TXFREE0_MSDU_CNT GENMASK(25, 16)
+ #define MT_TXFREE0_RX_BYTE GENMASK(15, 0)
+
+-#define MT_TXFREE1_VER GENMASK(18, 16)
++#define MT_TXFREE1_VER GENMASK(19, 16)
+
+ #define MT_TXFREE_INFO_PAIR BIT(31)
+ #define MT_TXFREE_INFO_HEADER BIT(30)
+-#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12)
++#define MT_TXFREE_INFO_TX_COUNT GENMASK(27, 24)
++#define MT_TXFREE_INFO_STAT GENMASK(29, 28)
++#define MT_TXFREE_INFO_MLD_ID GENMASK(23, 12)
+ #define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0)
+
+ #define MT_TXS0_BW GENMASK(31, 29)
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 71c346cb..f0bdec6b 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1024,6 +1024,12 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw,
+ sinfo->txrate.flags = txrate->flags;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
+
++ sinfo->tx_failed = msta->wcid.stats.tx_failed;
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
++
++ sinfo->tx_retries = msta->wcid.stats.tx_retries;
++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES);
++
+ sinfo->ack_signal = (s8)msta->ack_signal;
+ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_ACK_SIGNAL);
+
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
new file mode 100644
index 0000000..1b22e9a
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch
@@ -0,0 +1,171 @@
+From 97144fb0d20ba67ec6c3a022ed5a39bc95ed40e9 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Fri, 19 May 2023 14:56:07 +0800
+Subject: [PATCH 1014/1015] wifi: mt76: mt7996: add debugfs for fw coredump.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+---
+ mt7996/debugfs.c | 19 +++++++++++++++++--
+ mt7996/mac.c | 28 +++++++++++++++++++++++++---
+ mt7996/mcu.h | 4 ++++
+ mt7996/mt7996.h | 10 ++++++++++
+ 4 files changed, 56 insertions(+), 5 deletions(-)
+
+diff --git a/mt7996/debugfs.c b/mt7996/debugfs.c
+index 8a513f46..49c815a5 100644
+--- a/mt7996/debugfs.c
++++ b/mt7996/debugfs.c
+@@ -84,6 +84,8 @@ mt7996_sys_recovery_set(struct file *file, const char __user *user_buf,
+ * 7: trigger & enable system error L4 mdp recovery.
+ * 8: trigger & enable system error full recovery.
+ * 9: trigger firmware crash.
++ * 10: trigger grab wa firmware coredump.
++ * 11: trigger grab wm firmware coredump.
+ */
+ case UNI_CMD_SER_QUERY:
+ ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_QUERY, 0, band);
+@@ -105,15 +107,25 @@ mt7996_sys_recovery_set(struct file *file, const char __user *user_buf,
+ /* enable full chip reset */
+ case UNI_CMD_SER_SET_RECOVER_FULL:
+ mt76_set(dev, MT_WFDMA0_MCU_HOST_INT_ENA, MT_MCU_CMD_WDT_MASK);
+- dev->recovery.state |= MT_MCU_CMD_WDT_MASK;
++ dev->recovery.state |= MT_MCU_CMD_WM_WDT;
+ mt7996_reset(dev);
+ break;
+
+ /* WARNING: trigger firmware crash */
+ case UNI_CMD_SER_SET_SYSTEM_ASSERT:
++ // trigger wm assert exception
+ ret = mt7996_mcu_trigger_assert(dev);
+ if (ret)
+ return ret;
++ // trigger wa assert exception
++ mt76_wr(dev, 0x89098108, 0x20);
++ mt76_wr(dev, 0x89098118, 0x20);
++ break;
++ case UNI_CMD_SER_FW_COREDUMP_WA:
++ mt7996_coredump(dev, MT7996_COREDUMP_MANUAL_WA);
++ break;
++ case UNI_CMD_SER_FW_COREDUMP_WM:
++ mt7996_coredump(dev, MT7996_COREDUMP_MANUAL_WM);
+ break;
+ default:
+ break;
+@@ -160,7 +172,10 @@ mt7996_sys_recovery_get(struct file *file, char __user *user_buf,
+ "8: trigger system error full recovery\n");
+ desc += scnprintf(buff + desc, bufsz - desc,
+ "9: trigger firmware crash\n");
+-
++ desc += scnprintf(buff + desc, bufsz - desc,
++ "10: trigger grab wa firmware coredump\n");
++ desc += scnprintf(buff + desc, bufsz - desc,
++ "11: trigger grab wm firmware coredump\n");
+ /* SER statistics */
+ desc += scnprintf(buff + desc, bufsz - desc,
+ "\nlet's dump firmware SER statistics...\n");
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index bee4a8ae..993b43ce 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -2157,15 +2157,36 @@ void mt7996_mac_dump_work(struct work_struct *work)
+ struct mt7996_dev *dev;
+
+ dev = container_of(work, struct mt7996_dev, dump_work);
+- if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WA_WDT)
++ if (dev->dump_state == MT7996_COREDUMP_MANUAL_WA ||
++ READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WA_WDT)
+ mt7996_mac_fw_coredump(dev, MT7996_RAM_TYPE_WA);
+
+- if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WM_WDT)
++ if (dev->dump_state == MT7996_COREDUMP_MANUAL_WM ||
++ READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WM_WDT)
+ mt7996_mac_fw_coredump(dev, MT7996_RAM_TYPE_WM);
+
+- queue_work(dev->mt76.wq, &dev->reset_work);
++ if (READ_ONCE(dev->recovery.state) & MT_MCU_CMD_WDT_MASK)
++ queue_work(dev->mt76.wq, &dev->reset_work);
++
++ dev->dump_state = MT7996_COREDUMP_IDLE;
+ }
+
++void mt7996_coredump(struct mt7996_dev *dev, u8 state)
++{
++ if (state == MT7996_COREDUMP_IDLE ||
++ state >= __MT7996_COREDUMP_TYPE_MAX)
++ return;
++
++ if (dev->dump_state != MT7996_COREDUMP_IDLE)
++ return;
++
++ dev->dump_state = state;
++ dev_info(dev->mt76.dev, "%s attempting grab coredump\n",
++ wiphy_name(dev->mt76.hw->wiphy));
++
++ queue_work(dev->mt76.wq, &dev->dump_work);
++ }
++
+ void mt7996_reset(struct mt7996_dev *dev)
+ {
+ dev_info(dev->mt76.dev, "%s SER recovery state: 0x%08x\n",
+@@ -2187,6 +2208,7 @@ void mt7996_reset(struct mt7996_dev *dev)
+
+ mt7996_irq_disable(dev, MT_INT_MCU_CMD);
+ queue_work(dev->mt76.wq, &dev->dump_work);
++ mt7996_coredump(dev, MT7996_COREDUMP_AUTO);
+ return;
+ }
+
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index 1d2b7c58..a0cbf922 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -780,7 +780,11 @@ enum {
+ UNI_CMD_SER_SET_RECOVER_L3_BF,
+ UNI_CMD_SER_SET_RECOVER_L4_MDP,
+ UNI_CMD_SER_SET_RECOVER_FULL,
++ /* fw assert */
+ UNI_CMD_SER_SET_SYSTEM_ASSERT,
++ /* coredump */
++ UNI_CMD_SER_FW_COREDUMP_WA,
++ UNI_CMD_SER_FW_COREDUMP_WM,
+ /* action */
+ UNI_CMD_SER_ENABLE = 1,
+ UNI_CMD_SER_SET,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index d15bd950..e371964b 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -76,6 +76,14 @@ enum mt7996_ram_type {
+ __MT7996_RAM_TYPE_MAX,
+ };
+
++enum mt7996_coredump_state {
++ MT7996_COREDUMP_IDLE = 0,
++ MT7996_COREDUMP_MANUAL_WA,
++ MT7996_COREDUMP_MANUAL_WM,
++ MT7996_COREDUMP_AUTO,
++ __MT7996_COREDUMP_TYPE_MAX,
++};
++
+ enum mt7996_txq_id {
+ MT7996_TXQ_FWDL = 16,
+ MT7996_TXQ_MCU_WM,
+@@ -361,6 +369,7 @@ struct mt7996_dev {
+
+ /* protects coredump data */
+ struct mutex dump_mutex;
++ u8 dump_state;
+ #ifdef CONFIG_DEV_COREDUMP
+ struct {
+ struct mt7996_crash_data *crash_data[__MT7996_RAM_TYPE_MAX];
+@@ -540,6 +549,7 @@ void mt7996_init_txpower(struct mt7996_dev *dev,
+ struct ieee80211_supported_band *sband);
+ int mt7996_txbf_init(struct mt7996_dev *dev);
+ void mt7996_reset(struct mt7996_dev *dev);
++void mt7996_coredump(struct mt7996_dev *dev, u8 state);
+ int mt7996_run(struct ieee80211_hw *hw);
+ int mt7996_mcu_init(struct mt7996_dev *dev);
+ int mt7996_mcu_init_firmware(struct mt7996_dev *dev);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch b/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
new file mode 100644
index 0000000..33432ff
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch
@@ -0,0 +1,44 @@
+From 0d4c8fc47472e0acb7f823f483bc8b83c8a9f235 Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Tue, 6 Jun 2023 16:57:10 +0800
+Subject: [PATCH 1015/1015] wifi: mt76: mt7996: add support for runtime set
+ in-band discovery
+
+with this patch, AP can runtime set inband discovery via hostapd_cli
+
+Usage:
+Enable FILS: hostapd_cli -i [interface] inband_discovery 2 20
+Enable UBPR: hostapd_cli -i [interface] inband_discovery 1 20
+Disable inband discovery: hostapd_cli -i [interface] inband_discovery 0 0
+
+Signed-off-by: MeiChia Chiu <MeiChia.Chiu@mediatek.com>
+---
+ mt7996/mcu.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index aefbdca6..59f22f6d 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2438,8 +2438,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ if (IS_ERR(rskb))
+ return PTR_ERR(rskb);
+
+- if (changed & BSS_CHANGED_FILS_DISCOVERY &&
+- vif->bss_conf.fils_discovery.max_interval) {
++ if (changed & BSS_CHANGED_FILS_DISCOVERY) {
+ interval = vif->bss_conf.fils_discovery.max_interval;
+ skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
+ } else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
+@@ -2475,7 +2474,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev,
+ discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
+ discov->tx_interval = interval;
+ discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
+- discov->enable = true;
++ discov->enable = !!(interval);
+ discov->wcid = cpu_to_le16(MT7996_WTBL_RESERVED);
+
+ buf = (u8 *)tlv + sizeof(*discov);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-rework-wed-rx-flow.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-rework-wed-rx-flow.patch
new file mode 100644
index 0000000..050c6f2
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2000-wifi-mt76-rework-wed-rx-flow.patch
@@ -0,0 +1,443 @@
+From 06c6ad7b99c07aedc5403506c91cbb8e11cf95df Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Mon, 6 Feb 2023 13:37:23 +0800
+Subject: [PATCH 2000/2008] wifi: mt76: rework wed rx flow
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Change-Id: Icd787345c811cb5ad30d9c7c1c5f9e5298bd3be6
+---
+ dma.c | 89 +++++++++++++++++++++++++------------------------
+ mac80211.c | 2 +-
+ mt76.h | 23 ++++++++-----
+ mt7915/dma.c | 2 --
+ mt7915/mmio.c | 27 +++++++++++----
+ mt7915/mt7915.h | 1 +
+ tx.c | 16 ++++-----
+ 7 files changed, 90 insertions(+), 70 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index e1e9062b..35db73b9 100644
+--- a/dma.c
++++ b/dma.c
+@@ -59,17 +59,17 @@ mt76_alloc_txwi(struct mt76_dev *dev)
+ return t;
+ }
+
+-static struct mt76_txwi_cache *
++static struct mt76_rxwi_cache *
+ mt76_alloc_rxwi(struct mt76_dev *dev)
+ {
+- struct mt76_txwi_cache *t;
++ struct mt76_rxwi_cache *r;
+
+- t = kzalloc(L1_CACHE_ALIGN(sizeof(*t)), GFP_ATOMIC);
+- if (!t)
++ r = kzalloc(L1_CACHE_ALIGN(sizeof(*r)), GFP_ATOMIC);
++ if (!r)
+ return NULL;
+
+- t->ptr = NULL;
+- return t;
++ r->ptr = NULL;
++ return r;
+ }
+
+ static struct mt76_txwi_cache *
+@@ -88,20 +88,20 @@ __mt76_get_txwi(struct mt76_dev *dev)
+ return t;
+ }
+
+-static struct mt76_txwi_cache *
++static struct mt76_rxwi_cache *
+ __mt76_get_rxwi(struct mt76_dev *dev)
+ {
+- struct mt76_txwi_cache *t = NULL;
++ struct mt76_rxwi_cache *r = NULL;
+
+- spin_lock(&dev->wed_lock);
++ spin_lock(&dev->lock);
+ if (!list_empty(&dev->rxwi_cache)) {
+- t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache,
++ r = list_first_entry(&dev->rxwi_cache, struct mt76_rxwi_cache,
+ list);
+- list_del(&t->list);
++ list_del(&r->list);
+ }
+- spin_unlock(&dev->wed_lock);
++ spin_unlock(&dev->lock);
+
+- return t;
++ return r;
+ }
+
+ static struct mt76_txwi_cache *
+@@ -115,13 +115,13 @@ mt76_get_txwi(struct mt76_dev *dev)
+ return mt76_alloc_txwi(dev);
+ }
+
+-struct mt76_txwi_cache *
++struct mt76_rxwi_cache *
+ mt76_get_rxwi(struct mt76_dev *dev)
+ {
+- struct mt76_txwi_cache *t = __mt76_get_rxwi(dev);
++ struct mt76_rxwi_cache *r = __mt76_get_rxwi(dev);
+
+- if (t)
+- return t;
++ if (r)
++ return r;
+
+ return mt76_alloc_rxwi(dev);
+ }
+@@ -140,14 +140,14 @@ 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)
++mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r)
+ {
+- if (!t)
++ if (!r)
+ return;
+
+- spin_lock(&dev->wed_lock);
+- list_add(&t->list, &dev->rxwi_cache);
+- spin_unlock(&dev->wed_lock);
++ spin_lock(&dev->lock);
++ list_add(&r->list, &dev->rxwi_cache);
++ spin_unlock(&dev->lock);
+ }
+ EXPORT_SYMBOL_GPL(mt76_put_rxwi);
+
+@@ -168,13 +168,13 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+ void
+ mt76_free_pending_rxwi(struct mt76_dev *dev)
+ {
+- struct mt76_txwi_cache *t;
++ struct mt76_rxwi_cache *r;
+
+ local_bh_disable();
+- while ((t = __mt76_get_rxwi(dev)) != NULL) {
+- if (t->ptr)
+- mt76_put_page_pool_buf(t->ptr, false);
+- kfree(t);
++ while ((r = __mt76_get_rxwi(dev)) != NULL) {
++ if (r->ptr)
++ mt76_put_page_pool_buf(r->ptr, false);
++ kfree(r);
+ }
+ local_bh_enable();
+ }
+@@ -212,7 +212,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ {
+ struct mt76_desc *desc = &q->desc[q->head];
+ struct mt76_queue_entry *entry = &q->entry[q->head];
+- struct mt76_txwi_cache *txwi = NULL;
++ struct mt76_rxwi_cache *rxwi = NULL;
+ u32 buf1 = 0, ctrl;
+ int idx = q->head;
+ int rx_token;
+@@ -220,13 +220,13 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ 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)
++ rxwi = mt76_get_rxwi(dev);
++ if (!rxwi)
+ return -ENOMEM;
+
+- rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr);
++ rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
+ if (rx_token < 0) {
+- mt76_put_rxwi(dev, txwi);
++ mt76_put_rxwi(dev, rxwi);
+ return -ENOMEM;
+ }
+
+@@ -241,7 +241,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+
+ entry->dma_addr[0] = buf->addr;
+ entry->dma_len[0] = buf->len;
+- entry->txwi = txwi;
++ entry->rxwi = rxwi;
+ entry->buf = data;
+ entry->wcid = 0xffff;
+ entry->skip_buf1 = true;
+@@ -404,20 +404,20 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ 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);
++ struct mt76_rxwi_cache *r = mt76_rx_token_release(dev, token);
+
+- if (!t)
++ if (!r)
+ return NULL;
+
+- dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
++ dma_sync_single_for_cpu(dev->dma_dev, r->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;
++ buf = r->ptr;
++ r->dma_addr = 0;
++ r->ptr = NULL;
+
+- mt76_put_rxwi(dev, t);
++ mt76_put_rxwi(dev, r);
+
+ if (drop) {
+ u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+@@ -977,16 +977,19 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+ mt76_for_each_q_rx(dev, i) {
+ struct mt76_queue *q = &dev->q_rx[i];
+
++ if (mt76_queue_is_wed_rx(q))
++ continue;
++
+ netif_napi_del(&dev->napi[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);
++
++ mt76_free_pending_txwi(dev);
++ mt76_free_pending_rxwi(dev);
+ }
+ EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
+diff --git a/mac80211.c b/mac80211.c
+index 6430e6ee..5a203d31 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -613,7 +613,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+ spin_lock_init(&dev->lock);
+ spin_lock_init(&dev->cc_lock);
+ spin_lock_init(&dev->status_lock);
+- spin_lock_init(&dev->wed_lock);
+ mutex_init(&dev->mutex);
+ init_waitqueue_head(&dev->tx_wait);
+
+@@ -644,6 +643,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
+ INIT_LIST_HEAD(&dev->txwi_cache);
+ INIT_LIST_HEAD(&dev->rxwi_cache);
+ dev->token_size = dev->drv->token_size;
++ dev->rx_token_size = dev->drv->rx_token_size;
+
+ for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
+ skb_queue_head_init(&dev->rx_skb[i]);
+diff --git a/mt76.h b/mt76.h
+index 8abb6f41..72c3eb8f 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -180,6 +180,7 @@ struct mt76_queue_entry {
+ };
+ union {
+ struct mt76_txwi_cache *txwi;
++ struct mt76_rxwi_cache *rxwi;
+ struct urb *urb;
+ int buf_sz;
+ };
+@@ -371,10 +372,14 @@ struct mt76_txwi_cache {
+ struct list_head list;
+ dma_addr_t dma_addr;
+
+- union {
+- struct sk_buff *skb;
+- void *ptr;
+- };
++ struct sk_buff *skb;
++};
++
++struct mt76_rxwi_cache {
++ struct list_head list;
++ dma_addr_t dma_addr;
++
++ void *ptr;
+ };
+
+ struct mt76_rx_tid {
+@@ -460,6 +465,7 @@ struct mt76_driver_ops {
+ u16 txwi_size;
+ u16 token_size;
+ u8 mcs_rates;
++ u16 rx_token_size;
+
+ void (*update_survey)(struct mt76_phy *phy);
+
+@@ -810,7 +816,6 @@ struct mt76_dev {
+
+ struct ieee80211_hw *hw;
+
+- spinlock_t wed_lock;
+ spinlock_t lock;
+ spinlock_t cc_lock;
+
+@@ -1360,8 +1365,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
+ }
+
+ void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
+-void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
+-struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
++void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_rxwi_cache *r);
++struct mt76_rxwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
+ void mt76_free_pending_rxwi(struct mt76_dev *dev);
+ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
+ struct napi_struct *napi);
+@@ -1515,9 +1520,9 @@ struct mt76_txwi_cache *
+ mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
+ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
+ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+-struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
++struct mt76_rxwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
+ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
+- struct mt76_txwi_cache *r, dma_addr_t phys);
++ struct mt76_rxwi_cache *r, dma_addr_t phys);
+ int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q);
+ static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
+ {
+diff --git a/mt7915/dma.c b/mt7915/dma.c
+index 86a93ded..848e9843 100644
+--- a/mt7915/dma.c
++++ b/mt7915/dma.c
+@@ -493,7 +493,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
+ dev->mt76.q_rx[MT_RXQ_MAIN].flags =
+ MT_WED_Q_RX(MT7915_RXQ_BAND0);
+- dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
+ }
+
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
+@@ -530,7 +529,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2)
+ mtk_wed_get_rx_capa(&mdev->mmio.wed)) {
+ dev->mt76.q_rx[MT_RXQ_BAND1].flags =
+ MT_WED_Q_RX(MT7915_RXQ_BAND1);
+- dev->mt76.rx_token_size += MT7915_RX_RING_SIZE;
+ }
+
+ /* rx data queue for band1 */
+diff --git a/mt7915/mmio.c b/mt7915/mmio.c
+index 984b5f60..46256842 100644
+--- a/mt7915/mmio.c
++++ b/mt7915/mmio.c
+@@ -600,16 +600,28 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
+ for (i = 0; i < dev->mt76.rx_token_size; i++) {
+- struct mt76_txwi_cache *t;
++ struct mt76_rxwi_cache *r;
+
+- t = mt76_rx_token_release(&dev->mt76, i);
+- if (!t || !t->ptr)
++ r = mt76_rx_token_release(&dev->mt76, i);
++ if (!r || !r->ptr)
+ continue;
+
+- mt76_put_page_pool_buf(t->ptr, false);
+- t->ptr = NULL;
++ mt76_put_page_pool_buf(r->ptr, false);
++ r->ptr = NULL;
+
+- mt76_put_rxwi(&dev->mt76, t);
++ mt76_put_rxwi(&dev->mt76, r);
++ }
++
++ mt76_for_each_q_rx(dev, i) {
++ struct mt76_queue *q = &dev->q_rx[i];
++
++ if (!mt76_queue_is_wed_rx(q))
++ continue;
++
++ netif_napi_del(&dev->napi[i]);
++ mt76_dma_rx_cleanup(dev, q);
++
++ page_pool_destroy(q->page_pool);
+ }
+
+ mt76_free_pending_rxwi(&dev->mt76);
+@@ -812,7 +824,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr,
+ wed->wlan.reset = mt7915_mmio_wed_reset;
+ wed->wlan.reset_complete = mt7915_mmio_wed_reset_complete;
+
+- dev->mt76.rx_token_size = wed->wlan.rx_npkt;
++ dev->mt76.rx_token_size += wed->wlan.rx_npkt;
+
+ if (mtk_wed_device_attach(wed))
+ return 0;
+@@ -1018,6 +1030,7 @@ struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
+ SURVEY_INFO_TIME_RX |
+ SURVEY_INFO_TIME_BSS_RX,
+ .token_size = MT7915_TOKEN_SIZE,
++ .rx_token_size = MT7915_RX_TOKEN_SIZE;
+ .tx_prepare_skb = mt7915_tx_prepare_skb,
+ .tx_complete_skb = mt76_connac_tx_complete_skb,
+ .rx_skb = mt7915_queue_rx_skb,
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 103cd0d7..8ee62f63 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -62,6 +62,7 @@
+ #define MT7915_EEPROM_BLOCK_SIZE 16
+ #define MT7915_HW_TOKEN_SIZE 4096
+ #define MT7915_TOKEN_SIZE 8192
++#define MT7915_RX_TOKEN_SIZE 4096
+
+ #define MT7915_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
+ #define MT7915_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
+diff --git a/tx.c b/tx.c
+index 72b3ec71..6cb71f34 100644
+--- a/tx.c
++++ b/tx.c
+@@ -761,16 +761,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+ EXPORT_SYMBOL_GPL(mt76_token_consume);
+
+ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
+- struct mt76_txwi_cache *t, dma_addr_t phys)
++ struct mt76_rxwi_cache *r, dma_addr_t phys)
+ {
+ int token;
+
+ spin_lock_bh(&dev->rx_token_lock);
+- token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size,
++ token = idr_alloc(&dev->rx_token, r, 0, dev->rx_token_size,
+ GFP_ATOMIC);
+ if (token >= 0) {
+- t->ptr = ptr;
+- t->dma_addr = phys;
++ r->ptr = ptr;
++ r->dma_addr = phys;
+ }
+ spin_unlock_bh(&dev->rx_token_lock);
+
+@@ -807,15 +807,15 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
+ }
+ EXPORT_SYMBOL_GPL(mt76_token_release);
+
+-struct mt76_txwi_cache *
++struct mt76_rxwi_cache *
+ mt76_rx_token_release(struct mt76_dev *dev, int token)
+ {
+- struct mt76_txwi_cache *t;
++ struct mt76_rxwi_cache *r;
+
+ spin_lock_bh(&dev->rx_token_lock);
+- t = idr_remove(&dev->rx_token, token);
++ r = idr_remove(&dev->rx_token, token);
+ spin_unlock_bh(&dev->rx_token_lock);
+
+- return t;
++ return r;
+ }
+ EXPORT_SYMBOL_GPL(mt76_rx_token_release);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0022-mt76-revert-page-pool-changes.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
similarity index 83%
rename from recipes-wifi/linux-mt76/files/patches-3.x/0022-mt76-revert-page-pool-changes.patch
rename to recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
index f0daca8..58605d3 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/0022-mt76-revert-page-pool-changes.patch
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch
@@ -1,44 +1,47 @@
-From d28a3716f729848ef65192c84411b0912afe70c6 Mon Sep 17 00:00:00 2001
-From: Shayne Chen <shayne.chen@mediatek.com>
-Date: Mon, 6 Feb 2023 15:34:43 +0800
-Subject: [PATCH 22/22] mt76: revert page pool changes
+From 15b04fc966aa8f30492726132a6b81466b187581 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Mon, 6 Feb 2023 19:49:22 +0800
+Subject: [PATCH 2001/2008] wifi: mt76: revert page_poll for kernel 5.4
+This reverts commit e8c10835cf062c577ddf426913788c39d30b4bd7.
+
+Change-Id: I4e5764fc545087f691fb4c2f43e7a9cefd1e1657
---
- dma.c | 72 ++++++++++++++++++++++++++-------------------------
- mac80211.c | 57 ----------------------------------------
- mt76.h | 22 +---------------
- mt7915/main.c | 26 +++++++------------
- mt7915/mmio.c | 55 ++++++++++++++++++++++++---------------
- mt7921/main.c | 31 +++-------------------
- usb.c | 43 +++++++++++++++---------------
- 7 files changed, 108 insertions(+), 198 deletions(-)
+ dma.c | 78 +++++++++++++++++++++++++++++----------------------
+ mac80211.c | 57 -------------------------------------
+ mt76.h | 22 +--------------
+ mt7915/main.c | 26 +++++++----------
+ mt7915/mmio.c | 55 ++++++++++++++++++++++--------------
+ mt7921/main.c | 31 +++-----------------
+ usb.c | 43 ++++++++++++++--------------
+ 7 files changed, 115 insertions(+), 197 deletions(-)
diff --git a/dma.c b/dma.c
-index 465190eb..f560d37d 100644
+index 35db73b9..7153be47 100644
--- a/dma.c
+++ b/dma.c
@@ -173,7 +173,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev)
local_bh_disable();
- while ((t = __mt76_get_rxwi(dev)) != NULL) {
- if (t->ptr)
-- mt76_put_page_pool_buf(t->ptr, false);
-+ skb_free_frag(t->ptr);
- kfree(t);
+ while ((r = __mt76_get_rxwi(dev)) != NULL) {
+ if (r->ptr)
+- mt76_put_page_pool_buf(r->ptr, false);
++ skb_free_frag(r->ptr);
+ kfree(r);
}
local_bh_enable();
@@ -409,9 +409,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
- if (!t)
+ if (!r)
return NULL;
-- dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr,
+- dma_sync_single_for_cpu(dev->dma_dev, r->dma_addr,
- SKB_WITH_OVERHEAD(q->buf_size),
- page_pool_get_dma_dir(q->page_pool));
-+ dma_unmap_single(dev->dma_dev, t->dma_addr,
++ dma_unmap_single(dev->dma_dev, r->dma_addr,
+ SKB_WITH_OVERHEAD(q->buf_size),
+ DMA_FROM_DEVICE);
- buf = t->ptr;
- t->dma_addr = 0;
+ buf = r->ptr;
+ r->dma_addr = 0;
@@ -430,9 +430,9 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
} else {
buf = e->buf;
@@ -52,7 +55,7 @@
}
return buf;
-@@ -586,11 +586,11 @@ free_skb:
+@@ -592,11 +592,11 @@ free_skb:
}
static int
@@ -67,7 +70,7 @@
if (!q->ndesc)
return 0;
-@@ -598,25 +598,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -604,25 +604,26 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q,
spin_lock_bh(&q->lock);
while (q->queued < q->ndesc - 1) {
@@ -75,8 +78,7 @@
struct mt76_queue_buf qbuf;
- dma_addr_t addr;
- int offset;
-- void *buf;
-+ void *buf = NULL;
+ void *buf;
- buf = mt76_get_page_pool_buf(q, &offset, q->buf_size);
+ buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
@@ -105,7 +107,7 @@
break;
}
frames++;
-@@ -660,7 +661,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+@@ -666,7 +667,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
/* WED txfree queue needs ring to be initialized before setup */
q->flags = 0;
mt76_dma_queue_reset(dev, q);
@@ -114,7 +116,7 @@
q->flags = flags;
ret = mtk_wed_device_txfree_ring_setup(wed, q->regs);
-@@ -708,10 +709,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -714,10 +715,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
if (!q->entry)
return -ENOMEM;
@@ -125,7 +127,7 @@
ret = mt76_dma_wed_setup(dev, q, false);
if (ret)
return ret;
-@@ -725,6 +722,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -731,6 +728,7 @@ 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)
{
@@ -133,20 +135,28 @@
void *buf;
bool more;
-@@ -738,7 +736,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -744,7 +742,10 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
if (!buf)
break;
- mt76_put_page_pool_buf(buf, false);
++ if (q->flags & MT_QFLAG_RRO)
++ continue;
++
+ skb_free_frag(buf);
} while (1);
if (q->rx_head) {
-@@ -747,6 +745,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -753,6 +754,18 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
}
spin_unlock_bh(&q->lock);
+
++ if (((q->flags & MT_QFLAG_WED) &&
++ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) ||
++ (q->flags & MT_QFLAG_RRO))
++ return;
++
+ if (!q->rx_page.va)
+ return;
+
@@ -156,7 +166,7 @@
}
static void
-@@ -767,7 +772,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -773,7 +786,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
mt76_dma_wed_setup(dev, q, true);
if (q->flags != MT_WED_Q_TXFREE) {
mt76_dma_sync_idx(dev, q);
@@ -165,7 +175,7 @@
}
}
-@@ -785,7 +790,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+@@ -791,7 +804,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 {
@@ -174,7 +184,7 @@
}
if (more)
-@@ -858,7 +863,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -864,7 +877,6 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
goto free_frag;
skb_reserve(skb, q->buf_offset);
@@ -182,7 +192,7 @@
*(u32 *)skb->cb = info;
-@@ -874,10 +878,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -880,10 +892,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
continue;
free_frag:
@@ -195,7 +205,7 @@
return done;
}
-@@ -922,7 +926,7 @@ mt76_dma_init(struct mt76_dev *dev,
+@@ -928,7 +940,7 @@ mt76_dma_init(struct mt76_dev *dev,
mt76_for_each_q_rx(dev, i) {
netif_napi_add(&dev->napi_dev, &dev->napi[i], poll);
@@ -204,7 +214,7 @@
napi_enable(&dev->napi[i]);
}
-@@ -973,8 +977,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+@@ -982,8 +994,6 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
netif_napi_del(&dev->napi[i]);
mt76_dma_rx_cleanup(dev, q);
@@ -212,9 +222,9 @@
- page_pool_destroy(q->page_pool);
}
- mt76_free_pending_txwi(dev);
+ if (mtk_wed_device_active(&dev->mmio.wed))
diff --git a/mac80211.c b/mac80211.c
-index d1cdaee8..4599f697 100644
+index 5a203d31..f7578308 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -4,7 +4,6 @@
@@ -224,8 +234,8 @@
-#include <net/page_pool.h>
#include "mt76.h"
- #define CHAN2G(_idx, _freq) { \
-@@ -562,47 +561,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
+ static const struct ieee80211_channel mt76_channels_2ghz[] = {
+@@ -542,47 +541,6 @@ void mt76_unregister_phy(struct mt76_phy *phy)
}
EXPORT_SYMBOL_GPL(mt76_unregister_phy);
@@ -273,7 +283,7 @@
struct mt76_dev *
mt76_alloc_device(struct device *pdev, unsigned int size,
const struct ieee80211_ops *ops,
-@@ -1748,21 +1706,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
+@@ -1728,21 +1686,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
}
EXPORT_SYMBOL_GPL(mt76_ethtool_worker);
@@ -296,10 +306,10 @@
{
struct ieee80211_hw *hw = phy->hw;
diff --git a/mt76.h b/mt76.h
-index 31d5dc37..f012ac0c 100644
+index 72c3eb8f..a0c20d36 100644
--- a/mt76.h
+++ b/mt76.h
-@@ -202,7 +202,7 @@ struct mt76_queue {
+@@ -224,7 +224,7 @@ struct mt76_queue {
dma_addr_t desc_dma;
struct sk_buff *rx_head;
@@ -308,7 +318,7 @@
};
struct mt76_mcu_ops {
-@@ -1363,7 +1363,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
+@@ -1410,7 +1410,6 @@ mt76u_bulk_msg(struct mt76_dev *dev, void *data, int len, int *actual_len,
return usb_bulk_msg(udev, pipe, data, len, actual_len, timeout);
}
@@ -316,10 +326,10 @@
void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi,
struct mt76_sta_stats *stats, bool eht);
int mt76_skb_adjust_pad(struct sk_buff *skb, int pad);
-@@ -1475,25 +1474,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
- struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
+@@ -1523,25 +1522,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
+ struct mt76_rxwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
- struct mt76_txwi_cache *r, dma_addr_t phys);
+ struct mt76_rxwi_cache *r, dma_addr_t phys);
-int mt76_create_page_pool(struct mt76_dev *dev, struct mt76_queue *q);
-static inline void mt76_put_page_pool_buf(void *buf, bool allow_direct)
-{
@@ -401,7 +411,7 @@
static void
diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-index 984b5f60..1bb8a4cb 100644
+index 46256842..8ff2c70c 100644
--- a/mt7915/mmio.c
+++ b/mt7915/mmio.c
@@ -596,9 +596,13 @@ static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed)
@@ -416,20 +426,20 @@
+ sizeof(struct skb_shared_info));
+
for (i = 0; i < dev->mt76.rx_token_size; i++) {
- struct mt76_txwi_cache *t;
+ struct mt76_rxwi_cache *r;
@@ -606,7 +610,9 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
- if (!t || !t->ptr)
+ if (!r || !r->ptr)
continue;
-- mt76_put_page_pool_buf(t->ptr, false);
-+ dma_unmap_single(dev->mt76.dma_dev, t->dma_addr,
+- mt76_put_page_pool_buf(r->ptr, false);
++ dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
+ wed->wlan.rx_size, DMA_FROM_DEVICE);
-+ __free_pages(virt_to_page(t->ptr), get_order(length));
- t->ptr = NULL;
++ __free_pages(virt_to_page(r->ptr), get_order(length));
+ r->ptr = NULL;
- mt76_put_rxwi(&dev->mt76, t);
-@@ -618,38 +624,47 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
+ mt76_put_rxwi(&dev->mt76, r);
+@@ -630,38 +636,47 @@ static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
{
struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
@@ -450,7 +460,7 @@
- enum dma_data_direction dir;
- dma_addr_t addr;
- u32 offset;
-+ struct mt76_txwi_cache *t = mt76_get_rxwi(&dev->mt76);
++ struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
+ dma_addr_t phy_addr;
+ struct page *page;
int token;
@@ -465,7 +475,7 @@
- if (!buf)
+ page = __dev_alloc_pages(GFP_KERNEL, get_order(length));
+ if (!page) {
-+ mt76_put_rxwi(&dev->mt76, t);
++ mt76_put_rxwi(&dev->mt76, r);
goto unmap;
+ }
@@ -478,24 +488,24 @@
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(dev->mt76.dev, phy_addr))) {
+ __free_pages(page, get_order(length));
-+ mt76_put_rxwi(&dev->mt76, t);
++ mt76_put_rxwi(&dev->mt76, r);
+ goto unmap;
+ }
- desc->buf0 = cpu_to_le32(addr);
- token = mt76_rx_token_consume(&dev->mt76, buf, t, addr);
+ desc->buf0 = cpu_to_le32(phy_addr);
-+ token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr);
++ token = mt76_rx_token_consume(&dev->mt76, ptr, r, phy_addr);
if (token < 0) {
- mt76_put_page_pool_buf(buf, false);
+ dma_unmap_single(dev->mt76.dma_dev, phy_addr,
+ wed->wlan.rx_size, DMA_TO_DEVICE);
+ __free_pages(page, get_order(length));
-+ mt76_put_rxwi(&dev->mt76, t);
++ mt76_put_rxwi(&dev->mt76, r);
goto unmap;
}
-@@ -661,8 +676,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
+@@ -673,8 +688,6 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
return 0;
unmap:
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
new file mode 100644
index 0000000..21f5e83
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch
@@ -0,0 +1,38 @@
+From 2ced3e3d33ef919332226f09a214ef2b04555a6d Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Wed, 19 Apr 2023 17:13:41 +0800
+Subject: [PATCH 2002/2008] wifi: mt76: wed: change wed token init size to
+ adapt wed3.0
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ tx.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/tx.c b/tx.c
+index 6cb71f34..618c99a1 100644
+--- a/tx.c
++++ b/tx.c
+@@ -737,12 +737,16 @@ EXPORT_SYMBOL_GPL(__mt76_set_tx_blocked);
+
+ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+ {
+- int token;
++ int token, start = 0;
++
++ if (mtk_wed_device_active(&dev->mmio.wed))
++ start = dev->mmio.wed.wlan.nbuf;
+
+ spin_lock_bh(&dev->token_lock);
+
+- token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
+- if (token >= 0)
++ token = idr_alloc(&dev->token, *ptxwi, start, start + dev->token_size,
++ GFP_ATOMIC);
++ if (token >= start)
+ dev->token_count++;
+
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch
new file mode 100644
index 0000000..feb77a6
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch
@@ -0,0 +1,995 @@
+From d9167faacb2a8466e2d19993f29b2c0770c5164e Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Wed, 26 Apr 2023 16:44:57 +0800
+Subject: [PATCH 2003/2008] wifi: mt76: mt7996: wed: add wed3.0 tx support
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ dma.c | 17 ++-
+ mt76.h | 7 ++
+ mt7996/dma.c | 128 ++++++++++++++++++---
+ mt7996/init.c | 21 +++-
+ mt7996/mac.c | 29 ++++-
+ mt7996/main.c | 46 ++++++++
+ mt7996/mmio.c | 295 +++++++++++++++++++++++++++++++++++++++++++++---
+ mt7996/mt7996.h | 8 +-
+ mt7996/pci.c | 72 +++++++++---
+ mt7996/regs.h | 5 +
+ 10 files changed, 567 insertions(+), 61 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 7153be47..930ec768 100644
+--- a/dma.c
++++ b/dma.c
+@@ -13,6 +13,11 @@
+ u32 _offset = offsetof(struct mt76_queue_regs, _field); \
+ u32 _val; \
+ if ((_q)->flags & MT_QFLAG_WED) \
++ if((_q)->flags & MT_QFLAG_WED_EXT) \
++ _val = mtk_wed_device_reg_read(&(_dev)->mmio.wed_ext, \
++ ((_q)->wed_regs + \
++ _offset)); \
++ else \
+ _val = mtk_wed_device_reg_read(&(_dev)->mmio.wed, \
+ ((_q)->wed_regs + \
+ _offset)); \
+@@ -24,6 +29,11 @@
+ #define Q_WRITE(_dev, _q, _field, _val) do { \
+ u32 _offset = offsetof(struct mt76_queue_regs, _field); \
+ if ((_q)->flags & MT_QFLAG_WED) \
++ if((_q)->flags & MT_QFLAG_WED_EXT) \
++ mtk_wed_device_reg_write(&(_dev)->mmio.wed_ext, \
++ ((_q)->wed_regs + _offset), \
++ _val); \
++ else \
+ mtk_wed_device_reg_write(&(_dev)->mmio.wed, \
+ ((_q)->wed_regs + _offset), \
+ _val); \
+@@ -654,6 +664,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ if (!(q->flags & MT_QFLAG_WED))
+ return 0;
+
++ if ((q->flags & MT_QFLAG_WED_EXT))
++ wed = &dev->mmio.wed_ext;
++
+ type = FIELD_GET(MT_QFLAG_WED_TYPE, q->flags);
+ ring = FIELD_GET(MT_QFLAG_WED_RING, q->flags);
+
+@@ -719,7 +732,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ if (ret)
+ return ret;
+
+- if (q->flags != MT_WED_Q_TXFREE)
++ if (!mt76_queue_is_txfree(q))
+ mt76_dma_queue_reset(dev, q);
+
+ return 0;
+@@ -999,6 +1012,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+ if (mtk_wed_device_active(&dev->mmio.wed))
+ mtk_wed_device_detach(&dev->mmio.wed);
+
++ if (mtk_wed_device_active(&dev->mmio.wed_ext))
++ mtk_wed_device_detach(&dev->mmio.wed_ext);
+ mt76_free_pending_txwi(dev);
+ mt76_free_pending_rxwi(dev);
+ }
+diff --git a/mt76.h b/mt76.h
+index a0c20d36..ee0dbdd7 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -51,6 +51,7 @@
+ #define MT_QFLAG_WED_RING GENMASK(1, 0)
+ #define MT_QFLAG_WED_TYPE GENMASK(3, 2)
+ #define MT_QFLAG_WED BIT(4)
++#define MT_QFLAG_WED_EXT BIT(11)
+
+ #define __MT_WED_Q(_type, _n) (MT_QFLAG_WED | \
+ FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
+@@ -623,6 +624,7 @@ struct mt76_mmio {
+ u32 irqmask;
+
+ struct mtk_wed_device wed;
++ struct mtk_wed_device wed_ext;
+ struct completion wed_reset;
+ struct completion wed_reset_complete;
+ };
+@@ -1514,6 +1516,11 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+ return (q->flags & MT_QFLAG_WED) &&
+ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
+ }
++static inline bool mt76_queue_is_txfree(struct mt76_queue *q)
++{
++ return (q->flags & MT_QFLAG_WED) &&
++ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
++}
+
+ struct mt76_txwi_cache *
+ mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index b8f253d0..673b08bb 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -7,6 +7,25 @@
+ #include "../dma.h"
+ #include "mac.h"
+
++int
++mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, int n_desc,
++ int ring_base, struct mtk_wed_device *wed)
++{
++ struct mt7996_dev *dev = phy->dev;
++ u32 flags = 0;
++
++ if (mtk_wed_device_active(wed)) {
++ ring_base += MT_TXQ_ID(0) * MT_RING_SIZE;
++ idx -= MT_TXQ_ID(0);
++ flags = MT_WED_Q_TX(idx);
++ if (phy->mt76->band_idx == MT_BAND2)
++ flags = MT_QFLAG_WED_EXT | MT_WED_Q_TX(0) ;
++ }
++
++ return mt76_connac_init_tx_queues(phy->mt76, idx, n_desc,
++ ring_base, flags);
++}
++
+ static int mt7996_poll_tx(struct napi_struct *napi, int budget)
+ {
+ struct mt7996_dev *dev;
+@@ -128,7 +147,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
+ }
+ }
+
+-void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
++void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+ {
+ u32 hif1_ofs = 0;
+ u32 irq_mask;
+@@ -153,11 +172,9 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ }
+
+ /* enable interrupts for TX/RX rings */
+- irq_mask = MT_INT_MCU_CMD;
+- if (reset)
+- goto done;
+-
+- irq_mask |= (MT_INT_RX_DONE_MCU | MT_INT_TX_DONE_MCU);
++ irq_mask = MT_INT_MCU_CMD |
++ MT_INT_RX_DONE_MCU |
++ MT_INT_TX_DONE_MCU;
+
+ if (mt7996_band_valid(dev, MT_BAND0))
+ irq_mask |= MT_INT_BAND0_RX_DONE;
+@@ -168,7 +185,18 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ if (mt7996_band_valid(dev, MT_BAND2))
+ irq_mask |= MT_INT_BAND2_RX_DONE;
+
+-done:
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
++ u32 wed_irq_mask = irq_mask;
++
++ wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
++
++ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++
++ mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
++ }
++
++ irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
++
+ mt7996_irq_enable(dev, irq_mask);
+ mt7996_irq_disable(dev, 0);
+ }
+@@ -241,19 +269,24 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ /* fix hardware limitation, pcie1's rx ring3 is not available
+ * so, redirect pcie0 rx ring3 interrupt to pcie1
+ */
+- mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
+- MT_WFDMA0_RX_INT_SEL_RING3);
+-
+- /* TODO: redirect rx ring6 interrupt to pcie0 for wed function */
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->rro_support)
++ mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
++ MT_WFDMA0_RX_INT_SEL_RING6);
++ else
++ mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL,
++ MT_WFDMA0_RX_INT_SEL_RING3);
+ }
+
+- __mt7996_dma_enable(dev, reset);
++ __mt7996_dma_enable(dev, reset, true);
+
+ return 0;
+ }
+
+ int mt7996_dma_init(struct mt7996_dev *dev)
+ {
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++ struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
++ u32 rx_base;
+ u32 hif1_ofs = 0;
+ int ret;
+
+@@ -267,10 +300,11 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ mt7996_dma_disable(dev, true);
+
+ /* init tx queue */
+- ret = mt76_connac_init_tx_queues(dev->phy.mt76,
+- MT_TXQ_ID(dev->mphy.band_idx),
+- MT7996_TX_RING_SIZE,
+- MT_TXQ_RING_BASE(0), 0);
++ ret = mt7996_init_tx_queues(&dev->phy,
++ MT_TXQ_ID(dev->mphy.band_idx),
++ MT7996_TX_RING_SIZE,
++ MT_TXQ_RING_BASE(0),
++ wed);
+ if (ret)
+ return ret;
+
+@@ -326,6 +360,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ return ret;
+
+ /* tx free notify event from WA for band0 */
++ if (mtk_wed_device_active(wed) && !dev->rro_support)
++ dev->mt76.q_rx[MT_RXQ_MAIN_WA].flags = MT_WED_Q_TXFREE;
++
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN_WA],
+ MT_RXQ_ID(MT_RXQ_MAIN_WA),
+ MT7996_RX_MCU_RING_SIZE,
+@@ -336,17 +373,24 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+
+ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx data queue for band2 */
++ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
++ if (mtk_wed_device_active(wed))
++ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
++
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ MT_RXQ_ID(MT_RXQ_BAND2),
+ MT7996_RX_RING_SIZE,
+ MT_RX_BUF_SIZE,
+- MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs);
++ rx_base);
+ if (ret)
+ return ret;
+
+ /* tx free notify event from WA for band2
+ * use pcie0's rx ring3, but, redirect pcie0 rx ring3 interrupt to pcie1
+ */
++ if (mtk_wed_device_active(wed_ext) && !dev->rro_support)
++ dev->mt76.q_rx[MT_RXQ_BAND2_WA].flags = MT_WED_Q_TXFREE |
++ MT_QFLAG_WED_EXT;
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2_WA],
+ MT_RXQ_ID(MT_RXQ_BAND2_WA),
+ MT7996_RX_MCU_RING_SIZE,
+@@ -356,6 +400,56 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ return ret;
+ }
+
++
++ if (dev->rro_support) {
++ /* rx rro data queue for band0 */
++ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags = MT_RRO_Q_DATA(0);
++ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_QFLAG_MAGIC;
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
++ MT_RXQ_ID(MT_RXQ_RRO_BAND0),
++ MT7996_RX_RING_SIZE,
++ MT7996_RX_BUF_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND0));
++ if (ret)
++ return ret;
++
++ /* tx free notify event from WA for band0 */
++ if (mtk_wed_device_active(wed))
++ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
++ MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
++ MT7996_RX_MCU_RING_SIZE,
++ MT7996_RX_BUF_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND0));
++ if (ret)
++ return ret;
++
++ if (mt7996_band_valid(dev, MT_BAND2)) {
++ /* rx rro data queue for band2 */
++ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags = MT_RRO_Q_DATA(1);
++ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_QFLAG_MAGIC;
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
++ MT_RXQ_ID(MT_RXQ_RRO_BAND2),
++ MT7996_RX_RING_SIZE,
++ MT7996_RX_BUF_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_RRO_BAND2) + hif1_ofs);
++ if (ret)
++ return ret;
++
++ /* tx free notify event from MAC for band2 */
++ if (mtk_wed_device_active(wed_ext))
++ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2].flags = MT_WED_Q_TXFREE |
++ MT_QFLAG_WED_EXT;
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND2],
++ MT_RXQ_ID(MT_RXQ_TXFREE_BAND2),
++ MT7996_RX_MCU_RING_SIZE,
++ MT7996_RX_BUF_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_TXFREE_BAND2) + hif1_ofs);
++ if (ret)
++ return ret;
++ }
++ }
++
+ ret = mt76_init_queues(dev, mt76_dma_rx_poll);
+ if (ret < 0)
+ return ret;
+diff --git a/mt7996/init.c b/mt7996/init.c
+index a6caf4f1..6cfbc50d 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -534,6 +534,7 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ struct mt76_phy *mphy;
+ u32 mac_ofs, hif1_ofs = 0;
+ int ret;
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+
+ if (!mt7996_band_valid(dev, band) || band == MT_BAND0)
+ return 0;
+@@ -541,8 +542,10 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+ if (phy)
+ return 0;
+
+- if (band == MT_BAND2 && dev->hif2)
++ if (band == MT_BAND2 && dev->hif2) {
+ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++ wed = &dev->mt76.mmio.wed_ext;
++ }
+
+ mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7996_ops, band);
+ if (!mphy)
+@@ -576,10 +579,11 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy,
+
+ /* init wiphy according to mphy and phy */
+ mt7996_init_wiphy(mphy->hw);
+- ret = mt76_connac_init_tx_queues(phy->mt76,
+- MT_TXQ_ID(band),
+- MT7996_TX_RING_SIZE,
+- MT_TXQ_RING_BASE(band) + hif1_ofs, 0);
++ ret = mt7996_init_tx_queues(mphy->priv,
++ MT_TXQ_ID(band),
++ MT7996_TX_RING_SIZE,
++ MT_TXQ_RING_BASE(band) + hif1_ofs,
++ wed);
+ if (ret)
+ goto error;
+
+@@ -1119,6 +1123,13 @@ int mt7996_register_device(struct mt7996_dev *dev)
+
+ ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
+
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
++ mt76_wr(dev, MT_INT1_MASK_CSR,
++ dev->mt76.mmio.irqmask|MT_INT_TX_DONE_BAND2);
++ mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
++ dev->mt76.mmio.irqmask |MT_INT_TX_DONE_BAND2);
++ }
++
+ dev->recovery.hw_init_done = true;
+
+ ret = mt7996_init_debugfs(&dev->phy);
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 993b43ce..fc2d9269 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1175,6 +1175,29 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ return 0;
+ }
+
++u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
++{
++ struct mt76_connac_fw_txp *txp = ptr + MT_TXD_SIZE;
++ __le32 *txwi = ptr;
++ u32 val;
++
++ memset(ptr, 0, MT_TXD_SIZE + sizeof(*txp));
++
++ val = FIELD_PREP(MT_TXD0_TX_BYTES, MT_TXD_SIZE) |
++ FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CT);
++ txwi[0] = cpu_to_le32(val);
++
++ val = BIT(31) |
++ FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3);
++ txwi[1] = cpu_to_le32(val);
++
++ txp->token = cpu_to_le16(token_id);
++ txp->nbuf = 1;
++ txp->buf[0] = cpu_to_le32(phys + MT_TXD_SIZE + sizeof(*txp));
++
++ return MT_TXD_SIZE + sizeof(*txp);
++}
++
+ static void
+ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
+ {
+@@ -1561,6 +1584,10 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+
+ switch (type) {
+ case PKT_TYPE_TXRX_NOTIFY:
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext) &&
++ q == MT_RXQ_TXFREE_BAND2)
++ return;
++
+ mt7996_mac_tx_free(dev, skb->data, skb->len);
+ napi_consume_skb(skb, 1);
+ break;
+@@ -2035,7 +2062,7 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ mt7996_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
+
+ /* enable dma tx/rx and interrupt */
+- __mt7996_dma_enable(dev, false);
++ __mt7996_dma_enable(dev, false, false);
+
+ clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ clear_bit(MT76_RESET, &dev->mphy.state);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index f0bdec6b..50fa6523 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1405,6 +1405,49 @@ out:
+ return ret;
+ }
+
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++static int
++mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct ieee80211_sta *sta,
++ struct net_device_path_ctx *ctx,
++ struct net_device_path *path)
++{
++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
++ struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
++ struct mt7996_dev *dev = mt7996_hw_dev(hw);
++ struct mt7996_phy *phy = mt7996_hw_phy(hw);
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++
++ if(phy != &dev->phy && phy->mt76->band_idx == MT_BAND2)
++ wed = &dev->mt76.mmio.wed_ext;
++
++ if (!mtk_wed_device_active(wed))
++ return -ENODEV;
++
++ if (msta->wcid.idx > MT7996_WTBL_STA)
++ return -EIO;
++
++ path->type = DEV_PATH_MTK_WDMA;
++ path->dev = ctx->dev;
++ path->mtk_wdma.wdma_idx = wed->wdma_idx;
++ path->mtk_wdma.bss = mvif->mt76.idx;
++ path->mtk_wdma.queue = 0;
++ path->mtk_wdma.wcid = msta->wcid.idx;
++
++ /* pao info */
++ if (mtk_wed_device_support_pao(wed)) {
++ path->mtk_wdma.amsdu_en = 1;
++ path->mtk_wdma.is_sp = 0;
++ path->mtk_wdma.is_fixedrate = 0;
++ }
++ ctx->dev = NULL;
++
++ return 0;
++}
++
++#endif
++
+ const struct ieee80211_ops mt7996_ops = {
+ .tx = mt7996_tx,
+ .start = mt7996_start,
+@@ -1451,4 +1494,7 @@ const struct ieee80211_ops mt7996_ops = {
+ .sta_add_debugfs = mt7996_sta_add_debugfs,
+ #endif
+ .set_radar_background = mt7996_set_radar_background,
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++ .net_fill_forward_path = mt7996_net_fill_forward_path,
++#endif
+ };
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 3a591a7b..b9e47e73 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -10,6 +10,11 @@
+ #include "mt7996.h"
+ #include "mac.h"
+ #include "../trace.h"
++#include "../dma.h"
++
++
++static bool wed_enable = true;
++module_param(wed_enable, bool, 0644);
+
+ static const struct __base mt7996_reg_base[] = {
+ [WF_AGG_BASE] = { { 0x820e2000, 0x820f2000, 0x830e2000 } },
+@@ -191,6 +196,228 @@ static u32 mt7996_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
+ return dev->bus_ops->rmw(mdev, __mt7996_reg_addr(dev, offset), mask, val);
+ }
+
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++static void mt7996_mmio_wed_release_rx_buf(struct mtk_wed_device *wed)
++{
++ struct mt7996_dev *dev;
++ struct page *page;
++ int i;
++
++ dev = container_of(wed, struct mt7996_dev, mt76.mmio.wed);
++ for (i = 0; i < dev->mt76.rx_token_size; i++) {
++ struct mt76_rxwi_cache *r;
++
++ r = mt76_rx_token_release(&dev->mt76, i);
++ if (!r || !r->ptr)
++ continue;
++
++ dma_unmap_single(dev->mt76.dma_dev, r->dma_addr,
++ wed->wlan.rx_size, DMA_FROM_DEVICE);
++ skb_free_frag(r->ptr);
++ r->ptr = NULL;
++
++ mt76_put_rxwi(&dev->mt76, r);
++ }
++
++ mt76_free_pending_rxwi(&dev->mt76);
++
++ mt76_for_each_q_rx(&dev->mt76, i) {
++ struct mt76_queue *q = &dev->mt76.q_rx[i];
++
++ if (mt76_queue_is_wed_rx(q)) {
++ if (!q->rx_page.va)
++ continue;
++
++ 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));
++ }
++ }
++
++ 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 mt7996_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size)
++{
++ struct mtk_rxbm_desc *desc = wed->rx_buf_ring.desc;
++ struct mt7996_dev *dev;
++ u32 length;
++ int i;
++
++ dev = container_of(wed, struct mt7996_dev, mt76.mmio.wed);
++ length = SKB_DATA_ALIGN(NET_SKB_PAD + wed->wlan.rx_size +
++ sizeof(struct skb_shared_info));
++
++ for (i = 0; i < size; i++) {
++ struct mt76_rxwi_cache *r = mt76_get_rxwi(&dev->mt76);
++ dma_addr_t phy_addr;
++ int token;
++ void *ptr;
++
++ ptr = page_frag_alloc(&wed->rx_buf_ring.rx_page, length,
++ GFP_KERNEL);
++ if (!ptr) {
++ mt76_put_rxwi(&dev->mt76, r);
++ goto unmap;
++ }
++
++ 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);
++ mt76_put_rxwi(&dev->mt76, r);
++ goto unmap;
++ }
++
++ desc->buf0 = cpu_to_le32(phy_addr);
++ token = mt76_rx_token_consume(&dev->mt76, ptr, r, 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);
++ mt76_put_rxwi(&dev->mt76, r);
++ goto unmap;
++ }
++
++ desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN,
++ token));
++ desc++;
++ }
++
++ return 0;
++
++unmap:
++ mt7996_mmio_wed_release_rx_buf(wed);
++ return -ENOMEM;
++}
++#endif
++
++int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
++ bool hif2, int *irq)
++{
++#ifdef CONFIG_NET_MEDIATEK_SOC_WED
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++ struct pci_dev *pci_dev = pdev_ptr;
++ u32 hif1_ofs = 0;
++ int ret;
++
++ if (!wed_enable)
++ return 0;
++
++ dev->rro_support = true;
++
++ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++ if (hif2)
++ wed = &dev->mt76.mmio.wed_ext;
++
++ wed->wlan.pci_dev = pci_dev;
++ wed->wlan.bus_type = MTK_WED_BUS_PCIE;
++
++ wed->wlan.base = devm_ioremap(dev->mt76.dev,
++ pci_resource_start(pci_dev, 0),
++ pci_resource_len(pci_dev, 0));
++ wed->wlan.phy_base = pci_resource_start(pci_dev, 0);
++
++ if (hif2) {
++ wed->wlan.wpdma_int = wed->wlan.phy_base +
++ MT_INT_PCIE1_SOURCE_CSR_EXT;
++ wed->wlan.wpdma_mask = wed->wlan.phy_base +
++ MT_INT_PCIE1_MASK_CSR;
++ wed->wlan.wpdma_tx = wed->wlan.phy_base + hif1_ofs +
++ MT_TXQ_RING_BASE(0) +
++ MT7996_TXQ_BAND2 * MT_RING_SIZE;
++ if (dev->rro_support) {
++ wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
++ MT_RXQ_RING_BASE(0) +
++ MT7996_RXQ_TXFREE2 * MT_RING_SIZE;
++ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_EXT) - 1;
++ } else {
++ wed->wlan.wpdma_txfree = wed->wlan.phy_base + hif1_ofs +
++ MT_RXQ_RING_BASE(0) +
++ MT7996_RXQ_MCU_WA_TRI * MT_RING_SIZE;
++ wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
++ }
++
++ wed->wlan.chip_id = 0x7991;
++ wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
++ } else {
++ wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
++ wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
++ wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
++ MT7996_TXQ_BAND0 * MT_RING_SIZE;
++
++ wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + MT_WFDMA0_GLO_CFG;
++
++ wed->wlan.wpdma_rx = wed->wlan.phy_base +
++ MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
++ MT7996_RXQ_BAND0 * MT_RING_SIZE;
++
++ wed->wlan.rx_nbuf = 65536;
++ wed->wlan.rx_npkt = 24576;
++ wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
++
++ wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
++ wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
++
++ wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
++ wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
++ if (dev->rro_support) {
++ wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
++ MT7996_RXQ_TXFREE0 * MT_RING_SIZE;
++ wed->wlan.txfree_tbit = ffs(MT_INT_RX_TXFREE_MAIN) - 1;
++ } else {
++ wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_MAIN) - 1;
++ wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
++ MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
++ }
++ }
++
++ wed->wlan.nbuf = 16384;
++
++ wed->wlan.token_start = 0;
++
++ wed->wlan.max_amsdu_nums = 8;
++ wed->wlan.max_amsdu_len = 1536;
++
++ wed->wlan.init_buf = mt7996_wed_init_buf;
++ wed->wlan.offload_enable = NULL;
++ wed->wlan.offload_disable = NULL;
++ wed->wlan.init_rx_buf = mt7996_mmio_wed_init_rx_buf;
++ wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
++ wed->wlan.update_wo_rx_stats = NULL;
++
++ dev->mt76.rx_token_size += wed->wlan.rx_npkt;
++
++ if (mtk_wed_device_attach(wed))
++ return 0;
++
++ *irq = wed->irq;
++ dev->mt76.dma_dev = wed->dev;
++
++ dev->mt76.token_size = 1024;
++
++ ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32));
++ if (ret)
++ return ret;
++
++ ret = dma_set_coherent_mask(wed->dev, DMA_BIT_MASK(32));
++ if (ret)
++ return ret;
++
++ return 1;
++#else
++ return 0;
++#endif
++}
++
+ static int mt7996_mmio_init(struct mt76_dev *mdev,
+ void __iomem *mem_base,
+ u32 device_id)
+@@ -241,8 +468,17 @@ void mt7996_dual_hif_set_irq_mask(struct mt7996_dev *dev, bool write_reg,
+ mdev->mmio.irqmask |= set;
+
+ if (write_reg) {
+- mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
+- mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
++ if (mtk_wed_device_active(&mdev->mmio.wed)) {
++ mtk_wed_device_irq_set_mask(&mdev->mmio.wed,
++ mdev->mmio.irqmask);
++ if (mtk_wed_device_active(&mdev->mmio.wed_ext)) {
++ mtk_wed_device_irq_set_mask(&mdev->mmio.wed_ext,
++ mdev->mmio.irqmask);
++ }
++ } else {
++ mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
++ mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
++ }
+ }
+
+ spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
+@@ -260,22 +496,36 @@ static void mt7996_rx_poll_complete(struct mt76_dev *mdev,
+ static void mt7996_irq_tasklet(struct tasklet_struct *t)
+ {
+ struct mt7996_dev *dev = from_tasklet(dev, t, mt76.irq_tasklet);
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++ struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
+ u32 i, intr, mask, intr1;
+
+- mt76_wr(dev, MT_INT_MASK_CSR, 0);
+- if (dev->hif2)
+- mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+-
+- intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
+- intr &= dev->mt76.mmio.irqmask;
+- mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+-
+- if (dev->hif2) {
+- intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
+- intr1 &= dev->mt76.mmio.irqmask;
+- mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
++ if (dev->hif2 && mtk_wed_device_active(wed_ext)) {
++ mtk_wed_device_irq_set_mask(wed_ext, 0);
++ intr1 = mtk_wed_device_irq_get(wed_ext,
++ dev->mt76.mmio.irqmask);
++ if (intr1 & MT_INT_RX_TXFREE_EXT)
++ napi_schedule(&dev->mt76.napi[MT_RXQ_TXFREE_BAND2]);
++ }
+
+- intr |= intr1;
++ if (mtk_wed_device_active(wed)) {
++ mtk_wed_device_irq_set_mask(wed, 0);
++ intr = mtk_wed_device_irq_get(wed, dev->mt76.mmio.irqmask);
++ intr |= (intr1 & ~MT_INT_RX_TXFREE_EXT);
++ } else {
++ mt76_wr(dev, MT_INT_MASK_CSR, 0);
++ if (dev->hif2)
++ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
++
++ intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
++ intr &= dev->mt76.mmio.irqmask;
++ mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
++ if (dev->hif2) {
++ intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
++ intr1 &= dev->mt76.mmio.irqmask;
++ mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
++ intr |= intr1;
++ }
+ }
+
+ trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
+@@ -307,10 +557,19 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
+ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
+ {
+ struct mt7996_dev *dev = dev_instance;
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+
+- mt76_wr(dev, MT_INT_MASK_CSR, 0);
+- if (dev->hif2)
+- mt76_wr(dev, MT_INT1_MASK_CSR, 0);
++ if (mtk_wed_device_active(wed))
++ mtk_wed_device_irq_set_mask(wed, 0);
++ else
++ mt76_wr(dev, MT_INT_MASK_CSR, 0);
++
++ if (dev->hif2) {
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
++ mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed_ext, 0);
++ else
++ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
++ }
+
+ if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
+ return IRQ_NONE;
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index e371964b..43f20da4 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -544,7 +544,9 @@ int mt7996_dma_init(struct mt7996_dev *dev);
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force);
+ void mt7996_dma_prefetch(struct mt7996_dev *dev);
+ void mt7996_dma_cleanup(struct mt7996_dev *dev);
+-void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset);
++int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx,
++ int n_desc, int ring_base, struct mtk_wed_device *wed);
++void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset);
+ void mt7996_init_txpower(struct mt7996_dev *dev,
+ struct ieee80211_supported_band *sband);
+ int mt7996_txbf_init(struct mt7996_dev *dev);
+@@ -732,7 +734,9 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev,
+ void mt7996_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, struct dentry *dir);
+ #endif
+-
++int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
++ bool hif2, int *irq);
++u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id);
+ #ifdef CONFIG_MTK_VENDOR
+ void mt7996_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif);
+ void mt7996_vendor_register(struct mt7996_phy *phy);
+diff --git a/mt7996/pci.c b/mt7996/pci.c
+index c5301050..869f32ac 100644
+--- a/mt7996/pci.c
++++ b/mt7996/pci.c
+@@ -125,15 +125,26 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ mt7996_wfsys_reset(dev);
+ hif2 = mt7996_pci_init_hif2(pdev);
+
+- ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
++ ret = mt7996_mmio_wed_init(dev, pdev, false, &irq);
+ if (ret < 0)
+- goto free_device;
++ goto free_wed_or_irq_vector;
+
+- irq = pdev->irq;
+- ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
++ if (!ret) {
++ ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
++ if (ret < 0)
++ goto free_device;
++ }
++ ret = devm_request_irq(mdev->dev, pdev->irq, mt7996_irq_handler,
+ IRQF_SHARED, KBUILD_MODNAME, dev);
+ if (ret)
+- goto free_irq_vector;
++ goto free_wed_or_irq_vector;
++
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
++ ret = devm_request_irq(mdev->dev, irq, mt7996_irq_handler,
++ IRQF_SHARED, KBUILD_MODNAME "-wed", dev);
++ if (ret)
++ goto free_irq;
++ }
+
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+ /* master switch of PCIe tnterrupt enable */
+@@ -143,16 +154,30 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ hif2_dev = container_of(hif2->dev, struct pci_dev, dev);
+ dev->hif2 = hif2;
+
+- ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
++ ret = mt7996_mmio_wed_init(dev, hif2_dev, true, &irq);
+ if (ret < 0)
+- goto free_hif2;
++ goto free_irq;
++
++ if (!ret) {
++ ret = pci_alloc_irq_vectors(hif2_dev, 1, 1, PCI_IRQ_ALL_TYPES);
++ if (ret < 0)
++ goto free_hif2;
+
+- dev->hif2->irq = hif2_dev->irq;
+- ret = devm_request_irq(mdev->dev, dev->hif2->irq,
+- mt7996_irq_handler, IRQF_SHARED,
+- KBUILD_MODNAME "-hif", dev);
++ dev->hif2->irq = hif2_dev->irq;
++ }
++
++ ret = devm_request_irq(mdev->dev, hif2_dev->irq, mt7996_irq_handler,
++ IRQF_SHARED, KBUILD_MODNAME "-hif", dev);
+ if (ret)
+- goto free_hif2_irq_vector;
++ goto free_hif2;
++
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
++ ret = devm_request_irq(mdev->dev, irq,
++ mt7996_irq_handler, IRQF_SHARED,
++ KBUILD_MODNAME "-wed-hif", dev);
++ if (ret)
++ goto free_hif2_irq_vector;
++ }
+
+ mt76_wr(dev, MT_INT1_MASK_CSR, 0);
+ /* master switch of PCIe tnterrupt enable */
+@@ -168,15 +193,28 @@ static int mt7996_pci_probe(struct pci_dev *pdev,
+ free_hif2_irq:
+ if (dev->hif2)
+ devm_free_irq(mdev->dev, dev->hif2->irq, dev);
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
++ devm_free_irq(mdev->dev, dev->mt76.mmio.wed_ext.irq, dev);
+ free_hif2_irq_vector:
+- if (dev->hif2)
+- pci_free_irq_vectors(hif2_dev);
++ if (dev->hif2) {
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
++ mtk_wed_device_detach(&dev->mt76.mmio.wed_ext);
++ else
++ pci_free_irq_vectors(hif2_dev);
++ }
+ free_hif2:
+ if (dev->hif2)
+ put_device(dev->hif2->dev);
+- devm_free_irq(mdev->dev, irq, dev);
+-free_irq_vector:
+- pci_free_irq_vectors(pdev);
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ devm_free_irq(mdev->dev, dev->mt76.mmio.wed.irq, dev);
++free_irq:
++ devm_free_irq(mdev->dev, pdev->irq, dev);
++free_wed_or_irq_vector:
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ mtk_wed_device_detach(&dev->mt76.mmio.wed);
++ else
++ pci_free_irq_vectors(pdev);
++
+ free_device:
+ mt76_free_device(&dev->mt76);
+
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 6ef905a9..04658639 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -323,6 +323,7 @@ enum base_rev {
+
+ #define MT_WFDMA0_RX_INT_PCIE_SEL MT_WFDMA0(0x154)
+ #define MT_WFDMA0_RX_INT_SEL_RING3 BIT(3)
++#define MT_WFDMA0_RX_INT_SEL_RING6 BIT(6)
+
+ #define MT_WFDMA0_MCU_HOST_INT_ENA MT_WFDMA0(0x1f4)
+
+@@ -367,6 +368,9 @@ enum base_rev {
+ #define MT_WFDMA0_PCIE1_BASE 0xd8000
+ #define MT_WFDMA0_PCIE1(ofs) (MT_WFDMA0_PCIE1_BASE + (ofs))
+
++#define MT_INT_PCIE1_SOURCE_CSR_EXT MT_WFDMA0_PCIE1(0x118)
++#define MT_INT_PCIE1_MASK_CSR MT_WFDMA0_PCIE1(0x11c)
++
+ #define MT_WFDMA0_PCIE1_BUSY_ENA MT_WFDMA0_PCIE1(0x13c)
+ #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0 BIT(0)
+ #define MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1 BIT(1)
+@@ -412,6 +416,7 @@ enum base_rev {
+ #define MT_INT_RX_TXFREE_MAIN BIT(17)
+ #define MT_INT_RX_TXFREE_TRI BIT(15)
+ #define MT_INT_MCU_CMD BIT(29)
++#define MT_INT_RX_TXFREE_EXT BIT(26)
+
+ #define MT_INT_RX(q) (dev->q_int_mask[__RXQ(q)])
+ #define MT_INT_TX_MCU(q) (dev->q_int_mask[(q)])
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
new file mode 100644
index 0000000..8452177
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch
@@ -0,0 +1,1465 @@
+From 0eaa67d2a2558d1366c25e18e43475907903dea4 Mon Sep 17 00:00:00 2001
+From: Bo Jiao <Bo.Jiao@mediatek.com>
+Date: Mon, 6 Feb 2023 13:50:56 +0800
+Subject: [PATCH 2004/2008] wifi: mt76: mt7996: wed: add wed3.0 rx support
+
+add hardware rro support, This is the preliminary patch for WED3.0 support.
+
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Change-Id: I7e113b1392bcf085ec02c8a44ffbb7cf7c3fa027
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ dma.c | 197 +++++++++++++++++++++++++++++++++++++-----------
+ dma.h | 12 +++
+ mac80211.c | 1 +
+ mt76.h | 63 ++++++++++++++--
+ mt7996/dma.c | 163 +++++++++++++++++++++++++++++++++------
+ mt7996/init.c | 124 +++++++++++++++++++++++++++++-
+ mt7996/mac.c | 42 +++++++++--
+ mt7996/mcu.c | 8 +-
+ mt7996/mmio.c | 36 +++++++--
+ mt7996/mt7996.h | 58 ++++++++++++++
+ mt7996/regs.h | 63 +++++++++++++++-
+ 11 files changed, 675 insertions(+), 92 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index 930ec768..e5b4d898 100644
+--- a/dma.c
++++ b/dma.c
+@@ -193,46 +193,65 @@ EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi);
+ static void
+ mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
+ {
++ int ndesc = q->ndesc;
++
++ if (q->flags & MT_QFLAG_MAGIC)
++ ndesc |= MT_DMA_MAGIC_EN;
++
+ Q_WRITE(dev, q, desc_base, q->desc_dma);
+- Q_WRITE(dev, q, ring_size, q->ndesc);
++ Q_WRITE(dev, q, ring_size, ndesc);
+ q->head = Q_READ(dev, q, dma_idx);
+ q->tail = q->head;
+ }
+
+ static void
+-mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
++mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, bool skip)
+ {
+ int i;
+
+ if (!q || !q->ndesc)
+ return;
+
++ if (!q->desc)
++ goto done;
++
+ /* clear descriptors */
+ for (i = 0; i < q->ndesc; i++)
+ q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+
++ if (skip)
++ goto sync;
++
++done:
+ Q_WRITE(dev, q, cpu_idx, 0);
+ Q_WRITE(dev, q, dma_idx, 0);
++sync:
+ 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_queue_buf *buf, void *data,
++ struct mt76_rxwi_cache *rxwi)
+ {
+- struct mt76_desc *desc = &q->desc[q->head];
++ struct mt76_desc *desc;
+ struct mt76_queue_entry *entry = &q->entry[q->head];
+- struct mt76_rxwi_cache *rxwi = NULL;
+ u32 buf1 = 0, ctrl;
+ int idx = q->head;
+ int rx_token;
+
++ if (mt76_queue_is_rro_ind(q))
++ goto done;
++
++ desc = &q->desc[q->head];
+ ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len);
+
+ if (mt76_queue_is_wed_rx(q)) {
+- rxwi = mt76_get_rxwi(dev);
+- if (!rxwi)
+- return -ENOMEM;
++ if (!rxwi) {
++ rxwi = mt76_get_rxwi(dev);
++ if (!rxwi)
++ return -ENOMEM;
++ }
+
+ rx_token = mt76_rx_token_consume(dev, data, rxwi, buf->addr);
+ if (rx_token < 0) {
+@@ -249,6 +268,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q,
+ WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl));
+ WRITE_ONCE(desc->info, 0);
+
++done:
+ entry->dma_addr[0] = buf->addr;
+ entry->dma_len[0] = buf->len;
+ entry->rxwi = rxwi;
+@@ -396,14 +416,15 @@ 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, bool *drop)
++ int *len, u32 *info, bool *more, bool *drop, bool flush)
+ {
+ struct mt76_queue_entry *e = &q->entry[idx];
+ struct mt76_desc *desc = &q->desc[idx];
+ void *buf;
++ u32 ctrl;
+
++ ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+ if (len) {
+- 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);
+ }
+@@ -411,6 +432,12 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ if (info)
+ *info = le32_to_cpu(desc->info);
+
++ if (drop) {
++ *drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A | MT_DMA_CTL_DROP));
++ if (ctrl & MT_DMA_CTL_VER_MASK)
++ *drop = !!(ctrl & MT_DMA_CTL_PN_CHK_FAIL);
++ }
++
+ if (mt76_queue_is_wed_rx(q)) {
+ u32 buf1 = le32_to_cpu(desc->buf1);
+ u32 token = FIELD_GET(MT_DMA_CTL_TOKEN, buf1);
+@@ -423,20 +450,46 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
+ SKB_WITH_OVERHEAD(q->buf_size),
+ DMA_FROM_DEVICE);
+
+- buf = r->ptr;
+- r->dma_addr = 0;
+- r->ptr = NULL;
+-
+- mt76_put_rxwi(dev, r);
+-
+- if (drop) {
+- u32 ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
+-
+- *drop = !!(ctrl & (MT_DMA_CTL_TO_HOST_A |
+- MT_DMA_CTL_DROP));
++ if (flush) {
++ buf = r->ptr;
++ r->dma_addr = 0;
++ r->ptr = NULL;
++
++ mt76_put_rxwi(dev, r);
++ } else {
++ struct mt76_queue_buf qbuf;
++
++ buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++ if (!buf)
++ return NULL;
++
++ memcpy(buf, r->ptr, SKB_WITH_OVERHEAD(q->buf_size));
++
++ r->dma_addr = dma_map_single(dev->dma_dev, r->ptr,
++ SKB_WITH_OVERHEAD(q->buf_size),
++ DMA_FROM_DEVICE);
++ if (unlikely(dma_mapping_error(dev->dma_dev, r->dma_addr))) {
++ skb_free_frag(r->ptr);
++ mt76_put_rxwi(dev, r);
++ return NULL;
++ }
++
++ qbuf.addr = r->dma_addr;
++ qbuf.len = SKB_WITH_OVERHEAD(q->buf_size);
++ qbuf.skip_unmap = false;
++
++ if (mt76_dma_add_rx_buf(dev, q, &qbuf, r->ptr, r) < 0) {
++ dma_unmap_single(dev->dma_dev, r->dma_addr,
++ SKB_WITH_OVERHEAD(q->buf_size),
++ DMA_FROM_DEVICE);
++ skb_free_frag(r->ptr);
++ mt76_put_rxwi(dev, r);
++ return NULL;
++ }
++ }
+
++ if (drop)
+ *drop |= !!(buf1 & MT_DMA_CTL_WO_DROP);
+- }
+ } else {
+ buf = e->buf;
+ e->buf = NULL;
+@@ -458,15 +511,20 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+ if (!q->queued)
+ return NULL;
+
+- if (flush)
+- q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+- else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
+- return NULL;
++ if (q->flags & MT_QFLAG_RRO) {
++ goto done;
++ } else {
++ if (flush)
++ q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE);
++ else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE)))
++ return NULL;
++ }
+
++done:
+ q->tail = (q->tail + 1) % q->ndesc;
+ q->queued--;
+
+- return mt76_dma_get_buf(dev, q, idx, len, info, more, drop);
++ return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush);
+ }
+
+ static int
+@@ -615,7 +673,10 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+
+ while (q->queued < q->ndesc - 1) {
+ struct mt76_queue_buf qbuf;
+- void *buf;
++ void *buf = NULL;
++
++ if (mt76_queue_is_rro_ind(q))
++ goto done;
+
+ buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
+ if (!buf)
+@@ -627,10 +688,11 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ break;
+ }
+
++done:
+ qbuf.addr = addr + offset;
+ qbuf.len = len - offset;
+ qbuf.skip_unmap = false;
+- if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) {
++ if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf, NULL) < 0) {
+ dma_unmap_single(dev->dma_dev, addr, len,
+ DMA_FROM_DEVICE);
+ skb_free_frag(buf);
+@@ -639,7 +701,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+ frames++;
+ }
+
+- if (frames)
++ if (frames || mt76_queue_is_wed_rx(q))
+ mt76_dma_kick_queue(dev, q);
+
+ spin_unlock_bh(&q->lock);
+@@ -652,7 +714,7 @@ 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;
++ u16 flags;
+
+ if (!q || !q->ndesc)
+ return -EINVAL;
+@@ -679,7 +741,7 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ case MT76_WED_Q_TXFREE:
+ /* WED txfree queue needs ring to be initialized before setup */
+ q->flags = 0;
+- mt76_dma_queue_reset(dev, q);
++ mt76_dma_queue_reset(dev, q, false);
+ mt76_dma_rx_fill(dev, q);
+ q->flags = flags;
+
+@@ -688,9 +750,31 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ 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;
++ if (q->flags & MT_QFLAG_RRO) {
++ q->flags &= ~0x1f;
++
++ ring = FIELD_GET(MT_QFLAG_RRO_RING, q->flags);
++ type = FIELD_GET(MT_QFLAG_RRO_TYPE, q->flags);
++ if (type == MT76_RRO_Q_DATA) {
++ mt76_dma_queue_reset(dev, q, true);
++ ret = mtk_wed_device_rro_rx_ring_setup(wed, ring, q->regs);
++ } else if (type == MT76_RRO_Q_MSDU_PG) {
++ mt76_dma_queue_reset(dev, q, true);
++ ret = mtk_wed_device_msdu_pg_rx_ring_setup(wed, ring, q->regs);
++ } else if (type == MT76_RRO_Q_IND) {
++ mt76_dma_queue_reset(dev, q, false);
++ mt76_dma_rx_fill(dev, q);
++ ret = mtk_wed_device_ind_rx_ring_setup(wed, q->regs);
++ }
++ if (type != MT76_RRO_Q_IND) {
++ q->head = q->ndesc - 1;
++ q->queued = q->ndesc - 1;
++ }
++ } else {
++ ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, 0);
++ if (!ret)
++ q->wed_regs = wed->rx_ring[ring].reg_base;
++ }
+ break;
+ default:
+ ret = -EINVAL;
+@@ -719,10 +803,25 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ q->hw_idx = idx;
+
+ size = q->ndesc * sizeof(struct mt76_desc);
++ if (mt76_queue_is_rro_ind(q))
++ size = q->ndesc * sizeof(struct mt76_rro_desc);
++
+ q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
+ if (!q->desc)
+ return -ENOMEM;
+
++ if (mt76_queue_is_rro_ind(q)) {
++ struct mt76_rro_ind *cmd;
++ int i;
++
++ q->rro_desc = (struct mt76_rro_desc *)(q->desc);
++ q->desc = NULL;
++ for (i = 0; i < q->ndesc; i++) {
++ cmd = (struct mt76_rro_ind *) &q->rro_desc[i];
++ cmd->magic_cnt = MT_DMA_IND_CMD_MAGIC_CNT - 1;
++ }
++ }
++
+ size = q->ndesc * sizeof(*q->entry);
+ q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL);
+ if (!q->entry)
+@@ -732,8 +831,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+ if (ret)
+ return ret;
+
+- if (!mt76_queue_is_txfree(q))
+- mt76_dma_queue_reset(dev, q);
++ if (!mtk_wed_device_active(&dev->mmio.wed) ||
++ (!mt76_queue_is_wed_txfree(q) &&
++ !(mtk_wed_get_rx_capa(&dev->mmio.wed) &&
++ q->flags & MT_QFLAG_RRO)))
++ mt76_dma_queue_reset(dev, q, false);
+
+ return 0;
+ }
+@@ -751,13 +853,13 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+ spin_lock_bh(&q->lock);
+
+ do {
++ if (q->flags & MT_QFLAG_RRO)
++ break;
++
+ buf = mt76_dma_dequeue(dev, q, true, NULL, NULL, &more, NULL);
+ if (!buf)
+ break;
+
+- if (q->flags & MT_QFLAG_RRO)
+- continue;
+-
+ skb_free_frag(buf);
+ } while (1);
+
+@@ -768,8 +870,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+
+ spin_unlock_bh(&q->lock);
+
+- if (((q->flags & MT_QFLAG_WED) &&
+- FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) ||
++ if (mt76_queue_is_wed_rx(q) ||
+ (q->flags & MT_QFLAG_RRO))
+ return;
+
+@@ -790,9 +891,13 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+ if (!q->ndesc)
+ return;
+
++ if (!q->desc)
++ goto done;
++
+ for (i = 0; i < q->ndesc; i++)
+ q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE);
+
++done:
+ mt76_dma_rx_cleanup(dev, q);
+
+ /* reset WED rx queues */
+@@ -839,8 +944,8 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+ bool check_ddone = false;
+ bool more;
+
+- if (IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
+- q->flags == MT_WED_Q_TXFREE) {
++ if ((IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) &&
++ q->flags == MT_WED_Q_TXFREE)) {
+ dma_idx = Q_READ(dev, q, dma_idx);
+ check_ddone = true;
+ }
+@@ -1002,7 +1107,8 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+ mt76_for_each_q_rx(dev, i) {
+ struct mt76_queue *q = &dev->q_rx[i];
+
+- if (mt76_queue_is_wed_rx(q))
++ if (mtk_wed_device_active(&dev->mmio.wed) &&
++ (q->flags & MT_QFLAG_RRO))
+ continue;
+
+ netif_napi_del(&dev->napi[i]);
+@@ -1014,6 +1120,7 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+
+ if (mtk_wed_device_active(&dev->mmio.wed_ext))
+ mtk_wed_device_detach(&dev->mmio.wed_ext);
++
+ mt76_free_pending_txwi(dev);
+ mt76_free_pending_rxwi(dev);
+ }
+diff --git a/dma.h b/dma.h
+index 1b090d78..48037092 100644
+--- a/dma.h
++++ b/dma.h
+@@ -25,6 +25,13 @@
+ #define MT_DMA_PPE_ENTRY GENMASK(30, 16)
+ #define MT_DMA_INFO_PPE_VLD BIT(31)
+
++#define MT_DMA_CTL_PN_CHK_FAIL BIT(13)
++#define MT_DMA_CTL_VER_MASK BIT(7)
++
++#define MT_DMA_MAGIC_EN BIT(13)
++
++#define MT_DMA_IND_CMD_MAGIC_CNT 8
++
+ #define MT_DMA_HDR_LEN 4
+ #define MT_RX_INFO_LEN 4
+ #define MT_FCE_INFO_LEN 4
+@@ -37,6 +44,11 @@ struct mt76_desc {
+ __le32 info;
+ } __packed __aligned(4);
+
++struct mt76_rro_desc {
++ __le32 buf0;
++ __le32 buf1;
++} __packed __aligned(4);
++
+ enum mt76_qsel {
+ MT_QSEL_MGMT,
+ MT_QSEL_HCCA,
+diff --git a/mac80211.c b/mac80211.c
+index f7578308..3a5755f9 100644
+--- a/mac80211.c
++++ b/mac80211.c
+@@ -727,6 +727,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q)
+ return;
+ }
+ }
++
+ __skb_queue_tail(&dev->rx_skb[q], skb);
+ }
+
+diff --git a/mt76.h b/mt76.h
+index ee0dbdd7..e4351338 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -48,6 +48,18 @@
+
+ #define MT76_TOKEN_FREE_THR 64
+
++#define MT_QFLAG_RRO_RING GENMASK(6, 5)
++#define MT_QFLAG_RRO_TYPE GENMASK(8, 7)
++#define MT_QFLAG_RRO BIT(9)
++#define MT_QFLAG_MAGIC BIT(10)
++
++#define __MT_RRO_Q(_type, _n) (MT_QFLAG_RRO | \
++ FIELD_PREP(MT_QFLAG_RRO_TYPE, _type) | \
++ FIELD_PREP(MT_QFLAG_RRO_RING, _n))
++#define MT_RRO_Q_DATA(_n) __MT_RRO_Q(MT76_RRO_Q_DATA, _n)
++#define MT_RRO_Q_MSDU_PG(_n) __MT_RRO_Q(MT76_RRO_Q_MSDU_PG, _n)
++#define MT_RRO_Q_IND __MT_RRO_Q(MT76_RRO_Q_IND, 0)
++
+ #define MT_QFLAG_WED_RING GENMASK(1, 0)
+ #define MT_QFLAG_WED_TYPE GENMASK(3, 2)
+ #define MT_QFLAG_WED BIT(4)
+@@ -82,6 +94,12 @@ enum mt76_wed_type {
+ MT76_WED_Q_RX,
+ };
+
++enum mt76_RRO_type {
++ MT76_RRO_Q_DATA,
++ MT76_RRO_Q_MSDU_PG,
++ MT76_RRO_Q_IND,
++};
++
+ struct mt76_bus_ops {
+ u32 (*rr)(struct mt76_dev *dev, u32 offset);
+ void (*wr)(struct mt76_dev *dev, u32 offset, u32 val);
+@@ -128,6 +146,16 @@ enum mt76_rxq_id {
+ MT_RXQ_MAIN_WA,
+ MT_RXQ_BAND2,
+ MT_RXQ_BAND2_WA,
++ MT_RXQ_RRO_BAND0,
++ MT_RXQ_RRO_BAND1,
++ MT_RXQ_RRO_BAND2,
++ MT_RXQ_MSDU_PAGE_BAND0,
++ MT_RXQ_MSDU_PAGE_BAND1,
++ MT_RXQ_MSDU_PAGE_BAND2,
++ MT_RXQ_TXFREE_BAND0,
++ MT_RXQ_TXFREE_BAND1,
++ MT_RXQ_TXFREE_BAND2,
++ MT_RXQ_RRO_IND,
+ __MT_RXQ_MAX
+ };
+
+@@ -206,6 +234,7 @@ struct mt76_queue {
+ spinlock_t lock;
+ spinlock_t cleanup_lock;
+ struct mt76_queue_entry *entry;
++ struct mt76_rro_desc *rro_desc;
+ struct mt76_desc *desc;
+
+ u16 first;
+@@ -219,8 +248,8 @@ struct mt76_queue {
+
+ u8 buf_offset;
+ u8 hw_idx;
+- u8 flags;
+-
++ u8 magic_cnt;
++ u32 flags;
+ u32 wed_regs;
+
+ dma_addr_t desc_dma;
+@@ -274,7 +303,7 @@ struct mt76_queue_ops {
+
+ void (*kick)(struct mt76_dev *dev, struct mt76_queue *q);
+
+- void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q);
++ void (*reset_q)(struct mt76_dev *dev, struct mt76_queue *q, bool skip);
+ };
+
+ enum mt76_phy_type {
+@@ -369,6 +398,17 @@ struct mt76_txq {
+ bool aggr;
+ };
+
++struct mt76_rro_ind {
++ u32 se_id : 12;
++ u32 rsv : 4;
++ u32 start_sn : 12;
++ u32 ind_reason : 4;
++ u32 ind_cnt : 13;
++ u32 win_sz : 3;
++ u32 rsv2 : 13;
++ u32 magic_cnt : 3;
++};
++
+ struct mt76_txwi_cache {
+ struct list_head list;
+ dma_addr_t dma_addr;
+@@ -1516,12 +1556,19 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q)
+ return (q->flags & MT_QFLAG_WED) &&
+ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX;
+ }
+-static inline bool mt76_queue_is_txfree(struct mt76_queue *q)
++
++static inline bool mt76_queue_is_wed_txfree(struct mt76_queue *q)
+ {
+ return (q->flags & MT_QFLAG_WED) &&
+ FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_TXFREE;
+ }
+
++static inline bool mt76_queue_is_rro_ind(struct mt76_queue *q)
++{
++ return (q->flags & MT_QFLAG_RRO) &&
++ FIELD_GET(MT_QFLAG_RRO_TYPE, q->flags) == MT76_RRO_Q_IND;
++}
++
+ struct mt76_txwi_cache *
+ mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
+ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
+@@ -1540,10 +1587,14 @@ static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
+ static inline int
+ mt76_token_get(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi)
+ {
+- int token;
++ int token, start = 0;
++
++ if (mtk_wed_device_active(&dev->mmio.wed))
++ start = dev->mmio.wed.wlan.nbuf;
+
+ spin_lock_bh(&dev->token_lock);
+- token = idr_alloc(&dev->token, *ptxwi, 0, dev->token_size, GFP_ATOMIC);
++ token = idr_alloc(&dev->token, *ptxwi, start, start + dev->token_size,
++ GFP_ATOMIC);
+ spin_unlock_bh(&dev->token_lock);
+
+ return token;
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index 673b08bb..c5c7f160 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -64,6 +64,29 @@ static void mt7996_dma_config(struct mt7996_dev *dev)
+ RXQ_CONFIG(MT_RXQ_BAND2, WFDMA0, MT_INT_RX_DONE_BAND2, MT7996_RXQ_BAND2);
+ RXQ_CONFIG(MT_RXQ_BAND2_WA, WFDMA0, MT_INT_RX_DONE_WA_TRI, MT7996_RXQ_MCU_WA_TRI);
+
++ if (dev->rro_support) {
++ /* band0 */
++ RXQ_CONFIG(MT_RXQ_RRO_BAND0, WFDMA0, MT_INT_RX_DONE_RRO_BAND0,
++ MT7996_RXQ_RRO_BAND0);
++ RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND0, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND0,
++ MT7996_RXQ_MSDU_PG_BAND0);
++ RXQ_CONFIG(MT_RXQ_TXFREE_BAND0, WFDMA0, MT_INT_RX_TXFREE_MAIN,
++ MT7996_RXQ_TXFREE0);
++ /* band1 */
++ RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND1, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND1,
++ MT7996_RXQ_MSDU_PG_BAND1);
++ /* band2 */
++ RXQ_CONFIG(MT_RXQ_RRO_BAND2, WFDMA0, MT_INT_RX_DONE_RRO_BAND2,
++ MT7996_RXQ_RRO_BAND2);
++ RXQ_CONFIG(MT_RXQ_MSDU_PAGE_BAND2, WFDMA0, MT_INT_RX_DONE_MSDU_PG_BAND2,
++ MT7996_RXQ_MSDU_PG_BAND2);
++ RXQ_CONFIG(MT_RXQ_TXFREE_BAND2, WFDMA0, MT_INT_RX_TXFREE_TRI,
++ MT7996_RXQ_TXFREE2);
++
++ RXQ_CONFIG(MT_RXQ_RRO_IND, WFDMA0, MT_INT_RX_DONE_RRO_IND,
++ MT7996_RXQ_RRO_IND);
++ }
++
+ /* data tx queue */
+ TXQ_CONFIG(0, WFDMA0, MT_INT_TX_DONE_BAND0, MT7996_TXQ_BAND0);
+ TXQ_CONFIG(1, WFDMA0, MT_INT_TX_DONE_BAND1, MT7996_TXQ_BAND1);
+@@ -91,6 +114,22 @@ static void __mt7996_dma_prefetch(struct mt7996_dev *dev, u32 ofs)
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2_WA) + ofs, PREFETCH(0x180, 0x2));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MAIN) + ofs, PREFETCH(0x1a0, 0x10));
+ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_BAND2) + ofs, PREFETCH(0x2a0, 0x10));
++ if (dev->rro_support) {
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND0) + ofs,
++ PREFETCH(0x3a0, 0x10));
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_RRO_BAND2) + ofs,
++ PREFETCH(0x4a0, 0x10));
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND0) + ofs,
++ PREFETCH(0x5a0, 0x4));
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND1) + ofs,
++ PREFETCH(0x5e0, 0x4));
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_MSDU_PAGE_BAND2) + ofs,
++ PREFETCH(0x620, 0x4));
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND0) + ofs,
++ PREFETCH(0x660, 0x2));
++ mt76_wr(dev, MT_RXQ_BAND1_CTRL(MT_RXQ_TXFREE_BAND2) + ofs,
++ PREFETCH(0x680, 0x2));
++ }
+
+ mt76_set(dev, WF_WFDMA0_GLO_CFG_EXT1 + ofs, WF_WFDMA0_GLO_CFG_EXT1_CALC_MODE);
+ }
+@@ -149,6 +188,7 @@ static void mt7996_dma_disable(struct mt7996_dev *dev, bool reset)
+
+ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+ {
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+ u32 hif1_ofs = 0;
+ u32 irq_mask;
+
+@@ -157,11 +197,16 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+
+ /* enable wpdma tx/rx */
+ if (!reset) {
+- mt76_set(dev, MT_WFDMA0_GLO_CFG,
+- MT_WFDMA0_GLO_CFG_TX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_RX_DMA_EN |
+- MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
+- MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
++ if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
++ mt76_set(dev, MT_WFDMA0_GLO_CFG,
++ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO);
++ else
++ mt76_set(dev, MT_WFDMA0_GLO_CFG,
++ MT_WFDMA0_GLO_CFG_TX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_RX_DMA_EN |
++ MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
++ MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
+
+ if (dev->hif2)
+ mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
+@@ -173,8 +218,8 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+
+ /* enable interrupts for TX/RX rings */
+ irq_mask = MT_INT_MCU_CMD |
+- MT_INT_RX_DONE_MCU |
+- MT_INT_TX_DONE_MCU;
++ MT_INT_RX_DONE_MCU |
++ MT_INT_TX_DONE_MCU;
+
+ if (mt7996_band_valid(dev, MT_BAND0))
+ irq_mask |= MT_INT_BAND0_RX_DONE;
+@@ -185,14 +230,14 @@ void __mt7996_dma_enable(struct mt7996_dev *dev, bool reset, bool wed_reset)
+ if (mt7996_band_valid(dev, MT_BAND2))
+ irq_mask |= MT_INT_BAND2_RX_DONE;
+
+- if (mtk_wed_device_active(&dev->mt76.mmio.wed) && wed_reset) {
++ if (mtk_wed_device_active(wed) && wed_reset) {
+ u32 wed_irq_mask = irq_mask;
+
+ wed_irq_mask |= MT_INT_TX_DONE_BAND0 | MT_INT_TX_DONE_BAND1;
+
+ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
+
+- mtk_wed_device_start(&dev->mt76.mmio.wed, wed_irq_mask);
++ mtk_wed_device_start(wed, wed_irq_mask);
+ }
+
+ irq_mask = reset ? MT_INT_MCU_CMD : irq_mask;
+@@ -269,7 +314,8 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ /* fix hardware limitation, pcie1's rx ring3 is not available
+ * so, redirect pcie0 rx ring3 interrupt to pcie1
+ */
+- if (mtk_wed_device_active(&dev->mt76.mmio.wed) && dev->rro_support)
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ dev->rro_support)
+ mt76_set(dev, MT_WFDMA0_RX_INT_PCIE_SEL + hif1_ofs,
+ MT_WFDMA0_RX_INT_SEL_RING6);
+ else
+@@ -282,6 +328,78 @@ static int mt7996_dma_enable(struct mt7996_dev *dev, bool reset)
+ return 0;
+ }
+
++int mt7996_dma_rro_init(struct mt7996_dev *dev)
++{
++ int ret;
++ u32 hif1_ofs = 0;
++ u32 wed_irq_mask;
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++
++ if (dev->hif2)
++ hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++
++ /* ind cmd */
++ dev->mt76.q_rx[MT_RXQ_RRO_IND].flags = MT_RRO_Q_IND | MT_WED_Q_RX(0);
++ dev->mt76.q_rx[MT_RXQ_RRO_IND].flags |= MT_WED_Q_RX(0);
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_IND],
++ MT_RXQ_ID(MT_RXQ_RRO_IND),
++ MT7996_RX_RING_SIZE,
++ 0, MT_RXQ_RRO_IND_RING_BASE);
++ if (ret)
++ return ret;
++
++ /* rx msdu page queue for band0 */
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags = MT_RRO_Q_MSDU_PG(0);
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags |= MT_QFLAG_MAGIC;
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0].flags |= MT_WED_Q_RX(0);
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND0],
++ MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND0),
++ MT7996_RX_RING_SIZE,
++ MT7996_RX_MSDU_PAGE_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND0));
++ if (ret)
++ return ret;
++
++ if (mt7996_band_valid(dev, MT_BAND1)) {
++ /* rx msdu page queue for band1 */
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags = MT_RRO_Q_MSDU_PG(1);
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags |= MT_QFLAG_MAGIC;
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1].flags |= MT_WED_Q_RX(1);
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND1],
++ MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND1),
++ MT7996_RX_RING_SIZE,
++ MT7996_RX_MSDU_PAGE_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND1));
++ if (ret)
++ return ret;
++ }
++
++ if (mt7996_band_valid(dev, MT_BAND2)) {
++ /* rx msdu page queue for band2 */
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags = MT_RRO_Q_MSDU_PG(2);
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags |= MT_QFLAG_MAGIC;
++ dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2].flags |= MT_WED_Q_RX(0);
++ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MSDU_PAGE_BAND2],
++ MT_RXQ_ID(MT_RXQ_MSDU_PAGE_BAND2),
++ MT7996_RX_RING_SIZE,
++ MT7996_RX_MSDU_PAGE_SIZE,
++ MT_RXQ_RING_BASE(MT_RXQ_MSDU_PAGE_BAND2));
++ if (ret)
++ return ret;
++ }
++
++ wed_irq_mask = dev->mt76.mmio.irqmask |
++ MT_INT_RRO_RX_DONE |
++ MT_INT_TX_DONE_BAND2;
++
++ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++
++ mtk_wed_device_start_hwrro(wed, wed_irq_mask, false);
++ mt7996_irq_enable(dev, wed_irq_mask);
++
++ return 0;
++}
++
+ int mt7996_dma_init(struct mt7996_dev *dev)
+ {
+ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+@@ -351,6 +469,9 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ return ret;
+
+ /* rx data queue for band0 and band1 */
++ if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed))
++ dev->mt76.q_rx[MT_RXQ_MAIN].flags = MT_WED_Q_RX(0);
++
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
+ MT_RXQ_ID(MT_RXQ_MAIN),
+ MT7996_RX_RING_SIZE,
+@@ -374,9 +495,6 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx data queue for band2 */
+ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
+- if (mtk_wed_device_active(wed))
+- rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
+-
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ MT_RXQ_ID(MT_RXQ_BAND2),
+ MT7996_RX_RING_SIZE,
+@@ -400,11 +518,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ return ret;
+ }
+
+-
+- if (dev->rro_support) {
++ if (mtk_wed_device_active(wed) && mtk_wed_get_rx_capa(wed) &&
++ dev->rro_support) {
+ /* rx rro data queue for band0 */
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags = MT_RRO_Q_DATA(0);
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_QFLAG_MAGIC;
++ dev->mt76.q_rx[MT_RXQ_RRO_BAND0].flags |= MT_WED_Q_RX(0);
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND0],
+ MT_RXQ_ID(MT_RXQ_RRO_BAND0),
+ MT7996_RX_RING_SIZE,
+@@ -414,8 +533,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ return ret;
+
+ /* tx free notify event from WA for band0 */
+- if (mtk_wed_device_active(wed))
+- dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
++ dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0].flags = MT_WED_Q_TXFREE;
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_TXFREE_BAND0],
+ MT_RXQ_ID(MT_RXQ_TXFREE_BAND0),
+ MT7996_RX_MCU_RING_SIZE,
+@@ -428,6 +546,7 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ /* rx rro data queue for band2 */
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags = MT_RRO_Q_DATA(1);
+ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_QFLAG_MAGIC;
++ dev->mt76.q_rx[MT_RXQ_RRO_BAND2].flags |= MT_WED_Q_RX(1);
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_RRO_BAND2],
+ MT_RXQ_ID(MT_RXQ_RRO_BAND2),
+ MT7996_RX_RING_SIZE,
+@@ -505,18 +624,18 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+
+ /* reset hw queues */
+ for (i = 0; i < __MT_TXQ_MAX; i++) {
+- mt76_queue_reset(dev, dev->mphy.q_tx[i]);
++ mt76_queue_reset(dev, dev->mphy.q_tx[i], false);
+ if (phy2)
+- mt76_queue_reset(dev, phy2->q_tx[i]);
++ mt76_queue_reset(dev, phy2->q_tx[i], false);
+ if (phy3)
+- mt76_queue_reset(dev, phy3->q_tx[i]);
++ mt76_queue_reset(dev, phy3->q_tx[i], false);
+ }
+
+ for (i = 0; i < __MT_MCUQ_MAX; i++)
+- mt76_queue_reset(dev, dev->mt76.q_mcu[i]);
++ mt76_queue_reset(dev, dev->mt76.q_mcu[i], false);
+
+ mt76_for_each_q_rx(&dev->mt76, i) {
+- mt76_queue_reset(dev, &dev->mt76.q_rx[i]);
++ mt76_queue_reset(dev, &dev->mt76.q_rx[i], false);
+ }
+
+ mt76_tx_status_check(&dev->mt76, true);
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 6cfbc50d..d70dcf9f 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -496,8 +496,13 @@ void mt7996_mac_init(struct mt7996_dev *dev)
+
+ /* rro module init */
+ mt7996_mcu_set_rro(dev, UNI_RRO_SET_PLATFORM_TYPE, 2);
+- mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
+- mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
++ if (dev->rro_support) {
++ mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 1);
++ mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 0);
++ } else {
++ mt7996_mcu_set_rro(dev, UNI_RRO_SET_BYPASS_MODE, 3);
++ mt7996_mcu_set_rro(dev, UNI_RRO_SET_TXFREE_PATH, 1);
++ }
+
+ mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
+ MCU_WA_PARAM_HW_PATH_HIF_VER,
+@@ -650,6 +655,114 @@ void mt7996_wfsys_reset(struct mt7996_dev *dev)
+ msleep(20);
+ }
+
++static int mt7996_rro_init(struct mt7996_dev *dev)
++{
++ struct mt7996_rro_addr *ptr;
++ struct mt7996_rro_cfg *rro = &dev->rro;
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++ u32 size, val = 0, reg = MT_RRO_ADDR_ELEM_SEG_ADDR0;
++ int i, j;
++ void *buf;
++
++ for (i = 0; i < MT7996_RRO_BA_BITMAP_CR_CNT; i++) {
++ buf = dmam_alloc_coherent(dev->mt76.dma_dev,
++ MT7996_BA_BITMAP_SZ_PER_CR,
++ &rro->ba_bitmap_cache_pa[i],
++ GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ rro->ba_bitmap_cache_va[i] = buf;
++ }
++
++ rro->win_sz = MT7996_RRO_WIN_SIZE_MAX;
++ for (i = 0; i < MT7996_RRO_ADDR_ELEM_CR_CNT; i++) {
++ size = MT7996_RRO_SESSION_PER_CR *
++ rro->win_sz * sizeof(struct mt7996_rro_addr);
++
++ buf = dmam_alloc_coherent(dev->mt76.dma_dev, size,
++ &rro->addr_elem_alloc_pa[i],
++ GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++ rro->addr_elem_alloc_va[i] = buf;
++
++ memset(rro->addr_elem_alloc_va[i], 0, size);
++
++ ptr = rro->addr_elem_alloc_va[i];
++ for (j = 0; j < MT7996_RRO_SESSION_PER_CR * rro->win_sz; j++, ptr++)
++ ptr->signature = 0xff;
++
++ wed->wlan.ind_cmd.addr_elem_phys[i] = rro->addr_elem_alloc_pa[i];
++ }
++
++ rro->particular_se_id = MT7996_RRO_SESSION_MAX;
++ size = rro->win_sz * sizeof(struct mt7996_rro_addr);
++ buf = dmam_alloc_coherent(dev->mt76.dma_dev, size,
++ &rro->particular_session_pa,
++ GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ rro->particular_session_va = buf;
++ ptr = rro->particular_session_va;
++ for (j = 0; j < rro->win_sz; j++, ptr++)
++ ptr->signature = 0xff;
++
++ INIT_LIST_HEAD(&rro->pg_addr_cache);
++ for (i = 0; i < MT7996_RRO_MSDU_PG_HASH_SIZE; i++)
++ INIT_LIST_HEAD(&rro->pg_hash_head[i]);
++
++ /* rro hw init */
++ /* TODO: remove line after WM has set */
++ mt76_clear(dev, WF_RRO_AXI_MST_CFG, WF_RRO_AXI_MST_CFG_DIDX_OK);
++
++ /* setup BA bitmap cache address */
++ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE0,
++ rro->ba_bitmap_cache_pa[0]);
++ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE1, 0);
++ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT0,
++ rro->ba_bitmap_cache_pa[1]);
++ mt76_wr(dev, MT_RRO_BA_BITMAP_BASE_EXT1, 0);
++
++ /* setup Address element address */
++ for (i = 0; i < MT7996_RRO_ADDR_ELEM_CR_CNT; i++) {
++ mt76_wr(dev, reg, rro->addr_elem_alloc_pa[i] >> 4);
++ reg += 4;
++ }
++
++ /* setup Address element address - separate address segment mode */
++ mt76_wr(dev, MT_RRO_ADDR_ARRAY_BASE1,
++ MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE);
++
++ wed->wlan.ind_cmd.win_size = ffs(rro->win_sz) - 6;
++ wed->wlan.ind_cmd.particular_sid = rro->particular_se_id;
++ wed->wlan.ind_cmd.particular_se_phys = rro->particular_session_pa;
++ wed->wlan.ind_cmd.se_group_nums = MT7996_RRO_ADDR_ELEM_CR_CNT;
++ wed->wlan.ind_cmd.ack_sn_addr = MT_RRO_ACK_SN_CTRL;
++
++ mt76_wr(dev, MT_RRO_IND_CMD_SIGNATURE_BASE0, 0x15010e00);
++ mt76_set(dev, MT_RRO_IND_CMD_SIGNATURE_BASE1,
++ MT_RRO_IND_CMD_SIGNATURE_BASE1_EN);
++
++ /* particular session configure */
++ /* use max session idx + 1 as particular session id */
++ mt76_wr(dev, MT_RRO_PARTICULAR_CFG0,
++ rro->particular_session_pa);
++
++ val = FIELD_PREP(MT_RRO_PARTICULAR_SID,
++ MT7996_RRO_SESSION_MAX);
++ val |= MT_RRO_PARTICULAR_CONFG_EN;
++ mt76_wr(dev, MT_RRO_PARTICULAR_CFG1, val);
++
++ /* interrupt enable */
++ mt76_wr(dev, MT_RRO_HOST_INT_ENA,
++ MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
++
++ /* rro ind cmd queue init */
++ return mt7996_dma_rro_init(dev);
++}
++
+ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ {
+ int ret, idx;
+@@ -677,6 +790,13 @@ static int mt7996_init_hardware(struct mt7996_dev *dev)
+ if (ret)
+ return ret;
+
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ dev->rro_support) {
++ ret = mt7996_rro_init(dev);
++ if (ret)
++ return ret;
++ }
++
+ ret = mt7996_eeprom_init(dev);
+ if (ret < 0)
+ return ret;
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index fc2d9269..4fbbc077 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -614,8 +614,37 @@ mt7996_mac_fill_rx_rate(struct mt7996_dev *dev,
+ return 0;
+ }
+
++static void
++mt7996_wed_check_ppe(struct mt7996_dev *dev, struct mt76_queue *q,
++ struct mt7996_sta *msta, struct sk_buff *skb,
++ u32 info)
++{
++ struct ieee80211_vif *vif;
++ struct wireless_dev *wdev;
++
++ if (!msta || !msta->vif)
++ return;
++
++ if (!mt76_queue_is_wed_rx(q))
++ return;
++
++ if (!(info & MT_DMA_INFO_PPE_VLD))
++ return;
++
++ vif = container_of((void *)msta->vif, struct ieee80211_vif,
++ drv_priv);
++ wdev = ieee80211_vif_to_wdev(vif);
++ skb->dev = wdev->netdev;
++
++ mtk_wed_device_ppe_check(&dev->mt76.mmio.wed, skb,
++ FIELD_GET(MT_DMA_PPE_CPU_REASON, info),
++ FIELD_GET(MT_DMA_PPE_ENTRY, info));
++}
++
++
+ static int
+-mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
++mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
++ struct sk_buff *skb, u32 *info)
+ {
+ struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
+ struct mt76_phy *mphy = &dev->mt76.phy;
+@@ -640,7 +669,10 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ u16 seq_ctrl = 0;
+ __le16 fc = 0;
+ int idx;
++ u8 hw_aggr = false;
++ struct mt7996_sta *msta = NULL;
+
++ hw_aggr = status->aggr;
+ memset(status, 0, sizeof(*status));
+
+ band_idx = FIELD_GET(MT_RXD1_NORMAL_BAND_IDX, rxd1);
+@@ -667,8 +699,6 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ status->wcid = mt7996_rx_get_wcid(dev, idx, unicast);
+
+ if (status->wcid) {
+- struct mt7996_sta *msta;
+-
+ msta = container_of(status->wcid, struct mt7996_sta, wcid);
+ spin_lock_bh(&dev->sta_poll_lock);
+ if (list_empty(&msta->poll_list))
+@@ -871,12 +901,14 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)
+ #endif
+ } else {
+ status->flag |= RX_FLAG_8023;
++ mt7996_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb,
++ *info);
+ }
+
+ if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
+ mt7996_mac_decode_he_radiotap(skb, rxv, mode);
+
+- if (!status->wcid || !ieee80211_is_data_qos(fc))
++ if (!status->wcid || !ieee80211_is_data_qos(fc) || hw_aggr)
+ return 0;
+
+ status->aggr = unicast &&
+@@ -1604,7 +1636,7 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ dev_kfree_skb(skb);
+ break;
+ case PKT_TYPE_NORMAL:
+- if (!mt7996_mac_fill_rx(dev, skb)) {
++ if (!mt7996_mac_fill_rx(dev, q, skb, info)) {
+ mt76_rx(&dev->mt76, q, skb);
+ return;
+ }
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 59f22f6d..1891c0d7 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -949,7 +949,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif)
+ static int
+ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+ struct ieee80211_ampdu_params *params,
+- bool enable, bool tx)
++ bool enable, bool tx, bool rro_enable)
+ {
+ struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
+ struct sta_rec_ba_uni *ba;
+@@ -970,6 +970,8 @@ mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
+ ba->ba_en = enable << params->tid;
+ ba->amsdu = params->amsdu;
+ ba->tid = params->tid;
++ if (rro_enable && !tx && enable)
++ ba->ba_rdd_rro = true;
+
+ return mt76_mcu_skb_send_msg(dev, skb,
+ MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
+@@ -987,7 +989,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
+ msta->wcid.amsdu = false;
+
+ return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
+- enable, true);
++ enable, true, dev->rro_support);
+ }
+
+ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+@@ -998,7 +1000,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev,
+ struct mt7996_vif *mvif = msta->vif;
+
+ return mt7996_mcu_sta_ba(&dev->mt76, &mvif->mt76, params,
+- enable, false);
++ enable, false, dev->rro_support);
+ }
+
+ static void
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index b9e47e73..9960dca7 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -346,9 +346,15 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ wed->wlan.txfree_tbit = ffs(MT_INT_RX_DONE_WA_TRI) - 1;
+ }
+
++ wed->wlan.wpdma_rx_glo = wed->wlan.phy_base + hif1_ofs + MT_WFDMA0_GLO_CFG;
++ wed->wlan.wpdma_rx = wed->wlan.phy_base + hif1_ofs +
++ MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
++ MT7996_RXQ_BAND0 * MT_RING_SIZE;
++
+ wed->wlan.chip_id = 0x7991;
+ wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND2) - 1;
+ } else {
++ wed->wlan.hwrro = dev->rro_support; /* default on */
+ wed->wlan.wpdma_int = wed->wlan.phy_base + MT_INT_SOURCE_CSR;
+ wed->wlan.wpdma_mask = wed->wlan.phy_base + MT_INT_MASK_CSR;
+ wed->wlan.wpdma_tx = wed->wlan.phy_base + MT_TXQ_RING_BASE(0) +
+@@ -360,13 +366,33 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ MT_RXQ_RING_BASE(MT7996_RXQ_BAND0) +
+ MT7996_RXQ_BAND0 * MT_RING_SIZE;
+
++ wed->wlan.wpdma_rx_rro[0] = wed->wlan.phy_base +
++ MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND0) +
++ MT7996_RXQ_RRO_BAND0 * MT_RING_SIZE;
++ wed->wlan.wpdma_rx_rro[1] = wed->wlan.phy_base + hif1_ofs +
++ MT_RXQ_RING_BASE(MT7996_RXQ_RRO_BAND2) +
++ MT7996_RXQ_RRO_BAND2 * MT_RING_SIZE;
++ wed->wlan.wpdma_rx_pg = wed->wlan.phy_base +
++ MT_RXQ_RING_BASE(MT7996_RXQ_MSDU_PG_BAND0) +
++ MT7996_RXQ_MSDU_PG_BAND0 * MT_RING_SIZE;
++
+ wed->wlan.rx_nbuf = 65536;
+ wed->wlan.rx_npkt = 24576;
++ if (dev->hif2)
++ wed->wlan.rx_npkt += 8192;
++
+ wed->wlan.rx_size = SKB_WITH_OVERHEAD(MT_RX_BUF_SIZE);
+
+ wed->wlan.rx_tbit[0] = ffs(MT_INT_RX_DONE_BAND0) - 1;
+ wed->wlan.rx_tbit[1] = ffs(MT_INT_RX_DONE_BAND2) - 1;
+
++ wed->wlan.rro_rx_tbit[0] = ffs(MT_INT_RX_DONE_RRO_BAND0) - 1;
++ wed->wlan.rro_rx_tbit[1] = ffs(MT_INT_RX_DONE_RRO_BAND2) - 1;
++
++ wed->wlan.rx_pg_tbit[0] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND0) - 1;
++ wed->wlan.rx_pg_tbit[1] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND1) - 1;
++ wed->wlan.rx_pg_tbit[2] = ffs(MT_INT_RX_DONE_MSDU_PG_BAND2) - 1;
++
+ wed->wlan.tx_tbit[0] = ffs(MT_INT_TX_DONE_BAND0) - 1;
+ wed->wlan.tx_tbit[1] = ffs(MT_INT_TX_DONE_BAND1) - 1;
+ if (dev->rro_support) {
+@@ -378,6 +404,8 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ wed->wlan.wpdma_txfree = wed->wlan.phy_base + MT_RXQ_RING_BASE(0) +
+ MT7996_RXQ_MCU_WA_MAIN * MT_RING_SIZE;
+ }
++
++ dev->mt76.rx_token_size += wed->wlan.rx_npkt;
+ }
+
+ wed->wlan.nbuf = 16384;
+@@ -394,8 +422,6 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
+ wed->wlan.update_wo_rx_stats = NULL;
+
+- dev->mt76.rx_token_size += wed->wlan.rx_npkt;
+-
+ if (mtk_wed_device_attach(wed))
+ return 0;
+
+@@ -557,10 +583,9 @@ static void mt7996_irq_tasklet(struct tasklet_struct *t)
+ irqreturn_t mt7996_irq_handler(int irq, void *dev_instance)
+ {
+ struct mt7996_dev *dev = dev_instance;
+- struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
+
+- if (mtk_wed_device_active(wed))
+- mtk_wed_device_irq_set_mask(wed, 0);
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ mtk_wed_device_irq_set_mask(&dev->mt76.mmio.wed, 0);
+ else
+ mt76_wr(dev, MT_INT_MASK_CSR, 0);
+
+@@ -592,6 +617,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev,
+ SURVEY_INFO_TIME_RX |
+ SURVEY_INFO_TIME_BSS_RX,
+ .token_size = MT7996_TOKEN_SIZE,
++ .rx_token_size = MT7996_RX_TOKEN_SIZE,
+ .tx_prepare_skb = mt7996_tx_prepare_skb,
+ .tx_complete_skb = mt76_connac_tx_complete_skb,
+ .rx_skb = mt7996_queue_rx_skb,
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 43f20da4..836c7db7 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -39,6 +39,7 @@
+ #define MT7996_EEPROM_SIZE 7680
+ #define MT7996_EEPROM_BLOCK_SIZE 16
+ #define MT7996_TOKEN_SIZE 16384
++#define MT7996_RX_TOKEN_SIZE 16384
+
+ #define MT7996_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
+ #define MT7996_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
+@@ -63,6 +64,24 @@
+ #define MT7996_SKU_RATE_NUM 417
+ #define MT7996_SKU_PATH_NUM 494
+
++#define MT7996_RRO_MSDU_PG_HASH_SIZE 127
++#define MT7996_RRO_SESSION_MAX 1024
++#define MT7996_RRO_WIN_SIZE_MAX 1024
++#define MT7996_RRO_ADDR_ELEM_CR_CNT 128
++#define MT7996_RRO_BA_BITMAP_CR_CNT 2
++#define MT7996_RRO_SESSION_PER_CR (MT7996_RRO_SESSION_MAX / \
++ MT7996_RRO_ADDR_ELEM_CR_CNT)
++#define MT7996_BA_BITMAP_SZ_PER_SESSION 128
++#define MT7996_BA_BITMAP_SZ_PER_CR ((MT7996_RRO_SESSION_MAX * \
++ MT7996_BA_BITMAP_SZ_PER_SESSION) / \
++ MT7996_RRO_BA_BITMAP_CR_CNT)
++#define MT7996_SKB_TRUESIZE(x) ((x) + \
++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
++#define MT7996_RX_BUF_SIZE MT7996_SKB_TRUESIZE(1800)
++#define MT7996_RX_MSDU_PAGE_SIZE MT7996_SKB_TRUESIZE(128)
++
++#define MT7996_WED_RX_TOKEN_SIZE 32768
++
+ struct mt7996_vif;
+ struct mt7996_sta;
+ struct mt7996_dfs_pulse;
+@@ -102,6 +121,16 @@ enum mt7996_rxq_id {
+ MT7996_RXQ_BAND0 = 4,
+ MT7996_RXQ_BAND1 = 4,/* unused */
+ MT7996_RXQ_BAND2 = 5,
++ MT7996_RXQ_RRO_BAND0 = 8,
++ MT7996_RXQ_RRO_BAND1 = 8,/* unused */
++ MT7996_RXQ_RRO_BAND2 = 6,
++ MT7996_RXQ_MSDU_PG_BAND0 = 10,
++ MT7996_RXQ_MSDU_PG_BAND1 = 11,
++ MT7996_RXQ_MSDU_PG_BAND2 = 12,
++ MT7996_RXQ_TXFREE0 = 9,
++ MT7996_RXQ_TXFREE1 = 9,
++ MT7996_RXQ_TXFREE2 = 7,
++ MT7996_RXQ_RRO_IND = 0,
+ };
+
+ struct mt7996_twt_flow {
+@@ -272,6 +301,31 @@ struct mt7996_air_monitor_ctrl {
+ };
+ #endif
+
++struct mt7996_rro_addr {
++ u32 head_pkt_l;
++ u32 head_pkt_h : 4;
++ u32 seg_cnt : 11;
++ u32 out_of_range: 1;
++ u32 rsv : 8;
++ u32 signature : 8;
++};
++
++struct mt7996_rro_cfg {
++ u32 ind_signature;
++ void *ba_bitmap_cache_va[MT7996_RRO_BA_BITMAP_CR_CNT];
++ void *addr_elem_alloc_va[MT7996_RRO_ADDR_ELEM_CR_CNT];
++ void *particular_session_va;
++ u32 particular_se_id;
++ dma_addr_t ba_bitmap_cache_pa[MT7996_RRO_BA_BITMAP_CR_CNT];
++ dma_addr_t addr_elem_alloc_pa[MT7996_RRO_ADDR_ELEM_CR_CNT];
++ dma_addr_t particular_session_pa;
++ u16 win_sz;
++
++ spinlock_t lock;
++ struct list_head pg_addr_cache;
++ struct list_head pg_hash_head[MT7996_RRO_MSDU_PG_HASH_SIZE];
++};
++
+ struct mt7996_phy {
+ struct mt76_phy *mt76;
+ struct mt7996_dev *dev;
+@@ -390,6 +444,9 @@ struct mt7996_dev {
+ bool flash_mode:1;
+ bool has_eht:1;
+
++ bool rro_support:1;
++ struct mt7996_rro_cfg rro;
++
+ bool testmode_enable;
+ bool bin_file_mode;
+ u8 eeprom_mode;
+@@ -709,6 +766,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ struct ieee80211_sta *sta,
+ struct mt76_tx_info *tx_info);
+ void mt7996_tx_token_put(struct mt7996_dev *dev);
++int mt7996_dma_rro_init(struct mt7996_dev *dev);
+ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ struct sk_buff *skb, u32 *info);
+ bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 04658639..6624685e 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -39,6 +39,40 @@ enum base_rev {
+
+ #define __BASE(_id, _band) (dev->reg.base[(_id)].band_base[(_band)])
+
++
++/* RRO TOP */
++#define MT_RRO_TOP_BASE 0xA000
++#define MT_RRO_TOP(ofs) (MT_RRO_TOP_BASE + (ofs))
++
++#define MT_RRO_BA_BITMAP_BASE0 MT_RRO_TOP(0x8)
++#define MT_RRO_BA_BITMAP_BASE1 MT_RRO_TOP(0xC)
++#define WF_RRO_AXI_MST_CFG MT_RRO_TOP(0xB8)
++#define WF_RRO_AXI_MST_CFG_DIDX_OK BIT(12)
++#define MT_RRO_ADDR_ARRAY_BASE1 MT_RRO_TOP(0x34)
++#define MT_RRO_ADDR_ARRAY_ELEM_ADDR_SEG_MODE BIT(31)
++
++#define MT_RRO_IND_CMD_SIGNATURE_BASE0 MT_RRO_TOP(0x38)
++#define MT_RRO_IND_CMD_SIGNATURE_BASE1 MT_RRO_TOP(0x3C)
++#define MT_RRO_IND_CMD_0_CTRL0 MT_RRO_TOP(0x40)
++#define MT_RRO_IND_CMD_SIGNATURE_BASE1_EN BIT(31)
++
++#define MT_RRO_PARTICULAR_CFG0 MT_RRO_TOP(0x5C)
++#define MT_RRO_PARTICULAR_CFG1 MT_RRO_TOP(0x60)
++#define MT_RRO_PARTICULAR_CONFG_EN BIT(31)
++#define MT_RRO_PARTICULAR_SID GENMASK(30, 16)
++
++#define MT_RRO_BA_BITMAP_BASE_EXT0 MT_RRO_TOP(0x70)
++#define MT_RRO_BA_BITMAP_BASE_EXT1 MT_RRO_TOP(0x74)
++#define MT_RRO_HOST_INT_ENA MT_RRO_TOP(0x204)
++#define MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA BIT(0)
++
++#define MT_RRO_ADDR_ELEM_SEG_ADDR0 MT_RRO_TOP(0x400)
++
++#define MT_RRO_ACK_SN_CTRL MT_RRO_TOP(0x50)
++#define MT_RRO_ACK_SN_CTRL_SN_MASK GENMASK(27, 16)
++#define MT_RRO_ACK_SN_CTRL_SESSION_MASK GENMASK(11, 0)
++
++
+ #define MT_MCU_INT_EVENT 0x2108
+ #define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
+ #define MT_MCU_INT_EVENT_DMA_INIT BIT(1)
+@@ -391,6 +425,7 @@ enum base_rev {
+ #define MT_MCUQ_RING_BASE(q) (MT_Q_BASE(q) + 0x300)
+ #define MT_TXQ_RING_BASE(q) (MT_Q_BASE(__TXQ(q)) + 0x300)
+ #define MT_RXQ_RING_BASE(q) (MT_Q_BASE(__RXQ(q)) + 0x500)
++#define MT_RXQ_RRO_IND_RING_BASE MT_RRO_TOP(0x40)
+
+ #define MT_MCUQ_EXT_CTRL(q) (MT_Q_BASE(q) + 0x600 + \
+ MT_MCUQ_ID(q) * 0x4)
+@@ -418,6 +453,15 @@ enum base_rev {
+ #define MT_INT_MCU_CMD BIT(29)
+ #define MT_INT_RX_TXFREE_EXT BIT(26)
+
++#define MT_INT_RX_DONE_RRO_BAND0 BIT(16)
++#define MT_INT_RX_DONE_RRO_BAND1 BIT(16)
++#define MT_INT_RX_DONE_RRO_BAND2 BIT(14)
++#define MT_INT_RX_DONE_RRO_IND BIT(11)
++#define MT_INT_RX_DONE_MSDU_PG_BAND0 BIT(18)
++#define MT_INT_RX_DONE_MSDU_PG_BAND1 BIT(19)
++#define MT_INT_RX_DONE_MSDU_PG_BAND2 BIT(23)
++
++
+ #define MT_INT_RX(q) (dev->q_int_mask[__RXQ(q)])
+ #define MT_INT_TX_MCU(q) (dev->q_int_mask[(q)])
+
+@@ -425,20 +469,31 @@ enum base_rev {
+ MT_INT_RX(MT_RXQ_MCU_WA))
+
+ #define MT_INT_BAND0_RX_DONE (MT_INT_RX(MT_RXQ_MAIN) | \
+- MT_INT_RX(MT_RXQ_MAIN_WA))
++ MT_INT_RX(MT_RXQ_MAIN_WA) | \
++ MT_INT_RX(MT_RXQ_TXFREE_BAND0))
+
+ #define MT_INT_BAND1_RX_DONE (MT_INT_RX(MT_RXQ_BAND1) | \
+ MT_INT_RX(MT_RXQ_BAND1_WA) | \
+- MT_INT_RX(MT_RXQ_MAIN_WA))
++ MT_INT_RX(MT_RXQ_MAIN_WA) | \
++ MT_INT_RX(MT_RXQ_TXFREE_BAND0))
+
+ #define MT_INT_BAND2_RX_DONE (MT_INT_RX(MT_RXQ_BAND2) | \
+ MT_INT_RX(MT_RXQ_BAND2_WA) | \
+- MT_INT_RX(MT_RXQ_MAIN_WA))
++ MT_INT_RX(MT_RXQ_MAIN_WA) | \
++ MT_INT_RX(MT_RXQ_TXFREE_BAND0))
++
++#define MT_INT_RRO_RX_DONE (MT_INT_RX(MT_RXQ_RRO_BAND0) | \
++ MT_INT_RX(MT_RXQ_RRO_BAND1) | \
++ MT_INT_RX(MT_RXQ_RRO_BAND2) | \
++ MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND0) | \
++ MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND1) | \
++ MT_INT_RX(MT_RXQ_MSDU_PAGE_BAND2))
+
+ #define MT_INT_RX_DONE_ALL (MT_INT_RX_DONE_MCU | \
+ MT_INT_BAND0_RX_DONE | \
+ MT_INT_BAND1_RX_DONE | \
+- MT_INT_BAND2_RX_DONE)
++ MT_INT_BAND2_RX_DONE | \
++ MT_INT_RRO_RX_DONE)
+
+ #define MT_INT_TX_DONE_FWDL BIT(26)
+ #define MT_INT_TX_DONE_MCU_WM BIT(27)
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch
new file mode 100644
index 0000000..7fdee4c
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch
@@ -0,0 +1,50 @@
+From e5136e5f940adf55f1e7604960dba89e24a187bb Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 13 Apr 2023 14:12:16 +0800
+Subject: [PATCH 2005/2008] wifi: mt76: mt7996: wed: add mt7996_net_setup_tc to
+ support wifi2wifi offload
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ mt7996/main.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/mt7996/main.c b/mt7996/main.c
+index 50fa6523..cebac4ab 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -1446,6 +1446,24 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw,
+ return 0;
+ }
+
++static int mt7996_net_setup_tc(struct ieee80211_hw *hw,
++ struct ieee80211_vif *vif,
++ struct net_device *ndev,
++ enum tc_setup_type type,
++ void *type_data)
++
++{
++ struct mt7996_dev *dev = mt7996_hw_dev(hw);
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++
++ if (!mtk_wed_device_active(wed))
++ return -ENODEV;
++
++ mtk_wed_device_setup_tc(wed, ndev, type, type_data);
++
++ return 0;
++}
++
+ #endif
+
+ const struct ieee80211_ops mt7996_ops = {
+@@ -1496,5 +1514,6 @@ const struct ieee80211_ops mt7996_ops = {
+ .set_radar_background = mt7996_set_radar_background,
+ #ifdef CONFIG_NET_MEDIATEK_SOC_WED
+ .net_fill_forward_path = mt7996_net_fill_forward_path,
++ .net_setup_tc = mt7996_net_setup_tc,
+ #endif
+ };
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-add-random-early-drop-support.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-add-random-early-drop-support.patch
new file mode 100644
index 0000000..7902639
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2006-wifi-mt76-add-random-early-drop-support.patch
@@ -0,0 +1,144 @@
+From fba98d69dcbbbcbd4cbf61e997637ecead9e55a3 Mon Sep 17 00:00:00 2001
+From: Peter Chiu <chui-hao.chiu@mediatek.com>
+Date: Wed, 19 Apr 2023 18:32:41 +0800
+Subject: [PATCH 2006/2008] wifi: mt76: add random early drop support
+
+---
+ mt7996/mcu.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++--
+ mt7996/mcu.h | 4 ++-
+ mt7996/mt7996.h | 1 +
+ 3 files changed, 79 insertions(+), 3 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 1891c0d7..0c01e90b 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -2933,8 +2933,8 @@ int mt7996_mcu_init_firmware(struct mt7996_dev *dev)
+ if (ret)
+ return ret;
+
+- return mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
+- MCU_WA_PARAM_RED, 0, 0);
++ return mt7996_mcu_red_config(dev,
++ mtk_wed_device_active(&dev->mt76.mmio.wed));
+ }
+
+ int mt7996_mcu_init(struct mt7996_dev *dev)
+@@ -2966,6 +2966,79 @@ out:
+ skb_queue_purge(&dev->mt76.mcu.res_q);
+ }
+
++static int mt7996_mcu_wa_red_config(struct mt7996_dev *dev)
++{
++#define RED_TOKEN_SRC_CNT 4
++#define RED_TOKEN_CONFIG 2
++ struct {
++ __le32 arg0;
++ __le32 arg1;
++ __le32 arg2;
++
++ u8 mode;
++ u8 version;
++ u8 _rsv[4];
++ __le16 len;
++
++ __le16 tcp_offset;
++ __le16 priority_offset;
++ __le16 token_per_src[RED_TOKEN_SRC_CNT];
++ __le16 token_thr_per_src[RED_TOKEN_SRC_CNT];
++
++ u8 _rsv2[604];
++ } __packed req = {
++ .arg0 = cpu_to_le32(MCU_WA_PARAM_RED_CONFIG),
++
++ .mode = RED_TOKEN_CONFIG,
++ .len = cpu_to_le16(sizeof(req) - sizeof(__le32) * 3),
++
++ .tcp_offset = cpu_to_le16(200),
++ .priority_offset = cpu_to_le16(255),
++ };
++ u8 i;
++
++ for (i = 0; i < RED_TOKEN_SRC_CNT; i++) {
++ req.token_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
++ req.token_thr_per_src[i] = cpu_to_le16(MT7996_TOKEN_SIZE);
++ }
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET),
++ &req, sizeof(req), false);
++}
++
++int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable)
++{
++#define RED_DISABLE 0
++#define RED_BY_WA_ENABLE 2
++ struct {
++ u8 __rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++ u8 enable;
++ u8 __rsv2[3];
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_VOW_RED_ENABLE),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ .enable = enable ? RED_BY_WA_ENABLE : RED_DISABLE,
++ };
++ int ret;
++
++ ret = mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req,
++ sizeof(req), true);
++
++ if (ret)
++ return ret;
++
++ ret = mt7996_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET),
++ MCU_WA_PARAM_RED_EN, enable, 0);
++
++ if (ret || !enable)
++ return ret;
++
++ return mt7996_mcu_wa_red_config(dev);
++}
++
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans)
+ {
+ struct {
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index a0cbf922..ec074bc6 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -239,8 +239,9 @@ enum {
+ enum {
+ MCU_WA_PARAM_PDMA_RX = 0x04,
+ MCU_WA_PARAM_CPU_UTIL = 0x0b,
+- MCU_WA_PARAM_RED = 0x0e,
++ MCU_WA_PARAM_RED_EN = 0x0e,
+ MCU_WA_PARAM_HW_PATH_HIF_VER = 0x2f,
++ MCU_WA_PARAM_RED_CONFIG = 0x40,
+ };
+
+ enum mcu_mmps_mode {
+@@ -695,6 +696,7 @@ enum {
+ UNI_VOW_DRR_CTRL,
+ UNI_VOW_RX_AT_AIRTIME_EN = 0x0b,
+ UNI_VOW_RX_AT_AIRTIME_CLR_EN = 0x0e,
++ UNI_VOW_RED_ENABLE = 0x18,
+ };
+
+ enum {
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index 836c7db7..b239c44c 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -671,6 +671,7 @@ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set)
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
+ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
+ int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
++int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
+ int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
+ int mt7996_mcu_fw_dbg_ctrl(struct mt7996_dev *dev, u32 module, u8 level);
+ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
new file mode 100644
index 0000000..5897422
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch
@@ -0,0 +1,473 @@
+From cc7283ecc1da9d4f62803062466fb5420d2ea766 Mon Sep 17 00:00:00 2001
+From: "sujuan.chen" <sujuan.chen@mediatek.com>
+Date: Thu, 18 May 2023 15:01:47 +0800
+Subject: [PATCH 2007/2008] wifi: mt76: mt7996: reset addr_elem when delete ba
+
+The old addr element info may be used when the signature is not equel to
+0xff, and sta will find error SDP cause the SDP/SDL=0 issue.
+
+Signed-off-by: sujuan.chen <sujuan.chen@mediatek.com>
+---
+ mt76.h | 1 +
+ mt76_connac_mcu.h | 1 +
+ mt7996/init.c | 3 +
+ mt7996/mac.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/main.c | 7 +++
+ mt7996/mcu.c | 64 +++++++++++++++++++++
+ mt7996/mcu.h | 34 +++++++++++
+ mt7996/mt7996.h | 32 +++++++++++
+ mt7996/regs.h | 5 ++
+ 9 files changed, 287 insertions(+)
+
+diff --git a/mt76.h b/mt76.h
+index e4351338..7ebcf432 100644
+--- a/mt76.h
++++ b/mt76.h
+@@ -436,6 +436,7 @@ struct mt76_rx_tid {
+ u16 nframes;
+
+ u8 num;
++ u8 partial_id;
+
+ u8 started:1, stopped:1, timer_pending:1;
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index a53fa138..d74fd2dd 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1023,6 +1023,7 @@ enum {
+ MCU_UNI_EVENT_THERMAL = 0x35,
+ MCU_UNI_EVENT_BF = 0x33,
+ MCU_UNI_EVENT_TESTMODE_CTRL = 0x46,
++ MCU_UNI_EVENT_RRO = 0x57,
+ };
+
+ #define MCU_UNI_CMD_EVENT BIT(1)
+diff --git a/mt7996/init.c b/mt7996/init.c
+index d70dcf9f..93262297 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -759,6 +759,9 @@ static int mt7996_rro_init(struct mt7996_dev *dev)
+ mt76_wr(dev, MT_RRO_HOST_INT_ENA,
+ MT_RRO_HOST_INT_ENA_HOST_RRO_DONE_ENA);
+
++ INIT_DELAYED_WORK(&dev->rro.rro_del_work, mt7996_rro_delete_sessions);
++ INIT_LIST_HEAD(&dev->rro.rro_poll_list);
++
+ /* rro ind cmd queue init */
+ return mt7996_dma_rro_init(dev);
+ }
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 4fbbc077..3a89013c 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -1647,6 +1647,139 @@ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ }
+ }
+
++static struct mt7996_rro_addr *
++mt7996_rro_get_addr_elem(struct mt7996_dev *dev, u16 seid, u16 sn)
++{
++ struct mt7996_rro_cfg *rro = &dev->rro;
++ u32 idx;
++ void *addr;
++
++ if (seid == rro->particular_se_id) {
++ addr = rro->particular_session_va;
++ idx = sn % rro->win_sz;
++ } else {
++ addr = rro->addr_elem_alloc_va[seid / MT7996_RRO_SESSION_PER_CR];
++ idx = (seid % MT7996_RRO_SESSION_PER_CR) * rro->win_sz
++ + (sn % rro->win_sz);
++ }
++ return addr + idx * sizeof(struct mt7996_rro_addr);
++}
++
++static bool mt7996_rro_reset_sessions(struct mt7996_dev *dev,
++ u16 wcid, u8 partial_id)
++{
++ u32 sid = ((wcid & 0x7F) << 3) + partial_id;
++ u32 value[2];
++ struct mt7996_rro_ba_session *s;
++ struct mt7996_rro_addr *elem;
++ int i;
++
++ mt76_wr(dev, MT_RRO_DBG_RD_CTRL, MT_RRO_DBG_RD_EXEC |
++ sid >> 1 | 0x200);
++
++ if (sid & 0x1) {
++ value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2));
++ value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(2));
++ } else {
++ value[0] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(0));
++ value[1] = mt76_rr(dev, MT_RRO_DBG_RDAT_DW(1));
++ }
++
++ s = (struct mt7996_rro_ba_session *)&value[0];
++ if (!s->cn && s->ack_sn == s->last_in_sn) {
++ for (i = 0; i < MT7996_RRO_WIN_SIZE_MAX; i++) {
++ elem = mt7996_rro_get_addr_elem(dev, sid, i);
++ elem->signature = 0xff;
++ }
++ return true;
++ }
++
++ return false;
++}
++
++void mt7996_rro_delete_sessions(struct work_struct *work)
++{
++ struct mt7996_dev *dev;
++ struct mt7996_rro_ba_session_elem *e;
++ int elem_nums;
++ LIST_HEAD(rro_poll_list);
++
++ dev = (struct mt7996_dev *)container_of(work, struct mt7996_dev,
++ rro.rro_del_work.work);
++ elem_nums = dev->rro.elem_nums;
++
++ spin_lock_bh(&dev->rro.rro_stbl_lock);
++ list_splice_init(&dev->rro.rro_poll_list, &rro_poll_list);
++ spin_unlock_bh(&dev->rro.rro_stbl_lock);
++
++ do {
++ spin_lock_bh(&dev->rro.rro_stbl_lock);
++ if (list_empty(&rro_poll_list)) {
++ spin_unlock_bh(&dev->rro.rro_stbl_lock);
++ break;
++ }
++
++ e = list_first_entry(&rro_poll_list,
++ struct mt7996_rro_ba_session_elem,
++ poll_list);
++ if (!e) {
++ spin_unlock_bh(&dev->rro.rro_stbl_lock);
++ break;
++ }
++ list_del_init(&e->poll_list);
++ spin_unlock_bh(&dev->rro.rro_stbl_lock);
++
++ if (mt7996_rro_reset_sessions(dev, e->wlan_idx,
++ e->partial_id)) {
++ mt7996_mcu_reset_rro_sessions(dev, e->wlan_idx,
++ e->tid, e->partial_id);
++ kfree(e);
++ dev->rro.elem_nums--;
++ } else {
++ spin_lock_bh(&dev->rro.rro_stbl_lock);
++ list_add_tail(&e->poll_list, &dev->rro.rro_poll_list);
++ spin_unlock_bh(&dev->rro.rro_stbl_lock);
++ }
++ elem_nums--;
++ } while (elem_nums);
++
++ if (list_empty(&rro_poll_list))
++ ieee80211_queue_delayed_work(mt76_hw(dev),
++ &dev->rro.rro_del_work,
++ MT7996_WATCHDOG_TIME);
++}
++
++int mt7996_rro_add_delete_elem(struct mt7996_dev *dev,
++ struct mt7996_sta *msta, u8 tidno)
++{
++ struct mt76_rx_tid *tid = NULL;
++ struct mt76_wcid *wcid = &msta->wcid;
++ struct mt7996_rro_ba_session_elem *e;
++ u16 idx = msta->wcid.idx;
++
++ tid = rcu_dereference(wcid->aggr[tidno]);
++ if (!tid)
++ return 0;
++
++ e = kzalloc(sizeof(*e), GFP_ATOMIC);
++ if (!e)
++ return -ENOMEM;
++
++ e->wlan_idx = idx;
++ e->tid = tidno;
++ e->partial_id = tid->partial_id;
++
++ spin_lock_bh(&dev->rro.rro_stbl_lock);
++ list_add_tail(&e->poll_list, &dev->rro.rro_poll_list);
++ spin_unlock_bh(&dev->rro.rro_stbl_lock);
++ dev->rro.elem_nums++;
++
++ ieee80211_queue_delayed_work(mt76_hw(dev),
++ &dev->rro.rro_del_work,
++ MT7996_WATCHDOG_TIME);
++ return 0;
++}
++
+ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy)
+ {
+ struct mt7996_dev *dev = phy->dev;
+@@ -1971,6 +2104,9 @@ mt7996_mac_full_reset(struct mt7996_dev *dev)
+ if (phy3)
+ ieee80211_stop_queues(phy3->mt76->hw);
+
++ if (dev->rro_support)
++ cancel_delayed_work_sync(&dev->rro.rro_del_work);
++
+ cancel_delayed_work_sync(&dev->mphy.mac_work);
+ if (phy2)
+ cancel_delayed_work_sync(&phy2->mt76->mac_work);
+@@ -2062,6 +2198,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ set_bit(MT76_RESET, &dev->mphy.state);
+ set_bit(MT76_MCU_RESET, &dev->mphy.state);
+ wake_up(&dev->mt76.mcu.wait);
++
++ if (dev->rro_support)
++ cancel_delayed_work_sync(&dev->rro.rro_del_work);
++
+ cancel_delayed_work_sync(&dev->mphy.mac_work);
+ if (phy2) {
+ set_bit(MT76_RESET, &phy2->mt76->state);
+diff --git a/mt7996/main.c b/mt7996/main.c
+index cebac4ab..4cb72220 100644
+--- a/mt7996/main.c
++++ b/mt7996/main.c
+@@ -119,6 +119,9 @@ static void mt7996_stop(struct ieee80211_hw *hw)
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct mt7996_phy *phy = mt7996_hw_phy(hw);
+
++ if (dev->rro_support)
++ cancel_delayed_work_sync(&dev->rro.rro_del_work);
++
+ cancel_delayed_work_sync(&phy->mt76->mac_work);
+ cancel_delayed_work_sync(&dev->scs_work);
+
+@@ -797,6 +800,10 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ ret = mt7996_mcu_add_rx_ba(dev, params, true);
+ break;
+ case IEEE80211_AMPDU_RX_STOP:
++ if (dev->rro_support) {
++ ret = mt7996_rro_add_delete_elem(dev, msta,
++ params->tid);
++ }
+ mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
+ ret = mt7996_mcu_add_rx_ba(dev, params, false);
+ break;
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 0c01e90b..094f3656 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -476,6 +476,41 @@ mt7996_mcu_rx_thermal_notify(struct mt7996_dev *dev, struct sk_buff *skb)
+ phy->throttle_state = n->duty_percent;
+ }
+
++static void mt7996_mcu_rx_rro(struct mt7996_dev *dev, struct sk_buff *skb)
++{
++ struct mt7996_mcu_rro_event *event;
++
++ if (!dev->rro_support)
++ return;
++
++ event = (struct mt7996_mcu_rro_event*)skb->data;
++
++ switch (event->tag) {
++ case UNI_RRO_BA_SESSION_STATUS: {
++ struct mt7996_mcu_rro_ba *rro = (struct mt7996_mcu_rro_ba *)skb->data;
++ u16 idx = rro->wlan_id;
++ struct mt76_rx_tid *tid;
++ struct mt76_wcid *wcid;
++
++ wcid = rcu_dereference(dev->mt76.wcid[idx]);
++ if (!wcid || !wcid->sta)
++ return;
++
++ tid = rcu_dereference(wcid->aggr[rro->tid]);
++ if (!tid)
++ return;
++ tid->partial_id = rro->partial_id;
++
++ break;
++ }
++ default:
++ dev_info(dev->mt76.dev, "%s: unknown rro event tag %d\n",
++ __func__, event->tag);
++ break;
++ }
++
++}
++
+ static void
+ mt7996_mcu_rx_ext_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ {
+@@ -528,6 +563,9 @@ mt7996_mcu_uni_rx_unsolicited_event(struct mt7996_dev *dev, struct sk_buff *skb)
+ mt7996_tm_rf_test_event(dev, skb);
+ break;
+ #endif
++ case MCU_UNI_EVENT_RRO:
++ mt7996_mcu_rx_rro(dev, skb);
++ break;
+ default:
+ break;
+ }
+@@ -4533,6 +4571,32 @@ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val)
+ sizeof(req), true);
+ }
+
++int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev,
++ u16 wcid, u8 tid, u8 pid)
++{
++ struct {
++ /* fixed field */
++ u8 __rsv[4];
++
++ __le16 tag;
++ __le16 len;
++ u16 wcid;
++ u8 tid;
++ u8 partial_id;
++ u8 pad[4];
++ } __packed req = {
++ .tag = cpu_to_le16(UNI_RRO_DEL_BA_SESSION),
++ .len = cpu_to_le16(sizeof(req) - 4),
++ .wcid = wcid,
++ .tid = tid,
++ .partial_id = pid,
++ };
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(RRO),
++ &req, sizeof(req), true);
++}
++
++
+ int mt7996_mcu_set_tx_power_ctrl(struct mt7996_phy *phy, u8 power_ctrl_id, u8 data)
+ {
+ struct mt7996_dev *dev = phy->dev;
+diff --git a/mt7996/mcu.h b/mt7996/mcu.h
+index ec074bc6..10e3799f 100644
+--- a/mt7996/mcu.h
++++ b/mt7996/mcu.h
+@@ -191,6 +191,38 @@ struct mt7996_mcu_thermal_notify {
+ u8 __rsv2[4];
+ } __packed;
+
++struct mt7996_mcu_rro_event {
++ struct mt7996_mcu_rxd rxd;
++
++ u8 __rsv1[4];
++
++ __le16 tag;
++ __le16 len;
++} __packed;
++
++struct mt7996_mcu_rro_ba {
++ struct mt7996_mcu_rro_event event;
++
++ u16 wlan_id;
++ u8 tid;
++ u8 partial_id;
++ __le32 status;
++}__packed;
++
++enum {
++ UNI_RRO_BA_SESSION_STATUS = 0,
++ UNI_RRO_BA_SESSION_TBL = 1,
++ UNI_RRO_BA_SESSION_MAX_NUM
++};
++
++struct mt7996_mcu_rro_del_ba {
++ struct mt7996_mcu_rro_event event;
++
++ u8 wlan_idx;
++ u8 tid;
++ u8 __rsv2[2];
++};
++
+ enum mt7996_chan_mib_offs {
+ UNI_MIB_OBSS_AIRTIME = 26,
+ UNI_MIB_NON_WIFI_TIME = 27,
+@@ -718,6 +750,8 @@ enum {
+ UNI_RRO_GET_BA_SESSION_TABLE,
+ UNI_RRO_SET_BYPASS_MODE,
+ UNI_RRO_SET_TXFREE_PATH,
++ UNI_RRO_DEL_BA_SESSION,
++ UNI_RRO_SET_FLUSH_TIMEOUT
+ };
+
+ enum{
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index b239c44c..88d42c3a 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -310,6 +310,28 @@ struct mt7996_rro_addr {
+ u32 signature : 8;
+ };
+
++struct mt7996_rro_ba_session {
++ u32 ack_sn :12;
++ u32 win_sz :3;
++ u32 bn :1;
++ u32 last_in_sn :12;
++ u32 bc :1;
++ u32 bd :1;
++ u32 sat :1;
++ u32 cn :1;
++ u32 within_cnt :12;
++ u32 to_sel :3;
++ u32 rsv :1;
++ u32 last_in_rxtime :12;
++};
++
++struct mt7996_rro_ba_session_elem {
++ struct list_head poll_list;
++ u16 wlan_idx;
++ u8 tid;
++ u8 partial_id;
++};
++
+ struct mt7996_rro_cfg {
+ u32 ind_signature;
+ void *ba_bitmap_cache_va[MT7996_RRO_BA_BITMAP_CR_CNT];
+@@ -324,6 +346,11 @@ struct mt7996_rro_cfg {
+ spinlock_t lock;
+ struct list_head pg_addr_cache;
+ struct list_head pg_hash_head[MT7996_RRO_MSDU_PG_HASH_SIZE];
++
++ struct delayed_work rro_del_work;
++ spinlock_t rro_stbl_lock;
++ struct list_head rro_poll_list;
++ u16 elem_nums;
+ };
+
+ struct mt7996_phy {
+@@ -670,6 +697,8 @@ int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx,
+ int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set);
+ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans);
+ int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val);
++int mt7996_mcu_reset_rro_sessions(struct mt7996_dev *dev,
++ u16 wcid, u8 tid, u8 pid);
+ int mt7996_mcu_wa_cmd(struct mt7996_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
+ int mt7996_mcu_red_config(struct mt7996_dev *dev, bool enable);
+ int mt7996_mcu_fw_log_2_host(struct mt7996_dev *dev, u8 type, u8 ctrl);
+@@ -768,6 +797,9 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
+ struct mt76_tx_info *tx_info);
+ void mt7996_tx_token_put(struct mt7996_dev *dev);
+ int mt7996_dma_rro_init(struct mt7996_dev *dev);
++void mt7996_rro_delete_sessions(struct work_struct *work);
++int mt7996_rro_add_delete_elem(struct mt7996_dev *dev,
++ struct mt7996_sta *msta, u8 tid);
+ void mt7996_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+ struct sk_buff *skb, u32 *info);
+ bool mt7996_rx_check(struct mt76_dev *mdev, void *data, int len);
+diff --git a/mt7996/regs.h b/mt7996/regs.h
+index 6624685e..f97c87c9 100644
+--- a/mt7996/regs.h
++++ b/mt7996/regs.h
+@@ -72,6 +72,11 @@ enum base_rev {
+ #define MT_RRO_ACK_SN_CTRL_SN_MASK GENMASK(27, 16)
+ #define MT_RRO_ACK_SN_CTRL_SESSION_MASK GENMASK(11, 0)
+
++#define MT_RRO_DBG_RD_CTRL MT_RRO_TOP(0xe0)
++#define MT_RRO_DBG_RD_ADDR GENMASK(15, 0)
++#define MT_RRO_DBG_RD_EXEC BIT(31)
++
++#define MT_RRO_DBG_RDAT_DW(_n) MT_RRO_TOP(0xf0 + _n * 0x4)
+
+ #define MT_MCU_INT_EVENT 0x2108
+ #define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch b/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
new file mode 100644
index 0000000..0d2134b
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/2008-wifi-mt76-add-SER-support-for-wed3.0.patch
@@ -0,0 +1,303 @@
+From 5df084a32eac68dd66a3b833cf5f718118850b08 Mon Sep 17 00:00:00 2001
+From: mtk27745 <rex.lu@mediatek.com>
+Date: Tue, 23 May 2023 12:06:29 +0800
+Subject: [PATCH 2008/2008] wifi: mt76: add SER support for wed3.0
+
+Change-Id: I2711b9dc336fca9a1ae32a8fbf27810a7e27b1e3
+---
+ dma.c | 7 +++++--
+ mt7996/dma.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
+ mt7996/mac.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ mt7996/mmio.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 145 insertions(+), 6 deletions(-)
+
+diff --git a/dma.c b/dma.c
+index e5b4d898..e31f6390 100644
+--- a/dma.c
++++ b/dma.c
+@@ -770,8 +770,9 @@ int mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q, bool reset)
+ q->head = q->ndesc - 1;
+ q->queued = q->ndesc - 1;
+ }
++ q->flags = flags;
+ } else {
+- ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, 0);
++ ret = mtk_wed_device_rx_ring_setup(wed, ring, q->regs, reset);
+ if (!ret)
+ q->wed_regs = wed->rx_ring[ring].reg_base;
+ }
+@@ -902,7 +903,9 @@ done:
+
+ /* reset WED rx queues */
+ mt76_dma_wed_setup(dev, q, true);
+- if (q->flags != MT_WED_Q_TXFREE) {
++ if (q->flags != MT_WED_Q_TXFREE &&
++ !((q->flags & MT_QFLAG_RRO) &&
++ mtk_wed_device_active(&dev->mmio.wed))) {
+ mt76_dma_sync_idx(dev, q);
+ mt76_dma_rx_fill(dev, q);
+ }
+diff --git a/mt7996/dma.c b/mt7996/dma.c
+index c5c7f160..471ae81c 100644
+--- a/mt7996/dma.c
++++ b/mt7996/dma.c
+@@ -495,6 +495,12 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ if (mt7996_band_valid(dev, MT_BAND2)) {
+ /* rx data queue for band2 */
+ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2) + hif1_ofs;
++ if (mtk_wed_device_active(wed)) {
++ rx_base = MT_RXQ_RING_BASE(MT_RXQ_BAND2);
++ if (mtk_wed_get_rx_capa(wed))
++ dev->mt76.q_rx[MT_RXQ_BAND2].flags = MT_WED_Q_RX(1);
++ }
++
+ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_BAND2],
+ MT_RXQ_ID(MT_RXQ_BAND2),
+ MT7996_RX_RING_SIZE,
+@@ -582,11 +588,35 @@ int mt7996_dma_init(struct mt7996_dev *dev)
+ return 0;
+ }
+
++static void mt7996_dma_wed_reset(struct mt7996_dev *dev)
++{
++ struct mt76_dev *mdev = &dev->mt76;
++
++ if (!test_bit(MT76_STATE_WED_RESET, &dev->mphy.state))
++ return;
++
++ complete(&mdev->mmio.wed_reset);
++
++ if (!wait_for_completion_timeout(&dev->mt76.mmio.wed_reset_complete,
++ 3 * HZ))
++ dev_err(dev->mt76.dev, "wed reset complete timeout\n");
++}
++
++static void
++mt7996_dma_reset_tx_queue(struct mt7996_dev *dev, struct mt76_queue *q)
++{
++ mt76_queue_reset(dev, q, false);
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ mt76_dma_wed_setup(&dev->mt76, q, true);
++}
++
+ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+ {
+ struct mt76_phy *phy2 = dev->mt76.phys[MT_BAND1];
+ struct mt76_phy *phy3 = dev->mt76.phys[MT_BAND2];
+ u32 hif1_ofs = MT_WFDMA0_PCIE1(0) - MT_WFDMA0(0);
++ struct mtk_wed_device *wed = &dev->mt76.mmio.wed;
++ struct mtk_wed_device *wed_ext = &dev->mt76.mmio.wed_ext;
+ int i;
+
+ mt76_clear(dev, MT_WFDMA0_GLO_CFG,
+@@ -620,21 +650,33 @@ void mt7996_dma_reset(struct mt7996_dev *dev, bool force)
+ if (force)
+ mt7996_wfsys_reset(dev);
+
++ if (dev->hif2 && mtk_wed_device_active(wed_ext))
++ mtk_wed_device_dma_reset(wed_ext);
++
++ if (mtk_wed_device_active(wed))
++ mtk_wed_device_dma_reset(wed);
++
+ mt7996_dma_disable(dev, force);
++ mt7996_dma_wed_reset(dev);
+
+ /* reset hw queues */
+ for (i = 0; i < __MT_TXQ_MAX; i++) {
+- mt76_queue_reset(dev, dev->mphy.q_tx[i], false);
++ mt7996_dma_reset_tx_queue(dev, dev->mphy.q_tx[i]);
+ if (phy2)
+- mt76_queue_reset(dev, phy2->q_tx[i], false);
++ mt7996_dma_reset_tx_queue(dev, phy2->q_tx[i]);
+ if (phy3)
+- mt76_queue_reset(dev, phy3->q_tx[i], false);
++ mt7996_dma_reset_tx_queue(dev, phy3->q_tx[i]);
+ }
+
+ for (i = 0; i < __MT_MCUQ_MAX; i++)
+ mt76_queue_reset(dev, dev->mt76.q_mcu[i], false);
+
+ mt76_for_each_q_rx(&dev->mt76, i) {
++ if (mtk_wed_device_active(wed) &&
++ ((dev->mt76.q_rx[i].flags & MT_QFLAG_RRO) ||
++ dev->mt76.q_rx[i].flags == MT_WED_Q_TXFREE))
++ continue;
++
+ mt76_queue_reset(dev, &dev->mt76.q_rx[i], false);
+ }
+
+diff --git a/mt7996/mac.c b/mt7996/mac.c
+index 3a89013c..d1082e89 100644
+--- a/mt7996/mac.c
++++ b/mt7996/mac.c
+@@ -2002,6 +2002,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+ /* disable all tx/rx napi */
+ mt76_worker_disable(&dev->mt76.tx_worker);
+ mt76_for_each_q_rx(mdev, i) {
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ (mdev->q_rx[i].flags & MT_QFLAG_RRO))
++ continue;
++
+ if (mdev->q_rx[i].ndesc)
+ napi_disable(&dev->mt76.napi[i]);
+ }
+@@ -2015,6 +2019,10 @@ mt7996_mac_restart(struct mt7996_dev *dev)
+
+ local_bh_disable();
+ mt76_for_each_q_rx(mdev, i) {
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ (mdev->q_rx[i].flags & MT_QFLAG_RRO))
++ continue;
++
+ if (mdev->q_rx[i].ndesc) {
+ napi_enable(&dev->mt76.napi[i]);
+ napi_schedule(&dev->mt76.napi[i]);
+@@ -2189,6 +2197,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
+
+ dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.",
+ wiphy_name(dev->mt76.hw->wiphy));
++
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext))
++ mtk_wed_device_stop(&dev->mt76.mmio.wed_ext);
++
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed))
++ mtk_wed_device_stop(&dev->mt76.mmio.wed);
++
+ ieee80211_stop_queues(mt76_hw(dev));
+ if (phy2)
+ ieee80211_stop_queues(phy2->mt76->hw);
+@@ -2212,8 +2227,13 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ cancel_delayed_work_sync(&phy3->mt76->mac_work);
+ }
+ mt76_worker_disable(&dev->mt76.tx_worker);
+- mt76_for_each_q_rx(&dev->mt76, i)
++ mt76_for_each_q_rx(&dev->mt76, i) {
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ (dev->mt76.q_rx[i].flags & MT_QFLAG_RRO))
++ continue;
++
+ napi_disable(&dev->mt76.napi[i]);
++ }
+ napi_disable(&dev->mt76.tx_napi);
+
+ mutex_lock(&dev->mt76.mutex);
+@@ -2236,6 +2256,29 @@ void mt7996_mac_reset_work(struct work_struct *work)
+ /* enable dma tx/rx and interrupt */
+ __mt7996_dma_enable(dev, false, false);
+
++
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) {
++ u32 wed_irq_mask = dev->mt76.mmio.irqmask |
++ MT_INT_RRO_RX_DONE |
++ MT_INT_TX_DONE_BAND2;
++
++ if (mtk_wed_get_rx_capa(&dev->mt76.mmio.wed))
++ wed_irq_mask &= ~MT_INT_RX_DONE_RRO_IND;
++
++ mt76_wr(dev, MT_INT_MASK_CSR, wed_irq_mask);
++
++ mtk_wed_device_start_hwrro(&dev->mt76.mmio.wed, wed_irq_mask, true);
++ mt7996_irq_enable(dev, wed_irq_mask);
++ mt7996_irq_disable(dev, 0);
++ }
++
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed_ext)) {
++ mt76_wr(dev, MT_INT1_MASK_CSR,
++ dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2);
++ mtk_wed_device_start(&dev->mt76.mmio.wed_ext,
++ dev->mt76.mmio.irqmask | MT_INT_TX_DONE_BAND2);
++ }
++
+ clear_bit(MT76_MCU_RESET, &dev->mphy.state);
+ clear_bit(MT76_RESET, &dev->mphy.state);
+ if (phy2)
+@@ -2245,6 +2288,10 @@ void mt7996_mac_reset_work(struct work_struct *work)
+
+ local_bh_disable();
+ mt76_for_each_q_rx(&dev->mt76, i) {
++ if (mtk_wed_device_active(&dev->mt76.mmio.wed) &&
++ ((dev->mt76.q_rx[i].flags & MT_QFLAG_RRO)))
++ continue;
++
+ napi_enable(&dev->mt76.napi[i]);
+ napi_schedule(&dev->mt76.napi[i]);
+ }
+diff --git a/mt7996/mmio.c b/mt7996/mmio.c
+index 9960dca7..fe34bb7d 100644
+--- a/mt7996/mmio.c
++++ b/mt7996/mmio.c
+@@ -6,9 +6,11 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/pci.h>
++#include <linux/rtnetlink.h>
+
+ #include "mt7996.h"
+ #include "mac.h"
++#include "mcu.h"
+ #include "../trace.h"
+ #include "../dma.h"
+
+@@ -297,6 +299,43 @@ unmap:
+ mt7996_mmio_wed_release_rx_buf(wed);
+ return -ENOMEM;
+ }
++
++static int mt7996_mmio_wed_reset(struct mtk_wed_device *wed)
++{
++ struct mt76_dev *mdev = container_of(wed, struct mt76_dev, mmio.wed);
++ struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76);
++ struct mt76_phy *mphy = &dev->mphy;
++ int ret;
++
++ ASSERT_RTNL();
++
++ if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state))
++ return -EBUSY;
++
++ ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_TRIGGER, UNI_CMD_SER_SET_RECOVER_L1,
++ mphy->band_idx);
++ if (ret)
++ goto out;
++
++ rtnl_unlock();
++ if (!wait_for_completion_timeout(&mdev->mmio.wed_reset, 20 * HZ)) {
++ dev_err(mdev->dev, "wed reset timeout\n");
++ ret = -ETIMEDOUT;
++ }
++ rtnl_lock();
++out:
++ clear_bit(MT76_STATE_WED_RESET, &mphy->state);
++
++ return ret;
++}
++
++static void mt7996_mmio_wed_reset_complete(struct mtk_wed_device *wed)
++{
++ struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed);
++
++ complete(&dev->mmio.wed_reset_complete);
++}
++
+ #endif
+
+ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+@@ -421,6 +460,14 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr,
+ wed->wlan.init_rx_buf = mt7996_mmio_wed_init_rx_buf;
+ wed->wlan.release_rx_buf = mt7996_mmio_wed_release_rx_buf;
+ wed->wlan.update_wo_rx_stats = NULL;
++ if (hif2) {
++ wed->wlan.reset = NULL;
++ wed->wlan.reset_complete = NULL;
++ } else {
++ wed->wlan.reset = mt7996_mmio_wed_reset;
++ wed->wlan.reset_complete = mt7996_mmio_wed_reset_complete;
++ }
++
+
+ if (mtk_wed_device_attach(wed))
+ return 0;
+--
+2.39.2
+
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
index 12953cf..3114ebf 100644
--- a/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/patches.inc
@@ -1,28 +1,66 @@
#patch patches (come from openwrt/lede/target/linux/mediatek)
SRC_URI_append = " \
file://0001-wifi-mt76-mt7996-add-eht-rx-rate-support.patch \
- file://0002-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch \
- file://0003-wifi-mt76-mt7996-move-radio-enable-command-to-mt7996.patch \
- file://0004-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch \
- file://0005-wifi-mt76-mt7996-add-muru-support.patch \
- file://0006-wifi-mt76-mt7996-set-txd-v1.patch \
- file://0007-wifi-mt76-mt7996-add-thermal-protection-support.patch \
- file://0008-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch \
- file://0009-wifi-mt76-mt7996-add-dsp-firmware-download.patch \
- file://0010-wifi-mt76-mt7996-fix-icv-error-when-enable-AP-and-ST.patch \
- file://0011-wifi-mt76-mt7996-set-wcid-in-txp.patch \
- file://0012-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch \
- file://0013-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch \
- file://0014-wifi-mt76-mt7996-Fix-using-the-wrong-phy-for-backgro.patch \
- file://0015-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch \
- file://0016-wifi-mt76-mt7996-fill-txwi-by-SW-temporarily.patch \
- file://0017-wifi-mt76-mt7996-update-wmm-queue-mapping.patch \
- file://0018-wifi-mt76-mt7996-enable-IDS-debug-log.patch \
- file://0019-mt76-testmode-add-atenl-support-in-mt7996.patch \
- file://0020-mt76-testmode-add-basic-testmode-support.patch \
- file://0021-mt76-testmode-add-chainmask-hacking-for-eagle-band-2.patch \
- file://0022-mt76-revert-page-pool-changes.patch \
- file://0999-mt76-mt7996-for-build-pass.patch \
- file://1000-mt76-mt7996-add-debug-tool.patch \
- file://1001-mt76-mt7996-add-txpower-support.patch \
+ file://0002-wifi-mt76-mt7996-move-radio-ctrl-commands-to-proper-.patch \
+ file://0003-wifi-mt76-connac-add-support-for-dsp-firmware-downlo.patch \
+ file://0004-wifi-mt76-mt7996-fix-bss-wlan_idx-when-sending-bss_i.patch \
+ file://0005-wifi-mt76-mt7996-init-he-and-eht-cap-for-AP_VLAN.patch \
+ file://0006-wifi-mt76-mt7996-enable-VHT-extended-NSS-BW-feature.patch \
+ file://0007-wifi-mt76-connac-add-support-to-set-ifs-time-by-mcu-.patch \
+ file://0008-wifi-mt76-mt7996-use-correct-phy-for-background-rada.patch \
+ file://0009-wifi-mt76-mt7996-fix-WA-event-ring-size.patch \
+ file://0010-wifi-mt76-mt7996-add-muru-support.patch \
+ file://0011-wifi-mt76-mt7996-increase-tx-token-size.patch \
+ file://0014-wifi-mt76-mt7996-set-wcid-in-txp.patch \
+ file://0015-wifi-mt76-mt7996-reduce-repeated-bss_info-and-sta_re.patch \
+ file://0016-wifi-mt76-connac-set-correct-muar_idx-for-connac3-ch.patch \
+ file://0017-wifi-mt76-mt7996-add-thermal-protection-support.patch \
+ file://0018-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch \
+ file://0019-wifi-mt76-mt7996-fix-beamform-mcu-cmd-configuration.patch \
+ file://0020-wifi-mt76-mt7996-support-more-options-in-.set_bitrat.patch \
+ file://0021-wifi-mt76-mt7996-update-wmm-queue-mapping.patch \
+ file://0022-wifi-mt76-mt7996-enable-IDS-debug-log.patch \
+ file://0023-wifi-mt76-testmode-add-atenl-support-in-mt7996.patch \
+ file://0024-wifi-mt76-testmode-add-basic-testmode-support.patch \
+ file://0026-wifi-mt76-mt7996-add-led-feature-support.patch \
+ file://0027-wifi-mt76-mt7996-fix-twt-mcu-command.patch \
+ file://0028-wifi-mt76-mt7996-add-11v-mbss-support-for-mt76.patch \
+ file://0029-wifi-mt76-mt7996-Update-beacon-size-limitation-for-1.patch \
+ file://0030-wifi-mt76-mt7996-add-support-for-auxiliary-path.patch \
+ file://0031-wifi-mt76-mt7996-fix-memory-leak.patch \
+ file://0032-wifi-mt76-mt7996-add-eht-mode-tx-stats.patch \
+ file://0033-wifi-mt76-mt7996-disable-wfdma-tx-rx-during-SER.patch \
+ file://0034-wifi-mt76-mt7996-add-firmware-WA-s-coredump.patch \
+ file://0035-wifi-mt76-mt7996-make-band-capability-init-flexible.patch \
+ file://0036-wifi-mt76-mt7996-enable-SCS-feature-for-mt7996-drive.patch \
+ file://0037-wifi-mt76-mt7996-add-beacon-duplicate-tx-mode-suppor.patch \
+ file://0038-wifi-mt76-mt7996-fix-DFS-CAC-tx-emission-issue-after.patch \
+ file://0039-wifi-mt76-mt7996-fix-bss-rate-tlv-to-sync-firmware-c.patch \
+ file://0040-wifi-mt76-mt7996-fix-beamformee-ss-subfield-in-EHT-P.patch \
+ file://0999-wifi-mt76-mt7996-for-build-pass.patch \
+ file://1000-wifi-mt76-mt7996-add-debug-tool.patch \
+ file://1001-wifi-mt76-mt7996-add-txpower-support.patch \
+ file://1002-wifi-mt76-mt7996-add-mu-vendor-command-support.patch \
+ file://1003-wifi-mt76-mt7996-Add-air-monitor-support.patch \
+ file://1004-wifi-mt76-mt7996-add-driver-support-for-wpa3-ocv-and.patch \
+ file://1005-wifi-mt76-mt7996-add-U-NII-4-support.patch \
+ file://1006-wifi-mt76-testmode-add-testmode-pre-calibration-supp.patch \
+ file://1007-wifi-mt76-mt7996-add-binfile-mode-support.patch \
+ file://1008-wifi-mt76-mt7996-add-normal-mode-pre-calibration-sup.patch \
+ file://1009-wifi-mt76-mt7996-Beacon-protection-feature-added.patch \
+ file://1010-wifi-mt76-testmode-add-testmode-ZWDFS-verification-s.patch \
+ file://1011-wifi-mt76-mt7996-add-single-sku.patch \
+ file://1012-wifi-mt76-mt7996-add-vendor-cmd-to-get-available-col.patch \
+ file://1013-wifi-mt76-mt7996-get-tx_retries-and-tx_fails-from-tx.patch \
+ file://1014-wifi-mt76-mt7996-add-debugfs-for-fw-coredump.patch \
+ file://1015-wifi-mt76-mt7996-add-support-for-runtime-set-in-band.patch \
+ file://2000-wifi-mt76-rework-wed-rx-flow.patch \
+ file://2001-wifi-mt76-revert-page_poll-for-kernel-5.4.patch \
+ file://2002-wifi-mt76-wed-change-wed-token-init-size-to-adapt-we.patch \
+ file://2003-wifi-mt76-mt7996-wed-add-wed3.0-tx-support.patch \
+ file://2004-wifi-mt76-mt7996-wed-add-wed3.0-rx-support.patch \
+ file://2005-wifi-mt76-mt7996-wed-add-mt7996_net_setup_tc-to-supp.patch \
+ file://2006-wifi-mt76-add-random-early-drop-support.patch \
+ file://2007-wifi-mt76-mt7996-reset-addr_elem-when-delete-ba.patch \
+ file://2008-wifi-mt76-add-SER-support-for-wed3.0.patch \
"
diff --git a/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch b/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch
index cbdece6..7902ebc 100644
--- a/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1010-wifi-mt76-testmode-additional-supports.patch
@@ -1,32 +1,32 @@
-From 29deaa7cb606cf334238cb36d89891fa80bef0fc Mon Sep 17 00:00:00 2001
+From c311d022536c9c6be72f8e4a134f9dbaed13cd6d Mon Sep 17 00:00:00 2001
From: Shayne Chen <shayne.chen@mediatek.com>
Date: Thu, 21 Apr 2022 15:43:19 +0800
-Subject: [PATCH 1010/1033] wifi: mt76: testmode: additional supports
+Subject: [PATCH 1010/1014] wifi: mt76: testmode: additional supports
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
dma.c | 3 +-
mac80211.c | 12 +
- mt76.h | 108 ++++-
+ mt76.h | 108 +++-
mt76_connac_mcu.c | 4 +
mt76_connac_mcu.h | 2 +
mt7915/eeprom.c | 2 +-
mt7915/init.c | 2 +-
mt7915/mac.c | 39 +-
mt7915/main.c | 2 +-
- mt7915/mcu.c | 19 +-
+ mt7915/mcu.c | 22 +-
mt7915/mcu.h | 29 +-
mt7915/mmio.c | 2 +
mt7915/mt7915.h | 16 +-
mt7915/regs.h | 3 +
- mt7915/testmode.c | 1184 ++++++++++++++++++++++++++++++++++++++++++---
+ mt7915/testmode.c | 1221 ++++++++++++++++++++++++++++++++++++++++++---
mt7915/testmode.h | 278 +++++++++++
- testmode.c | 280 +++++++++--
+ testmode.c | 282 +++++++++--
testmode.h | 75 +++
tools/fields.c | 84 +++-
tx.c | 3 +-
- 20 files changed, 1991 insertions(+), 156 deletions(-)
+ 20 files changed, 2023 insertions(+), 166 deletions(-)
diff --git a/dma.c b/dma.c
index c9d2671..fc92e39 100644
@@ -398,7 +398,7 @@
mvif->mt76.wmm_idx += 2;
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 5a68bb7..e4ab3e0 100644
+index 5a68bb7..5cea513 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -387,6 +387,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
@@ -421,7 +421,17 @@
!rxd->seq)
mt7915_mcu_rx_unsolicited_event(dev, skb);
else
-@@ -2781,21 +2787,21 @@ static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev)
+@@ -2713,7 +2719,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
+ }
+ #endif
+
+- if (mt76_connac_spe_idx(phy->mt76->antenna_mask))
++ if (mt76_connac_spe_idx(phy->mt76->antenna_mask) &&
++ !mt76_testmode_enabled(phy->mt76))
+ req.tx_path_num = fls(phy->mt76->antenna_mask);
+
+ if (dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
+@@ -2781,21 +2788,21 @@ static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev)
return 0;
}
@@ -446,7 +456,7 @@
{
struct mt7915_mcu_eeprom_info req = {
.addr = cpu_to_le32(round_down(offset,
-@@ -2804,7 +2810,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
+@@ -2804,7 +2811,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
struct mt7915_mcu_eeprom_info *res;
struct sk_buff *skb;
int ret;
@@ -455,7 +465,7 @@
ret = mt76_mcu_send_and_get_msg(&dev->mt76,
MCU_EXT_QUERY(EFUSE_ACCESS),
-@@ -2813,8 +2819,11 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
+@@ -2813,8 +2820,11 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
return ret;
res = (struct mt7915_mcu_eeprom_info *)skb->data;
@@ -595,7 +605,7 @@
static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
{
diff --git a/mt7915/regs.h b/mt7915/regs.h
-index e7bc181..0339d4b 100644
+index e7bc181..b6f36f5 100644
--- a/mt7915/regs.h
+++ b/mt7915/regs.h
@@ -62,6 +62,7 @@ enum offs_rev {
@@ -611,12 +621,12 @@
#define MT_WF_AGG(_band, ofs) (MT_WF_AGG_BASE(_band) + (ofs))
+#define MT_AGG_AALCR0(_band, _n) MT_WF_AGG(_band, (__OFFS(AGG_AALCR0) + \
-+ (_n) * 4))
++ (_n) * 4))
#define MT_AGG_AWSCR0(_band, _n) MT_WF_AGG(_band, (__OFFS(AGG_AWSCR0) + \
(_n) * 4))
#define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, (__OFFS(AGG_PCR0) + \
diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 4693919..c44f13f 100644
+index 4693919..62ef4db 100644
--- a/mt7915/testmode.c
+++ b/mt7915/testmode.c
@@ -9,6 +9,9 @@
@@ -639,7 +649,7 @@
};
struct reg_band {
-@@ -33,6 +39,38 @@ struct reg_band {
+@@ -33,6 +39,57 @@ struct reg_band {
#define TM_REG_MAX_ID 20
static struct reg_band reg_backup_list[TM_REG_MAX_ID];
@@ -664,6 +674,25 @@
+ return width_to_bw[width];
+}
+
++static int
++mt7915_tm_check_antenna(struct mt7915_phy *phy)
++{
++ struct mt76_testmode_data *td = &phy->mt76->test;
++ struct mt7915_dev *dev = phy->dev;
++ u8 band_idx = phy->mt76->band_idx;
++ u32 chainmask = phy->mt76->chainmask;
++
++ chainmask = chainmask >> (dev->chainshift * band_idx);
++ if (td->tx_antenna_mask & ~chainmask) {
++ dev_err(dev->mt76.dev,
++ "tx antenna mask %d exceeds hardware limitation (chainmask %d)\n",
++ td->tx_antenna_mask, chainmask);
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
+static void
+mt7915_tm_update_channel(struct mt7915_phy *phy)
+{
@@ -678,7 +707,7 @@
static int
mt7915_tm_set_tx_power(struct mt7915_phy *phy)
-@@ -119,18 +157,28 @@ mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
+@@ -119,18 +176,28 @@ mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
}
static int
@@ -711,7 +740,7 @@
}
static int
-@@ -141,7 +189,7 @@ mt7915_tm_set_phy_count(struct mt7915_phy *phy, u8 control)
+@@ -141,7 +208,7 @@ mt7915_tm_set_phy_count(struct mt7915_phy *phy, u8 control)
.testmode_en = 1,
.param_idx = MCU_ATE_SET_PHY_COUNT,
.param.cfg.enable = control,
@@ -720,7 +749,7 @@
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
-@@ -182,12 +230,738 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu)
+@@ -182,12 +249,738 @@ mt7915_tm_set_tam_arb(struct mt7915_phy *phy, bool enable, bool mu)
return mt7915_mcu_set_muru_ctrl(dev, MURU_SET_ARB_OP_MODE, op_mode);
}
@@ -1461,7 +1490,7 @@
struct edca *e = &req.edca[0];
e->queue = qid + mvif->mt76.wmm_idx * MT76_CONNAC_MAX_WMM_SETS;
-@@ -263,7 +1037,8 @@ done:
+@@ -263,7 +1056,8 @@ done:
return mt7915_tm_set_wmm_qid(phy,
mt76_connac_lmac_mapping(IEEE80211_AC_BE),
@@ -1471,7 +1500,7 @@
}
static int
-@@ -339,7 +1114,7 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
+@@ -339,7 +1133,7 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
bitrate = cfg80211_calculate_bitrate(&rate);
tx_len = bitrate * tx_time / 10 / 8;
@@ -1480,7 +1509,7 @@
if (ret)
return ret;
-@@ -458,64 +1233,227 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -458,64 +1252,227 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
phy->mt76->test.flag |= MT_TM_FW_RX_COUNT;
@@ -1580,7 +1609,7 @@
+ comm->spe_idx = phy->test.spe_idx;
+
+ dl->bw = mt7915_tm_chan_bw(chandef->width);
-+ dl->gi = td->tx_rate_sgi;;
++ dl->gi = td->tx_rate_sgi;
+ dl->ltf = td->tx_ltf;
+ dl->tx_mode = MT_PHY_TYPE_HE_MU;
+
@@ -1739,7 +1768,7 @@
mt7915_tm_set_trx(phy, TM_MAC_TX, en);
}
-@@ -544,10 +1482,6 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
+@@ -544,10 +1501,6 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
return ret;
rs_band = (struct mt7915_tm_rx_stat_band *)skb->data;
@@ -1750,7 +1779,7 @@
if (!clear) {
enum mt76_rxq_id q = req.band ? MT_RXQ_BAND1 : MT_RXQ_MAIN;
-@@ -562,13 +1496,61 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
+@@ -562,13 +1515,61 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear)
return 0;
}
@@ -1813,7 +1842,7 @@
/* read-clear */
mt7915_tm_get_rx_stats(phy, true);
-@@ -576,9 +1558,12 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
+@@ -576,9 +1577,12 @@ mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
/* clear fw count */
mt7915_tm_set_phy_count(phy, 0);
mt7915_tm_set_phy_count(phy, 1);
@@ -1828,7 +1857,7 @@
}
static int
-@@ -617,34 +1602,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
+@@ -617,34 +1621,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
tx_cont->tx_ant = td->tx_antenna_mask;
tx_cont->band = band;
@@ -1864,7 +1893,7 @@
if (!en) {
req.op.rf.param.func_data = cpu_to_le32(band);
-@@ -728,6 +1686,12 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+@@ -728,6 +1705,12 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0);
if (changed & BIT(TM_CHANGED_TXPOWER))
mt7915_tm_set_tx_power(phy);
@@ -1877,7 +1906,7 @@
}
static int
-@@ -737,6 +1701,11 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -737,6 +1720,11 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
struct mt7915_phy *phy = mphy->priv;
enum mt76_testmode_state prev_state = td->state;
@@ -1889,7 +1918,53 @@
mphy->test.state = state;
if (prev_state == MT76_TM_STATE_TX_FRAMES ||
-@@ -807,6 +1776,7 @@ static int
+@@ -757,7 +1745,7 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+ (state == MT76_TM_STATE_OFF &&
+ prev_state == MT76_TM_STATE_IDLE)) {
+ u32 changed = 0;
+- int i;
++ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
+ u16 cur = tm_change_map[i];
+@@ -766,6 +1754,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+ changed |= BIT(i);
+ }
+
++ ret = mt7915_tm_check_antenna(phy);
++ if (ret)
++ return ret;
++
+ mt7915_tm_update_params(phy, changed);
+ }
+
+@@ -778,10 +1770,8 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
+ {
+ struct mt76_testmode_data *td = &mphy->test;
+ struct mt7915_phy *phy = mphy->priv;
+- struct mt7915_dev *dev = phy->dev;
+- u32 chainmask = mphy->chainmask, changed = 0;
+- bool ext_phy = phy != &dev->phy;
+- int i;
++ u32 changed = 0;
++ int i, ret;
+
+ BUILD_BUG_ON(NUM_TM_CHANGED >= 32);
+
+@@ -789,9 +1779,9 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
+ td->state == MT76_TM_STATE_OFF)
+ return 0;
+
+- chainmask = ext_phy ? chainmask >> dev->chainshift : chainmask;
+- if (td->tx_antenna_mask > chainmask)
+- return -EINVAL;
++ ret = mt7915_tm_check_antenna(phy);
++ if (ret)
++ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
+ if (tb[tm_change_map[i]])
+@@ -807,6 +1797,7 @@ static int
mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
{
struct mt7915_phy *phy = mphy->priv;
@@ -1897,7 +1972,7 @@
void *rx, *rssi;
int i;
-@@ -852,11 +1822,75 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
+@@ -852,11 +1843,75 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
nla_nest_end(msg, rx);
@@ -1974,7 +2049,7 @@
+ .set_eeprom = mt7915_tm_set_eeprom,
};
diff --git a/mt7915/testmode.h b/mt7915/testmode.h
-index a1c54c8..01b08e9 100644
+index a1c54c8..eb0e043 100644
--- a/mt7915/testmode.h
+++ b/mt7915/testmode.h
@@ -4,6 +4,8 @@
@@ -2121,12 +2196,12 @@
+/* Common Config */
+/* #define MURU_COMM_PPDU_FMT BIT(0) */
+/* #define MURU_COMM_SCH_TYPE BIT(1) */
-+/* #define MURU_COMM_BAND BIT(2) */
-+/* #define MURU_COMM_WMM BIT(3) */
++/* #define MURU_COMM_BAND BIT(2) */
++/* #define MURU_COMM_WMM BIT(3) */
+/* #define MURU_COMM_SPE_IDX BIT(4) */
+/* #define MURU_COMM_PROC_TYPE BIT(5) */
+/* #define MURU_COMM_SET (MURU_COMM_PPDU_FMT | MURU_COMM_BAND | \ */
-+/* MURU_COMM_WMM | MURU_COMM_SPE_IDX) */
++/* MURU_COMM_WMM | MURU_COMM_SPE_IDX) */
+/* DL Config */
+#define MURU_DL_BW BIT(0)
+#define MURU_DL_GI BIT(1)
@@ -2289,7 +2364,7 @@
+
#endif
diff --git a/testmode.c b/testmode.c
-index 1d0d5d3..fd3b9b2 100644
+index 1d0d5d3..97f65fd 100644
--- a/testmode.c
+++ b/testmode.c
@@ -27,28 +27,16 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
@@ -2340,8 +2415,8 @@
td->tx_queued++;
+
+ if (td->tx_rate_mode != MT76_TM_TX_MODE_HE_MU)
-+ if (td->tx_queued - td->tx_done >= limit)
-+ break;
++ if (td->tx_queued - td->tx_done >= limit)
++ break;
}
dev->queue_ops->kick(dev, q);
@@ -2368,7 +2443,7 @@
+ q = phy->q_tx[qid];
+ spin_lock_bh(&q->lock);
+ mt76_testmode_queue_tx(phy, &phy->dev->global_wcid,
-+ td->tx_skb, q, qid, tx_queued_limit);
++ td->tx_skb, q, qid, tx_queued_limit);
+ spin_unlock_bh(&q->lock);
+
+ return;
@@ -2387,7 +2462,7 @@
+
+ mt76_testmode_queue_tx(phy, td->cur_entry, ed->tx_skb, q, qid, tx_queued_limit);
+
-+ if (td->tx_pending % td->tx_count == 0 || is_mu)
++ if ((td->tx_count != UINT_MAX && td->tx_pending % td->tx_count == 0) || is_mu)
+ td->cur_entry = list_next_entry(td->cur_entry, list);
spin_unlock_bh(&q->lock);
@@ -2686,7 +2761,7 @@
+
+ if (!tb[MT76_TM_ATTR_TXBF_PARAM] ||
+ mt76_tm_get_u8(tb[MT76_TM_ATTR_TXBF_ACT], &td->txbf_act,
-+ 0, MT76_TM_TXBF_ACT_MAX))
++ 0, MT76_TM_TXBF_ACT_MAX))
+ goto out;
+
+ memset(td->txbf_param, 0, sizeof(td->txbf_param));
@@ -2743,10 +2818,14 @@
nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) ||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_LTF) &&
nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
-@@ -643,6 +824,15 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
- nla_put_u8(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
- goto out;
-
+@@ -640,7 +821,16 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) &&
+ nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) ||
+ (mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) &&
+- nla_put_u8(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
++ nla_put_u32(msg, MT76_TM_ATTR_FREQ_OFFSET, td->freq_offset)))
++ goto out;
++
+ if (nla_put_u32(msg, MT76_TM_ATTR_TX_LENGTH, ed->tx_mpdu_len) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_NSS, ed->tx_rate_nss) ||
+ nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_IDX, ed->tx_rate_idx) ||
@@ -2754,13 +2833,11 @@
+ nla_put_u8(msg, MT76_TM_ATTR_AID, ed->aid) ||
+ nla_put_u8(msg, MT76_TM_ATTR_RU_ALLOC, ed->ru_alloc) ||
+ nla_put_u8(msg, MT76_TM_ATTR_RU_IDX, ed->ru_idx))
-+ goto out;
-+
+ goto out;
+
if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) {
- a = nla_nest_start(msg, MT76_TM_ATTR_TX_POWER);
- if (!a)
diff --git a/testmode.h b/testmode.h
-index 8961326..57949f2 100644
+index 8961326..8c55fa0 100644
--- a/testmode.h
+++ b/testmode.h
@@ -6,6 +6,8 @@
@@ -2778,10 +2855,10 @@
* @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested)
+ *
+ * @MT76_TM_ATTR_EEPROM_ACTION: eeprom setting actions
-+ * (u8, see &enum mt76_testmode_eeprom_action)
++ * (u8, see &enum mt76_testmode_eeprom_action)
+ * @MT76_TM_ATTR_EEPROM_OFFSET: offset of eeprom data block for writing (u32)
+ * @MT76_TM_ATTR_EEPROM_VAL: values for writing into a 16-byte data block
-+ * (nested, u8 attrs)
++ * (nested, u8 attrs)
+ *
+ * @MT76_TM_ATTR_CFG: config testmode rf feature (nested, see &mt76_testmode_cfg)
+ *
@@ -2814,7 +2891,7 @@
+ * enum mt76_testmode_eeprom_action - eeprom setting actions
+ *
+ * @MT76_TM_EEPROM_ACTION_UPDATE_DATA: update rf values to specific
-+ * eeprom data block
++ * eeprom data block
+ * @MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE: send updated eeprom data to fw
+ * @MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE: write eeprom data back to efuse
+ */
@@ -2832,7 +2909,7 @@
+ * enum mt76_testmode_cfg - packet tx phy mode
+ *
+ * @MT76_TM_EEPROM_ACTION_UPDATE_DATA: update rf values to specific
-+ * eeprom data block
++ * eeprom data block
+ * @MT76_TM_EEPROM_ACTION_UPDATE_BUFFER_MODE: send updated eeprom data to fw
+ * @MT76_TM_EEPROM_ACTION_WRITE_TO_EFUSE: write eeprom data back to efuse
+ */
diff --git a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
index ac7b121..82e8e7d 100644
--- a/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1011-wifi-mt76-testmode-add-pre-cal-support.patch
@@ -1,10 +1,9 @@
-From 0b10a07db9b3c9dd93861d71da449c521e228b3e Mon Sep 17 00:00:00 2001
+From b933c76718db1c21ecaaf0cddfa4d598617153ea Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Wed, 31 Aug 2022 20:06:52 +0800
-Subject: [PATCH 1011/1033] wifi: mt76: testmode: add pre-cal support
+Subject: [PATCH 1011/1014] wifi: mt76: testmode: add pre-cal support
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Change-Id: Ibfbbc3443de994eeb4daa5e364b0a90f5d7d3bcd
---
eeprom.c | 6 +-
mt76.h | 1 +
@@ -114,7 +113,7 @@
#endif
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index e4ab3e0..abb54eb 100644
+index 5cea513..2a515e3 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -391,6 +391,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb)
@@ -127,7 +126,7 @@
#endif
default:
break;
-@@ -2887,7 +2890,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
+@@ -2888,7 +2891,7 @@ int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev)
u8 idx = 0, *cal = dev->cal, *eep = dev->mt76.eeprom.data;
u32 total = MT_EE_CAL_GROUP_SIZE;
@@ -136,7 +135,7 @@
return 0;
/*
-@@ -2967,11 +2970,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
+@@ -2968,11 +2971,29 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
@@ -192,7 +191,7 @@
static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev)
{
diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index c44f13f..146c4d3 100644
+index 62ef4db..b2d26ff 100644
--- a/mt7915/testmode.c
+++ b/mt7915/testmode.c
@@ -5,6 +5,7 @@
@@ -203,7 +202,7 @@
enum {
TM_CHANGED_TXPOWER,
-@@ -1580,18 +1581,16 @@ mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
+@@ -1599,18 +1600,16 @@ mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
static int
mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
{
@@ -224,7 +223,7 @@
.icap_len = 120,
.op.rf.func_idx = cpu_to_le32(func_idx),
};
-@@ -1676,6 +1675,316 @@ out:
+@@ -1695,6 +1694,316 @@ out:
sizeof(req), true);
}
@@ -541,7 +540,7 @@
static void
mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
{
-@@ -1720,6 +2029,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
+@@ -1739,6 +2048,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
else if (prev_state == MT76_TM_STATE_OFF ||
state == MT76_TM_STATE_OFF)
mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF));
@@ -552,7 +551,7 @@
if ((state == MT76_TM_STATE_IDLE &&
prev_state == MT76_TM_STATE_OFF) ||
-@@ -1888,9 +2201,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
+@@ -1909,9 +2222,113 @@ mt7915_tm_set_eeprom(struct mt76_phy *mphy, u32 offset, u8 *val, u8 action)
return ret;
}
@@ -667,7 +666,7 @@
+ .dump_precal = mt7915_tm_dump_precal,
};
diff --git a/mt7915/testmode.h b/mt7915/testmode.h
-index 01b08e9..d500987 100644
+index eb0e043..7569826 100644
--- a/mt7915/testmode.h
+++ b/mt7915/testmode.h
@@ -81,6 +81,11 @@ struct tm_tx_cont {
@@ -735,7 +734,7 @@
TAM_ARB_OP_MODE_NORMAL = 1,
TAM_ARB_OP_MODE_TEST,
diff --git a/testmode.c b/testmode.c
-index fd3b9b2..b5a919a 100644
+index 97f65fd..21362bd 100644
--- a/testmode.c
+++ b/testmode.c
@@ -766,6 +766,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
@@ -768,7 +767,7 @@
if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
diff --git a/testmode.h b/testmode.h
-index 57949f2..34936e5 100644
+index 8c55fa0..109a556 100644
--- a/testmode.h
+++ b/testmode.h
@@ -19,6 +19,7 @@
diff --git a/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch b/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch
index 5a4d921..fb2113a 100644
--- a/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1012-wifi-mt76-testmode-add-iBF-command-mode-support.patch
@@ -1,10 +1,9 @@
-From 5537367425c0e52ce5da53612e4aaa1bc756c39f Mon Sep 17 00:00:00 2001
+From e44d59d15e90c11b1466b12ac9401922c11504f6 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 12 Sep 2022 18:16:54 +0800
-Subject: [PATCH 1012/1033] wifi: mt76: testmode: add iBF command mode support
+Subject: [PATCH 1012/1014] wifi: mt76: testmode: add iBF command mode support
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
-Change-Id: I7eea1d6412563f889e5774e787e58ce9eba001bd
---
mt7915/testmode.c | 21 ++++++++++++++-------
testmode.c | 41 +++++++++++++++++++++++++++++++++++++++++
@@ -13,10 +12,10 @@
4 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 146c4d3..6a18cdb 100644
+index b2d26ff..40a3a06 100644
--- a/mt7915/testmode.c
+++ b/mt7915/testmode.c
-@@ -701,6 +701,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -720,6 +720,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
struct ieee80211_vif *vif = phy->monitor_vif;
struct mt7915_tm_pfmu_tag *tag = phy->dev->test.txbf_pfmu_tag;
u8 pfmu_idx = val[0], nc = val[2], nr;
@@ -24,7 +23,7 @@
int ret;
if (td->tx_antenna_mask == 3)
-@@ -748,7 +749,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
+@@ -767,7 +768,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf)
if (ret)
return ret;
@@ -33,7 +32,7 @@
return mt7915_tm_txbf_apply_tx(phy, 1, false, true, true);
return 0;
-@@ -775,7 +776,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
+@@ -794,7 +795,7 @@ mt7915_tm_txbf_phase_cal(struct mt7915_phy *phy, u16 *val)
.group_l_m_n = val[1],
.sx2 = val[2],
.cal_type = val[3],
@@ -42,7 +41,7 @@
};
struct mt7915_tm_txbf_phase *phase =
(struct mt7915_tm_txbf_phase *)dev->test.txbf_phase_cal;
-@@ -814,6 +815,8 @@ int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb)
+@@ -833,6 +834,8 @@ int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb)
phase = &phase[cal->group];
memcpy(&phase->phase, cal->buf + 16, sizeof(phase->phase));
phase->status = cal->status;
@@ -51,7 +50,7 @@
break;
case IBF_PHASE_CAL_VERIFY:
case IBF_PHASE_CAL_VERIFY_INSTRUMENT:
-@@ -865,7 +868,6 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
+@@ -884,7 +887,6 @@ mt7915_tm_txbf_profile_update_all(struct mt7915_phy *phy, u16 *val)
pfmu_data->phi11 = cpu_to_le16(phi11);
pfmu_data->phi21 = cpu_to_le16(phi21);
pfmu_data->phi31 = cpu_to_le16(phi31);
@@ -59,7 +58,7 @@
if (subc_id == 63) {
struct mt7915_dev *dev = phy->dev;
struct {
-@@ -923,8 +925,8 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -942,8 +944,8 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
struct mt76_testmode_data *td = &phy->mt76->test;
u16 *val = td->txbf_param;
@@ -70,7 +69,7 @@
switch (td->txbf_act) {
case MT76_TM_TXBF_ACT_INIT:
-@@ -942,10 +944,17 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -961,10 +963,17 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
return mt7915_tm_txbf_profile_update(phy, val, true);
case MT76_TM_TXBF_ACT_PHASE_CAL:
return mt7915_tm_txbf_phase_cal(phy, val);
@@ -88,7 +87,7 @@
default:
break;
};
-@@ -1072,7 +1081,6 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
+@@ -1091,7 +1100,6 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
rate.legacy = sband->bitrates[rate.mcs].bitrate;
break;
case MT76_TM_TX_MODE_HT:
@@ -96,7 +95,7 @@
flags |= RATE_INFO_FLAGS_MCS;
if (td->tx_rate_sgi)
-@@ -1437,7 +1445,6 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
+@@ -1456,7 +1464,6 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
if (duty_cycle < 100)
tx_time = duty_cycle * ipg / (100 - duty_cycle);
}
@@ -105,7 +104,7 @@
mt7915_tm_set_tx_len(phy, tx_time);
diff --git a/testmode.c b/testmode.c
-index b5a919a..f1982ac 100644
+index 21362bd..39cacb2 100644
--- a/testmode.c
+++ b/testmode.c
@@ -533,6 +533,42 @@ out:
@@ -152,7 +151,7 @@
void *data, int len)
{
@@ -671,6 +707,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- 0, MT76_TM_TXBF_ACT_MAX))
+ 0, MT76_TM_TXBF_ACT_MAX))
goto out;
+ if (td->txbf_act == MT76_TM_TXBF_ACT_PROF_UPDATE_ALL_CMD) {
@@ -164,7 +163,7 @@
nla_for_each_nested(cur, tb[MT76_TM_ATTR_TXBF_PARAM], rem) {
if (nla_len(cur) != 2 ||
diff --git a/testmode.h b/testmode.h
-index 34936e5..bbfb313 100644
+index 109a556..d2675dd 100644
--- a/testmode.h
+++ b/testmode.h
@@ -281,8 +281,10 @@ enum mt76_testmode_txbf_act {
diff --git a/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch b/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
index 164b46a..f920fd6 100644
--- a/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1013-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch
@@ -1,22 +1,21 @@
-From 32e4319f0e34cb0a1ebb2dbb45c6561a96196a52 Mon Sep 17 00:00:00 2001
+From ee654a359005c8f5e48cc34a42dc76a6550d7e7f Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Thu, 27 Oct 2022 17:42:07 +0800
-Subject: [PATCH 1013/1033] wifi: mt76: testmode: add ZWDFS test mode support
+Subject: [PATCH 1013/1014] wifi: mt76: testmode: add ZWDFS test mode support
-Change-Id: I14d104b7158a35acf6b0595357d07fb87f5a9d94
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
mt76.h | 9 ++
mt76_connac_mcu.h | 2 +
- mt7915/mcu.c | 66 +++++++++++++
- mt7915/mcu.h | 46 +++++++++
+ mt7915/mcu.c | 66 +++++++++++
+ mt7915/mcu.h | 46 ++++++++
mt7915/mt7915.h | 4 +
mt7915/regs.h | 2 +
- mt7915/testmode.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++
- testmode.c | 25 ++++-
- testmode.h | 45 +++++++++
- tools/fields.c | 22 +++++
- 10 files changed, 452 insertions(+), 1 deletion(-)
+ mt7915/testmode.c | 288 ++++++++++++++++++++++++++++++++++++++++++++++
+ testmode.c | 25 +++-
+ testmode.h | 45 ++++++++
+ tools/fields.c | 22 ++++
+ 10 files changed, 508 insertions(+), 1 deletion(-)
diff --git a/mt76.h b/mt76.h
index c632852..f4412a2 100644
@@ -59,7 +58,7 @@
enum {
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index abb54eb..2432e57 100644
+index 2a515e3..cb70af5 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -2619,6 +2619,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy,
@@ -70,7 +69,7 @@
req.band_idx = phy->mt76->band_idx;
req.scan_mode = 2;
break;
-@@ -4601,3 +4602,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable)
+@@ -4602,3 +4603,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable)
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MEC_CTRL), &req, sizeof(req), true);
}
#endif
@@ -219,7 +218,7 @@
int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp);
diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 0339d4b..0798b08 100644
+index b6f36f5..a7e8598 100644
--- a/mt7915/regs.h
+++ b/mt7915/regs.h
@@ -1205,6 +1205,8 @@ enum offs_rev {
@@ -232,7 +231,7 @@
#define MT_WF_PHY_BASE 0x83080000
#define MT_WF_PHY(ofs) (MT_WF_PHY_BASE + (ofs))
diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 6a18cdb..09b0e98 100644
+index 40a3a06..b98aaaa 100644
--- a/mt7915/testmode.c
+++ b/mt7915/testmode.c
@@ -13,6 +13,12 @@ enum {
@@ -261,12 +260,53 @@
};
struct reg_band {
-@@ -962,6 +974,216 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
+@@ -981,6 +993,272 @@ mt7915_tm_set_txbf(struct mt7915_phy *phy)
return 0;
}
++static u8
++mt7915_tm_get_center_chan(struct mt7915_phy *phy, struct cfg80211_chan_def *chandef,
++ int width_mhz)
++{
++ struct mt76_phy *mphy = phy->mt76;
++ const struct ieee80211_channel *chan = mphy->sband_5g.sband.channels;
++ u32 bitmap, i, offset, size = 32;
++ u16 first_control = 0, control_chan = chandef->chan->hw_value;
++ static const u32 width_to_bitmap[] = {
++ [NL80211_CHAN_WIDTH_20_NOHT] = 0x0,
++ [NL80211_CHAN_WIDTH_20] = 0x0,
++ [NL80211_CHAN_WIDTH_40] = 0x55554055,
++ [NL80211_CHAN_WIDTH_80] = 0x44444011,
++ [NL80211_CHAN_WIDTH_80P80] = 0x0,
++ [NL80211_CHAN_WIDTH_160] = 0x04004001,
++ };
++
++ bitmap = width_to_bitmap[chandef->width];
++ if (!bitmap)
++ return control_chan;
++
++ offset = width_mhz / 10 - 2;
++ for (i = 0; i < size; i++) {
++ if (!((1 << i) & bitmap))
++ continue;
++
++ if (control_chan >= chan[i].hw_value)
++ first_control = chan[i].hw_value;
++ else
++ break;
++ }
++
++ if (chandef->width == NL80211_CHAN_WIDTH_40 &&
++ control_chan >= chan[size].hw_value)
++ return chan[size].hw_value + offset;
++ else if (first_control == 0)
++ return control_chan;
++
++ return first_control + offset;
++}
++
+static int
-+mt7915_tm_set_offchan(struct mt7915_phy *phy)
++mt7915_tm_set_offchan(struct mt7915_phy *phy, bool no_center)
+{
+ struct mt76_phy *mphy = phy->mt76;
+ struct mt7915_dev *dev = phy->dev;
@@ -293,10 +333,24 @@
+
+ chandef.width = td->offchan_bw;
+ width_mhz = bw_to_mhz[chandef.width];
-+ chandef.center_freq1 = freq;
+ chan = ieee80211_get_channel(hw->wiphy, freq);
++ if (!chan) {
++ ret = -EINVAL;
++ dev_info(dev->mt76.dev, "Failed to set offchan (invalid control channel)!\n");
++ goto out;
++ }
+ chandef.chan = chan;
+
++ if (no_center)
++ td->offchan_center_ch = mt7915_tm_get_center_chan(phy, &chandef, width_mhz);
++ chandef.center_freq1 = ieee80211_channel_to_frequency(td->offchan_center_ch,
++ NL80211_BAND_5GHZ);
++ if (!cfg80211_chandef_valid(&chandef)) {
++ ret = -EINVAL;
++ dev_info(dev->mt76.dev, "Failed to set offchan, chandef is invalid!\n");
++ goto out;
++ }
++
+ memset(&dev->rdd2_chandef, 0, sizeof(struct cfg80211_chan_def));
+
+ ret = mt7915_mcu_rdd_background_enable(phy, &chandef);
@@ -311,6 +365,7 @@
+
+out:
+ td->offchan_ch = 0;
++ td->offchan_center_ch = 0;
+ td->offchan_bw = 0;
+
+ return ret;
@@ -478,7 +533,7 @@
static int
mt7915_tm_set_wmm_qid(struct mt7915_phy *phy, u8 qid, u8 aifs, u8 cw_min,
u16 cw_max, u16 txop, u8 tx_cmd)
-@@ -1249,6 +1471,8 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
+@@ -1268,6 +1546,8 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
phy->mt76->test.tx_mpdu_len = 0;
phy->test.bf_en = 0;
mt7915_tm_set_entry(phy);
@@ -487,13 +542,13 @@
}
}
-@@ -2008,6 +2232,14 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
+@@ -2027,6 +2307,14 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
mt7915_tm_set_cfg(phy);
if (changed & BIT(TM_CHANGED_TXBF_ACT))
mt7915_tm_set_txbf(phy);
+ if ((changed & BIT(TM_CHANGED_OFF_CHAN_CH)) &&
+ (changed & BIT(TM_CHANGED_OFF_CHAN_BW)))
-+ mt7915_tm_set_offchan(phy);
++ mt7915_tm_set_offchan(phy, !(changed & BIT(TM_CHANGED_OFF_CHAN_CENTER_CH)));
+ if ((changed & BIT(TM_CHANGED_IPI_THRESHOLD)) &&
+ (changed & BIT(TM_CHANGED_IPI_PERIOD)))
+ mt7915_tm_set_ipi(phy);
@@ -503,7 +558,7 @@
static int
diff --git a/testmode.c b/testmode.c
-index f1982ac..503d714 100644
+index 39cacb2..293ad98 100644
--- a/testmode.c
+++ b/testmode.c
@@ -24,6 +24,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
@@ -567,11 +622,11 @@
nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
diff --git a/testmode.h b/testmode.h
-index bbfb313..e03fa6d 100644
+index d2675dd..97e7596 100644
--- a/testmode.h
+++ b/testmode.h
@@ -63,6 +63,20 @@
- * (nested, u8 attrs)
+ * (nested, u8 attrs)
*
* @MT76_TM_ATTR_CFG: config testmode rf feature (nested, see &mt76_testmode_cfg)
+ * @MT76_TM_ATTR_TXBF_ACT: txbf setting actions (u8)
diff --git a/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch b/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
index 3ae285a..1163a02 100644
--- a/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
+++ b/recipes-wifi/linux-mt76/files/patches/1014-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch
@@ -1,4 +1,4 @@
-From 4340e9c467389c104e62d7cd060a5494d83f24bf Mon Sep 17 00:00:00 2001
+From 44b3c5fed9a9c63e7da34004d265669f241a2886 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Thu, 15 Dec 2022 19:45:18 +0800
Subject: [PATCH] wifi: mt76: testmode: add iBF/eBF cal and cert commands with
@@ -836,7 +836,7 @@
+}
+#endif
diff --git a/mt7915/regs.h b/mt7915/regs.h
-index 0d90251e..a0d5324b 100644
+index a7e8598..5d91b80 100644
--- a/mt7915/regs.h
+++ b/mt7915/regs.h
@@ -61,6 +61,7 @@ enum offs_rev {
@@ -858,7 +858,7 @@
#define MT_WF_RMAC_BASE(_band) ((_band) ? 0x820f5000 : 0x820e5000)
#define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs))
diff --git a/mt7915/testmode.c b/mt7915/testmode.c
-index 09b0e98e..b99bed54 100644
+index b98aaaa..5665da7 100644
--- a/mt7915/testmode.c
+++ b/mt7915/testmode.c
@@ -53,6 +53,8 @@ struct reg_band {
@@ -1491,7 +1491,7 @@
- pr_info("ibf cal process: act = %u, val = %u, %u, %u, %u, %u, %u\n",
- td->txbf_act, val[0], val[1], val[2], val[3], val[4], val[5]);
-+ dev_info(phy->dev->mt76.dev, "ibf cal process: act = %u, val = %u, %u, %u, %u, %u, %u\n",
++ dev_info(phy->dev->mt76.dev, "ibf cal process: act = %u, val = %u, %u, %u, %u, %u, %u, %u\n",
+ td->txbf_act, val[0], val[1], val[2], val[3], val[4], val[5], val[6]);
switch (td->txbf_act) {
@@ -1701,7 +1701,7 @@
rateval = mode << 6 | rate_idx;
tx_cont->rateval = cpu_to_le16(rateval);
diff --git a/mt7915/testmode.h b/mt7915/testmode.h
-index d500987d..19823694 100644
+index 7569826..5aba13c 100644
--- a/mt7915/testmode.h
+++ b/mt7915/testmode.h
@@ -311,137 +311,7 @@ struct mt7915_tm_muru {
@@ -1845,7 +1845,7 @@
#endif
diff --git a/testmode.c b/testmode.c
-index 503d714b..91638083 100644
+index 293ad98..f16c6ea 100644
--- a/testmode.c
+++ b/testmode.c
@@ -194,6 +194,7 @@ mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len,
@@ -1857,7 +1857,7 @@
memcpy(hdr->addr2, addr[1], ETH_ALEN);
memcpy(hdr->addr3, addr[2], ETH_ALEN);
diff --git a/testmode.h b/testmode.h
-index e03fa6df..0e96173b 100644
+index 97e7596..e13920e 100644
--- a/testmode.h
+++ b/testmode.h
@@ -299,7 +299,10 @@ enum mt76_testmode_cfg {
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin
index d5d541f..1c7710b 100755
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_dsp.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
index 8a02116..7b151c9 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_rom_patch.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin
index 924509d..b0433e8 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wa.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin
index 5bbf475..7188830 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm.bin
Binary files differ
diff --git a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin
index 8f91f29..9ddee02 100644
--- a/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin
+++ b/recipes-wifi/linux-mt76/files/src/firmware/mt7996/mt7996_wm_tm.bin
Binary files differ
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/432-missing-typedef.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/432-missing-typedef.patch
deleted file mode 100644
index 7a100f1..0000000
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/432-missing-typedef.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/src/drivers/linux_wext.h
-+++ b/src/drivers/linux_wext.h
-@@ -26,6 +26,7 @@ typedef int32_t __s32;
- typedef uint16_t __u16;
- typedef int16_t __s16;
- typedef uint8_t __u8;
-+typedef int8_t __s8;
- #ifndef __user
- #define __user
- #endif /* __user */
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
index a79555a..0892d3f 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0006-hostapd-mtk-Add-hostapd-MU-SET-GET-control.patch
@@ -1,7 +1,7 @@
-From fd2df638591cc86c21153e94abe8fc00451703b8 Mon Sep 17 00:00:00 2001
+From ee34d2ccb27863f0eaa7abb0f65477ab9a0dd92f Mon Sep 17 00:00:00 2001
From: TomLiu <tomml.liu@mediatek.com>
Date: Tue, 9 Aug 2022 10:23:44 -0700
-Subject: [PATCH 06/28] hostapd: mtk: Add hostapd MU SET/GET control
+Subject: [PATCH 06/32] hostapd: mtk: Add hostapd MU SET/GET control
---
hostapd/config_file.c | 9 +++
@@ -156,14 +156,14 @@
{ "dpp_qr_code", hostapd_cli_cmd_dpp_qr_code, NULL,
"report a scanned DPP URI from a QR Code" },
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
-index 55c35c7..1cad303 100644
+index 55c35c7..afa19ec 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -280,6 +280,7 @@ struct hostapd_config * hostapd_config_defaults(void)
conf->he_6ghz_max_ampdu_len_exp = 7;
conf->he_6ghz_rx_ant_pat = 1;
conf->he_6ghz_tx_ant_pat = 1;
-+ conf->mu_onoff = 13;
++ conf->mu_onoff = 15;
#endif /* CONFIG_IEEE80211AX */
/* The third octet of the country string uses an ASCII space character
@@ -446,5 +446,5 @@
}
--
-2.18.0
+2.39.0
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
index c53b55a..bf91686 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0018-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
@@ -1,19 +1,18 @@
-From 3237a993233da052219018eec10ca82d79225fdb Mon Sep 17 00:00:00 2001
+From 705e1a59381e7bbd92043ad4338834aad504f232 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 20 Feb 2023 16:58:20 +0800
-Subject: [PATCH 18/28] hostapd: mtk: Fix auto ht issue when switching to DFS
- channel
+Subject: [PATCH] hostapd: mtk: Fix auto ht issue when switching to DFS channel
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
- hostapd/ctrl_iface.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
+ hostapd/ctrl_iface.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 07de0ad..be86f6c 100644
+index 07de0ad..3c38df5 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
-@@ -2773,6 +2773,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2773,6 +2773,13 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
break;
}
@@ -21,12 +20,13 @@
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
++ settings.freq_params.eht_enabled = iface->conf->ieee80211be;
+ }
+
if (settings.freq_params.center_freq1)
dfs_range += hostapd_is_dfs_overlap(
iface, bandwidth, settings.freq_params.center_freq1);
-@@ -2810,12 +2816,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2810,12 +2817,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
return 0;
}
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0101-hostapd-mtk-Fix-CCA-issue.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-hostapd-mtk-Fix-CCA-issue.patch
similarity index 88%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0101-hostapd-mtk-Fix-CCA-issue.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-hostapd-mtk-Fix-CCA-issue.patch
index 9b46d70..e4667e4 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0101-hostapd-mtk-Fix-CCA-issue.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0029-hostapd-mtk-Fix-CCA-issue.patch
@@ -1,12 +1,12 @@
-From 39a0dd44653f12ce13af68de81bfae683669623a Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Thu, 11 May 2023 14:08:59 +0800
-Subject: [PATCH 101/103] hostapd: mtk: Fix CCA issue
+From c92a1e50abdad2bf3e961c9d5aa34baea81f025b Mon Sep 17 00:00:00 2001
+From: Michael Lee <michael-cy.lee@mediatek.com>
+Date: Wed, 3 May 2023 14:55:18 +0800
+Subject: [PATCH] hostapd: mtk: Fix CCA issue
-When receiving CCA related nl80211 command, hostapd used to work on
+When receiving CCA-related nl80211 commands, hostapd used to work on
struct wpa_driver_nl80211_data, whose ctx always points to
-hostpad_iface->bss[0]. However, CCA command is sent on per-BSS based.
-This patch makes hostapd handle CCA related commands on per-BSS based.
+hostpad_iface->bss[0]. However, CCA commands are sent on a per-BSS based.
+This patch makes hostapd handle CCA-related commands on a per-BSS based.
Signed-off-by: Michael Lee <michael-cy.lee@mediatek.com>
---
@@ -93,5 +93,5 @@
#endif /* CONFIG_IEEE80211AX */
default:
--
-2.18.0
+2.25.1
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
similarity index 66%
rename from recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
rename to recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
index 4075531..f9c4714 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch
@@ -1,15 +1,14 @@
-From 097b204ffed838a4bbf7649fb23310f64ace22ad Mon Sep 17 00:00:00 2001
-From: Evelyn Tsai <evelyn.tsai@mediatek.com>
-Date: Thu, 11 May 2023 14:12:44 +0800
-Subject: [PATCH 102/103] hostapd: mtk: Fix unexpected AP beacon state
- transition
+From c4d3890bbf1bd8c8ac8bfaa56fd16e2391e05181 Mon Sep 17 00:00:00 2001
+From: Michael Lee <michael-cy.lee@mediatek.com>
+Date: Wed, 3 May 2023 16:10:57 +0800
+Subject: [PATCH] hostapd: mtk: Fix unexpected AP beacon state transition
-When AP fails setting the beacon, it assigns bss->beacon_set to 0 no
+When AP fails to set the beacon, it assigns bss->beacon_set to 0 no
matter what the error number is.
However, in the case that the error number is -EBUSY, the driver might
not free the beacon and expect a later beacon re-setting. If hostapd set
-a new beacon under this case, driver will return -EALREADY.
-This patch checks the error number after hostapd fails setting the
+a new beacon under this case, the driver will return -EALREADY.
+This patch checks the error number after hostapd fails to set the
beacon. If the error number is -EBUSY, bss->beacon_set will not be
assigned to 0.
@@ -19,7 +18,7 @@
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
-index 8400e57..ccfc2d0 100644
+index 8400e57..5013207 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5126,7 +5126,8 @@ static int wpa_driver_nl80211_set_ap(void *priv,
@@ -33,5 +32,5 @@
bss->flink->beacon_set = 1;
nl80211_set_bss(bss, params->cts_protect, params->preamble,
--
-2.18.0
+2.25.1
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch
new file mode 100644
index 0000000..1c5cacc
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch
@@ -0,0 +1,53 @@
+From 43c8934074a4f6fd1e98143b3bd011e71fe69fdb Mon Sep 17 00:00:00 2001
+From: MeiChia Chiu <meichia.chiu@mediatek.com>
+Date: Fri Jun 9 09:03:05 2023 +0800
+Subject: hostapd: mtk: Add HE capabilities check
+
+Add HE capabilities check.
+Since "HE capabilities" check has been removed by driver,
+add the support for "HE capabilities" check in hostapd.
+
+---
+ src/ap/hw_features.c | 26 ++++++++++++++++++++++++++
+ 1 files changed, 26 insertions(+)
+
+diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
+index 9967494..309f2d5 100644
+--- a/src/ap/hw_features.c
++++ b/src/ap/hw_features.c
+@@ -680,6 +680,32 @@ static int ieee80211ac_supported_vht_capab(struct hostapd_iface *iface)
+ #ifdef CONFIG_IEEE80211AX
+ static int ieee80211ax_supported_he_capab(struct hostapd_iface *iface)
+ {
++ struct hostapd_hw_modes *mode = iface->current_mode;
++ struct he_capabilities *he_cap = &mode->he_capab[IEEE80211_MODE_AP];
++ struct hostapd_config *conf = iface->conf;
++
++#define HE_CAP_CHECK(hw_cap, field, phy_idx, cfg_cap) \
++ do { \
++ if (cfg_cap && !(hw_cap[phy_idx] & field)) { \
++ wpa_printf(MSG_ERROR, "Driver does not support configured" \
++ " HE capability [%s]", #field); \
++ return 0; \
++ } \
++ } while (0)
++
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_LDPC_CODING_IN_PAYLOAD,
++ HE_PHYCAP_LDPC_CODING_IN_PAYLOAD_IDX,
++ conf->he_phy_capab.he_ldpc);
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_SU_BEAMFORMER_CAPAB,
++ HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX,
++ conf->he_phy_capab.he_su_beamformer);
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_SU_BEAMFORMEE_CAPAB,
++ HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX,
++ conf->he_phy_capab.he_su_beamformee);
++ HE_CAP_CHECK(he_cap->phy_cap, HE_PHYCAP_MU_BEAMFORMER_CAPAB,
++ HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX,
++ conf->he_phy_capab.he_mu_beamformer);
++
+ return 1;
+ }
+ #endif /* CONFIG_IEEE80211AX */
+--
+2.39.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
new file mode 100644
index 0000000..01a134e
--- /dev/null
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch
@@ -0,0 +1,44 @@
+From 0aaec4ebc72e40da76a279d817763f4655f45d21 Mon Sep 17 00:00:00 2001
+From: mtk23510 <rudra.shahi@mediatek.com>
+Date: Fri, 26 May 2023 14:52:35 +0800
+Subject: [PATCH] hostapd: mtk: Add support for gtk rekeying in hostapd cli
+
+Signed-off-by: mtk23510 <rudra.shahi@mediatek.com>
+---
+ hostapd/hostapd_cli.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/hostapd/hostapd_cli.c b/hostapd/hostapd_cli.c
+index 02f8546..d529bbc 100644
+--- a/hostapd/hostapd_cli.c
++++ b/hostapd/hostapd_cli.c
+@@ -1256,6 +1256,15 @@ static int hostapd_cli_cmd_update_beacon(struct wpa_ctrl *ctrl, int argc,
+ }
+
+
++#ifdef CONFIG_TESTING_OPTIONS
++static int hostapd_cli_cmd_rekey_gtk(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "REKEY_GTK");
++}
++#endif
++
++
+ static int hostapd_cli_cmd_vendor(struct wpa_ctrl *ctrl, int argc, char *argv[])
+ {
+ char cmd[256];
+@@ -1761,6 +1770,10 @@ static const struct hostapd_cli_cmd hostapd_cli_commands[] = {
+ "= disable hostapd on current interface" },
+ { "update_beacon", hostapd_cli_cmd_update_beacon, NULL,
+ "= update Beacon frame contents\n"},
++#ifdef CONFIG_TESTING_OPTIONS
++ { "rekey_gtk", hostapd_cli_cmd_rekey_gtk, NULL,
++ "= rekey gtk\n"},
++#endif
+ { "erp_flush", hostapd_cli_cmd_erp_flush, NULL,
+ "= drop all ERP keys"},
+ { "log_level", hostapd_cli_cmd_log_level, NULL,
+--
+2.18.0
+
diff --git a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
index a71c43f..a0c06b1 100644
--- a/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
+++ b/recipes-wifi/wpa-supplicant/files/patches-2.10.3/patches.inc
@@ -36,7 +36,6 @@
file://420-indicate-features.patch \
file://430-hostapd_cli_ifdef.patch \
file://431-wpa_cli_ifdef.patch \
- file://432-missing-typedef.patch \
file://450-scan_wait.patch;apply=no \
file://460-wpa_supplicant-add-new-config-params-to-be-used-with.patch \
file://463-add-mcast_rate-to-11s.patch \
@@ -87,8 +86,10 @@
file://mtk-0026-hostapd-mtk-avoid-setting-beacon-after-wpa_supplican.patch \
file://mtk-0027-hostapd-mtk-Fix-setting-wrong-seg0-index-for-5G-cent.patch \
file://mtk-0028-hostapd-mtk-Add-muru-user-number-debug-command.patch \
+ file://mtk-0029-hostapd-mtk-Fix-CCA-issue.patch \
+ file://mtk-0030-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch \
+ file://mtk-0032-hostapd-mtk-Add-HE-capabilities-check.patch \
file://mtk-0100-hostapd-mtk-update-eht-operation-element.patch \
- file://mtk-0101-hostapd-mtk-Fix-CCA-issue.patch \
- file://mtk-0102-hostapd-mtk-Fix-unexpected-AP-beacon-state-transitio.patch \
file://mtk-0103-hostapd-mtk-Add-BW320-channel-switch-command.patch \
+ file://mtk-0104-hostapd-mtk-Add-support-for-gtk-rekeying-in-hostapd-.patch \
"
diff --git a/recipes-wifi/wpa-supplicant/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch b/recipes-wifi/wpa-supplicant/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
index f89da87..d5f0dac 100644
--- a/recipes-wifi/wpa-supplicant/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
+++ b/recipes-wifi/wpa-supplicant/files/patches/mtk-0019-hostapd-mtk-Fix-auto-ht-issue-when-switching-to-DFS-.patch
@@ -1,19 +1,18 @@
-From 0aa1200534c41279f5f05e1919040a86f003ca0a Mon Sep 17 00:00:00 2001
+From a71a78bc51b74d331aeb3f900c03480d058d5233 Mon Sep 17 00:00:00 2001
From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Date: Mon, 20 Feb 2023 16:58:20 +0800
-Subject: [PATCH 19/29] hostapd: mtk: Fix auto ht issue when switching to DFS
- channel
+Subject: [PATCH] hostapd: mtk: Fix auto ht issue when switching to DFS channel
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
---
- hostapd/ctrl_iface.c | 13 +++++++------
- 1 file changed, 7 insertions(+), 6 deletions(-)
+ hostapd/ctrl_iface.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
-index 61c9e80..06cbea1 100644
+index 61c9e80..c33b7a4 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
-@@ -2698,6 +2698,13 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2698,6 +2698,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
break;
}
@@ -21,13 +20,12 @@
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
-+ settings.freq_params.eht_enabled = iface->conf->ieee80211be;
+ }
+
if (settings.freq_params.center_freq1)
dfs_range += hostapd_is_dfs_overlap(
iface, bandwidth, settings.freq_params.center_freq1);
-@@ -2735,12 +2742,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
+@@ -2735,12 +2741,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
return 0;
}