[PATCH net-next v8 04/15] net: microchip: fdma: use little-endian types for descriptor fields
From: Daniel Machon
Date: Thu Sep 24 2026 - 15:58:58 EST
The FDMA engine reads and writes the DCB and DB descriptors in
little-endian byte order. So far the descriptors have only been produced
by the little-endian SoC itself, so plain u64 fields were fine. With the
PCIe FDMA path, the descriptors live in host memory and are written by
the host CPU, which may be big-endian.
Change the descriptor fields to __le64 and convert at the library
boundary: in __fdma_db_add() and __fdma_dcb_add() on write, and in the
fdma_db_*() accessors on read. The dataptr and nextptr callbacks keep
their u64 signatures, so their implementations are unchanged. Add
fdma_db_dataptr_get(), and convert the lan966x sites that read the
descriptor fields directly to use the accessors.
No functional change on little-endian hosts.
Signed-off-by: Daniel Machon <daniel.machon@xxxxxxxxxxxxx>
---
drivers/net/ethernet/microchip/fdma/fdma_api.c | 21 ++++++++++++++++-----
drivers/net/ethernet/microchip/fdma/fdma_api.h | 20 +++++++++++++-------
.../net/ethernet/microchip/lan966x/lan966x_fdma.c | 9 +++++----
3 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/microchip/fdma/fdma_api.c b/drivers/net/ethernet/microchip/fdma/fdma_api.c
index a3c9e3097c5c..f7a42348e932 100644
--- a/drivers/net/ethernet/microchip/fdma/fdma_api.c
+++ b/drivers/net/ethernet/microchip/fdma/fdma_api.c
@@ -12,10 +12,18 @@ static int __fdma_db_add(struct fdma *fdma, int dcb_idx, int db_idx, u64 status,
int db_idx, u64 *dataptr))
{
struct fdma_db *db = fdma_db_get(fdma, dcb_idx, db_idx);
+ u64 dataptr;
+ int err;
+
+ db->status = cpu_to_le64(status);
- db->status = status;
+ err = cb(fdma, dcb_idx, db_idx, &dataptr);
+ if (unlikely(err))
+ return err;
- return cb(fdma, dcb_idx, db_idx, &db->dataptr);
+ db->dataptr = cpu_to_le64(dataptr);
+
+ return 0;
}
/* Add a DB to a DCB, using the callback set in the fdma_ops struct. */
@@ -35,6 +43,7 @@ int __fdma_dcb_add(struct fdma *fdma, int dcb_idx, u64 info, u64 status,
u64 *dataptr))
{
struct fdma_dcb *dcb = fdma_dcb_get(fdma, dcb_idx);
+ u64 nextptr;
int i, err;
for (i = 0; i < fdma->n_dbs; i++) {
@@ -43,14 +52,16 @@ int __fdma_dcb_add(struct fdma *fdma, int dcb_idx, u64 info, u64 status,
return err;
}
- err = dcb_cb(fdma, dcb_idx, &fdma->last_dcb->nextptr);
+ err = dcb_cb(fdma, dcb_idx, &nextptr);
if (unlikely(err))
return err;
+ fdma->last_dcb->nextptr = cpu_to_le64(nextptr);
+
fdma->last_dcb = dcb;
- dcb->nextptr = FDMA_DCB_INVALID_DATA;
- dcb->info = info;
+ dcb->nextptr = cpu_to_le64(FDMA_DCB_INVALID_DATA);
+ dcb->info = cpu_to_le64(info);
return 0;
}
diff --git a/drivers/net/ethernet/microchip/fdma/fdma_api.h b/drivers/net/ethernet/microchip/fdma/fdma_api.h
index ccc30d506e89..4e4f009b77cb 100644
--- a/drivers/net/ethernet/microchip/fdma/fdma_api.h
+++ b/drivers/net/ethernet/microchip/fdma/fdma_api.h
@@ -66,13 +66,13 @@
struct fdma;
struct fdma_db {
- u64 dataptr;
- u64 status;
+ __le64 dataptr;
+ __le64 status;
};
struct fdma_dcb {
- u64 nextptr;
- u64 info;
+ __le64 nextptr;
+ __le64 info;
struct fdma_db db[FDMA_DB_MAX];
};
@@ -147,19 +147,25 @@ static inline bool fdma_dcb_is_reusable(struct fdma *fdma)
/* Check if the FDMA has marked this DB as done. */
static inline bool fdma_db_is_done(struct fdma_db *db)
{
- return db->status & FDMA_DCB_STATUS_DONE;
+ return le64_to_cpu(db->status) & FDMA_DCB_STATUS_DONE;
}
/* Get the length of a DB. */
static inline int fdma_db_len_get(struct fdma_db *db)
{
- return FDMA_DCB_STATUS_BLOCKL(db->status);
+ return FDMA_DCB_STATUS_BLOCKL(le64_to_cpu(db->status));
+}
+
+/* Get the dataptr of a DB. */
+static inline u64 fdma_db_dataptr_get(struct fdma_db *db)
+{
+ return le64_to_cpu(db->dataptr);
}
/* Set the length of a DB. */
static inline void fdma_dcb_len_set(struct fdma_dcb *dcb, u32 len)
{
- dcb->info = FDMA_DCB_INFO_DATAL(len);
+ dcb->info = cpu_to_le64(FDMA_DCB_INFO_DATAL(len));
}
/* Get a DB by index. */
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
index 41d4ec7f2f57..68fd454ebc98 100644
--- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
+++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c
@@ -406,8 +406,9 @@ static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
return FDMA_ERROR;
dma_sync_single_for_cpu(lan966x->dev,
- (dma_addr_t)db->dataptr + XDP_PACKET_HEADROOM,
- FDMA_DCB_STATUS_BLOCKL(db->status),
+ (dma_addr_t)fdma_db_dataptr_get(db) +
+ XDP_PACKET_HEADROOM,
+ fdma_db_len_get(db),
DMA_FROM_DEVICE);
lan966x_ifh_get_src_port(page_address(page) + XDP_PACKET_HEADROOM,
@@ -419,7 +420,7 @@ static int lan966x_fdma_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
if (!lan966x_xdp_port_present(port))
return FDMA_PASS;
- return lan966x_xdp_run(port, page, FDMA_DCB_STATUS_BLOCKL(db->status));
+ return lan966x_xdp_run(port, page, fdma_db_len_get(db));
}
static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
@@ -443,7 +444,7 @@ static struct sk_buff *lan966x_fdma_rx_get_frame(struct lan966x_rx *rx,
skb_mark_for_recycle(skb);
skb_reserve(skb, XDP_PACKET_HEADROOM);
- skb_put(skb, FDMA_DCB_STATUS_BLOCKL(db->status));
+ skb_put(skb, fdma_db_len_get(db));
lan966x_ifh_get_timestamp(skb->data, ×tamp);
--
2.34.1