iPXE
velocity.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Adrian Jamróz <adrian.jamroz@gmail.com>
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 
20 FILE_LICENCE ( GPL2_OR_LATER );
21 
22 #include <stdint.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <byteswap.h>
27 #include <ipxe/netdevice.h>
28 #include <ipxe/ethernet.h>
29 #include <ipxe/if_ether.h>
30 #include <ipxe/iobuf.h>
31 #include <ipxe/malloc.h>
32 #include <ipxe/pci.h>
33 #include <ipxe/mii.h>
34 #include "velocity.h"
35 
36 #define velocity_setbit(_reg, _mask) writeb ( readb ( _reg ) | _mask, _reg )
37 #define virt_to_le32bus(x) ( cpu_to_le32 ( virt_to_bus ( x ) ) )
38 
39 /** @file
40  *
41  * VIA Velocity network driver
42  *
43  */
44 
45 /******************************************************************************
46  *
47  * MII interface
48  *
49  ******************************************************************************
50  */
51 
52 /**
53  * Stop MII auto-polling
54  *
55  * @v vlc Velocity device
56  * @ret rc Return status code
57  */
58 static int velocity_autopoll_stop ( struct velocity_nic *vlc ) {
60 
61  /* Disable MII auto polling */
62  writeb ( 0, vlc->regs + VELOCITY_MIICR );
63 
64  /* Wait for disabling to take effect */
65  while ( timeout-- ) {
66  udelay ( 1 );
67  if ( readb ( vlc->regs + VELOCITY_MIISR ) &
69  return 0;
70  }
71 
72  DBGC ( vlc, "MII autopoll stop timeout\n" );
73  return -ETIMEDOUT;
74 }
75 
76 /**
77  * Start MII auto-polling
78  *
79  * @v vlc Velocity device
80  * @ret rc Return status code
81  */
82 static int velocity_autopoll_start ( struct velocity_nic *vlc ) {
84 
85  /* Enable MII auto polling */
87 
88  /* Wait for enabling to take effect */
89  while ( timeout-- ) {
90  udelay ( 1 );
91  if ( ( readb ( vlc->regs + VELOCITY_MIISR ) &
92  VELOCITY_MIISR_IDLE ) == 0 )
93  return 0;
94  }
95 
96  DBGC ( vlc, "MII autopoll start timeout\n" );
97  return -ETIMEDOUT;
98 }
99 
100 /**
101  * Read from MII register
102  *
103  * @v mdio MII interface
104  * @v phy PHY address
105  * @v reg Register address
106  * @ret value Data read, or negative error
107  */
108 static int velocity_mii_read ( struct mii_interface *mdio,
109  unsigned int phy __unused, unsigned int reg ) {
110  struct velocity_nic *vlc =
111  container_of ( mdio, struct velocity_nic, mdio );
113  int result;
114 
115  DBGC2 ( vlc, "VELOCITY %p MII read reg %d\n", vlc, reg );
116 
117  /* Disable autopolling before we can access MII */
118  velocity_autopoll_stop ( vlc );
119 
120  /* Send read command and address */
121  writeb ( reg, vlc->regs + VELOCITY_MIIADDR );
123 
124  /* Wait for read to complete */
125  while ( timeout-- ) {
126  udelay ( 1 );
127  if ( ( readb ( vlc->regs + VELOCITY_MIICR ) &
128  VELOCITY_MIICR_RCMD ) == 0 ) {
129  result = readw ( vlc->regs + VELOCITY_MIIDATA );
130  velocity_autopoll_start ( vlc );
131  return result;
132  }
133  }
134 
135  /* Restart autopolling */
136  velocity_autopoll_start ( vlc );
137 
138  DBGC ( vlc, "MII read timeout\n" );
139  return -ETIMEDOUT;
140 }
141 
142 /**
143  * Write to MII register
144  *
145  * @v mdio MII interface
146  * @v phy PHY address
147  * @v reg Register address
148  * @v data Data to write
149  * @ret rc Return status code
150  */
151 static int velocity_mii_write ( struct mii_interface *mdio,
152  unsigned int phy __unused, unsigned int reg,
153  unsigned int data) {
154  struct velocity_nic *vlc =
155  container_of ( mdio, struct velocity_nic, mdio );
157 
158  DBGC2 ( vlc, "VELOCITY %p MII write reg %d data 0x%04x\n",
159  vlc, reg, data );
160 
161  /* Disable autopolling before we can access MII */
162  velocity_autopoll_stop ( vlc );
163 
164  /* Send write command, data and destination register */
165  writeb ( reg, vlc->regs + VELOCITY_MIIADDR );
166  writew ( data, vlc->regs + VELOCITY_MIIDATA );
168 
169  /* Wait for write to complete */
170  while ( timeout-- ) {
171  udelay ( 1 );
172  if ( ( readb ( vlc->regs + VELOCITY_MIICR ) &
173  VELOCITY_MIICR_WCMD ) == 0 ) {
174  velocity_autopoll_start ( vlc );
175  return 0;
176  }
177  }
178 
179  /* Restart autopolling */
180  velocity_autopoll_start ( vlc );
181 
182  DBGC ( vlc, "MII write timeout\n" );
183  return -ETIMEDOUT;
184 }
185 
186 /** Velocity MII operations */
189  .write = velocity_mii_write,
190 };
191 
192 /**
193  * Set Link speed
194  *
195  * @v vlc Velocity device
196  */
197 static void velocity_set_link ( struct velocity_nic *vlc ) {
198  int tmp;
199 
200  /* Advertise 1000MBit */
201  tmp = mii_read ( &vlc->mii, MII_CTRL1000 );
203  mii_write ( &vlc->mii, MII_CTRL1000, tmp );
204 
205  /* Enable GBit operation in MII Control Register */
206  tmp = mii_read ( &vlc->mii, MII_BMCR );
207  tmp |= BMCR_SPEED1000;
208  mii_write ( &vlc->mii, MII_BMCR, tmp );
209 }
210 
211 /******************************************************************************
212  *
213  * Device reset
214  *
215  ******************************************************************************
216  */
217 
218 /**
219  * Reload eeprom contents
220  *
221  * @v vlc Velocity device
222  */
223 static int velocity_reload_eeprom ( struct velocity_nic *vlc ) {
225 
226  /* Initiate reload */
228 
229  /* Wait for reload to complete */
230  while ( timeout-- ) {
231  udelay ( 1 );
232  if ( ( readb ( vlc->regs + VELOCITY_EECSR ) &
233  VELOCITY_EECSR_RELOAD ) == 0 )
234  return 0;
235  }
236 
237  DBGC ( vlc, "VELOCITY %p EEPROM reload timeout\n", vlc );
238  return -ETIMEDOUT;
239 }
240 
241 /**
242  * Reset hardware
243  *
244  * @v vlc Velocity device
245  * @ret rc Return status code
246  */
247 static int velocity_reset ( struct velocity_nic *vlc ) {
249  uint8_t tmp;
250 
251  DBGC ( vlc, "VELOCITY %p reset\n", vlc );
252 
253  /* clear sticky Power state bits */
254  tmp = readb ( vlc->regs + VELOCITY_STICKY );
256  writeb ( tmp, vlc->regs + VELOCITY_STICKY );
257 
258  /* clear PACPI, which might have been enabled by the EEPROM reload */
259  tmp = readb ( vlc->regs + VELOCITY_CFGA );
261  writeb ( tmp, vlc->regs + VELOCITY_CFGA );
262 
264 
265  /* Wait for reset to complete */
266  while ( timeout-- ) {
267  udelay ( 1 );
268  if ( ( readb ( vlc->regs + VELOCITY_CRS1 ) &
269  VELOCITY_CR1_SFRST ) == 0 )
270  return 0;
271  }
272 
273  return -EINVAL;
274 }
275 
276 /******************************************************************************
277  *
278  * Link state
279  *
280  ******************************************************************************
281  */
282 
283 /**
284  * Check link state
285  *
286  * @v netdev Network device
287  */
288 static void velocity_check_link ( struct net_device *netdev ) {
289  struct velocity_nic *vlc = netdev->priv;
290 
291  if ( readb ( vlc->regs + VELOCITY_PHYSTS0 ) & VELOCITY_PHYSTS0_LINK ) {
293  DBGC ( vlc, "VELOCITY %p link up\n", vlc );
294  } else {
296  DBGC ( vlc, "VELOCITY %p link down\n", vlc );
297  }
298 
299  /* The card disables auto-poll after a link change */
300  velocity_autopoll_start ( vlc );
301 }
302 
303 /******************************************************************************
304  *
305  * Network device interface
306  *
307  ******************************************************************************
308  */
309 
310 /**
311  * Allocate descriptor rings
312  *
313  * @v vlc Velocity device
314  * @ret rc Return status code
315  */
316 static int velocity_alloc_rings ( struct velocity_nic *vlc ) {
317  int rc = 0;
318 
319  /* Allocate RX descriptor ring */
320  vlc->rx_prod = 0;
321  vlc->rx_cons = 0;
322  vlc->rx_commit = 0;
325  if ( ! vlc->rx_ring )
326  return -ENOMEM;
327 
328  memset ( vlc->rx_ring, 0, VELOCITY_RXDESC_SIZE );
329 
330  DBGC2 ( vlc, "VELOCITY %p RX ring start address: %p(phys: %#08lx)\n",
331  vlc, vlc->rx_ring, virt_to_bus ( vlc->rx_ring ) );
332 
333  /* Allocate TX descriptor ring */
334  vlc->tx_prod = 0;
335  vlc->tx_cons = 0;
338  if ( ! vlc->tx_ring ) {
339  rc = -ENOMEM;
340  goto err_tx_alloc;
341  }
342 
343  memset ( vlc->tx_ring, 0, VELOCITY_TXDESC_SIZE );
344 
345  /* Send RX ring to the card */
346  writel ( virt_to_bus ( vlc->rx_ring ),
347  vlc->regs + VELOCITY_RXDESC_ADDR_LO );
349 
350  /* Send TX ring to the card */
351  writel ( virt_to_bus ( vlc->tx_ring ),
354 
355  DBGC2 ( vlc, "VELOCITY %p TX ring start address: %p(phys: %#08lx)\n",
356  vlc, vlc->tx_ring, virt_to_bus ( vlc->tx_ring ) );
357 
358  return 0;
359 
360 err_tx_alloc:
362  return rc;
363 }
364 
365 /**
366  * Refill receive descriptor ring
367  *
368  * @v vlc Velocity device
369  */
370 static void velocity_refill_rx ( struct velocity_nic *vlc ) {
372  struct io_buffer *iobuf;
373  int rx_idx, i = 0;
374 
375  /* Check for new packets */
376  while ( ( vlc->rx_prod - vlc->rx_cons ) < VELOCITY_RXDESC_NUM ) {
377  iobuf = alloc_iob ( VELOCITY_RX_MAX_LEN );
378 
379  /* Memory pressure: try again next poll */
380  if ( ! iobuf )
381  break;
382 
383  rx_idx = ( vlc->rx_prod++ % VELOCITY_RXDESC_NUM );
384  desc = &vlc->rx_ring[rx_idx];
385 
386  /* Set descrptor fields */
387  desc->des1 = 0;
388  desc->addr = virt_to_le32bus ( iobuf-> data );
389  desc->des2 = cpu_to_le32 (
392 
393  vlc->rx_buffs[rx_idx] = iobuf;
394  i++;
395 
396  /* Return RX descriptors in blocks of 4 (hw requirement) */
397  if ( rx_idx % 4 == 3 ) {
398  int j;
399  for (j = 0; j < 4; j++) {
400  desc = &vlc->rx_ring[rx_idx - j];
401  desc->des0 = cpu_to_le32 ( VELOCITY_DES0_OWN );
402  }
403  vlc->rx_commit += 4;
404  }
405  }
406 
407  wmb();
408 
409  if ( vlc->rx_commit ) {
410  writew ( vlc->rx_commit,
412  vlc->rx_commit = 0;
413  }
414 
415  if ( i > 0 )
416  DBGC2 ( vlc, "VELOCITY %p refilled %d RX descriptors\n",
417  vlc, i );
418 }
419 
420 /**
421  * Open network device
422  *
423  * @v netdev Network device
424  * @ret rc Return status code
425  */
426 static int velocity_open ( struct net_device *netdev ) {
427  struct velocity_nic *vlc = netdev->priv;
428  int rc;
429 
430  DBGC ( vlc, "VELOCITY %p open\n", vlc );
431  DBGC ( vlc, "VELOCITY %p regs at: %p\n", vlc, vlc->regs );
432 
433  /* Allocate descriptor rings */
434  if ( ( rc = velocity_alloc_rings ( vlc ) ) != 0 )
435  return rc;
436 
437  velocity_refill_rx ( vlc );
438 
439  /* Enable TX/RX queue */
442  vlc->regs + VELOCITY_RXQCSRS );
443 
444  /* Enable interrupts */
445  writeb ( 0xff, vlc->regs + VELOCITY_IMR0 );
446  writeb ( 0xff, vlc->regs + VELOCITY_IMR1 );
447 
448  /* Start MAC */
452  vlc->regs + VELOCITY_CRS0 );
453 
454  /* Receive all packets */
455  writeb ( 0xff, vlc->regs + VELOCITY_RCR );
456 
457  /* Set initial link state */
459 
460  velocity_autopoll_start ( vlc );
461 
462  DBGC2 ( vlc, "VELOCITY %p CR3 %02x\n",
463  vlc, readb ( vlc->regs + 0x0B ) );
464 
465  return 0;
466 }
467 
468 /**
469  * Close network device
470  *
471  * @v netdev Network device
472  */
473 static void velocity_close ( struct net_device *netdev ) {
474  struct velocity_nic *vlc = netdev->priv;
475  int i;
476 
477  /* Stop NIC */
479  vlc->regs + VELOCITY_CRC0 );
481 
482  /* Clear RX ring information */
483  writel ( 0, vlc->regs + VELOCITY_RXDESC_ADDR_LO );
484  writew ( 0, vlc->regs + VELOCITY_RXDESCNUM );
485 
486  /* Destroy RX ring */
488  vlc->rx_ring = NULL;
489  vlc->rx_prod = 0;
490  vlc->rx_cons = 0;
491 
492  /* Discard receive buffers */
493  for ( i = 0 ; i < VELOCITY_RXDESC_NUM ; i++ ) {
494  if ( vlc->rx_buffs[i] )
495  free_iob ( vlc->rx_buffs[i] );
496  vlc->rx_buffs[i] = NULL;
497  }
498 
499  /* Clear TX ring information */
500  writel ( 0, vlc->regs + VELOCITY_TXDESC_ADDR_LO0 );
501  writew ( 0, vlc->regs + VELOCITY_TXDESCNUM );
502 
503  /* Destroy TX ring */
505  vlc->tx_ring = NULL;
506  vlc->tx_prod = 0;
507  vlc->tx_cons = 0;
508 }
509 
510 /**
511  * Transmit packet
512  *
513  * @v netdev Network device
514  * @v iobuf I/O buffer
515  * @ret rc Return status code
516  */
517 static int velocity_transmit ( struct net_device *netdev,
518  struct io_buffer *iobuf ) {
519  struct velocity_nic *vlc = netdev->priv;
521  unsigned int tx_idx;
522 
523  /* Pad packet to minimum length */
524  iob_pad ( iobuf, ETH_ZLEN );
525 
526  tx_idx = ( vlc->tx_prod++ % VELOCITY_TXDESC_NUM );
527  desc = &vlc->tx_ring[tx_idx];
528 
529  /* Set packet size and transfer ownership to NIC */
531  VELOCITY_DES2_SIZE ( iob_len ( iobuf ) ) );
532  /* Data in first desc fragment, only desc for packet, generate INT */
533  desc->des1 = cpu_to_le32 ( VELOCITY_DES1_FRAG ( 1 ) |
536 
537  desc->frags[0].addr = virt_to_le32bus ( iobuf->data );
538  desc->frags[0].des2 = cpu_to_le32 (
539  VELOCITY_DES2_SIZE ( iob_len ( iobuf ) ) );
540 
541  wmb();
542 
543  /* Initiate TX */
545 
546  DBGC2 ( vlc, "VELOCITY %p tx_prod=%d desc=%p iobuf=%p len=%zd\n",
547  vlc, tx_idx, desc, iobuf->data, iob_len ( iobuf ) );
548 
549  return 0;
550 }
551 
552 /**
553  * Poll for received packets.
554  *
555  * @v vlc Velocity device
556  */
557 static void velocity_poll_rx ( struct velocity_nic *vlc ) {
559  struct io_buffer *iobuf;
560  int rx_idx;
561  size_t len;
562  uint32_t des0;
563 
564  /* Check for packets */
565  while ( vlc->rx_cons != vlc->rx_prod ) {
566  rx_idx = ( vlc->rx_cons % VELOCITY_RXDESC_NUM );
567  desc = &vlc->rx_ring[rx_idx];
568 
569  des0 = cpu_to_le32 ( desc->des0 );
570 
571  /* Return if descriptor still in use */
572  if ( des0 & VELOCITY_DES0_OWN )
573  return;
574 
575  iobuf = vlc->rx_buffs[rx_idx];
576 
577  /* Get length, strip CRC */
578  len = VELOCITY_DES0_RMBC ( des0 ) - 4;
579  iob_put ( iobuf, len );
580 
581  DBGC2 ( vlc, "VELOCITY %p got packet on idx=%d (prod=%d), len %zd\n",
582  vlc, rx_idx, vlc->rx_prod % VELOCITY_RXDESC_NUM, len );
583 
584  if ( des0 & VELOCITY_DES0_RX_ERR ) {
585  /* Report receive error */
586  netdev_rx_err ( vlc->netdev, iobuf, -EINVAL );
587  DBGC ( vlc, "VELOCITY %p receive error, status: %02x\n",
588  vlc, des0 );
589  } else if ( des0 & VELOCITY_DES0_RXOK ) {
590  /* Report receive success */
591  netdev_rx( vlc->netdev, iobuf );
592  } else {
593  /* Card indicated neither success nor failure
594  * Technically this shouldn't happen, but we saw it
595  * in debugging once. */
596  DBGC ( vlc, "VELOCITY %p RX neither ERR nor OK: %04x\n",
597  vlc, des0 );
598  DBGC ( vlc, "packet len: %zd\n", len );
599  DBGC_HD ( vlc, iobuf->data, 64 );
600 
601  /* we don't know what it is, treat is as an error */
602  netdev_rx_err ( vlc->netdev, iobuf, -EINVAL );
603  }
604 
605  vlc->rx_cons++;
606  }
607 }
608 
609 /**
610  * Poll for completed packets.
611  *
612  * @v vlc Velocity device
613  */
614 static void velocity_poll_tx ( struct velocity_nic *vlc ) {
616  int tx_idx;
617 
618  /* Check for packets */
619  while ( vlc->tx_cons != vlc->tx_prod ) {
620  tx_idx = ( vlc->tx_cons % VELOCITY_TXDESC_NUM );
621  desc = &vlc->tx_ring[tx_idx];
622 
623  /* Return if descriptor still in use */
624  if ( le32_to_cpu ( desc->des0 ) & VELOCITY_DES0_OWN )
625  return;
626 
627  /* Report errors */
628  if ( le32_to_cpu ( desc->des0 ) & VELOCITY_DES0_TERR ) {
630  return;
631  }
632 
634 
635  DBGC2 ( vlc, "VELOCITY %p poll_tx cons=%d prod=%d tsr=%04x\n",
636  vlc, tx_idx, vlc->tx_prod % VELOCITY_TXDESC_NUM,
637  ( desc->des0 & 0xffff ) );
638  vlc->tx_cons++;
639  }
640 }
641 
642 /**
643  * Poll for completed and received packets
644  *
645  * @v netdev Network device
646  */
647 static void velocity_poll ( struct net_device *netdev ) {
648  struct velocity_nic *vlc = netdev->priv;
649  uint8_t isr1;
650 
651  isr1 = readb ( vlc->regs + VELOCITY_ISR1 );
652 
653  /* ACK interrupts */
654  writew ( 0xFFFF, vlc->regs + VELOCITY_ISR0 );
655 
656  /* Check for competed packets */
657  velocity_poll_rx ( vlc );
658  velocity_poll_tx ( vlc );
659 
660  if ( isr1 & VELOCITY_ISR1_SRCI ) {
661  /* Update linkstate */
662  DBGC2 ( vlc, "VELOCITY %p link status interrupt\n", vlc );
664  }
665 
666  velocity_refill_rx ( vlc );
667 
668  /* deal with potential RX stall caused by RX ring underrun */
670  vlc->regs + VELOCITY_RXQCSRS );
671 }
672 
673 /**
674  * Enable or disable interrupts
675  *
676  * @v netdev Network device
677  * @v enable Interrupts should be enabled
678  */
679 static void velocity_irq ( struct net_device *netdev, int enable ) {
680  struct velocity_nic *vlc = netdev->priv;
681 
682  DBGC ( vlc, "VELOCITY %p interrupts %s\n", vlc,
683  enable ? "enable" : "disable" );
684 
685  if (enable) {
686  /* Enable interrupts */
688  } else {
689  /* Disable interrupts */
691  }
692 }
693 
694 /** Velocity network device operations */
696  .open = velocity_open,
697  .close = velocity_close,
698  .transmit = velocity_transmit,
699  .poll = velocity_poll,
700  .irq = velocity_irq,
701 };
702 
703 /******************************************************************************
704  *
705  * PCI interface
706  *
707  ******************************************************************************
708  */
709 
710 /**
711  * Probe PCI device
712  *
713  * @v pci PCI device
714  * @ret rc Return status code
715  */
716 static int velocity_probe ( struct pci_device *pci ) {
717  struct net_device *netdev;
718  struct velocity_nic *vlc;
719  int rc;
720 
721  /* Allocate and initialise net device */
722  netdev = alloc_etherdev ( sizeof ( *vlc ) );
723  if ( ! netdev ) {
724  rc = -ENOMEM;
725  goto err_alloc;
726  }
728  vlc = netdev->priv;
729  pci_set_drvdata ( pci, netdev );
730  netdev->dev = &pci->dev;
731 
732  /* Fix up PCI device */
733  adjust_pci_device ( pci );
734 
735  /* Map registers */
736  vlc->regs = pci_ioremap ( pci, pci->membase, VELOCITY_BAR_SIZE );
737  vlc->netdev = netdev;
738 
739  /* Reset the NIC */
740  if ( ( rc = velocity_reset ( vlc ) ) != 0 )
741  goto err_reset;
742 
743  /* Reload EEPROM */
744  if ( ( rc = velocity_reload_eeprom ( vlc ) ) != 0 )
745  goto err_reset;
746 
747  /* Get MAC address */
748  netdev->hw_addr[0] = readb ( vlc->regs + VELOCITY_MAC0 );
749  netdev->hw_addr[1] = readb ( vlc->regs + VELOCITY_MAC1 );
750  netdev->hw_addr[2] = readb ( vlc->regs + VELOCITY_MAC2 );
751  netdev->hw_addr[3] = readb ( vlc->regs + VELOCITY_MAC3 );
752  netdev->hw_addr[4] = readb ( vlc->regs + VELOCITY_MAC4 );
753  netdev->hw_addr[5] = readb ( vlc->regs + VELOCITY_MAC5 );
754 
755  /* Initialise and reset MII interface */
757  mii_init ( &vlc->mii, &vlc->mdio, 0 );
758  if ( ( rc = mii_reset ( &vlc->mii ) ) != 0 ) {
759  DBGC ( vlc, "VELOCITY %p could not reset MII: %s\n",
760  vlc, strerror ( rc ) );
761  goto err_mii_reset;
762  }
763 
764  /* Enable proper link advertising */
765  velocity_set_link ( vlc );
766 
767  /* Register network device */
768  if ( ( rc = register_netdev ( netdev ) ) != 0 )
769  goto err_register_netdev;
770 
771  return 0;
772 
773  err_register_netdev:
774  err_mii_reset:
775  velocity_reset ( vlc );
776  err_reset:
778  netdev_put ( netdev );
779  err_alloc:
780  return rc;
781 }
782 
783 /**
784  * Remove PCI device
785  *
786  * @v pci PCI device
787  */
788 static void velocity_remove ( struct pci_device *pci ) {
789  struct net_device *netdev = pci_get_drvdata ( pci );
790  struct velocity_nic *vlc = netdev->priv;
791 
792  /* Unregister network device */
794 
795  /* Reset card */
796  velocity_reset ( vlc );
797 
798  /* Free network device */
800  netdev_put ( netdev );
801 }
802 
803 /** Velocity PCI device IDs */
804 static struct pci_device_id velocity_nics[] = {
805  PCI_ROM ( 0x1106, 0x3119, "vt6122", "VIA Velocity", 0 ),
806 };
807 
808 /** Velocity PCI driver */
809 struct pci_driver velocity_driver __pci_driver = {
810  .ids = velocity_nics,
811  .id_count = ( sizeof ( velocity_nics ) / sizeof ( velocity_nics[0] ) ),
814 };
#define VELOCITY_MIIADDR
Definition: velocity.h:297
#define VELOCITY_TXQCSRS
Definition: velocity.h:232
#define velocity_setbit(_reg, _mask)
Definition: velocity.c:36
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct velocity_tx_descriptor * tx_ring
Transmit descriptor ring.
Definition: velocity.h:351
#define VELOCITY_DES1_INTR
Definition: velocity.h:68
#define VELOCITY_DES0_RX_ERR
Definition: velocity.h:59
unsigned long membase
Memory base.
Definition: pci.h:215
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct velocity_rx_descriptor * rx_ring
Receive descriptor ring.
Definition: velocity.h:336
wmb()
unsigned int rx_cons
Receive consumer index.
Definition: velocity.h:342
uint8_t readb(volatile uint8_t *io_addr)
Read byte from memory-mapped device.
#define iob_put(iobuf, len)
Definition: iobuf.h:120
static const void const void void * result
Definition: crypto.h:335
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:586
#define VELOCITY_DES0_RMBC(_n)
Definition: velocity.h:38
static int velocity_probe(struct pci_device *pci)
Probe PCI device.
Definition: velocity.c:716
#define ADVERTISE_1000FULL
Definition: mii.h:133
#define VELOCITY_ISR1_SRCI
Definition: velocity.h:198
A PCI driver.
Definition: pci.h:247
#define VELOCITY_ISR0
Interrupt status register 0.
Definition: velocity.h:186
#define VELOCITY_TXQCSRS_RUN0
Definition: velocity.h:249
static unsigned int unsigned int reg
Definition: myson.h:162
#define le32_to_cpu(value)
Definition: byteswap.h:113
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
#define VELOCITY_ISR1
Interrupt status register 1.
Definition: velocity.h:197
Error codes.
#define VELOCITY_EECSR
Definition: velocity.h:318
uint16_t readw(volatile uint16_t *io_addr)
Read 16-bit word from memory-mapped device.
static void netdev_tx_complete_next(struct net_device *netdev)
Complete network transmission.
Definition: netdevice.h:764
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
struct pci_device_id * ids
PCI ID table.
Definition: pci.h:249
int(* read)(struct mii_interface *mdio, unsigned int phy, unsigned int reg)
Read from MII register.
Definition: mii.h:27
struct pci_driver velocity_driver __pci_driver
Velocity PCI driver.
Definition: velocity.c:809
#define VELOCITY_RXDESCNUM
Definition: velocity.h:269
uint64_t desc
Microcode descriptor list physical address.
Definition: ucode.h:12
#define VELOCITY_IMR1
Interrupt mask register 1.
Definition: velocity.h:223
#define DBGC(...)
Definition: compiler.h:505
#define VELOCITY_DES2_IC
Definition: velocity.h:77
struct io_buffer * rx_buffs[VELOCITY_RXDESC_NUM]
Receive I/O buffers.
Definition: velocity.h:338
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition: malloc.h:62
#define VELOCITY_MIIDATA
Definition: velocity.h:298
void netdev_tx_complete_next_err(struct net_device *netdev, int rc)
Complete network transmission.
Definition: netdevice.c:509
void netdev_link_down(struct net_device *netdev)
Mark network device as having link down.
Definition: netdevice.c:230
#define VELOCITY_MAC0
MAC address registers.
Definition: velocity.h:100
#define VELOCITY_MAC3
Definition: velocity.h:103
#define VELOCITY_RXDESC_RESIDUECNT
Definition: velocity.h:276
#define VELOCITY_CR1_SFRST
Definition: velocity.h:134
#define virt_to_le32bus(x)
Definition: velocity.c:37
static int velocity_autopoll_stop(struct velocity_nic *vlc)
Stop MII auto-polling.
Definition: velocity.c:58
static int velocity_alloc_rings(struct velocity_nic *vlc)
Allocate descriptor rings.
Definition: velocity.c:316
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition: pci.c:154
struct io_buffer * alloc_iob(size_t len)
Allocate I/O buffer.
Definition: iobuf.c:129
#define VELOCITY_RXQCSR_RUN
Definition: velocity.h:257
#define VELOCITY_MIICR_WCMD
Definition: velocity.h:290
struct device dev
Generic device.
Definition: pci.h:208
uint32_t des0
Definition: rhine.h:11
void writeb(uint8_t data, volatile uint8_t *io_addr)
Write byte to memory-mapped device.
unsigned int rx_commit
Receive commit number.
Definition: velocity.h:348
static void mdio_init(struct mii_interface *mdio, struct mii_operations *op)
Initialise MII interface.
Definition: mii.h:63
#define VELOCITY_STICKY_DS1
Definition: velocity.h:314
#define VELOCITY_PHYSTS0_LINK
Definition: velocity.h:285
Dynamic memory allocation.
unsigned long tmp
Definition: linux_pci.h:53
#define BMCR_SPEED1000
Definition: mii.h:43
#define VELOCITY_CRS1
Command register 1 (set)
Definition: velocity.h:133
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:515
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition: pci.h:359
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define VELOCITY_TIMEOUT_US
Default timeout.
Definition: velocity.h:16
#define VELOCITY_RING_ALIGN
Descriptor alignment.
Definition: velocity.h:94
#define VELOCITY_RXDESC_NUM
Number of receive descriptors.
Definition: velocity.h:84
FILE_LICENCE(GPL2_OR_LATER)
static void velocity_check_link(struct net_device *netdev)
Check link state.
Definition: velocity.c:288
static int velocity_mii_read(struct mii_interface *mdio, unsigned int phy __unused, unsigned int reg)
Read from MII register.
Definition: velocity.c:108
static __always_inline unsigned long virt_to_bus(volatile const void *addr)
Convert virtual address to a bus address.
Definition: io.h:183
#define VELOCITY_MAC1
Definition: velocity.h:101
static int velocity_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: velocity.c:517
#define VELOCITY_CR1_DPOLL
Definition: velocity.h:137
static void velocity_remove(struct pci_device *pci)
Remove PCI device.
Definition: velocity.c:788
#define VELOCITY_RCR
Receive control register.
Definition: velocity.h:108
#define VELOCITY_DES0_RXOK
Definition: velocity.h:41
static struct mii_operations velocity_mii_operations
Velocity MII operations.
Definition: velocity.c:187
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:572
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Ethernet protocol.
#define VELOCITY_TXDESC_NUM
Number of transmit descriptors.
Definition: velocity.h:89
void * priv
Driver private data.
Definition: netdevice.h:431
unsigned int rx_prod
Receive producer index.
Definition: velocity.h:340
#define VELOCITY_IMR0
Interrupt mask register 0.
Definition: velocity.h:220
static void netdev_link_up(struct net_device *netdev)
Mark network device as having link up.
Definition: netdevice.h:774
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 int velocity_reload_eeprom(struct velocity_nic *vlc)
Reload eeprom contents.
Definition: velocity.c:223
static struct net_device * netdev
Definition: gdbudp.c:52
static struct net_device_operations velocity_operations
Velocity network device operations.
Definition: velocity.c:695
#define MII_CTRL1000
Definition: mii.h:24
static void velocity_poll_rx(struct velocity_nic *vlc)
Poll for received packets.
Definition: velocity.c:557
static void velocity_poll_tx(struct velocity_nic *vlc)
Poll for completed packets.
Definition: velocity.c:614
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:941
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define VELOCITY_CR0_TXON
Definition: velocity.h:127
A Velocity network card.
Definition: velocity.h:325
#define VELOCITY_PHYSTS0
Definition: velocity.h:284
#define VELOCITY_DES2_SIZE(_n)
Definition: velocity.h:78
unsigned int tx_prod
Transmit producer index.
Definition: velocity.h:353
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define VELOCITY_DES0_OWN
Definition: velocity.h:39
static void velocity_close(struct net_device *netdev)
Close network device.
Definition: velocity.c:473
#define VELOCITY_CRS0
Command register 0 (set)
Definition: velocity.h:126
static void velocity_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition: velocity.c:647
#define VELOCITY_BAR_SIZE
Skeleton BAR size.
Definition: velocity.h:13
PCI bus.
A PCI device.
Definition: pci.h:206
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:759
#define VELOCITY_CRC3
Command register 3 (clear.
Definition: velocity.h:166
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define VELOCITY_RX_MAX_LEN
Receive buffer length.
Definition: velocity.h:97
#define DBGC_HD(...)
Definition: compiler.h:507
#define VELOCITY_RXQCSRS
Definition: velocity.h:251
A network device.
Definition: netdevice.h:352
Media Independent Interface.
#define VELOCITY_RXQCSR_WAK
Definition: velocity.h:255
#define VELOCITY_TXDESC_SIZE
Definition: velocity.h:90
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:528
static int velocity_reset(struct velocity_nic *vlc)
Reset hardware.
Definition: velocity.c:247
Velocity descriptor format.
Definition: velocity.h:24
#define VELOCITY_TXDESC_ADDR_LO0
Definition: velocity.h:265
unsigned char uint8_t
Definition: stdint.h:10
#define MII_BMCR
Definition: atl1e.h:871
int mii_reset(struct mii_device *mii)
Reset MII device.
Definition: mii.c:74
#define VELOCITY_MIISR
Definition: velocity.h:282
#define ETH_ZLEN
Definition: if_ether.h:10
A PCI device ID list entry.
Definition: pci.h:170
#define ADVERTISE_1000HALF
Definition: mii.h:134
#define VELOCITY_MIISR_IDLE
Definition: velocity.h:283
unsigned int uint32_t
Definition: stdint.h:12
#define VELOCITY_DES1_FRAG(_n)
TX descriptor fragment number.
Definition: velocity.h:66
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39
static int velocity_mii_write(struct mii_interface *mdio, unsigned int phy __unused, unsigned int reg, unsigned int data)
Write to MII register.
Definition: velocity.c:151
#define VELOCITY_EECSR_RELOAD
Definition: velocity.h:319
#define VELOCITY_CRS3
Command register 3 (set)
Definition: velocity.h:148
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 VELOCITY_MIICR
Definition: velocity.h:287
Network device management.
MII interface operations.
Definition: mii.h:18
static int velocity_open(struct net_device *netdev)
Open network device.
Definition: velocity.c:426
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition: pci.h:369
#define VELOCITY_CR0_RXON
Definition: velocity.h:128
static void velocity_irq(struct net_device *netdev, int enable)
Enable or disable interrupts.
Definition: velocity.c:679
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
#define VELOCITY_STICKY
Power Management Sticky Register.
Definition: velocity.h:312
int(* probe)(struct pci_device *pci)
Probe device.
Definition: pci.h:260
#define writew
Definition: w89c840.c:159
#define VELOCITY_DES0_TERR
Definition: velocity.h:40
#define VELOCITY_RXDESC_ADDR_LO
Definition: velocity.h:261
static struct pci_device_id velocity_nics[]
Velocity PCI device IDs.
Definition: velocity.c:804
void * data
Start of data.
Definition: iobuf.h:48
#define VELOCITY_DES1_TCPLS
Definition: velocity.h:67
#define VELOCITY_CFGA_PACPI
Definition: velocity.h:309
#define VELOCITY_MIICR_MAUTO
Definition: velocity.h:288
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
unsigned int tx_cons
Transmit consumer index.
Definition: velocity.h:355
An MII interface.
Definition: mii.h:43
static void velocity_set_link(struct velocity_nic *vlc)
Set Link speed.
Definition: velocity.c:197
static void velocity_refill_rx(struct velocity_nic *vlc)
Refill receive descriptor ring.
Definition: velocity.c:370
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define VELOCITY_MAC4
Definition: velocity.h:104
#define VELOCITY_CR0_STOP
Definition: velocity.h:129
#define VELOCITY_MAC5
Definition: velocity.h:105
struct mii_device mii
MII device.
Definition: velocity.h:331
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.h:77
#define VELOCITY_TXQCSRS_WAK0
Definition: velocity.h:247
static int mii_read(int phy_id, int location)
Definition: epic100.c:499
void timeout(int)
#define VELOCITY_CFGA
Chip Configuration Register A.
Definition: velocity.h:308
#define VELOCITY_STICKY_DS0
Definition: velocity.h:313
#define VELOCITY_RXDESC_SIZE
Definition: velocity.h:85
struct mii_interface mdio
MII interface.
Definition: velocity.h:329
struct net_device * netdev
Netdev.
Definition: velocity.h:333
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
static int velocity_autopoll_start(struct velocity_nic *vlc)
Start MII auto-polling.
Definition: velocity.c:82
static int mii_write(struct mii_device *mii, unsigned int reg, unsigned int data)
Write to MII register.
Definition: mii.h:104
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:381
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define VELOCITY_MAC2
Definition: velocity.h:102
VIA Velocity network driver.
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
String functions.
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition: pci.h:303
void iob_pad(struct io_buffer *iobuf, size_t min_len)
Pad I/O buffer.
Definition: iobpad.c:49
#define VELOCITY_CR3_GINTMSK1
Definition: velocity.h:153
#define VELOCITY_MIICR_RCMD
Definition: velocity.h:289
#define VELOCITY_CRC0
Command register 0 (clear)
Definition: velocity.h:157
#define VELOCITY_TXDESCNUM
Definition: velocity.h:270
void * regs
Registers.
Definition: velocity.h:327
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33
#define VELOCITY_CR0_START
Definition: velocity.h:130