sfxge.c revision 272325
1/*-
2 * Copyright (c) 2010-2011 Solarflare Communications, Inc.
3 * All rights reserved.
4 *
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge.c 272325 2014-09-30 20:18:10Z gnn $");
32
33#include <sys/param.h>
34#include <sys/kernel.h>
35#include <sys/bus.h>
36#include <sys/rman.h>
37#include <sys/lock.h>
38#include <sys/module.h>
39#include <sys/mutex.h>
40#include <sys/smp.h>
41#include <sys/socket.h>
42#include <sys/taskqueue.h>
43#include <sys/sockio.h>
44#include <sys/sysctl.h>
45
46#include <dev/pci/pcireg.h>
47#include <dev/pci/pcivar.h>
48
49#include <net/ethernet.h>
50#include <net/if.h>
51#include <net/if_var.h>
52#include <net/if_media.h>
53#include <net/if_types.h>
54
55#include "common/efx.h"
56
57#include "sfxge.h"
58#include "sfxge_rx.h"
59
60#define	SFXGE_CAP (IFCAP_VLAN_MTU | \
61		   IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO |	\
62		   IFCAP_JUMBO_MTU | IFCAP_LRO |			\
63		   IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE)
64#define	SFXGE_CAP_ENABLE SFXGE_CAP
65#define	SFXGE_CAP_FIXED (IFCAP_VLAN_MTU | IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | \
66			 IFCAP_JUMBO_MTU | IFCAP_LINKSTATE)
67
68MALLOC_DEFINE(M_SFXGE, "sfxge", "Solarflare 10GigE driver");
69
70static void
71sfxge_reset(void *arg, int npending);
72
73static int
74sfxge_start(struct sfxge_softc *sc)
75{
76	int rc;
77
78	sx_assert(&sc->softc_lock, LA_XLOCKED);
79
80	if (sc->init_state == SFXGE_STARTED)
81		return (0);
82
83	if (sc->init_state != SFXGE_REGISTERED) {
84		rc = EINVAL;
85		goto fail;
86	}
87
88	if ((rc = efx_nic_init(sc->enp)) != 0)
89		goto fail;
90
91	/* Start processing interrupts. */
92	if ((rc = sfxge_intr_start(sc)) != 0)
93		goto fail2;
94
95	/* Start processing events. */
96	if ((rc = sfxge_ev_start(sc)) != 0)
97		goto fail3;
98
99	/* Start the receiver side. */
100	if ((rc = sfxge_rx_start(sc)) != 0)
101		goto fail4;
102
103	/* Start the transmitter side. */
104	if ((rc = sfxge_tx_start(sc)) != 0)
105		goto fail5;
106
107	/* Fire up the port. */
108	if ((rc = sfxge_port_start(sc)) != 0)
109		goto fail6;
110
111	sc->init_state = SFXGE_STARTED;
112
113	/* Tell the stack we're running. */
114	sc->ifnet->if_drv_flags |= IFF_DRV_RUNNING;
115	sc->ifnet->if_drv_flags &= ~IFF_DRV_OACTIVE;
116
117	return (0);
118
119fail6:
120	sfxge_tx_stop(sc);
121
122fail5:
123	sfxge_rx_stop(sc);
124
125fail4:
126	sfxge_ev_stop(sc);
127
128fail3:
129	sfxge_intr_stop(sc);
130
131fail2:
132	efx_nic_fini(sc->enp);
133
134fail:
135	device_printf(sc->dev, "sfxge_start: %d\n", rc);
136
137	return (rc);
138}
139
140static void
141sfxge_if_init(void *arg)
142{
143	struct sfxge_softc *sc;
144
145	sc = (struct sfxge_softc *)arg;
146
147	sx_xlock(&sc->softc_lock);
148	(void)sfxge_start(sc);
149	sx_xunlock(&sc->softc_lock);
150}
151
152static void
153sfxge_stop(struct sfxge_softc *sc)
154{
155	sx_assert(&sc->softc_lock, LA_XLOCKED);
156
157	if (sc->init_state != SFXGE_STARTED)
158		return;
159
160	sc->init_state = SFXGE_REGISTERED;
161
162	/* Stop the port. */
163	sfxge_port_stop(sc);
164
165	/* Stop the transmitter. */
166	sfxge_tx_stop(sc);
167
168	/* Stop the receiver. */
169	sfxge_rx_stop(sc);
170
171	/* Stop processing events. */
172	sfxge_ev_stop(sc);
173
174	/* Stop processing interrupts. */
175	sfxge_intr_stop(sc);
176
177	efx_nic_fini(sc->enp);
178
179	sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING;
180}
181
182static int
183sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
184{
185	struct sfxge_softc *sc;
186	struct ifreq *ifr;
187	int error;
188
189	ifr = (struct ifreq *)data;
190	sc = ifp->if_softc;
191	error = 0;
192
193	switch (command) {
194	case SIOCSIFFLAGS:
195		sx_xlock(&sc->softc_lock);
196		if (ifp->if_flags & IFF_UP) {
197			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
198				if ((ifp->if_flags ^ sc->if_flags) &
199				    (IFF_PROMISC | IFF_ALLMULTI)) {
200					sfxge_mac_filter_set(sc);
201				}
202			} else
203				sfxge_start(sc);
204		} else
205			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
206				sfxge_stop(sc);
207		sc->if_flags = ifp->if_flags;
208		sx_xunlock(&sc->softc_lock);
209		break;
210	case SIOCSIFMTU:
211		if (ifr->ifr_mtu == ifp->if_mtu) {
212			/* Nothing to do */
213			error = 0;
214		} else if (ifr->ifr_mtu > SFXGE_MAX_MTU) {
215			error = EINVAL;
216		} else if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
217			ifp->if_mtu = ifr->ifr_mtu;
218			error = 0;
219		} else {
220			/* Restart required */
221			sx_xlock(&sc->softc_lock);
222			sfxge_stop(sc);
223			ifp->if_mtu = ifr->ifr_mtu;
224			error = sfxge_start(sc);
225			sx_xunlock(&sc->softc_lock);
226			if (error != 0) {
227				ifp->if_flags &= ~IFF_UP;
228				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
229				if_down(ifp);
230			}
231		}
232		break;
233	case SIOCADDMULTI:
234	case SIOCDELMULTI:
235		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
236			sfxge_mac_filter_set(sc);
237		break;
238	case SIOCSIFCAP:
239		sx_xlock(&sc->softc_lock);
240
241		/*
242		 * The networking core already rejects attempts to
243		 * enable capabilities we don't have.  We still have
244		 * to reject attempts to disable capabilities that we
245		 * can't (yet) disable.
246		 */
247		if (~ifr->ifr_reqcap & SFXGE_CAP_FIXED) {
248			error = EINVAL;
249			sx_xunlock(&sc->softc_lock);
250			break;
251		}
252
253		ifp->if_capenable = ifr->ifr_reqcap;
254		if (ifp->if_capenable & IFCAP_TXCSUM)
255			ifp->if_hwassist |= (CSUM_IP | CSUM_TCP | CSUM_UDP);
256		else
257			ifp->if_hwassist &= ~(CSUM_IP | CSUM_TCP | CSUM_UDP);
258		if (ifp->if_capenable & IFCAP_TSO)
259			ifp->if_hwassist |= CSUM_TSO;
260		else
261			ifp->if_hwassist &= ~CSUM_TSO;
262
263		sx_xunlock(&sc->softc_lock);
264		break;
265	case SIOCSIFMEDIA:
266	case SIOCGIFMEDIA:
267		error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
268		break;
269	default:
270		error = ether_ioctl(ifp, command, data);
271	}
272
273	return (error);
274}
275
276static void
277sfxge_ifnet_fini(struct ifnet *ifp)
278{
279	struct sfxge_softc *sc = ifp->if_softc;
280
281	sx_xlock(&sc->softc_lock);
282	sfxge_stop(sc);
283	sx_xunlock(&sc->softc_lock);
284
285	ifmedia_removeall(&sc->media);
286	ether_ifdetach(ifp);
287	if_free(ifp);
288}
289
290static int
291sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
292{
293	const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
294	device_t dev;
295	int rc;
296
297	dev = sc->dev;
298	sc->ifnet = ifp;
299
300	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
301	ifp->if_init = sfxge_if_init;
302	ifp->if_softc = sc;
303	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
304	ifp->if_ioctl = sfxge_if_ioctl;
305
306	ifp->if_capabilities = SFXGE_CAP;
307	ifp->if_capenable = SFXGE_CAP_ENABLE;
308	ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO;
309
310	ether_ifattach(ifp, encp->enc_mac_addr);
311
312#ifdef SFXGE_HAVE_MQ
313	ifp->if_transmit = sfxge_if_transmit;
314	ifp->if_qflush = sfxge_if_qflush;
315#else
316	ifp->if_start = sfxge_if_start;
317	IFQ_SET_MAXLEN(&ifp->if_snd, SFXGE_NDESCS - 1);
318	ifp->if_snd.ifq_drv_maxlen = SFXGE_NDESCS - 1;
319	IFQ_SET_READY(&ifp->if_snd);
320
321	mtx_init(&sc->tx_lock, "txq", NULL, MTX_DEF);
322#endif
323
324	if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
325		goto fail;
326
327	return (0);
328
329fail:
330	ether_ifdetach(sc->ifnet);
331	return (rc);
332}
333
334void
335sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n, uint32_t *idp)
336{
337	KASSERT(sc->buffer_table_next + n <=
338		efx_nic_cfg_get(sc->enp)->enc_buftbl_limit,
339		("buffer table full"));
340
341	*idp = sc->buffer_table_next;
342	sc->buffer_table_next += n;
343}
344
345static int
346sfxge_bar_init(struct sfxge_softc *sc)
347{
348	efsys_bar_t *esbp = &sc->bar;
349
350	esbp->esb_rid = PCIR_BAR(EFX_MEM_BAR);
351	if ((esbp->esb_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
352	    &esbp->esb_rid, RF_ACTIVE)) == NULL) {
353		device_printf(sc->dev, "Cannot allocate BAR region %d\n",
354		    EFX_MEM_BAR);
355		return (ENXIO);
356	}
357	esbp->esb_tag = rman_get_bustag(esbp->esb_res);
358	esbp->esb_handle = rman_get_bushandle(esbp->esb_res);
359	mtx_init(&esbp->esb_lock, "sfxge_efsys_bar", NULL, MTX_DEF);
360
361	return (0);
362}
363
364static void
365sfxge_bar_fini(struct sfxge_softc *sc)
366{
367	efsys_bar_t *esbp = &sc->bar;
368
369	bus_release_resource(sc->dev, SYS_RES_MEMORY, esbp->esb_rid,
370	    esbp->esb_res);
371	mtx_destroy(&esbp->esb_lock);
372}
373
374static int
375sfxge_create(struct sfxge_softc *sc)
376{
377	device_t dev;
378	efx_nic_t *enp;
379	int error;
380
381	dev = sc->dev;
382
383	sx_init(&sc->softc_lock, "sfxge_softc");
384
385	sc->stats_node = SYSCTL_ADD_NODE(
386		device_get_sysctl_ctx(dev),
387		SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
388		OID_AUTO, "stats", CTLFLAG_RD, NULL, "Statistics");
389	if (sc->stats_node == NULL) {
390		error = ENOMEM;
391		goto fail;
392	}
393
394	TASK_INIT(&sc->task_reset, 0, sfxge_reset, sc);
395
396	(void) pci_enable_busmaster(dev);
397
398	/* Initialize DMA mappings. */
399	if ((error = sfxge_dma_init(sc)) != 0)
400		goto fail;
401
402	/* Map the device registers. */
403	if ((error = sfxge_bar_init(sc)) != 0)
404		goto fail;
405
406	error = efx_family(pci_get_vendor(dev), pci_get_device(dev),
407	    &sc->family);
408	KASSERT(error == 0, ("Family should be filtered by sfxge_probe()"));
409
410	/* Create the common code nic object. */
411	mtx_init(&sc->enp_lock, "sfxge_nic", NULL, MTX_DEF);
412	if ((error = efx_nic_create(sc->family, (efsys_identifier_t *)sc,
413	    &sc->bar, &sc->enp_lock, &enp)) != 0)
414		goto fail3;
415	sc->enp = enp;
416
417	/* Initialize MCDI to talk to the microcontroller. */
418	if ((error = sfxge_mcdi_init(sc)) != 0)
419		goto fail4;
420
421	/* Probe the NIC and build the configuration data area. */
422	if ((error = efx_nic_probe(enp)) != 0)
423		goto fail5;
424
425	/* Initialize the NVRAM. */
426	if ((error = efx_nvram_init(enp)) != 0)
427		goto fail6;
428
429	/* Initialize the VPD. */
430	if ((error = efx_vpd_init(enp)) != 0)
431		goto fail7;
432
433	/* Reset the NIC. */
434	if ((error = efx_nic_reset(enp)) != 0)
435		goto fail8;
436
437	/* Initialize buffer table allocation. */
438	sc->buffer_table_next = 0;
439
440	/* Set up interrupts. */
441	if ((error = sfxge_intr_init(sc)) != 0)
442		goto fail8;
443
444	/* Initialize event processing state. */
445	if ((error = sfxge_ev_init(sc)) != 0)
446		goto fail11;
447
448	/* Initialize receive state. */
449	if ((error = sfxge_rx_init(sc)) != 0)
450		goto fail12;
451
452	/* Initialize transmit state. */
453	if ((error = sfxge_tx_init(sc)) != 0)
454		goto fail13;
455
456	/* Initialize port state. */
457	if ((error = sfxge_port_init(sc)) != 0)
458		goto fail14;
459
460	sc->init_state = SFXGE_INITIALIZED;
461
462	return (0);
463
464fail14:
465	sfxge_tx_fini(sc);
466
467fail13:
468	sfxge_rx_fini(sc);
469
470fail12:
471	sfxge_ev_fini(sc);
472
473fail11:
474	sfxge_intr_fini(sc);
475
476fail8:
477	efx_vpd_fini(enp);
478
479fail7:
480	efx_nvram_fini(enp);
481
482fail6:
483	efx_nic_unprobe(enp);
484
485fail5:
486	sfxge_mcdi_fini(sc);
487
488fail4:
489	sc->enp = NULL;
490	efx_nic_destroy(enp);
491	mtx_destroy(&sc->enp_lock);
492
493fail3:
494	sfxge_bar_fini(sc);
495	(void) pci_disable_busmaster(sc->dev);
496
497fail:
498	sc->dev = NULL;
499	sx_destroy(&sc->softc_lock);
500	return (error);
501}
502
503static void
504sfxge_destroy(struct sfxge_softc *sc)
505{
506	efx_nic_t *enp;
507
508	/* Clean up port state. */
509	sfxge_port_fini(sc);
510
511	/* Clean up transmit state. */
512	sfxge_tx_fini(sc);
513
514	/* Clean up receive state. */
515	sfxge_rx_fini(sc);
516
517	/* Clean up event processing state. */
518	sfxge_ev_fini(sc);
519
520	/* Clean up interrupts. */
521	sfxge_intr_fini(sc);
522
523	/* Tear down common code subsystems. */
524	efx_nic_reset(sc->enp);
525	efx_vpd_fini(sc->enp);
526	efx_nvram_fini(sc->enp);
527	efx_nic_unprobe(sc->enp);
528
529	/* Tear down MCDI. */
530	sfxge_mcdi_fini(sc);
531
532	/* Destroy common code context. */
533	enp = sc->enp;
534	sc->enp = NULL;
535	efx_nic_destroy(enp);
536
537	/* Free DMA memory. */
538	sfxge_dma_fini(sc);
539
540	/* Free mapped BARs. */
541	sfxge_bar_fini(sc);
542
543	(void) pci_disable_busmaster(sc->dev);
544
545	taskqueue_drain(taskqueue_thread, &sc->task_reset);
546
547	/* Destroy the softc lock. */
548	sx_destroy(&sc->softc_lock);
549}
550
551static int
552sfxge_vpd_handler(SYSCTL_HANDLER_ARGS)
553{
554	struct sfxge_softc *sc = arg1;
555	efx_vpd_value_t value;
556	int rc;
557
558	value.evv_tag = arg2 >> 16;
559	value.evv_keyword = arg2 & 0xffff;
560	if ((rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value))
561	    != 0)
562		return (rc);
563
564	return (SYSCTL_OUT(req, value.evv_value, value.evv_length));
565}
566
567static void
568sfxge_vpd_try_add(struct sfxge_softc *sc, struct sysctl_oid_list *list,
569		  efx_vpd_tag_t tag, const char *keyword)
570{
571	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
572	efx_vpd_value_t value;
573
574	/* Check whether VPD tag/keyword is present */
575	value.evv_tag = tag;
576	value.evv_keyword = EFX_VPD_KEYWORD(keyword[0], keyword[1]);
577	if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) != 0)
578		return;
579
580	SYSCTL_ADD_PROC(
581		ctx, list, OID_AUTO, keyword, CTLTYPE_STRING|CTLFLAG_RD,
582		sc, tag << 16 | EFX_VPD_KEYWORD(keyword[0], keyword[1]),
583		sfxge_vpd_handler, "A", "");
584}
585
586static int
587sfxge_vpd_init(struct sfxge_softc *sc)
588{
589	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
590	struct sysctl_oid *vpd_node;
591	struct sysctl_oid_list *vpd_list;
592	char keyword[3];
593	efx_vpd_value_t value;
594	int rc;
595
596	if ((rc = efx_vpd_size(sc->enp, &sc->vpd_size)) != 0)
597		goto fail;
598	sc->vpd_data = malloc(sc->vpd_size, M_SFXGE, M_WAITOK);
599	if ((rc = efx_vpd_read(sc->enp, sc->vpd_data, sc->vpd_size)) != 0)
600		goto fail2;
601
602	/* Copy ID (product name) into device description, and log it. */
603	value.evv_tag = EFX_VPD_ID;
604	if (efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value) == 0) {
605		value.evv_value[value.evv_length] = 0;
606		device_set_desc_copy(sc->dev, value.evv_value);
607		device_printf(sc->dev, "%s\n", value.evv_value);
608	}
609
610	vpd_node = SYSCTL_ADD_NODE(
611		ctx, SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
612		OID_AUTO, "vpd", CTLFLAG_RD, NULL, "Vital Product Data");
613	vpd_list = SYSCTL_CHILDREN(vpd_node);
614
615	/* Add sysctls for all expected and any vendor-defined keywords. */
616	sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "PN");
617	sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "EC");
618	sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, "SN");
619	keyword[0] = 'V';
620	keyword[2] = 0;
621	for (keyword[1] = '0'; keyword[1] <= '9'; keyword[1]++)
622		sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword);
623	for (keyword[1] = 'A'; keyword[1] <= 'Z'; keyword[1]++)
624		sfxge_vpd_try_add(sc, vpd_list, EFX_VPD_RO, keyword);
625
626	return (0);
627
628fail2:
629	free(sc->vpd_data, M_SFXGE);
630fail:
631	return (rc);
632}
633
634static void
635sfxge_vpd_fini(struct sfxge_softc *sc)
636{
637	free(sc->vpd_data, M_SFXGE);
638}
639
640static void
641sfxge_reset(void *arg, int npending)
642{
643	struct sfxge_softc *sc;
644	int rc;
645
646	(void)npending;
647
648	sc = (struct sfxge_softc *)arg;
649
650	sx_xlock(&sc->softc_lock);
651
652	if (sc->init_state != SFXGE_STARTED)
653		goto done;
654
655	sfxge_stop(sc);
656	efx_nic_reset(sc->enp);
657	if ((rc = sfxge_start(sc)) != 0)
658		device_printf(sc->dev,
659			      "reset failed (%d); interface is now stopped\n",
660			      rc);
661
662done:
663	sx_xunlock(&sc->softc_lock);
664}
665
666void
667sfxge_schedule_reset(struct sfxge_softc *sc)
668{
669	taskqueue_enqueue(taskqueue_thread, &sc->task_reset);
670}
671
672static int
673sfxge_attach(device_t dev)
674{
675	struct sfxge_softc *sc;
676	struct ifnet *ifp;
677	int error;
678
679	sc = device_get_softc(dev);
680	sc->dev = dev;
681
682	/* Allocate ifnet. */
683	ifp = if_alloc(IFT_ETHER);
684	if (ifp == NULL) {
685		device_printf(dev, "Couldn't allocate ifnet\n");
686		error = ENOMEM;
687		goto fail;
688	}
689	sc->ifnet = ifp;
690
691	/* Initialize hardware. */
692	if ((error = sfxge_create(sc)) != 0)
693		goto fail2;
694
695	/* Create the ifnet for the port. */
696	if ((error = sfxge_ifnet_init(ifp, sc)) != 0)
697		goto fail3;
698
699	if ((error = sfxge_vpd_init(sc)) != 0)
700		goto fail4;
701
702	sc->init_state = SFXGE_REGISTERED;
703
704	return (0);
705
706fail4:
707	sfxge_ifnet_fini(ifp);
708fail3:
709	sfxge_destroy(sc);
710
711fail2:
712	if_free(sc->ifnet);
713
714fail:
715	return (error);
716}
717
718static int
719sfxge_detach(device_t dev)
720{
721	struct sfxge_softc *sc;
722
723	sc = device_get_softc(dev);
724
725	sfxge_vpd_fini(sc);
726
727	/* Destroy the ifnet. */
728	sfxge_ifnet_fini(sc->ifnet);
729
730	/* Tear down hardware. */
731	sfxge_destroy(sc);
732
733	return (0);
734}
735
736static int
737sfxge_probe(device_t dev)
738{
739	uint16_t pci_vendor_id;
740	uint16_t pci_device_id;
741	efx_family_t family;
742	int rc;
743
744	pci_vendor_id = pci_get_vendor(dev);
745	pci_device_id = pci_get_device(dev);
746
747	rc = efx_family(pci_vendor_id, pci_device_id, &family);
748	if (rc != 0)
749		return (ENXIO);
750
751	KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family"));
752	device_set_desc(dev, "Solarflare SFC9000 family");
753	return (0);
754}
755
756static device_method_t sfxge_methods[] = {
757	DEVMETHOD(device_probe,		sfxge_probe),
758	DEVMETHOD(device_attach,	sfxge_attach),
759	DEVMETHOD(device_detach,	sfxge_detach),
760
761	DEVMETHOD_END
762};
763
764static devclass_t sfxge_devclass;
765
766static driver_t sfxge_driver = {
767	"sfxge",
768	sfxge_methods,
769	sizeof(struct sfxge_softc)
770};
771
772DRIVER_MODULE(sfxge, pci, sfxge_driver, sfxge_devclass, 0, 0);
773