Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixl/if_ixl.c
/****************************************************************************** | /****************************************************************************** | ||||
Copyright (c) 2013-2017, Intel Corporation | Copyright (c) 2013-2019, Intel Corporation | ||||
All rights reserved. | All rights reserved. | ||||
Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | ||||
modification, are permitted provided that the following conditions are met: | modification, are permitted provided that the following conditions are met: | ||||
1. Redistributions of source code must retain the above copyright notice, | 1. Redistributions of source code must retain the above copyright notice, | ||||
this list of conditions and the following disclaimer. | this list of conditions and the following disclaimer. | ||||
2. Redistributions in binary form must reproduce the above copyright | 2. Redistributions in binary form must reproduce the above copyright | ||||
notice, this list of conditions and the following disclaimer in the | notice, this list of conditions and the following disclaimer in the | ||||
Show All 29 Lines | |||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
#include "ixl_pf_iov.h" | #include "ixl_pf_iov.h" | ||||
#endif | #endif | ||||
/********************************************************************* | /********************************************************************* | ||||
* Driver version | * Driver version | ||||
*********************************************************************/ | *********************************************************************/ | ||||
#define IXL_DRIVER_VERSION_MAJOR 1 | #define IXL_DRIVER_VERSION_MAJOR 1 | ||||
#define IXL_DRIVER_VERSION_MINOR 9 | #define IXL_DRIVER_VERSION_MINOR 11 | ||||
#define IXL_DRIVER_VERSION_BUILD 9 | #define IXL_DRIVER_VERSION_BUILD 9 | ||||
char ixl_driver_version[] = __XSTRING(IXL_DRIVER_VERSION_MAJOR) "." | char ixl_driver_version[] = __XSTRING(IXL_DRIVER_VERSION_MAJOR) "." | ||||
__XSTRING(IXL_DRIVER_VERSION_MINOR) "." | __XSTRING(IXL_DRIVER_VERSION_MINOR) "." | ||||
__XSTRING(IXL_DRIVER_VERSION_BUILD) "-k"; | __XSTRING(IXL_DRIVER_VERSION_BUILD) "-k"; | ||||
/********************************************************************* | /********************************************************************* | ||||
* PCI Device ID Table | * PCI Device ID Table | ||||
Show All 18 Lines | static ixl_vendor_info_t ixl_vendor_info_array[] = | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_X722, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_KX_X722, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_X722, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_QSFP_X722, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_X722, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_X722, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_1G_BASE_T_X722, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_X722, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_B, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_B, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_SFP28, 0, 0, 0}, | {I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_SFP28, 0, 0, 0}, | ||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC, 0, 0, 0}, | |||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_SFP, 0, 0, 0}, | |||||
{I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_B, 0, 0, 0}, | |||||
/* required last entry */ | /* required last entry */ | ||||
{0, 0, 0, 0, 0} | {0, 0, 0, 0, 0} | ||||
}; | }; | ||||
/********************************************************************* | /********************************************************************* | ||||
* Table of branding strings | * Table of branding strings | ||||
*********************************************************************/ | *********************************************************************/ | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static int ixl_enable_tx_fc_filter = 1; | static int ixl_enable_tx_fc_filter = 1; | ||||
TUNABLE_INT("hw.ixl.enable_tx_fc_filter", | TUNABLE_INT("hw.ixl.enable_tx_fc_filter", | ||||
&ixl_enable_tx_fc_filter); | &ixl_enable_tx_fc_filter); | ||||
SYSCTL_INT(_hw_ixl, OID_AUTO, enable_tx_fc_filter, CTLFLAG_RDTUN, | SYSCTL_INT(_hw_ixl, OID_AUTO, enable_tx_fc_filter, CTLFLAG_RDTUN, | ||||
&ixl_enable_tx_fc_filter, 0, | &ixl_enable_tx_fc_filter, 0, | ||||
"Filter out packets with Ethertype 0x8808 from being sent out by non-HW sources"); | "Filter out packets with Ethertype 0x8808 from being sent out by non-HW sources"); | ||||
static int ixl_i2c_access_method = 0; | |||||
TUNABLE_INT("hw.ixl.i2c_access_method", | |||||
&ixl_i2c_access_method); | |||||
SYSCTL_INT(_hw_ixl, OID_AUTO, i2c_access_method, CTLFLAG_RDTUN, | |||||
&ixl_i2c_access_method, 0, | |||||
IXL_SYSCTL_HELP_I2C_METHOD); | |||||
/* | /* | ||||
* Different method for processing TX descriptor | * Different method for processing TX descriptor | ||||
* completion. | * completion. | ||||
*/ | */ | ||||
static int ixl_enable_head_writeback = 1; | static int ixl_enable_head_writeback = 1; | ||||
TUNABLE_INT("hw.ixl.enable_head_writeback", | TUNABLE_INT("hw.ixl.enable_head_writeback", | ||||
&ixl_enable_head_writeback); | &ixl_enable_head_writeback); | ||||
SYSCTL_INT(_hw_ixl, OID_AUTO, enable_head_writeback, CTLFLAG_RDTUN, | SYSCTL_INT(_hw_ixl, OID_AUTO, enable_head_writeback, CTLFLAG_RDTUN, | ||||
Show All 9 Lines | |||||
static int ixl_shared_debug_mask = 0; | static int ixl_shared_debug_mask = 0; | ||||
TUNABLE_INT("hw.ixl.shared_debug_mask", | TUNABLE_INT("hw.ixl.shared_debug_mask", | ||||
&ixl_shared_debug_mask); | &ixl_shared_debug_mask); | ||||
SYSCTL_INT(_hw_ixl, OID_AUTO, shared_debug_mask, CTLFLAG_RDTUN, | SYSCTL_INT(_hw_ixl, OID_AUTO, shared_debug_mask, CTLFLAG_RDTUN, | ||||
&ixl_shared_debug_mask, 0, | &ixl_shared_debug_mask, 0, | ||||
"Display debug statements that are printed in shared code"); | "Display debug statements that are printed in shared code"); | ||||
/* | /* | ||||
** Controls for Interrupt Throttling | ** Controls for Interrupt Throttling | ||||
** - true/false for dynamic adjustment | ** - true/false for dynamic adjustment | ||||
** - default values for static ITR | ** - default values for static ITR | ||||
*/ | */ | ||||
static int ixl_dynamic_rx_itr = 1; | static int ixl_dynamic_rx_itr = 1; | ||||
TUNABLE_INT("hw.ixl.dynamic_rx_itr", &ixl_dynamic_rx_itr); | TUNABLE_INT("hw.ixl.dynamic_rx_itr", &ixl_dynamic_rx_itr); | ||||
SYSCTL_INT(_hw_ixl, OID_AUTO, dynamic_rx_itr, CTLFLAG_RDTUN, | SYSCTL_INT(_hw_ixl, OID_AUTO, dynamic_rx_itr, CTLFLAG_RDTUN, | ||||
▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | |||||
#ifdef DEV_NETMAP | #ifdef DEV_NETMAP | ||||
if (ixl_enable_head_writeback == 0) | if (ixl_enable_head_writeback == 0) | ||||
device_printf(dev, "Head writeback mode cannot be disabled " | device_printf(dev, "Head writeback mode cannot be disabled " | ||||
"when netmap is enabled\n"); | "when netmap is enabled\n"); | ||||
pf->vsi.enable_head_writeback = 1; | pf->vsi.enable_head_writeback = 1; | ||||
#else | #else | ||||
pf->vsi.enable_head_writeback = !!(ixl_enable_head_writeback); | pf->vsi.enable_head_writeback = !!(ixl_enable_head_writeback); | ||||
#endif | #endif | ||||
ixl_vsi_setup_rings_size(&pf->vsi, ixl_tx_ring_size, ixl_rx_ring_size); | ixl_vsi_setup_rings_size(&pf->vsi, ixl_tx_ring_size, ixl_rx_ring_size); | ||||
if (ixl_i2c_access_method > IXL_I2C_ACCESS_METHOD_TYPE_LENGTH - 1 | |||||
|| ixl_i2c_access_method < IXL_I2C_ACCESS_METHOD_BEST_AVAILABLE) | |||||
pf->i2c_access_method = IXL_I2C_ACCESS_METHOD_BEST_AVAILABLE; | |||||
else | |||||
pf->i2c_access_method = | |||||
(enum ixl_i2c_access_method_t)ixl_i2c_access_method; | |||||
if (ixl_tx_itr < 0 || ixl_tx_itr > IXL_MAX_ITR) { | if (ixl_tx_itr < 0 || ixl_tx_itr > IXL_MAX_ITR) { | ||||
device_printf(dev, "Invalid tx_itr value of %d set!\n", | device_printf(dev, "Invalid tx_itr value of %d set!\n", | ||||
ixl_tx_itr); | ixl_tx_itr); | ||||
device_printf(dev, "tx_itr must be between %d and %d, " | device_printf(dev, "tx_itr must be between %d and %d, " | ||||
"inclusive\n", | "inclusive\n", | ||||
0, IXL_MAX_ITR); | 0, IXL_MAX_ITR); | ||||
device_printf(dev, "Using default value of %d instead\n", | device_printf(dev, "Using default value of %d instead\n", | ||||
IXL_ITR_4K); | IXL_ITR_4K); | ||||
Show All 11 Lines | device_printf(dev, "Using default value of %d instead\n", | ||||
IXL_ITR_8K); | IXL_ITR_8K); | ||||
pf->rx_itr = IXL_ITR_8K; | pf->rx_itr = IXL_ITR_8K; | ||||
} else | } else | ||||
pf->rx_itr = ixl_rx_itr; | pf->rx_itr = ixl_rx_itr; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | |||||
ixl_attach_recovery_mode(struct ixl_pf *pf) | |||||
{ | |||||
struct ixl_vsi *vsi = &pf->vsi; | |||||
struct i40e_hw *hw = &pf->hw; | |||||
device_t dev = pf->dev; | |||||
int error = 0; | |||||
device_printf(dev, "Firmware recovery mode detected. Limiting functionality. Refer to Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n"); | |||||
atomic_set_int(&pf->state, IXL_PF_STATE_RECOVERY_MODE); | |||||
i40e_get_mac_addr(hw, hw->mac.addr); | |||||
pf->msix = ixl_init_msix(pf); | |||||
ixl_setup_stations(pf); | |||||
ixl_setup_interface(pf->dev, vsi); | |||||
if (pf->msix > 1) { | |||||
error = ixl_setup_adminq_msix(pf); | |||||
if (error) { | |||||
device_printf(dev, "ixl_setup_adminq_msix() error: %d\n", | |||||
error); | |||||
goto recovery_err_late; | |||||
} | |||||
error = ixl_setup_adminq_tq(pf); | |||||
if (error) { | |||||
device_printf(dev, "ixl_setup_adminq_tq() error: %d\n", | |||||
error); | |||||
goto recovery_err_late; | |||||
} | |||||
ixl_configure_intr0_msix(pf); | |||||
ixl_enable_intr0(hw); | |||||
} else { | |||||
error = ixl_setup_legacy(pf); | |||||
error = ixl_setup_adminq_tq(pf); | |||||
if (error) { | |||||
device_printf(dev, "ixl_setup_adminq_tq() error: %d\n", | |||||
error); | |||||
goto recovery_err_late; | |||||
} | |||||
} | |||||
/* Get the bus configuration and set the shared code's config */ | |||||
ixl_get_bus_info(pf); | |||||
/* Initialize statistics & add sysctls */ | |||||
ixl_add_device_sysctls(pf); | |||||
/* Start the local timer */ | |||||
IXL_PF_LOCK(pf); | |||||
callout_reset(&pf->timer, hz, ixl_local_timer, pf); | |||||
IXL_PF_UNLOCK(pf); | |||||
recovery_err_late: | |||||
return (error); | |||||
} | |||||
/********************************************************************* | /********************************************************************* | ||||
* Device initialization routine | * Device initialization routine | ||||
* | * | ||||
* The attach entry point is called when the driver is being loaded. | * The attach entry point is called when the driver is being loaded. | ||||
* This routine identifies the type of hardware, allocates all resources | * This routine identifies the type of hardware, allocates all resources | ||||
* and initializes the hardware. | * and initializes the hardware. | ||||
* | * | ||||
* return 0 on success, positive on failure | * return 0 on success, positive on failure | ||||
*********************************************************************/ | *********************************************************************/ | ||||
static int | static int | ||||
ixl_attach(device_t dev) | ixl_attach(device_t dev) | ||||
{ | { | ||||
struct ixl_pf *pf; | struct ixl_pf *pf; | ||||
struct i40e_hw *hw; | struct i40e_hw *hw; | ||||
struct ixl_vsi *vsi; | struct ixl_vsi *vsi; | ||||
enum i40e_get_fw_lldp_status_resp lldp_status; | |||||
enum i40e_status_code status; | enum i40e_status_code status; | ||||
int error = 0; | int error = 0; | ||||
INIT_DEBUGOUT("ixl_attach: begin"); | INIT_DEBUGOUT("ixl_attach: begin"); | ||||
/* Allocate, clear, and link in our primary soft structure */ | /* Allocate, clear, and link in our primary soft structure */ | ||||
pf = device_get_softc(dev); | pf = device_get_softc(dev); | ||||
pf->dev = pf->osdep.dev = dev; | pf->dev = pf->osdep.dev = dev; | ||||
Show All 15 Lines | ixl_attach(device_t dev) | ||||
/* Core Lock Init*/ | /* Core Lock Init*/ | ||||
IXL_PF_LOCK_INIT(pf, device_get_nameunit(dev)); | IXL_PF_LOCK_INIT(pf, device_get_nameunit(dev)); | ||||
/* Set up the timer callout */ | /* Set up the timer callout */ | ||||
callout_init_mtx(&pf->timer, &pf->pf_mtx, 0); | callout_init_mtx(&pf->timer, &pf->pf_mtx, 0); | ||||
/* Do PCI setup - map BAR0, etc */ | /* Do PCI setup - map BAR0, etc */ | ||||
if (ixl_allocate_pci_resources(pf)) { | if (ixl_allocate_pci_resources(pf)) { | ||||
device_printf(dev, "Allocation of PCI resources failed\n"); | |||||
error = ENXIO; | error = ENXIO; | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
/* Establish a clean starting point */ | /* Establish a clean starting point */ | ||||
i40e_clear_hw(hw); | i40e_clear_hw(hw); | ||||
/* Don't try to reset device if it's in recovery mode */ | |||||
if (!ixl_fw_recovery_mode(pf)) { | |||||
status = i40e_pf_reset(hw); | status = i40e_pf_reset(hw); | ||||
if (status) { | if (status) { | ||||
device_printf(dev, "PF reset failure %s\n", | device_printf(dev, "PF reset failure %s\n", | ||||
i40e_stat_str(hw, status)); | i40e_stat_str(hw, status)); | ||||
error = EIO; | error = EIO; | ||||
goto err_out; | goto err_out; | ||||
} | } | ||||
} | |||||
/* Initialize the shared code */ | /* Initialize the shared code */ | ||||
status = i40e_init_shared_code(hw); | status = i40e_init_shared_code(hw); | ||||
if (status) { | if (status) { | ||||
device_printf(dev, "Unable to initialize shared code, error %s\n", | device_printf(dev, "Unable to initialize shared code, error %s\n", | ||||
i40e_stat_str(hw, status)); | i40e_stat_str(hw, status)); | ||||
error = EIO; | error = EIO; | ||||
goto err_out; | goto err_out; | ||||
Show All 30 Lines | if (status == I40E_ERR_FIRMWARE_API_VERSION) { | ||||
device_printf(dev, "Please install the most recent version " | device_printf(dev, "Please install the most recent version " | ||||
"of the network driver.\n"); | "of the network driver.\n"); | ||||
} else if (hw->aq.api_maj_ver == 1 && hw->aq.api_min_ver < 4) { | } else if (hw->aq.api_maj_ver == 1 && hw->aq.api_min_ver < 4) { | ||||
device_printf(dev, "The driver for the device detected " | device_printf(dev, "The driver for the device detected " | ||||
"an older version of the NVM image than expected.\n"); | "an older version of the NVM image than expected.\n"); | ||||
device_printf(dev, "Please update the NVM image.\n"); | device_printf(dev, "Please update the NVM image.\n"); | ||||
} | } | ||||
if (ixl_fw_recovery_mode(pf)) | |||||
return ixl_attach_recovery_mode(pf); | |||||
/* Clear PXE mode */ | /* Clear PXE mode */ | ||||
i40e_clear_pxe_mode(hw); | i40e_clear_pxe_mode(hw); | ||||
/* Get capabilities from the device */ | /* Get capabilities from the device */ | ||||
error = ixl_get_hw_capabilities(pf); | error = ixl_get_hw_capabilities(pf); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "HW capabilities failure!\n"); | device_printf(dev, "HW capabilities failure!\n"); | ||||
goto err_get_cap; | goto err_get_cap; | ||||
Show All 33 Lines | ixl_attach(device_t dev) | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "Failed to reserve queues for PF LAN VSI, error %d\n", | device_printf(dev, "Failed to reserve queues for PF LAN VSI, error %d\n", | ||||
error); | error); | ||||
goto err_mac_hmc; | goto err_mac_hmc; | ||||
} | } | ||||
device_printf(dev, "Allocating %d queues for PF LAN VSI; %d queues active\n", | device_printf(dev, "Allocating %d queues for PF LAN VSI; %d queues active\n", | ||||
pf->qtag.num_allocated, pf->qtag.num_active); | pf->qtag.num_allocated, pf->qtag.num_active); | ||||
/* Disable LLDP from the firmware for certain NVM versions */ | /* Disable LLDP from the firmware on XL710 for certain NVM versions */ | ||||
if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) || | if (hw->mac.type == I40E_MAC_XL710 && | ||||
(pf->hw.aq.fw_maj_ver < 4)) { | (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 3)) || | ||||
i40e_aq_stop_lldp(hw, TRUE, NULL); | (hw->aq.fw_maj_ver < 4))) { | ||||
i40e_aq_stop_lldp(hw, true, false, NULL); | |||||
pf->state |= IXL_PF_STATE_FW_LLDP_DISABLED; | pf->state |= IXL_PF_STATE_FW_LLDP_DISABLED; | ||||
} | } | ||||
/* Try enabling Energy Efficient Ethernet (EEE) mode */ | |||||
if(i40e_enable_eee(hw, true) == I40E_SUCCESS) | |||||
atomic_set_int(&pf->state, IXL_PF_STATE_EEE_ENABLED); | |||||
else | |||||
atomic_clear_int(&pf->state, IXL_PF_STATE_EEE_ENABLED); | |||||
/* Get MAC addresses from hardware */ | /* Get MAC addresses from hardware */ | ||||
i40e_get_mac_addr(hw, hw->mac.addr); | i40e_get_mac_addr(hw, hw->mac.addr); | ||||
error = i40e_validate_mac_addr(hw->mac.addr); | error = i40e_validate_mac_addr(hw->mac.addr); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "validate_mac_addr failed: %d\n", error); | device_printf(dev, "validate_mac_addr failed: %d\n", error); | ||||
goto err_mac_hmc; | goto err_mac_hmc; | ||||
} | } | ||||
bcopy(hw->mac.addr, hw->mac.perm_addr, ETHER_ADDR_LEN); | bcopy(hw->mac.addr, hw->mac.perm_addr, ETHER_ADDR_LEN); | ||||
i40e_get_port_mac_addr(hw, hw->mac.port_addr); | i40e_get_port_mac_addr(hw, hw->mac.port_addr); | ||||
/* Query device FW LLDP status */ | /* Query device FW LLDP status */ | ||||
ixl_get_fw_lldp_status(pf); | if (i40e_get_fw_lldp_status(hw, &lldp_status) == I40E_SUCCESS) { | ||||
if (lldp_status == I40E_GET_FW_LLDP_STATUS_DISABLED) { | |||||
atomic_set_int(&pf->state, | |||||
IXL_PF_STATE_FW_LLDP_DISABLED); | |||||
} else { | |||||
atomic_clear_int(&pf->state, | |||||
IXL_PF_STATE_FW_LLDP_DISABLED); | |||||
} | |||||
} | |||||
/* Tell FW to apply DCB config on link up */ | /* Tell FW to apply DCB config on link up */ | ||||
if ((hw->mac.type != I40E_MAC_X722) | |||||
&& ((pf->hw.aq.api_maj_ver > 1) | |||||
|| (pf->hw.aq.api_maj_ver == 1 && pf->hw.aq.api_min_ver >= 7))) | |||||
i40e_aq_set_dcb_parameters(hw, true, NULL); | i40e_aq_set_dcb_parameters(hw, true, NULL); | ||||
/* Initialize mac filter list for VSI */ | |||||
SLIST_INIT(&vsi->ftl); | |||||
/* Set up SW VSI and allocate queue memory and rings */ | /* Set up SW VSI and allocate queue memory and rings */ | ||||
if (ixl_setup_stations(pf)) { | if (ixl_setup_stations(pf)) { | ||||
device_printf(dev, "setup stations failed!\n"); | device_printf(dev, "setup stations failed!\n"); | ||||
error = ENOMEM; | error = ENOMEM; | ||||
goto err_mac_hmc; | goto err_mac_hmc; | ||||
} | } | ||||
/* Setup OS network interface / ifnet */ | /* Setup OS network interface / ifnet */ | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | ixl_attach(device_t dev) | ||||
/* Initialize statistics & add sysctls */ | /* Initialize statistics & add sysctls */ | ||||
ixl_add_device_sysctls(pf); | ixl_add_device_sysctls(pf); | ||||
ixl_pf_reset_stats(pf); | ixl_pf_reset_stats(pf); | ||||
ixl_update_stats_counters(pf); | ixl_update_stats_counters(pf); | ||||
ixl_add_hw_stats(pf); | ixl_add_hw_stats(pf); | ||||
/* Add protocol filters to list */ | |||||
ixl_init_filters(vsi); | |||||
/* Register for VLAN events */ | /* Register for VLAN events */ | ||||
vsi->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, | vsi->vlan_attach = EVENTHANDLER_REGISTER(vlan_config, | ||||
ixl_register_vlan, vsi, EVENTHANDLER_PRI_FIRST); | ixl_register_vlan, vsi, EVENTHANDLER_PRI_FIRST); | ||||
vsi->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, | vsi->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig, | ||||
ixl_unregister_vlan, vsi, EVENTHANDLER_PRI_FIRST); | ixl_unregister_vlan, vsi, EVENTHANDLER_PRI_FIRST); | ||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
ixl_initialize_sriov(pf); | ixl_initialize_sriov(pf); | ||||
Show All 18 Lines | if (hw->func_caps.iwarp && ixl_enable_iwarp) { | ||||
} else | } else | ||||
device_printf(dev, | device_printf(dev, | ||||
"iwarp disabled on this device (no msix vectors)\n"); | "iwarp disabled on this device (no msix vectors)\n"); | ||||
} else { | } else { | ||||
pf->iw_enabled = false; | pf->iw_enabled = false; | ||||
device_printf(dev, "The device is not iWARP enabled\n"); | device_printf(dev, "The device is not iWARP enabled\n"); | ||||
} | } | ||||
#endif | #endif | ||||
/* Start the local timer */ | |||||
IXL_PF_LOCK(pf); | |||||
callout_reset(&pf->timer, hz, ixl_local_timer, pf); | |||||
IXL_PF_UNLOCK(pf); | |||||
INIT_DEBUGOUT("ixl_attach: end"); | INIT_DEBUGOUT("ixl_attach: end"); | ||||
return (0); | return (0); | ||||
err_late: | err_late: | ||||
if (vsi->ifp != NULL) { | if (vsi->ifp != NULL) { | ||||
ether_ifdetach(vsi->ifp); | ether_ifdetach(vsi->ifp); | ||||
if_free(vsi->ifp); | if_free(vsi->ifp); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | #endif | ||||
/* Remove all previously allocated media types */ | /* Remove all previously allocated media types */ | ||||
ifmedia_removeall(&vsi->media); | ifmedia_removeall(&vsi->media); | ||||
ether_ifdetach(vsi->ifp); | ether_ifdetach(vsi->ifp); | ||||
if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) | if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) | ||||
ixl_stop(pf); | ixl_stop(pf); | ||||
/* Shutdown LAN HMC */ | /* Shutdown LAN HMC */ | ||||
if (hw->hmc.hmc_obj) { | |||||
status = i40e_shutdown_lan_hmc(hw); | status = i40e_shutdown_lan_hmc(hw); | ||||
if (status) | if (status) | ||||
device_printf(dev, | device_printf(dev, | ||||
"Shutdown LAN HMC failed with code %d\n", status); | "Shutdown LAN HMC failed with code %s\n", i40e_stat_str(hw, status)); | ||||
} | |||||
/* Teardown LAN queue resources */ | /* Teardown LAN queue resources */ | ||||
ixl_teardown_queue_msix(vsi); | ixl_teardown_queue_msix(vsi); | ||||
ixl_free_queue_tqs(vsi); | ixl_free_queue_tqs(vsi); | ||||
/* Timer enqueues admin task. Stop it before freeing the admin taskqueue */ | |||||
callout_drain(&pf->timer); | |||||
/* Shutdown admin queue */ | /* Shutdown admin queue */ | ||||
ixl_disable_intr0(hw); | ixl_disable_intr0(hw); | ||||
ixl_teardown_adminq_msix(pf); | ixl_teardown_adminq_msix(pf); | ||||
ixl_free_adminq_tq(pf); | |||||
status = i40e_shutdown_adminq(hw); | status = i40e_shutdown_adminq(hw); | ||||
if (status) | if (status) | ||||
device_printf(dev, | device_printf(dev, | ||||
"Shutdown Admin queue failed with code %d\n", status); | "Shutdown Admin queue failed with code %d\n", status); | ||||
ixl_free_adminq_tq(pf); | |||||
/* Unregister VLAN events */ | /* Unregister VLAN events */ | ||||
if (vsi->vlan_attach != NULL) | if (vsi->vlan_attach != NULL) | ||||
EVENTHANDLER_DEREGISTER(vlan_config, vsi->vlan_attach); | EVENTHANDLER_DEREGISTER(vlan_config, vsi->vlan_attach); | ||||
if (vsi->vlan_detach != NULL) | if (vsi->vlan_detach != NULL) | ||||
EVENTHANDLER_DEREGISTER(vlan_unconfig, vsi->vlan_detach); | EVENTHANDLER_DEREGISTER(vlan_unconfig, vsi->vlan_detach); | ||||
callout_drain(&pf->timer); | |||||
#ifdef IXL_IW | #ifdef IXL_IW | ||||
if (ixl_enable_iwarp && pf->iw_enabled) { | if (ixl_enable_iwarp && pf->iw_enabled) { | ||||
error = ixl_iw_pf_detach(pf); | error = ixl_iw_pf_detach(pf); | ||||
if (error == EBUSY) { | if (error == EBUSY) { | ||||
device_printf(dev, "iwarp in use; stop it first.\n"); | device_printf(dev, "iwarp in use; stop it first.\n"); | ||||
return (error); | return (error); | ||||
} | } | ||||
Show All 29 Lines |