Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115923740
D24304.id75253.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
41 KB
Referenced Files
None
Subscribers
None
D24304.id75253.diff
View Options
Index: share/man/man4/Makefile
===================================================================
--- share/man/man4/Makefile
+++ share/man/man4/Makefile
@@ -106,6 +106,7 @@
cdceem.4 \
cfi.4 \
cfumass.4 \
+ ${_cgem.4} \
ch.4 \
chromebook_platform.4 \
${_chvgpio.4} \
@@ -880,6 +881,12 @@
_virtio_random.4= virtio_random.4
_virtio_scsi.4= virtio_scsi.4
_vtnet.4= vtnet.4
+.endif
+
+.if ${MACHINE_ARCH} == "armv7" || ${MACHINE_ARCH} == "aarch64" || \
+ ${MACHINE_ARCH} == "riscv64"
+_cgem.4= cgem.4
+MLINKS+=cgem.4 if_cgem.4
.endif
.if empty(MAN_ARCH)
Index: share/man/man4/cgem.4
===================================================================
--- share/man/man4/cgem.4
+++ share/man/man4/cgem.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD: head/share/man/man4/man4.arm/cgem.4 301591 2016-06-08 09:36:07Z trasz $
.\"
-.Dd August 26, 2014
+.Dd March 27, 2020
.Dt CGEM 4
.Os
.Sh NAME
@@ -44,7 +44,8 @@
.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 @@
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 @@
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.
Index: share/man/man4/man4.arm/Makefile
===================================================================
--- share/man/man4/man4.arm/Makefile
+++ share/man/man4/man4.arm/Makefile
@@ -8,7 +8,6 @@
aw_spi.4 \
aw_syscon.4 \
bcm283x_pwm.4 \
- cgem.4 \
devcfg.4 \
imx6_ahci.4 \
imx6_snvs.4 \
@@ -16,8 +15,7 @@
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
Index: share/man/man4/man4.arm/cgem.4
===================================================================
--- share/man/man4/man4.arm/cgem.4
+++ share/man/man4/man4.arm/cgem.4
@@ -1,298 +0,0 @@
-.\"
-.\" Copyright (c) 2014 Thomas Skibo <thomasskibo@yahoo.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. The name of the author may not be used to endorse or promote products
-.\" derived from this software without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd August 26, 2014
-.Dt CGEM 4
-.Os
-.Sh NAME
-.Nm cgem
-.Nd "Cadence GEM Gigabit Ethernet driver"
-.Sh SYNOPSIS
-To compile this driver into the kernel,
-place the following lines in your
-kernel configuration file:
-.Bd -ragged -offset indent
-.Cd "device ether"
-.Cd "device miibus"
-.Cd "device cgem"
-.Ed
-.Sh DESCRIPTION
-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.
-.Pp
-The
-.Nm
-driver supports the following media types:
-.Bl -tag -width ".Cm 10baseT/UTP"
-.It Cm autoselect
-Enable autoselection of the media type and options.
-The user can manually override
-the autoselected mode using
-.Xr ifconfig 8
-or by adding media options to
-.Xr rc.conf 5 .
-.It Cm 10baseT/UTP
-Set 10Mbps operation.
-The
-.Xr ifconfig 8
-.Cm mediaopt
-option can also be used to select either
-.Cm full-duplex
-or
-.Cm half-duplex
-modes.
-.It Cm 100baseTX
-Set 100Mbps (Fast Ethernet) operation.
-The
-.Xr ifconfig 8
-.Cm mediaopt
-option can also be used to select either
-.Cm full-duplex
-or
-.Cm half-duplex
-modes.
-.It Cm 1000baseT
-Set 1000Mbps (Gigabit Ethernet) operation over twisted pair.
-The GEM supports 1000Mbps in
-.Cm full-duplex
-mode only.
-.El
-.Pp
-The
-.Nm
-driver supports the following media options:
-.Bl -tag -width ".Cm full-duplex"
-.It Cm full-duplex
-Force full-duplex operation.
-.It Cm half-duplex
-Force half-duplex operation.
-.El
-.Pp
-The driver provides support for TCP/UDP/IP checksum offloading (although
-disabled by default).
-The device and driver also support 1536-byte frames for VLANs (vlanmtu).
-.Sh SYSCTL VARIABLES
-The following variables are available as both
-.Xr sysctl 8
-variables and
-.Xr loader 8
-tunables:
-.Bl -tag -width "xxxxxxxx"
-.It Va dev.cgem.%d.rxbufs
-The number of receive buffers allocated to the hardware.
-The default value is 256.
-The maximum value is 511.
-If this number is increased while the interface is UP, it will not
-take effect until the next packet is received.
-If this number is decreased while the interface is UP, buffers will
-not be immediately removed from the receive buffer ring but the
-number of buffers will decrease as packets are received until it
-reaches the new value.
-.It Va dev.cgem.%d.rxhangwar
-This tunable enables a work-around to recover from receive hangs.
-The default value is 1.
-Set to 0 to disable the work-around.
-.El
-.Pp
-The following read-only variables are available as
-.Xr sysctl 8
-variables:
-.Bl -tag -width "xxxxxxxx"
-.It Va dev.cgem.%d._rxoverruns
-This variable counts the number of receive packet buffer overrun interrupts.
-.It Va dev.cgem.%d._rxnobufs
-This variable counts the number of interrupts due to the GEM buffer ring
-going empty.
-.It Va dev.cgem.%d._rxdmamapfails
-This variable is the number of times bus_dmamap_load_mbuf_sg(9) failed in
-the receive path.
-.It Va dev.cgem.%d._txfull
-The number of times the GEM's transmit ring was full.
-.It Va dev.cgem.%d._txdmamapfails
-This variable is the number of times bus_dmamap_load_mbuf_sg(9) failed in
-the transmit path.
-.It Va dev.cgem.%d._txdefrags
-This variable is the number of times the driver needed to call m_defrag(9)
-because a packet queued for transmit had too many DMA segments.
-.It Va dev.cgem.%d._txdefragfails
-This variable is the number of times
-.Xr m_defrag 9
-failed.
-.It Va dev.cgem.%d.stats.*
-The following variables are useful MAC counters supplied by the hardware:
-.It Va dev.cgem.%d.stats.tx_bytes
-A 64-bit counter of the number of bytes transmitted in frames without error.
-.It Va dev.cgem.%d.stats.tx_frames
-Counter of frames transmitted without error excluding pause frames.
-.It Va dev.cgem.%d.stats.tx_frames_bcast
-Counter of broadcast frames transmitted without error excluding
-pause frames.
-.It Va dev.cgem.%d.stats.tx_frames_multi
-Counter of multicast frames transmitted without error excluding
-pause frames.
-.It Va dev.cgem.%d.stats.tx_frames_pause
-Counter of pause frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_frames_64b
-Counter of 64 byte frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_frames_65to127b
-Counter of 65 to 127 byte frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_frames_128to255b
-Counter of 128 to 255 byte frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_frames_256to511b
-Counter of 256 to 511 byte frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_frames_512to1023b
-Counter of 512 to 1023 byte frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_frames_1024to1536b
-Counter of 1024 to 1536 byte frames transmitted without error.
-.It Va dev.cgem.%d.stats.tx_under_runs
-Counter of frames not transmitted due to a transmit underrun.
-.It Va dev.cgem.%d.stats.tx_single_collisn
-Counter of frames experiencing a single collision before being successfully
-transmitted.
-.It Va dev.cgem.%d.stats.tx_multi_collisn
-Counter of frames experiencing between 2 and 15 collisions before
-being successfully transmitted.
-.It Va dev.cgem.%d.stats.tx_excsv_collisn
-Counter of frames that failed to transmit because they experienced 16
-collisions.
-.It Va dev.cgem.%d.stats.tx_late_collisn
-Counter of frames that experienced a late collision.
-.It Va dev.cgem.%d.stats.tx_deferred_frames
-Counter of frames experiencing deferral due to carrier sense being
-active on their first attempt at transmission.
-.It Va dev.cgem.%d.stats.tx_carrier_sense_errs
-Counter of frames transmitted where carrier sense was not seen during
-transmission or where carrier sense was deasserted after being asserted
-in a transmit frame without collision.
-.It Va dev.cgem.%d.stats.rx_bytes
-A 64-bit counter of bytes received without error excluding pause
-frames.
-.It Va dev.cgem.%d.stats.rx_frames
-Counter of frames received without error excluding pause frames.
-.It Va dev.cgem.%d.stats.rx_frames_bcast
-Counter of broadcast frames receive without error excluding pause frames.
-.It Va dev.cgem.%d.stats.rx_frames_multi
-Counter of multicast frames receive without error excluding pause frames.
-.It Va dev.cgem.%d.stats.rx_frames_pause
-Counter of pause frames recevied without error.
-.It Va dev.cgem.%d.stats.rx_frames_64b
-Counter of 64-byte frames received without error.
-.It Va dev.cgem.%d.stats.rx_frames_65to127b
-Counter of 65 to 127 byte frames received without error.
-.It Va dev.cgem.%d.stats.rx_frames_128to255b
-Counter of 128 to 255 byte frames received without error.
-.It Va dev.cgem.%d.stats.rx_frames_256to511b
-Counter of 256 to 511 byte frames received without error.
-.It Va dev.cgem.%d.stats.rx_frames_512to1023b
-Counter of 512 to 1023 byte frames received without error.
-.It Va dev.cgem.%d.stats.rx_frames_1024to1536b
-Counter of 1024 to 1536 byte frames received without error.
-.It Va dev.cgem.%d.stats.rx_frames_undersize
-Counter of frames received less than 64 bytes in length that
-do not also have either a CRC error or an alignment error.
-.It Va dev.cgem.%d.stats.rx_frames_oversize
-Counter of frames received exceeding 1536 bytes and do not also have either
-a CRC error or an alignment error.
-.It Va dev.cgem.%d.stats.rx_frames_jabber
-Counter of frames received exceeding 1536 bytes and also have either a CRC
-error, an alignment error, or a receive symbol error.
-.It Va dev.cgem.%d.stats.rx_frames_fcs_errs
-Counter of frames received with a bad CRC and are between 64
-and 1536 bytes.
-.It Va dev.cgem.%d.stats.rx_frames_length_errs
-Counter of frames received that are shorter than that extracted
-from the length field.
-.It Va dev.cgem.%d.stats.rx_symbol_errs
-Counter of receive symbol errors.
-.It Va dev.cgem.%d.stats.rx_align_errs
-Counter of received frames that are not an integral number of bytes.
-.It Va dev.cgem.%d.stats.rx_resource_errs
-Counter of frames successfully receive by the MAC but could not be
-copied to memory because no receive buffer was available.
-.It Va dev.cgem.%d.stats.rx_overrun_errs
-Counter of frames that are address recognized but were not copied
-to memory due to a receive overrun.
-.It Va dev.cgem.%d.stats.rx_frames_ip_hdr_csum_errs
-Counter of frames discarded due to an incorrect IP header checksum when
-checksum offloading is enabled.
-.It Va dev.cgem.%d.stats.rx_frames_tcp_csum_errs
-Counter of frames discarded due to an incorrect TCP checksum when
-checksum offloading is enabled.
-.It Va dev.cgem.%d.stats.rx_frames_udp_csum_errs
-Counter of frames discarded due to an incorrect UDP checksum when
-checksum offloading is enabled.
-.El
-.Sh SEE ALSO
-.Xr miibus 4 ,
-.Xr ifconfig 8
-.Rs
-.%T "Zynq-7000 SoC Technical Reference Manual (Xilinx doc UG585)"
-.%U http://www.xilinx.com/support/documentation/user_guides/\:ug585-Zynq-7000-TRM.pdf
-.Re
-.Sh HISTORY
-The
-.Nm
-device driver first appeared in
-.Fx 10.0 .
-.Sh AUTHORS
-The
-.Nm
-driver and this manual page was written by
-.An Thomas Skibo Aq Mt thomasskibo@yahoo.com .
-.Sh BUGS
-The GEM can perform TCP/UDP/IP checksum offloading.
-However, when transmit checksum offloading is enabled, the GEM generates and
-replaces checksums for all packets it transmits.
-In a system that is forwarding packets, the device could potentially correct
-the checksum of packet that was corrupted in transit.
-For this reason, checksum offloading is disabled by default but can be
-enabled using ifconfig(8).
-.Pp
-When receive checksum offloading is enabled, the device will discard packets
-with bad TCP/UDP/IP checksums.
-The bad packets will not be counted in any
-.Xr netstat 1
-statistics.
-There are
-.Xr sysctl 8
-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
-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
-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
-.Xr sysctl 8
-variable to 0.
Index: sys/arm/conf/GENERIC
===================================================================
--- sys/arm/conf/GENERIC
+++ sys/arm/conf/GENERIC
@@ -226,8 +226,8 @@
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
Index: sys/arm/conf/ZEDBOARD
===================================================================
--- sys/arm/conf/ZEDBOARD
+++ sys/arm/conf/ZEDBOARD
@@ -49,7 +49,7 @@
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
Index: sys/arm64/conf/GENERIC
===================================================================
--- sys/arm64/conf/GENERIC
+++ sys/arm64/conf/GENERIC
@@ -166,6 +166,7 @@
device miibus # MII bus support
device awg # Allwinner EMAC Gigabit Ethernet
device axgbe # AMD Opteron A1100 integrated NIC
+device cgem # Cadence GEM Gigabit Ethernet device
device msk # Marvell/SysKonnect Yukon II Gigabit Ethernet
device neta # Marvell Armada 370/38x/XP/3700 NIC
device smc # SMSC LAN91C111
Index: sys/dev/cadence/if_cgem.c
===================================================================
--- sys/dev/cadence/if_cgem.c
+++ sys/dev/cadence/if_cgem.c
@@ -77,6 +77,14 @@
#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,10 +94,6 @@
#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. */
@@ -98,11 +102,18 @@
#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 {
@@ -117,8 +128,13 @@
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;
@@ -147,12 +163,15 @@
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;
@@ -275,9 +294,9 @@
/*
* 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
@@ -322,18 +341,15 @@
{
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;
@@ -341,12 +357,12 @@
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. */
@@ -359,40 +375,92 @@
*(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,
+#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);
@@ -410,19 +478,10 @@
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);
+ 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);
- /* 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);
-
/* Initialize TX descriptor ring. */
for (i = 0; i < CGEM_NUM_TX_DESCS; i++) {
sc->txring[i].addr = 0;
@@ -436,6 +495,14 @@
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);
}
@@ -485,6 +552,9 @@
/* 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;
@@ -510,7 +580,7 @@
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;
@@ -632,9 +702,16 @@
/* 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);
@@ -643,8 +720,8 @@
/*
* 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)
@@ -763,7 +840,10 @@
/* 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) {
@@ -965,8 +1045,21 @@
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);
@@ -977,8 +1070,8 @@
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);
@@ -989,33 +1082,33 @@
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? */
@@ -1025,8 +1118,12 @@
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);
@@ -1059,8 +1156,10 @@
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);
}
@@ -1089,9 +1188,9 @@
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,
@@ -1110,9 +1209,9 @@
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,
@@ -1176,6 +1275,8 @@
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;
@@ -1210,16 +1311,16 @@
/* 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)) ==
@@ -1240,15 +1341,6 @@
/* 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)
{
@@ -1385,24 +1477,22 @@
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:
@@ -1410,15 +1500,25 @@
}
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;
}
@@ -1646,19 +1746,46 @@
{
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;
@@ -1671,7 +1798,8 @@
/* 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);
@@ -1703,7 +1831,6 @@
sc->if_old_flags = if_getflags(ifp);
sc->rxbufs = DEFAULT_NUM_RX_BUFS;
- sc->rxhangwar = 1;
/* Reset hardware. */
CGEM_LOCK(sc);
@@ -1714,11 +1841,8 @@
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);
@@ -1793,26 +1917,21 @@
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,
@@ -1829,6 +1948,13 @@
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);
@@ -1842,9 +1968,6 @@
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),
@@ -1864,3 +1987,4 @@
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);
Index: sys/dev/cadence/if_cgem_hw.h
===================================================================
--- sys/dev/cadence/if_cgem_hw.h
+++ 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 @@
#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 @@
#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_ */
Index: sys/dts/arm/zynq-7000.dtsi
===================================================================
--- sys/dts/arm/zynq-7000.dtsi
+++ sys/dts/arm/zynq-7000.dtsi
@@ -177,7 +177,7 @@
// Gigabit Ethernet controllers
eth0: eth@b000 {
device_type = "network";
- compatible = "cadence,gem";
+ compatible = "cdns,zynq-gem", "cadence,gem";
status = "disabled";
reg = <0xb000 0x1000>;
interrupts = <0 22 4>;
@@ -187,7 +187,7 @@
eth1: eth@c000 {
device_type = "network";
- compatible = "cadence,gem";
+ compatible = "cdns,zynq-gem", "cadence,gem";
status = "disabled";
reg = <0xc000 0x1000>;
interrupts = <0 45 4>;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, May 1, 11:37 AM (10 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17880408
Default Alt Text
D24304.id75253.diff (41 KB)
Attached To
Mode
D24304: Add 64-bit support to Cadence CGEM Ethernet driver.
Attached
Detach File
Event Timeline
Log In to Comment