if_ixl.c revision 303967
147061Sbrian/******************************************************************************
247061Sbrian
347061Sbrian  Copyright (c) 2013-2015, Intel Corporation
447061Sbrian  All rights reserved.
547061Sbrian
647061Sbrian  Redistribution and use in source and binary forms, with or without
747061Sbrian  modification, are permitted provided that the following conditions are met:
847061Sbrian
947061Sbrian   1. Redistributions of source code must retain the above copyright notice,
1047061Sbrian      this list of conditions and the following disclaimer.
1147061Sbrian
1247061Sbrian   2. Redistributions in binary form must reproduce the above copyright
1347061Sbrian      notice, this list of conditions and the following disclaimer in the
1447061Sbrian      documentation and/or other materials provided with the distribution.
1547061Sbrian
1647061Sbrian   3. Neither the name of the Intel Corporation nor the names of its
1747061Sbrian      contributors may be used to endorse or promote products derived from
1847061Sbrian      this software without specific prior written permission.
1947061Sbrian
2047061Sbrian  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2147061Sbrian  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2247061Sbrian  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2347061Sbrian  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2447061Sbrian  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2547061Sbrian  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2650479Speter  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2747061Sbrian  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2847061Sbrian  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2947061Sbrian  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3047061Sbrian  POSSIBILITY OF SUCH DAMAGE.
3147061Sbrian
3247061Sbrian******************************************************************************/
3347061Sbrian/*$FreeBSD: stable/11/sys/dev/ixl/if_ixl.c 303967 2016-08-11 19:13:30Z sbruno $*/
3447061Sbrian
3547061Sbrian#include "ixl.h"
3647061Sbrian#include "ixl_pf.h"
3747061Sbrian
3847061Sbrian#ifdef PCI_IOV
3947769Sbrian#include "ixl_pf_iov.h"
4071006Sbrian#endif
4147061Sbrian
4247061Sbrian/*********************************************************************
4347061Sbrian *  Driver version
4447061Sbrian *********************************************************************/
4547061Sbrianchar ixl_driver_version[] = "1.6.6-k";
4647061Sbrian
4747061Sbrian/*********************************************************************
4847061Sbrian *  PCI Device ID Table
4947061Sbrian *
5047061Sbrian *  Used by probe to select devices to load on
5147061Sbrian *  Last field stores an index into ixl_strings
5247061Sbrian *  Last entry must be all 0s
5347061Sbrian *
5447061Sbrian *  { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
5547061Sbrian *********************************************************************/
5647061Sbrian
5747061Sbrianstatic ixl_vendor_info_t ixl_vendor_info_array[] =
5847061Sbrian{
5947061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_XL710, 0, 0, 0},
6047769Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_B, 0, 0, 0},
6147061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_C, 0, 0, 0},
6247061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_A, 0, 0, 0},
6368424Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_B, 0, 0, 0},
6468424Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_C, 0, 0, 0},
6568424Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T, 0, 0, 0},
6668424Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T4, 0, 0, 0},
6768424Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_X722, 0, 0, 0},
6847061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_X722, 0, 0, 0},
6947061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_X722, 0, 0, 0},
7047061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722, 0, 0, 0},
7168424Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722, 0, 0, 0},
7247061Sbrian	{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722, 0, 0, 0},
7347061Sbrian	/* required last entry */
7447061Sbrian	{0, 0, 0, 0, 0}
7547061Sbrian};
76134789Sbrian
7747769Sbrian/*********************************************************************
7847769Sbrian *  Table of branding strings
7947769Sbrian *********************************************************************/
8047769Sbrian
8147769Sbrianstatic char    *ixl_strings[] = {
8247061Sbrian	"Intel(R) Ethernet Connection XL710/X722 Driver"
8347061Sbrian};
8447061Sbrian
8547061Sbrian
8668424Sbrian/*********************************************************************
8747061Sbrian *  Function prototypes
8868424Sbrian *********************************************************************/
8968424Sbrianstatic int      ixl_probe(device_t);
9068424Sbrianstatic int      ixl_attach(device_t);
9168424Sbrianstatic int      ixl_detach(device_t);
9247061Sbrianstatic int      ixl_shutdown(device_t);
9368424Sbrian
9468424Sbrianstatic int	ixl_save_pf_tunables(struct ixl_pf *);
9568424Sbrianstatic int	ixl_attach_get_link_status(struct ixl_pf *);
9668424Sbrian
9768424Sbrian/*********************************************************************
9868424Sbrian *  FreeBSD Device Interface Entry Points
9968424Sbrian *********************************************************************/
10068424Sbrian
10168424Sbrianstatic device_method_t ixl_methods[] = {
10268424Sbrian	/* Device interface */
10368424Sbrian	DEVMETHOD(device_probe, ixl_probe),
10468424Sbrian	DEVMETHOD(device_attach, ixl_attach),
10568424Sbrian	DEVMETHOD(device_detach, ixl_detach),
10668424Sbrian	DEVMETHOD(device_shutdown, ixl_shutdown),
10768424Sbrian#ifdef PCI_IOV
10847061Sbrian	DEVMETHOD(pci_iov_init, ixl_iov_init),
10947061Sbrian	DEVMETHOD(pci_iov_uninit, ixl_iov_uninit),
11047061Sbrian	DEVMETHOD(pci_iov_add_vf, ixl_add_vf),
11147061Sbrian#endif
11247061Sbrian	{0, 0}
11347061Sbrian};
11447061Sbrian
11547061Sbrianstatic driver_t ixl_driver = {
11668424Sbrian	"ixl", ixl_methods, sizeof(struct ixl_pf),
11747061Sbrian};
11847061Sbrian
11947061Sbriandevclass_t ixl_devclass;
12047061SbrianDRIVER_MODULE(ixl, pci, ixl_driver, ixl_devclass, 0, 0);
12147061Sbrian
12247061SbrianMODULE_DEPEND(ixl, pci, 1, 1, 1);
12347061SbrianMODULE_DEPEND(ixl, ether, 1, 1, 1);
12447061Sbrian#ifdef DEV_NETMAP
12547061SbrianMODULE_DEPEND(ixl, netmap, 1, 1, 1);
12647061Sbrian#endif /* DEV_NETMAP */
12747061Sbrian
12847061Sbrian/*
12947061Sbrian** TUNEABLE PARAMETERS:
13047061Sbrian*/
13147061Sbrian
13247061Sbrianstatic SYSCTL_NODE(_hw, OID_AUTO, ixl, CTLFLAG_RD, 0,
13347061Sbrian                   "IXL driver parameters");
13447061Sbrian
13547061Sbrian/*
13647061Sbrian * MSIX should be the default for best performance,
13747061Sbrian * but this allows it to be forced off for testing.
13847061Sbrian */
13947061Sbrianstatic int ixl_enable_msix = 1;
14047769SbrianTUNABLE_INT("hw.ixl.enable_msix", &ixl_enable_msix);
141134789SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, enable_msix, CTLFLAG_RDTUN, &ixl_enable_msix, 0,
14247061Sbrian    "Enable MSI-X interrupts");
14347769Sbrian
14447769Sbrian/*
14547769Sbrian** Number of descriptors per ring:
14647769Sbrian**   - TX and RX are the same size
14747769Sbrian*/
14847769Sbrianstatic int ixl_ring_size = DEFAULT_RING;
14947769SbrianTUNABLE_INT("hw.ixl.ring_size", &ixl_ring_size);
15047769SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, ring_size, CTLFLAG_RDTUN,
15147061Sbrian    &ixl_ring_size, 0, "Descriptor Ring Size");
15247061Sbrian
15347061Sbrian/*
15447061Sbrian** This can be set manually, if left as 0 the
15547061Sbrian** number of queues will be calculated based
15647061Sbrian** on cpus and msix vectors available.
15778410Sbrian*/
15853733Sbrianstatic int ixl_max_queues = 0;
15947061SbrianTUNABLE_INT("hw.ixl.max_queues", &ixl_max_queues);
16047061SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, max_queues, CTLFLAG_RDTUN,
16147061Sbrian    &ixl_max_queues, 0, "Number of Queues");
16247061Sbrian
16349472Sbrianstatic int ixl_enable_tx_fc_filter = 1;
16452942SbrianTUNABLE_INT("hw.ixl.enable_tx_fc_filter",
16593418Sbrian    &ixl_enable_tx_fc_filter);
16647061SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, enable_tx_fc_filter, CTLFLAG_RDTUN,
16747061Sbrian    &ixl_enable_tx_fc_filter, 0,
16847061Sbrian    "Filter out packets with Ethertype 0x8808 from being sent out by non-HW sources");
16947061Sbrian
17047061Sbrianstatic int ixl_core_debug_mask = 0;
17196582SbrianTUNABLE_INT("hw.ixl.core_debug_mask",
17247061Sbrian    &ixl_core_debug_mask);
17347061SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, core_debug_mask, CTLFLAG_RDTUN,
17447061Sbrian    &ixl_core_debug_mask, 0,
17547061Sbrian    "Display debug statements that are printed in non-shared code");
17647061Sbrian
177134789Sbrianstatic int ixl_shared_debug_mask = 0;
17847061SbrianTUNABLE_INT("hw.ixl.shared_debug_mask",
17947061Sbrian    &ixl_shared_debug_mask);
18047461SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, shared_debug_mask, CTLFLAG_RDTUN,
18147061Sbrian    &ixl_shared_debug_mask, 0,
18247769Sbrian    "Display debug statements that are printed in shared code");
18347769Sbrian
18447769Sbrian/*
18547769Sbrian** Controls for Interrupt Throttling
18647769Sbrian**	- true/false for dynamic adjustment
18747769Sbrian** 	- default values for static ITR
18847769Sbrian*/
18947061Sbrianstatic int ixl_dynamic_rx_itr = 1;
19047461SbrianTUNABLE_INT("hw.ixl.dynamic_rx_itr", &ixl_dynamic_rx_itr);
19147061SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, dynamic_rx_itr, CTLFLAG_RDTUN,
19247461Sbrian    &ixl_dynamic_rx_itr, 0, "Dynamic RX Interrupt Rate");
19347461Sbrian
19447461Sbrianstatic int ixl_dynamic_tx_itr = 1;
19547061SbrianTUNABLE_INT("hw.ixl.dynamic_tx_itr", &ixl_dynamic_tx_itr);
19647461SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, dynamic_tx_itr, CTLFLAG_RDTUN,
19747061Sbrian    &ixl_dynamic_tx_itr, 0, "Dynamic TX Interrupt Rate");
19847061Sbrian
19947061Sbrianstatic int ixl_rx_itr = IXL_ITR_8K;
20047061SbrianTUNABLE_INT("hw.ixl.rx_itr", &ixl_rx_itr);
20147061SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, rx_itr, CTLFLAG_RDTUN,
20247061Sbrian    &ixl_rx_itr, 0, "RX Interrupt Rate");
20347061Sbrian
20447061Sbrianstatic int ixl_tx_itr = IXL_ITR_4K;
20547061SbrianTUNABLE_INT("hw.ixl.tx_itr", &ixl_tx_itr);
20647061SbrianSYSCTL_INT(_hw_ixl, OID_AUTO, tx_itr, CTLFLAG_RDTUN,
20747061Sbrian    &ixl_tx_itr, 0, "TX Interrupt Rate");
20847061Sbrian
20947061Sbrian#ifdef DEV_NETMAP
21047061Sbrian#define NETMAP_IXL_MAIN /* only bring in one part of the netmap code */
21147061Sbrian#include <dev/netmap/if_ixl_netmap.h>
21247061Sbrian#endif /* DEV_NETMAP */
21347061Sbrian
21447061Sbrian/*********************************************************************
21547061Sbrian *  Device identification routine
21647061Sbrian *
21747061Sbrian *  ixl_probe determines if the driver should be loaded on
21847061Sbrian *  the hardware based on PCI vendor/device id of the device.
21947061Sbrian *
22047061Sbrian *  return BUS_PROBE_DEFAULT on success, positive on failure
22147061Sbrian *********************************************************************/
22247061Sbrian
22347061Sbrianstatic int
22447061Sbrianixl_probe(device_t dev)
22547061Sbrian{
22647061Sbrian	ixl_vendor_info_t *ent;
22747061Sbrian
22847061Sbrian	u16	pci_vendor_id, pci_device_id;
22947061Sbrian	u16	pci_subvendor_id, pci_subdevice_id;
23047061Sbrian	char	device_name[256];
23147061Sbrian
23247061Sbrian#if 0
23389422Sbrian	INIT_DEBUGOUT("ixl_probe: begin");
23447061Sbrian#endif
23547061Sbrian	pci_vendor_id = pci_get_vendor(dev);
23647061Sbrian	if (pci_vendor_id != I40E_INTEL_VENDOR_ID)
23747061Sbrian		return (ENXIO);
23868424Sbrian
23947061Sbrian	pci_device_id = pci_get_device(dev);
24047061Sbrian	pci_subvendor_id = pci_get_subvendor(dev);
24147061Sbrian	pci_subdevice_id = pci_get_subdevice(dev);
24247061Sbrian
24347061Sbrian	ent = ixl_vendor_info_array;
24447061Sbrian	while (ent->vendor_id != 0) {
24547061Sbrian		if ((pci_vendor_id == ent->vendor_id) &&
24647061Sbrian		    (pci_device_id == ent->device_id) &&
24747061Sbrian
24847061Sbrian		    ((pci_subvendor_id == ent->subvendor_id) ||
24947061Sbrian		     (ent->subvendor_id == 0)) &&
25047061Sbrian
25147061Sbrian		    ((pci_subdevice_id == ent->subdevice_id) ||
25247061Sbrian		     (ent->subdevice_id == 0))) {
25347061Sbrian			sprintf(device_name, "%s, Version - %s",
25447061Sbrian				ixl_strings[ent->index],
25547061Sbrian				ixl_driver_version);
25647061Sbrian			device_set_desc_copy(dev, device_name);
25747061Sbrian			return (BUS_PROBE_DEFAULT);
25847061Sbrian		}
25947061Sbrian		ent++;
26052942Sbrian	}
26147061Sbrian	return (ENXIO);
26247061Sbrian}
26347061Sbrian
26447061Sbrianstatic int
26547061Sbrianixl_attach_get_link_status(struct ixl_pf *pf)
26647061Sbrian{
26747061Sbrian	struct i40e_hw *hw = &pf->hw;
26847061Sbrian	device_t dev = pf->dev;
26952942Sbrian	int error = 0;
27052942Sbrian
27147061Sbrian	if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
27252942Sbrian	    (hw->aq.fw_maj_ver < 4)) {
27347061Sbrian		i40e_msec_delay(75);
27447061Sbrian		error = i40e_aq_set_link_restart_an(hw, TRUE, NULL);
27547061Sbrian		if (error) {
27647061Sbrian			device_printf(dev, "link restart failed, aq_err=%d\n",
27747061Sbrian			    pf->hw.aq.asq_last_status);
27847061Sbrian			return error;
27947061Sbrian		}
28047061Sbrian	}
28147061Sbrian
28247061Sbrian	/* Determine link state */
28371006Sbrian	hw->phy.get_link_info = TRUE;
28447061Sbrian	i40e_get_link_status(hw, &pf->link_up);
28571006Sbrian	return (0);
28671006Sbrian}
28771006Sbrian
28871006Sbrian/*
28971006Sbrian * Sanity check and save off tunable values.
29071006Sbrian */
29171006Sbrianstatic int
29271006Sbrianixl_save_pf_tunables(struct ixl_pf *pf)
29347061Sbrian{
29447061Sbrian	device_t dev = pf->dev;
29547061Sbrian
29671006Sbrian	/* Save tunable information */
29789720Sbrian	pf->enable_msix = ixl_enable_msix;
29889720Sbrian	pf->max_queues = ixl_max_queues;
29989720Sbrian	pf->ringsz = ixl_ring_size;
30071006Sbrian	pf->enable_tx_fc_filter = ixl_enable_tx_fc_filter;
30171006Sbrian	pf->dynamic_rx_itr = ixl_dynamic_rx_itr;
30271006Sbrian	pf->dynamic_tx_itr = ixl_dynamic_tx_itr;
30371006Sbrian	pf->tx_itr = ixl_tx_itr;
30471006Sbrian	pf->rx_itr = ixl_rx_itr;
30547061Sbrian	pf->dbg_mask = ixl_core_debug_mask;
30689720Sbrian	pf->hw.debug_mask = ixl_shared_debug_mask;
30789720Sbrian
30889720Sbrian	if (ixl_ring_size < IXL_MIN_RING
30989720Sbrian	     || ixl_ring_size > IXL_MAX_RING
31089720Sbrian	     || ixl_ring_size % IXL_RING_INCREMENT != 0) {
31189720Sbrian		device_printf(dev, "Invalid ring_size value of %d set!\n",
31289720Sbrian		    ixl_ring_size);
31347061Sbrian		device_printf(dev, "ring_size must be between %d and %d, "
31489720Sbrian		    "inclusive, and must be a multiple of %d\n",
31571006Sbrian		    IXL_MIN_RING, IXL_MAX_RING, IXL_RING_INCREMENT);
31689720Sbrian		return (EINVAL);
31789720Sbrian	}
31889720Sbrian
31989720Sbrian	return (0);
32089720Sbrian}
32171006Sbrian
32247061Sbrian/*********************************************************************
32347061Sbrian *  Device initialization routine
32447061Sbrian *
32547061Sbrian *  The attach entry point is called when the driver is being loaded.
32647061Sbrian *  This routine identifies the type of hardware, allocates all resources
32747061Sbrian *  and initializes the hardware.
32847461Sbrian *
32953733Sbrian *  return 0 on success, positive on failure
33053733Sbrian *********************************************************************/
33147061Sbrian
33247061Sbrianstatic int
33347061Sbrianixl_attach(device_t dev)
33447061Sbrian{
33547061Sbrian	struct ixl_pf	*pf;
336	struct i40e_hw	*hw;
337	struct ixl_vsi  *vsi;
338	enum i40e_status_code status;
339	int             error = 0;
340
341	INIT_DEBUGOUT("ixl_attach: begin");
342
343	/* Allocate, clear, and link in our primary soft structure */
344	pf = device_get_softc(dev);
345	pf->dev = pf->osdep.dev = dev;
346	hw = &pf->hw;
347
348	/*
349	** Note this assumes we have a single embedded VSI,
350	** this could be enhanced later to allocate multiple
351	*/
352	vsi = &pf->vsi;
353	vsi->dev = pf->dev;
354
355	/* Save tunable values */
356	error = ixl_save_pf_tunables(pf);
357	if (error)
358		return (error);
359
360	/* Core Lock Init*/
361	IXL_PF_LOCK_INIT(pf, device_get_nameunit(dev));
362
363	/* Set up the timer callout */
364	callout_init_mtx(&pf->timer, &pf->pf_mtx, 0);
365
366	/* Do PCI setup - map BAR0, etc */
367	if (ixl_allocate_pci_resources(pf)) {
368		device_printf(dev, "Allocation of PCI resources failed\n");
369		error = ENXIO;
370		goto err_out;
371	}
372
373	/* Establish a clean starting point */
374	i40e_clear_hw(hw);
375	status = i40e_pf_reset(hw);
376	if (status) {
377		device_printf(dev, "PF reset failure %s\n",
378		    i40e_stat_str(hw, status));
379		error = EIO;
380		goto err_out;
381	}
382
383	/* Initialize the shared code */
384	status = i40e_init_shared_code(hw);
385	if (status) {
386		device_printf(dev, "Unable to initialize shared code, error %s\n",
387		    i40e_stat_str(hw, status));
388		error = EIO;
389		goto err_out;
390	}
391
392	/*
393	 * Allocate interrupts and figure out number of queues to use
394	 * for PF interface
395	 */
396	pf->msix = ixl_init_msix(pf);
397
398	/* Set up the admin queue */
399	hw->aq.num_arq_entries = IXL_AQ_LEN;
400	hw->aq.num_asq_entries = IXL_AQ_LEN;
401	hw->aq.arq_buf_size = IXL_AQ_BUF_SZ;
402	hw->aq.asq_buf_size = IXL_AQ_BUF_SZ;
403
404	status = i40e_init_adminq(hw);
405	if (status != 0 && status != I40E_ERR_FIRMWARE_API_VERSION) {
406		device_printf(dev, "Unable to initialize Admin Queue, error %s\n",
407		    i40e_stat_str(hw, status));
408		error = EIO;
409		goto err_out;
410	}
411	ixl_print_nvm_version(pf);
412
413	if (status == I40E_ERR_FIRMWARE_API_VERSION) {
414		device_printf(dev, "The driver for the device stopped "
415		    "because the NVM image is newer than expected.\n"
416		    "You must install the most recent version of "
417		    "the network driver.\n");
418		error = EIO;
419		goto err_out;
420	}
421
422        if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
423	    hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR)
424		device_printf(dev, "The driver for the device detected "
425		    "a newer version of the NVM image than expected.\n"
426		    "Please install the most recent version of the network driver.\n");
427	else if (hw->aq.api_maj_ver < I40E_FW_API_VERSION_MAJOR ||
428	    hw->aq.api_min_ver < (I40E_FW_API_VERSION_MINOR - 1))
429		device_printf(dev, "The driver for the device detected "
430		    "an older version of the NVM image than expected.\n"
431		    "Please update the NVM image.\n");
432
433	/* Clear PXE mode */
434	i40e_clear_pxe_mode(hw);
435
436	/* Get capabilities from the device */
437	error = ixl_get_hw_capabilities(pf);
438	if (error) {
439		device_printf(dev, "HW capabilities failure!\n");
440		goto err_get_cap;
441	}
442
443	/* Set up host memory cache */
444	status = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp,
445	    hw->func_caps.num_rx_qp, 0, 0);
446	if (status) {
447		device_printf(dev, "init_lan_hmc failed: %s\n",
448		    i40e_stat_str(hw, status));
449		goto err_get_cap;
450	}
451
452	status = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY);
453	if (status) {
454		device_printf(dev, "configure_lan_hmc failed: %s\n",
455		    i40e_stat_str(hw, status));
456		goto err_mac_hmc;
457	}
458
459	/* Init queue allocation manager */
460	error = ixl_pf_qmgr_init(&pf->qmgr, hw->func_caps.num_tx_qp);
461	if (error) {
462		device_printf(dev, "Failed to init queue manager for PF queues, error %d\n",
463		    error);
464		goto err_mac_hmc;
465	}
466	/* reserve a contiguous allocation for the PF's VSI */
467	error = ixl_pf_qmgr_alloc_contiguous(&pf->qmgr, vsi->num_queues, &pf->qtag);
468	if (error) {
469		device_printf(dev, "Failed to reserve queues for PF LAN VSI, error %d\n",
470		    error);
471		goto err_mac_hmc;
472	}
473	device_printf(dev, "Allocating %d queues for PF LAN VSI; %d queues active\n",
474	    pf->qtag.num_allocated, pf->qtag.num_active);
475
476	/* Disable LLDP from the firmware for certain NVM versions */
477	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
478	    (pf->hw.aq.fw_maj_ver < 4))
479		i40e_aq_stop_lldp(hw, TRUE, NULL);
480
481	/* Get MAC addresses from hardware */
482	i40e_get_mac_addr(hw, hw->mac.addr);
483	error = i40e_validate_mac_addr(hw->mac.addr);
484	if (error) {
485		device_printf(dev, "validate_mac_addr failed: %d\n", error);
486		goto err_mac_hmc;
487	}
488	bcopy(hw->mac.addr, hw->mac.perm_addr, ETHER_ADDR_LEN);
489	i40e_get_port_mac_addr(hw, hw->mac.port_addr);
490
491	/* Initialize mac filter list for VSI */
492	SLIST_INIT(&vsi->ftl);
493
494	/* Set up SW VSI and allocate queue memory and rings */
495	if (ixl_setup_stations(pf)) {
496		device_printf(dev, "setup stations failed!\n");
497		error = ENOMEM;
498		goto err_mac_hmc;
499	}
500
501	/* Setup OS network interface / ifnet */
502	if (ixl_setup_interface(dev, vsi)) {
503		device_printf(dev, "interface setup failed!\n");
504		error = EIO;
505		goto err_late;
506	}
507
508	/* Determine link state */
509	if (ixl_attach_get_link_status(pf)) {
510		error = EINVAL;
511		goto err_late;
512	}
513
514	error = ixl_switch_config(pf);
515	if (error) {
516		device_printf(dev, "Initial ixl_switch_config() failed: %d\n",
517		     error);
518		goto err_late;
519	}
520
521	/* Limit PHY interrupts to link, autoneg, and modules failure */
522	status = i40e_aq_set_phy_int_mask(hw, IXL_DEFAULT_PHY_INT_MASK,
523	    NULL);
524        if (status) {
525		device_printf(dev, "i40e_aq_set_phy_mask() failed: err %s,"
526		    " aq_err %s\n", i40e_stat_str(hw, status),
527		    i40e_aq_str(hw, hw->aq.asq_last_status));
528		goto err_late;
529	}
530
531	/* Get the bus configuration and set the shared code's config */
532	ixl_get_bus_info(hw, dev);
533
534	/*
535	 * In MSI-X mode, initialize the Admin Queue interrupt,
536	 * so userland tools can communicate with the adapter regardless of
537	 * the ifnet interface's status.
538	 */
539	if (pf->msix > 1) {
540		error = ixl_setup_adminq_msix(pf);
541		if (error) {
542			device_printf(dev, "ixl_setup_adminq_msix error: %d\n",
543			    error);
544			goto err_late;
545		}
546		error = ixl_setup_adminq_tq(pf);
547		if (error) {
548			device_printf(dev, "ixl_setup_adminq_tq error: %d\n",
549			    error);
550			goto err_late;
551		}
552		ixl_configure_intr0_msix(pf);
553		ixl_enable_adminq(hw);
554	}
555
556	/* Initialize statistics & add sysctls */
557	ixl_add_device_sysctls(pf);
558
559	ixl_pf_reset_stats(pf);
560	ixl_update_stats_counters(pf);
561	ixl_add_hw_stats(pf);
562
563	/* Register for VLAN events */
564	vsi->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
565	    ixl_register_vlan, vsi, EVENTHANDLER_PRI_FIRST);
566	vsi->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
567	    ixl_unregister_vlan, vsi, EVENTHANDLER_PRI_FIRST);
568
569#ifdef PCI_IOV
570	ixl_initialize_sriov(pf);
571#endif
572
573#ifdef DEV_NETMAP
574	ixl_netmap_attach(vsi);
575#endif /* DEV_NETMAP */
576	INIT_DEBUGOUT("ixl_attach: end");
577	return (0);
578
579err_late:
580	if (vsi->ifp != NULL) {
581		ether_ifdetach(vsi->ifp);
582		if_free(vsi->ifp);
583	}
584err_mac_hmc:
585	i40e_shutdown_lan_hmc(hw);
586err_get_cap:
587	i40e_shutdown_adminq(hw);
588err_out:
589	ixl_free_pci_resources(pf);
590	ixl_free_vsi(vsi);
591	IXL_PF_LOCK_DESTROY(pf);
592	return (error);
593}
594
595/*********************************************************************
596 *  Device removal routine
597 *
598 *  The detach entry point is called when the driver is being removed.
599 *  This routine stops the adapter and deallocates all the resources
600 *  that were allocated for driver operation.
601 *
602 *  return 0 on success, positive on failure
603 *********************************************************************/
604
605static int
606ixl_detach(device_t dev)
607{
608	struct ixl_pf		*pf = device_get_softc(dev);
609	struct i40e_hw		*hw = &pf->hw;
610	struct ixl_vsi		*vsi = &pf->vsi;
611	enum i40e_status_code	status;
612#ifdef PCI_IOV
613	int			error;
614#endif
615
616	INIT_DEBUGOUT("ixl_detach: begin");
617
618	/* Make sure VLANS are not using driver */
619	if (vsi->ifp->if_vlantrunk != NULL) {
620		device_printf(dev, "Vlan in use, detach first\n");
621		return (EBUSY);
622	}
623
624#ifdef PCI_IOV
625	error = pci_iov_detach(dev);
626	if (error != 0) {
627		device_printf(dev, "SR-IOV in use; detach first.\n");
628		return (error);
629	}
630#endif
631
632	ether_ifdetach(vsi->ifp);
633	if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING)
634		ixl_stop(pf);
635
636	ixl_free_queue_tqs(vsi);
637
638	/* Shutdown LAN HMC */
639	status = i40e_shutdown_lan_hmc(hw);
640	if (status)
641		device_printf(dev,
642		    "Shutdown LAN HMC failed with code %d\n", status);
643
644	/* Shutdown admin queue */
645	ixl_disable_adminq(hw);
646	ixl_free_adminq_tq(pf);
647	ixl_teardown_adminq_msix(pf);
648	status = i40e_shutdown_adminq(hw);
649	if (status)
650		device_printf(dev,
651		    "Shutdown Admin queue failed with code %d\n", status);
652
653	/* Unregister VLAN events */
654	if (vsi->vlan_attach != NULL)
655		EVENTHANDLER_DEREGISTER(vlan_config, vsi->vlan_attach);
656	if (vsi->vlan_detach != NULL)
657		EVENTHANDLER_DEREGISTER(vlan_unconfig, vsi->vlan_detach);
658
659	callout_drain(&pf->timer);
660#ifdef DEV_NETMAP
661	netmap_detach(vsi->ifp);
662#endif /* DEV_NETMAP */
663	ixl_pf_qmgr_destroy(&pf->qmgr);
664	ixl_free_pci_resources(pf);
665	bus_generic_detach(dev);
666	if_free(vsi->ifp);
667	ixl_free_vsi(vsi);
668	IXL_PF_LOCK_DESTROY(pf);
669	return (0);
670}
671
672/*********************************************************************
673 *
674 *  Shutdown entry point
675 *
676 **********************************************************************/
677
678static int
679ixl_shutdown(device_t dev)
680{
681	struct ixl_pf *pf = device_get_softc(dev);
682	ixl_stop(pf);
683	return (0);
684}
685
686