From: Vivian Wang <wangruikang@iscas.ac.cn>
To: Vadim Fedorenko <vadim.fedorenko@linux.dev>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>, Yixun Lan <dlan@gentoo.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Albert Ou <aou@eecs.berkeley.edu>,
Alexandre Ghiti <alex@ghiti.fr>,
Richard Cochran <richardcochran@gmail.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
Russell King <linux@armlinux.org.uk>
Cc: Vivian Wang <uwu@dram.page>,
netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-riscv@lists.infradead.org, spacemit@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next 2/4] net: spacemit: Add K1 Ethernet MAC
Date: Mon, 16 Jun 2025 11:04:06 +0800 [thread overview]
Message-ID: <440e3913-e41a-446d-92ba-b3599f57170e@iscas.ac.cn> (raw)
In-Reply-To: <d59be8aa-a288-4db5-9f93-1716ed1dd64e@linux.dev>
Hi Vadim,
Thanks for the review.
On 6/13/25 23:04, Vadim Fedorenko wrote:
> On 13/06/2025 03:15, 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".
>>
>> This driver is based on "k1x-emac" in the same directory in the vendor's
>> tree [1]. Some debugging tunables have been fixed to vendor-recommended
>> defaults, and PTP support is not included yet.
>>
>> [1]: https://github.com/spacemit-com/linux-k1x
>>
>> Signed-off-by: Vivian Wang <wangruikang@iscas.ac.cn>
>> ---
>> 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 | 2059
>> +++++++++++++++++++++++++++++++
>> drivers/net/ethernet/spacemit/k1_emac.h | 416 +++++++
>> 6 files changed, 2512 insertions(+)
>
> [...]
>
>> +
>> +static int emac_init_hw(struct emac_priv *priv)
>> +{
>> + u32 val = 0;
>> +
>> + regmap_set_bits(priv->regmap_apmu,
>> + priv->regmap_apmu_offset + APMU_EMAC_CTRL_REG,
>> + AXI_SINGLE_ID);
>> +
>> + /* Disable transmit and receive units */
>> + emac_wr(priv, MAC_RECEIVE_CONTROL, 0x0);
>> + emac_wr(priv, MAC_TRANSMIT_CONTROL, 0x0);
>> +
>> + /* Enable mac address 1 filtering */
>> + emac_wr(priv, MAC_ADDRESS_CONTROL, MREGBIT_MAC_ADDRESS1_ENABLE);
>> +
>> + /* Zero initialize the multicast hash table */
>> + emac_wr(priv, MAC_MULTICAST_HASH_TABLE1, 0x0);
>> + emac_wr(priv, MAC_MULTICAST_HASH_TABLE2, 0x0);
>> + emac_wr(priv, MAC_MULTICAST_HASH_TABLE3, 0x0);
>> + emac_wr(priv, MAC_MULTICAST_HASH_TABLE4, 0x0);
>> +
>> + /* Configure Thresholds */
>> + emac_wr(priv, MAC_TRANSMIT_FIFO_ALMOST_FULL,
>> DEFAULT_TX_ALMOST_FULL);
>> + emac_wr(priv, MAC_TRANSMIT_PACKET_START_THRESHOLD,
>> DEFAULT_TX_THRESHOLD);
>> + emac_wr(priv, MAC_RECEIVE_PACKET_START_THRESHOLD,
>> DEFAULT_RX_THRESHOLD);
>> +
>> + /* RX IRQ mitigation */
>> + val = EMAC_RX_FRAMES & MREGBIT_RECEIVE_IRQ_FRAME_COUNTER_MASK;
>> + val |= (EMAC_RX_COAL_TIMEOUT
>> + << MREGBIT_RECEIVE_IRQ_TIMEOUT_COUNTER_SHIFT) &
>> + MREGBIT_RECEIVE_IRQ_TIMEOUT_COUNTER_MASK;
>> +
>> + val |= MREGBIT_RECEIVE_IRQ_MITIGATION_ENABLE;
>> + emac_wr(priv, DMA_RECEIVE_IRQ_MITIGATION_CTRL, val);
>> +
>> + /* Disable and reset DMA */
>> + emac_wr(priv, DMA_CONTROL, 0x0);
>> +
>> + emac_wr(priv, DMA_CONFIGURATION, MREGBIT_SOFTWARE_RESET);
>> + usleep_range(9000, 10000);
>> + emac_wr(priv, DMA_CONFIGURATION, 0x0);
>> + usleep_range(9000, 10000);
>> +
>> + val |= MREGBIT_STRICT_BURST;
>> + val |= MREGBIT_DMA_64BIT_MODE;
>> + val |= DEFAULT_DMA_BURST;
>
> val here will have bits of MREGBIT_RECEIVE_IRQ_FRAME_COUNTER_MASK
> and MREGBIT_RECEIVE_IRQ_TIMEOUT_COUNTER_MASK set. Not sure if
> it's intended
>
Thanks for the catch. I will fix this in the next version.
>> +
>> + emac_wr(priv, DMA_CONFIGURATION, val);
>> +
>> + return 0;
>> +}
>> +
>> +static void emac_set_mac_addr(struct emac_priv *priv, const unsigned
>> char *addr)
>> +{
>> + emac_wr(priv, MAC_ADDRESS1_HIGH, ((addr[1] << 8) | addr[0]));
>> + emac_wr(priv, MAC_ADDRESS1_MED, ((addr[3] << 8) | addr[2]));
>> + emac_wr(priv, MAC_ADDRESS1_LOW, ((addr[5] << 8) | addr[4]));
>> +}
>> +
>> +static void emac_dma_start_transmit(struct emac_priv *priv)
>> +{
>> + emac_wr(priv, DMA_TRANSMIT_POLL_DEMAND, 0xFF);
>> +}
>> +
>> +static void emac_enable_interrupt(struct emac_priv *priv)
>> +{
>> + u32 val;
>> +
>> + val = emac_rd(priv, DMA_INTERRUPT_ENABLE);
>> + val |= MREGBIT_TRANSMIT_TRANSFER_DONE_INTR_ENABLE;
>> + val |= MREGBIT_RECEIVE_TRANSFER_DONE_INTR_ENABLE;
>> + emac_wr(priv, DMA_INTERRUPT_ENABLE, val);
>> +}
>> +
>> +static void emac_disable_interrupt(struct emac_priv *priv)
>> +{
>> + u32 val;
>> +
>> + val = emac_rd(priv, DMA_INTERRUPT_ENABLE);
>> + val &= ~MREGBIT_TRANSMIT_TRANSFER_DONE_INTR_ENABLE;
>> + val &= ~MREGBIT_RECEIVE_TRANSFER_DONE_INTR_ENABLE;
>> + emac_wr(priv, DMA_INTERRUPT_ENABLE, val);
>> +}
>> +
>> +static inline u32 emac_tx_avail(struct emac_priv *priv)
>
> please, avoid "static inline" in .c files, let the compiler to choose
> what to inline.
>
I will remove inline in next version.
>> +{
>> + struct emac_desc_ring *tx_ring = &priv->tx_ring;
>> + u32 avail;
>> +
>> + if (tx_ring->tail > tx_ring->head)
>> + avail = tx_ring->tail - tx_ring->head - 1;
>> + else
>> + avail = tx_ring->total_cnt - tx_ring->head + tx_ring->tail - 1;
>> +
>> + return avail;
>> +}
>> +
[...]
>> +static int emac_up(struct emac_priv *priv)
>> +{
>> + struct platform_device *pdev = priv->pdev;
>> + struct net_device *ndev = priv->ndev;
>> + int ret;
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> + pm_runtime_get_sync(&pdev->dev);
>> +#endif
>
> Not sure why do you depend on CONFIG_PM_SLEEP, but
> pm_runtime_get_sync/pm_runtime_put_sync are available with and without
> CONFIG_PM, no need
> for ifdef
>
I will remove #ifdef in next version.
>> +
>> + ret = emac_phy_connect(ndev);
>> + if (ret) {
>> + dev_err(&pdev->dev, "emac_phy_connect failed\n");
>> + goto err;
>> + }
>> +
>> + emac_init_hw(priv);
>> +
>> + emac_set_mac_addr(priv, ndev->dev_addr);
>> + emac_configure_tx(priv);
>> + emac_configure_rx(priv);
>> +
>> + emac_alloc_rx_desc_buffers(priv);
>> +
>> + if (ndev->phydev)
>> + phy_start(ndev->phydev);
>> +
>> + ret = request_irq(priv->irq, emac_interrupt_handler, IRQF_SHARED,
>> + ndev->name, ndev);
>> + if (ret) {
>> + dev_err(&pdev->dev, "request_irq failed\n");
>> + goto request_irq_failed;
>> + }
>> +
>> + /* Don't enable MAC interrupts */
>> + emac_wr(priv, MAC_INTERRUPT_ENABLE, 0x0);
>> +
>> + /* Enable DMA interrupts */
>> + emac_wr(priv, DMA_INTERRUPT_ENABLE,
>> + MREGBIT_TRANSMIT_TRANSFER_DONE_INTR_ENABLE |
>> + MREGBIT_TRANSMIT_DMA_STOPPED_INTR_ENABLE |
>> + MREGBIT_RECEIVE_TRANSFER_DONE_INTR_ENABLE |
>> + MREGBIT_RECEIVE_DMA_STOPPED_INTR_ENABLE |
>> + MREGBIT_RECEIVE_MISSED_FRAME_INTR_ENABLE);
>> +
>> + napi_enable(&priv->napi);
>> +
>> + netif_start_queue(ndev);
>> + return 0;
>> +
>> +request_irq_failed:
>> + emac_reset_hw(priv);
>> + if (ndev->phydev) {
>> + phy_stop(ndev->phydev);
>> + phy_disconnect(ndev->phydev);
>> + }
>> +err:
>> +#ifdef CONFIG_PM_SLEEP
>> + pm_runtime_put_sync(&pdev->dev);
>> +#endif
>> + return ret;
>> +}
>> +
>> +static int emac_down(struct emac_priv *priv)
>> +{
>> + struct platform_device *pdev = priv->pdev;
>> + struct net_device *ndev = priv->ndev;
>> +
>> + netif_stop_queue(ndev);
>> +
>> + if (ndev->phydev) {
>> + phy_stop(ndev->phydev);
>> + phy_disconnect(ndev->phydev);
>> + }
>> +
>> + priv->link = false;
>> + priv->duplex = DUPLEX_UNKNOWN;
>> + priv->speed = SPEED_UNKNOWN;
>> +
>> + emac_wr(priv, MAC_INTERRUPT_ENABLE, 0x0);
>> + emac_wr(priv, DMA_INTERRUPT_ENABLE, 0x0);
>> +
>> + free_irq(priv->irq, ndev);
>> +
>> + napi_disable(&priv->napi);
>> +
>> + emac_reset_hw(priv);
>> + netif_carrier_off(ndev);
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> + pm_runtime_put_sync(&pdev->dev);
>> +#endif
>
> ditto
>
I will remove #ifdef in next version.
Thanks again for your review.
Regards,
Vivian "dramforever" Wang
>> + return 0;
>> +}
>> +
>
> [...]
next prev parent reply other threads:[~2025-06-16 3:04 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-13 2:15 [PATCH net-next 0/4] Add Ethernet MAC support for SpacemiT K1 Vivian Wang
2025-06-13 2:15 ` [PATCH net-next 1/4] dt-bindings: net: Add " Vivian Wang
2025-06-13 14:43 ` Conor Dooley
2025-06-13 2:15 ` [PATCH net-next 2/4] net: spacemit: Add K1 Ethernet MAC Vivian Wang
2025-06-13 13:31 ` Jakub Kicinski
2025-06-16 3:02 ` Vivian Wang
2025-06-13 14:32 ` Andrew Lunn
2025-06-16 3:04 ` Vivian Wang
2025-06-13 15:04 ` Vadim Fedorenko
2025-06-16 3:04 ` Vivian Wang [this message]
2025-06-16 6:33 ` Russell King (Oracle)
2025-06-16 6:41 ` Vivian Wang
2025-06-13 2:15 ` [PATCH net-next 3/4] riscv: dts: spacemit: Add Ethernet support for K1 Vivian Wang
2025-06-13 2:15 ` [PATCH net-next 4/4] riscv: dts: spacemit: Add Ethernet support for BPI-F3 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=440e3913-e41a-446d-92ba-b3599f57170e@iscas.ac.cn \
--to=wangruikang@iscas.ac.cn \
--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=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=pabeni@redhat.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=richardcochran@gmail.com \
--cc=robh@kernel.org \
--cc=spacemit@lists.linux.dev \
--cc=uwu@dram.page \
--cc=vadim.fedorenko@linux.dev \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®