CGEM(4)

πŸ“¦ in nixpkgs unstable

πŸ’– cgem(4) β€” the Cadence GEM Gigabit Ethernet driver, explained by your local Unix bestie πŸ’–

okay so this is a page from the Kernel Interfaces Manual, and it's all about cgem β€” literally the driver for the Cadence GEM, which stands for Gigabit Ethernet MAC. no cap, it's lowkey iconic. πŸ¦‹


✨ NAME ✨

cgem β€” the Cadence GEM Gigabit Ethernet driver. that's it, that's the name, slay. πŸ‘‘


🌸 SYNOPSIS 🌸

so if you wanna compile this driver into the kernel (main character energy, no modules), you drop these lines into your kernel config file:

device ether
device miibus
device cgem

that's the whole vibe check. three lines. you got this. 🫢


πŸŽ€ DESCRIPTION πŸŽ€

okay so the cgem driver is out here providing support for the Cadence GEM (Gigabit Ethernet MAC). and the Cadence GEM shows up in some SoC (System on a Chip) devices β€” specifically these icons:

  • the Xilinx Zynq-7000
  • the Xilinx Zynq UltraScale+
  • the SiFive HiFive Unleashed

the cgem driver supports the following media types, bestie:

  • autoselect β€” turns on autoselection of the media type and options. you can still manually override the autoselected mode using ifconfig(8), or by adding media options to rc.conf(5). yes, you're allowed to be a control freak about it. πŸ’…
  • 10baseT/UTP β€” sets 10Mbps operation. the ifconfig(8) mediaopt option can also be used to select either full-duplex or half-duplex modes.
  • 100baseTX β€” sets 100Mbps (Fast Ethernet) operation. the ifconfig(8) mediaopt option can also be used to select either full-duplex or half-duplex modes.
  • 1000baseT β€” sets 1000Mbps (Gigabit Ethernet) operation over twisted pair. real talk though: the GEM supports 1000Mbps in full-duplex mode only. that's the rule, periodt.

and the cgem driver supports these media options too:

  • full-duplex β€” force full-duplex operation.
  • half-duplex β€” force half-duplex operation.

the driver also provides support for TCP/UDP/IP checksum offloading β€” although it's disabled by default, so don't come for me. πŸ™ˆ and the device + driver support 1536-byte frames for VLANs (vlanmtu). cute.


πŸ”₯ SYSCTL VARIABLES πŸ”₯

the following variables are available as both sysctl(8) variables and loader(8) tunables. double duty, we stan:

  • dev.cgem.%d.rxbufs β€” the number of receive buffers allocated to the hardware. the default value is 256. the maximum value is 511. careful though, bestie: if you increase this number while the interface is UP, it will not take effect until the next packet is received. and if you decrease this number 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. so it's giving "eventually", not "instantly". ⭐
  • dev.cgem.%d.rxhangwar β€” this tunable enables a work-around to recover from receive hangs. the default value is 1. set it to 0 to disable the work-around.

πŸ’œ the read-only girlies πŸ’œ

the following read-only variables are available as sysctl(8) variables:

  • dev.cgem.%d._rxoverruns β€” this variable counts the number of receive packet buffer overrun interrupts.
  • dev.cgem.%d._rxnobufs β€” this variable counts the number of interrupts due to the GEM buffer ring going empty.
  • dev.cgem.%d._rxdmamapfails β€” this variable is the number of times bus_dmamap_load_mbuf_sg(9) failed in the receive path.
  • dev.cgem.%d._txfull β€” the number of times the GEM's transmit ring was full.
  • dev.cgem.%d._txdmamapfails β€” this variable is the number of times bus_dmamap_load_mbuf_sg(9) failed in the transmit path.
  • 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.
  • dev.cgem.%d._txdefragfails β€” this variable is the number of times m_defrag(9) failed.

🌈 dev.cgem.%d.stats.* β€” the hardware flex 🌈

the following variables are useful MAC counters supplied by the hardware. these are literally the receipts:

πŸ’« transmit counters πŸ’«

  • dev.cgem.%d.stats.tx_bytes β€” a 64-bit counter of the number of bytes transmitted in frames without error.
  • dev.cgem.%d.stats.tx_frames β€” counter of frames transmitted without error excluding pause frames.
  • dev.cgem.%d.stats.tx_frames_bcast β€” counter of broadcast frames transmitted without error excluding pause frames.
  • dev.cgem.%d.stats.tx_frames_multi β€” counter of multicast frames transmitted without error excluding pause frames.
  • dev.cgem.%d.stats.tx_frames_pause β€” counter of pause frames transmitted without error.
  • dev.cgem.%d.stats.tx_frames_64b β€” counter of 64 byte frames transmitted without error.
  • dev.cgem.%d.stats.tx_frames_65to127b β€” counter of 65 to 127 byte frames transmitted without error.
  • dev.cgem.%d.stats.tx_frames_128to255b β€” counter of 128 to 255 byte frames transmitted without error.
  • dev.cgem.%d.stats.tx_frames_256to511b β€” counter of 256 to 511 byte frames transmitted without error.
  • dev.cgem.%d.stats.tx_frames_512to1023b β€” counter of 512 to 1023 byte frames transmitted without error.
  • dev.cgem.%d.stats.tx_frames_1024to1536b β€” counter of 1024 to 1536 byte frames transmitted without error.
  • dev.cgem.%d.stats.tx_under_runs β€” counter of frames not transmitted due to a transmit underrun. πŸ’€
  • dev.cgem.%d.stats.tx_single_collisn β€” counter of frames experiencing a single collision before being successfully transmitted.
  • dev.cgem.%d.stats.tx_multi_collisn β€” counter of frames experiencing between 2 and 15 collisions before being successfully transmitted.
  • dev.cgem.%d.stats.tx_excsv_collisn β€” counter of frames that failed to transmit because they experienced 16 collisions.
  • dev.cgem.%d.stats.tx_late_collisn β€” counter of frames that experienced a late collision.
  • dev.cgem.%d.stats.tx_deferred_frames β€” counter of frames experiencing deferral due to carrier sense being active on their first attempt at transmission.
  • 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.

🌸 receive counters 🌸

  • dev.cgem.%d.stats.rx_bytes β€” a 64-bit counter of bytes received without error excluding pause frames.
  • dev.cgem.%d.stats.rx_frames β€” counter of frames received without error excluding pause frames.
  • dev.cgem.%d.stats.rx_frames_bcast β€” counter of broadcast frames receive without error excluding pause frames.
  • dev.cgem.%d.stats.rx_frames_multi β€” counter of multicast frames receive without error excluding pause frames.
  • dev.cgem.%d.stats.rx_frames_pause β€” counter of pause frames received without error.
  • dev.cgem.%d.stats.rx_frames_64b β€” counter of 64-byte frames received without error.
  • dev.cgem.%d.stats.rx_frames_65to127b β€” counter of 65 to 127 byte frames received without error.
  • dev.cgem.%d.stats.rx_frames_128to255b β€” counter of 128 to 255 byte frames received without error.
  • dev.cgem.%d.stats.rx_frames_256to511b β€” counter of 256 to 511 byte frames received without error.
  • dev.cgem.%d.stats.rx_frames_512to1023b β€” counter of 512 to 1023 byte frames received without error.
  • dev.cgem.%d.stats.rx_frames_1024to1536b β€” counter of 1024 to 1536 byte frames received without error.
  • 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.
  • 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.
  • 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.
  • dev.cgem.%d.stats.rx_frames_fcs_errs β€” counter of frames received with a bad CRC and are between 64 and 1536 bytes.
  • dev.cgem.%d.stats.rx_frames_length_errs β€” counter of frames received that are shorter than that extracted from the length field.
  • dev.cgem.%d.stats.rx_symbol_errs β€” counter of receive symbol errors.
  • dev.cgem.%d.stats.rx_align_errs β€” counter of received frames that are not an integral number of bytes.
  • 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. 😭
  • 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.
  • 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.
  • dev.cgem.%d.stats.rx_frames_tcp_csum_errs β€” counter of frames discarded due to an incorrect TCP checksum when checksum offloading is enabled.
  • dev.cgem.%d.stats.rx_frames_udp_csum_errs β€” counter of frames discarded due to an incorrect UDP checksum when checksum offloading is enabled.

πŸ¦‹ SEE ALSO πŸ¦‹

and also this absolute tome, iykyk:

Zynq-7000 SoC Technical Reference Manual (Xilinx doc UG585), http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf.

⭐ HISTORY ⭐

the cgem device driver first appeared in FreeBSD 10.0. a whole era. πŸŽ€


πŸ’… AUTHORS πŸ’…

the cgem driver and this manual page was written by Thomas Skibo <thomasskibo@yahoo.com>. give him his flowers. πŸ‘‘


πŸ’€ BUGS πŸ’€

okay so this is the part where we're real with each other, bestie. buckle up.

the GEM can perform TCP/UDP/IP checksum offloading. however β€” and this is the big 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. that's literally not the vibe. for this reason, checksum offloading is disabled by default but can be enabled using ifconfig(8). so like, think before you toggle. πŸ™ˆ

when receive checksum offloading is enabled, the device will discard packets with bad TCP/UDP/IP checksums. and plot twist: the bad packets will not be counted in any netstat(1) statistics. there are sysctl(8) variables that count packets discarded by the hardware β€” see below, they've got you covered. πŸ”₯

and here's the lore: 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 cgem driver implements the work-around suggested in the manual. 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. and if you really wanna turn it off yourself, you can β€” by setting the dev.cgem.%d.rxhangwar sysctl(8) variable to 0. you do you. πŸ’œ


okay that's the whole page, go touch grass and then go configure your NIC 🧚 this was the Debian build, dated January 10, 2021 β€” mwah, love u, bye! πŸ’–βœ¨πŸ“

πŸ“¦ where this page comes from
  • nixpkgs unstable: source
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms