aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ixl/if_ixl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ixl/if_ixl.c')
-rw-r--r--sys/dev/ixl/if_ixl.c162
1 files changed, 96 insertions, 66 deletions
diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c
index f814855c187c..105bc9ce4972 100644
--- a/sys/dev/ixl/if_ixl.c
+++ b/sys/dev/ixl/if_ixl.c
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2013-2015, Intel Corporation
+ Copyright (c) 2013-2017, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -47,7 +47,13 @@
/*********************************************************************
* Driver version
*********************************************************************/
-char ixl_driver_version[] = "1.7.12-k";
+#define IXL_DRIVER_VERSION_MAJOR 1
+#define IXL_DRIVER_VERSION_MINOR 9
+#define IXL_DRIVER_VERSION_BUILD 9
+
+char ixl_driver_version[] = __XSTRING(IXL_DRIVER_VERSION_MAJOR) "."
+ __XSTRING(IXL_DRIVER_VERSION_MINOR) "."
+ __XSTRING(IXL_DRIVER_VERSION_BUILD) "-k";
/*********************************************************************
* PCI Device ID Table
@@ -86,7 +92,7 @@ static ixl_vendor_info_t ixl_vendor_info_array[] =
*********************************************************************/
static char *ixl_strings[] = {
- "Intel(R) Ethernet Connection XL710/X722 Driver"
+ "Intel(R) Ethernet Connection 700 Series PF Driver"
};
@@ -99,7 +105,6 @@ static int ixl_detach(device_t);
static int ixl_shutdown(device_t);
static int ixl_save_pf_tunables(struct ixl_pf *);
-static int ixl_attach_get_link_status(struct ixl_pf *);
/*********************************************************************
* FreeBSD Device Interface Entry Points
@@ -151,13 +156,18 @@ SYSCTL_INT(_hw_ixl, OID_AUTO, enable_msix, CTLFLAG_RDTUN, &ixl_enable_msix, 0,
"Enable MSI-X interrupts");
/*
-** Number of descriptors per ring:
-** - TX and RX are the same size
+** Number of descriptors per ring
+** - TX and RX sizes are independently configurable
*/
-static int ixl_ring_size = IXL_DEFAULT_RING;
-TUNABLE_INT("hw.ixl.ring_size", &ixl_ring_size);
-SYSCTL_INT(_hw_ixl, OID_AUTO, ring_size, CTLFLAG_RDTUN,
- &ixl_ring_size, 0, "Descriptor Ring Size");
+static int ixl_tx_ring_size = IXL_DEFAULT_RING;
+TUNABLE_INT("hw.ixl.tx_ring_size", &ixl_tx_ring_size);
+SYSCTL_INT(_hw_ixl, OID_AUTO, tx_ring_size, CTLFLAG_RDTUN,
+ &ixl_tx_ring_size, 0, "TX Descriptor Ring Size");
+
+static int ixl_rx_ring_size = IXL_DEFAULT_RING;
+TUNABLE_INT("hw.ixl.rx_ring_size", &ixl_rx_ring_size);
+SYSCTL_INT(_hw_ixl, OID_AUTO, rx_ring_size, CTLFLAG_RDTUN,
+ &ixl_rx_ring_size, 0, "RX Descriptor Ring Size");
/*
** This can be set manually, if left as 0 the
@@ -169,6 +179,10 @@ TUNABLE_INT("hw.ixl.max_queues", &ixl_max_queues);
SYSCTL_INT(_hw_ixl, OID_AUTO, max_queues, CTLFLAG_RDTUN,
&ixl_max_queues, 0, "Number of Queues");
+/*
+ * Leave this on unless you need to send flow control
+ * frames (or other control frames) from software
+ */
static int ixl_enable_tx_fc_filter = 1;
TUNABLE_INT("hw.ixl.enable_tx_fc_filter",
&ixl_enable_tx_fc_filter);
@@ -176,6 +190,17 @@ SYSCTL_INT(_hw_ixl, OID_AUTO, enable_tx_fc_filter, CTLFLAG_RDTUN,
&ixl_enable_tx_fc_filter, 0,
"Filter out packets with Ethertype 0x8808 from being sent out by non-HW sources");
+/*
+ * Different method for processing TX descriptor
+ * completion.
+ */
+static int ixl_enable_head_writeback = 1;
+TUNABLE_INT("hw.ixl.enable_head_writeback",
+ &ixl_enable_head_writeback);
+SYSCTL_INT(_hw_ixl, OID_AUTO, enable_head_writeback, CTLFLAG_RDTUN,
+ &ixl_enable_head_writeback, 0,
+ "For detecting last completed TX descriptor by hardware, use value written by HW instead of checking descriptors");
+
static int ixl_core_debug_mask = 0;
TUNABLE_INT("hw.ixl.core_debug_mask",
&ixl_core_debug_mask);
@@ -218,6 +243,17 @@ SYSCTL_INT(_hw_ixl, OID_AUTO, tx_itr, CTLFLAG_RDTUN,
#ifdef IXL_IW
int ixl_enable_iwarp = 0;
TUNABLE_INT("hw.ixl.enable_iwarp", &ixl_enable_iwarp);
+SYSCTL_INT(_hw_ixl, OID_AUTO, enable_iwarp, CTLFLAG_RDTUN,
+ &ixl_enable_iwarp, 0, "iWARP enabled");
+
+#if __FreeBSD_version < 1100000
+int ixl_limit_iwarp_msix = 1;
+#else
+int ixl_limit_iwarp_msix = IXL_IW_MAX_MSIX;
+#endif
+TUNABLE_INT("hw.ixl.limit_iwarp_msix", &ixl_limit_iwarp_msix);
+SYSCTL_INT(_hw_ixl, OID_AUTO, limit_iwarp_msix, CTLFLAG_RDTUN,
+ &ixl_limit_iwarp_msix, 0, "Limit MSIX vectors assigned to iWARP");
#endif
#ifdef DEV_NETMAP
@@ -275,30 +311,6 @@ ixl_probe(device_t dev)
return (ENXIO);
}
-static int
-ixl_attach_get_link_status(struct ixl_pf *pf)
-{
- struct i40e_hw *hw = &pf->hw;
- device_t dev = pf->dev;
- int error = 0;
-
- if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
- (hw->aq.fw_maj_ver < 4)) {
- i40e_msec_delay(75);
- error = i40e_aq_set_link_restart_an(hw, TRUE, NULL);
- if (error) {
- device_printf(dev, "link restart failed, aq_err=%d\n",
- pf->hw.aq.asq_last_status);
- return error;
- }
- }
-
- /* Determine link state */
- hw->phy.get_link_info = TRUE;
- i40e_get_link_status(hw, &pf->link_up);
- return (0);
-}
-
/*
* Sanity check and save off tunable values.
*/
@@ -315,20 +327,16 @@ ixl_save_pf_tunables(struct ixl_pf *pf)
pf->dynamic_tx_itr = ixl_dynamic_tx_itr;
pf->dbg_mask = ixl_core_debug_mask;
pf->hw.debug_mask = ixl_shared_debug_mask;
+#ifdef DEV_NETMAP
+ if (ixl_enable_head_writeback == 0)
+ device_printf(dev, "Head writeback mode cannot be disabled "
+ "when netmap is enabled\n");
+ pf->vsi.enable_head_writeback = 1;
+#else
+ pf->vsi.enable_head_writeback = !!(ixl_enable_head_writeback);
+#endif
- if (ixl_ring_size < IXL_MIN_RING
- || ixl_ring_size > IXL_MAX_RING
- || ixl_ring_size % IXL_RING_INCREMENT != 0) {
- device_printf(dev, "Invalid ring_size value of %d set!\n",
- ixl_ring_size);
- device_printf(dev, "ring_size must be between %d and %d, "
- "inclusive, and must be a multiple of %d\n",
- IXL_MIN_RING, IXL_MAX_RING, IXL_RING_INCREMENT);
- device_printf(dev, "Using default value of %d instead\n",
- IXL_DEFAULT_RING);
- pf->ringsz = IXL_DEFAULT_RING;
- } else
- pf->ringsz = ixl_ring_size;
+ ixl_vsi_setup_rings_size(&pf->vsi, ixl_tx_ring_size, ixl_rx_ring_size);
if (ixl_tx_itr < 0 || ixl_tx_itr > IXL_MAX_ITR) {
device_printf(dev, "Invalid tx_itr value of %d set!\n",
@@ -389,6 +397,7 @@ ixl_attach(device_t dev)
*/
vsi = &pf->vsi;
vsi->dev = pf->dev;
+ vsi->back = pf;
/* Save tunable values */
error = ixl_save_pf_tunables(pf);
@@ -427,12 +436,6 @@ ixl_attach(device_t dev)
goto err_out;
}
- /*
- * Allocate interrupts and figure out number of queues to use
- * for PF interface
- */
- pf->msix = ixl_init_msix(pf);
-
/* Set up the admin queue */
hw->aq.num_arq_entries = IXL_AQ_LEN;
hw->aq.num_asq_entries = IXL_AQ_LEN;
@@ -450,23 +453,24 @@ ixl_attach(device_t dev)
if (status == I40E_ERR_FIRMWARE_API_VERSION) {
device_printf(dev, "The driver for the device stopped "
- "because the NVM image is newer than expected.\n"
- "You must install the most recent version of "
+ "because the NVM image is newer than expected.\n");
+ device_printf(dev, "You must install the most recent version of "
"the network driver.\n");
error = EIO;
goto err_out;
}
if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR &&
- hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR)
+ hw->aq.api_min_ver > I40E_FW_MINOR_VERSION(hw)) {
device_printf(dev, "The driver for the device detected "
- "a newer version of the NVM image than expected.\n"
- "Please install the most recent version of the network driver.\n");
- else if (hw->aq.api_maj_ver < I40E_FW_API_VERSION_MAJOR ||
- hw->aq.api_min_ver < (I40E_FW_API_VERSION_MINOR - 1))
+ "a newer version of the NVM image than expected.\n");
+ device_printf(dev, "Please install the most recent version "
+ "of the network driver.\n");
+ } else if (hw->aq.api_maj_ver == 1 && hw->aq.api_min_ver < 4) {
device_printf(dev, "The driver for the device detected "
- "an older version of the NVM image than expected.\n"
- "Please update the NVM image.\n");
+ "an older version of the NVM image than expected.\n");
+ device_printf(dev, "Please update the NVM image.\n");
+ }
/* Clear PXE mode */
i40e_clear_pxe_mode(hw);
@@ -478,6 +482,12 @@ ixl_attach(device_t dev)
goto err_get_cap;
}
+ /*
+ * Allocate interrupts and figure out number of queues to use
+ * for PF interface
+ */
+ pf->msix = ixl_init_msix(pf);
+
/* Set up host memory cache */
status = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp,
hw->func_caps.num_rx_qp, 0, 0);
@@ -513,8 +523,10 @@ ixl_attach(device_t dev)
/* Disable LLDP from the firmware for certain NVM versions */
if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
- (pf->hw.aq.fw_maj_ver < 4))
+ (pf->hw.aq.fw_maj_ver < 4)) {
i40e_aq_stop_lldp(hw, TRUE, NULL);
+ pf->state |= IXL_PF_STATE_FW_LLDP_DISABLED;
+ }
/* Get MAC addresses from hardware */
i40e_get_mac_addr(hw, hw->mac.addr);
@@ -526,6 +538,14 @@ ixl_attach(device_t dev)
bcopy(hw->mac.addr, hw->mac.perm_addr, ETHER_ADDR_LEN);
i40e_get_port_mac_addr(hw, hw->mac.port_addr);
+ /* Query device FW LLDP status */
+ ixl_get_fw_lldp_status(pf);
+ /* 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);
+
/* Initialize mac filter list for VSI */
SLIST_INIT(&vsi->ftl);
@@ -619,7 +639,7 @@ ixl_attach(device_t dev)
}
/* Set initial advertised speed sysctl value */
- ixl_get_initial_advertised_speeds(pf);
+ ixl_set_initial_advertised_speeds(pf);
/* Initialize statistics & add sysctls */
ixl_add_device_sysctls(pf);
@@ -639,7 +659,13 @@ ixl_attach(device_t dev)
#endif
#ifdef DEV_NETMAP
- ixl_netmap_attach(vsi);
+ if (vsi->num_rx_desc == vsi->num_tx_desc) {
+ vsi->queues[0].num_desc = vsi->num_rx_desc;
+ ixl_netmap_attach(vsi);
+ } else
+ device_printf(dev,
+ "Netmap is not supported when RX and TX descriptor ring sizes differ\n");
+
#endif /* DEV_NETMAP */
#ifdef IXL_IW
@@ -652,7 +678,8 @@ ixl_attach(device_t dev)
"interfacing to iwarp driver failed: %d\n",
error);
goto err_late;
- }
+ } else
+ device_printf(dev, "iWARP ready\n");
} else
device_printf(dev,
"iwarp disabled on this device (no msix vectors)\n");
@@ -718,6 +745,9 @@ ixl_detach(device_t dev)
}
#endif
+ /* Remove all previously allocated media types */
+ ifmedia_removeall(&vsi->media);
+
ether_ifdetach(vsi->ifp);
if (vsi->ifp->if_drv_flags & IFF_DRV_RUNNING)
ixl_stop(pf);