iPXE
smsc95xx.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 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 <string.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #include <byteswap.h>
30 #include <ipxe/ethernet.h>
31 #include <ipxe/usb.h>
32 #include <ipxe/usbnet.h>
33 #include <ipxe/profile.h>
34 #include <ipxe/base16.h>
35 #include <ipxe/smbios.h>
36 #include "smsc95xx.h"
37 
38 /** @file
39  *
40  * SMSC LAN95xx USB Ethernet driver
41  *
42  */
43 
44 /** Bulk IN completion profiler */
45 static struct profiler smsc95xx_in_profiler __profiler =
46  { .name = "smsc95xx.in" };
47 
48 /** Bulk OUT profiler */
49 static struct profiler smsc95xx_out_profiler __profiler =
50  { .name = "smsc95xx.out" };
51 
52 /******************************************************************************
53  *
54  * MAC address
55  *
56  ******************************************************************************
57  */
58 
59 /**
60  * Construct MAC address for Honeywell VM3
61  *
62  * @v smscusb SMSC USB device
63  * @ret rc Return status code
64  */
65 static int smsc95xx_vm3_fetch_mac ( struct smscusb_device *smscusb ) {
66  struct net_device *netdev = smscusb->netdev;
67  struct smbios_structure structure;
69  struct {
70  char manufacturer[ 10 /* "Honeywell" + NUL */ ];
71  char product[ 4 /* "VM3" + NUL */ ];
72  char mac[ base16_encoded_len ( ETH_ALEN ) + 1 /* NUL */ ];
73  } strings;
74  int len;
75  int rc;
76 
77  /* Find system information */
79  &structure ) ) != 0 ) {
80  DBGC ( smscusb, "SMSC95XX %p could not find system "
81  "information: %s\n", smscusb, strerror ( rc ) );
82  return rc;
83  }
84 
85  /* Read system information */
86  if ( ( rc = read_smbios_structure ( &structure, &system,
87  sizeof ( system ) ) ) != 0 ) {
88  DBGC ( smscusb, "SMSC95XX %p could not read system "
89  "information: %s\n", smscusb, strerror ( rc ) );
90  return rc;
91  }
92 
93  /* NUL-terminate all strings to be fetched */
94  memset ( &strings, 0, sizeof ( strings ) );
95 
96  /* Fetch system manufacturer name */
97  len = read_smbios_string ( &structure, system.manufacturer,
98  strings.manufacturer,
99  ( sizeof ( strings.manufacturer ) - 1 ) );
100  if ( len < 0 ) {
101  rc = len;
102  DBGC ( smscusb, "SMSC95XX %p could not read manufacturer "
103  "name: %s\n", smscusb, strerror ( rc ) );
104  return rc;
105  }
106 
107  /* Fetch system product name */
108  len = read_smbios_string ( &structure, system.product, strings.product,
109  ( sizeof ( strings.product ) - 1 ) );
110  if ( len < 0 ) {
111  rc = len;
112  DBGC ( smscusb, "SMSC95XX %p could not read product name: "
113  "%s\n", smscusb, strerror ( rc ) );
114  return rc;
115  }
116 
117  /* Ignore non-VM3 devices */
118  if ( ( strcmp ( strings.manufacturer, "Honeywell" ) != 0 ) ||
119  ( strcmp ( strings.product, "VM3" ) != 0 ) )
120  return -ENOTTY;
121 
122  /* Find OEM strings */
124  &structure ) ) != 0 ) {
125  DBGC ( smscusb, "SMSC95XX %p could not find OEM strings: %s\n",
126  smscusb, strerror ( rc ) );
127  return rc;
128  }
129 
130  /* Fetch MAC address */
132  strings.mac, ( sizeof ( strings.mac ) - 1 ));
133  if ( len < 0 ) {
134  rc = len;
135  DBGC ( smscusb, "SMSC95XX %p could not read OEM string: %s\n",
136  smscusb, strerror ( rc ) );
137  return rc;
138  }
139 
140  /* Sanity check */
141  if ( len != ( ( int ) ( sizeof ( strings.mac ) - 1 ) ) ) {
142  DBGC ( smscusb, "SMSC95XX %p invalid MAC address \"%s\"\n",
143  smscusb, strings.mac );
144  return -EINVAL;
145  }
146 
147  /* Decode MAC address */
148  len = base16_decode ( strings.mac, netdev->hw_addr, ETH_ALEN );
149  if ( len < 0 ) {
150  rc = len;
151  DBGC ( smscusb, "SMSC95XX %p invalid MAC address \"%s\"\n",
152  smscusb, strings.mac );
153  return rc;
154  }
155 
156  DBGC ( smscusb, "SMSC95XX %p using VM3 MAC %s\n",
157  smscusb, eth_ntoa ( netdev->hw_addr ) );
158  return 0;
159 }
160 
161 /**
162  * Fetch MAC address
163  *
164  * @v smscusb SMSC USB device
165  * @ret rc Return status code
166  */
167 static int smsc95xx_fetch_mac ( struct smscusb_device *smscusb ) {
168  struct net_device *netdev = smscusb->netdev;
169  int rc;
170 
171  /* Read MAC address from EEPROM, if present */
172  if ( ( rc = smscusb_eeprom_fetch_mac ( smscusb,
173  SMSC95XX_E2P_BASE ) ) == 0 )
174  return 0;
175 
176  /* Read MAC address from device tree, if present */
177  if ( ( rc = smscusb_fdt_fetch_mac ( smscusb ) ) == 0 )
178  return 0;
179 
180  /* Construct MAC address for Honeywell VM3, if applicable */
181  if ( ( rc = smsc95xx_vm3_fetch_mac ( smscusb ) ) == 0 )
182  return 0;
183 
184  /* Otherwise, generate a random MAC address */
186  DBGC ( smscusb, "SMSC95XX %p using random MAC %s\n",
187  smscusb, eth_ntoa ( netdev->hw_addr ) );
188  return 0;
189 }
190 
191 /******************************************************************************
192  *
193  * Statistics (for debugging)
194  *
195  ******************************************************************************
196  */
197 
198 /**
199  * Dump statistics (for debugging)
200  *
201  * @v smscusb SMSC USB device
202  * @ret rc Return status code
203  */
204 static int smsc95xx_dump_statistics ( struct smscusb_device *smscusb ) {
205  struct smsc95xx_rx_statistics rx;
206  struct smsc95xx_tx_statistics tx;
207  int rc;
208 
209  /* Do nothing unless debugging is enabled */
210  if ( ! DBG_LOG )
211  return 0;
212 
213  /* Get RX statistics */
215  &rx, sizeof ( rx ) ) ) != 0 ) {
216  DBGC ( smscusb, "SMSC95XX %p could not get RX statistics: "
217  "%s\n", smscusb, strerror ( rc ) );
218  return rc;
219  }
220 
221  /* Get TX statistics */
223  &tx, sizeof ( tx ) ) ) != 0 ) {
224  DBGC ( smscusb, "SMSC95XX %p could not get TX statistics: "
225  "%s\n", smscusb, strerror ( rc ) );
226  return rc;
227  }
228 
229  /* Dump statistics */
230  DBGC ( smscusb, "SMSC95XX %p RX good %d bad %d crc %d und %d aln %d "
231  "ovr %d lat %d drp %d\n", smscusb, le32_to_cpu ( rx.good ),
232  le32_to_cpu ( rx.bad ), le32_to_cpu ( rx.crc ),
233  le32_to_cpu ( rx.undersize ), le32_to_cpu ( rx.alignment ),
234  le32_to_cpu ( rx.oversize ), le32_to_cpu ( rx.late ),
235  le32_to_cpu ( rx.dropped ) );
236  DBGC ( smscusb, "SMSC95XX %p TX good %d bad %d pau %d sgl %d mul %d "
237  "exc %d lat %d und %d def %d car %d\n", smscusb,
238  le32_to_cpu ( tx.good ), le32_to_cpu ( tx.bad ),
239  le32_to_cpu ( tx.pause ), le32_to_cpu ( tx.single ),
240  le32_to_cpu ( tx.multiple ), le32_to_cpu ( tx.excessive ),
241  le32_to_cpu ( tx.late ), le32_to_cpu ( tx.underrun ),
242  le32_to_cpu ( tx.deferred ), le32_to_cpu ( tx.carrier ) );
243 
244  return 0;
245 }
246 
247 /******************************************************************************
248  *
249  * Device reset
250  *
251  ******************************************************************************
252  */
253 
254 /**
255  * Reset device
256  *
257  * @v smscusb SMSC USB device
258  * @ret rc Return status code
259  */
260 static int smsc95xx_reset ( struct smscusb_device *smscusb ) {
261  uint32_t hw_cfg;
262  uint32_t led_gpio_cfg;
263  int rc;
264 
265  /* Reset device */
266  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_HW_CFG,
267  SMSC95XX_HW_CFG_LRST ) ) != 0 )
268  return rc;
269 
270  /* Wait for reset to complete */
272 
273  /* Check that reset has completed */
274  if ( ( rc = smscusb_readl ( smscusb, SMSC95XX_HW_CFG, &hw_cfg ) ) != 0 )
275  return rc;
276  if ( hw_cfg & SMSC95XX_HW_CFG_LRST ) {
277  DBGC ( smscusb, "SMSC95XX %p failed to reset\n", smscusb );
278  return -ETIMEDOUT;
279  }
280 
281  /* Configure LEDs */
282  led_gpio_cfg = ( SMSC95XX_LED_GPIO_CFG_GPCTL2_NSPD_LED |
285  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_LED_GPIO_CFG,
286  led_gpio_cfg ) ) != 0 ) {
287  DBGC ( smscusb, "SMSC95XX %p could not configure LEDs: %s\n",
288  smscusb, strerror ( rc ) );
289  /* Ignore error and continue */
290  }
291 
292  return 0;
293 }
294 
295 /******************************************************************************
296  *
297  * Endpoint operations
298  *
299  ******************************************************************************
300  */
301 
302 /**
303  * Complete bulk IN transfer
304  *
305  * @v ep USB endpoint
306  * @v iobuf I/O buffer
307  * @v rc Completion status code
308  */
309 static void smsc95xx_in_complete ( struct usb_endpoint *ep,
310  struct io_buffer *iobuf, int rc ) {
311  struct smscusb_device *smscusb =
312  container_of ( ep, struct smscusb_device, usbnet.in );
313  struct net_device *netdev = smscusb->netdev;
314  struct smsc95xx_rx_header *header;
315 
316  /* Profile completions */
317  profile_start ( &smsc95xx_in_profiler );
318 
319  /* Ignore packets cancelled when the endpoint closes */
320  if ( ! ep->open ) {
321  free_iob ( iobuf );
322  return;
323  }
324 
325  /* Record USB errors against the network device */
326  if ( rc != 0 ) {
327  DBGC ( smscusb, "SMSC95XX %p bulk IN failed: %s\n",
328  smscusb, strerror ( rc ) );
329  goto err;
330  }
331 
332  /* Sanity check */
333  if ( iob_len ( iobuf ) < ( sizeof ( *header ) + 4 /* CRC */ ) ) {
334  DBGC ( smscusb, "SMSC95XX %p underlength bulk IN\n",
335  smscusb );
336  DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
337  rc = -EINVAL;
338  goto err;
339  }
340 
341  /* Strip header and CRC */
342  header = iobuf->data;
343  iob_pull ( iobuf, sizeof ( *header ) );
344  iob_unput ( iobuf, 4 /* CRC */ );
345 
346  /* Check for errors */
347  if ( header->command & cpu_to_le32 ( SMSC95XX_RX_RUNT |
349  SMSC95XX_RX_CRC ) ) {
350  DBGC ( smscusb, "SMSC95XX %p receive error (%08x):\n",
351  smscusb, le32_to_cpu ( header->command ) );
352  DBGC_HDA ( smscusb, 0, iobuf->data, iob_len ( iobuf ) );
353  rc = -EIO;
354  goto err;
355  }
356 
357  /* Hand off to network stack */
358  netdev_rx ( netdev, iob_disown ( iobuf ) );
359 
360  profile_stop ( &smsc95xx_in_profiler );
361  return;
362 
363  err:
364  /* Hand off to network stack */
365  netdev_rx_err ( netdev, iob_disown ( iobuf ), rc );
366 }
367 
368 /** Bulk IN endpoint operations */
371 };
372 
373 /**
374  * Transmit packet
375  *
376  * @v smscusb SMSC USB device
377  * @v iobuf I/O buffer
378  * @ret rc Return status code
379  */
380 static int smsc95xx_out_transmit ( struct smscusb_device *smscusb,
381  struct io_buffer *iobuf ) {
382  struct smsc95xx_tx_header *header;
383  size_t len = iob_len ( iobuf );
384  int rc;
385 
386  /* Profile transmissions */
387  profile_start ( &smsc95xx_out_profiler );
388 
389  /* Prepend header */
390  if ( ( rc = iob_ensure_headroom ( iobuf, sizeof ( *header ) ) ) != 0 )
391  return rc;
392  header = iob_push ( iobuf, sizeof ( *header ) );
394  SMSC95XX_TX_LEN ( len ) );
395  header->len = cpu_to_le32 ( len );
396 
397  /* Enqueue I/O buffer */
398  if ( ( rc = usb_stream ( &smscusb->usbnet.out, iobuf, 0 ) ) != 0 )
399  return rc;
400 
401  profile_stop ( &smsc95xx_out_profiler );
402  return 0;
403 }
404 
405 /******************************************************************************
406  *
407  * Network device interface
408  *
409  ******************************************************************************
410  */
411 
412 /**
413  * Open network device
414  *
415  * @v netdev Network device
416  * @ret rc Return status code
417  */
418 static int smsc95xx_open ( struct net_device *netdev ) {
419  struct smscusb_device *smscusb = netdev->priv;
420  int rc;
421 
422  /* Clear stored interrupt status */
423  smscusb->int_sts = 0;
424 
425  /* Configure bulk IN empty response */
426  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_HW_CFG,
427  SMSC95XX_HW_CFG_BIR ) ) != 0 )
428  goto err_hw_cfg;
429 
430  /* Open USB network device */
431  if ( ( rc = usbnet_open ( &smscusb->usbnet ) ) != 0 ) {
432  DBGC ( smscusb, "SMSC95XX %p could not open: %s\n",
433  smscusb, strerror ( rc ) );
434  goto err_open;
435  }
436 
437  /* Configure interrupt endpoint */
438  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_INT_EP_CTL,
440  SMSC95XX_INT_EP_CTL_PHY_EN ) ) ) != 0 )
441  goto err_int_ep_ctl;
442 
443  /* Configure bulk IN delay */
444  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_BULK_IN_DLY,
445  SMSC95XX_BULK_IN_DLY_SET ( 0 ) ) ) != 0 )
446  goto err_bulk_in_dly;
447 
448  /* Configure MAC */
449  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_MAC_CR,
456  SMSC95XX_MAC_CR_RXEN ) ) ) != 0 )
457  goto err_mac_cr;
458 
459  /* Configure transmit datapath */
460  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_TX_CFG,
461  SMSC95XX_TX_CFG_ON ) ) != 0 )
462  goto err_tx_cfg;
463 
464  /* Set MAC address */
465  if ( ( rc = smscusb_set_address ( smscusb, SMSC95XX_ADDR_BASE ) ) != 0 )
466  goto err_set_address;
467 
468  /* Enable PHY interrupts and update link status */
469  if ( ( rc = smscusb_mii_open ( smscusb, SMSC95XX_MII_PHY_INTR_MASK,
471  SMSC95XX_PHY_INTR_LINK_DOWN ) ) ) != 0)
472  goto err_mii_open;
473 
474  return 0;
475 
476  err_mii_open:
477  err_set_address:
478  err_tx_cfg:
479  err_mac_cr:
480  err_bulk_in_dly:
481  err_int_ep_ctl:
482  usbnet_close ( &smscusb->usbnet );
483  err_open:
484  err_hw_cfg:
485  smsc95xx_reset ( smscusb );
486  return rc;
487 }
488 
489 /**
490  * Close network device
491  *
492  * @v netdev Network device
493  */
494 static void smsc95xx_close ( struct net_device *netdev ) {
495  struct smscusb_device *smscusb = netdev->priv;
496 
497  /* Close USB network device */
498  usbnet_close ( &smscusb->usbnet );
499 
500  /* Dump statistics (for debugging) */
501  smsc95xx_dump_statistics ( smscusb );
502 
503  /* Reset device */
504  smsc95xx_reset ( smscusb );
505 }
506 
507 /**
508  * Transmit packet
509  *
510  * @v netdev Network device
511  * @v iobuf I/O buffer
512  * @ret rc Return status code
513  */
514 static int smsc95xx_transmit ( struct net_device *netdev,
515  struct io_buffer *iobuf ) {
516  struct smscusb_device *smscusb = netdev->priv;
517  int rc;
518 
519  /* Transmit packet */
520  if ( ( rc = smsc95xx_out_transmit ( smscusb, iobuf ) ) != 0 )
521  return rc;
522 
523  return 0;
524 }
525 
526 /**
527  * Poll for completed and received packets
528  *
529  * @v netdev Network device
530  */
531 static void smsc95xx_poll ( struct net_device *netdev ) {
532  struct smscusb_device *smscusb = netdev->priv;
534  int rc;
535 
536  /* Poll USB bus */
537  usb_poll ( smscusb->bus );
538 
539  /* Refill endpoints */
540  if ( ( rc = usbnet_refill ( &smscusb->usbnet ) ) != 0 )
541  netdev_rx_err ( netdev, NULL, rc );
542 
543  /* Do nothing more unless there are interrupts to handle */
544  int_sts = smscusb->int_sts;
545  if ( ! int_sts )
546  return;
547 
548  /* Check link status if applicable */
550  smscusb_mii_check_link ( smscusb );
552  }
553 
554  /* Record RX FIFO overflow if applicable */
556  DBGC2 ( smscusb, "SMSC95XX %p RX FIFO overflowed\n",
557  smscusb );
560  }
561 
562  /* Check for unexpected interrupts */
563  if ( int_sts ) {
564  DBGC ( smscusb, "SMSC95XX %p unexpected interrupt %#08x\n",
565  smscusb, int_sts );
567  }
568 
569  /* Clear interrupts */
570  if ( ( rc = smscusb_writel ( smscusb, SMSC95XX_INT_STS,
571  smscusb->int_sts ) ) != 0 )
572  netdev_rx_err ( netdev, NULL, rc );
573  smscusb->int_sts = 0;
574 }
575 
576 /** SMSC95xx network device operations */
578  .open = smsc95xx_open,
579  .close = smsc95xx_close,
580  .transmit = smsc95xx_transmit,
581  .poll = smsc95xx_poll,
582 };
583 
584 /******************************************************************************
585  *
586  * USB interface
587  *
588  ******************************************************************************
589  */
590 
591 /**
592  * Probe device
593  *
594  * @v func USB function
595  * @v config Configuration descriptor
596  * @ret rc Return status code
597  */
598 static int smsc95xx_probe ( struct usb_function *func,
599  struct usb_configuration_descriptor *config ) {
600  struct net_device *netdev;
601  struct smscusb_device *smscusb;
602  int rc;
603 
604  /* Allocate and initialise structure */
605  netdev = alloc_etherdev ( sizeof ( *smscusb ) );
606  if ( ! netdev ) {
607  rc = -ENOMEM;
608  goto err_alloc;
609  }
611  netdev->dev = &func->dev;
612  smscusb = netdev->priv;
613  memset ( smscusb, 0, sizeof ( *smscusb ) );
614  smscusb_init ( smscusb, netdev, func, &smsc95xx_in_operations );
617  usb_refill_init ( &smscusb->usbnet.in,
618  ( sizeof ( struct smsc95xx_tx_header ) -
619  sizeof ( struct smsc95xx_rx_header ) ),
621  DBGC ( smscusb, "SMSC95XX %p on %s\n", smscusb, func->name );
622 
623  /* Describe USB network device */
624  if ( ( rc = usbnet_describe ( &smscusb->usbnet, config ) ) != 0 ) {
625  DBGC ( smscusb, "SMSC95XX %p could not describe: %s\n",
626  smscusb, strerror ( rc ) );
627  goto err_describe;
628  }
629 
630  /* Reset device */
631  if ( ( rc = smsc95xx_reset ( smscusb ) ) != 0 )
632  goto err_reset;
633 
634  /* Read MAC address */
635  if ( ( rc = smsc95xx_fetch_mac ( smscusb ) ) != 0 )
636  goto err_fetch_mac;
637 
638  /* Register network device */
639  if ( ( rc = register_netdev ( netdev ) ) != 0 )
640  goto err_register;
641 
642  usb_func_set_drvdata ( func, netdev );
643  return 0;
644 
646  err_register:
647  err_fetch_mac:
648  err_reset:
649  err_describe:
651  netdev_put ( netdev );
652  err_alloc:
653  return rc;
654 }
655 
656 /**
657  * Remove device
658  *
659  * @v func USB function
660  */
661 static void smsc95xx_remove ( struct usb_function *func ) {
662  struct net_device *netdev = usb_func_get_drvdata ( func );
663 
666  netdev_put ( netdev );
667 }
668 
669 /** SMSC95xx device IDs */
670 static struct usb_device_id smsc95xx_ids[] = {
671  {
672  .name = "smsc9500",
673  .vendor = 0x0424,
674  .product = 0x9500,
675  },
676  {
677  .name = "smsc9505",
678  .vendor = 0x0424,
679  .product = 0x9505,
680  },
681  {
682  .name = "smsc9500a",
683  .vendor = 0x0424,
684  .product = 0x9e00,
685  },
686  {
687  .name = "smsc9505a",
688  .vendor = 0x0424,
689  .product = 0x9e01,
690  },
691  {
692  .name = "smsc9514",
693  .vendor = 0x0424,
694  .product = 0xec00,
695  },
696  {
697  .name = "smsc9500-s",
698  .vendor = 0x0424,
699  .product = 0x9900,
700  },
701  {
702  .name = "smsc9505-s",
703  .vendor = 0x0424,
704  .product = 0x9901,
705  },
706  {
707  .name = "smsc9500a-s",
708  .vendor = 0x0424,
709  .product = 0x9902,
710  },
711  {
712  .name = "smsc9505a-s",
713  .vendor = 0x0424,
714  .product = 0x9903,
715  },
716  {
717  .name = "smsc9514-s",
718  .vendor = 0x0424,
719  .product = 0x9904,
720  },
721  {
722  .name = "smsc9500a-h",
723  .vendor = 0x0424,
724  .product = 0x9905,
725  },
726  {
727  .name = "smsc9505a-h",
728  .vendor = 0x0424,
729  .product = 0x9906,
730  },
731  {
732  .name = "smsc9500-2",
733  .vendor = 0x0424,
734  .product = 0x9907,
735  },
736  {
737  .name = "smsc9500a-2",
738  .vendor = 0x0424,
739  .product = 0x9908,
740  },
741  {
742  .name = "smsc9514-2",
743  .vendor = 0x0424,
744  .product = 0x9909,
745  },
746  {
747  .name = "smsc9530",
748  .vendor = 0x0424,
749  .product = 0x9530,
750  },
751  {
752  .name = "smsc9730",
753  .vendor = 0x0424,
754  .product = 0x9730,
755  },
756  {
757  .name = "smsc89530",
758  .vendor = 0x0424,
759  .product = 0x9e08,
760  },
761 };
762 
763 /** SMSC LAN95xx driver */
764 struct usb_driver smsc95xx_driver __usb_driver = {
765  .ids = smsc95xx_ids,
766  .id_count = ( sizeof ( smsc95xx_ids ) / sizeof ( smsc95xx_ids[0] ) ),
767  .class = USB_CLASS_ID ( 0xff, 0x00, 0xff ),
768  .score = USB_SCORE_NORMAL,
769  .probe = smsc95xx_probe,
770  .remove = smsc95xx_remove,
771 };
int smscusb_set_address(struct smscusb_device *smscusb, unsigned int addr_base)
Set receive address.
Definition: smscusb.c:686
Transmit packet header.
Definition: smsc95xx.h:96
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
A USB driver.
Definition: usb.h:1363
#define SMSC95XX_INT_EP_CTL_RXDF_EN
RX FIFO overflow.
Definition: smsc95xx.h:45
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define SMSC95XX_VM3_OEM_STRING_MAC
Honeywell VM3 MAC address OEM string index.
Definition: smsc95xx.h:178
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int smsc95xx_open(struct net_device *netdev)
Open network device.
Definition: smsc95xx.c:418
A USB device ID.
Definition: usb.h:1317
static struct usb_device_id smsc95xx_ids[]
SMSC95xx device IDs.
Definition: smsc95xx.c:670
void(* complete)(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete transfer.
Definition: usb.h:481
void netdev_rx_err(struct net_device *netdev, struct io_buffer *iobuf, int rc)
Discard received packet.
Definition: netdevice.c:501
Receive packet header.
Definition: smsc95xx.h:81
Receive statistics.
Definition: smsc95xx.h:113
static void * usb_func_get_drvdata(struct usb_function *func)
Get USB function driver private data.
Definition: usb.h:701
const char * name
Name.
Definition: usb.h:659
#define SMSC95XX_PHY_INTR_LINK_DOWN
PHY interrupt: link down.
Definition: smsc95xx.h:78
static void smsc95xx_close(struct net_device *netdev)
Close network device.
Definition: smsc95xx.c:494
#define le32_to_cpu(value)
Definition: byteswap.h:113
int(* open)(struct net_device *netdev)
Open network device.
Definition: netdevice.h:222
const char * name
Name.
Definition: usb.h:1319
static int smsc95xx_out_transmit(struct smscusb_device *smscusb, struct io_buffer *iobuf)
Transmit packet.
Definition: smsc95xx.c:380
Error codes.
#define iob_push(iobuf, len)
Definition: iobuf.h:80
An SMSC USB device.
Definition: smscusb.h:147
#define SMSC95XX_ADDR_BASE
MAC address register base.
Definition: smsc95xx.h:63
uint8_t product
Product string.
Definition: smbios.h:105
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
Transmit statistics.
Definition: smsc95xx.h:136
#define SMSC95XX_RX_LATE
Late collision.
Definition: smsc95xx.h:90
static void smscusb_init(struct smscusb_device *smscusb, struct net_device *netdev, struct usb_function *func, struct usb_endpoint_driver_operations *in)
Initialise SMSC USB device.
Definition: smscusb.h:259
#define SMSC95XX_HW_CFG
Hardware configuration register.
Definition: smsc95xx.h:24
#define DBGC(...)
Definition: compiler.h:505
int read_smbios_structure(struct smbios_structure *structure, void *data, size_t len)
Copy SMBIOS structure.
Definition: smbios.c:184
#define SMSC95XX_INT_STS
Interrupt status register.
Definition: smsc95xx.h:15
int usb_stream(struct usb_endpoint *ep, struct io_buffer *iobuf, int terminate)
Enqueue USB stream transfer.
Definition: usb.c:528
#define SMSC95XX_LED_GPIO_CFG_GPCTL0_NFDX_LED
Full-duplex LED.
Definition: smsc95xx.h:37
#define SMSC95XX_TX_LAST
Last segment.
Definition: smsc95xx.h:107
static struct net_device_operations smsc95xx_operations
SMSC95xx network device operations.
Definition: smsc95xx.c:577
#define SMSC95XX_BULK_IN_DLY
Bulk IN delay register.
Definition: smsc95xx.h:49
#define SMSC95XX_LED_GPIO_CFG_GPCTL1_NLNKA_LED
Activity LED.
Definition: smsc95xx.h:34
static int smscusb_writel(struct smscusb_device *smscusb, unsigned int address, uint32_t value)
Write register.
Definition: smscusb.h:182
uint8_t mac[ETH_ALEN]
MAC address.
Definition: ena.h:24
A data structure for storing profiling information.
Definition: profile.h:26
#define SMSC95XX_HW_CFG_BIR
Bulk IN use NAK.
Definition: smsc95xx.h:25
int open
Endpoint is open.
Definition: usb.h:404
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition: profile.h:171
#define SMSC95XX_TX_LEN(len)
Buffer size.
Definition: smsc95xx.h:110
#define SMSC95XX_E2P_BASE
EEPROM register base.
Definition: smsc95xx.h:41
static void smscusb_mii_init(struct smscusb_device *smscusb, unsigned int mii_base, unsigned int phy_source)
Initialise SMSC USB device MII interface.
Definition: smscusb.h:280
#define SMSC95XX_TX_CFG_ON
TX enable.
Definition: smsc95xx.h:21
int smscusb_mii_open(struct smscusb_device *smscusb, unsigned int phy_mask, unsigned int intrs)
Enable PHY interrupts and update link status.
Definition: smscusb.c:655
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition: base16.h:21
struct usb_endpoint out
Bulk OUT endpoint.
Definition: usbnet.h:31
#define SMSC95XX_MAC_CR_MCPAS
All multicast.
Definition: smsc95xx.h:56
static void netdev_init(struct net_device *netdev, struct net_device_operations *op)
Initialise a network device.
Definition: netdevice.h:498
static int smsc95xx_probe(struct usb_function *func, struct usb_configuration_descriptor *config)
Probe device.
Definition: smsc95xx.c:598
uint32_t int_sts
Interrupt status.
Definition: smscusb.h:165
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
A USB endpoint.
Definition: usb.h:389
#define SMSC95XX_PHY_INTR_ANEG_DONE
PHY interrupt: auto-negotiation complete.
Definition: smsc95xx.h:75
const char * name
Name.
Definition: profile.h:28
#define SMBIOS_TYPE_OEM_STRINGS
SMBIOS OEM strings structure type.
Definition: smbios.h:156
int find_smbios_structure(unsigned int type, unsigned int instance, struct smbios_structure *structure)
Find specific structure type within SMBIOS.
Definition: smbios.c:118
struct usbnet_device usbnet
USB network device.
Definition: smscusb.h:155
#define SMSC95XX_IN_MTU
Bulk IN buffer size.
Definition: smsc95xx.h:172
static void netdev_put(struct net_device *netdev)
Drop reference to network device.
Definition: netdevice.h:555
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Ethernet protocol.
#define SMSC95XX_MAC_CR
MAC control register.
Definition: smsc95xx.h:53
void * priv
Driver private data.
Definition: netdevice.h:425
#define DBGC_HDA(...)
Definition: compiler.h:506
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
#define SMSC95XX_INT_EP_CTL
Interrupt endpoint control register.
Definition: smsc95xx.h:44
static void usb_refill_init(struct usb_endpoint *ep, size_t reserve, size_t len, unsigned int max)
Initialise USB endpoint refill.
Definition: usb.h:601
static struct net_device * netdev
Definition: gdbudp.c:52
#define SMSC95XX_IN_MAX_FILL
Bulk IN maximum fill level.
Definition: smsc95xx.h:169
int read_smbios_string(struct smbios_structure *structure, unsigned int index, void *data, size_t len)
Find indexed string within SMBIOS structure.
Definition: smbios.c:204
static int smscusb_readl(struct smscusb_device *smscusb, unsigned int address, uint32_t *value)
Read register.
Definition: smscusb.h:203
static void usb_func_set_drvdata(struct usb_function *func, void *priv)
Set USB function driver private data.
Definition: usb.h:690
static void smsc95xx_poll(struct net_device *netdev)
Poll for completed and received packets.
Definition: smsc95xx.c:531
static void profile_start(struct profiler *profiler)
Start profiling.
Definition: profile.h:158
Profiling.
void unregister_netdev(struct net_device *netdev)
Unregister network device.
Definition: netdevice.c:844
uint32_t rx
Maximum number of receive queues.
Definition: intelvf.h:16
#define SMSC95XX_TX_CFG
Transmit configuration register.
Definition: smsc95xx.h:20
int usbnet_refill(struct usbnet_device *usbnet)
Refill USB network device bulk IN and interrupt endpoints.
Definition: usbnet.c:151
#define cpu_to_le32(value)
Definition: byteswap.h:107
static int smsc95xx_dump_statistics(struct smscusb_device *smscusb)
Dump statistics (for debugging)
Definition: smsc95xx.c:204
static int smsc95xx_transmit(struct net_device *netdev, struct io_buffer *iobuf)
Transmit packet.
Definition: smsc95xx.c:514
#define SMSC95XX_INT_STS_PHY_INT
PHY interrupt.
Definition: smsc95xx.h:17
static void usb_poll(struct usb_bus *bus)
Poll USB bus.
Definition: usb.h:1049
#define iob_unput(iobuf, len)
Definition: iobuf.h:131
int smscusb_eeprom_fetch_mac(struct smscusb_device *smscusb, unsigned int e2p_base)
Fetch MAC address from EEPROM.
Definition: smscusb.c:215
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t tx
Maximum number of transmit queues.
Definition: intelvf.h:14
#define SMSC95XX_RX_STATISTICS
Receive statistics.
Definition: smsc95xx.h:133
int register_netdev(struct net_device *netdev)
Register network device.
Definition: netdevice.c:667
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
const char * eth_ntoa(const void *ll_addr)
Transcribe Ethernet address.
Definition: ethernet.c:175
#define USB_CLASS_ID(base, subclass, protocol)
Construct USB class ID.
Definition: usb.h:1345
A network device.
Definition: netdevice.h:348
struct usb_endpoint in
Bulk IN endpoint.
Definition: usbnet.h:29
static void netdev_nullify(struct net_device *netdev)
Stop using a network device.
Definition: netdevice.h:511
Normal driver.
Definition: usb.h:1406
#define SMSC95XX_INT_STS_RXDF_INT
RX FIFO overflow.
Definition: smsc95xx.h:16
#define SMSC95XX_MAC_CR_TXEN
TX enabled.
Definition: smsc95xx.h:59
static struct profiler smsc95xx_in_profiler __profiler
Bulk IN completion profiler.
Definition: smsc95xx.c:45
static int smsc95xx_vm3_fetch_mac(struct smscusb_device *smscusb)
Construct MAC address for Honeywell VM3.
Definition: smsc95xx.c:65
#define ETH_ALEN
Definition: if_ether.h:8
unsigned int uint32_t
Definition: stdint.h:12
#define SMSC95XX_HW_CFG_LRST
Soft lite reset.
Definition: smsc95xx.h:26
System Management BIOS.
#define SMSC95XX_INT_EP_CTL_PHY_EN
PHY interrupt.
Definition: smsc95xx.h:46
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:470
struct device * dev
Underlying hardware device.
Definition: netdevice.h:360
static int smsc95xx_fetch_mac(struct smscusb_device *smscusb)
Fetch MAC address.
Definition: smsc95xx.c:167
static struct usb_endpoint_driver_operations smsc95xx_in_operations
Bulk IN endpoint operations.
Definition: smsc95xx.c:369
USB network devices.
A USB configuration descriptor.
Definition: usb.h:195
SMBIOS system information structure.
Definition: smbios.h:99
uint32_t len
Length.
Definition: ena.h:14
#define ENOBUFS
No buffer space available.
Definition: errno.h:498
#define DBGC2(...)
Definition: compiler.h:522
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
Universal Serial Bus (USB)
#define SMSC95XX_MAC_CR_PRMS
Promiscuous.
Definition: smsc95xx.h:57
SMSC LAN95xx USB Ethernet driver.
void * data
Start of data.
Definition: iobuf.h:44
int smscusb_mii_check_link(struct smscusb_device *smscusb)
Check link status.
Definition: smscusb.c:613
#define EIO
Input/output error.
Definition: errno.h:433
#define SMSC95XX_MAC_CR_FDPX
Full duplex.
Definition: smsc95xx.h:55
#define SMSC95XX_BULK_IN_DLY_SET(ticks)
Delay / 16.7ns.
Definition: smsc95xx.h:50
struct net_device * alloc_etherdev(size_t priv_size)
Allocate Ethernet device.
Definition: ethernet.c:264
struct ena_aq_header header
Header.
Definition: ena.h:12
uint8_t manufacturer
Manufacturer string.
Definition: smbios.h:103
#define SMSC95XX_MAC_CR_PASSBAD
Pass bad frames.
Definition: smsc95xx.h:58
static int smsc95xx_reset(struct smscusb_device *smscusb)
Reset device.
Definition: smsc95xx.c:260
int usbnet_describe(struct usbnet_device *usbnet, struct usb_configuration_descriptor *config)
Describe USB network device interfaces.
Definition: usbnet.c:277
#define SMSC95XX_RX_CRC
CRC error.
Definition: smsc95xx.h:93
struct usb_bus * bus
USB bus.
Definition: smscusb.h:151
struct net_device * netdev
Network device.
Definition: smscusb.h:153
static int smscusb_get_statistics(struct smscusb_device *smscusb, unsigned int index, void *data, size_t len)
Get statistics.
Definition: smscusb.h:225
#define SMSC95XX_RX_RUNT
Runt frame.
Definition: smsc95xx.h:87
void usbnet_close(struct usbnet_device *usbnet)
Close USB network device.
Definition: usbnet.c:127
USB endpoint driver operations.
Definition: usb.h:474
struct device dev
Generic device.
Definition: usb.h:665
A USB function.
Definition: usb.h:657
#define SMSC95XX_MAC_CR_RXEN
RX enabled.
Definition: smsc95xx.h:60
int iob_ensure_headroom(struct io_buffer *iobuf, size_t len)
Ensure I/O buffer has sufficient headroom.
Definition: iobuf.c:183
#define DBG_LOG
Definition: compiler.h:317
#define SMSC95XX_RESET_DELAY_US
Reset delay (in microseconds)
Definition: smsc95xx.h:163
#define SMSC95XX_TX_STATISTICS
Transmit statistics.
Definition: smsc95xx.h:160
#define SMSC95XX_MII_BASE
MII register base.
Definition: smsc95xx.h:66
uint8_t hw_addr[MAX_HW_ADDR_LEN]
Hardware address.
Definition: netdevice.h:375
SMBIOS structure descriptor.
Definition: smbios.h:89
int smscusb_fdt_fetch_mac(struct smscusb_device *smscusb)
Fetch MAC address from device tree.
Definition: smscusb.c:456
#define SMBIOS_TYPE_SYSTEM_INFORMATION
SMBIOS system information structure type.
Definition: smbios.h:117
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
struct usb_driver smsc95xx_driver __usb_driver
SMSC LAN95xx driver.
Definition: smsc95xx.c:764
String functions.
#define SMSC95XX_TX_FIRST
First segment.
Definition: smsc95xx.h:104
#define SMSC95XX_MII_PHY_INTR_MASK
PHY interrupt mask MII register.
Definition: smsc95xx.h:72
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define SMSC95XX_LED_GPIO_CFG
LED GPIO configuration register.
Definition: smsc95xx.h:29
void eth_random_addr(void *hw_addr)
Generate random Ethernet address.
Definition: ethernet.c:159
#define SMSC95XX_MAC_CR_RXALL
Receive all.
Definition: smsc95xx.h:54
static void smsc95xx_in_complete(struct usb_endpoint *ep, struct io_buffer *iobuf, int rc)
Complete bulk IN transfer.
Definition: smsc95xx.c:309
#define SMSC95XX_MII_PHY_INTR_SOURCE
PHY interrupt source MII register.
Definition: smsc95xx.h:69
struct usb_device_id * ids
USB ID table.
Definition: usb.h:1365
static void smsc95xx_remove(struct usb_function *func)
Remove device.
Definition: smsc95xx.c:661
uint8_t system[ETH_ALEN]
System identifier.
Definition: eth_slow.h:24
void * memset(void *dest, int character, size_t len) __nonnull
Base16 encoding.
A persistent I/O buffer.
Definition: iobuf.h:32
#define SMSC95XX_LED_GPIO_CFG_GPCTL2_NSPD_LED
Link speed LED.
Definition: smsc95xx.h:31
int usbnet_open(struct usbnet_device *usbnet)
Open USB network device.
Definition: usbnet.c:54