iPXE
cgem.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdint.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <byteswap.h>
31 #include <ipxe/netdevice.h>
32 #include <ipxe/ethernet.h>
33 #include <ipxe/if_ether.h>
34 #include <ipxe/iobuf.h>
35 #include <ipxe/timer.h>
36 #include <ipxe/devtree.h>
37 #include <ipxe/fdt.h>
38 #include "cgem.h"
39 
40 /** @file
41  *
42  * Cadence Gigabit Ethernet MAC (GEM) network driver
43  *
44  * Based primarily on the Zynq 7000 SoC Technical Reference Manual,
45  * available at the time of writing from:
46  *
47  * https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM
48  *
49  */
50 
51 /******************************************************************************
52  *
53  * Device reset
54  *
55  ******************************************************************************
56  */
57 
58 /**
59  * Reset hardware
60  *
61  * @v cgem Cadence GEM device
62  * @ret rc Return status code
63  */
64 static int cgem_reset ( struct cgem_nic *cgem ) {
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 */
78  writel ( CGEM_NWCTRL_STATCLR, ( cgem->regs + CGEM_NWCTRL ) );
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 }
96 
97 /******************************************************************************
98  *
99  * PHY access
100  *
101  ******************************************************************************
102  */
103 
104 /**
105  * Wait for MII operation to complete
106  *
107  * @v cgem Cadence GEM device
108  * @ret rc Return status code
109  */
110 static int cgem_mii_wait ( struct cgem_nic *cgem ) {
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 }
129 
130 /**
131  * Read from MII register
132  *
133  * @v mdio MII interface
134  * @v phy PHY address
135  * @v reg Register address
136  * @ret data Data read, or negative error
137  */
138 static int cgem_mii_read ( struct mii_interface *mdio, unsigned int phy,
139  unsigned int reg ) {
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 }
160 
161 /**
162  * Write to MII register
163  *
164  * @v mdio MII interface
165  * @v phy PHY address
166  * @v reg Register address
167  * @v data Data to write
168  * @ret rc Return status code
169  */
170 static int cgem_mii_write ( struct mii_interface *mdio, unsigned int phy,
171  unsigned int reg, unsigned int data ) {
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 }
187 
188 /** MII operations */
190  .read = cgem_mii_read,
191  .write = cgem_mii_write,
192 };
193 
194 /******************************************************************************
195  *
196  * Link state
197  *
198  ******************************************************************************
199  */
200 
201 /**
202  * Initialise PHY
203  *
204  * @v cgem Cadence GEM device
205  * @ret rc Return status code
206  */
207 static int cgem_init_phy ( struct cgem_nic *cgem ) {
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 }
226 
227 /**
228  * Check link state
229  *
230  * @v netdev Network device
231  */
232 static int cgem_check_link ( struct net_device *netdev ) {
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 }
245 
246 /**
247  * Check link state periodically
248  *
249  * @v retry Link state check timer
250  * @v over Failure indicator
251  */
252 static void cgem_expired ( struct retry_timer *timer, int over __unused ) {
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 }
262 
263 /******************************************************************************
264  *
265  * Network device interface
266  *
267  ******************************************************************************
268  */
269 
270 /**
271  * Create descriptor ring
272  *
273  * @v cgem Cadence GEM device
274  * @v ring Descriptor ring
275  * @ret rc Return status code
276  */
277 static int cgem_create_ring ( struct cgem_nic *cgem, struct cgem_ring *ring ) {
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];
289  desc->addr = cpu_to_le32 ( CGEM_RX_ADDR_OWNED );
290  desc->flags = cpu_to_le32 ( CGEM_TX_FL_OWNED );
291  }
292  desc = &ring->desc[ ring->count - 1 ];
293  desc->addr |= cpu_to_le32 ( CGEM_RX_ADDR_WRAP );
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 }
305 
306 /**
307  * Destroy descriptor ring
308  *
309  * @v cgem Cadence GEM device
310  * @v ring Descriptor ring
311  */
312 static void cgem_destroy_ring ( struct cgem_nic *cgem,
313  struct cgem_ring *ring ) {
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 }
324 
325 /**
326  * Refill receive descriptor ring
327  *
328  * @v cgem Cadence GEM device
329  */
330 static void cgem_refill_rx ( struct cgem_nic *cgem ) {
331  struct cgem_descriptor *rx;
332  struct io_buffer *iobuf;
333  unsigned int rx_idx;
334  uint32_t addr;
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 }
366 
367 /**
368  * Open network device
369  *
370  * @v netdev Network device
371  * @ret rc Return status code
372  */
373 static int cgem_open ( struct net_device *netdev ) {
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 }
411 
412 /**
413  * Close network device
414  *
415  * @v netdev Network device
416  */
417 static void cgem_close ( struct net_device *netdev ) {
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 }
440 
441 /**
442  * Transmit packet
443  *
444  * @v netdev Network device
445  * @v iobuf I/O buffer
446  * @ret rc Return status code
447  */
448 static int cgem_transmit ( struct net_device *netdev,
449  struct io_buffer *iobuf ) {
450  struct cgem_nic *cgem = netdev->priv;
451  struct cgem_descriptor *tx;
452  unsigned int tx_idx;
453  uint32_t flags;
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 }
493 
494 /**
495  * Poll for completed packets
496  *
497  * @V netdev Network device
498  */
499 static void cgem_poll_tx ( struct net_device *netdev ) {
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 }
522 
523 /**
524  * Poll for received packets
525  *
526  * @v netdev Network device
527  */
528 static void cgem_poll_rx ( struct net_device *netdev ) {
529  struct cgem_nic *cgem = netdev->priv;
530  struct cgem_descriptor *rx;
531  struct io_buffer *iobuf;
532  unsigned int rx_idx;
533  uint32_t flags;
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 );
551  len = CGEM_RX_FL_LEN ( 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 }
561 
562 /**
563  * Poll for completed and received packets
564  *
565  * @v netdev Network device
566  */
567 static void cgem_poll ( struct net_device *netdev ) {
568  struct cgem_nic *cgem = netdev->priv;
569 
570  /* Poll for TX competions */
571  cgem_poll_tx ( netdev );
572 
573  /* Poll for RX completions */
574  cgem_poll_rx ( netdev );
575 
576  /* Refill RX ring */
577  cgem_refill_rx ( cgem );
578 }
579 
580 /** Cadence GEM network device operations */
582  .open = cgem_open,
583  .close = cgem_close,
584  .transmit = cgem_transmit,
585  .poll = cgem_poll,
586 };
587 
588 /******************************************************************************
589  *
590  * Devicetree interface
591  *
592  ******************************************************************************
593  */
594 
595 /**
596  * Probe devicetree device
597  *
598  * @v dt Devicetree device
599  * @v offset Starting node offset
600  * @ret rc Return status code
601  */
602 static int cgem_probe ( struct dt_device *dt, unsigned int offset ) {
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;
622  mdio_init ( &cgem->mdio, &cgem_mii_operations );
623  mii_init ( &cgem->mii, &cgem->mdio, 0 );
624  timer_init ( &cgem->timer, cgem_expired, &netdev->refcnt );
627 
628  /* Map registers */
629  cgem->regs = dt_ioremap ( dt, offset, CGEM_REG_IDX, CGEM_REG_LEN );
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 }
677 
678 /**
679  * Remove devicetree device
680  *
681  * @v dt Devicetree device
682  */
683 static void cgem_remove ( struct dt_device *dt ) {
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 }
698 
699 /** Cadence GEM compatible model identifiers */
700 static const char * cgem_ids[] = {
701  "sifive,fu540-c000-gem",
702 };
703 
704 /** Cadence GEM devicetree driver */
705 struct dt_driver cgem_driver __dt_driver = {
706  .name = "cgem",
707  .ids = cgem_ids,
708  .id_count = ( sizeof ( cgem_ids ) / sizeof ( cgem_ids[0] ) ),
709  .probe = cgem_probe,
710  .remove = cgem_remove,
711 };
#define CGEM_NUM_RX_DESC
Receive ring length.
Definition: cgem.h:111
static void cgem_poll_tx(struct net_device *netdev)
Poll for completed packets.
Definition: cgem.c:499
struct io_buffer * rx_iobuf[CGEM_NUM_RX_DESC]
Receive I/O buffers.
Definition: cgem.h:186
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define CGEM_IDR_ALL
Disable all interrupts.
Definition: cgem.h:63
A Cadence GEM MAC address.
Definition: cgem.h:120
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int cgem_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: cgem.c:448
wmb()
#define iob_put(iobuf, len)
Definition: iobuf.h:124
static unsigned int unsigned int reg
Definition: myson.h:162
#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
static void cgem_remove(struct dt_device *dt)
Remove devicetree device.
Definition: cgem.c:683
#define le32_to_cpu(value)
Definition: byteswap.h:113
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
struct cgem_descriptor * desc
Descriptors.
Definition: cgem.h:131
#define CGEM_RX_FL_LEN(x)
Receive flags.
Definition: cgem.h:108
static int cgem_probe(struct dt_device *dt, unsigned int offset)
Probe devicetree device.
Definition: cgem.c:602
#define CGEM_MII_MAX_WAIT_US
Maximum time to wait for PHY access, in microseconds.
Definition: cgem.h:76
Error codes.
static void cgem_poll_rx(struct net_device *netdev)
Poll for received packets.
Definition: cgem.c:528
static void netdev_tx_complete_next(struct net_device *netdev)
Complete network transmission.
Definition: netdevice.h:778
A devicetree driver.
Definition: devtree.h:31
I/O buffers.
int(* read)(struct mii_interface *mdio, unsigned int phy, unsigned int reg)
Read from MII register.
Definition: mii.h:27
static struct mii_operations cgem_mii_operations
MII operations.
Definition: cgem.c:189
uint16_t len
Length of descriptors.
Definition: cgem.h:144
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
static int cgem_create_ring(struct cgem_nic *cgem, struct cgem_ring *ring)
Create descriptor ring.
Definition: cgem.c:277
#define CGEM_TX_FL_OWNED
Transmit flags.
Definition: cgem.h:96
static struct net_device_operations cgem_operations
Cadence GEM network device operations.
Definition: cgem.c:581
Cadence Gigabit Ethernet MAC (GEM) network driver.
#define DBGC(...)
Definition: compiler.h:505
struct mii_device mii
PHY device.
Definition: cgem.h:177
char name[40]
Name.
Definition: device.h:78
A retry timer.
Definition: retry.h:21
#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
static void cgem_refill_rx(struct cgem_nic *cgem)
Refill receive descriptor ring.
Definition: cgem.c:330
iPXE timers
#define CGEM_PHYMNTNC
PHY maintenance register.
Definition: cgem.h:66
static void cgem_expired(struct retry_timer *timer, int over __unused)
Check link state periodically.
Definition: cgem.c:252
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
struct net_device * netdev
Network device.
Definition: cgem.h:170
int fdt_mac(struct fdt *fdt, unsigned int offset, struct net_device *netdev)
Get MAC address from property.
Definition: fdt.c:866
unsigned int cons
Consumer index.
Definition: cgem.h:137
const char * name
Device name (for debugging)
Definition: cgem.h:172
struct cgem_ring tx
Transmit ring.
Definition: cgem.h:182
#define CGEM_NWSR_MII_IDLE
MII interface is idle.
Definition: cgem.h:40
static void mdio_init(struct mii_interface *mdio, struct mii_operations *op)
Initialise MII interface.
Definition: mii.h:63
#define CGEM_NWCTRL_MDEN
MII interface enable.
Definition: cgem.h:27
struct mii_interface mdio
PHY interface.
Definition: cgem.h:175
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
static void cgem_close(struct net_device *netdev)
Close network device.
Definition: cgem.c:417
A timer.
Definition: timer.h:28
struct device dev
Generic device.
Definition: devtree.h:21
static void cgem_init_ring(struct cgem_ring *ring, unsigned int count, unsigned int qbase)
Initialise descriptor ring.
Definition: cgem.h:155
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:243
struct dt_driver cgem_driver __dt_driver
Cadence GEM devicetree driver.
Definition: cgem.c:705
#define CGEM_DMACR
DMA configuration register.
Definition: cgem.h:43
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:518
#define CGEM_LADDRL
Local MAC address (low half) register.
Definition: cgem.h:82
struct ena_llq_option desc
Descriptor counts.
Definition: ena.h:20
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
int(* probe)(struct dt_device *dt, unsigned int offset)
Probe device.
Definition: devtree.h:45
#define CGEM_NWCTRL_NORMAL
Normal value for network control register while up and running.
Definition: cgem.h:32
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int cgem_mii_read(struct mii_interface *mdio, unsigned int phy, unsigned int reg)
Read from MII register.
Definition: cgem.c:138
#define CGEM_NWCTRL_STATCLR
Clear statistics.
Definition: cgem.h:26
uint8_t qbase
Queue base address register.
Definition: cgem.h:140
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int cgem_reset(struct cgem_nic *cgem)
Reset hardware.
Definition: cgem.c:64
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:575
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Ethernet protocol.
void * regs
Registers.
Definition: cgem.h:166
Devicetree bus.
#define CGEM_PHYMNTNC_REG(x)
Register address.
Definition: cgem.h:71
void * priv
Driver private data.
Definition: netdevice.h:431
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
#define CGEM_DMACR_BLENGTH_MAX
Max DMA burst length.
Definition: cgem.h:52
ring len
Length.
Definition: dwmac.h:231
void writel(uint32_t data, volatile uint32_t *io_addr)
Write 32-bit dword to memory-mapped device.
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
static struct net_device * netdev
Definition: gdbudp.c:52
static __always_inline physaddr_t iob_dma(struct io_buffer *iobuf)
Get I/O buffer DMA address.
Definition: iobuf.h:267
#define CGEM_PHYMNTNC_FIXED
Fixed value to write.
Definition: cgem.h:72
A devicetree device.
Definition: devtree.h:17
static void cgem_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition: cgem.c:567
struct dma_device * dma
DMA device.
Definition: cgem.h:168
#define CGEM_NWCTRL_STARTTX
Start transmission.
Definition: cgem.h:25
static int cgem_open(struct net_device *netdev)
Open network device.
Definition: cgem.c:373
#define CGEM_PHYMNTNC_OP_READ
Read from PHY register.
Definition: cgem.h:69
#define CGEM_TXQBASE
TX queue base address register.
Definition: cgem.h:59
#define CGEM_NWCTRL
Network control register.
Definition: cgem.h:24
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
#define CGEM_RXQBASE
RX queue base address register.
Definition: cgem.h:56
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define CGEM_PHYMNTNC_DATA_MASK
Data mask.
Definition: cgem.h:73
A Cadence GEM descriptor ring.
Definition: cgem.h:129
#define CGEM_PHYMNTNC_CLAUSE22
Clause 22 operation.
Definition: cgem.h:67
uint8_t flags
Flags.
Definition: ena.h:18
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct refcnt refcnt
Reference counter.
Definition: netdevice.h:354
static void dt_set_drvdata(struct dt_device *dt, void *priv)
Set devicetree driver-private data.
Definition: devtree.h:66
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:187
static int cgem_mii_wait(struct cgem_nic *cgem)
Wait for MII operation to complete.
Definition: cgem.c:110
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
uint32_t addr
Buffer address.
Definition: dwmac.h:20
struct retry_timer timer
Link state timer.
Definition: cgem.h:179
#define CGEM_REG_IDX
I/O region index.
Definition: cgem.h:18
A network device.
Definition: netdevice.h:352
#define CGEM_TX_FL_WRAP
End of descriptor ring.
Definition: cgem.h:97
#define ENODEV
No such device.
Definition: errno.h:509
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:531
int mii_reset(struct mii_device *mii)
Reset MII device.
Definition: mii.c:74
#define ETH_ALEN
Definition: if_ether.h:8
#define ETH_ZLEN
Definition: if_ether.h:10
unsigned int uint32_t
Definition: stdint.h:12
void * dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
int mii_check_link(struct mii_device *mii, struct net_device *netdev)
Update link status via MII.
Definition: mii.c:126
unsigned int prod
Producer index.
Definition: cgem.h:135
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39
#define CGEM_RX_ADDR_OWNED
Receive flags (in buffer address)
Definition: cgem.h:104
#define CGEM_NWSR
Network status register.
Definition: cgem.h:39
Network device operations.
Definition: netdevice.h:213
void netdev_rx(struct net_device *netdev, struct io_buffer *iobuf)
Add packet to receive queue.
Definition: netdevice.c:548
struct device * dev
Underlying hardware device.
Definition: netdevice.h:364
static void mii_init(struct mii_device *mii, struct mii_interface *mdio, unsigned int address)
Initialise MII device.
Definition: mii.h:75
#define CGEM_DMACR_TXSIZE_MAX
Max TX memory size.
Definition: cgem.h:46
A Cadence GEM network card.
Definition: cgem.h:164
Network device management.
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
MII interface operations.
Definition: mii.h:18
int mii_find(struct mii_device *mii)
Find PHY address.
Definition: mii.c:157
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
const char * name
Driver name.
Definition: devtree.h:33
static const char * cgem_ids[]
Cadence GEM compatible model identifiers.
Definition: cgem.c:700
void free_rx_iob(struct io_buffer *iobuf)
Unmap and free I/O buffer for receive DMA.
Definition: iobuf.c:214
#define CGEM_LINK_INTERVAL
Link state check interval.
Definition: cgem.h:79
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
#define DBGC2(...)
Definition: compiler.h:522
struct dma_mapping map
Descriptor ring DMA mapping.
Definition: cgem.h:133
#define CGEM_LADDRH
Local MAC address (high half) register.
Definition: cgem.h:85
void * data
Start of data.
Definition: iobuf.h:52
static int cgem_init_phy(struct cgem_nic *cgem)
Initialise PHY.
Definition: cgem.c:207
struct cgem_ring rx
Receive ring.
Definition: cgem.h:184
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
Flattened Device Tree.
void * dt_ioremap(struct dt_device *dt, unsigned int offset, unsigned int index, size_t len)
Map devicetree range.
Definition: devtree.c:52
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition: wpa.h:234
An MII interface.
Definition: mii.h:43
void iounmap(volatile const void *io_addr)
Unmap I/O address.
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define CGEM_PHYMNTNC_ADDR(x)
PHY address.
Definition: cgem.h:70
static int cgem_check_link(struct net_device *netdev)
Check link state.
Definition: cgem.c:232
uint8_t ll_addr[MAX_LL_ADDR_LEN]
Link-layer address.
Definition: netdevice.h:387
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define CGEM_RX_ADDR_WRAP
End of descriptor ring.
Definition: cgem.h:105
#define CGEM_REG_LEN
I/O region length.
Definition: cgem.h:21
uint8_t count
Number of descriptors.
Definition: cgem.h:142
struct dma_device dma
DMA device.
Definition: devtree.h:23
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
String functions.
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition: iobpad.c:49
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
static void cgem_destroy_ring(struct cgem_nic *cgem, struct cgem_ring *ring)
Destroy descriptor ring.
Definition: cgem.c:312
#define CGEM_DMACR_RXBUF(x)
RX buffer size.
Definition: cgem.h:44
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition: wpa.h:237
#define CGEM_IDR
Interrupt disable register.
Definition: cgem.h:62
static void * dt_get_drvdata(struct dt_device *dt)
Get devicetree driver-private data.
Definition: devtree.h:76
A Cadence GEM descriptor.
Definition: cgem.h:88
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:37
struct fdt sysfdt
The system flattened device tree (if present)
Definition: fdt.c:44