From: Jacky Chou <jacky_chou@aspeedtech.com>
To: 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>,
Po-Yu Chuang <ratbert@faraday-tech.com>
Cc: <netdev@vger.kernel.org>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>,
Jacky Chou <jacky_chou@aspeedtech.com>
Subject: [PATCH 4/5] net: ftgmac100: Add AST2700 upper DMA address support
Date: Sun, 27 Sep 2026 15:16:23 +0800 [thread overview]
Message-ID: <20260927-support_ast2700-v1-4-9f03f29d2c82@aspeedtech.com> (raw)
In-Reply-To: <20260927-support_ast2700-v1-0-9f03f29d2c82@aspeedtech.com>
Program the high RX and TX descriptor ring base registers and carry the
upper DMA address bits in RX and TX descriptors. Rebuild full buffer DMA
addresses in a 64-bit type before unmapping them so bits 34:32 are not
lost to 32-bit arithmetic.
The descriptor format provides three upper buffer address bits, so
request a 35-bit DMA mask instead of advertising an address range that
the hardware cannot encode. Gate all extended address handling with a
match-data quirk so older register layouts remain untouched and later
compatible controllers can opt into the same capability.
Signed-off-by: Jacky Chou <jacky_chou@aspeedtech.com>
---
drivers/net/ethernet/faraday/ftgmac100.c | 62 +++++++++++++++++++++++++++-----
drivers/net/ethernet/faraday/ftgmac100.h | 6 ++++
2 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c
index b835472da360..4becd28f805b 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -8,6 +8,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/reset.h>
#include <linux/dma-mapping.h>
@@ -42,6 +43,7 @@ enum ftgmac100_mac_id {
};
#define FTGMAC100_QUIRK_RMII_ENABLE BIT(0)
+#define FTGMAC100_QUIRK_DMA_35BIT BIT(1)
struct ftgmac100_match_data {
enum ftgmac100_mac_id mac_id;
@@ -303,10 +305,16 @@ static void ftgmac100_init_hw(struct ftgmac100 *priv)
iowrite32(reg, priv->base + FTGMAC100_OFFSET_ISR);
/* Setup RX ring buffer base */
- iowrite32(priv->rxdes_dma, priv->base + FTGMAC100_OFFSET_RXR_BADR);
+ iowrite32(lower_32_bits(priv->rxdes_dma), priv->base + FTGMAC100_OFFSET_RXR_BADR);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ iowrite32(upper_32_bits(priv->rxdes_dma),
+ priv->base + FTGMAC100_OFFSET_RXR_BADDR_HIGH);
/* Setup TX ring buffer base */
- iowrite32(priv->txdes_dma, priv->base + FTGMAC100_OFFSET_NPTXR_BADR);
+ iowrite32(lower_32_bits(priv->txdes_dma), priv->base + FTGMAC100_OFFSET_NPTXR_BADR);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ iowrite32(upper_32_bits(priv->txdes_dma),
+ priv->base + FTGMAC100_OFFSET_TXR_BADDR_HIGH);
/* Configure RX buffer size */
iowrite32(FTGMAC100_RBSR_SIZE(RX_BUF_SIZE),
@@ -469,7 +477,10 @@ static int ftgmac100_alloc_rx_buf(struct ftgmac100 *priv, unsigned int entry,
priv->rx_skbs[entry] = skb;
/* Store DMA address into RX desc */
- rxdes->rxdes3 = cpu_to_le32(map);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ rxdes->rxdes2 = cpu_to_le32(FIELD_PREP(FTGMAC100_RXDES2_RXBUF_BADR_HI,
+ upper_32_bits(map)));
+ rxdes->rxdes3 = cpu_to_le32(lower_32_bits(map));
/* Ensure the above is ordered vs clearing the OWN bit */
dma_wmb();
@@ -596,6 +607,9 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
/* Tear down DMA mapping, do necessary cache management */
map = le32_to_cpu(rxdes->rxdes3);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ map |= (u64)FIELD_GET(FTGMAC100_RXDES2_RXBUF_BADR_HI,
+ le32_to_cpu(rxdes->rxdes2)) << 32;
#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_DMA_USE_IOMMU)
/* When we don't have an iommu, we can save cycles by not
@@ -672,9 +686,14 @@ static void ftgmac100_free_tx_packet(struct ftgmac100 *priv,
struct ftgmac100_txdes *txdes,
u32 ctl_stat)
{
- dma_addr_t map = le32_to_cpu(txdes->txdes3);
+ dma_addr_t map;
size_t len;
+ map = le32_to_cpu(txdes->txdes3);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ map |= (u64)FIELD_GET(FTGMAC100_TXDES2_TXBUF_BADR_HI,
+ le32_to_cpu(txdes->txdes2)) << 32;
+
if (ctl_stat & FTGMAC100_TXDES0_FTS) {
len = skb_headlen(skb);
dma_unmap_single(priv->dev, map, len, DMA_TO_DEVICE);
@@ -828,7 +847,10 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
f_ctl_stat |= FTGMAC100_TXDES0_FTS;
if (nfrags == 0)
f_ctl_stat |= FTGMAC100_TXDES0_LTS;
- txdes->txdes3 = cpu_to_le32(map);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ txdes->txdes2 = cpu_to_le32(FIELD_PREP(FTGMAC100_TXDES2_TXBUF_BADR_HI,
+ upper_32_bits(map)));
+ txdes->txdes3 = cpu_to_le32(lower_32_bits(map));
txdes->txdes1 = cpu_to_le32(csum_vlan);
/* Next descriptor */
@@ -856,7 +878,10 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
ctl_stat |= FTGMAC100_TXDES0_LTS;
txdes->txdes0 = cpu_to_le32(ctl_stat);
txdes->txdes1 = 0;
- txdes->txdes3 = cpu_to_le32(map);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ txdes->txdes2 = cpu_to_le32(FIELD_PREP(FTGMAC100_TXDES2_TXBUF_BADR_HI,
+ upper_32_bits(map)));
+ txdes->txdes3 = cpu_to_le32(lower_32_bits(map));
/* Next one */
pointer = ftgmac100_next_tx_pointer(priv, pointer);
@@ -931,7 +956,12 @@ static void ftgmac100_free_buffers(struct ftgmac100 *priv)
for (i = 0; i < priv->rx_q_entries; i++) {
struct ftgmac100_rxdes *rxdes = &priv->rxdes[i];
struct sk_buff *skb = priv->rx_skbs[i];
- dma_addr_t map = le32_to_cpu(rxdes->rxdes3);
+ dma_addr_t map;
+
+ map = le32_to_cpu(rxdes->rxdes3);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT)
+ map |= (u64)FIELD_GET(FTGMAC100_RXDES2_RXBUF_BADR_HI,
+ le32_to_cpu(rxdes->rxdes2)) << 32;
if (!skb)
continue;
@@ -1050,7 +1080,12 @@ static void ftgmac100_init_rings(struct ftgmac100 *priv)
for (i = 0; i < priv->rx_q_entries; i++) {
rxdes = &priv->rxdes[i];
rxdes->rxdes0 = 0;
- rxdes->rxdes3 = cpu_to_le32(priv->rx_scratch_dma);
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT) {
+ u32 hi = upper_32_bits(priv->rx_scratch_dma);
+
+ rxdes->rxdes2 = cpu_to_le32(FIELD_PREP(FTGMAC100_RXDES2_RXBUF_BADR_HI, hi));
+ }
+ rxdes->rxdes3 = cpu_to_le32(lower_32_bits(priv->rx_scratch_dma));
}
/* Mark the end of the ring */
rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask);
@@ -2094,6 +2129,14 @@ static int ftgmac100_probe(struct platform_device *pdev)
netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM);
netdev->features |= netdev->hw_features;
+ if (priv->quirks & FTGMAC100_QUIRK_DMA_35BIT) {
+ err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(35));
+ if (err) {
+ dev_err(&pdev->dev, "35-bit DMA enable failed\n");
+ goto err;
+ }
+ }
+
/* register network device */
err = register_netdev(netdev);
if (err) {
@@ -2146,7 +2189,8 @@ static const struct ftgmac100_match_data ftgmac100_match_data_ast2600 = {
static const struct ftgmac100_match_data ftgmac100_match_data_ast2700 = {
.mac_id = FTGMAC100_AST2700,
- .quirks = FTGMAC100_QUIRK_RMII_ENABLE,
+ .quirks = FTGMAC100_QUIRK_RMII_ENABLE |
+ FTGMAC100_QUIRK_DMA_35BIT,
};
static const struct ftgmac100_match_data ftgmac100_match_data_faraday = {
diff --git a/drivers/net/ethernet/faraday/ftgmac100.h b/drivers/net/ethernet/faraday/ftgmac100.h
index 8c35c895b146..0c244b1c0a35 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.h
+++ b/drivers/net/ethernet/faraday/ftgmac100.h
@@ -57,6 +57,9 @@
#define FTGMAC100_OFFSET_RX_RUNT 0xc0
#define FTGMAC100_OFFSET_RX_CRCER_FTL 0xc4
#define FTGMAC100_OFFSET_RX_COL_LOST 0xc8
+/* reserved 0xcc - 0x178 */
+#define FTGMAC100_OFFSET_TXR_BADDR_HIGH 0x17c
+#define FTGMAC100_OFFSET_RXR_BADDR_HIGH 0x18c
/*
* Interrupt status register & interrupt enable register
@@ -226,6 +229,7 @@ struct ftgmac100_txdes {
#define FTGMAC100_TXDES1_TX2FIC (1 << 30)
#define FTGMAC100_TXDES1_TXIC (1 << 31)
+#define FTGMAC100_TXDES2_TXBUF_BADR_HI GENMASK(18, 16)
/*
* Receive descriptor, aligned to 16 bytes
*/
@@ -272,4 +276,6 @@ struct ftgmac100_rxdes {
#define FTGMAC100_RXDES1_UDP_CHKSUM_ERR (1 << 26)
#define FTGMAC100_RXDES1_IP_CHKSUM_ERR (1 << 27)
+#define FTGMAC100_RXDES2_RXBUF_BADR_HI GENMASK(18, 16)
+
#endif /* __FTGMAC100_H */
--
2.34.1
next prev parent reply other threads:[~2026-09-27 7:17 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 7:16 [PATCH 0/5] net: ftgmac100: Add AST2700 support Jacky Chou
2026-09-27 7:16 ` [PATCH 1/5] dt-bindings: net: ftgmac100: Add AST2700 compatible Jacky Chou
2026-09-27 7:16 ` [PATCH 2/5] net: ftgmac100: Add AST2700 compatible support Jacky Chou
2026-09-27 7:16 ` [PATCH 3/5] net: ftgmac100: Enable AST2700 RMII support Jacky Chou
2026-09-27 7:16 ` Jacky Chou [this message]
2026-09-27 7:16 ` [PATCH 5/5] net: ftgmac100: Allow building on ARM64 Jacky Chou
2026-09-27 17:39 ` [PATCH 0/5] net: ftgmac100: Add AST2700 support Andrew Lunn
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=20260927-support_ast2700-v1-4-9f03f29d2c82@aspeedtech.com \
--to=jacky_chou@aspeedtech.com \
--cc=andrew+netdev@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=ratbert@faraday-tech.com \
--cc=robh@kernel.org \
/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®