From: Simon Horman <horms@kernel.org>
To: Vivian Wang <wangruikang@iscas.ac.cn>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>,
Jakub Kicinski <kuba@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>, Yixun Lan <dlan@gentoo.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>, Vivian Wang <uwu@dram.page>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Junhui Liu <junhui.liu@pigmoral.tech>,
Maxime Chevallier <maxime.chevallier@bootlin.com>,
netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-riscv@lists.infradead.org, spacemit@lists.linux.dev,
linux-kernel@vger.kernel.org,
Troy Mitchell <troy.mitchell@linux.spacemit.com>
Subject: Re: [PATCH net-next v10 2/5] net: spacemit: Add K1 Ethernet MAC
Date: Thu, 11 Sep 2025 10:44:04 +0100 [thread overview]
Message-ID: <20250911094404.GE30363@horms.kernel.org> (raw)
In-Reply-To: <20250908-net-k1-emac-v10-2-90d807ccd469@iscas.ac.cn>
On Mon, Sep 08, 2025 at 08:34:26PM +0800, Vivian Wang wrote:
> The Ethernet MACs found on SpacemiT K1 appears to be a custom design
> that only superficially resembles some other embedded MACs. SpacemiT
> refers to them as "EMAC", so let's just call the driver "k1_emac".
>
> Supports RGMII and RMII interfaces. Includes support for MAC hardware
> statistics counters. PTP support is not implemented.
>
> Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
> Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
> Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
> Tested-by: Junhui Liu <junhui.liu@pigmoral.tech>
> Tested-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
> ---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/spacemit/Kconfig | 29 +
> drivers/net/ethernet/spacemit/Makefile | 6 +
> drivers/net/ethernet/spacemit/k1_emac.c | 2156 +++++++++++++++++++++++++++++++
This is a large patch, so I'm sure I've missed some things.
But, overall, I think this is coming together.
Thanks for your recent updates.
As the Kernel Patch Robot noticed a problem,
I've provided some minor feedback for your consideration.
...
> +static void emac_wr(struct emac_priv *priv, u32 reg, u32 val)
> +{
> + writel(val, priv->iobase + reg);
> +}
> +
> +static int emac_rd(struct emac_priv *priv, u32 reg)
nit: maybe u32 would be a more suitable return type.
> +{
> + return readl(priv->iobase + reg);
> +}
...
> +static int emac_alloc_tx_resources(struct emac_priv *priv)
> +{
> + struct emac_desc_ring *tx_ring = &priv->tx_ring;
> + struct platform_device *pdev = priv->pdev;
> + u32 size;
> +
> + size = sizeof(struct emac_tx_desc_buffer) * tx_ring->total_cnt;
> +
> + tx_ring->tx_desc_buf = kzalloc(size, GFP_KERNEL);
nit: I think you can use kcalloc() here.
> + if (!tx_ring->tx_desc_buf)
> + return -ENOMEM;
> +
> + tx_ring->total_size = tx_ring->total_cnt * sizeof(struct emac_desc);
> + tx_ring->total_size = ALIGN(tx_ring->total_size, PAGE_SIZE);
> +
> + tx_ring->desc_addr = dma_alloc_coherent(&pdev->dev, tx_ring->total_size,
> + &tx_ring->desc_dma_addr,
> + GFP_KERNEL);
> + if (!tx_ring->desc_addr) {
> + kfree(tx_ring->tx_desc_buf);
> + return -ENOMEM;
> + }
> +
> + tx_ring->head = 0;
> + tx_ring->tail = 0;
> +
> + return 0;
> +}
...
> +static int emac_alloc_rx_resources(struct emac_priv *priv)
> +{
> + struct emac_desc_ring *rx_ring = &priv->rx_ring;
> + struct platform_device *pdev = priv->pdev;
> + u32 buf_len;
> +
> + buf_len = sizeof(struct emac_rx_desc_buffer) * rx_ring->total_cnt;
> +
> + rx_ring->rx_desc_buf = kzalloc(buf_len, GFP_KERNEL);
Ditto.
> + if (!rx_ring->rx_desc_buf)
> + return -ENOMEM;
> +
> + rx_ring->total_size = rx_ring->total_cnt * sizeof(struct emac_desc);
> +
> + rx_ring->total_size = ALIGN(rx_ring->total_size, PAGE_SIZE);
> +
> + rx_ring->desc_addr = dma_alloc_coherent(&pdev->dev, rx_ring->total_size,
> + &rx_ring->desc_dma_addr,
> + GFP_KERNEL);
> + if (!rx_ring->desc_addr) {
> + kfree(rx_ring->rx_desc_buf);
> + return -ENOMEM;
> + }
> +
> + rx_ring->head = 0;
> + rx_ring->tail = 0;
> +
> + return 0;
> +}
...
> +static int emac_mii_read(struct mii_bus *bus, int phy_addr, int regnum)
> +{
> + struct emac_priv *priv = bus->priv;
> + u32 cmd = 0, val;
> + int ret;
> +
> + cmd |= phy_addr & 0x1F;
> + cmd |= (regnum & 0x1F) << 5;
nit: I think this could benefit from using FIELD_PREP
Likewise for similar patterns in this patch.
> + cmd |= MREGBIT_START_MDIO_TRANS | MREGBIT_MDIO_READ_WRITE;
> +
> + emac_wr(priv, MAC_MDIO_DATA, 0x0);
> + emac_wr(priv, MAC_MDIO_CONTROL, cmd);
> +
> + ret = readl_poll_timeout(priv->iobase + MAC_MDIO_CONTROL, val,
> + !((val >> 15) & 0x1), 100, 10000);
> +
> + if (ret)
> + return ret;
> +
> + val = emac_rd(priv, MAC_MDIO_DATA);
> + return val;
> +}
...
> +/*
> + * Even though this MAC supports gigabit operation, it only provides 32-bit
> + * statistics counters. The most overflow-prone counters are the "bytes" ones,
> + * which at gigabit overflow about twice a minute.
> + *
> + * Therefore, we maintain the high 32 bits of counters ourselves, incrementing
> + * every time statistics seem to go backwards. Also, update periodically to
> + * catch overflows when we are not otherwise checking the statistics often
> + * enough.
> + */
> +
> +#define EMAC_STATS_TIMER_PERIOD 20
> +
> +static int emac_read_stat_cnt(struct emac_priv *priv, u8 cnt, u32 *res,
> + u32 control_reg, u32 high_reg, u32 low_reg)
> +{
> + u32 val;
> + int ret;
> +
> + /* The "read" bit is the same for TX and RX */
> +
> + val = MREGBIT_START_TX_COUNTER_READ | cnt;
> + emac_wr(priv, control_reg, val);
> + val = emac_rd(priv, control_reg);
> +
> + ret = readl_poll_timeout_atomic(priv->iobase + control_reg, val,
> + !(val & MREGBIT_START_TX_COUNTER_READ),
> + 100, 10000);
> +
> + if (ret) {
> + netdev_err(priv->ndev, "Read stat timeout\n");
> + return ret;
> + }
> +
> + *res = emac_rd(priv, high_reg) << 16;
> + *res |= (u16)emac_rd(priv, low_reg);
nit: I think lower_16_bits() and lower_16_bits() would be appropriate here.
> +
> + return 0;
> +}
...
> +static void emac_update_counter(u64 *counter, u32 new_low)
> +{
> + u32 old_low = (u32)*counter;
> + u64 high = *counter >> 32;
Similarly, lower_32_bits() and upper_32_bits here.
> +
> + if (old_low > new_low) {
> + /* Overflowed, increment high 32 bits */
> + high++;
> + }
> +
> + *counter = (high << 32) | new_low;
> +}
> +
> +static void emac_stats_update(struct emac_priv *priv)
> +{
> + u64 *tx_stats_off = (u64 *)&priv->tx_stats_off;
> + u64 *rx_stats_off = (u64 *)&priv->rx_stats_off;
> + u64 *tx_stats = (u64 *)&priv->tx_stats;
> + u64 *rx_stats = (u64 *)&priv->rx_stats;
nit: I think it would be interesting to use a union containing
1. the existing tx/rx stats struct and 2. an array of u64.
This may allow avoiding this cast. Which seems nice to me.
But YMMV.
> + u32 i, res;
> +
> + assert_spin_locked(&priv->stats_lock);
> +
> + if (!netif_running(priv->ndev) || !netif_device_present(priv->ndev)) {
> + /* Not up, don't try to update */
> + return;
> + }
> +
> + for (i = 0; i < sizeof(priv->tx_stats) / sizeof(*tx_stats); i++) {
> + /*
> + * If reading stats times out, everything is broken and there's
> + * nothing we can do. Reading statistics also can't return an
> + * error, so just return without updating and without
> + * rescheduling.
> + */
> + if (emac_tx_read_stat_cnt(priv, i, &res))
> + return;
> +
> + /*
> + * Re-initializing while bringing interface up resets counters
> + * to zero, so to provide continuity, we add the values saved
> + * last time we did emac_down() to the new hardware-provided
> + * value.
> + */
> + emac_update_counter(&tx_stats[i], res + (u32)tx_stats_off[i]);
nit: maybe lower_32_bits(tx_stats_off[i]) ?
> + }
> +
> + /* Similar remarks as TX stats */
> + for (i = 0; i < sizeof(priv->rx_stats) / sizeof(*rx_stats); i++) {
> + if (emac_rx_read_stat_cnt(priv, i, &res))
> + return;
> + emac_update_counter(&rx_stats[i], res + (u32)rx_stats_off[i]);
Likewise, here for rx_stats_off[i].
> + }
> +
> + mod_timer(&priv->stats_timer, jiffies + EMAC_STATS_TIMER_PERIOD * HZ);
> +}
...
> +static u64 emac_get_stat_tx_dropped(struct emac_priv *priv)
> +{
> + u64 result;
> + int cpu;
> +
> + for_each_possible_cpu(cpu) {
> + result += READ_ONCE(per_cpu(*priv->stat_tx_dropped, cpu));
> + }
nit: no need for {} here ?
> +
> + return result;
> +}
...
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: Simon Horman <horms@kernel.org>
To: Vivian Wang <wangruikang@iscas.ac.cn>
Cc: Andrew Lunn <andrew+netdev@lunn.ch>,
Jakub Kicinski <kuba@kernel.org>, Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>, Yixun Lan <dlan@gentoo.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Paolo Abeni <pabeni@redhat.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>, Vivian Wang <uwu@dram.page>,
Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Junhui Liu <junhui.liu@pigmoral.tech>,
Maxime Chevallier <maxime.chevallier@bootlin.com>,
netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-riscv@lists.infradead.org, spacemit@lists.linux.dev,
linux-kernel@vger.kernel.org,
Troy Mitchell <troy.mitchell@linux.spacemit.com>
Subject: Re: [PATCH net-next v10 2/5] net: spacemit: Add K1 Ethernet MAC
Date: Thu, 11 Sep 2025 10:44:04 +0100 [thread overview]
Message-ID: <20250911094404.GE30363@horms.kernel.org> (raw)
In-Reply-To: <20250908-net-k1-emac-v10-2-90d807ccd469@iscas.ac.cn>
On Mon, Sep 08, 2025 at 08:34:26PM +0800, Vivian Wang wrote:
> The Ethernet MACs found on SpacemiT K1 appears to be a custom design
> that only superficially resembles some other embedded MACs. SpacemiT
> refers to them as "EMAC", so let's just call the driver "k1_emac".
>
> Supports RGMII and RMII interfaces. Includes support for MAC hardware
> statistics counters. PTP support is not implemented.
>
> Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
> Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
> Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
> Tested-by: Junhui Liu <junhui.liu@pigmoral.tech>
> Tested-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
> ---
> drivers/net/ethernet/Kconfig | 1 +
> drivers/net/ethernet/Makefile | 1 +
> drivers/net/ethernet/spacemit/Kconfig | 29 +
> drivers/net/ethernet/spacemit/Makefile | 6 +
> drivers/net/ethernet/spacemit/k1_emac.c | 2156 +++++++++++++++++++++++++++++++
This is a large patch, so I'm sure I've missed some things.
But, overall, I think this is coming together.
Thanks for your recent updates.
As the Kernel Patch Robot noticed a problem,
I've provided some minor feedback for your consideration.
...
> +static void emac_wr(struct emac_priv *priv, u32 reg, u32 val)
> +{
> + writel(val, priv->iobase + reg);
> +}
> +
> +static int emac_rd(struct emac_priv *priv, u32 reg)
nit: maybe u32 would be a more suitable return type.
> +{
> + return readl(priv->iobase + reg);
> +}
...
> +static int emac_alloc_tx_resources(struct emac_priv *priv)
> +{
> + struct emac_desc_ring *tx_ring = &priv->tx_ring;
> + struct platform_device *pdev = priv->pdev;
> + u32 size;
> +
> + size = sizeof(struct emac_tx_desc_buffer) * tx_ring->total_cnt;
> +
> + tx_ring->tx_desc_buf = kzalloc(size, GFP_KERNEL);
nit: I think you can use kcalloc() here.
> + if (!tx_ring->tx_desc_buf)
> + return -ENOMEM;
> +
> + tx_ring->total_size = tx_ring->total_cnt * sizeof(struct emac_desc);
> + tx_ring->total_size = ALIGN(tx_ring->total_size, PAGE_SIZE);
> +
> + tx_ring->desc_addr = dma_alloc_coherent(&pdev->dev, tx_ring->total_size,
> + &tx_ring->desc_dma_addr,
> + GFP_KERNEL);
> + if (!tx_ring->desc_addr) {
> + kfree(tx_ring->tx_desc_buf);
> + return -ENOMEM;
> + }
> +
> + tx_ring->head = 0;
> + tx_ring->tail = 0;
> +
> + return 0;
> +}
...
> +static int emac_alloc_rx_resources(struct emac_priv *priv)
> +{
> + struct emac_desc_ring *rx_ring = &priv->rx_ring;
> + struct platform_device *pdev = priv->pdev;
> + u32 buf_len;
> +
> + buf_len = sizeof(struct emac_rx_desc_buffer) * rx_ring->total_cnt;
> +
> + rx_ring->rx_desc_buf = kzalloc(buf_len, GFP_KERNEL);
Ditto.
> + if (!rx_ring->rx_desc_buf)
> + return -ENOMEM;
> +
> + rx_ring->total_size = rx_ring->total_cnt * sizeof(struct emac_desc);
> +
> + rx_ring->total_size = ALIGN(rx_ring->total_size, PAGE_SIZE);
> +
> + rx_ring->desc_addr = dma_alloc_coherent(&pdev->dev, rx_ring->total_size,
> + &rx_ring->desc_dma_addr,
> + GFP_KERNEL);
> + if (!rx_ring->desc_addr) {
> + kfree(rx_ring->rx_desc_buf);
> + return -ENOMEM;
> + }
> +
> + rx_ring->head = 0;
> + rx_ring->tail = 0;
> +
> + return 0;
> +}
...
> +static int emac_mii_read(struct mii_bus *bus, int phy_addr, int regnum)
> +{
> + struct emac_priv *priv = bus->priv;
> + u32 cmd = 0, val;
> + int ret;
> +
> + cmd |= phy_addr & 0x1F;
> + cmd |= (regnum & 0x1F) << 5;
nit: I think this could benefit from using FIELD_PREP
Likewise for similar patterns in this patch.
> + cmd |= MREGBIT_START_MDIO_TRANS | MREGBIT_MDIO_READ_WRITE;
> +
> + emac_wr(priv, MAC_MDIO_DATA, 0x0);
> + emac_wr(priv, MAC_MDIO_CONTROL, cmd);
> +
> + ret = readl_poll_timeout(priv->iobase + MAC_MDIO_CONTROL, val,
> + !((val >> 15) & 0x1), 100, 10000);
> +
> + if (ret)
> + return ret;
> +
> + val = emac_rd(priv, MAC_MDIO_DATA);
> + return val;
> +}
...
> +/*
> + * Even though this MAC supports gigabit operation, it only provides 32-bit
> + * statistics counters. The most overflow-prone counters are the "bytes" ones,
> + * which at gigabit overflow about twice a minute.
> + *
> + * Therefore, we maintain the high 32 bits of counters ourselves, incrementing
> + * every time statistics seem to go backwards. Also, update periodically to
> + * catch overflows when we are not otherwise checking the statistics often
> + * enough.
> + */
> +
> +#define EMAC_STATS_TIMER_PERIOD 20
> +
> +static int emac_read_stat_cnt(struct emac_priv *priv, u8 cnt, u32 *res,
> + u32 control_reg, u32 high_reg, u32 low_reg)
> +{
> + u32 val;
> + int ret;
> +
> + /* The "read" bit is the same for TX and RX */
> +
> + val = MREGBIT_START_TX_COUNTER_READ | cnt;
> + emac_wr(priv, control_reg, val);
> + val = emac_rd(priv, control_reg);
> +
> + ret = readl_poll_timeout_atomic(priv->iobase + control_reg, val,
> + !(val & MREGBIT_START_TX_COUNTER_READ),
> + 100, 10000);
> +
> + if (ret) {
> + netdev_err(priv->ndev, "Read stat timeout\n");
> + return ret;
> + }
> +
> + *res = emac_rd(priv, high_reg) << 16;
> + *res |= (u16)emac_rd(priv, low_reg);
nit: I think lower_16_bits() and lower_16_bits() would be appropriate here.
> +
> + return 0;
> +}
...
> +static void emac_update_counter(u64 *counter, u32 new_low)
> +{
> + u32 old_low = (u32)*counter;
> + u64 high = *counter >> 32;
Similarly, lower_32_bits() and upper_32_bits here.
> +
> + if (old_low > new_low) {
> + /* Overflowed, increment high 32 bits */
> + high++;
> + }
> +
> + *counter = (high << 32) | new_low;
> +}
> +
> +static void emac_stats_update(struct emac_priv *priv)
> +{
> + u64 *tx_stats_off = (u64 *)&priv->tx_stats_off;
> + u64 *rx_stats_off = (u64 *)&priv->rx_stats_off;
> + u64 *tx_stats = (u64 *)&priv->tx_stats;
> + u64 *rx_stats = (u64 *)&priv->rx_stats;
nit: I think it would be interesting to use a union containing
1. the existing tx/rx stats struct and 2. an array of u64.
This may allow avoiding this cast. Which seems nice to me.
But YMMV.
> + u32 i, res;
> +
> + assert_spin_locked(&priv->stats_lock);
> +
> + if (!netif_running(priv->ndev) || !netif_device_present(priv->ndev)) {
> + /* Not up, don't try to update */
> + return;
> + }
> +
> + for (i = 0; i < sizeof(priv->tx_stats) / sizeof(*tx_stats); i++) {
> + /*
> + * If reading stats times out, everything is broken and there's
> + * nothing we can do. Reading statistics also can't return an
> + * error, so just return without updating and without
> + * rescheduling.
> + */
> + if (emac_tx_read_stat_cnt(priv, i, &res))
> + return;
> +
> + /*
> + * Re-initializing while bringing interface up resets counters
> + * to zero, so to provide continuity, we add the values saved
> + * last time we did emac_down() to the new hardware-provided
> + * value.
> + */
> + emac_update_counter(&tx_stats[i], res + (u32)tx_stats_off[i]);
nit: maybe lower_32_bits(tx_stats_off[i]) ?
> + }
> +
> + /* Similar remarks as TX stats */
> + for (i = 0; i < sizeof(priv->rx_stats) / sizeof(*rx_stats); i++) {
> + if (emac_rx_read_stat_cnt(priv, i, &res))
> + return;
> + emac_update_counter(&rx_stats[i], res + (u32)rx_stats_off[i]);
Likewise, here for rx_stats_off[i].
> + }
> +
> + mod_timer(&priv->stats_timer, jiffies + EMAC_STATS_TIMER_PERIOD * HZ);
> +}
...
> +static u64 emac_get_stat_tx_dropped(struct emac_priv *priv)
> +{
> + u64 result;
> + int cpu;
> +
> + for_each_possible_cpu(cpu) {
> + result += READ_ONCE(per_cpu(*priv->stat_tx_dropped, cpu));
> + }
nit: no need for {} here ?
> +
> + return result;
> +}
...
next prev parent reply other threads:[~2025-09-11 9:44 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-08 12:34 [PATCH net-next v10 0/5] Add Ethernet MAC support for SpacemiT K1 Vivian Wang
2025-09-08 12:34 ` Vivian Wang
2025-09-08 12:34 ` [PATCH net-next v10 1/5] dt-bindings: net: Add " Vivian Wang
2025-09-08 12:34 ` Vivian Wang
2025-09-08 12:34 ` [PATCH net-next v10 2/5] net: spacemit: Add K1 Ethernet MAC Vivian Wang
2025-09-08 12:34 ` Vivian Wang
2025-09-08 15:25 ` Vivian Wang
2025-09-08 15:25 ` Vivian Wang
2025-09-09 4:20 ` kernel test robot
2025-09-09 4:20 ` kernel test robot
2025-09-11 9:44 ` Simon Horman [this message]
2025-09-11 9:44 ` Simon Horman
2025-09-11 10:23 ` Vivian Wang
2025-09-11 10:23 ` Vivian Wang
2025-09-08 12:34 ` [PATCH net-next v10 3/5] riscv: dts: spacemit: Add Ethernet support for K1 Vivian Wang
2025-09-08 12:34 ` Vivian Wang
2025-09-08 12:34 ` [PATCH net-next v10 4/5] riscv: dts: spacemit: Add Ethernet support for BPI-F3 Vivian Wang
2025-09-08 12:34 ` Vivian Wang
2025-09-08 12:34 ` [PATCH net-next v10 5/5] riscv: dts: spacemit: Add Ethernet support for Jupiter Vivian Wang
2025-09-08 12:34 ` Vivian Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250911094404.GE30363@horms.kernel.org \
--to=horms@kernel.org \
--cc=alex@ghiti.fr \
--cc=andrew+netdev@lunn.ch \
--cc=aou@eecs.berkeley.edu \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=dlan@gentoo.org \
--cc=edumazet@google.com \
--cc=junhui.liu@pigmoral.tech \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=maxime.chevallier@bootlin.com \
--cc=netdev@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=pabeni@redhat.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=robh@kernel.org \
--cc=spacemit@lists.linux.dev \
--cc=troy.mitchell@linux.spacemit.com \
--cc=uwu@dram.page \
--cc=vadim.fedorenko@linux.dev \
--cc=wangruikang@iscas.ac.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.