git: facdd1cd2045 - main - cgem: add 64-bit support
Michal Meloun
meloun.michal at gmail.com
Wed Jan 13 12:36:06 UTC 2021
On 10.01.2021 21:53, Mitchell Horne wrote:
> The branch main has been updated by mhorne:
>
> URL: https://cgit.FreeBSD.org/src/commit/?id=facdd1cd20451d7817c72a25e9253b934ca65eb6
>
> commit facdd1cd20451d7817c72a25e9253b934ca65eb6
> Author: Thomas Skibo <thomas-bsd at skibo.net>
> AuthorDate: 2021-01-10 20:18:41 +0000
> Commit: Mitchell Horne <mhorne at FreeBSD.org>
> CommitDate: 2021-01-10 20:51:52 +0000
>
> cgem: add 64-bit support
>
> Add 64-bit address support to Cadence CGEM Ethernet driver for use in
> other SoCs such as the Zynq UltraScale+ and SiFive HighFive Unleashed.
>
> Reviewed by: philip, 0mp (manpages)
> Differential Revision: https://reviews.freebsd.org/D24304
> ---
> share/man/man4/Makefile | 7 +
> share/man/man4/{man4.arm => }/cgem.4 | 14 +-
> share/man/man4/man4.arm/Makefile | 4 +-
> sys/arm/conf/GENERIC | 2 +-
> sys/arm/conf/ZEDBOARD | 2 +-
> sys/arm64/conf/GENERIC | 1 +
> sys/dev/cadence/if_cgem.c | 341 ++++++++++++++++++++++++-----------
> sys/dev/cadence/if_cgem_hw.h | 64 ++++++-
> sys/dts/arm/zynq-7000.dtsi | 12 +-
> sys/riscv/conf/GENERIC | 2 +-
> 10 files changed, 323 insertions(+), 126 deletions(-)
>
> diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
> index c72caf0199c9..b8e63315cb95 100644
> --- a/share/man/man4/Makefile
> +++ b/share/man/man4/Makefile
> @@ -106,6 +106,7 @@ MAN= aac.4 \
> cdceem.4 \
> cfi.4 \
> cfumass.4 \
> + ${_cgem.4} \
> ch.4 \
> chromebook_platform.4 \
> ${_chvgpio.4} \
> @@ -903,6 +904,12 @@ _virtio_scsi.4= virtio_scsi.4
> _vtnet.4= vtnet.4
> .endif
>
> +.if ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "aarch64" || \
> + ${MACHINE_CPUARCH} == "riscv"
> +_cgem.4= cgem.4
> +MLINKS+=cgem.4 if_cgem.4
> +.endif
> +
> .if empty(MAN_ARCH)
> __arches= ${MACHINE} ${MACHINE_ARCH} ${MACHINE_CPUARCH}
> .elif ${MAN_ARCH} == "all"
> diff --git a/share/man/man4/man4.arm/cgem.4 b/share/man/man4/cgem.4
> similarity index 96%
> rename from share/man/man4/man4.arm/cgem.4
> rename to share/man/man4/cgem.4
> index 6de1d7961788..f9f525dc4554 100644
> --- a/share/man/man4/man4.arm/cgem.4
> +++ b/share/man/man4/cgem.4
> @@ -24,7 +24,7 @@
> .\"
> .\" $FreeBSD$
> .\"
> -.Dd August 26, 2014
> +.Dd January 10, 2021
> .Dt CGEM 4
> .Os
> .Sh NAME
> @@ -44,7 +44,8 @@ The
> .Nm
> driver provides support for the Cadence GEM (Gigabit Ethernet MAC).
> The Cadence GEM is used in some SoC (System on a Chip) devices such as
> -the Xilinx Zynq-7000 and the Atmel SAMA5D3.
> +the Xilinx Zynq-7000, the Xilinx Zynq UltraScale+, and the SiFive
> +HiFive Unleashed.
> .Pp
> The
> .Nm
> @@ -284,7 +285,7 @@ There are
> variables that count
> packets discarded by the hardware (see below).
> .Pp
> -The GEM used in the Zynq-7000 has a bug such that the receiver can
> +The GEM used in the Zynq-7000 has a bug such that the receiver can
> potentially freeze up under a high load.
> The issue is described in sec. 16.7
> "Known Issues" of the Zynq-7000 SoC Technical Reference Manual (Xilinx
> @@ -292,7 +293,10 @@ UG585 v1.7).
> The
> .Nm
> driver implements the work-around suggested in the manual.
> -If the bug does not exist in other versions of this device, the
> -work-around can be disabled by setting the dev.cgem.%d.rxhangwar
> +It is believed that the bug does not exist in the Zynq UltraScale+ and
> +SiFive SoCs so the work-around is disabled in those instances and enabled
> +in all others.
> +The work-around can be disabled by setting the
> +.Va dev.cgem.%d.rxhangwar
> .Xr sysctl 8
> variable to 0.
> diff --git a/share/man/man4/man4.arm/Makefile b/share/man/man4/man4.arm/Makefile
> index 21d53f43a7c8..0b3eec427934 100644
> --- a/share/man/man4/man4.arm/Makefile
> +++ b/share/man/man4/man4.arm/Makefile
> @@ -8,7 +8,6 @@ MAN= \
> aw_spi.4 \
> aw_syscon.4 \
> bcm283x_pwm.4 \
> - cgem.4 \
> devcfg.4 \
> imx6_ahci.4 \
> imx6_snvs.4 \
> @@ -16,8 +15,7 @@ MAN= \
> mge.4 \
> ti_adc.4
>
> -MLINKS= cgem.4 if_cgem.4
> -MLINKS+= imx_wdog.4 imxwdt.4
> +MLINKS= imx_wdog.4 imxwdt.4
> MLINKS+= mge.4 if_mge.4
>
> MANSUBDIR=/arm
> diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC
> index 0f0522eb9802..3cfe16ccfe54 100644
> --- a/sys/arm/conf/GENERIC
> +++ b/sys/arm/conf/GENERIC
> @@ -228,8 +228,8 @@ device e6000sw
> device miibus
>
> device awg # 10/100/1000 integrated EMAC controller
> +device cgem # Cadence GEM Gigabit Ethernet device
> device cpsw # TI Common Platform Ethernet Switch (CPSW)
> -device cgem # Zynq-7000 gig ethernet device
> device dwc # 10/100/1000 integrated GMAC controller
> device emac # 10/100 integrated EMAC controller
> device ffec # Freescale Fast Ethernet Controller
> diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD
> index 613e0c73a16d..24490a5129e5 100644
> --- a/sys/arm/conf/ZEDBOARD
> +++ b/sys/arm/conf/ZEDBOARD
> @@ -49,7 +49,7 @@ device mpcore_timer
>
> device loop
> device ether
> -device cgem # Zynq-7000 gig ethernet device
> +device cgem # Cadence GEM Gigabit Ethernet device
> device mii
> device e1000phy
> device rgephy # Zybo uses Realtek RTL8211E
> diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC
> index 268089dba1fc..463271d1db26 100644
> --- a/sys/arm64/conf/GENERIC
> +++ b/sys/arm64/conf/GENERIC
> @@ -278,6 +278,7 @@ device miibus # MII bus support
> device al_eth # Annapurna Alpine Ethernet NIC
> device awg # Allwinner EMAC Gigabit Ethernet
> device axa # AMD Opteron A1100 integrated NIC
> +device cgem # Cadence GEM Gigabit Ethernet device
> device dwc_rk # Rockchip Designware
> device dwc_socfpga # Altera SOCFPGA Ethernet MAC
> device ffec # iMX FFEC
> diff --git a/sys/dev/cadence/if_cgem.c b/sys/dev/cadence/if_cgem.c
> index 3c5277452469..77337e977dcc 100644
> --- a/sys/dev/cadence/if_cgem.c
> +++ b/sys/dev/cadence/if_cgem.c
> @@ -77,6 +77,14 @@ __FBSDID("$FreeBSD$");
> #include <dev/mii/mii.h>
> #include <dev/mii/miivar.h>
>
> +#ifdef EXT_RESOURCES
> +#include <dev/extres/clk/clk.h>
> +#endif
> +
> +#if INTPTR_MAX == INT64_MAX
> +#define CGEM64
> +#endif
> +
> #include <dev/cadence/if_cgem_hw.h>
>
> #include "miibus_if.h"
> @@ -86,9 +94,6 @@ __FBSDID("$FreeBSD$");
> #define CGEM_NUM_RX_DESCS 512 /* size of receive descriptor ring */
> #define CGEM_NUM_TX_DESCS 512 /* size of transmit descriptor ring */
>
> -#define MAX_DESC_RING_SIZE (MAX(CGEM_NUM_RX_DESCS*sizeof(struct cgem_rx_desc),\
> - CGEM_NUM_TX_DESCS*sizeof(struct cgem_tx_desc)))
> -
> /* Default for sysctl rxbufs. Must be < CGEM_NUM_RX_DESCS of course. */
> #define DEFAULT_NUM_RX_BUFS 256 /* number of receive bufs to queue. */
>
> @@ -97,11 +102,18 @@ __FBSDID("$FreeBSD$");
> #define CGEM_CKSUM_ASSIST (CSUM_IP | CSUM_TCP | CSUM_UDP | \
> CSUM_TCP_IPV6 | CSUM_UDP_IPV6)
>
> +#define HWTYPE_GENERIC_GEM 1
> +#define HWTYPE_ZYNQ 2
> +#define HWTYPE_ZYNQMP 3
> +#define HWTYPE_SIFIVE_FU540 4
> +
> static struct ofw_compat_data compat_data[] = {
> - { "cadence,gem", 1 },
> - { "cdns,macb", 1 },
> - { "sifive,fu540-c000-gem", 1 },
> - { NULL, 0 },
> + { "cdns,zynq-gem", HWTYPE_ZYNQ },
> + { "cdns,zynqmp-gem", HWTYPE_ZYNQMP },
> + { "sifive,fu540-c000-gem", HWTYPE_SIFIVE_FU540 },
> + { "cdns,gem", HWTYPE_GENERIC_GEM },
> + { "cadence,gem", HWTYPE_GENERIC_GEM },
> + { NULL, 0 }
> };
>
> struct cgem_softc {
> @@ -116,8 +128,13 @@ struct cgem_softc {
> void *intrhand;
> struct callout tick_ch;
> uint32_t net_ctl_shadow;
> + uint32_t net_cfg_shadow;
> +#ifdef EXT_RESOURCES
> + clk_t ref_clk;
> +#else
> int ref_clk_num;
> - u_char eaddr[6];
> +#endif
> + int neednullqs;
>
> bus_dma_tag_t desc_dma_tag;
> bus_dma_tag_t mbuf_dma_tag;
> @@ -146,12 +163,15 @@ struct cgem_softc {
> int txring_hd_ptr; /* where to put next xmits */
> int txring_tl_ptr; /* next xmit mbuf to free */
> int txring_queued; /* num xmits segs queued */
> - bus_dmamap_t txring_dma_map;
> u_int txfull; /* tx ring full events */
> u_int txdefrags; /* tx calls to m_defrag() */
> u_int txdefragfails; /* tx m_defrag() failures */
> u_int txdmamapfails; /* tx dmamap failures */
>
> + /* null descriptor rings */
> + void *null_qs;
> + bus_addr_t null_qs_physaddr;
> +
> /* hardware provided statistics */
> struct cgem_hw_stats {
> uint64_t tx_bytes;
> @@ -274,9 +294,9 @@ cgem_get_mac(struct cgem_softc *sc, u_char eaddr[])
>
> /*
> * cgem_mac_hash(): map 48-bit address to a 6-bit hash. The 6-bit hash
> - * corresponds to a bit in a 64-bit hash register. Setting that bit in the hash
> - * register enables reception of all frames with a destination address that
> - * hashes to that 6-bit value.
> + * corresponds to a bit in a 64-bit hash register. Setting that bit in the
> + * hash register enables reception of all frames with a destination address
> + * that hashes to that 6-bit value.
> *
> * The hash function is described in sec. 16.2.3 in the Zynq-7000 Tech
> * Reference Manual. Bits 0-5 in the hash are the exclusive-or of
> @@ -321,18 +341,15 @@ cgem_rx_filter(struct cgem_softc *sc)
> {
> if_t ifp = sc->ifp;
> uint32_t hashes[2] = { 0, 0 };
> - uint32_t net_cfg;
> -
> - net_cfg = RD4(sc, CGEM_NET_CFG);
>
> - net_cfg &= ~(CGEM_NET_CFG_MULTI_HASH_EN |
> + sc->net_cfg_shadow &= ~(CGEM_NET_CFG_MULTI_HASH_EN |
> CGEM_NET_CFG_NO_BCAST | CGEM_NET_CFG_COPY_ALL);
>
> if ((if_getflags(ifp) & IFF_PROMISC) != 0)
> - net_cfg |= CGEM_NET_CFG_COPY_ALL;
> + sc->net_cfg_shadow |= CGEM_NET_CFG_COPY_ALL;
> else {
> if ((if_getflags(ifp) & IFF_BROADCAST) == 0)
> - net_cfg |= CGEM_NET_CFG_NO_BCAST;
> + sc->net_cfg_shadow |= CGEM_NET_CFG_NO_BCAST;
> if ((if_getflags(ifp) & IFF_ALLMULTI) != 0) {
> hashes[0] = 0xffffffff;
> hashes[1] = 0xffffffff;
> @@ -340,12 +357,12 @@ cgem_rx_filter(struct cgem_softc *sc)
> if_foreach_llmaddr(ifp, cgem_hash_maddr, hashes);
>
> if (hashes[0] != 0 || hashes[1] != 0)
> - net_cfg |= CGEM_NET_CFG_MULTI_HASH_EN;
> + sc->net_cfg_shadow |= CGEM_NET_CFG_MULTI_HASH_EN;
> }
>
> WR4(sc, CGEM_HASH_TOP, hashes[0]);
> WR4(sc, CGEM_HASH_BOT, hashes[1]);
> - WR4(sc, CGEM_NET_CFG, net_cfg);
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
> }
>
> /* For bus_dmamap_load() callback. */
> @@ -358,40 +375,92 @@ cgem_getaddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
> *(bus_addr_t *)arg = segs[0].ds_addr;
> }
>
> +/* Set up null queues for priority queues we actually can't disable. */
> +static void
> +cgem_null_qs(struct cgem_softc *sc)
> +{
> + struct cgem_rx_desc *rx_desc;
> + struct cgem_tx_desc *tx_desc;
> + uint32_t queue_mask;
> + int n;
> +
> + /* Read design config register 6 to determine number of queues. */
> + queue_mask = (RD4(sc, CGEM_DESIGN_CFG6) &
> + CGEM_DESIGN_CFG6_DMA_PRIO_Q_MASK) >> 1;
> + if (queue_mask == 0)
> + return;
> +
> + /* Create empty RX queue and empty TX buf queues. */
> + memset(sc->null_qs, 0, sizeof(struct cgem_rx_desc) +
> + sizeof(struct cgem_tx_desc));
> + rx_desc = sc->null_qs;
> + rx_desc->addr = CGEM_RXDESC_OWN | CGEM_RXDESC_WRAP;
> + tx_desc = (struct cgem_tx_desc *)(rx_desc + 1);
> + tx_desc->ctl = CGEM_TXDESC_USED | CGEM_TXDESC_WRAP;
> +
> + /* Point all valid ring base pointers to the null queues. */
> + for (n = 1; (queue_mask & 1) != 0; n++, queue_mask >>= 1) {
> + WR4(sc, CGEM_RX_QN_BAR(n), sc->null_qs_physaddr);
> + WR4(sc, CGEM_TX_QN_BAR(n), sc->null_qs_physaddr +
> + sizeof(struct cgem_rx_desc));
> + }
> +}
> +
> /* Create DMA'able descriptor rings. */
> static int
> cgem_setup_descs(struct cgem_softc *sc)
> {
> int i, err;
> + int desc_rings_size = CGEM_NUM_RX_DESCS * sizeof(struct cgem_rx_desc) +
> + CGEM_NUM_TX_DESCS * sizeof(struct cgem_tx_desc);
> +
> + if (sc->neednullqs)
> + desc_rings_size += sizeof(struct cgem_rx_desc) +
> + sizeof(struct cgem_tx_desc);
>
> sc->txring = NULL;
> sc->rxring = NULL;
>
> /* Allocate non-cached DMA space for RX and TX descriptors. */
> - err = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, 0,
> - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
> - MAX_DESC_RING_SIZE, 1, MAX_DESC_RING_SIZE, 0,
> + err = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1,
> +#ifdef CGEM64
> + 1ULL << 32, /* Do not cross a 4G boundary. */
> +#else
> + 0,
> +#endif
> + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
> + desc_rings_size, 1, desc_rings_size, 0,
> busdma_lock_mutex, &sc->sc_mtx, &sc->desc_dma_tag);
> if (err)
> return (err);
>
> /* Set up a bus_dma_tag for mbufs. */
> err = bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, 0,
> - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
> - MCLBYTES, TX_MAX_DMA_SEGS, MCLBYTES, 0,
> - busdma_lock_mutex, &sc->sc_mtx, &sc->mbuf_dma_tag);
> + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
> + TX_MAX_DMA_SEGS, MCLBYTES, 0, busdma_lock_mutex, &sc->sc_mtx,
> + &sc->mbuf_dma_tag);
> if (err)
> return (err);
>
> - /* Allocate DMA memory in non-cacheable space. */
> + /*
> + * Allocate DMA memory in non-cacheable space. We allocate transmit,
> + * receive and null descriptor queues all at once because the
> + * hardware only provides one register for the upper 32 bits of
> + * rx and tx descriptor queues hardware addresses.
> + */
> err = bus_dmamem_alloc(sc->desc_dma_tag, (void **)&sc->rxring,
> - BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->rxring_dma_map);
> +#ifdef __arm__
> + BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_ZERO,
> +#else
> + BUS_DMA_NOWAIT | BUS_DMA_NOCACHE | BUS_DMA_ZERO,
Using BUS_DMA_NOCACHE is clearly wrong on arm64 and probably also on all
other architectures. In other words - the only real usage of
BUS_DMA_NOCACHE is buggy hardware - (when snooping is not delivered to
all levels of caches). In all other cases it indicates problem in the
implementation of busdma.
Memory types in busdma should works as follows:
Normal -> allocate cached memory although device is not on DMA coherent
bus.
BUS_DMA_COHERENT -> allocate cached memory if device is on DMA coherent
bus, uncached otherwise.
BUS_DMA_NOCACHE -> allocate uncached memory although given device is on
DMA coherent bus.
Michal
> +#endif
> + &sc->rxring_dma_map);
> if (err)
> return (err);
>
> /* Load descriptor DMA memory. */
> err = bus_dmamap_load(sc->desc_dma_tag, sc->rxring_dma_map,
> - (void *)sc->rxring, CGEM_NUM_RX_DESCS*sizeof(struct cgem_rx_desc),
> + (void *)sc->rxring, desc_rings_size,
> cgem_getaddr, &sc->rxring_physaddr, BUS_DMA_NOWAIT);
> if (err)
> return (err);
> @@ -409,18 +478,9 @@ cgem_setup_descs(struct cgem_softc *sc)
> sc->rxring_tl_ptr = 0;
> sc->rxring_queued = 0;
>
> - /* Allocate DMA memory for TX descriptors in non-cacheable space. */
> - err = bus_dmamem_alloc(sc->desc_dma_tag, (void **)&sc->txring,
> - BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &sc->txring_dma_map);
> - if (err)
> - return (err);
> -
> - /* Load TX descriptor DMA memory. */
> - err = bus_dmamap_load(sc->desc_dma_tag, sc->txring_dma_map,
> - (void *)sc->txring, CGEM_NUM_TX_DESCS*sizeof(struct cgem_tx_desc),
> - cgem_getaddr, &sc->txring_physaddr, BUS_DMA_NOWAIT);
> - if (err)
> - return (err);
> + sc->txring = (struct cgem_tx_desc *)(sc->rxring + CGEM_NUM_RX_DESCS);
> + sc->txring_physaddr = sc->rxring_physaddr + CGEM_NUM_RX_DESCS *
> + sizeof(struct cgem_rx_desc);
>
> /* Initialize TX descriptor ring. */
> for (i = 0; i < CGEM_NUM_TX_DESCS; i++) {
> @@ -435,6 +495,14 @@ cgem_setup_descs(struct cgem_softc *sc)
> sc->txring_tl_ptr = 0;
> sc->txring_queued = 0;
>
> + if (sc->neednullqs) {
> + sc->null_qs = (void *)(sc->txring + CGEM_NUM_TX_DESCS);
> + sc->null_qs_physaddr = sc->txring_physaddr +
> + CGEM_NUM_TX_DESCS * sizeof(struct cgem_tx_desc);
> +
> + cgem_null_qs(sc);
> + }
> +
> return (0);
> }
>
> @@ -484,6 +552,9 @@ cgem_fill_rqueue(struct cgem_softc *sc)
>
> /* Write rx descriptor and increment head pointer. */
> sc->rxring[sc->rxring_hd_ptr].ctl = 0;
> +#ifdef CGEM64
> + sc->rxring[sc->rxring_hd_ptr].addrhi = segs[0].ds_addr >> 32;
> +#endif
> if (sc->rxring_hd_ptr == CGEM_NUM_RX_DESCS - 1) {
> sc->rxring[sc->rxring_hd_ptr].addr = segs[0].ds_addr |
> CGEM_RXDESC_WRAP;
> @@ -509,7 +580,7 @@ cgem_recv(struct cgem_softc *sc)
> m_hd = NULL;
> m_tl = &m_hd;
> while (sc->rxring_queued > 0 &&
> - (sc->rxring[sc->rxring_tl_ptr].addr & CGEM_RXDESC_OWN) != 0) {
> + (sc->rxring[sc->rxring_tl_ptr].addr & CGEM_RXDESC_OWN) != 0) {
> ctl = sc->rxring[sc->rxring_tl_ptr].ctl;
>
> /* Grab filled mbuf. */
> @@ -629,9 +700,16 @@ cgem_clean_tx(struct cgem_softc *sc)
> /* Check the status. */
> if ((ctl & CGEM_TXDESC_AHB_ERR) != 0) {
> /* Serious bus error. log to console. */
> +#ifdef CGEM64
> + device_printf(sc->dev,
> + "cgem_clean_tx: AHB error, addr=0x%x%08x\n",
> + sc->txring[sc->txring_tl_ptr].addrhi,
> + sc->txring[sc->txring_tl_ptr].addr);
> +#else
> device_printf(sc->dev,
> "cgem_clean_tx: AHB error, addr=0x%x\n",
> sc->txring[sc->txring_tl_ptr].addr);
> +#endif
> } else if ((ctl & (CGEM_TXDESC_RETRY_ERR |
> CGEM_TXDESC_LATE_COLL)) != 0) {
> if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
> @@ -640,8 +718,8 @@ cgem_clean_tx(struct cgem_softc *sc)
>
> /*
> * If the packet spanned more than one tx descriptor, skip
> - * descriptors until we find the end so that only start-of-frame
> - * descriptors are processed.
> + * descriptors until we find the end so that only
> + * start-of-frame descriptors are processed.
> */
> while ((ctl & CGEM_TXDESC_LAST_BUF) == 0) {
> if ((ctl & CGEM_TXDESC_WRAP) != 0)
> @@ -759,7 +837,10 @@ cgem_start_locked(if_t ifp)
> /* Descriptor address. */
> sc->txring[sc->txring_hd_ptr + i].addr =
> segs[i].ds_addr;
> -
> +#ifdef CGEM64
> + sc->txring[sc->txring_hd_ptr + i].addrhi =
> + segs[i].ds_addr >> 32;
> +#endif
> /* Descriptor control word. */
> ctl = segs[i].ds_len;
> if (i == nsegs - 1) {
> @@ -961,8 +1042,21 @@ cgem_reset(struct cgem_softc *sc)
>
> CGEM_ASSERT_LOCKED(sc);
>
> + /* Determine data bus width from design configuration register. */
> + switch (RD4(sc, CGEM_DESIGN_CFG1) &
> + CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_MASK) {
> + case CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_64:
> + sc->net_cfg_shadow = CGEM_NET_CFG_DBUS_WIDTH_64;
> + break;
> + case CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_128:
> + sc->net_cfg_shadow = CGEM_NET_CFG_DBUS_WIDTH_128;
> + break;
> + default:
> + sc->net_cfg_shadow = CGEM_NET_CFG_DBUS_WIDTH_32;
> + }
> +
> WR4(sc, CGEM_NET_CTRL, 0);
> - WR4(sc, CGEM_NET_CFG, 0);
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
> WR4(sc, CGEM_NET_CTRL, CGEM_NET_CTRL_CLR_STAT_REGS);
> WR4(sc, CGEM_TX_STAT, CGEM_TX_STAT_ALL);
> WR4(sc, CGEM_RX_STAT, CGEM_RX_STAT_ALL);
> @@ -973,8 +1067,8 @@ cgem_reset(struct cgem_softc *sc)
> WR4(sc, CGEM_RX_QBAR, 0);
>
> /* Get management port running even if interface is down. */
> - WR4(sc, CGEM_NET_CFG, CGEM_NET_CFG_DBUS_WIDTH_32 |
> - CGEM_NET_CFG_MDC_CLK_DIV_64);
> + sc->net_cfg_shadow |= CGEM_NET_CFG_MDC_CLK_DIV_48;
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
>
> sc->net_ctl_shadow = CGEM_NET_CTRL_MGMT_PORT_EN;
> WR4(sc, CGEM_NET_CTRL, sc->net_ctl_shadow);
> @@ -985,33 +1079,33 @@ static void
> cgem_config(struct cgem_softc *sc)
> {
> if_t ifp = sc->ifp;
> - uint32_t net_cfg;
> uint32_t dma_cfg;
> u_char *eaddr = if_getlladdr(ifp);
>
> CGEM_ASSERT_LOCKED(sc);
>
> /* Program Net Config Register. */
> - net_cfg = CGEM_NET_CFG_DBUS_WIDTH_32 |
> - CGEM_NET_CFG_MDC_CLK_DIV_64 |
> - CGEM_NET_CFG_FCS_REMOVE |
> + sc->net_cfg_shadow &= (CGEM_NET_CFG_MDC_CLK_DIV_MASK |
> + CGEM_NET_CFG_DBUS_WIDTH_MASK);
> + sc->net_cfg_shadow |= (CGEM_NET_CFG_FCS_REMOVE |
> CGEM_NET_CFG_RX_BUF_OFFSET(ETHER_ALIGN) |
> - CGEM_NET_CFG_GIGE_EN |
> - CGEM_NET_CFG_1536RXEN |
> - CGEM_NET_CFG_FULL_DUPLEX |
> - CGEM_NET_CFG_SPEED100;
> + CGEM_NET_CFG_GIGE_EN | CGEM_NET_CFG_1536RXEN |
> + CGEM_NET_CFG_FULL_DUPLEX | CGEM_NET_CFG_SPEED100);
>
> /* Enable receive checksum offloading? */
> if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0)
> - net_cfg |= CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN;
> + sc->net_cfg_shadow |= CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN;
>
> - WR4(sc, CGEM_NET_CFG, net_cfg);
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
>
> /* Program DMA Config Register. */
> dma_cfg = CGEM_DMA_CFG_RX_BUF_SIZE(MCLBYTES) |
> CGEM_DMA_CFG_RX_PKTBUF_MEMSZ_SEL_8K |
> CGEM_DMA_CFG_TX_PKTBUF_MEMSZ_SEL |
> CGEM_DMA_CFG_AHB_FIXED_BURST_LEN_16 |
> +#ifdef CGEM64
> + CGEM_DMA_CFG_ADDR_BUS_64 |
> +#endif
> CGEM_DMA_CFG_DISC_WHEN_NO_AHB;
>
> /* Enable transmit checksum offloading? */
> @@ -1021,8 +1115,12 @@ cgem_config(struct cgem_softc *sc)
> WR4(sc, CGEM_DMA_CFG, dma_cfg);
>
> /* Write the rx and tx descriptor ring addresses to the QBAR regs. */
> - WR4(sc, CGEM_RX_QBAR, (uint32_t) sc->rxring_physaddr);
> - WR4(sc, CGEM_TX_QBAR, (uint32_t) sc->txring_physaddr);
> + WR4(sc, CGEM_RX_QBAR, (uint32_t)sc->rxring_physaddr);
> + WR4(sc, CGEM_TX_QBAR, (uint32_t)sc->txring_physaddr);
> +#ifdef CGEM64
> + WR4(sc, CGEM_RX_QBAR_HI, (uint32_t)(sc->rxring_physaddr >> 32));
> + WR4(sc, CGEM_TX_QBAR_HI, (uint32_t)(sc->txring_physaddr >> 32));
> +#endif
>
> /* Enable rx and tx. */
> sc->net_ctl_shadow |= (CGEM_NET_CTRL_TX_EN | CGEM_NET_CTRL_RX_EN);
> @@ -1055,8 +1153,10 @@ cgem_init_locked(struct cgem_softc *sc)
>
> if_setdrvflagbits(sc->ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
>
> - mii = device_get_softc(sc->miibus);
> - mii_mediachg(mii);
> + if (sc->miibus != NULL) {
> + mii = device_get_softc(sc->miibus);
> + mii_mediachg(mii);
> + }
>
> callout_reset(&sc->tick_ch, hz, cgem_tick, sc);
> }
> @@ -1085,9 +1185,9 @@ cgem_stop(struct cgem_softc *sc)
> cgem_reset(sc);
>
> /* Clear out transmit queue. */
> + memset(sc->txring, 0, CGEM_NUM_TX_DESCS * sizeof(struct cgem_tx_desc));
> for (i = 0; i < CGEM_NUM_TX_DESCS; i++) {
> sc->txring[i].ctl = CGEM_TXDESC_USED;
> - sc->txring[i].addr = 0;
> if (sc->txring_m[i]) {
> /* Unload and destroy dmamap. */
> bus_dmamap_unload(sc->mbuf_dma_tag,
> @@ -1106,9 +1206,9 @@ cgem_stop(struct cgem_softc *sc)
> sc->txring_queued = 0;
>
> /* Clear out receive queue. */
> + memset(sc->rxring, 0, CGEM_NUM_RX_DESCS * sizeof(struct cgem_rx_desc));
> for (i = 0; i < CGEM_NUM_RX_DESCS; i++) {
> sc->rxring[i].addr = CGEM_RXDESC_OWN;
> - sc->rxring[i].ctl = 0;
> if (sc->rxring_m[i]) {
> /* Unload and destroy dmamap. */
> bus_dmamap_unload(sc->mbuf_dma_tag,
> @@ -1171,6 +1271,8 @@ cgem_ioctl(if_t ifp, u_long cmd, caddr_t data)
>
> case SIOCSIFMEDIA:
> case SIOCGIFMEDIA:
> + if (sc->miibus == NULL)
> + return (ENXIO);
> mii = device_get_softc(sc->miibus);
> error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
> break;
> @@ -1205,16 +1307,16 @@ cgem_ioctl(if_t ifp, u_long cmd, caddr_t data)
> /* Turn on RX checksumming. */
> if_setcapenablebit(ifp, IFCAP_RXCSUM |
> IFCAP_RXCSUM_IPV6, 0);
> - WR4(sc, CGEM_NET_CFG,
> - RD4(sc, CGEM_NET_CFG) |
> - CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN);
> + sc->net_cfg_shadow |=
> + CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN;
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
> } else {
> /* Turn off RX checksumming. */
> if_setcapenablebit(ifp, 0, IFCAP_RXCSUM |
> IFCAP_RXCSUM_IPV6);
> - WR4(sc, CGEM_NET_CFG,
> - RD4(sc, CGEM_NET_CFG) &
> - ~CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN);
> + sc->net_cfg_shadow &=
> + ~CGEM_NET_CFG_RX_CHKSUM_OFFLD_EN;
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
> }
> }
> if ((if_getcapenable(ifp) & (IFCAP_RXCSUM | IFCAP_TXCSUM)) ==
> @@ -1235,15 +1337,6 @@ cgem_ioctl(if_t ifp, u_long cmd, caddr_t data)
>
> /* MII bus support routines.
> */
> -static void
> -cgem_child_detached(device_t dev, device_t child)
> -{
> - struct cgem_softc *sc = device_get_softc(dev);
> -
> - if (child == sc->miibus)
> - sc->miibus = NULL;
> -}
> -
> static int
> cgem_ifmedia_upd(if_t ifp)
> {
> @@ -1380,24 +1473,22 @@ __weak_reference(cgem_default_set_ref_clk, cgem_set_ref_clk);
> static void
> cgem_mediachange(struct cgem_softc *sc, struct mii_data *mii)
> {
> - uint32_t net_cfg;
> int ref_clk_freq;
>
> CGEM_ASSERT_LOCKED(sc);
>
> /* Update hardware to reflect media. */
> - net_cfg = RD4(sc, CGEM_NET_CFG);
> - net_cfg &= ~(CGEM_NET_CFG_SPEED100 | CGEM_NET_CFG_GIGE_EN |
> + sc->net_cfg_shadow &= ~(CGEM_NET_CFG_SPEED100 | CGEM_NET_CFG_GIGE_EN |
> CGEM_NET_CFG_FULL_DUPLEX);
>
> switch (IFM_SUBTYPE(mii->mii_media_active)) {
> case IFM_1000_T:
> - net_cfg |= (CGEM_NET_CFG_SPEED100 |
> + sc->net_cfg_shadow |= (CGEM_NET_CFG_SPEED100 |
> CGEM_NET_CFG_GIGE_EN);
> ref_clk_freq = 125000000;
> break;
> case IFM_100_TX:
> - net_cfg |= CGEM_NET_CFG_SPEED100;
> + sc->net_cfg_shadow |= CGEM_NET_CFG_SPEED100;
> ref_clk_freq = 25000000;
> break;
> default:
> @@ -1405,15 +1496,25 @@ cgem_mediachange(struct cgem_softc *sc, struct mii_data *mii)
> }
>
> if ((mii->mii_media_active & IFM_FDX) != 0)
> - net_cfg |= CGEM_NET_CFG_FULL_DUPLEX;
> + sc->net_cfg_shadow |= CGEM_NET_CFG_FULL_DUPLEX;
>
> - WR4(sc, CGEM_NET_CFG, net_cfg);
> + WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
>
> +#ifdef EXT_RESOURCES
> + if (sc->ref_clk != NULL) {
> + CGEM_UNLOCK(sc);
> + if (clk_set_freq(sc->ref_clk, ref_clk_freq, 0))
> + device_printf(sc->dev, "could not set ref clk to %d\n",
> + ref_clk_freq);
> + CGEM_LOCK(sc);
> + }
> +#else
> /* Set the reference clock if necessary. */
> if (cgem_set_ref_clk(sc->ref_clk_num, ref_clk_freq))
> device_printf(sc->dev,
> "cgem_mediachange: could not set ref clk%d to %d.\n",
> sc->ref_clk_num, ref_clk_freq);
> +#endif
>
> sc->mii_media_active = mii->mii_media_active;
> }
> @@ -1640,19 +1741,46 @@ cgem_attach(device_t dev)
> {
> struct cgem_softc *sc = device_get_softc(dev);
> if_t ifp = NULL;
> - phandle_t node;
> - pcell_t cell;
> int rid, err;
> u_char eaddr[ETHER_ADDR_LEN];
> + int hwtype;
> +#ifndef EXT_RESOURCES
> + phandle_t node;
> + pcell_t cell;
> +#endif
>
> sc->dev = dev;
> CGEM_LOCK_INIT(sc);
>
> + /* Key off of compatible string and set hardware-specific options. */
> + hwtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
> + if (hwtype == HWTYPE_ZYNQMP)
> + sc->neednullqs = 1;
> + if (hwtype == HWTYPE_ZYNQ)
> + sc->rxhangwar = 1;
> +
> +#ifdef EXT_RESOURCES
> + if (hwtype == HWTYPE_ZYNQ || hwtype == HWTYPE_ZYNQMP) {
> + if (clk_get_by_ofw_name(dev, 0, "tx_clk", &sc->ref_clk) != 0)
> + device_printf(dev,
> + "could not retrieve reference clock.\n");
> + else if (clk_enable(sc->ref_clk) != 0)
> + device_printf(dev, "could not enable clock.\n");
> + }
> + else if (hwtype == HWTYPE_SIFIVE_FU540) {
> + if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->ref_clk) != 0)
> + device_printf(dev,
> + "could not retrieve reference clock.\n");
> + else if (clk_enable(sc->ref_clk) != 0)
> + device_printf(dev, "could not enable clock.\n");
> + }
> +#else
> /* Get reference clock number and base divider from fdt. */
> node = ofw_bus_get_node(dev);
> sc->ref_clk_num = 0;
> if (OF_getprop(node, "ref-clock-num", &cell, sizeof(cell)) > 0)
> sc->ref_clk_num = fdt32_to_cpu(cell);
> +#endif
>
> /* Get memory resource. */
> rid = 0;
> @@ -1665,7 +1793,8 @@ cgem_attach(device_t dev)
>
> /* Get IRQ resource. */
> rid = 0;
> - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE);
> + sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
> + RF_ACTIVE);
> if (sc->irq_res == NULL) {
> device_printf(dev, "could not allocate interrupt resource.\n");
> cgem_detach(dev);
> @@ -1697,7 +1826,6 @@ cgem_attach(device_t dev)
>
> sc->if_old_flags = if_getflags(ifp);
> sc->rxbufs = DEFAULT_NUM_RX_BUFS;
> - sc->rxhangwar = 1;
>
> /* Reset hardware. */
> CGEM_LOCK(sc);
> @@ -1708,11 +1836,8 @@ cgem_attach(device_t dev)
> err = mii_attach(dev, &sc->miibus, ifp,
> cgem_ifmedia_upd, cgem_ifmedia_sts, BMSR_DEFCAPMASK,
> MII_PHY_ANY, MII_OFFSET_ANY, 0);
> - if (err) {
> - device_printf(dev, "attaching PHYs failed\n");
> - cgem_detach(dev);
> - return (err);
> - }
> + if (err)
> + device_printf(dev, "warning: attaching PHYs failed\n");
>
> /* Set up TX and RX descriptor area. */
> err = cgem_setup_descs(sc);
> @@ -1787,26 +1912,21 @@ cgem_detach(device_t dev)
> bus_dmamap_unload(sc->desc_dma_tag,
> sc->rxring_dma_map);
> sc->rxring_physaddr = 0;
> + sc->txring_physaddr = 0;
> + sc->null_qs_physaddr = 0;
> }
> bus_dmamem_free(sc->desc_dma_tag, sc->rxring,
> sc->rxring_dma_map);
> sc->rxring = NULL;
> + sc->txring = NULL;
> + sc->null_qs = NULL;
> +
> for (i = 0; i < CGEM_NUM_RX_DESCS; i++)
> if (sc->rxring_m_dmamap[i] != NULL) {
> bus_dmamap_destroy(sc->mbuf_dma_tag,
> sc->rxring_m_dmamap[i]);
> sc->rxring_m_dmamap[i] = NULL;
> }
> - }
> - if (sc->txring != NULL) {
> - if (sc->txring_physaddr != 0) {
> - bus_dmamap_unload(sc->desc_dma_tag,
> - sc->txring_dma_map);
> - sc->txring_physaddr = 0;
> - }
> - bus_dmamem_free(sc->desc_dma_tag, sc->txring,
> - sc->txring_dma_map);
> - sc->txring = NULL;
> for (i = 0; i < CGEM_NUM_TX_DESCS; i++)
> if (sc->txring_m_dmamap[i] != NULL) {
> bus_dmamap_destroy(sc->mbuf_dma_tag,
> @@ -1823,6 +1943,13 @@ cgem_detach(device_t dev)
> sc->mbuf_dma_tag = NULL;
> }
>
> +#ifdef EXT_RESOURCES
> + if (sc->ref_clk != NULL) {
> + clk_release(sc->ref_clk);
> + sc->ref_clk = NULL;
> + }
> +#endif
> +
> bus_generic_detach(dev);
>
> CGEM_LOCK_DESTROY(sc);
> @@ -1836,9 +1963,6 @@ static device_method_t cgem_methods[] = {
> DEVMETHOD(device_attach, cgem_attach),
> DEVMETHOD(device_detach, cgem_detach),
>
> - /* Bus interface */
> - DEVMETHOD(bus_child_detached, cgem_child_detached),
> -
> /* MII interface */
> DEVMETHOD(miibus_readreg, cgem_miibus_readreg),
> DEVMETHOD(miibus_writereg, cgem_miibus_writereg),
> @@ -1858,3 +1982,4 @@ DRIVER_MODULE(cgem, simplebus, cgem_driver, cgem_devclass, NULL, NULL);
> DRIVER_MODULE(miibus, cgem, miibus_driver, miibus_devclass, NULL, NULL);
> MODULE_DEPEND(cgem, miibus, 1, 1, 1);
> MODULE_DEPEND(cgem, ether, 1, 1, 1);
> +SIMPLEBUS_PNP_INFO(compat_data);
> diff --git a/sys/dev/cadence/if_cgem_hw.h b/sys/dev/cadence/if_cgem_hw.h
> index fced73327d91..784b131a885e 100644
> --- a/sys/dev/cadence/if_cgem_hw.h
> +++ b/sys/dev/cadence/if_cgem_hw.h
> @@ -35,6 +35,10 @@
> * Reference: Zynq-7000 All Programmable SoC Technical Reference Manual.
> * (v1.4) November 16, 2012. Xilinx doc UG585. GEM is covered in Ch. 16
> * and register definitions are in appendix B.18.
> + *
> + * Additional Reference: Zynq UltraScale+ Device Register Reference
> + * (UG1087 v1.7 Feb 8,2019):
> + * https://www.xilinx.com/html_docs/registers/ug1087/ug1087-zynq-ultrascale-registers.html
> */
>
> #ifndef _IF_CGEM_HW_H_
> @@ -113,6 +117,7 @@
> #define CGEM_USER_IO 0x00C /* User I/O */
>
> #define CGEM_DMA_CFG 0x010 /* DMA Config */
> +#define CGEM_DMA_CFG_ADDR_BUS_64 (1 << 30)
> #define CGEM_DMA_CFG_DISC_WHEN_NO_AHB (1 << 24)
> #define CGEM_DMA_CFG_RX_BUF_SIZE_SHIFT 16
> #define CGEM_DMA_CFG_RX_BUF_SIZE_MASK (0xff << 16)
> @@ -290,6 +295,29 @@
> #define CGEM_PTP_PEER_RX_S 0x1F8 /* PTP Peer Event rcv'd s */
> #define CGEM_PTP_PEER_RX_NS 0x1FC /* PTP Peer Event rcv'd ns */
>
> +#define CGEM_DESIGN_CFG1 0x280 /* Design Configuration 1 */
> +#define CGEM_DESIGN_CFG1_AXI_CACHE_WIDTH_MASK (0xfU << 28)
> +#define CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_MASK (7 << 25)
> +#define CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_32 (1 << 25)
> +#define CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_64 (2 << 25)
> +#define CGEM_DESIGN_CFG1_DMA_BUS_WIDTH_128 (4 << 25)
> +#define CGEM_DESIGN_CFG1_IRQ_READ_CLR (1 << 23)
> +#define CGEM_DESIGN_CFG1_NO_SNAPSHOT (1 << 22)
> +#define CGEM_DESIGN_CFG1_NO_STATS (1 << 21)
> +#define CGEM_DESIGN_CFG1_NO_SCAN_PINS (1 << 20)
> +#define CGEM_DESIGN_CFG1_USER_IN_WIDTH_MASK (0x1f << 15)
> +#define CGEM_DESIGN_CFG1_USER_OUT_WIDTH_MASK (0x1f << 10)
> +#define CGEM_DESIGN_CFG1_USER_IO (1 << 9)
> +#define CGEM_DESIGN_CFG1_APB_REV2 (1 << 8)
> +#define CGEM_DESIGN_CFG1_APB_REV1 (1 << 7)
> +#define CGEM_DESIGN_CFG1_EXT_FIFO_INTERFACE (1 << 6)
> +#define CGEM_DESIGN_CFG1_NO_INT_LOOPBACK (1 << 5)
> +#define CGEM_DESIGN_CFG1_INT_LOOPBACK (1 << 4)
> +#define CGEM_DESIGN_CFG1_TDC_50 (1 << 3)
> +#define CGEM_DESIGN_CFG1_RDC_50 (1 << 2)
> +#define CGEM_DESIGN_CFG1_SERDES (1 << 1)
> +#define CGEM_DESIGN_CFG1_NO_PCS (1 << 0)
> +
> #define CGEM_DESIGN_CFG2 0x284 /* Design Configuration 2 */
> #define CGEM_DESIGN_CFG2_TX_PBUF_ADDR_SHIFT 26
> #define CGEM_DESIGN_CFG2_TX_PBUF_ADDR_MASK (0xf << 26)
> @@ -330,7 +358,25 @@
> #define CGEM_DESIGN_CFG5_TX_FIFO_CNT_WIDTH_MASK (0xf << 4)
> #define CGEM_DESIGN_CFG5_RX_FIFO_CNT_WIDTH_MASK 0xf
>
> -/* Transmit Descriptors */
> +#define CGEM_DESIGN_CFG6 0x294 /* Design Configuration 6 */
> +#define CGEM_DESIGN_CFG6_ADDR_64B (1 << 23) /* 64-bit addr cap */
> +#define CGEM_DESIGN_CFG6_DMA_PRIO_Q_MASK 0xfffe
> +#define CGEM_DESIGN_CFG6_DMA_PRIO_Q(n) (1 << (n))
> +
> +#define CGEM_TX_QN_BAR(n) (0x440 + ((n) - 1) * 4)
> +#define CGEM_RX_QN_BAR(n) (0x480 + ((n) - 1) * 4)
> +
> +#define CGEM_TX_QBAR_HI 0x4C8
> +#define CGEM_RX_QBAR_HI 0x4D4
> +
> +/*
> + * Transmit Descriptors: two or four 32-bit words:
> + * word0: address
> + * word1: length and control
> + * word2: address upper 32-bits (64-bit mode)
> + * word3: unused (64-bit mode)
> + */
> +
> struct cgem_tx_desc {
> uint32_t addr;
> uint32_t ctl;
> @@ -350,8 +396,20 @@ struct cgem_tx_desc {
> #define CGEM_TXDESC_NO_CRC_APPENDED (1 << 16)
> #define CGEM_TXDESC_LAST_BUF (1 << 15) /* last in frame */
> #define CGEM_TXDESC_LENGTH_MASK 0x3fff
> +#ifdef CGEM64
> + uint32_t addrhi;
> + uint32_t unused;
> +#endif
> };
>
> +/*
> + * Receive Descriptors: two or four 32-bit words:
> + * word0: address | WRAP and OWN flags
> + * word1: length and control
> + * word2: address upper 32 bits (64-bit mode)
> + * word3: unused
> + */
> +
> struct cgem_rx_desc {
> uint32_t addr;
> #define CGEM_RXDESC_WRAP (1 << 1) /* goes in addr! */
> @@ -379,6 +437,10 @@ struct cgem_rx_desc {
> #define CGEM_RXDESC_SOF (1 << 14) /* start of frame */
> #define CGEM_RXDESC_BAD_FCS (1 << 13)
> #define CGEM_RXDESC_LENGTH_MASK 0x1fff
> +#ifdef CGEM64
> + uint32_t addrhi;
> + uint32_t unused;
> +#endif
> };
>
> #endif /* _IF_CGEM_HW_H_ */
> diff --git a/sys/dts/arm/zynq-7000.dtsi b/sys/dts/arm/zynq-7000.dtsi
> index a48c7bb732a1..a2a585a39446 100644
> --- a/sys/dts/arm/zynq-7000.dtsi
> +++ b/sys/dts/arm/zynq-7000.dtsi
> @@ -176,20 +176,20 @@
> *** 40 LINES SKIPPED ***
>
More information about the dev-commits-src-all
mailing list