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