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