[rdkb][common][bsp][Refactor and sync kernel from openwrt]
[Description]
68c27229 [kernel][mt7988][eth][remove XFRM offload related code]
8e0c3427 [kernel][common][eth][Add MIB read feature to the Aquantia PHY driver]
a6ac22c6 [kernel][mt7988][eth][i2.5Gphy: Add 20230731 version firmware]
[Release-log]
Change-Id: I6f24b3d195da60efd817f1472b9accf4eb0e067d
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/Makefile b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/Makefile
old mode 100755
new mode 100644
index 13d852c..634640d
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/Makefile
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/Makefile
@@ -6,4 +6,3 @@
obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_usxgmii.o mtk_eth_path.o mtk_eth_dbg.o mtk_eth_reset.o
obj-$(CONFIG_NET_MEDIATEK_HNAT) += mtk_hnat/
-obj-$(CONFIG_XFRM_OFFLOAD) += mtk_ipsec.o
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
old mode 100755
new mode 100644
index 353b656..6272f11
--- 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
@@ -31,12 +31,6 @@
#include "mtk_hnat/nf_hnat_mtk.h"
#endif
-#if defined(CONFIG_XFRM_OFFLOAD)
-#include <crypto/sha.h>
-#include <net/xfrm.h>
-#include "mtk_ipsec.h"
-#endif
-
static int mtk_msg_level = -1;
atomic_t reset_lock = ATOMIC_INIT(0);
atomic_t force = ATOMIC_INIT(0);
@@ -4935,9 +4929,6 @@
mtk_napi_rx, MTK_NAPI_WEIGHT);
}
-#if defined(CONFIG_XFRM_OFFLOAD)
- mtk_ipsec_offload_init(eth);
-#endif
mtketh_debugfs_init(eth);
debug_proc_init(eth);
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c
deleted file mode 100644
index ff61b90..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.c
+++ /dev/null
@@ -1,326 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-// Copyright (c) 2022 MediaTek Inc.
-
-#include <crypto/aes.h>
-#include <crypto/hash.h>
-#include <crypto/hmac.h>
-#include <crypto/sha.h>
-#include <crypto/sha3.h>
-#include <net/xfrm.h>
-#include <linux/ip.h>
-#include <linux/psp-sev.h>
-#include <linux/netdevice.h>
-
-#include "mtk_eth_soc.h"
-#include "mtk_ipsec.h"
-
-static inline void write_state_le(__le32 *dst, const u32 *src, u32 size)
-{
- int i;
-
- for (i = 0; i < SIZE_IN_WORDS(size); i++)
- dst[i] = cpu_to_le32(src[i]);
-}
-
-static inline void write_state_be(__le32 *dst, const u32 *src, u32 size)
-{
- int i;
-
- for (i = 0; i < SIZE_IN_WORDS(size); i++)
- dst[i] = cpu_to_be32(src[i]);
-}
-
-static int hmac_init_iv(struct crypto_shash *tfm,
- unsigned int blocksize, u8 *pad, void *state)
-{
- SHASH_DESC_ON_STACK(desc, tfm);
- int ret;
-
- desc->tfm = tfm;
-
- ret = crypto_shash_init(desc);
- if (ret)
- return ret;
-
- ret = crypto_shash_update(desc, pad, blocksize);
- if (ret && ret != -EINPROGRESS && ret != -EBUSY)
- return ret;
-
- crypto_shash_export(desc, state);
- shash_desc_zero(desc);
-
- return 0;
-}
-
-static int hmac_init_pad(unsigned int blocksize, const u8 *key,
- unsigned int keylen, u8 *ipad, u8 *opad)
-{
- int i;
-
- if (keylen <= blocksize)
- memcpy(ipad, key, keylen);
-
- memset(ipad + keylen, 0, blocksize - keylen);
- memcpy(opad, ipad, blocksize);
-
- for (i = 0; i < blocksize; i++) {
- ipad[i] ^= HMAC_IPAD_VALUE;
- opad[i] ^= HMAC_OPAD_VALUE;
- }
-
- return 0;
-}
-
-int hmac_setkey(const char *alg, const u8 *key, unsigned int keylen,
- void *istate, void *ostate)
-{
- struct crypto_shash *tfm;
- unsigned int blocksize;
- u8 *ipad, *opad;
- int ret;
-
- tfm = crypto_alloc_shash(alg, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- crypto_shash_clear_flags(tfm, ~0);
- blocksize = crypto_tfm_alg_blocksize(crypto_shash_tfm(tfm));
-
- ipad = kcalloc(2, blocksize, GFP_KERNEL);
- if (!ipad) {
- ret = -ENOMEM;
- goto free_request;
- }
-
- opad = ipad + blocksize;
-
- ret = hmac_init_pad(blocksize, key, keylen, ipad, opad);
- if (ret)
- goto free_ipad;
-
- ret = hmac_init_iv(tfm, blocksize, ipad, istate);
- if (ret)
- goto free_ipad;
-
- ret = hmac_init_iv(tfm, blocksize, opad, ostate);
-
-free_ipad:
- kfree(ipad);
-free_request:
- crypto_free_shash(tfm);
-
- return ret;
-}
-
-static int mtk_ipsec_add_sa(struct xfrm_state *xs)
-{
- struct net_device *dev = xs->xso.dev;
- struct mtk_mac *mac = netdev_priv(dev);
- struct mtk_eth *eth = mac->hw;
- struct context_record *context;
- struct ahash_export_state istate, ostate;
- unsigned char *key_aalg;
- unsigned char *key_ealg;
- unsigned int checksum;
- unsigned int key_len;
- int i;
- int cdrt_idx;
-
- if (xs->props.family != AF_INET) {
- netdev_info(dev, "Only IPv4 xfrm states may be offloaded\n");
- return -EINVAL;
- }
-
- if (xs->id.proto != IPPROTO_ESP) {
- netdev_info(dev, "Unsupported protocol 0x%04x\n",
- xs->id.proto);
- return -EINVAL;
- }
-
- context = kzalloc(sizeof(*context), GFP_KERNEL);
- if (unlikely(!context))
- return -ENOMEM;
-
- /**
- * Set Transform record
- * cdrt_idx=0, outbound for encryption
- * cdrt_idx=1, inbound for decryption
- **/
- if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
- /* rx path */
- context->control0 = CTRL_WORD0_IN;
- context->control1 = CTRL_WORD1_IN;
- context->data[46] = 0x01020000;
- context->data[49] = 0x6117d6a5;
- context->data[50] = 0x07040c10;
- context->data[52] = 0xdd07000c;
- context->data[53] = 0xe4561820;
- cdrt_idx = 1;
-
- } else {
- /* tx path */
- context->control0 = CTRL_WORD0_OUT;
- context->control1 = CTRL_WORD1_OUT;
- memcpy(context->data + 38, &xs->props.saddr.a4, 4);
- memcpy(context->data + 42, &xs->id.daddr.a4, 4);
- context->data[46] = 0x04020000;
- context->data[49] = 0x9e14ed69;
- context->data[50] = 0x01020c10;
- context->data[52] = 0xd0060000;
- context->data[53] = 0xe1560811;
- context->data[55] = 0x00000049;
- cdrt_idx = 0;
- }
- context->data[47] = 0x00080000;
- context->data[48] = 0x00f00008;
- context->data[51] = 0x94119411;
-
- /* Calculate Checksum */
- checksum = 0;
- checksum += context->data[38] % 0x10000;
- checksum += context->data[38] / 0x10000;
- checksum += context->data[42] % 0x10000;
- checksum += context->data[42] / 0x10000;
- checksum += checksum / 0x10000;
- checksum = checksum % 0x10000;
- context->data[39] = checksum;
-
- /* EIP-96 context words[2...39]*/
- if (strcmp(xs->aalg->alg_name, "hmac(sha1)") == 0) {
- key_aalg = &xs->aalg->alg_key[0];
- hmac_setkey("sha1-generic", key_aalg,
- xs->aalg->alg_key_len / 8,
- &istate.state, &ostate.state);
- key_ealg = &xs->ealg->alg_key[0];
- key_len = xs->ealg->alg_key_len / 8;
- write_state_le(context->data, (const u32 *)key_ealg, key_len);
- write_state_be(context->data + SIZE_IN_WORDS(key_len),
- (const u32 *)&istate.state, SHA1_DIGEST_SIZE);
-
- key_len += SHA1_DIGEST_SIZE;
- write_state_be(context->data + SIZE_IN_WORDS(key_len),
- (const u32 *)&ostate.state, SHA1_DIGEST_SIZE);
-
- key_len += SHA1_DIGEST_SIZE;
- memcpy(context->data + SIZE_IN_WORDS(key_len),
- &xs->id.spi, 4);
- } else if (strcmp(xs->aalg->alg_name, "hmac(sha256)") == 0) {
- key_aalg = &xs->aalg->alg_key[0];
- hmac_setkey("sha256-generic", key_aalg,
- xs->aalg->alg_key_len / 8,
- &istate.state, &ostate.state);
- key_ealg = &xs->ealg->alg_key[0];
- key_len = xs->ealg->alg_key_len / 8;
- write_state_le(context->data, (const u32 *)key_ealg, key_len);
- write_state_be(context->data + SIZE_IN_WORDS(key_len),
- (const u32 *)&istate.state, SHA256_DIGEST_SIZE);
-
- key_len += SHA256_DIGEST_SIZE;
- write_state_be(context->data + SIZE_IN_WORDS(key_len),
- (const u32 *)&ostate.state, SHA256_DIGEST_SIZE);
-
- key_len += SHA256_DIGEST_SIZE;
- memcpy(context->data + SIZE_IN_WORDS(key_len),
- &xs->id.spi, 4);
-
- if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
- /* rx path */
- context->control0 = CTRL_WORD0_IN_SHA256;
- context->control1 = CTRL_WORD1_IN_SHA256;
- context->data[50] = 0x07041010;
- context->data[52] = 0xdd070010;
- context->data[53] = 0xe4561820;
- } else {
- /* tx path */
- context->control0 = CTRL_WORD0_OUT_SHA256;
- context->control1 = CTRL_WORD1_OUT_SHA256;
- context->data[50] = 0x01021010;
- context->data[53] = 0xe1560817;
- context->data[55] = 0x0000004d;
- }
- }
-
- /**
- * Set CDRT for inline IPSec
- * Follow FE_CSR_MEM config flow.
- **/
-
- /* Command descriptor W0-W3 */
- for (i = MTK_GLO_MEM_DATA0; i <= MTK_GLO_MEM_DATA9; i = i + 4)
- mtk_w32(eth, 0, i);
-
- mtk_w32(eth, TYPE(3), MTK_GLO_MEM_DATA0);
- mtk_w32(eth, TOKEN_LEN(48), MTK_GLO_MEM_DATA1);
- mtk_w32(eth, __psp_pa(context) | 2, MTK_GLO_MEM_DATA2);
- mtk_w32(eth, CTRL_CMD(1) | CTRL_INDEX(3) | CTRL_ADDR(cdrt_idx * 3),
- MTK_GLO_MEM_CTRL);
-
- /* Command descriptor W4-W7 */
- for (i = MTK_GLO_MEM_DATA0; i <= MTK_GLO_MEM_DATA9; i = i + 4)
- mtk_w32(eth, 0, i);
-
- mtk_w32(eth, HW_SER(2) | ALLOW_PAD | STRIP_PAD, MTK_GLO_MEM_DATA0);
- mtk_w32(eth, CTRL_CMD(1) | CTRL_INDEX(3) | CTRL_ADDR(cdrt_idx * 3 + 1),
- MTK_GLO_MEM_CTRL);
-
- /* Command descriptor W8-W11 */
- for (i = MTK_GLO_MEM_DATA0; i <= MTK_GLO_MEM_DATA9; i = i + 4)
- mtk_w32(eth, 0, i);
-
- mtk_w32(eth, CTRL_CMD(1) | CTRL_INDEX(3) | CTRL_ADDR(cdrt_idx * 3 + 2),
- MTK_GLO_MEM_CTRL);
-
- xs->xso.offload_handle = (unsigned long)context;
-
- return 0;
-}
-
-static void mtk_ipsec_free_state(struct xfrm_state *xs)
-{
- struct context_record *context;
-
- if (!xs->xso.offload_handle)
- return;
-
- context = (struct context_record *)xs->xso.offload_handle;
- kfree(context);
-}
-
-static bool mtk_ipsec_offload_ok(struct sk_buff *skb,
- struct xfrm_state *xs)
-{
- struct xfrm_offload *xo = NULL;
-
- if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) {
- /* rx path */
- if (xfrm_offload(skb) != NULL)
- xo = xfrm_offload(skb);
-
- } else {
- /* tx path */
- if (xfrm_offload(skb) != NULL)
- xo = xfrm_offload(skb);
- }
-
- if (xs->props.family == AF_INET) {
- /* Offload with IPv4 options is not supported yet */
- if (ip_hdr(skb)->ihl != 5)
- return false;
- }
-
- return true;
-}
-
-static const struct xfrmdev_ops mtk_xfrmdev_ops = {
- .xdo_dev_state_add = mtk_ipsec_add_sa,
- .xdo_dev_state_free = mtk_ipsec_free_state,
- .xdo_dev_offload_ok = mtk_ipsec_offload_ok,
-};
-
-void mtk_ipsec_offload_init(struct mtk_eth *eth)
-{
- int i;
-
- for (i = 0; i < MTK_MAC_COUNT; i++)
- eth->netdev[i]->xfrmdev_ops = &mtk_xfrmdev_ops;
-}
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.h b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.h
deleted file mode 100644
index a662dc3..0000000
--- a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_ipsec.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2022 MediaTek Inc. */
-
-#ifndef MTK_IPSEC_H
-#define MTK_IPSEC_H
-
-#define CTRL_WORD0_OUT 0x196b1006
-#define CTRL_WORD1_OUT 0x51400001
-#define CTRL_WORD0_IN 0x096ba20f
-#define CTRL_WORD1_IN 0x00010001
-#define CTRL_WORD0_OUT_SHA256 0x19eb1606
-#define CTRL_WORD1_OUT_SHA256 0x57400001
-#define CTRL_WORD0_IN_SHA256 0x09eba20f
-#define CTRL_WORD1_IN_SHA256 0x00010001
-#define SIZE_IN_WORDS(x) ((x) >> 2)
-
-/* Global memory */
-#define MTK_GLO_MEM_CFG 0x600
-#define MTK_GLO_MEM_CTRL 0x604
-#define MTK_GLO_MEM_DATA0 0x608
-#define MTK_GLO_MEM_DATA1 0x60c
-#define MTK_GLO_MEM_DATA2 0x610
-#define MTK_GLO_MEM_DATA3 0x614
-#define MTK_GLO_MEM_DATA4 0x618
-#define MTK_GLO_MEM_DATA5 0x61c
-#define MTK_GLO_MEM_DATA6 0x620
-#define MTK_GLO_MEM_DATA7 0x624
-#define MTK_GLO_MEM_DATA8 0x628
-#define MTK_GLO_MEM_DATA9 0x62c
-
-/* GLO MEM CTRL */
-#define CTRL_CMD(x) ((x) << 30)
-#define CTRL_CMD_SFT 30
-#define CTRL_CMD_MASK GENMASK(31, 30)
-#define CTRL_INDEX(x) ((x) << 20)
-#define CTRL_INDEX_SFT 20
-#define CTRL_INDEX_MASK GENMASK(29, 20)
-#define CTRL_ADDR(x) ((x) << 0)
-#define CTRL_ADDR_SFT 0
-#define CTRL_ADDR_MASK GENMASK(19, 0)
-
-/* CDR Word0 */
-#define TYPE(x) ((x) << 30)
-#define TYPE_SFT 30
-#define TYPE_MASK GENMASK(31, 30)
-#define ENCLASTDEST BIT(25)
-#define ENCLASTDEST_MASK BIT(25)
-
-/* CDR Word1 */
-#define TOKEN_LEN(x) ((x) << 16)
-#define TOKEN_LEN_SFT 16
-#define TOKEN_LEN_MASK GENMASK(23, 16)
-#define APP_ID(x) ((x) << 9)
-#define APP_ID_SFT 9
-#define APP_ID_MASK GENMASK(15, 9)
-#define ADD_LEN(x) ((x) << 0)
-#define ADD_LEN_SFT 0
-#define ADD_LEN_MASK GENMASK(7, 0)
-
-/* CDR Word4 */
-#define FLOW_LOOKUP BIT(31)
-#define FLOW_LOOKUP_MASK BIT(31)
-#define HW_SER(x) ((x) << 24)
-#define HW_SER_SFT 24
-#define HW_SER_MASK GENMASK(29, 24)
-#define ALLOW_PAD BIT(23)
-#define ALLOW_PAD_MASK BIT(23)
-#define STRIP_PAD BIT(22)
-#define STRIP_PAD_MASK BIT(22)
-#define USER_DEF(x) ((x) << 0)
-#define USER_DEF_SFT 0
-#define USER_DEF_MASK GENMASK(15, 0)
-
-/* CDR Word5 */
-#define KEEP_OUTER BIT(28)
-#define KEEP_OUTER_MASK BIT(28)
-#define PARSE_ETH BIT(27)
-#define PARSE_ETH_MASK BIT(27)
-#define L4CHECKSUM BIT(26)
-#define L4CHECKSUM_MASK BIT(26)
-#define IPV4CHECKSUM BIT(25)
-#define IPV4CHECKSUM_MASK BIT(25)
-#define FL BIT(24)
-#define FL_MASK BIT(24)
-#define NEXT_HEADER(x) ((x) << 16)
-#define NEXT_HEADER_SFT 16
-#define NEXT_HEADER_MASK GENMASK(23, 16)
-
-#define HASH_CACHE_SIZE SHA512_BLOCK_SIZE
-
-struct ahash_export_state {
- u64 len;
- u64 processed;
-
- u32 digest;
-
- u32 state[SHA512_DIGEST_SIZE / sizeof(u32)];
- u8 cache[HASH_CACHE_SIZE];
-};
-
-/* Context Control */
-struct context_record {
- __le32 control0;
- __le32 control1;
-
- __le32 data[62];
-};
-
-void mtk_ipsec_offload_init(struct mtk_eth *eth);
-#endif /* MTK_IPSEC_H */
diff --git a/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2728-net-phy-aquantia-add-mib-read.patch b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2728-net-phy-aquantia-add-mib-read.patch
new file mode 100644
index 0000000..9da1224
--- /dev/null
+++ b/recipes-kernel/linux/linux-mediatek-5.4/mediatek/patches-5.4/999-2728-net-phy-aquantia-add-mib-read.patch
@@ -0,0 +1,281 @@
+From f65c0f12471c39c5833b045a429d25ad504dc320 Mon Sep 17 00:00:00 2001
+From: Bo-Cun Chen <bc-bocun.chen@mediatek.com>
+Date: Thu, 3 Aug 2023 17:05:20 +0800
+Subject: [PATCH] 999-2728-net-phy-aquantia-add-mib-read.patch
+
+---
+ drivers/net/phy/Kconfig | 6 ++
+ drivers/net/phy/Makefile | 3 +
+ drivers/net/phy/aquantia.h | 22 +++++
+ drivers/net/phy/aquantia_main.c | 4 +
+ drivers/net/phy/aquantia_mib.c | 167 ++++++++++++++++++++++++++++++++
+ 5 files changed, 202 insertions(+)
+ create mode 100644 drivers/net/phy/aquantia_mib.c
+
+diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
+index d467834..d6e2f37 100644
+--- a/drivers/net/phy/Kconfig
++++ b/drivers/net/phy/Kconfig
+@@ -405,6 +405,12 @@ config AQUANTIA_PHY_FW_FILE
+ ---help---
+ Currently supports the Aquantia AQR113c
+
++config AQUANTIA_PHY_MIB
++ tristate "MIB Read Enable"
++ depends on AQUANTIA_PHY
++ ---help---
++ Currently supports the Aquantia AQR113C
++
+ config AX88796B_PHY
+ tristate "Asix PHYs"
+ help
+diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
+index e9653de..7aff0be 100644
+--- a/drivers/net/phy/Makefile
++++ b/drivers/net/phy/Makefile
+@@ -71,6 +71,9 @@ endif
+ ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
+ aquantia-objs += aquantia_firmware.o
+ endif
++ifdef CONFIG_AQUANTIA_PHY_MIB
++aquantia-objs += aquantia_mib.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 ab1c241..68845b5 100644
+--- a/drivers/net/phy/aquantia.h
++++ b/drivers/net/phy/aquantia.h
+@@ -47,6 +47,21 @@ static const struct aqr107_hw_stat aqr107_hw_stats[] = {
+ };
+ #define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
+
++#ifdef CONFIG_AQUANTIA_PHY_MIB
++struct aqr107_mib_stat {
++ u64 crc8_error_packets;
++ u64 ldpc_error_packets;
++ u64 ls_tx_good_packets;
++ u64 ls_tx_bad_packets;
++ u64 ls_rx_good_packets;
++ u64 ls_rx_bad_packets;
++ u64 ss_tx_good_packets;
++ u64 ss_tx_bad_packets;
++ u64 ss_rx_good_packets;
++ u64 ss_rx_bad_packets;
++};
++#endif
++
+ struct aqr107_priv {
+ u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
+ #ifdef CONFIG_AQUANTIA_PHY_FW_DOWNLOAD
+@@ -57,6 +72,10 @@ struct aqr107_priv {
+ int fw_dl_mode;
+ u16 heartbeat;
+ #endif
++#ifdef CONFIG_AQUANTIA_PHY_MIB
++ struct aqr107_mib_stat mib;
++ struct task_struct *mib_thread;
++#endif
+ };
+
+ int aqr107_set_downshift(struct phy_device *phydev, u8 cnt);
+@@ -78,3 +97,6 @@ enum {
+ int aqr_firmware_heartbeat_thread(void *data);
+ int aqr_firmware_download(struct phy_device *phydev);
+ #endif
++#ifdef CONFIG_AQUANTIA_PHY_MIB
++int aqr107_config_mib(struct phy_device *phydev);
++#endif
+\ No newline at end of file
+diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c
+index 874cd26..5c05ea8 100644
+--- a/drivers/net/phy/aquantia_main.c
++++ b/drivers/net/phy/aquantia_main.c
+@@ -605,6 +605,10 @@ static int aqr107_probe(struct phy_device *phydev)
+ if (!phydev->priv)
+ return -ENOMEM;
+
++#ifdef CONFIG_AQUANTIA_PHY_MIB
++ aqr107_config_mib(phydev);
++#endif
++
+ return aqr_hwmon_probe(phydev);
+ }
+
+diff --git a/drivers/net/phy/aquantia_mib.c b/drivers/net/phy/aquantia_mib.c
+new file mode 100644
+index 0000000..07223fa
+--- /dev/null
++++ b/drivers/net/phy/aquantia_mib.c
+@@ -0,0 +1,167 @@
++// SPDX-License-Identifier: GPL-2.0
++/* Packet counter driver for Aquantia PHY
++ */
++
++#include <linux/phy.h>
++#include <linux/kernel.h>
++#include <linux/debugfs.h>
++#include <linux/kthread.h>
++
++#include "aquantia.h"
++
++#define MDIO_PCS_LS_TX_GOOD_COUNTER 0xc820
++#define MDIO_PCS_LS_TX_BAD_COUNTER 0xc822
++#define MDIO_PCS_SS_TX_GOOD_COUNTER 0xc860
++#define MDIO_PCS_SS_TX_BAD_COUNTER 0xc862
++#define MDIO_PCS_CRC8_ERROR_COUNTER 0xe810
++#define MDIO_PCS_LS_RX_GOOD_COUNTER 0xe812
++#define MDIO_PCS_LS_RX_BAD_COUNTER 0xe814
++#define MDIO_PCS_LDPC_ERROR_COUNTER 0xe820
++#define MDIO_PCS_SS_RX_GOOD_COUNTER 0xe860
++#define MDIO_PCS_SS_RX_BAD_COUNTER 0xe862
++
++static int aqr107_mib_read_word(struct phy_device *phydev, u32 reg, u16 *lsw, u16 *msw)
++{
++ int val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_PCS, reg + 1);
++ if (val < 0)
++ return val;
++
++ *msw = val;
++
++ val = phy_read_mmd(phydev, MDIO_MMD_PCS, reg);
++ if (val < 0)
++ return val;
++
++ *lsw = val;
++
++ return 0;
++}
++
++static void aqr107_mib_read(struct phy_device *phydev)
++{
++ struct aqr107_priv *priv = phydev->priv;
++ u16 lsw, msw;
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_CRC8_ERROR_COUNTER, &lsw, &msw))
++ priv->mib.crc8_error_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_LDPC_ERROR_COUNTER, &lsw, &msw))
++ priv->mib.ldpc_error_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_LS_TX_GOOD_COUNTER, &lsw, &msw))
++ priv->mib.ls_tx_good_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_LS_TX_BAD_COUNTER, &lsw, &msw))
++ priv->mib.ls_tx_bad_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_LS_RX_GOOD_COUNTER, &lsw, &msw))
++ priv->mib.ls_rx_good_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_LS_RX_BAD_COUNTER, &lsw, &msw))
++ priv->mib.ls_rx_bad_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_SS_TX_GOOD_COUNTER, &lsw, &msw))
++ priv->mib.ss_tx_good_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_SS_TX_BAD_COUNTER, &lsw, &msw))
++ priv->mib.ss_tx_bad_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_SS_RX_GOOD_COUNTER, &lsw, &msw))
++ priv->mib.ss_rx_good_packets += ((msw << 16) | lsw);
++
++ if (!aqr107_mib_read_word(phydev, MDIO_PCS_SS_RX_BAD_COUNTER, &lsw, &msw))
++ priv->mib.ss_rx_bad_packets += ((msw << 16) | lsw);
++}
++
++static int aqr107_mib_thread(void *data)
++{
++ struct phy_device *phydev = data;
++
++ for (;;) {
++ if (kthread_should_stop())
++ break;
++
++ aqr107_mib_read(phydev);
++
++ set_current_state(TASK_INTERRUPTIBLE);
++ schedule_timeout(HZ);
++ }
++
++ return 0;
++}
++
++static int aqr107_mib_show(struct seq_file *m, void *private)
++{
++ struct phy_device *phydev = m->private;
++ struct aqr107_priv *priv = phydev->priv;
++
++ aqr107_mib_read(phydev);
++
++ seq_printf(m, "+---------------------------------+\n");
++ seq_printf(m, "| <<AQUANTIA MIB>> |\n");
++ seq_printf(m, "| CRC8 Error Packets=%012lld |\n", priv->mib.crc8_error_packets);
++ seq_printf(m, "| LDPC Error Packets=%012lld |\n", priv->mib.ldpc_error_packets);
++ seq_printf(m, "| [Line Side]\n");
++ seq_printf(m, "| TX Good Packets=%012lld |\n", priv->mib.ls_tx_good_packets);
++ seq_printf(m, "| TX Bad Packets=%012lld |\n", priv->mib.ls_tx_bad_packets);
++ seq_printf(m, "| RX Good Packets=%012lld |\n", priv->mib.ls_rx_good_packets);
++ seq_printf(m, "| RX Bad Packets=%012lld |\n", priv->mib.ls_rx_bad_packets);
++ seq_printf(m, "| [System Side]\n");
++ seq_printf(m, "| TX Good Packets=%012lld |\n", priv->mib.ss_tx_good_packets);
++ seq_printf(m, "| TX Bad Packets=%012lld |\n", priv->mib.ss_tx_bad_packets);
++ seq_printf(m, "| RX Good Packets=%012lld |\n", priv->mib.ss_rx_good_packets);
++ seq_printf(m, "| RX Bad Packets=%012lld |\n", priv->mib.ss_rx_bad_packets);
++ seq_printf(m, "+---------------------------------+\n");
++
++ memset(&priv->mib, 0, sizeof(priv->mib));
++
++ return 0;
++}
++
++static int aqr107_mib_open(struct inode *inode, struct file *file)
++{
++ return single_open(file, aqr107_mib_show, inode->i_private);
++}
++
++int aqr107_config_mib(struct phy_device *phydev)
++{
++ static const struct file_operations fops_mib = {
++ .open = aqr107_mib_open,
++ .read = seq_read,
++ .llseek = seq_lseek,
++ .release = single_release
++ };
++
++ struct aqr107_priv *priv = phydev->priv;
++ struct dentry *root;
++ char dirname[5];
++
++ snprintf(dirname, sizeof(dirname), "phy%d", phydev->mdio.addr);
++
++ root = debugfs_lookup("aquantia", NULL);
++ if (!root) {
++ root = debugfs_create_dir("aquantia", NULL);
++ if (!root)
++ return -ENOMEM;
++ }
++
++ debugfs_create_file(dirname, S_IRUGO, root, phydev, &fops_mib);
++
++ if (!priv->mib_thread) {
++ /* create a thread for recording packet counts */
++ priv->mib_thread = kthread_create(aqr107_mib_thread,
++ phydev,
++ "aqr107_mib_thread");
++ if (IS_ERR(priv->mib_thread)) {
++ phydev_err(phydev,
++ "failed to create aqr107_mib_thread(%ld)\n",
++ PTR_ERR(priv->mib_thread));
++ return PTR_ERR(priv->mib_thread);
++ }
++ wake_up_process(priv->mib_thread);
++ }
++
++ return 0;
++}
+--
+2.18.0
+
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 2b9ec88..3fce397 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
@@ -147,6 +147,7 @@
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-2727-net-phy-sfp-add-debug-info.patch.patch \
+ file://999-2728-net-phy-aquantia-add-mib-read.patch \
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 \