[smscusb] Fetch MAC from device tree for Raspberry Pi Model B+
[ipxe.git] / src / drivers / net / smsc95xx.c
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;
68 struct smbios_system_information system;
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 */
78 if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_SYSTEM_INFORMATION, 0,
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 */
123 if ( ( rc = find_smbios_structure ( SMBIOS_TYPE_OEM_STRINGS, 0,
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 */
131 len = read_smbios_string ( &structure, SMSC95XX_VM3_OEM_STRING_MAC,
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 */
185 eth_random_addr ( netdev->hw_addr );
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 */
214 if ( ( rc = smscusb_get_statistics ( smscusb, SMSC95XX_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 */
222 if ( ( rc = smscusb_get_statistics ( smscusb, SMSC95XX_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 */
271 udelay ( SMSC95XX_RESET_DELAY_US );
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 |
283 SMSC95XX_LED_GPIO_CFG_GPCTL1_NLNKA_LED |
284 SMSC95XX_LED_GPIO_CFG_GPCTL0_NFDX_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 |
348 SMSC95XX_RX_LATE |
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 */
369 static struct usb_endpoint_driver_operations smsc95xx_in_operations = {
370 .complete = smsc95xx_in_complete,
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 ) );
393 header->command = cpu_to_le32 ( SMSC95XX_TX_FIRST | SMSC95XX_TX_LAST |
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,
439 ( SMSC95XX_INT_EP_CTL_RXDF_EN |
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,
450 ( SMSC95XX_MAC_CR_RXALL |
451 SMSC95XX_MAC_CR_FDPX |
452 SMSC95XX_MAC_CR_MCPAS |
453 SMSC95XX_MAC_CR_PRMS |
454 SMSC95XX_MAC_CR_PASSBAD |
455 SMSC95XX_MAC_CR_TXEN |
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,
470 ( SMSC95XX_PHY_INTR_ANEG_DONE |
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;
533 uint32_t int_sts;
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 */
549 if ( int_sts & SMSC95XX_INT_STS_PHY_INT ) {
550 smscusb_mii_check_link ( smscusb );
551 int_sts &= ~SMSC95XX_INT_STS_PHY_INT;
552 }
553
554 /* Record RX FIFO overflow if applicable */
555 if ( int_sts & SMSC95XX_INT_STS_RXDF_INT ) {
556 DBGC2 ( smscusb, "SMSC95XX %p RX FIFO overflowed\n",
557 smscusb );
558 netdev_rx_err ( netdev, NULL, -ENOBUFS );
559 int_sts &= ~SMSC95XX_INT_STS_RXDF_INT;
560 }
561
562 /* Check for unexpected interrupts */
563 if ( int_sts ) {
564 DBGC ( smscusb, "SMSC95XX %p unexpected interrupt %#08x\n",
565 smscusb, int_sts );
566 netdev_rx_err ( netdev, NULL, -ENOTTY );
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 */
577 static struct net_device_operations smsc95xx_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 }
610 netdev_init ( netdev, &smsc95xx_operations );
611 netdev->dev = &func->dev;
612 smscusb = netdev->priv;
613 memset ( smscusb, 0, sizeof ( *smscusb ) );
614 smscusb_init ( smscusb, netdev, func, &smsc95xx_in_operations );
615 smscusb_mii_init ( smscusb, SMSC95XX_MII_BASE,
616 SMSC95XX_MII_PHY_INTR_SOURCE );
617 usb_refill_init ( &smscusb->usbnet.in,
618 ( sizeof ( struct smsc95xx_tx_header ) -
619 sizeof ( struct smsc95xx_rx_header ) ),
620 SMSC95XX_IN_MTU, SMSC95XX_IN_MAX_FILL );
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
645 unregister_netdev ( netdev );
646 err_register:
647 err_fetch_mac:
648 err_reset:
649 err_describe:
650 netdev_nullify ( netdev );
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
664 unregister_netdev ( netdev );
665 netdev_nullify ( netdev );
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 };