iPXE
cgem.c File Reference

Cadence Gigabit Ethernet MAC (GEM) network driver. More...

#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/timer.h>
#include <ipxe/devtree.h>
#include <ipxe/fdt.h>
#include "cgem.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int cgem_reset (struct cgem_nic *cgem)
 Reset hardware.
static int cgem_mii_wait (struct cgem_nic *cgem)
 Wait for MII operation to complete.
static int cgem_mii_read (struct mii_interface *mdio, unsigned int phy, unsigned int reg)
 Read from MII register.
static int cgem_mii_write (struct mii_interface *mdio, unsigned int phy, unsigned int reg, unsigned int data)
 Write to MII register.
static int cgem_init_phy (struct cgem_nic *cgem)
 Initialise PHY.
static int cgem_check_link (struct net_device *netdev)
 Check link state.
static void cgem_expired (struct retry_timer *timer, int over __unused)
 Check link state periodically.
static int cgem_create_ring (struct cgem_nic *cgem, struct cgem_ring *ring)
 Create descriptor ring.
static void cgem_destroy_ring (struct cgem_nic *cgem, struct cgem_ring *ring)
 Destroy descriptor ring.
static void cgem_refill_rx (struct cgem_nic *cgem)
 Refill receive descriptor ring.
static int cgem_open (struct net_device *netdev)
 Open network device.
static void cgem_close (struct net_device *netdev)
 Close network device.
static int cgem_transmit (struct net_device *netdev, struct io_buffer *iobuf)
 Transmit packet.
static void cgem_poll_tx (struct net_device *netdev)
 Poll for completed packets.
static void cgem_poll_rx (struct net_device *netdev)
 Poll for received packets.
static void cgem_poll (struct net_device *netdev)
 Poll for completed and received packets.
static int cgem_probe (struct dt_device *dt, unsigned int offset)
 Probe devicetree device.
static void cgem_remove (struct dt_device *dt)
 Remove devicetree device.

Variables

static struct mii_operations cgem_mii_operations
 MII operations.
static struct net_device_operations cgem_operations
 Cadence GEM network device operations.
static const char * cgem_ids []
 Cadence GEM compatible model identifiers.
struct dt_driver cgem_driver __dt_driver
 Cadence GEM devicetree driver.

Detailed Description

Cadence Gigabit Ethernet MAC (GEM) network driver.

Based primarily on the Zynq 7000 SoC Technical Reference Manual, available at the time of writing from:

https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM

Definition in file cgem.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ cgem_reset()

int cgem_reset ( struct cgem_nic * cgem)
static

Reset hardware.

Parameters
cgemCadence GEM device
Return values
rcReturn status code

Definition at line 64 of file cgem.c.

64 {
65
66 /* There is no software-driven reset capability in the
67 * hardware. Instead we have to write the expected reset
68 * values to the various registers.
69 */
70
71 /* Disable all interrupts */
72 writel ( CGEM_IDR_ALL, ( cgem->regs + CGEM_IDR ) );
73
74 /* Clear network control register */
75 writel ( 0, ( cgem->regs + CGEM_NWCTRL ) );
76
77 /* Clear statistics registers now that TX and RX are stopped */
79
80 /* Clear TX queue base address */
81 writel ( 0, ( cgem->regs + CGEM_TXQBASE ) );
82
83 /* Clear RX queue base address */
84 writel ( 0, ( cgem->regs + CGEM_RXQBASE ) );
85
86 /* Configure DMA */
89 ( cgem->regs + CGEM_DMACR ) );
90
91 /* Enable MII interface */
92 writel ( CGEM_NWCTRL_MDEN, ( cgem->regs + CGEM_NWCTRL ) );
93
94 return 0;
95}
#define CGEM_NWCTRL_STATCLR
Clear statistics.
Definition cgem.h:26
#define CGEM_DMACR_BLENGTH_MAX
Max DMA burst length.
Definition cgem.h:52
#define CGEM_NWCTRL
Network control register.
Definition cgem.h:24
#define CGEM_DMACR_TXSIZE_MAX
Max TX memory size.
Definition cgem.h:46
#define CGEM_IDR_ALL
Disable all interrupts.
Definition cgem.h:63
#define CGEM_DMACR
DMA configuration register.
Definition cgem.h:43
#define CGEM_DMACR_RXBUF(x)
RX buffer size.
Definition cgem.h:44
#define CGEM_RX_LEN
Length of receive buffers.
Definition cgem.h:117
#define CGEM_DMACR_RXSIZE_MAX
Max RX memory size.
Definition cgem.h:49
#define CGEM_NWCTRL_MDEN
MII interface enable.
Definition cgem.h:27
#define CGEM_TXQBASE
TX queue base address register.
Definition cgem.h:59
#define CGEM_RXQBASE
RX queue base address register.
Definition cgem.h:56
#define CGEM_IDR
Interrupt disable register.
Definition cgem.h:62
void * regs
Registers.
Definition cgem.h:166
#define writel
Definition w89c840.c:160

References CGEM_DMACR, CGEM_DMACR_BLENGTH_MAX, CGEM_DMACR_RXBUF, CGEM_DMACR_RXSIZE_MAX, CGEM_DMACR_TXSIZE_MAX, CGEM_IDR, CGEM_IDR_ALL, CGEM_NWCTRL, CGEM_NWCTRL_MDEN, CGEM_NWCTRL_STATCLR, CGEM_RX_LEN, CGEM_RXQBASE, CGEM_TXQBASE, cgem_nic::regs, and writel.

Referenced by cgem_close(), cgem_probe(), and cgem_remove().

◆ cgem_mii_wait()

int cgem_mii_wait ( struct cgem_nic * cgem)
static

Wait for MII operation to complete.

Parameters
cgemCadence GEM device
Return values
rcReturn status code

Definition at line 110 of file cgem.c.

110 {
111 uint32_t nwsr;
112 unsigned int i;
113
114 /* Wait for MII interface to become idle */
115 for ( i = 0 ; i < CGEM_MII_MAX_WAIT_US ; i++ ) {
116
117 /* Check if MII interface is idle */
118 nwsr = readl ( cgem->regs + CGEM_NWSR );
119 if ( nwsr & CGEM_NWSR_MII_IDLE )
120 return 0;
121
122 /* Delay */
123 udelay ( 1 );
124 }
125
126 DBGC ( cgem, "CGEM %s timed out waiting for MII\n", cgem->name );
127 return -ETIMEDOUT;
128}
unsigned int uint32_t
Definition stdint.h:12
#define CGEM_NWSR_MII_IDLE
MII interface is idle.
Definition cgem.h:40
#define CGEM_MII_MAX_WAIT_US
Maximum time to wait for PHY access, in microseconds.
Definition cgem.h:76
#define CGEM_NWSR
Network status register.
Definition cgem.h:39
#define DBGC(...)
Definition compiler.h:505
#define ETIMEDOUT
Connection timed out.
Definition errno.h:670
const char * name
Device name (for debugging)
Definition cgem.h:172
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition timer.c:61
#define readl
Definition w89c840.c:157

References CGEM_MII_MAX_WAIT_US, CGEM_NWSR, CGEM_NWSR_MII_IDLE, DBGC, ETIMEDOUT, cgem_nic::name, readl, cgem_nic::regs, and udelay().

Referenced by cgem_mii_read(), and cgem_mii_write().

◆ cgem_mii_read()

int cgem_mii_read ( struct mii_interface * mdio,
unsigned int phy,
unsigned int reg )
static

Read from MII register.

Parameters
mdioMII interface
phyPHY address
regRegister address
Return values
dataData read, or negative error

Definition at line 138 of file cgem.c.

139 {
140 struct cgem_nic *cgem = container_of ( mdio, struct cgem_nic, mdio );
141 unsigned int data;
142 int rc;
143
144 /* Initiate read */
148 ( cgem->regs + CGEM_PHYMNTNC ) );
149
150 /* Wait for read to complete */
151 if ( ( rc = cgem_mii_wait ( cgem ) ) != 0 )
152 return rc;
153
154 /* Read data */
155 data = ( readl ( cgem->regs + CGEM_PHYMNTNC ) &
157
158 return data;
159}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
static int cgem_mii_wait(struct cgem_nic *cgem)
Wait for MII operation to complete.
Definition cgem.c:110
#define CGEM_PHYMNTNC_DATA_MASK
Data mask.
Definition cgem.h:73
#define CGEM_PHYMNTNC
PHY maintenance register.
Definition cgem.h:66
#define CGEM_PHYMNTNC_FIXED
Fixed value to write.
Definition cgem.h:72
#define CGEM_PHYMNTNC_ADDR(x)
PHY address.
Definition cgem.h:70
#define CGEM_PHYMNTNC_CLAUSE22
Clause 22 operation.
Definition cgem.h:67
#define CGEM_PHYMNTNC_OP_READ
Read from PHY register.
Definition cgem.h:69
#define CGEM_PHYMNTNC_REG(x)
Register address.
Definition cgem.h:71
uint8_t data[48]
Additional event data.
Definition ena.h:11
static unsigned int unsigned int reg
Definition myson.h:162
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A Cadence GEM network card.
Definition cgem.h:164
struct mii_interface mdio
PHY interface.
Definition cgem.h:175

References cgem_mii_wait(), CGEM_PHYMNTNC, CGEM_PHYMNTNC_ADDR, CGEM_PHYMNTNC_CLAUSE22, CGEM_PHYMNTNC_DATA_MASK, CGEM_PHYMNTNC_FIXED, CGEM_PHYMNTNC_OP_READ, CGEM_PHYMNTNC_REG, container_of, data, cgem_nic::mdio, rc, readl, reg, cgem_nic::regs, and writel.

◆ cgem_mii_write()

int cgem_mii_write ( struct mii_interface * mdio,
unsigned int phy,
unsigned int reg,
unsigned int data )
static

Write to MII register.

Parameters
mdioMII interface
phyPHY address
regRegister address
dataData to write
Return values
rcReturn status code

Definition at line 170 of file cgem.c.

171 {
172 struct cgem_nic *cgem = container_of ( mdio, struct cgem_nic, mdio );
173 int rc;
174
175 /* Initiate write */
179 ( cgem->regs + CGEM_PHYMNTNC ) );
180
181 /* Wait for write to complete */
182 if ( ( rc = cgem_mii_wait ( cgem ) ) != 0 )
183 return rc;
184
185 return 0;
186}

References cgem_mii_wait(), CGEM_PHYMNTNC, CGEM_PHYMNTNC_ADDR, CGEM_PHYMNTNC_CLAUSE22, CGEM_PHYMNTNC_FIXED, CGEM_PHYMNTNC_OP_READ, CGEM_PHYMNTNC_REG, container_of, data, cgem_nic::mdio, rc, reg, cgem_nic::regs, and writel.

◆ cgem_init_phy()

int cgem_init_phy ( struct cgem_nic * cgem)
static

Initialise PHY.

Parameters
cgemCadence GEM device
Return values
rcReturn status code

Definition at line 207 of file cgem.c.

207 {
208 int rc;
209
210 /* Find PHY address */
211 if ( ( rc = mii_find ( &cgem->mii ) ) != 0 ) {
212 DBGC ( cgem, "CGEM %s could not find PHY address: %s\n",
213 cgem->name, strerror ( rc ) );
214 return rc;
215 }
216
217 /* Reset PHY */
218 if ( ( rc = mii_reset ( &cgem->mii ) ) != 0 ) {
219 DBGC ( cgem, "CGEM %s could not reset PHY: %s\n",
220 cgem->name, strerror ( rc ) );
221 return rc;
222 }
223
224 return 0;
225}
int mii_reset(struct mii_device *mii)
Reset MII device.
Definition mii.c:75
int mii_find(struct mii_device *mii)
Find PHY address.
Definition mii.c:158
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct mii_device mii
PHY device.
Definition cgem.h:177

References DBGC, cgem_nic::mii, mii_find(), mii_reset(), cgem_nic::name, rc, and strerror().

Referenced by cgem_probe().

◆ cgem_check_link()

int cgem_check_link ( struct net_device * netdev)
static

Check link state.

Parameters
netdevNetwork device

Definition at line 232 of file cgem.c.

232 {
233 struct cgem_nic *cgem = netdev->priv;
234 int rc;
235
236 /* Check link state */
237 if ( ( rc = mii_check_link ( &cgem->mii, netdev ) ) != 0 ) {
238 DBGC ( cgem, "CGEM %s could not check link: %s\n",
239 cgem->name, strerror ( rc ) );
240 return rc;
241 }
242
243 return 0;
244}
static struct net_device * netdev
Definition gdbudp.c:53
int mii_check_link(struct mii_device *mii, struct net_device *netdev)
Update link status via MII.
Definition mii.c:127

References DBGC, cgem_nic::mii, mii_check_link(), cgem_nic::name, netdev, rc, and strerror().

Referenced by cgem_expired(), cgem_open(), and cgem_probe().

◆ cgem_expired()

void cgem_expired ( struct retry_timer * timer,
int over __unused )
static

Check link state periodically.

Parameters
retryLink state check timer
overFailure indicator

Definition at line 252 of file cgem.c.

252 {
253 struct cgem_nic *cgem = container_of ( timer, struct cgem_nic, timer );
254 struct net_device *netdev = cgem->netdev;
255
256 /* Restart timer */
258
259 /* Check link state */
261}
static int cgem_check_link(struct net_device *netdev)
Check link state.
Definition cgem.c:232
#define CGEM_LINK_INTERVAL
Link state check interval.
Definition cgem.h:79
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65
struct net_device * netdev
Network device.
Definition cgem.h:170
A network device.
Definition netdevice.h:353
A timer.
Definition timer.h:29

References __unused, cgem_check_link(), CGEM_LINK_INTERVAL, container_of, cgem_nic::netdev, netdev, and start_timer_fixed().

Referenced by cgem_probe().

◆ cgem_create_ring()

int cgem_create_ring ( struct cgem_nic * cgem,
struct cgem_ring * ring )
static

Create descriptor ring.

Parameters
cgemCadence GEM device
ringDescriptor ring
Return values
rcReturn status code

Definition at line 277 of file cgem.c.

277 {
278 struct cgem_descriptor *desc;
279 unsigned int i;
280
281 /* Allocate descriptor ring (on its own size) */
282 ring->desc = dma_alloc ( cgem->dma, &ring->map, ring->len, ring->len );
283 if ( ! ring->desc )
284 return -ENOMEM;
285
286 /* Initialise descriptor ring */
287 for ( i = 0 ; i < ring->count ; i++ ) {
288 desc = &ring->desc[i];
290 desc->flags = cpu_to_le32 ( CGEM_TX_FL_OWNED );
291 }
292 desc = &ring->desc[ ring->count - 1 ];
294 desc->flags |= cpu_to_le32 ( CGEM_TX_FL_WRAP );
295
296 /* Program ring address */
297 writel ( dma ( &ring->map, ring->desc ),
298 ( cgem->regs + ring->qbase ) );
299
300 DBGC ( cgem, "CGEM %s ring %02x is at [%08lx,%08lx)\n",
301 cgem->name, ring->qbase, virt_to_phys ( ring->desc ),
302 ( virt_to_phys ( ring->desc ) + ring->len ) );
303 return 0;
304}
#define CGEM_RX_ADDR_WRAP
End of descriptor ring.
Definition cgem.h:105
#define CGEM_TX_FL_OWNED
Transmit flags.
Definition cgem.h:96
#define CGEM_RX_ADDR_OWNED
Receive flags (in buffer address)
Definition cgem.h:104
#define CGEM_TX_FL_WRAP
End of descriptor ring.
Definition cgem.h:97
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define ENOMEM
Not enough space.
Definition errno.h:535
#define cpu_to_le32(value)
Definition byteswap.h:108
void * dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
A Cadence GEM descriptor.
Definition cgem.h:88
struct dma_device * dma
DMA device.
Definition cgem.h:168
struct cgem_descriptor * desc
Descriptors.
Definition cgem.h:131
uint16_t len
Length of descriptors.
Definition cgem.h:144
struct dma_mapping map
Descriptor ring DMA mapping.
Definition cgem.h:133
uint8_t qbase
Queue base address register.
Definition cgem.h:140
uint8_t count
Number of descriptors.
Definition cgem.h:142

References CGEM_RX_ADDR_OWNED, CGEM_RX_ADDR_WRAP, CGEM_TX_FL_OWNED, CGEM_TX_FL_WRAP, cgem_ring::count, cpu_to_le32, DBGC, cgem_ring::desc, desc, cgem_nic::dma, dma(), dma_alloc(), ENOMEM, cgem_ring::len, cgem_ring::map, cgem_nic::name, cgem_ring::qbase, cgem_nic::regs, and writel.

Referenced by cgem_open().

◆ cgem_destroy_ring()

void cgem_destroy_ring ( struct cgem_nic * cgem,
struct cgem_ring * ring )
static

Destroy descriptor ring.

Parameters
cgemCadence GEM device
ringDescriptor ring

Definition at line 312 of file cgem.c.

313 {
314
315 /* Clear ring address */
316 writel ( 0, ( cgem->regs + ring->qbase ) );
317
318 /* Free descriptor ring */
319 dma_free ( &ring->map, ring->desc, ring->len );
320 ring->desc = NULL;
321 ring->prod = 0;
322 ring->cons = 0;
323}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
unsigned int cons
Consumer index.
Definition cgem.h:137
unsigned int prod
Producer index.
Definition cgem.h:135

References cgem_ring::cons, cgem_ring::desc, dma_free(), cgem_ring::len, cgem_ring::map, NULL, cgem_ring::prod, cgem_ring::qbase, cgem_nic::regs, and writel.

Referenced by cgem_close(), and cgem_open().

◆ cgem_refill_rx()

void cgem_refill_rx ( struct cgem_nic * cgem)
static

Refill receive descriptor ring.

Parameters
cgemCadence GEM device

Definition at line 330 of file cgem.c.

330 {
331 struct cgem_descriptor *rx;
332 struct io_buffer *iobuf;
333 unsigned int rx_idx;
335
336 /* Refill ring */
337 while ( ( cgem->rx.prod - cgem->rx.cons ) != CGEM_NUM_RX_DESC ) {
338
339 /* Allocate I/O buffer */
340 iobuf = alloc_rx_iob ( CGEM_RX_LEN, cgem->dma );
341 if ( ! iobuf ) {
342 /* Wait for next refill */
343 break;
344 }
345
346 /* Get next receive descriptor */
347 rx_idx = ( cgem->rx.prod++ % CGEM_NUM_RX_DESC );
348 rx = &cgem->rx.desc[rx_idx];
349
350 /* Populate receive descriptor */
351 rx->flags = 0;
352 addr = 0;
353 if ( ( cgem->rx.prod % CGEM_NUM_RX_DESC ) == 0 )
355 rx->addr = cpu_to_le32 ( addr | iob_dma ( iobuf ) );
356
357 /* Record I/O buffer */
358 assert ( cgem->rx_iobuf[rx_idx] == NULL );
359 cgem->rx_iobuf[rx_idx] = iobuf;
360
361 DBGC2 ( cgem, "CGEM %s RX %d is [%08lx,%08lx)\n",
362 cgem->name, rx_idx, virt_to_phys ( iobuf->data ),
363 ( virt_to_phys ( iobuf->data ) + CGEM_RX_LEN ) );
364 }
365}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define CGEM_NUM_RX_DESC
Receive ring length.
Definition cgem.h:111
uint32_t addr
Buffer address.
Definition dwmac.h:9
#define DBGC2(...)
Definition compiler.h:522
struct io_buffer * alloc_rx_iob(size_t len, struct dma_device *dma)
Allocate and map I/O buffer for receive DMA.
Definition iobuf.c:188
static __always_inline physaddr_t iob_dma(struct io_buffer *iobuf)
Get I/O buffer DMA address.
Definition iobuf.h:268
struct cgem_ring rx
Receive ring.
Definition cgem.h:184
struct io_buffer * rx_iobuf[CGEM_NUM_RX_DESC]
Receive I/O buffers.
Definition cgem.h:186
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1

References addr, alloc_rx_iob(), assert, CGEM_NUM_RX_DESC, CGEM_RX_ADDR_WRAP, CGEM_RX_LEN, cgem_ring::cons, cpu_to_le32, io_buffer::data, DBGC2, cgem_ring::desc, cgem_nic::dma, iob_dma(), cgem_nic::name, NULL, cgem_ring::prod, cgem_nic::rx, rx, and cgem_nic::rx_iobuf.

Referenced by cgem_open(), and cgem_poll().

◆ cgem_open()

int cgem_open ( struct net_device * netdev)
static

Open network device.

Parameters
netdevNetwork device
Return values
rcReturn status code

Definition at line 373 of file cgem.c.

373 {
374 struct cgem_nic *cgem = netdev->priv;
375 union cgem_mac mac;
376 int rc;
377
378 /* Create transmit descriptor ring */
379 if ( ( rc = cgem_create_ring ( cgem, &cgem->tx ) ) != 0 )
380 goto err_create_tx;
381
382 /* Create receive descriptor ring */
383 if ( ( rc = cgem_create_ring ( cgem, &cgem->rx ) ) != 0 )
384 goto err_create_rx;
385
386 /* Set MAC address */
387 memcpy ( mac.raw, netdev->ll_addr, ETH_ALEN );
388 writel ( mac.reg.low, ( cgem->regs + CGEM_LADDRL ) );
389 writel ( mac.reg.high, ( cgem->regs + CGEM_LADDRH ) );
390
391 /* Enable transmit and receive */
392 writel ( CGEM_NWCTRL_NORMAL, ( cgem->regs + CGEM_NWCTRL ) );
393
394 /* Refill receive descriptor ring */
395 cgem_refill_rx ( cgem );
396
397 /* Update link state */
399
400 /* Start link state timer */
402
403 return 0;
404
405 cgem_destroy_ring ( cgem, &cgem->rx );
406 err_create_rx:
407 cgem_destroy_ring ( cgem, &cgem->tx );
408 err_create_tx:
409 return rc;
410}
static void cgem_destroy_ring(struct cgem_nic *cgem, struct cgem_ring *ring)
Destroy descriptor ring.
Definition cgem.c:312
static void cgem_refill_rx(struct cgem_nic *cgem)
Refill receive descriptor ring.
Definition cgem.c:330
static int cgem_create_ring(struct cgem_nic *cgem, struct cgem_ring *ring)
Create descriptor ring.
Definition cgem.c:277
#define CGEM_LADDRL
Local MAC address (low half) register.
Definition cgem.h:82
#define CGEM_NWCTRL_NORMAL
Normal value for network control register while up and running.
Definition cgem.h:32
#define CGEM_LADDRH
Local MAC address (high half) register.
Definition cgem.h:85
uint8_t mac[ETH_ALEN]
MAC address.
Definition ena.h:13
#define ETH_ALEN
Definition if_ether.h:9
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct cgem_ring tx
Transmit ring.
Definition cgem.h:182
struct retry_timer timer
Link state timer.
Definition cgem.h:179
A Cadence GEM MAC address.
Definition cgem.h:120

References cgem_check_link(), cgem_create_ring(), cgem_destroy_ring(), CGEM_LADDRH, CGEM_LADDRL, CGEM_LINK_INTERVAL, CGEM_NWCTRL, CGEM_NWCTRL_NORMAL, cgem_refill_rx(), ETH_ALEN, mac, memcpy(), netdev, rc, cgem_nic::regs, cgem_nic::rx, start_timer_fixed(), cgem_nic::timer, cgem_nic::tx, and writel.

◆ cgem_close()

void cgem_close ( struct net_device * netdev)
static

Close network device.

Parameters
netdevNetwork device

Definition at line 417 of file cgem.c.

417 {
418 struct cgem_nic *cgem = netdev->priv;
419 unsigned int i;
420
421 /* Stop link state timer */
422 stop_timer ( &cgem->timer );
423
424 /* Reset NIC */
425 cgem_reset ( cgem );
426
427 /* Discard unused receive buffers */
428 for ( i = 0 ; i < CGEM_NUM_RX_DESC ; i++ ) {
429 if ( cgem->rx_iobuf[i] )
430 free_rx_iob ( cgem->rx_iobuf[i] );
431 cgem->rx_iobuf[i] = NULL;
432 }
433
434 /* Destroy receive descriptor ring */
435 cgem_destroy_ring ( cgem, &cgem->rx );
436
437 /* Destroy transmit descriptor ring */
438 cgem_destroy_ring ( cgem, &cgem->tx );
439}
static int cgem_reset(struct cgem_nic *cgem)
Reset hardware.
Definition cgem.c:64
void free_rx_iob(struct io_buffer *iobuf)
Unmap and free I/O buffer for receive DMA.
Definition iobuf.c:215
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118

References cgem_destroy_ring(), CGEM_NUM_RX_DESC, cgem_reset(), free_rx_iob(), netdev, NULL, cgem_nic::rx, cgem_nic::rx_iobuf, stop_timer(), cgem_nic::timer, and cgem_nic::tx.

◆ cgem_transmit()

int cgem_transmit ( struct net_device * netdev,
struct io_buffer * iobuf )
static

Transmit packet.

Parameters
netdevNetwork device
iobufI/O buffer
Return values
rcReturn status code

Definition at line 448 of file cgem.c.

449 {
450 struct cgem_nic *cgem = netdev->priv;
451 struct cgem_descriptor *tx;
452 unsigned int tx_idx;
454 int rc;
455
456 /* Get next transmit descriptor */
457 if ( ( cgem->tx.prod - cgem->tx.cons ) >= CGEM_NUM_TX_DESC ) {
458 DBGC ( cgem, "CGEM %s out of transmit descriptors\n",
459 cgem->name );
460 return -ENOBUFS;
461 }
462 tx_idx = ( cgem->tx.prod % CGEM_NUM_TX_DESC );
463 tx = &cgem->tx.desc[tx_idx];
464
465 /* Pad to minimum length */
466 iob_pad ( iobuf, ETH_ZLEN );
467
468 /* Map I/O buffer */
469 if ( ( rc = iob_map_tx ( iobuf, cgem->dma ) ) != 0 )
470 return rc;
471
472 /* Update producer index */
473 cgem->tx.prod++;
474
475 /* Populate transmit descriptor */
477 if ( ( cgem->tx.prod % CGEM_NUM_TX_DESC ) == 0 )
479 tx->addr = cpu_to_le32 ( iob_dma ( iobuf ) );
480 wmb();
481 tx->flags = cpu_to_le32 ( flags | iob_len ( iobuf ) );
482 wmb();
483
484 /* Initiate transmission */
486 ( cgem->regs + CGEM_NWCTRL ) );
487
488 DBGC2 ( cgem, "CGEM %s TX %d is [%08lx,%08lx)\n",
489 cgem->name, tx_idx, virt_to_phys ( iobuf->data ),
490 ( virt_to_phys ( iobuf->data ) + iob_len ( iobuf ) ) );
491 return 0;
492}
#define CGEM_NWCTRL_STARTTX
Start transmission.
Definition cgem.h:25
#define CGEM_NUM_TX_DESC
Transmit ring length.
Definition cgem.h:101
#define CGEM_TX_FL_LAST
Last buffer in frame.
Definition cgem.h:98
uint8_t flags
Flags.
Definition ena.h:7
#define ENOBUFS
No buffer space available.
Definition errno.h:499
#define ETH_ZLEN
Definition if_ether.h:11
#define wmb()
Definition io.h:546
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition iobpad.c:50
static __always_inline int iob_map_tx(struct io_buffer *iobuf, struct dma_device *dma)
Map I/O buffer for transmit DMA.
Definition iobuf.h:244
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition wpa.h:4

References CGEM_NUM_TX_DESC, CGEM_NWCTRL, CGEM_NWCTRL_NORMAL, CGEM_NWCTRL_STARTTX, CGEM_TX_FL_LAST, CGEM_TX_FL_WRAP, cgem_ring::cons, cpu_to_le32, io_buffer::data, DBGC, DBGC2, cgem_ring::desc, cgem_nic::dma, ENOBUFS, ETH_ZLEN, flags, iob_dma(), iob_len(), iob_map_tx(), iob_pad(), cgem_nic::name, netdev, cgem_ring::prod, rc, cgem_nic::regs, cgem_nic::tx, tx, wmb, and writel.

◆ cgem_poll_tx()

void cgem_poll_tx ( struct net_device * netdev)
static

Poll for completed packets.

@V netdev Network device

Definition at line 499 of file cgem.c.

499 {
500 struct cgem_nic *cgem = netdev->priv;
501 struct cgem_descriptor *tx;
502 unsigned int tx_idx;
503
504 /* Check for completed packets */
505 while ( cgem->tx.cons != cgem->tx.prod ) {
506
507 /* Get next transmit descriptor */
508 tx_idx = ( cgem->tx.cons % CGEM_NUM_TX_DESC );
509 tx = &cgem->tx.desc[tx_idx];
510
511 /* Stop if descriptor is still owned by hardware */
512 if ( ! ( tx->flags & cpu_to_le32 ( CGEM_TX_FL_OWNED ) ) )
513 return;
514 DBGC2 ( cgem, "CGEM %s TX %d complete\n",
515 cgem->name, tx_idx );
516
517 /* Complete transmit descriptor */
519 cgem->tx.cons++;
520 }
521}
static void netdev_tx_complete_next(struct net_device *netdev)
Complete network transmission.
Definition netdevice.h:779

References CGEM_NUM_TX_DESC, CGEM_TX_FL_OWNED, cgem_ring::cons, cpu_to_le32, DBGC2, cgem_ring::desc, cgem_nic::name, netdev, netdev_tx_complete_next(), cgem_ring::prod, cgem_nic::tx, and tx.

Referenced by cgem_poll().

◆ cgem_poll_rx()

void cgem_poll_rx ( struct net_device * netdev)
static

Poll for received packets.

Parameters
netdevNetwork device

Definition at line 528 of file cgem.c.

528 {
529 struct cgem_nic *cgem = netdev->priv;
530 struct cgem_descriptor *rx;
531 struct io_buffer *iobuf;
532 unsigned int rx_idx;
534 size_t len;
535
536 /* Check for received packets */
537 while ( cgem->rx.cons != cgem->rx.prod ) {
538
539 /* Get next receive descriptor */
540 rx_idx = ( cgem->rx.cons % CGEM_NUM_RX_DESC );
541 rx = &cgem->rx.desc[rx_idx];
542
543 /* Stop if descriptor is still in use */
544 if ( ! ( rx->addr & cpu_to_le32 ( CGEM_RX_ADDR_OWNED ) ) )
545 return;
546
547 /* Populate I/O buffer */
548 iobuf = cgem->rx_iobuf[rx_idx];
549 cgem->rx_iobuf[rx_idx] = NULL;
550 flags = le32_to_cpu ( rx->flags );
552 iob_put ( iobuf, len );
553 DBGC2 ( cgem, "CGEM %s RX %d complete (length %zd)\n",
554 cgem->name, rx_idx, len );
555
556 /* Hand off to network stack */
557 netdev_rx ( netdev, iobuf );
558 cgem->rx.cons++;
559 }
560}
#define CGEM_RX_FL_LEN(x)
Receive flags.
Definition cgem.h:108
ring len
Length.
Definition dwmac.h:226
#define le32_to_cpu(value)
Definition byteswap.h:114
#define iob_put(iobuf, len)
Definition iobuf.h:125
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition netdevice.c:549

References CGEM_NUM_RX_DESC, CGEM_RX_ADDR_OWNED, CGEM_RX_FL_LEN, cgem_ring::cons, cpu_to_le32, DBGC2, cgem_ring::desc, flags, iob_put, le32_to_cpu, len, cgem_nic::name, netdev, netdev_rx(), NULL, cgem_ring::prod, cgem_nic::rx, rx, and cgem_nic::rx_iobuf.

Referenced by cgem_poll().

◆ cgem_poll()

void cgem_poll ( struct net_device * netdev)
static

Poll for completed and received packets.

Parameters
netdevNetwork device

Definition at line 567 of file cgem.c.

567 {
568 struct cgem_nic *cgem = netdev->priv;
569
570 /* Poll for TX competions */
572
573 /* Poll for RX completions */
575
576 /* Refill RX ring */
577 cgem_refill_rx ( cgem );
578}
static void cgem_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition cgem.c:528
static void cgem_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition cgem.c:499

References cgem_poll_rx(), cgem_poll_tx(), cgem_refill_rx(), and netdev.

◆ cgem_probe()

int cgem_probe ( struct dt_device * dt,
unsigned int offset )
static

Probe devicetree device.

Parameters
dtDevicetree device
offsetStarting node offset
Return values
rcReturn status code

Definition at line 602 of file cgem.c.

602 {
603 struct net_device *netdev;
604 struct cgem_nic *cgem;
605 union cgem_mac mac;
606 int rc;
607
608 /* Allocate and initialise net device */
609 netdev = alloc_etherdev ( sizeof ( *cgem ) );
610 if ( ! netdev ) {
611 rc = -ENOMEM;
612 goto err_alloc;
613 }
615 cgem = netdev->priv;
616 dt_set_drvdata ( dt, netdev );
617 netdev->dev = &dt->dev;
618 memset ( cgem, 0, sizeof ( *cgem ) );
619 cgem->dma = &dt->dma;
620 cgem->netdev = netdev;
621 cgem->name = netdev->dev->name;
623 mii_init ( &cgem->mii, &cgem->mdio, 0 );
624 timer_init ( &cgem->timer, cgem_expired, &netdev->refcnt );
627
628 /* Map registers */
630 if ( ! cgem->regs ) {
631 rc = -ENODEV;
632 goto err_ioremap;
633 }
634
635 /* Reset the NIC */
636 if ( ( rc = cgem_reset ( cgem ) ) != 0 )
637 goto err_reset;
638
639 /* Initialise the PHY */
640 if ( ( rc = cgem_init_phy ( cgem ) ) != 0 )
641 goto err_init_phy;
642
643 /* Fetch devicetree MAC address */
644 if ( ( rc = fdt_mac ( &sysfdt, offset, netdev ) ) != 0 ) {
645 DBGC ( cgem, "CGEM %s could not fetch MAC: %s\n",
646 cgem->name, strerror ( rc ) );
647 goto err_mac;
648 }
649
650 /* Fetch current MAC address, if set */
651 mac.reg.low = readl ( cgem->regs + CGEM_LADDRL );
652 mac.reg.high = readl ( cgem->regs + CGEM_LADDRH );
653 memcpy ( netdev->ll_addr, mac.raw, ETH_ALEN );
654
655 /* Register network device */
656 if ( ( rc = register_netdev ( netdev ) ) != 0 )
657 goto err_register_netdev;
658
659 /* Set initial link state */
661
662 return 0;
663
665 err_register_netdev:
666 err_mac:
667 err_init_phy:
668 cgem_reset ( cgem );
669 err_reset:
670 iounmap ( cgem->regs );
671 err_ioremap:
673 netdev_put ( netdev );
674 err_alloc:
675 return rc;
676}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
static void cgem_expired(struct retry_timer *timer, int over __unused)
Check link state periodically.
Definition cgem.c:252
static struct net_device_operations cgem_operations
Cadence GEM network device operations.
Definition cgem.c:581
static struct mii_operations cgem_mii_operations
MII operations.
Definition cgem.c:189
static int cgem_init_phy(struct cgem_nic *cgem)
Initialise PHY.
Definition cgem.c:207
#define CGEM_REG_LEN
I/O region length.
Definition cgem.h:21
#define CGEM_REG_IDX
I/O region index.
Definition cgem.h:18
static void cgem_init_ring(struct cgem_ring *ring, unsigned int count, unsigned int qbase)
Initialise descriptor ring.
Definition cgem.h:155
void * dt_ioremap(struct dt_device *dt, unsigned int offset, unsigned int index, size_t len)
Map devicetree range.
Definition devtree.c:52
static void dt_set_drvdata(struct dt_device *dt, void *priv)
Set devicetree driver-private data.
Definition devtree.h:72
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition ethernet.c:265
int fdt_mac(struct fdt *fdt, unsigned int offset, struct net_device *netdev)
Get MAC address from property.
Definition fdt.c:867
struct fdt sysfdt
The system flattened device tree (if present)
Definition fdt.c:45
#define ENODEV
No such device.
Definition errno.h:510
void iounmap(volatile const void *io_addr)
Unmap I/O address.
void * memset(void *dest, int character, size_t len) __nonnull
static void mdio_init(struct mii_interface *mdio, struct mii_operations *op)
Initialise MII interface.
Definition mii.h:64
static void mii_init(struct mii_device *mii, struct mii_interface *mdio, unsigned int address)
Initialise MII device.
Definition mii.h:76
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition netdevice.c:942
int register_netdev(struct net_device *netdev)
Register network device.
Definition netdevice.c:760
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition netdevice.h:519
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition netdevice.h:532
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition netdevice.h:576
struct dma_device dma
DMA device.
Definition devtree.h:23
struct device dev
Generic device.
Definition devtree.h:21

References alloc_etherdev(), cgem_check_link(), cgem_expired(), cgem_init_phy(), cgem_init_ring(), CGEM_LADDRH, CGEM_LADDRL, cgem_mii_operations, CGEM_NUM_RX_DESC, CGEM_NUM_TX_DESC, cgem_operations, CGEM_REG_IDX, CGEM_REG_LEN, cgem_reset(), CGEM_RXQBASE, CGEM_TXQBASE, DBGC, dt_device::dev, cgem_nic::dma, dt_device::dma, dt_ioremap(), dt_set_drvdata(), ENODEV, ENOMEM, ETH_ALEN, fdt_mac(), iounmap(), mac, cgem_nic::mdio, mdio_init(), memcpy(), memset(), cgem_nic::mii, mii_init(), cgem_nic::name, cgem_nic::netdev, netdev, netdev_init(), netdev_nullify(), netdev_put(), offset, rc, readl, register_netdev(), cgem_nic::regs, cgem_nic::rx, strerror(), sysfdt, cgem_nic::timer, cgem_nic::tx, and unregister_netdev().

◆ cgem_remove()

void cgem_remove ( struct dt_device * dt)
static

Remove devicetree device.

Parameters
dtDevicetree device

Definition at line 683 of file cgem.c.

683 {
684 struct net_device *netdev = dt_get_drvdata ( dt );
685 struct cgem_nic *cgem = netdev->priv;
686
687 /* Unregister network device */
689
690 /* Reset card */
691 cgem_reset ( cgem );
692
693 /* Free network device */
694 iounmap ( cgem->regs );
696 netdev_put ( netdev );
697}
static void * dt_get_drvdata(struct dt_device *dt)
Get devicetree driver-private data.
Definition devtree.h:82

References cgem_reset(), dt_get_drvdata(), iounmap(), netdev, netdev_nullify(), netdev_put(), cgem_nic::regs, and unregister_netdev().

Variable Documentation

◆ cgem_mii_operations

struct mii_operations cgem_mii_operations
static
Initial value:
= {
.read = cgem_mii_read,
.write = cgem_mii_write,
}
static int cgem_mii_read(struct mii_interface *mdio, unsigned int phy, unsigned int reg)
Read from MII register.
Definition cgem.c:138
static int cgem_mii_write(struct mii_interface *mdio, unsigned int phy, unsigned int reg, unsigned int data)
Write to MII register.
Definition cgem.c:170

MII operations.

Definition at line 189 of file cgem.c.

189 {
190 .read = cgem_mii_read,
191 .write = cgem_mii_write,
192};

Referenced by cgem_probe().

◆ cgem_operations

struct net_device_operations cgem_operations
static
Initial value:
= {
.open = cgem_open,
.close = cgem_close,
.transmit = cgem_transmit,
.poll = cgem_poll,
}
static int cgem_open(struct net_device *netdev)
Open network device.
Definition cgem.c:373
static void cgem_close(struct net_device *netdev)
Close network device.
Definition cgem.c:417
static void cgem_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition cgem.c:567
static int cgem_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition cgem.c:448

Cadence GEM network device operations.

Definition at line 581 of file cgem.c.

581 {
582 .open = cgem_open,
583 .close = cgem_close,
584 .transmit = cgem_transmit,
585 .poll = cgem_poll,
586};

Referenced by cgem_probe().

◆ cgem_ids

const char* cgem_ids[]
static
Initial value:
= {
DT_ROM ( "sifive,fu540-c000-gem", "SiFive GEM" ),
}
#define DT_ROM(_name, _desc)
Definition devtree.h:34

Cadence GEM compatible model identifiers.

Definition at line 700 of file cgem.c.

700 {
701 DT_ROM ( "sifive,fu540-c000-gem", "SiFive GEM" ),
702};

◆ __dt_driver

struct dt_driver cgem_driver __dt_driver
Initial value:
= {
.name = "cgem",
.ids = cgem_ids,
.id_count = ( sizeof ( cgem_ids ) / sizeof ( cgem_ids[0] ) ),
.probe = cgem_probe,
}
static const char * cgem_ids[]
Cadence GEM compatible model identifiers.
Definition cgem.c:700
static void cgem_remove(struct dt_device *dt)
Remove devicetree device.
Definition cgem.c:683
static int cgem_probe(struct dt_device *dt, unsigned int offset)
Probe devicetree device.
Definition cgem.c:602
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40

Cadence GEM devicetree driver.

Definition at line 705 of file cgem.c.

705 {
706 .name = "cgem",
707 .ids = cgem_ids,
708 .id_count = ( sizeof ( cgem_ids ) / sizeof ( cgem_ids[0] ) ),
709 .probe = cgem_probe,
711};