2017-01-10 04:50:26 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 2016 Matt Macy <mmacy@nextbsd.org>
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* $FreeBSD$ */
|
2007-05-04 00:00:12 +00:00
|
|
|
#include "if_em.h"
|
2017-01-10 03:23:22 +00:00
|
|
|
#include <sys/sbuf.h>
|
|
|
|
#include <machine/_inttypes.h>
|
|
|
|
|
|
|
|
#define em_mac_min e1000_82547
|
|
|
|
#define igb_mac_min e1000_82575
|
2001-12-02 07:37:17 +00:00
|
|
|
|
|
|
|
/*********************************************************************
|
2007-05-04 00:00:12 +00:00
|
|
|
* Driver version:
|
2001-12-02 07:37:17 +00:00
|
|
|
*********************************************************************/
|
2016-02-05 17:14:37 +00:00
|
|
|
char em_driver_version[] = "7.6.1-k";
|
2001-12-02 07:37:17 +00:00
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
* PCI Device ID Table
|
|
|
|
*
|
|
|
|
* Used by probe to select devices to load on
|
2007-05-04 00:00:12 +00:00
|
|
|
* Last field stores an index into e1000_strings
|
2001-12-02 07:37:17 +00:00
|
|
|
* Last entry must be all 0s
|
|
|
|
*
|
|
|
|
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID, String Index }
|
|
|
|
*********************************************************************/
|
2003-03-21 21:47:31 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static pci_vendor_info_t em_vendor_info_array[] =
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Intel(R) PRO/1000 Network Connection - Legacy em*/
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82540EM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82540EM_LOM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82540EP, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82540EP_LOM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82540EP_LP, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541EI, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541ER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541ER_LOM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541EI_MOBILE, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541GI, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541GI_LF, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82541GI_MOBILE, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82542, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82543GC_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82543GC_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82544EI_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82544EI_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82544GC_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82544GC_LOM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82545EM_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82545EM_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82545GM_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82545GM_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82545GM_SERDES, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546EB_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546EB_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546EB_QUAD_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546GB_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546GB_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546GB_SERDES, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546GB_PCIE, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82547EI, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82547EI_MOBILE, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82547GI, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
|
|
|
|
/* Intel(R) PRO/1000 Network Connection - em */
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_SERDES, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_SERDES_DUAL, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_SERDES_QUAD, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_QUAD_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_QUAD_COPPER_LP, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571EB_QUAD_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82571PT_QUAD_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82572EI_COPPER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82572EI_FIBER, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82572EI_SERDES, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82573E, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82573E_IAMT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82573L, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82583V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_80003ES2LAN_COPPER_SPT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_80003ES2LAN_SERDES_SPT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_80003ES2LAN_COPPER_DPT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_80003ES2LAN_SERDES_DPT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IGP_M_AMT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IGP_AMT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IGP_C, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IFE, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IFE_GT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IFE_G, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_IGP_M, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH8_82567V_3, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IGP_M_AMT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IGP_AMT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IGP_C, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IGP_M, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IGP_M_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IFE, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IFE_GT, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_IFE_G, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH9_BM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82574L, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82574LA, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH10_R_BM_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH10_R_BM_LF, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH10_R_BM_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH10_D_BM_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH10_D_BM_LF, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_ICH10_D_BM_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_M_HV_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_M_HV_LC, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_D_HV_DM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_D_HV_DC, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH2_LV_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH2_LV_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_LPT_I217_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_LPT_I217_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_LPTLP_I218_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_LPTLP_I218_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_I218_LM2, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_I218_V2, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_I218_LM3, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_I218_V3, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_LM2, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_SPT_I219_V2, "Intel(R) PRO/1000 Network Connection"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_PCH_LBG_I219_LM3, "Intel(R) PRO/1000 Network Connection"),
|
2006-02-15 08:39:50 +00:00
|
|
|
/* required last entry */
|
2017-01-10 03:23:22 +00:00
|
|
|
PVID_END
|
2001-12-02 07:37:17 +00:00
|
|
|
};
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static pci_vendor_info_t igb_vendor_info_array[] =
|
|
|
|
{
|
|
|
|
/* Intel(R) PRO/1000 Network Connection - em */
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82575EB_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82575EB_FIBER_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82575GB_QUAD_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_NS, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_NS_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_FIBER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_SERDES_QUAD, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_QUAD_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_QUAD_COPPER_ET2, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82576_VF, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82580_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82580_FIBER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82580_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82580_SGMII, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82580_COPPER_DUAL, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_82580_QUAD_FIBER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_DH89XXCC_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_DH89XXCC_SGMII, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_DH89XXCC_SFP, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_DH89XXCC_BACKPLANE, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I350_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I350_FIBER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I350_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I350_SGMII, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I350_VF, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_COPPER_IT, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_COPPER_OEM1, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_COPPER_FLASHLESS, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_SERDES_FLASHLESS, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_FIBER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_SERDES, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I210_SGMII, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I211_COPPER, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I354_BACKPLANE_1GBPS, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I354_BACKPLANE_2_5GBPS, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
PVID(0x8086, E1000_DEV_ID_I354_SGMII, "Intel(R) PRO/1000 PCI-Express Network Driver"),
|
|
|
|
/* required last entry */
|
|
|
|
PVID_END
|
2001-12-02 07:37:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*********************************************************************
|
2006-01-20 11:38:25 +00:00
|
|
|
* Function prototypes
|
2001-12-02 07:37:17 +00:00
|
|
|
*********************************************************************/
|
2017-01-10 03:23:22 +00:00
|
|
|
static void *em_register(device_t dev);
|
|
|
|
static void *igb_register(device_t dev);
|
|
|
|
static int em_if_attach_pre(if_ctx_t ctx);
|
|
|
|
static int em_if_attach_post(if_ctx_t ctx);
|
|
|
|
static int em_if_detach(if_ctx_t ctx);
|
|
|
|
static int em_if_shutdown(if_ctx_t ctx);
|
|
|
|
static int em_if_suspend(if_ctx_t ctx);
|
|
|
|
static int em_if_resume(if_ctx_t ctx);
|
|
|
|
|
|
|
|
static int em_if_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs, int ntxqs, int ntxqsets);
|
|
|
|
static int em_if_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs, int nrxqs, int nrxqsets);
|
|
|
|
static void em_if_queues_free(if_ctx_t ctx);
|
|
|
|
|
|
|
|
static uint64_t em_if_get_counter(if_ctx_t, ift_counter);
|
|
|
|
static void em_if_init(if_ctx_t ctx);
|
|
|
|
static void em_if_stop(if_ctx_t ctx);
|
|
|
|
static void em_if_media_status(if_ctx_t, struct ifmediareq *);
|
|
|
|
static int em_if_media_change(if_ctx_t ctx);
|
|
|
|
static int em_if_mtu_set(if_ctx_t ctx, uint32_t mtu);
|
|
|
|
static void em_if_timer(if_ctx_t ctx, uint16_t qid);
|
|
|
|
static void em_if_vlan_register(if_ctx_t ctx, u16 vtag);
|
|
|
|
static void em_if_vlan_unregister(if_ctx_t ctx, u16 vtag);
|
|
|
|
|
|
|
|
static void em_identify_hardware(if_ctx_t ctx);
|
|
|
|
static int em_allocate_pci_resources(if_ctx_t ctx);
|
|
|
|
static void em_free_pci_resources(if_ctx_t ctx);
|
|
|
|
static void em_reset(if_ctx_t ctx);
|
|
|
|
static int em_setup_interface(if_ctx_t ctx);
|
|
|
|
static int em_setup_msix(if_ctx_t ctx);
|
|
|
|
|
|
|
|
static void em_initialize_transmit_unit(if_ctx_t ctx);
|
|
|
|
static void em_initialize_receive_unit(if_ctx_t ctx);
|
|
|
|
|
|
|
|
static void em_if_enable_intr(if_ctx_t ctx);
|
|
|
|
static void em_if_disable_intr(if_ctx_t ctx);
|
|
|
|
static int em_if_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid);
|
|
|
|
static void em_if_multi_set(if_ctx_t ctx);
|
|
|
|
static void em_if_update_admin_status(if_ctx_t ctx);
|
2006-08-03 19:05:04 +00:00
|
|
|
static void em_update_stats_counters(struct adapter *);
|
2010-06-16 20:57:41 +00:00
|
|
|
static void em_add_hw_stats(struct adapter *adapter);
|
2017-01-10 03:23:22 +00:00
|
|
|
static int em_if_set_promisc(if_ctx_t ctx, int flags);
|
2009-06-24 17:41:29 +00:00
|
|
|
static void em_setup_vlan_hw_support(struct adapter *);
|
2010-06-16 20:57:41 +00:00
|
|
|
static int em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS);
|
2007-11-20 21:41:22 +00:00
|
|
|
static void em_print_nvm_info(struct adapter *);
|
2010-10-26 00:07:58 +00:00
|
|
|
static int em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
|
|
|
|
static void em_print_debug_info(struct adapter *);
|
2008-02-29 21:50:11 +00:00
|
|
|
static int em_is_valid_ether_addr(u8 *);
|
2006-02-15 08:39:50 +00:00
|
|
|
static int em_sysctl_int_delay(SYSCTL_HANDLER_ARGS);
|
2006-08-03 19:05:04 +00:00
|
|
|
static void em_add_int_delay_sysctl(struct adapter *, const char *,
|
2007-05-04 00:00:12 +00:00
|
|
|
const char *, struct em_int_delay_info *, int, int);
|
|
|
|
/* Management and WOL Support */
|
|
|
|
static void em_init_manageability(struct adapter *);
|
|
|
|
static void em_release_manageability(struct adapter *);
|
|
|
|
static void em_get_hw_control(struct adapter *);
|
|
|
|
static void em_release_hw_control(struct adapter *);
|
2017-01-10 03:23:22 +00:00
|
|
|
static void em_get_wakeup(if_ctx_t ctx);
|
|
|
|
static void em_enable_wakeup(if_ctx_t ctx);
|
2009-12-08 01:07:44 +00:00
|
|
|
static int em_enable_phy_wakeup(struct adapter *);
|
2010-11-24 22:24:07 +00:00
|
|
|
static void em_disable_aspm(struct adapter *);
|
2006-06-06 08:03:49 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
int em_intr(void *arg);
|
|
|
|
static void em_disable_promisc(if_ctx_t ctx);
|
2009-04-10 00:05:46 +00:00
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
/* MSIX handlers */
|
2017-01-10 03:23:22 +00:00
|
|
|
static int em_if_msix_intr_assign(if_ctx_t, int);
|
|
|
|
static int em_msix_link(void *);
|
|
|
|
static void em_handle_link(void *context);
|
|
|
|
|
|
|
|
static void em_enable_vectors_82574(if_ctx_t);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2011-03-18 18:54:00 +00:00
|
|
|
static void em_set_sysctl_value(struct adapter *, const char *,
|
2010-10-26 00:07:58 +00:00
|
|
|
const char *, int *, int);
|
2011-12-10 07:08:52 +00:00
|
|
|
static int em_set_flowcntl(SYSCTL_HANDLER_ARGS);
|
2012-07-07 20:21:05 +00:00
|
|
|
static int em_sysctl_eee(SYSCTL_HANDLER_ARGS);
|
2017-01-10 03:23:22 +00:00
|
|
|
static void em_if_led_func(if_ctx_t ctx, int onoff);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static void em_init_tx_ring(struct em_tx_queue *que);
|
|
|
|
static int em_get_regs(SYSCTL_HANDLER_ARGS);
|
|
|
|
|
|
|
|
static void lem_smartspeed(struct adapter *adapter);
|
|
|
|
static void igb_configure_queues(struct adapter *adapter);
|
2010-09-07 20:13:08 +00:00
|
|
|
|
2007-11-21 12:55:33 +00:00
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
/*********************************************************************
|
2006-01-20 11:38:25 +00:00
|
|
|
* FreeBSD Device Interface Entry Points
|
2001-12-02 07:37:17 +00:00
|
|
|
*********************************************************************/
|
|
|
|
static device_method_t em_methods[] = {
|
2002-06-03 22:30:51 +00:00
|
|
|
/* Device interface */
|
2017-01-10 03:23:22 +00:00
|
|
|
DEVMETHOD(device_register, em_register),
|
|
|
|
DEVMETHOD(device_probe, iflib_device_probe),
|
|
|
|
DEVMETHOD(device_attach, iflib_device_attach),
|
|
|
|
DEVMETHOD(device_detach, iflib_device_detach),
|
|
|
|
DEVMETHOD(device_shutdown, iflib_device_shutdown),
|
|
|
|
DEVMETHOD(device_suspend, iflib_device_suspend),
|
|
|
|
DEVMETHOD(device_resume, iflib_device_resume),
|
|
|
|
DEVMETHOD_END
|
|
|
|
};
|
|
|
|
|
|
|
|
static device_method_t igb_methods[] = {
|
|
|
|
/* Device interface */
|
|
|
|
DEVMETHOD(device_register, igb_register),
|
|
|
|
DEVMETHOD(device_probe, iflib_device_probe),
|
|
|
|
DEVMETHOD(device_attach, iflib_device_attach),
|
|
|
|
DEVMETHOD(device_detach, iflib_device_detach),
|
|
|
|
DEVMETHOD(device_shutdown, iflib_device_shutdown),
|
|
|
|
DEVMETHOD(device_suspend, iflib_device_suspend),
|
|
|
|
DEVMETHOD(device_resume, iflib_device_resume),
|
|
|
|
DEVMETHOD_END
|
2001-12-02 07:37:17 +00:00
|
|
|
};
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
static driver_t em_driver = {
|
2006-08-03 19:05:04 +00:00
|
|
|
"em", em_methods, sizeof(struct adapter),
|
2001-12-02 07:37:17 +00:00
|
|
|
};
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static devclass_t em_devclass;
|
2003-04-15 06:37:30 +00:00
|
|
|
DRIVER_MODULE(em, pci, em_driver, em_devclass, 0, 0);
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2003-04-15 06:37:30 +00:00
|
|
|
MODULE_DEPEND(em, pci, 1, 1, 1);
|
|
|
|
MODULE_DEPEND(em, ether, 1, 1, 1);
|
2017-01-10 03:23:22 +00:00
|
|
|
MODULE_DEPEND(em, iflib, 1, 1, 1);
|
|
|
|
|
|
|
|
static driver_t igb_driver = {
|
|
|
|
"igb", igb_methods, sizeof(struct adapter),
|
|
|
|
};
|
|
|
|
|
|
|
|
static devclass_t igb_devclass;
|
|
|
|
DRIVER_MODULE(igb, pci, igb_driver, igb_devclass, 0, 0);
|
|
|
|
|
|
|
|
MODULE_DEPEND(igb, pci, 1, 1, 1);
|
|
|
|
MODULE_DEPEND(igb, ether, 1, 1, 1);
|
|
|
|
MODULE_DEPEND(igb, iflib, 1, 1, 1);
|
|
|
|
|
|
|
|
|
|
|
|
static device_method_t em_if_methods[] = {
|
|
|
|
DEVMETHOD(ifdi_attach_pre, em_if_attach_pre),
|
|
|
|
DEVMETHOD(ifdi_attach_post, em_if_attach_post),
|
|
|
|
DEVMETHOD(ifdi_detach, em_if_detach),
|
|
|
|
DEVMETHOD(ifdi_shutdown, em_if_shutdown),
|
|
|
|
DEVMETHOD(ifdi_suspend, em_if_suspend),
|
|
|
|
DEVMETHOD(ifdi_resume, em_if_resume),
|
|
|
|
DEVMETHOD(ifdi_init, em_if_init),
|
|
|
|
DEVMETHOD(ifdi_stop, em_if_stop),
|
|
|
|
DEVMETHOD(ifdi_msix_intr_assign, em_if_msix_intr_assign),
|
|
|
|
DEVMETHOD(ifdi_intr_enable, em_if_enable_intr),
|
|
|
|
DEVMETHOD(ifdi_intr_disable, em_if_disable_intr),
|
|
|
|
DEVMETHOD(ifdi_tx_queues_alloc, em_if_tx_queues_alloc),
|
|
|
|
DEVMETHOD(ifdi_rx_queues_alloc, em_if_rx_queues_alloc),
|
|
|
|
DEVMETHOD(ifdi_queues_free, em_if_queues_free),
|
|
|
|
DEVMETHOD(ifdi_update_admin_status, em_if_update_admin_status),
|
|
|
|
DEVMETHOD(ifdi_multi_set, em_if_multi_set),
|
|
|
|
DEVMETHOD(ifdi_media_status, em_if_media_status),
|
|
|
|
DEVMETHOD(ifdi_media_change, em_if_media_change),
|
|
|
|
DEVMETHOD(ifdi_mtu_set, em_if_mtu_set),
|
|
|
|
DEVMETHOD(ifdi_promisc_set, em_if_set_promisc),
|
|
|
|
DEVMETHOD(ifdi_timer, em_if_timer),
|
|
|
|
DEVMETHOD(ifdi_vlan_register, em_if_vlan_register),
|
|
|
|
DEVMETHOD(ifdi_vlan_unregister, em_if_vlan_unregister),
|
|
|
|
DEVMETHOD(ifdi_get_counter, em_if_get_counter),
|
|
|
|
DEVMETHOD(ifdi_led_func, em_if_led_func),
|
|
|
|
DEVMETHOD(ifdi_queue_intr_enable, em_if_queue_intr_enable),
|
|
|
|
DEVMETHOD_END
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* note that if (adapter->msix_mem) is replaced by:
|
|
|
|
* if (adapter->intr_type == IFLIB_INTR_MSIX)
|
|
|
|
*/
|
|
|
|
static driver_t em_if_driver = {
|
|
|
|
"em_if", em_if_methods, sizeof(struct adapter)
|
|
|
|
};
|
2001-12-02 07:37:17 +00:00
|
|
|
|
2003-08-01 17:33:59 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* Tunable default values.
|
|
|
|
*********************************************************************/
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
#define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000)
|
|
|
|
#define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024)
|
2017-01-10 03:23:22 +00:00
|
|
|
#define M_TSO_LEN 66
|
2003-08-01 17:33:59 +00:00
|
|
|
|
2013-05-09 17:07:30 +00:00
|
|
|
#define MAX_INTS_PER_SEC 8000
|
|
|
|
#define DEFAULT_ITR (1000000000/(MAX_INTS_PER_SEC * 256))
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Allow common code without TSO */
|
|
|
|
#ifndef CSUM_TSO
|
|
|
|
#define CSUM_TSO 0
|
|
|
|
#endif
|
|
|
|
|
2015-08-16 19:43:44 +00:00
|
|
|
#define TSO_WORKAROUND 4
|
|
|
|
|
2011-11-07 15:43:11 +00:00
|
|
|
static SYSCTL_NODE(_hw, OID_AUTO, em, CTLFLAG_RD, 0, "EM driver parameters");
|
2011-06-29 16:20:52 +00:00
|
|
|
|
2015-08-16 19:06:23 +00:00
|
|
|
static int em_disable_crc_stripping = 0;
|
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, disable_crc_stripping, CTLFLAG_RDTUN,
|
|
|
|
&em_disable_crc_stripping, 0, "Disable CRC Stripping");
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
static int em_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV);
|
|
|
|
static int em_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR);
|
2011-06-29 16:20:52 +00:00
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, tx_int_delay, CTLFLAG_RDTUN, &em_tx_int_delay_dflt,
|
|
|
|
0, "Default transmit interrupt delay in usecs");
|
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, rx_int_delay, CTLFLAG_RDTUN, &em_rx_int_delay_dflt,
|
|
|
|
0, "Default receive interrupt delay in usecs");
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
|
|
|
static int em_tx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_TADV);
|
|
|
|
static int em_rx_abs_int_delay_dflt = EM_TICKS_TO_USECS(EM_RADV);
|
2011-06-29 16:20:52 +00:00
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, tx_abs_int_delay, CTLFLAG_RDTUN,
|
|
|
|
&em_tx_abs_int_delay_dflt, 0,
|
|
|
|
"Default transmit interrupt delay limit in usecs");
|
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, rx_abs_int_delay, CTLFLAG_RDTUN,
|
|
|
|
&em_rx_abs_int_delay_dflt, 0,
|
|
|
|
"Default receive interrupt delay limit in usecs");
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
|
|
|
static int em_smart_pwr_down = FALSE;
|
2011-06-29 16:20:52 +00:00
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, smart_pwr_down, CTLFLAG_RDTUN, &em_smart_pwr_down,
|
|
|
|
0, "Set to true to leave smart power down enabled on newer adapters");
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
|
|
|
/* Controls whether promiscuous also shows bad packets */
|
2017-01-10 03:23:22 +00:00
|
|
|
static int em_debug_sbp = TRUE;
|
2011-06-29 16:20:52 +00:00
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, sbp, CTLFLAG_RDTUN, &em_debug_sbp, 0,
|
|
|
|
"Show bad packets in promiscuous mode");
|
2008-02-29 21:50:11 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/* How many packets rxeof tries to clean at a time */
|
2006-10-28 08:11:07 +00:00
|
|
|
static int em_rx_process_limit = 100;
|
2011-06-29 16:20:52 +00:00
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, rx_process_limit, CTLFLAG_RDTUN,
|
|
|
|
&em_rx_process_limit, 0,
|
2011-12-10 07:08:52 +00:00
|
|
|
"Maximum number of received packets to process "
|
|
|
|
"at a time, -1 means unlimited");
|
2009-06-24 17:41:29 +00:00
|
|
|
|
2011-03-18 18:54:00 +00:00
|
|
|
/* Energy efficient ethernet - default to OFF */
|
2012-07-07 20:21:05 +00:00
|
|
|
static int eee_setting = 1;
|
2011-06-29 16:20:52 +00:00
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, eee_setting, CTLFLAG_RDTUN, &eee_setting, 0,
|
|
|
|
"Enable Energy Efficient Ethernet");
|
2011-03-18 18:54:00 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*
|
|
|
|
** Tuneable Interrupt rate
|
|
|
|
*/
|
|
|
|
static int em_max_interrupt_rate = 8000;
|
|
|
|
SYSCTL_INT(_hw_em, OID_AUTO, max_interrupt_rate, CTLFLAG_RDTUN,
|
|
|
|
&em_max_interrupt_rate, 0, "Maximum interrupts per second");
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/* Global used in WOL setup with multiport cards */
|
|
|
|
static int global_quad_port_a = 0;
|
2003-08-01 17:33:59 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
extern struct if_txrx igb_txrx;
|
|
|
|
extern struct if_txrx em_txrx;
|
|
|
|
extern struct if_txrx lem_txrx;
|
|
|
|
|
|
|
|
static struct if_shared_ctx em_sctx_init = {
|
|
|
|
.isc_magic = IFLIB_MAGIC,
|
|
|
|
.isc_q_align = PAGE_SIZE,
|
|
|
|
.isc_tx_maxsize = EM_TSO_SIZE,
|
|
|
|
.isc_tx_maxsegsize = PAGE_SIZE,
|
|
|
|
.isc_rx_maxsize = MJUM9BYTES,
|
|
|
|
.isc_rx_nsegments = 1,
|
|
|
|
.isc_rx_maxsegsize = MJUM9BYTES,
|
|
|
|
.isc_nfl = 1,
|
|
|
|
.isc_nrxqs = 1,
|
|
|
|
.isc_ntxqs = 1,
|
|
|
|
.isc_admin_intrcnt = 1,
|
|
|
|
.isc_vendor_info = em_vendor_info_array,
|
|
|
|
.isc_driver_version = em_driver_version,
|
|
|
|
.isc_driver = &em_if_driver,
|
|
|
|
.isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP,
|
|
|
|
|
|
|
|
.isc_nrxd_min = {EM_MIN_RXD},
|
|
|
|
.isc_ntxd_min = {EM_MIN_TXD},
|
|
|
|
.isc_nrxd_max = {EM_MAX_RXD},
|
|
|
|
.isc_ntxd_max = {EM_MAX_TXD},
|
|
|
|
.isc_nrxd_default = {EM_DEFAULT_RXD},
|
|
|
|
.isc_ntxd_default = {EM_DEFAULT_TXD},
|
|
|
|
};
|
|
|
|
|
|
|
|
if_shared_ctx_t em_sctx = &em_sctx_init;
|
|
|
|
|
|
|
|
|
|
|
|
static struct if_shared_ctx igb_sctx_init = {
|
|
|
|
.isc_magic = IFLIB_MAGIC,
|
|
|
|
.isc_q_align = PAGE_SIZE,
|
|
|
|
.isc_tx_maxsize = EM_TSO_SIZE,
|
|
|
|
.isc_tx_maxsegsize = PAGE_SIZE,
|
|
|
|
.isc_rx_maxsize = MJUM9BYTES,
|
|
|
|
.isc_rx_nsegments = 1,
|
|
|
|
.isc_rx_maxsegsize = MJUM9BYTES,
|
|
|
|
.isc_nfl = 1,
|
|
|
|
.isc_nrxqs = 1,
|
|
|
|
.isc_ntxqs = 1,
|
|
|
|
.isc_admin_intrcnt = 1,
|
|
|
|
.isc_vendor_info = igb_vendor_info_array,
|
|
|
|
.isc_driver_version = em_driver_version,
|
|
|
|
.isc_driver = &em_if_driver,
|
|
|
|
.isc_flags = IFLIB_NEED_SCRATCH | IFLIB_TSO_INIT_IP,
|
|
|
|
|
|
|
|
.isc_nrxd_min = {EM_MIN_RXD},
|
|
|
|
.isc_ntxd_min = {EM_MIN_TXD},
|
|
|
|
.isc_nrxd_max = {EM_MAX_RXD},
|
|
|
|
.isc_ntxd_max = {EM_MAX_TXD},
|
|
|
|
.isc_nrxd_default = {EM_DEFAULT_RXD},
|
|
|
|
.isc_ntxd_default = {EM_DEFAULT_TXD},
|
|
|
|
};
|
|
|
|
|
|
|
|
if_shared_ctx_t igb_sctx = &igb_sctx_init;
|
2011-12-05 15:33:13 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*****************************************************************
|
2001-12-02 07:37:17 +00:00
|
|
|
*
|
2017-01-10 03:23:22 +00:00
|
|
|
* Dump Registers
|
2001-12-02 07:37:17 +00:00
|
|
|
*
|
2017-01-10 03:23:22 +00:00
|
|
|
****************************************************************/
|
|
|
|
#define IGB_REGS_LEN 739
|
2001-12-02 07:37:17 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static int em_get_regs(SYSCTL_HANDLER_ARGS)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = (struct adapter *)arg1;
|
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
struct sbuf *sb;
|
|
|
|
u32 *regs_buff = (u32 *)malloc(sizeof(u32) * IGB_REGS_LEN, M_DEVBUF, M_NOWAIT);
|
|
|
|
int rc;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
memset(regs_buff, 0, IGB_REGS_LEN * sizeof(u32));
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
rc = sysctl_wire_old_buffer(req, 0);
|
|
|
|
MPASS(rc == 0);
|
|
|
|
if (rc != 0)
|
|
|
|
return (rc);
|
|
|
|
|
|
|
|
sb = sbuf_new_for_sysctl(NULL, NULL, 32*400, req);
|
|
|
|
MPASS(sb != NULL);
|
|
|
|
if (sb == NULL)
|
|
|
|
return (ENOMEM);
|
|
|
|
|
|
|
|
/* General Registers */
|
|
|
|
regs_buff[0] = E1000_READ_REG(hw, E1000_CTRL);
|
|
|
|
regs_buff[1] = E1000_READ_REG(hw, E1000_STATUS);
|
|
|
|
regs_buff[2] = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
|
|
|
regs_buff[3] = E1000_READ_REG(hw, E1000_ICR);
|
|
|
|
regs_buff[4] = E1000_READ_REG(hw, E1000_RCTL);
|
|
|
|
regs_buff[5] = E1000_READ_REG(hw, E1000_RDLEN(0));
|
|
|
|
regs_buff[6] = E1000_READ_REG(hw, E1000_RDH(0));
|
|
|
|
regs_buff[7] = E1000_READ_REG(hw, E1000_RDT(0));
|
|
|
|
regs_buff[8] = E1000_READ_REG(hw, E1000_RXDCTL(0));
|
|
|
|
regs_buff[9] = E1000_READ_REG(hw, E1000_RDBAL(0));
|
|
|
|
regs_buff[10] = E1000_READ_REG(hw, E1000_RDBAH(0));
|
|
|
|
regs_buff[11] = E1000_READ_REG(hw, E1000_TCTL);
|
|
|
|
regs_buff[12] = E1000_READ_REG(hw, E1000_TDBAL(0));
|
|
|
|
regs_buff[13] = E1000_READ_REG(hw, E1000_TDBAH(0));
|
|
|
|
regs_buff[14] = E1000_READ_REG(hw, E1000_TDLEN(0));
|
|
|
|
regs_buff[15] = E1000_READ_REG(hw, E1000_TDH(0));
|
|
|
|
regs_buff[16] = E1000_READ_REG(hw, E1000_TDT(0));
|
|
|
|
regs_buff[17] = E1000_READ_REG(hw, E1000_TXDCTL(0));
|
|
|
|
regs_buff[18] = E1000_READ_REG(hw, E1000_TDFH);
|
|
|
|
regs_buff[19] = E1000_READ_REG(hw, E1000_TDFT);
|
|
|
|
regs_buff[20] = E1000_READ_REG(hw, E1000_TDFHS);
|
|
|
|
regs_buff[21] = E1000_READ_REG(hw, E1000_TDFPC);
|
|
|
|
|
|
|
|
sbuf_printf(sb, "General Registers\n");
|
|
|
|
sbuf_printf(sb, "\tCTRL\t %08x\n", regs_buff[0]);
|
|
|
|
sbuf_printf(sb, "\tSTATUS\t %08x\n", regs_buff[1]);
|
|
|
|
sbuf_printf(sb, "\tCTRL_EXIT\t %08x\n\n", regs_buff[2]);
|
|
|
|
|
|
|
|
sbuf_printf(sb, "Interrupt Registers\n");
|
|
|
|
sbuf_printf(sb, "\tICR\t %08x\n\n", regs_buff[3]);
|
|
|
|
|
|
|
|
sbuf_printf(sb, "RX Registers\n");
|
|
|
|
sbuf_printf(sb, "\tRCTL\t %08x\n", regs_buff[4]);
|
|
|
|
sbuf_printf(sb, "\tRDLEN\t %08x\n", regs_buff[5]);
|
|
|
|
sbuf_printf(sb, "\tRDH\t %08x\n", regs_buff[6]);
|
|
|
|
sbuf_printf(sb, "\tRDT\t %08x\n", regs_buff[7]);
|
|
|
|
sbuf_printf(sb, "\tRXDCTL\t %08x\n", regs_buff[8]);
|
|
|
|
sbuf_printf(sb, "\tRDBAL\t %08x\n", regs_buff[9]);
|
|
|
|
sbuf_printf(sb, "\tRDBAH\t %08x\n\n", regs_buff[10]);
|
|
|
|
|
|
|
|
sbuf_printf(sb, "TX Registers\n");
|
|
|
|
sbuf_printf(sb, "\tTCTL\t %08x\n", regs_buff[11]);
|
|
|
|
sbuf_printf(sb, "\tTDBAL\t %08x\n", regs_buff[12]);
|
|
|
|
sbuf_printf(sb, "\tTDBAH\t %08x\n", regs_buff[13]);
|
|
|
|
sbuf_printf(sb, "\tTDLEN\t %08x\n", regs_buff[14]);
|
|
|
|
sbuf_printf(sb, "\tTDH\t %08x\n", regs_buff[15]);
|
|
|
|
sbuf_printf(sb, "\tTDT\t %08x\n", regs_buff[16]);
|
|
|
|
sbuf_printf(sb, "\tTXDCTL\t %08x\n", regs_buff[17]);
|
|
|
|
sbuf_printf(sb, "\tTDFH\t %08x\n", regs_buff[18]);
|
|
|
|
sbuf_printf(sb, "\tTDFT\t %08x\n", regs_buff[19]);
|
|
|
|
sbuf_printf(sb, "\tTDFHS\t %08x\n", regs_buff[20]);
|
|
|
|
sbuf_printf(sb, "\tTDFPC\t %08x\n\n", regs_buff[21]);
|
|
|
|
|
|
|
|
#ifdef DUMP_DESCS
|
|
|
|
{
|
|
|
|
if_softc_ctx_t scctx = adapter->shared;
|
|
|
|
struct rx_ring *rxr = &rx_que->rxr;
|
|
|
|
struct tx_ring *txr = &tx_que->txr;
|
|
|
|
int ntxd = scctx->isc_ntxd[0];
|
|
|
|
int nrxd = scctx->isc_nrxd[0];
|
|
|
|
int j;
|
|
|
|
|
|
|
|
for (j = 0; j < nrxd; j++) {
|
|
|
|
u32 staterr = le32toh(rxr->rx_base[j].wb.upper.status_error);
|
|
|
|
u32 length = le32toh(rxr->rx_base[j].wb.upper.length);
|
|
|
|
sbuf_printf(sb, "\tReceive Descriptor Address %d: %08" PRIx64 " Error:%d Length:%d\n", j, rxr->rx_base[j].read.buffer_addr, staterr, length);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j = 0; j < min(ntxd, 256); j++) {
|
|
|
|
struct em_txbuffer *buf = &txr->tx_buffers[j];
|
|
|
|
unsigned int *ptr = (unsigned int *)&txr->tx_base[j];
|
|
|
|
|
|
|
|
sbuf_printf(sb, "\tTXD[%03d] [0]: %08x [1]: %08x [2]: %08x [3]: %08x eop: %d DD=%d\n",
|
|
|
|
j, ptr[0], ptr[1], ptr[2], ptr[3], buf->eop,
|
|
|
|
buf->eop != -1 ? txr->tx_base[buf->eop].upper.fields.status & E1000_TXD_STAT_DD : 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
rc = sbuf_finish(sb);
|
|
|
|
sbuf_delete(sb);
|
|
|
|
return(rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
em_register(device_t dev)
|
|
|
|
{
|
|
|
|
return (em_sctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
|
|
|
igb_register(device_t dev)
|
|
|
|
{
|
|
|
|
return (igb_sctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
em_init_tx_ring(struct em_tx_queue *que)
|
|
|
|
{
|
|
|
|
struct adapter *sc = que->adapter;
|
|
|
|
if_softc_ctx_t scctx = sc->shared;
|
|
|
|
struct tx_ring *txr = &que->txr;
|
|
|
|
struct em_txbuffer *tx_buffer;
|
|
|
|
|
|
|
|
tx_buffer = txr->tx_buffers;
|
|
|
|
for (int i = 0; i < scctx->isc_ntxd[0]; i++, tx_buffer++) {
|
|
|
|
tx_buffer->eop = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
em_set_num_queues(if_ctx_t ctx)
|
|
|
|
{
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
int maxqueues;
|
|
|
|
|
|
|
|
/* Sanity check based on HW */
|
|
|
|
switch (adapter->hw.mac.type) {
|
|
|
|
case e1000_82576:
|
|
|
|
case e1000_82580:
|
|
|
|
case e1000_i350:
|
|
|
|
case e1000_i354:
|
|
|
|
maxqueues = 8;
|
|
|
|
break;
|
|
|
|
case e1000_i210:
|
|
|
|
case e1000_82575:
|
|
|
|
maxqueues = 4;
|
|
|
|
break;
|
|
|
|
case e1000_i211:
|
|
|
|
case e1000_82574:
|
|
|
|
maxqueues = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
maxqueues = 1;
|
|
|
|
break;
|
2002-06-03 22:30:51 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
return (maxqueues);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
#define EM_CAPS \
|
|
|
|
IFCAP_TSO4 | IFCAP_TXCSUM | IFCAP_LRO | IFCAP_RXCSUM | IFCAP_VLAN_HWFILTER | IFCAP_WOL_MAGIC | \
|
|
|
|
IFCAP_WOL_MCAST | IFCAP_WOL | IFCAP_VLAN_HWTSO | IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING | \
|
|
|
|
IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWTSO | IFCAP_VLAN_MTU;
|
|
|
|
|
|
|
|
#define IGB_CAPS \
|
|
|
|
IFCAP_TSO4 | IFCAP_TXCSUM | IFCAP_LRO | IFCAP_RXCSUM | IFCAP_VLAN_HWFILTER | IFCAP_WOL_MAGIC | \
|
|
|
|
IFCAP_WOL_MCAST | IFCAP_WOL | IFCAP_VLAN_HWTSO | IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWCSUM | \
|
|
|
|
IFCAP_VLAN_HWTSO | IFCAP_VLAN_MTU | IFCAP_TXCSUM_IPV6 | IFCAP_HWCSUM_IPV6 | IFCAP_JUMBO_MTU;
|
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* Device initialization routine
|
|
|
|
*
|
|
|
|
* The attach entry point is called when the driver is being loaded.
|
2006-01-20 11:38:25 +00:00
|
|
|
* This routine identifies the type of hardware, allocates all resources
|
|
|
|
* and initializes the hardware.
|
|
|
|
*
|
2001-12-02 07:37:17 +00:00
|
|
|
* return 0 on success, positive on failure
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_attach_pre(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter;
|
|
|
|
if_softc_ctx_t scctx;
|
|
|
|
device_t dev;
|
2011-03-18 18:54:00 +00:00
|
|
|
struct e1000_hw *hw;
|
2003-06-05 17:51:38 +00:00
|
|
|
int error = 0;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
INIT_DEBUGOUT("em_if_attach_pre begin");
|
|
|
|
dev = iflib_get_dev(ctx);
|
|
|
|
adapter = iflib_get_softc(ctx);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2012-10-22 13:06:09 +00:00
|
|
|
if (resource_disabled("em", device_get_unit(dev))) {
|
|
|
|
device_printf(dev, "Disabled by device hint\n");
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
adapter->ctx = ctx;
|
2006-08-03 19:05:04 +00:00
|
|
|
adapter->dev = adapter->osdep.dev = dev;
|
2017-01-10 03:23:22 +00:00
|
|
|
scctx = adapter->shared = iflib_get_softc_ctx(ctx);
|
|
|
|
adapter->media = iflib_get_media(ctx);
|
|
|
|
hw = &adapter->hw;
|
|
|
|
|
|
|
|
adapter->tx_process_limit = scctx->isc_ntxd[0];
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2003-06-05 17:51:38 +00:00
|
|
|
/* SYSCTL stuff */
|
2006-02-15 08:39:50 +00:00
|
|
|
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
2010-06-16 20:57:41 +00:00
|
|
|
OID_AUTO, "nvm", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
|
|
|
|
em_sysctl_nvm_info, "I", "NVM Information");
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
|
|
|
OID_AUTO, "debug", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
|
|
|
|
em_sysctl_debug_info, "I", "Debug Information");
|
|
|
|
|
2011-12-10 07:08:52 +00:00
|
|
|
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
|
|
|
OID_AUTO, "fc", CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
|
|
|
|
em_set_flowcntl, "I", "Flow Control");
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
|
|
|
OID_AUTO, "reg_dump", CTLTYPE_STRING | CTLFLAG_RD, adapter, 0,
|
|
|
|
em_get_regs, "A", "Dump Registers");
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2007-05-17 00:14:03 +00:00
|
|
|
/* Determine hardware and mac info */
|
2017-01-10 03:23:22 +00:00
|
|
|
em_identify_hardware(ctx);
|
|
|
|
|
|
|
|
/* Set isc_msix_bar */
|
|
|
|
scctx->isc_msix_bar = PCIR_BAR(EM_MSIX_BAR);
|
|
|
|
scctx->isc_tx_nsegments = EM_MAX_SCATTER;
|
|
|
|
scctx->isc_tx_tso_segments_max = scctx->isc_tx_nsegments;
|
|
|
|
scctx->isc_tx_tso_size_max = EM_TSO_SIZE;
|
|
|
|
scctx->isc_tx_tso_segsize_max = EM_TSO_SEG_SIZE;
|
|
|
|
scctx->isc_nrxqsets_max = scctx->isc_ntxqsets_max = em_set_num_queues(ctx);
|
|
|
|
device_printf(dev, "attach_pre capping queues at %d\n", scctx->isc_ntxqsets_max);
|
|
|
|
|
|
|
|
scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO;
|
|
|
|
|
|
|
|
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min) {
|
2017-01-12 14:18:52 +00:00
|
|
|
int try_second_bar;
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
scctx->isc_txqsizes[0] = roundup2(scctx->isc_ntxd[0] * sizeof(union e1000_adv_tx_desc), EM_DBA_ALIGN);
|
|
|
|
scctx->isc_rxqsizes[0] = roundup2(scctx->isc_nrxd[0] * sizeof(union e1000_adv_rx_desc), EM_DBA_ALIGN);
|
|
|
|
scctx->isc_txrx = &igb_txrx;
|
|
|
|
scctx->isc_capenable = IGB_CAPS;
|
|
|
|
scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_TSO | CSUM_IP6_TCP \
|
|
|
|
| CSUM_IP6_UDP | CSUM_IP6_TCP;
|
|
|
|
if (adapter->hw.mac.type != e1000_82575)
|
|
|
|
scctx->isc_tx_csum_flags |= CSUM_SCTP | CSUM_IP6_SCTP;
|
|
|
|
|
2017-01-12 14:18:52 +00:00
|
|
|
/*
|
|
|
|
** Some new devices, as with ixgbe, now may
|
|
|
|
** use a different BAR, so we need to keep
|
|
|
|
** track of which is used.
|
|
|
|
*/
|
|
|
|
try_second_bar = pci_read_config(dev, scctx->isc_msix_bar, 4);
|
|
|
|
if (try_second_bar == 0)
|
|
|
|
scctx->isc_msix_bar += 4;
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
} else if (adapter->hw.mac.type >= em_mac_min) {
|
|
|
|
scctx->isc_txqsizes[0] = roundup2(scctx->isc_ntxd[0]* sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
|
|
|
|
scctx->isc_rxqsizes[0] = roundup2(scctx->isc_nrxd[0] * sizeof(union e1000_rx_desc_extended), EM_DBA_ALIGN);
|
|
|
|
scctx->isc_txrx = &em_txrx;
|
|
|
|
scctx->isc_capenable = EM_CAPS;
|
|
|
|
scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO;
|
|
|
|
} else {
|
|
|
|
scctx->isc_txqsizes[0] = roundup2((scctx->isc_ntxd[0] + 1) * sizeof(struct e1000_tx_desc), EM_DBA_ALIGN);
|
|
|
|
scctx->isc_rxqsizes[0] = roundup2((scctx->isc_nrxd[0] + 1) * sizeof(struct e1000_rx_desc), EM_DBA_ALIGN);
|
|
|
|
scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO;
|
|
|
|
scctx->isc_txrx = &lem_txrx;
|
|
|
|
scctx->isc_capenable = EM_CAPS;
|
|
|
|
if (adapter->hw.mac.type < e1000_82543)
|
|
|
|
scctx->isc_capenable &= ~(IFCAP_HWCSUM|IFCAP_VLAN_HWCSUM);
|
|
|
|
scctx->isc_tx_csum_flags = CSUM_TCP | CSUM_UDP | CSUM_IP_TSO;
|
|
|
|
scctx->isc_msix_bar = 0;
|
|
|
|
}
|
2003-08-01 17:33:59 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/* Setup PCI resources */
|
2017-01-10 03:23:22 +00:00
|
|
|
if (em_allocate_pci_resources(ctx)) {
|
2007-05-04 00:00:12 +00:00
|
|
|
device_printf(dev, "Allocation of PCI resources failed\n");
|
|
|
|
error = ENXIO;
|
|
|
|
goto err_pci;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** For ICH8 and family we need to
|
|
|
|
** map the flash memory, and this
|
|
|
|
** must happen after the MAC is
|
|
|
|
** identified
|
|
|
|
*/
|
2011-03-18 18:54:00 +00:00
|
|
|
if ((hw->mac.type == e1000_ich8lan) ||
|
|
|
|
(hw->mac.type == e1000_ich9lan) ||
|
|
|
|
(hw->mac.type == e1000_ich10lan) ||
|
|
|
|
(hw->mac.type == e1000_pchlan) ||
|
2013-02-21 00:25:45 +00:00
|
|
|
(hw->mac.type == e1000_pch2lan) ||
|
|
|
|
(hw->mac.type == e1000_pch_lpt)) {
|
2007-05-04 00:00:12 +00:00
|
|
|
int rid = EM_BAR_TYPE_FLASH;
|
2008-02-29 21:50:11 +00:00
|
|
|
adapter->flash = bus_alloc_resource_any(dev,
|
2007-05-04 00:00:12 +00:00
|
|
|
SYS_RES_MEMORY, &rid, RF_ACTIVE);
|
2008-02-29 21:50:11 +00:00
|
|
|
if (adapter->flash == NULL) {
|
|
|
|
device_printf(dev, "Mapping of Flash failed\n");
|
|
|
|
error = ENXIO;
|
|
|
|
goto err_pci;
|
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
/* This is used in the shared code */
|
2011-03-18 18:54:00 +00:00
|
|
|
hw->flash_address = (u8 *)adapter->flash;
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->osdep.flash_bus_space_tag =
|
2008-02-29 21:50:11 +00:00
|
|
|
rman_get_bustag(adapter->flash);
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->osdep.flash_bus_space_handle =
|
2008-02-29 21:50:11 +00:00
|
|
|
rman_get_bushandle(adapter->flash);
|
2007-05-04 00:00:12 +00:00
|
|
|
}
|
2016-02-05 17:14:37 +00:00
|
|
|
/*
|
|
|
|
** In the new SPT device flash is not a
|
2016-05-06 22:54:56 +00:00
|
|
|
** separate BAR, rather it is also in BAR0,
|
2016-02-05 17:14:37 +00:00
|
|
|
** so use the same tag and an offset handle for the
|
|
|
|
** FLASH read/write macros in the shared code.
|
|
|
|
*/
|
|
|
|
else if (hw->mac.type == e1000_pch_spt) {
|
|
|
|
adapter->osdep.flash_bus_space_tag =
|
|
|
|
adapter->osdep.mem_bus_space_tag;
|
|
|
|
adapter->osdep.flash_bus_space_handle =
|
|
|
|
adapter->osdep.mem_bus_space_handle
|
|
|
|
+ E1000_FLASH_BASE_ADDR;
|
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
|
|
|
|
/* Do Shared Code initialization */
|
2016-02-05 17:14:37 +00:00
|
|
|
error = e1000_setup_init_funcs(hw, TRUE);
|
|
|
|
if (error) {
|
|
|
|
device_printf(dev, "Setup of Shared code failed, error %d\n",
|
|
|
|
error);
|
2007-05-04 00:00:12 +00:00
|
|
|
error = ENXIO;
|
|
|
|
goto err_pci;
|
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_setup_msix(ctx);
|
2011-03-18 18:54:00 +00:00
|
|
|
e1000_get_bus_info(hw);
|
2007-05-04 00:00:12 +00:00
|
|
|
|
2003-08-01 17:33:59 +00:00
|
|
|
/* Set up some sysctls for the tunable interrupt delays */
|
2006-08-03 19:05:04 +00:00
|
|
|
em_add_int_delay_sysctl(adapter, "rx_int_delay",
|
|
|
|
"receive interrupt delay in usecs", &adapter->rx_int_delay,
|
2011-03-18 18:54:00 +00:00
|
|
|
E1000_REGISTER(hw, E1000_RDTR), em_rx_int_delay_dflt);
|
2006-08-03 19:05:04 +00:00
|
|
|
em_add_int_delay_sysctl(adapter, "tx_int_delay",
|
|
|
|
"transmit interrupt delay in usecs", &adapter->tx_int_delay,
|
2011-03-18 18:54:00 +00:00
|
|
|
E1000_REGISTER(hw, E1000_TIDV), em_tx_int_delay_dflt);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
em_add_int_delay_sysctl(adapter, "rx_abs_int_delay",
|
|
|
|
"receive interrupt delay limit in usecs",
|
|
|
|
&adapter->rx_abs_int_delay,
|
2011-03-18 18:54:00 +00:00
|
|
|
E1000_REGISTER(hw, E1000_RADV),
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
em_rx_abs_int_delay_dflt);
|
|
|
|
em_add_int_delay_sysctl(adapter, "tx_abs_int_delay",
|
|
|
|
"transmit interrupt delay limit in usecs",
|
|
|
|
&adapter->tx_abs_int_delay,
|
2011-03-18 18:54:00 +00:00
|
|
|
E1000_REGISTER(hw, E1000_TADV),
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
em_tx_abs_int_delay_dflt);
|
2013-05-09 17:07:30 +00:00
|
|
|
em_add_int_delay_sysctl(adapter, "itr",
|
|
|
|
"interrupt delay limit in usecs/4",
|
|
|
|
&adapter->tx_itr,
|
|
|
|
E1000_REGISTER(hw, E1000_ITR),
|
|
|
|
DEFAULT_ITR);
|
2005-11-17 10:13:18 +00:00
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
/* Sysctl for limiting the amount of work done in the taskqueue */
|
2011-03-18 18:54:00 +00:00
|
|
|
em_set_sysctl_value(adapter, "rx_processing_limit",
|
2006-10-28 08:11:07 +00:00
|
|
|
"max number of rx packets to process", &adapter->rx_process_limit,
|
|
|
|
em_rx_process_limit);
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2011-03-18 18:54:00 +00:00
|
|
|
hw->mac.autoneg = DO_AUTO_NEG;
|
|
|
|
hw->phy.autoneg_wait_to_complete = FALSE;
|
|
|
|
hw->phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
|
2007-05-04 00:00:12 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type < em_mac_min) {
|
|
|
|
e1000_init_script_state_82541(&adapter->hw, TRUE);
|
|
|
|
e1000_set_tbi_compatibility_82543(&adapter->hw, TRUE);
|
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
/* Copper options */
|
2011-03-18 18:54:00 +00:00
|
|
|
if (hw->phy.media_type == e1000_media_type_copper) {
|
|
|
|
hw->phy.mdix = AUTO_ALL_MODES;
|
|
|
|
hw->phy.disable_polarity_correction = FALSE;
|
|
|
|
hw->phy.ms_type = EM_MASTER_SLAVE;
|
2007-05-04 00:00:12 +00:00
|
|
|
}
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2006-01-20 11:38:25 +00:00
|
|
|
/*
|
2007-11-20 21:41:22 +00:00
|
|
|
* Set the frame limits assuming
|
|
|
|
* standard ethernet sized frames.
|
2006-01-20 11:38:25 +00:00
|
|
|
*/
|
2013-02-21 00:25:45 +00:00
|
|
|
adapter->hw.mac.max_frame_size =
|
|
|
|
ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2006-01-20 11:38:25 +00:00
|
|
|
/*
|
|
|
|
* This controls when hardware reports transmit completion
|
|
|
|
* status.
|
2003-03-21 21:47:31 +00:00
|
|
|
*/
|
2011-03-18 18:54:00 +00:00
|
|
|
hw->mac.report_tx_early = 1;
|
2003-03-21 21:47:31 +00:00
|
|
|
|
2010-08-28 00:34:22 +00:00
|
|
|
/* Allocate multicast array memory. */
|
|
|
|
adapter->mta = malloc(sizeof(u8) * ETH_ADDR_LEN *
|
|
|
|
MAX_NUM_MULTICAST_ADDRESSES, M_DEVBUF, M_NOWAIT);
|
|
|
|
if (adapter->mta == NULL) {
|
|
|
|
device_printf(dev, "Can not allocate multicast setup array\n");
|
|
|
|
error = ENOMEM;
|
|
|
|
goto err_late;
|
|
|
|
}
|
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
/* Check SOL/IDER usage */
|
2011-03-18 18:54:00 +00:00
|
|
|
if (e1000_check_reset_block(hw))
|
2010-10-26 00:07:58 +00:00
|
|
|
device_printf(dev, "PHY reset is blocked"
|
|
|
|
" due to SOL/IDER session.\n");
|
|
|
|
|
2011-03-18 18:54:00 +00:00
|
|
|
/* Sysctl for setting Energy Efficient Ethernet */
|
2012-07-07 20:21:05 +00:00
|
|
|
hw->dev_spec.ich8lan.eee_disable = eee_setting;
|
|
|
|
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
|
|
|
OID_AUTO, "eee_control", CTLTYPE_INT|CTLFLAG_RW,
|
|
|
|
adapter, 0, em_sysctl_eee, "I",
|
|
|
|
"Disable Energy Efficient Ethernet");
|
2011-03-18 18:54:00 +00:00
|
|
|
|
2009-04-10 00:05:46 +00:00
|
|
|
/*
|
|
|
|
** Start from a known state, this is
|
|
|
|
** important in reading the nvm and
|
|
|
|
** mac from that.
|
|
|
|
*/
|
2011-03-18 18:54:00 +00:00
|
|
|
e1000_reset_hw(hw);
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/* Make sure we have a good EEPROM before we read from it */
|
2011-03-18 18:54:00 +00:00
|
|
|
if (e1000_validate_nvm_checksum(hw) < 0) {
|
2007-05-04 00:00:12 +00:00
|
|
|
/*
|
|
|
|
** Some PCI-E parts fail the first check due to
|
|
|
|
** the link being in sleep state, call it again,
|
|
|
|
** if it fails a second time its a real issue.
|
|
|
|
*/
|
2011-03-18 18:54:00 +00:00
|
|
|
if (e1000_validate_nvm_checksum(hw) < 0) {
|
2007-05-04 00:00:12 +00:00
|
|
|
device_printf(dev,
|
|
|
|
"The EEPROM Checksum Is Not Valid\n");
|
|
|
|
error = EIO;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
goto err_late;
|
2007-05-04 00:00:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-07-16 16:55:03 +00:00
|
|
|
/* Copy the permanent MAC address out of the EEPROM */
|
2011-03-18 18:54:00 +00:00
|
|
|
if (e1000_read_mac_addr(hw) < 0) {
|
2006-02-15 08:39:50 +00:00
|
|
|
device_printf(dev, "EEPROM read error while reading MAC"
|
|
|
|
" address\n");
|
2003-06-05 17:51:38 +00:00
|
|
|
error = EIO;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
goto err_late;
|
2002-07-16 16:55:03 +00:00
|
|
|
}
|
|
|
|
|
2011-03-18 18:54:00 +00:00
|
|
|
if (!em_is_valid_ether_addr(hw->mac.addr)) {
|
2006-02-15 08:39:50 +00:00
|
|
|
device_printf(dev, "Invalid MAC address\n");
|
|
|
|
error = EIO;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
goto err_late;
|
2007-11-20 21:41:22 +00:00
|
|
|
}
|
|
|
|
|
2014-06-26 21:33:32 +00:00
|
|
|
/* Disable ULP support */
|
|
|
|
e1000_disable_ulp_lpt_lp(hw, TRUE);
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*
|
2009-12-08 01:07:44 +00:00
|
|
|
* Get Wake-on-Lan and Management info for later use
|
|
|
|
*/
|
2017-01-10 03:23:22 +00:00
|
|
|
em_get_wakeup(ctx);
|
|
|
|
|
|
|
|
iflib_set_mac(ctx, hw->mac.addr);
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
|
|
|
|
err_late:
|
|
|
|
em_release_hw_control(adapter);
|
|
|
|
err_pci:
|
|
|
|
em_free_pci_resources(ctx);
|
|
|
|
free(adapter->mta, M_DEVBUF);
|
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
2009-12-08 01:07:44 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static int
|
|
|
|
em_if_attach_post(if_ctx_t ctx)
|
|
|
|
{
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
int error = 0;
|
|
|
|
|
2002-06-03 22:30:51 +00:00
|
|
|
/* Setup OS specific network interface */
|
2017-01-10 03:23:22 +00:00
|
|
|
error = em_setup_interface(ctx);
|
|
|
|
if (error != 0) {
|
2010-08-28 00:09:19 +00:00
|
|
|
goto err_late;
|
2017-01-10 03:23:22 +00:00
|
|
|
}
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_reset(ctx);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2002-06-03 22:30:51 +00:00
|
|
|
/* Initialize statistics */
|
2006-08-03 19:05:04 +00:00
|
|
|
em_update_stats_counters(adapter);
|
2011-03-18 18:54:00 +00:00
|
|
|
hw->mac.get_link_status = 1;
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_update_admin_status(ctx);
|
2010-06-16 20:57:41 +00:00
|
|
|
em_add_hw_stats(adapter);
|
|
|
|
|
2009-12-08 01:07:44 +00:00
|
|
|
/* Non-AMT based hardware can now take control from firmware */
|
|
|
|
if (adapter->has_manage && !adapter->has_amt)
|
|
|
|
em_get_hw_control(adapter);
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
INIT_DEBUGOUT("em_if_attach_post: end");
|
2009-12-08 01:07:44 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
return (error);
|
2006-02-15 08:39:50 +00:00
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
err_late:
|
2007-05-04 00:00:12 +00:00
|
|
|
em_release_hw_control(adapter);
|
2017-01-10 03:23:22 +00:00
|
|
|
em_free_pci_resources(ctx);
|
|
|
|
em_if_queues_free(ctx);
|
2010-08-28 00:34:22 +00:00
|
|
|
free(adapter->mta, M_DEVBUF);
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
return (error);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
* Device removal routine
|
|
|
|
*
|
|
|
|
* The detach entry point is called when the driver is being removed.
|
|
|
|
* This routine stops the adapter and deallocates all the resources
|
|
|
|
* that were allocated for driver operation.
|
2006-01-20 11:38:25 +00:00
|
|
|
*
|
2001-12-02 07:37:17 +00:00
|
|
|
* return 0 on success, positive on failure
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_detach(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
|
|
|
INIT_DEBUGOUT("em_detach: begin");
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
e1000_phy_hw_reset(&adapter->hw);
|
|
|
|
|
|
|
|
em_release_manageability(adapter);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
em_release_hw_control(adapter);
|
2017-01-10 03:23:22 +00:00
|
|
|
em_free_pci_resources(ctx);
|
2003-10-10 23:14:21 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
return (0);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2002-11-08 18:14:17 +00:00
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Shutdown entry point
|
2002-12-23 19:11:23 +00:00
|
|
|
*
|
2006-01-20 11:38:25 +00:00
|
|
|
**********************************************************************/
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_shutdown(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
return em_if_suspend(ctx);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2005-12-26 10:39:21 +00:00
|
|
|
/*
|
|
|
|
* Suspend/resume device methods.
|
|
|
|
*/
|
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_suspend(if_ctx_t ctx)
|
2005-12-26 10:39:21 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2007-11-26 19:47:03 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
em_release_manageability(adapter);
|
2009-12-08 01:07:44 +00:00
|
|
|
em_release_hw_control(adapter);
|
2017-01-10 03:23:22 +00:00
|
|
|
em_enable_wakeup(ctx);
|
|
|
|
return (0);
|
2005-12-26 10:39:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_resume(if_ctx_t ctx)
|
2005-12-26 10:39:21 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2005-12-26 10:39:21 +00:00
|
|
|
|
2011-12-10 07:08:52 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_pch2lan)
|
|
|
|
e1000_resume_workarounds_pchlan(&adapter->hw);
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_init(ctx);
|
2007-05-04 00:00:12 +00:00
|
|
|
em_init_manageability(adapter);
|
2012-03-30 19:54:48 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
return(0);
|
|
|
|
}
|
2005-12-26 10:39:21 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static int
|
|
|
|
em_if_mtu_set(if_ctx_t ctx, uint32_t mtu)
|
|
|
|
{
|
|
|
|
int max_frame_size;
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
|
|
|
|
|
|
|
IOCTL_DEBUGOUT("ioctl rcv'd: SIOCSIFMTU (Set Interface MTU)");
|
|
|
|
|
|
|
|
switch (adapter->hw.mac.type) {
|
|
|
|
case e1000_82571:
|
|
|
|
case e1000_82572:
|
|
|
|
case e1000_ich9lan:
|
|
|
|
case e1000_ich10lan:
|
|
|
|
case e1000_pch2lan:
|
|
|
|
case e1000_pch_lpt:
|
|
|
|
case e1000_pch_spt:
|
|
|
|
case e1000_82574:
|
|
|
|
case e1000_82583:
|
|
|
|
case e1000_80003es2lan: /* 9K Jumbo Frame size */
|
|
|
|
max_frame_size = 9234;
|
|
|
|
break;
|
|
|
|
case e1000_pchlan:
|
|
|
|
max_frame_size = 4096;
|
|
|
|
break;
|
|
|
|
/* Adapters that do not support jumbo frames */
|
|
|
|
case e1000_ich8lan:
|
|
|
|
max_frame_size = ETHER_MAX_LEN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
max_frame_size = MAX_JUMBO_FRAME_SIZE;
|
|
|
|
}
|
|
|
|
if (mtu > max_frame_size - ETHER_HDR_LEN - ETHER_CRC_LEN) {
|
|
|
|
return (EINVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
adapter->hw.mac.max_frame_size = if_getmtu(ifp) + ETHER_HDR_LEN + ETHER_CRC_LEN;
|
|
|
|
return (0);
|
2005-12-26 10:39:21 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*********************************************************************
|
|
|
|
* Init entry point
|
|
|
|
*
|
|
|
|
* This routine is used in two ways. It is used by the stack as
|
|
|
|
* init entry point in network interface structure. It is also used
|
|
|
|
* by the driver as a hw/sw initialization routine to get to a
|
|
|
|
* consistent state.
|
|
|
|
*
|
|
|
|
* return 0 on success, positive on failure
|
|
|
|
**********************************************************************/
|
2002-12-23 19:11:23 +00:00
|
|
|
|
2009-04-14 03:36:59 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_init(if_ctx_t ctx)
|
2009-04-14 03:36:59 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
2009-04-14 03:36:59 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
INIT_DEBUGOUT("em_if_init: begin");
|
2009-04-14 03:36:59 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Get the latest mac address, User can use a LAA */
|
|
|
|
bcopy(if_getlladdr(ifp), adapter->hw.mac.addr,
|
|
|
|
ETHER_ADDR_LEN);
|
2015-06-02 18:28:41 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Put the address into the Receive Address Array */
|
|
|
|
e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*
|
|
|
|
* With the 82571 adapter, RAR[0] may be overwritten
|
|
|
|
* when the other port is reset, we make a duplicate
|
|
|
|
* in RAR[14] for that eventuality, this assures
|
|
|
|
* the interface continues to function.
|
|
|
|
*/
|
|
|
|
if (adapter->hw.mac.type == e1000_82571) {
|
|
|
|
e1000_set_laa_state_82571(&adapter->hw, TRUE);
|
|
|
|
e1000_rar_set(&adapter->hw, adapter->hw.mac.addr,
|
|
|
|
E1000_RAR_ENTRIES - 1);
|
2009-04-14 03:36:59 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Initialize the hardware */
|
|
|
|
em_reset(ctx);
|
|
|
|
em_if_update_admin_status(ctx);
|
2009-04-14 03:36:59 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Setup VLAN support, basic and offload if available */
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
|
2003-09-23 00:18:25 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Clear bad data from Rx FIFOs */
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min)
|
|
|
|
e1000_rx_fifo_flush_82575(&adapter->hw);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Configure for OS presence */
|
|
|
|
em_init_manageability(adapter);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Prepare transmit descriptors and buffers */
|
|
|
|
em_initialize_transmit_unit(ctx);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Setup Multicast table */
|
|
|
|
em_if_multi_set(ctx);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*
|
|
|
|
** Figure out the desired mbuf
|
|
|
|
** pool for doing jumbos
|
|
|
|
*/
|
|
|
|
if (adapter->hw.mac.max_frame_size <= 2048)
|
|
|
|
adapter->rx_mbuf_sz = MCLBYTES;
|
|
|
|
else if (adapter->hw.mac.max_frame_size <= 4096)
|
|
|
|
adapter->rx_mbuf_sz = MJUMPAGESIZE;
|
|
|
|
else
|
|
|
|
adapter->rx_mbuf_sz = MJUM9BYTES;
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_initialize_receive_unit(ctx);
|
2006-01-20 11:38:25 +00:00
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
/* Use real VLAN Filter support? */
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) {
|
|
|
|
if (if_getcapenable(ifp) & IFCAP_VLAN_HWFILTER)
|
2010-10-26 00:07:58 +00:00
|
|
|
/* Use real VLAN Filter support */
|
|
|
|
em_setup_vlan_hw_support(adapter);
|
|
|
|
else {
|
|
|
|
u32 ctrl;
|
|
|
|
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
|
|
|
|
ctrl |= E1000_CTRL_VME;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-04 07:56:35 +00:00
|
|
|
/* Don't lose promiscuous settings */
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_set_promisc(ctx, IFF_PROMISC);
|
2007-05-04 00:00:12 +00:00
|
|
|
e1000_clear_hw_cntrs_base_generic(&adapter->hw);
|
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
/* MSI/X configuration for 82574 */
|
|
|
|
if (adapter->hw.mac.type == e1000_82574) {
|
2017-01-10 03:23:22 +00:00
|
|
|
int tmp = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
|
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
tmp |= E1000_CTRL_EXT_PBA_CLR;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, tmp);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Set the IVAR - interrupt vector routing. */
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_IVAR, adapter->ivars);
|
2017-01-10 03:23:22 +00:00
|
|
|
} else if (adapter->intr_type == IFLIB_INTR_MSIX) /* Set up queue routing */
|
|
|
|
igb_configure_queues(adapter);
|
2008-04-02 22:00:36 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* this clears any pending interrupts */
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_ICR);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_ICS, E1000_ICS_LSC);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2009-12-08 01:07:44 +00:00
|
|
|
/* AMT based hardware can now take control from firmware */
|
|
|
|
if (adapter->has_manage && adapter->has_amt)
|
|
|
|
em_get_hw_control(adapter);
|
2003-09-23 00:18:25 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Set Energy Efficient Ethernet */
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min &&
|
|
|
|
adapter->hw.phy.media_type == e1000_media_type_copper) {
|
|
|
|
if (adapter->hw.mac.type == e1000_i354)
|
|
|
|
e1000_set_eee_i354(&adapter->hw, TRUE, TRUE);
|
|
|
|
else
|
|
|
|
e1000_set_eee_i350(&adapter->hw, TRUE, TRUE);
|
2006-02-15 08:39:50 +00:00
|
|
|
}
|
2003-09-23 00:18:25 +00:00
|
|
|
}
|
2008-02-29 21:50:11 +00:00
|
|
|
|
2006-10-28 08:11:07 +00:00
|
|
|
/*********************************************************************
|
|
|
|
*
|
2008-02-29 21:50:11 +00:00
|
|
|
* Fast Legacy/MSI Combined Interrupt Service routine
|
2006-10-28 08:11:07 +00:00
|
|
|
*
|
|
|
|
*********************************************************************/
|
2017-01-10 03:23:22 +00:00
|
|
|
int
|
|
|
|
em_intr(void *arg)
|
2006-10-28 08:11:07 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = arg;
|
|
|
|
if_ctx_t ctx = adapter->ctx;
|
2008-02-29 21:50:11 +00:00
|
|
|
u32 reg_icr;
|
2006-10-28 08:11:07 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
|
2006-10-28 08:11:07 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->intr_type != IFLIB_INTR_LEGACY)
|
|
|
|
goto skip_stray;
|
2006-10-28 08:11:07 +00:00
|
|
|
/* Hot eject? */
|
|
|
|
if (reg_icr == 0xffffffff)
|
2007-11-20 21:41:22 +00:00
|
|
|
return FILTER_STRAY;
|
2006-10-28 08:11:07 +00:00
|
|
|
|
|
|
|
/* Definitely not our interrupt. */
|
|
|
|
if (reg_icr == 0x0)
|
2007-11-20 21:41:22 +00:00
|
|
|
return FILTER_STRAY;
|
2006-10-28 08:11:07 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Starting with the 82571 chip, bit 31 should be used to
|
|
|
|
* determine whether the interrupt belongs to us.
|
|
|
|
*/
|
2007-05-04 00:00:12 +00:00
|
|
|
if (adapter->hw.mac.type >= e1000_82571 &&
|
2006-10-28 08:11:07 +00:00
|
|
|
(reg_icr & E1000_ICR_INT_ASSERTED) == 0)
|
2007-11-20 21:41:22 +00:00
|
|
|
return FILTER_STRAY;
|
2006-10-28 08:11:07 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
skip_stray:
|
2006-10-28 08:11:07 +00:00
|
|
|
/* Link status change */
|
2008-04-02 22:00:36 +00:00
|
|
|
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
|
|
|
|
adapter->hw.mac.get_link_status = 1;
|
2017-01-10 03:23:22 +00:00
|
|
|
iflib_admin_intr_deferred(ctx);
|
2008-04-02 22:00:36 +00:00
|
|
|
}
|
2006-10-28 08:11:07 +00:00
|
|
|
|
|
|
|
if (reg_icr & E1000_ICR_RXO)
|
|
|
|
adapter->rx_overruns++;
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
return (FILTER_SCHEDULE_THREAD);
|
2006-10-28 08:11:07 +00:00
|
|
|
}
|
2008-02-29 21:50:11 +00:00
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
igb_enable_queue(struct adapter *adapter, struct em_rx_queue *rxq)
|
2008-02-29 21:50:11 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIMS, rxq->eims);
|
2008-02-29 21:50:11 +00:00
|
|
|
}
|
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_enable_queue(struct adapter *adapter, struct em_rx_queue *rxq)
|
2008-02-29 21:50:11 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxq->eims);
|
|
|
|
}
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static int
|
|
|
|
em_if_queue_intr_enable(if_ctx_t ctx, uint16_t rxqid)
|
|
|
|
{
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct em_rx_queue *rxq = &adapter->rx_queues[rxqid];
|
|
|
|
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min)
|
|
|
|
igb_enable_queue(adapter, rxq);
|
|
|
|
else
|
|
|
|
em_enable_queue(adapter, rxq);
|
|
|
|
return (0);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* MSIX RX Interrupt Service routine
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
2017-01-10 03:23:22 +00:00
|
|
|
static int
|
|
|
|
em_msix_que(void *arg)
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct em_rx_queue *que = arg;
|
|
|
|
|
|
|
|
++que->irqs;
|
|
|
|
|
|
|
|
return (FILTER_SCHEDULE_THREAD);
|
2008-02-29 21:50:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* MSIX Link Fast Interrupt Service routine
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
2017-01-10 03:23:22 +00:00
|
|
|
static int
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
em_msix_link(void *arg)
|
2008-02-29 21:50:11 +00:00
|
|
|
{
|
|
|
|
struct adapter *adapter = arg;
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
u32 reg_icr;
|
2008-02-29 21:50:11 +00:00
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
++adapter->link_irq;
|
2017-01-10 03:23:22 +00:00
|
|
|
MPASS(adapter->hw.back != NULL);
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
|
2008-02-29 21:50:11 +00:00
|
|
|
|
2015-05-22 17:01:43 +00:00
|
|
|
if (reg_icr & E1000_ICR_RXO)
|
|
|
|
adapter->rx_overruns++;
|
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
|
2017-01-10 03:23:22 +00:00
|
|
|
em_handle_link(adapter->ctx);
|
|
|
|
} else {
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_IMS,
|
2017-01-10 03:23:22 +00:00
|
|
|
EM_MSIX_LINK | E1000_IMS_LSC);
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min)
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIMS, adapter->link_mask);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
/*
|
|
|
|
** Because we must read the ICR for this interrupt
|
|
|
|
** it may clear other causes using autoclear, for
|
|
|
|
** this reason we simply create a soft interrupt
|
|
|
|
** for all these vectors.
|
|
|
|
*/
|
2017-01-10 03:23:22 +00:00
|
|
|
if (reg_icr && adapter->hw.mac.type < igb_mac_min) {
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw,
|
|
|
|
E1000_ICS, adapter->ims);
|
|
|
|
}
|
2009-04-10 00:05:46 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
return (FILTER_HANDLED);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_handle_link(void *context)
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
if_ctx_t ctx = context;
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
adapter->hw.mac.get_link_status = 1;
|
|
|
|
iflib_admin_intr_deferred(ctx);
|
2009-04-10 00:05:46 +00:00
|
|
|
}
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2006-10-28 08:11:07 +00:00
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Media Ioctl callback
|
|
|
|
*
|
|
|
|
* This routine is called whenever the user queries the status of
|
|
|
|
* the interface using ifconfig.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
u_char fiber_type = IFM_1000_SX;
|
|
|
|
|
|
|
|
INIT_DEBUGOUT("em_if_media_status: begin");
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
iflib_admin_intr_deferred(ctx);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2002-11-08 18:14:17 +00:00
|
|
|
ifmr->ifm_status = IFM_AVALID;
|
|
|
|
ifmr->ifm_active = IFM_ETHER;
|
|
|
|
|
2006-09-01 16:08:36 +00:00
|
|
|
if (!adapter->link_active) {
|
2002-11-08 18:14:17 +00:00
|
|
|
return;
|
2006-09-01 16:08:36 +00:00
|
|
|
}
|
2002-11-08 18:14:17 +00:00
|
|
|
|
|
|
|
ifmr->ifm_status |= IFM_ACTIVE;
|
|
|
|
|
2007-11-20 21:41:22 +00:00
|
|
|
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
|
|
|
|
(adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82545)
|
|
|
|
fiber_type = IFM_1000_LX;
|
2007-05-04 00:00:12 +00:00
|
|
|
ifmr->ifm_active |= fiber_type | IFM_FDX;
|
2002-11-08 18:14:17 +00:00
|
|
|
} else {
|
2006-08-03 19:05:04 +00:00
|
|
|
switch (adapter->link_speed) {
|
2002-11-08 18:14:17 +00:00
|
|
|
case 10:
|
|
|
|
ifmr->ifm_active |= IFM_10_T;
|
|
|
|
break;
|
|
|
|
case 100:
|
|
|
|
ifmr->ifm_active |= IFM_100_TX;
|
|
|
|
break;
|
|
|
|
case 1000:
|
|
|
|
ifmr->ifm_active |= IFM_1000_T;
|
|
|
|
break;
|
|
|
|
}
|
2006-08-03 19:05:04 +00:00
|
|
|
if (adapter->link_duplex == FULL_DUPLEX)
|
2002-11-08 18:14:17 +00:00
|
|
|
ifmr->ifm_active |= IFM_FDX;
|
|
|
|
else
|
|
|
|
ifmr->ifm_active |= IFM_HDX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Media Ioctl callback
|
|
|
|
*
|
|
|
|
* This routine is called when the user changes speed/duplex using
|
|
|
|
* media/mediopt option with ifconfig.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_media_change(if_ctx_t ctx)
|
2002-11-08 18:14:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifmedia *ifm = iflib_get_media(ctx);
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
INIT_DEBUGOUT("em_if_media_change: begin");
|
2002-11-08 18:14:17 +00:00
|
|
|
|
|
|
|
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
|
2006-02-15 08:39:50 +00:00
|
|
|
return (EINVAL);
|
2002-11-08 18:14:17 +00:00
|
|
|
|
|
|
|
switch (IFM_SUBTYPE(ifm->ifm_media)) {
|
|
|
|
case IFM_AUTO:
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.autoneg = DO_AUTO_NEG;
|
|
|
|
adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT;
|
2002-11-08 18:14:17 +00:00
|
|
|
break;
|
2006-08-11 10:58:24 +00:00
|
|
|
case IFM_1000_LX:
|
2002-11-08 18:14:17 +00:00
|
|
|
case IFM_1000_SX:
|
|
|
|
case IFM_1000_T:
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.autoneg = DO_AUTO_NEG;
|
|
|
|
adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
|
2002-11-08 18:14:17 +00:00
|
|
|
break;
|
|
|
|
case IFM_100_TX:
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.autoneg = FALSE;
|
|
|
|
adapter->hw.phy.autoneg_advertised = 0;
|
2002-11-08 18:14:17 +00:00
|
|
|
if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_FULL;
|
2002-11-08 18:14:17 +00:00
|
|
|
else
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.forced_speed_duplex = ADVERTISE_100_HALF;
|
2002-11-08 18:14:17 +00:00
|
|
|
break;
|
|
|
|
case IFM_10_T:
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.autoneg = FALSE;
|
|
|
|
adapter->hw.phy.autoneg_advertised = 0;
|
2002-11-08 18:14:17 +00:00
|
|
|
if ((ifm->ifm_media & IFM_GMASK) == IFM_FDX)
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_FULL;
|
2002-11-08 18:14:17 +00:00
|
|
|
else
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.mac.forced_speed_duplex = ADVERTISE_10_HALF;
|
2002-11-08 18:14:17 +00:00
|
|
|
break;
|
|
|
|
default:
|
2006-08-03 19:05:04 +00:00
|
|
|
device_printf(adapter->dev, "Unsupported media type\n");
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_init(ctx);
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
return (0);
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
2006-01-20 11:38:25 +00:00
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_set_promisc(if_ctx_t ctx, int flags)
|
2003-05-02 21:17:08 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
u32 reg_rctl;
|
2004-11-12 11:03:07 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_disable_promisc(ctx);
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (flags & IFF_PROMISC) {
|
2002-11-08 18:14:17 +00:00
|
|
|
reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
/* Turn this on if you want to see bad packets */
|
|
|
|
if (em_debug_sbp)
|
|
|
|
reg_rctl |= E1000_RCTL_SBP;
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
2017-01-10 03:23:22 +00:00
|
|
|
} else if (flags & IFF_ALLMULTI) {
|
2002-11-08 18:14:17 +00:00
|
|
|
reg_rctl |= E1000_RCTL_MPE;
|
|
|
|
reg_rctl &= ~E1000_RCTL_UPE;
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
2006-11-18 23:18:43 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
return (0);
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_disable_promisc(if_ctx_t ctx)
|
2002-11-08 18:14:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
2013-04-03 23:39:54 +00:00
|
|
|
u32 reg_rctl;
|
|
|
|
int mcnt = 0;
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
2002-11-08 18:14:17 +00:00
|
|
|
reg_rctl &= (~E1000_RCTL_UPE);
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getflags(ifp) & IFF_ALLMULTI)
|
2013-04-03 23:39:54 +00:00
|
|
|
mcnt = MAX_NUM_MULTICAST_ADDRESSES;
|
2014-06-02 18:52:03 +00:00
|
|
|
else
|
|
|
|
mcnt = if_multiaddr_count(ifp, MAX_NUM_MULTICAST_ADDRESSES);
|
2013-04-03 23:39:54 +00:00
|
|
|
/* Don't disable if in MAX groups */
|
|
|
|
if (mcnt < MAX_NUM_MULTICAST_ADDRESSES)
|
|
|
|
reg_rctl &= (~E1000_RCTL_MPE);
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
reg_rctl &= (~E1000_RCTL_SBP);
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
* Multicast Update
|
|
|
|
*
|
|
|
|
* This routine is called whenever multicast address list is updated.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_multi_set(if_ctx_t ctx)
|
2002-11-08 18:14:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
2008-02-29 21:50:11 +00:00
|
|
|
u32 reg_rctl = 0;
|
2009-04-10 00:05:46 +00:00
|
|
|
u8 *mta; /* Multicast array memory */
|
2006-02-15 08:39:50 +00:00
|
|
|
int mcnt = 0;
|
2006-01-20 11:38:25 +00:00
|
|
|
|
|
|
|
IOCTL_DEBUGOUT("em_set_multi: begin");
|
|
|
|
|
2010-08-28 00:34:22 +00:00
|
|
|
mta = adapter->mta;
|
|
|
|
bzero(mta, sizeof(u8) * ETH_ADDR_LEN * MAX_NUM_MULTICAST_ADDRESSES);
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82542 &&
|
|
|
|
adapter->hw.revision_id == E1000_REVISION_2) {
|
|
|
|
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
|
|
|
if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
|
|
|
|
e1000_pci_clear_mwi(&adapter->hw);
|
2006-01-20 11:38:25 +00:00
|
|
|
reg_rctl |= E1000_RCTL_RST;
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
2006-01-20 11:38:25 +00:00
|
|
|
msec_delay(5);
|
|
|
|
}
|
2005-08-03 00:18:35 +00:00
|
|
|
|
2014-06-02 18:52:03 +00:00
|
|
|
if_multiaddr_array(ifp, mta, &mcnt, MAX_NUM_MULTICAST_ADDRESSES);
|
2006-01-20 11:38:25 +00:00
|
|
|
|
|
|
|
if (mcnt >= MAX_NUM_MULTICAST_ADDRESSES) {
|
2007-05-04 00:00:12 +00:00
|
|
|
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
2006-01-20 11:38:25 +00:00
|
|
|
reg_rctl |= E1000_RCTL_MPE;
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
2006-01-20 11:38:25 +00:00
|
|
|
} else
|
2009-04-10 00:05:46 +00:00
|
|
|
e1000_update_mc_addr_list(&adapter->hw, mta, mcnt);
|
2002-12-23 19:11:23 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82542 &&
|
|
|
|
adapter->hw.revision_id == E1000_REVISION_2) {
|
|
|
|
reg_rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
2006-01-20 11:38:25 +00:00
|
|
|
reg_rctl &= ~E1000_RCTL_RST;
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, reg_rctl);
|
2006-01-20 11:38:25 +00:00
|
|
|
msec_delay(5);
|
2007-05-04 00:00:12 +00:00
|
|
|
if (adapter->hw.bus.pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
|
|
|
|
e1000_pci_set_mwi(&adapter->hw);
|
2006-01-20 11:38:25 +00:00
|
|
|
}
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
* Timer routine
|
|
|
|
*
|
|
|
|
* This routine checks for link status and updates statistics.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_timer(if_ctx_t ctx, uint16_t qid)
|
2002-11-08 18:14:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct em_rx_queue *que;
|
|
|
|
int i;
|
|
|
|
int trigger = 0;
|
2002-11-08 18:14:17 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_update_admin_status(ctx);
|
2006-08-03 19:05:04 +00:00
|
|
|
em_update_stats_counters(adapter);
|
2007-05-31 23:36:21 +00:00
|
|
|
|
2007-11-20 21:41:22 +00:00
|
|
|
/* Reset LAA into RAR[0] on 82571 */
|
2010-10-26 00:07:58 +00:00
|
|
|
if ((adapter->hw.mac.type == e1000_82571) &&
|
|
|
|
e1000_get_laa_state_82571(&adapter->hw))
|
2007-05-31 23:36:21 +00:00
|
|
|
e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type < em_mac_min)
|
|
|
|
lem_smartspeed(adapter);
|
|
|
|
|
2011-04-01 18:48:31 +00:00
|
|
|
/* Mask to use in the irq trigger */
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->intr_type == IFLIB_INTR_MSIX) {
|
|
|
|
for (i = 0, que = adapter->rx_queues; i < adapter->rx_num_queues; i++, que++)
|
|
|
|
trigger |= que->eims;
|
|
|
|
} else {
|
2011-04-01 18:48:31 +00:00
|
|
|
trigger = E1000_ICS_RXDMT0;
|
2011-12-10 07:08:52 +00:00
|
|
|
}
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2002-11-08 18:14:17 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_update_admin_status(if_ctx_t ctx)
|
2002-11-08 18:14:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2008-04-02 22:00:36 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2017-01-10 03:23:22 +00:00
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
|
|
|
device_t dev = iflib_get_dev(ctx);
|
2008-04-02 22:00:36 +00:00
|
|
|
u32 link_check = 0;
|
|
|
|
|
|
|
|
/* Get the cached link value or read phy for real */
|
|
|
|
switch (hw->phy.media_type) {
|
|
|
|
case e1000_media_type_copper:
|
|
|
|
if (hw->mac.get_link_status) {
|
2016-02-05 17:14:37 +00:00
|
|
|
if (hw->mac.type == e1000_pch_spt)
|
|
|
|
msec_delay(50);
|
2008-04-02 22:00:36 +00:00
|
|
|
/* Do the work to read phy */
|
|
|
|
e1000_check_for_link(hw);
|
|
|
|
link_check = !hw->mac.get_link_status;
|
2008-11-26 23:57:23 +00:00
|
|
|
if (link_check) /* ESB2 fix */
|
|
|
|
e1000_cfg_on_link_up(hw);
|
2017-01-10 03:23:22 +00:00
|
|
|
} else {
|
2008-04-02 22:00:36 +00:00
|
|
|
link_check = TRUE;
|
2017-01-10 03:23:22 +00:00
|
|
|
}
|
2008-04-02 22:00:36 +00:00
|
|
|
break;
|
|
|
|
case e1000_media_type_fiber:
|
|
|
|
e1000_check_for_link(hw);
|
|
|
|
link_check = (E1000_READ_REG(hw, E1000_STATUS) &
|
|
|
|
E1000_STATUS_LU);
|
|
|
|
break;
|
|
|
|
case e1000_media_type_internal_serdes:
|
|
|
|
e1000_check_for_link(hw);
|
|
|
|
link_check = adapter->hw.mac.serdes_has_link;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
case e1000_media_type_unknown:
|
|
|
|
break;
|
|
|
|
}
|
2005-02-04 18:36:04 +00:00
|
|
|
|
2008-04-02 22:00:36 +00:00
|
|
|
/* Now check for a transition */
|
|
|
|
if (link_check && (adapter->link_active == 0)) {
|
|
|
|
e1000_get_speed_and_duplex(hw, &adapter->link_speed,
|
|
|
|
&adapter->link_duplex);
|
|
|
|
/* Check if we must disable SPEED_MODE bit on PCI-E */
|
|
|
|
if ((adapter->link_speed != SPEED_1000) &&
|
|
|
|
((hw->mac.type == e1000_82571) ||
|
|
|
|
(hw->mac.type == e1000_82572))) {
|
|
|
|
int tarc0;
|
|
|
|
tarc0 = E1000_READ_REG(hw, E1000_TARC(0));
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
tarc0 &= ~TARC_SPEED_MODE_BIT;
|
2008-04-02 22:00:36 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_TARC(0), tarc0);
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
2008-04-02 22:00:36 +00:00
|
|
|
if (bootverbose)
|
|
|
|
device_printf(dev, "Link is up %d Mbps %s\n",
|
|
|
|
adapter->link_speed,
|
|
|
|
((adapter->link_duplex == FULL_DUPLEX) ?
|
|
|
|
"Full Duplex" : "Half Duplex"));
|
|
|
|
adapter->link_active = 1;
|
|
|
|
adapter->smartspeed = 0;
|
2014-06-02 18:52:03 +00:00
|
|
|
if_setbaudrate(ifp, adapter->link_speed * 1000000);
|
2017-01-10 03:23:22 +00:00
|
|
|
iflib_link_state_change(ctx, LINK_STATE_UP, ifp->if_baudrate);
|
|
|
|
printf("Link state changed to up\n");
|
2008-04-02 22:00:36 +00:00
|
|
|
} else if (!link_check && (adapter->link_active == 1)) {
|
2014-06-02 18:52:03 +00:00
|
|
|
if_setbaudrate(ifp, 0);
|
|
|
|
adapter->link_speed = 0;
|
2008-04-02 22:00:36 +00:00
|
|
|
adapter->link_duplex = 0;
|
|
|
|
if (bootverbose)
|
|
|
|
device_printf(dev, "Link is Down\n");
|
|
|
|
adapter->link_active = 0;
|
2017-01-10 03:23:22 +00:00
|
|
|
iflib_link_state_change(ctx, LINK_STATE_DOWN, ifp->if_baudrate);
|
|
|
|
printf("link state changed to down\n");
|
2002-11-08 18:14:17 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_LINK | E1000_IMS_LSC);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
2002-11-08 18:14:17 +00:00
|
|
|
* This routine disables all traffic on the adapter by issuing a
|
2006-01-20 11:38:25 +00:00
|
|
|
* global reset on the MAC and deallocates TX/RX buffers.
|
2001-12-02 07:37:17 +00:00
|
|
|
*
|
2007-11-26 19:47:03 +00:00
|
|
|
* This routine should always be called with BOTH the CORE
|
|
|
|
* and TX locks.
|
2001-12-02 07:37:17 +00:00
|
|
|
**********************************************************************/
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2002-11-08 18:14:17 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_stop(if_ctx_t ctx)
|
2002-11-08 18:14:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2003-09-23 00:18:25 +00:00
|
|
|
|
2003-08-27 21:52:37 +00:00
|
|
|
INIT_DEBUGOUT("em_stop: begin");
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
e1000_reset_hw(&adapter->hw);
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type >= e1000_82544)
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0);
|
2010-03-31 20:43:24 +00:00
|
|
|
|
|
|
|
e1000_led_off(&adapter->hw);
|
|
|
|
e1000_cleanup_led(&adapter->hw);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/*********************************************************************
|
2001-12-02 07:37:17 +00:00
|
|
|
*
|
|
|
|
* Determine hardware revision.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_identify_hardware(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
device_t dev = iflib_get_dev(ctx);
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
|
2002-06-03 22:30:51 +00:00
|
|
|
/* Make sure our PCI config space has the necessary stuff set */
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.bus.pci_cmd_word = pci_read_config(dev, PCIR_COMMAND, 2);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
|
|
|
/* Save off the information about this board */
|
2006-08-03 19:05:04 +00:00
|
|
|
adapter->hw.vendor_id = pci_get_vendor(dev);
|
|
|
|
adapter->hw.device_id = pci_get_device(dev);
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->hw.revision_id = pci_read_config(dev, PCIR_REVID, 1);
|
|
|
|
adapter->hw.subsystem_vendor_id =
|
|
|
|
pci_read_config(dev, PCIR_SUBVEND_0, 2);
|
2007-11-20 21:41:22 +00:00
|
|
|
adapter->hw.subsystem_device_id =
|
|
|
|
pci_read_config(dev, PCIR_SUBDEV_0, 2);
|
2007-05-04 00:00:12 +00:00
|
|
|
|
|
|
|
/* Do Shared Code Init and Setup */
|
|
|
|
if (e1000_set_mac_type(&adapter->hw)) {
|
|
|
|
device_printf(dev, "Setup init failure\n");
|
|
|
|
return;
|
|
|
|
}
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_allocate_pci_resources(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
device_t dev = iflib_get_dev(ctx);
|
|
|
|
int rid, val;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2005-11-09 08:43:18 +00:00
|
|
|
rid = PCIR_BAR(0);
|
2008-02-29 21:50:11 +00:00
|
|
|
adapter->memory = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
2006-02-15 08:39:50 +00:00
|
|
|
&rid, RF_ACTIVE);
|
2008-02-29 21:50:11 +00:00
|
|
|
if (adapter->memory == NULL) {
|
2006-02-15 08:39:50 +00:00
|
|
|
device_printf(dev, "Unable to allocate bus resource: memory\n");
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
2006-08-03 19:05:04 +00:00
|
|
|
adapter->osdep.mem_bus_space_tag =
|
2008-02-29 21:50:11 +00:00
|
|
|
rman_get_bustag(adapter->memory);
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->osdep.mem_bus_space_handle =
|
2008-02-29 21:50:11 +00:00
|
|
|
rman_get_bushandle(adapter->memory);
|
|
|
|
adapter->hw.hw_addr = (u8 *)&adapter->osdep.mem_bus_space_handle;
|
2006-02-15 08:39:50 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Only older adapters use IO mapping */
|
|
|
|
if (adapter->hw.mac.type < em_mac_min &&
|
|
|
|
adapter->hw.mac.type > e1000_82543) {
|
|
|
|
/* Figure our where our IO BAR is ? */
|
|
|
|
for (rid = PCIR_BAR(0); rid < PCIR_CIS;) {
|
|
|
|
val = pci_read_config(dev, rid, 4);
|
|
|
|
if (EM_BAR_TYPE(val) == EM_BAR_TYPE_IO) {
|
|
|
|
adapter->io_rid = rid;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rid += 4;
|
|
|
|
/* check for 64bit BAR */
|
|
|
|
if (EM_BAR_MEM_TYPE(val) == EM_BAR_MEM_TYPE_64BIT)
|
|
|
|
rid += 4;
|
|
|
|
}
|
|
|
|
if (rid >= PCIR_CIS) {
|
|
|
|
device_printf(dev, "Unable to locate IO BAR\n");
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
|
|
|
adapter->ioport = bus_alloc_resource_any(dev,
|
|
|
|
SYS_RES_IOPORT, &adapter->io_rid, RF_ACTIVE);
|
|
|
|
if (adapter->ioport == NULL) {
|
|
|
|
device_printf(dev, "Unable to allocate bus resource: "
|
|
|
|
"ioport\n");
|
|
|
|
return (ENXIO);
|
|
|
|
}
|
|
|
|
adapter->hw.io_base = 0;
|
|
|
|
adapter->osdep.io_bus_space_tag =
|
|
|
|
rman_get_bustag(adapter->ioport);
|
|
|
|
adapter->osdep.io_bus_space_handle =
|
|
|
|
rman_get_bushandle(adapter->ioport);
|
2008-02-29 21:50:11 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
adapter->hw.back = &adapter->osdep;
|
|
|
|
|
2006-10-28 08:11:07 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2008-02-29 21:50:11 +00:00
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Setup the MSIX Interrupt handlers
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
2017-01-10 03:23:22 +00:00
|
|
|
static int
|
|
|
|
em_if_msix_intr_assign(if_ctx_t ctx, int msix)
|
2006-01-13 08:18:04 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct em_rx_queue *rx_que = adapter->rx_queues;
|
|
|
|
struct em_tx_queue *tx_que = adapter->tx_queues;
|
|
|
|
int error, rid, i, vector = 0;
|
|
|
|
char buf[16];
|
2008-02-29 21:50:11 +00:00
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* First set up ring resources */
|
2017-01-10 03:23:22 +00:00
|
|
|
for (i = 0; i < adapter->rx_num_queues; i++, rx_que++, vector++) {
|
|
|
|
rid = vector +1;
|
|
|
|
snprintf(buf, sizeof(buf), "rxq%d", i);
|
|
|
|
error = iflib_irq_alloc_generic(ctx, &rx_que->que_irq, rid, IFLIB_INTR_RX, em_msix_que, rx_que, rx_que->me, buf);
|
|
|
|
if (error) {
|
|
|
|
device_printf(iflib_get_dev(ctx), "Failed to allocate que int %d err: %d", i, error);
|
|
|
|
adapter->rx_num_queues = i + 1;
|
|
|
|
goto fail;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
rx_que->msix = vector;
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/*
|
|
|
|
** Set the bit to enable interrupt
|
|
|
|
** in E1000_IMS -- bits 20 and 21
|
|
|
|
** are for RX0 and RX1, note this has
|
|
|
|
** NOTHING to do with the MSIX vector
|
|
|
|
*/
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82574) {
|
|
|
|
rx_que->eims = 1 << (20 + i);
|
|
|
|
adapter->ims |= rx_que->eims;
|
|
|
|
adapter->ivars |= (8 | rx_que->msix) << (i * 4);
|
|
|
|
} else if (adapter->hw.mac.type == e1000_82575)
|
|
|
|
rx_que->eims = E1000_EICR_TX_QUEUE0 << vector;
|
|
|
|
else
|
|
|
|
rx_que->eims = 1 << vector;
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (i = 0; i < adapter->tx_num_queues; i++, tx_que++) {
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
rid = vector + 1;
|
2017-01-10 03:23:22 +00:00
|
|
|
snprintf(buf, sizeof(buf), "txq%d", i);
|
|
|
|
tx_que = &adapter->tx_queues[i];
|
|
|
|
iflib_softirq_alloc_generic(ctx, rid, IFLIB_INTR_TX, tx_que, tx_que->me, buf);
|
|
|
|
|
|
|
|
tx_que->msix = vector;
|
|
|
|
|
|
|
|
/*
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
** Set the bit to enable interrupt
|
|
|
|
** in E1000_IMS -- bits 22 and 23
|
|
|
|
** are for TX0 and TX1, note this has
|
|
|
|
** NOTHING to do with the MSIX vector
|
|
|
|
*/
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type < igb_mac_min) {
|
|
|
|
tx_que->eims = 1 << (22 + i);
|
|
|
|
adapter->ims |= tx_que->eims;
|
|
|
|
adapter->ivars |= (8 | tx_que->msix) << (8 + (i * 4));
|
|
|
|
} if (adapter->hw.mac.type == e1000_82575)
|
|
|
|
tx_que->eims = E1000_EICR_TX_QUEUE0 << (i % adapter->tx_num_queues);
|
|
|
|
else
|
|
|
|
tx_que->eims = 1 << (i % adapter->tx_num_queues);
|
2006-10-28 00:47:55 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Link interrupt */
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
rid = vector + 1;
|
2017-01-10 03:23:22 +00:00
|
|
|
error = iflib_irq_alloc_generic(ctx, &adapter->irq, rid, IFLIB_INTR_ADMIN, em_msix_link, adapter, 0, "aq");
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
if (error) {
|
2017-01-10 03:23:22 +00:00
|
|
|
device_printf(iflib_get_dev(ctx), "Failed to register admin handler");
|
|
|
|
goto fail;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
adapter->linkvec = vector;
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type < igb_mac_min) {
|
|
|
|
adapter->ivars |= (8 | vector) << 16;
|
|
|
|
adapter->ivars |= 0x80000000;
|
|
|
|
}
|
2008-02-29 21:50:11 +00:00
|
|
|
return (0);
|
2017-01-10 03:23:22 +00:00
|
|
|
fail:
|
|
|
|
iflib_irq_free(ctx, &adapter->irq);
|
|
|
|
rx_que = adapter->rx_queues;
|
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++, rx_que++)
|
|
|
|
iflib_irq_free(ctx, &rx_que->que_irq);
|
|
|
|
return (error);
|
2006-10-28 08:11:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
igb_configure_queues(struct adapter *adapter)
|
2006-10-28 08:11:07 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
struct em_rx_queue *rx_que;
|
|
|
|
struct em_tx_queue *tx_que;
|
|
|
|
u32 tmp, ivar = 0, newitr = 0;
|
|
|
|
|
|
|
|
/* First turn on RSS capability */
|
|
|
|
if (adapter->hw.mac.type != e1000_82575)
|
|
|
|
E1000_WRITE_REG(hw, E1000_GPIE,
|
|
|
|
E1000_GPIE_MSIX_MODE | E1000_GPIE_EIAME |
|
|
|
|
E1000_GPIE_PBA | E1000_GPIE_NSICR);
|
|
|
|
|
|
|
|
/* Turn on MSIX */
|
|
|
|
switch (adapter->hw.mac.type) {
|
|
|
|
case e1000_82580:
|
|
|
|
case e1000_i350:
|
|
|
|
case e1000_i354:
|
|
|
|
case e1000_i210:
|
|
|
|
case e1000_i211:
|
|
|
|
case e1000_vfadapt:
|
|
|
|
case e1000_vfadapt_i350:
|
|
|
|
/* RX entries */
|
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++) {
|
|
|
|
u32 index = i >> 1;
|
|
|
|
ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
|
|
|
|
rx_que = &adapter->rx_queues[i];
|
|
|
|
if (i & 1) {
|
|
|
|
ivar &= 0xFF00FFFF;
|
|
|
|
ivar |= (rx_que->msix | E1000_IVAR_VALID) << 16;
|
|
|
|
} else {
|
|
|
|
ivar &= 0xFFFFFF00;
|
|
|
|
ivar |= rx_que->msix | E1000_IVAR_VALID;
|
|
|
|
}
|
|
|
|
E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
|
|
|
|
}
|
|
|
|
/* TX entries */
|
|
|
|
for (int i = 0; i < adapter->tx_num_queues; i++) {
|
|
|
|
u32 index = i >> 1;
|
|
|
|
ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
|
|
|
|
tx_que = &adapter->tx_queues[i];
|
|
|
|
if (i & 1) {
|
|
|
|
ivar &= 0x00FFFFFF;
|
|
|
|
ivar |= (tx_que->msix | E1000_IVAR_VALID) << 24;
|
|
|
|
} else {
|
|
|
|
ivar &= 0xFFFF00FF;
|
|
|
|
ivar |= (tx_que->msix | E1000_IVAR_VALID) << 8;
|
|
|
|
}
|
|
|
|
E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
|
|
|
|
adapter->que_mask |= tx_que->eims;
|
|
|
|
}
|
2007-05-17 00:14:03 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* And for the link interrupt */
|
|
|
|
ivar = (adapter->linkvec | E1000_IVAR_VALID) << 8;
|
|
|
|
adapter->link_mask = 1 << adapter->linkvec;
|
|
|
|
E1000_WRITE_REG(hw, E1000_IVAR_MISC, ivar);
|
|
|
|
break;
|
|
|
|
case e1000_82576:
|
|
|
|
/* RX entries */
|
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++) {
|
|
|
|
u32 index = i & 0x7; /* Each IVAR has two entries */
|
|
|
|
ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
|
|
|
|
rx_que = &adapter->rx_queues[i];
|
|
|
|
if (i < 8) {
|
|
|
|
ivar &= 0xFFFFFF00;
|
|
|
|
ivar |= rx_que->msix | E1000_IVAR_VALID;
|
|
|
|
} else {
|
|
|
|
ivar &= 0xFF00FFFF;
|
|
|
|
ivar |= (rx_que->msix | E1000_IVAR_VALID) << 16;
|
|
|
|
}
|
|
|
|
E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
|
|
|
|
adapter->que_mask |= rx_que->eims;
|
|
|
|
}
|
|
|
|
/* TX entries */
|
|
|
|
for (int i = 0; i < adapter->tx_num_queues; i++) {
|
|
|
|
u32 index = i & 0x7; /* Each IVAR has two entries */
|
|
|
|
ivar = E1000_READ_REG_ARRAY(hw, E1000_IVAR0, index);
|
|
|
|
tx_que = &adapter->tx_queues[i];
|
|
|
|
if (i < 8) {
|
|
|
|
ivar &= 0xFFFF00FF;
|
|
|
|
ivar |= (tx_que->msix | E1000_IVAR_VALID) << 8;
|
|
|
|
} else {
|
|
|
|
ivar &= 0x00FFFFFF;
|
|
|
|
ivar |= (tx_que->msix | E1000_IVAR_VALID) << 24;
|
|
|
|
}
|
|
|
|
E1000_WRITE_REG_ARRAY(hw, E1000_IVAR0, index, ivar);
|
|
|
|
adapter->que_mask |= tx_que->eims;
|
2008-02-29 21:50:11 +00:00
|
|
|
}
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* And for the link interrupt */
|
|
|
|
ivar = (adapter->linkvec | E1000_IVAR_VALID) << 8;
|
|
|
|
adapter->link_mask = 1 << adapter->linkvec;
|
|
|
|
E1000_WRITE_REG(hw, E1000_IVAR_MISC, ivar);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case e1000_82575:
|
|
|
|
/* enable MSI-X support*/
|
|
|
|
tmp = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
|
|
|
tmp |= E1000_CTRL_EXT_PBA_CLR;
|
|
|
|
/* Auto-Mask interrupts upon ICR read. */
|
|
|
|
tmp |= E1000_CTRL_EXT_EIAME;
|
|
|
|
tmp |= E1000_CTRL_EXT_IRCA;
|
|
|
|
E1000_WRITE_REG(hw, E1000_CTRL_EXT, tmp);
|
|
|
|
|
|
|
|
/* Queues */
|
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++) {
|
|
|
|
rx_que = &adapter->rx_queues[i];
|
|
|
|
tmp = E1000_EICR_RX_QUEUE0 << i;
|
|
|
|
tmp |= E1000_EICR_TX_QUEUE0 << i;
|
|
|
|
rx_que->eims = tmp;
|
|
|
|
E1000_WRITE_REG_ARRAY(hw, E1000_MSIXBM(0),
|
|
|
|
i, rx_que->eims);
|
|
|
|
adapter->que_mask |= rx_que->eims;
|
2008-02-29 21:50:11 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
/* Link */
|
|
|
|
E1000_WRITE_REG(hw, E1000_MSIXBM(adapter->linkvec),
|
|
|
|
E1000_EIMS_OTHER);
|
|
|
|
adapter->link_mask |= E1000_EIMS_OTHER;
|
|
|
|
default:
|
|
|
|
break;
|
2008-02-29 21:50:11 +00:00
|
|
|
}
|
2006-11-15 20:04:57 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Set the starting interrupt rate */
|
|
|
|
if (em_max_interrupt_rate > 0)
|
|
|
|
newitr = (4000000 / em_max_interrupt_rate) & 0x7FFC;
|
|
|
|
|
|
|
|
if (hw->mac.type == e1000_82575)
|
|
|
|
newitr |= newitr << 16;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
else
|
2017-01-10 03:23:22 +00:00
|
|
|
newitr |= E1000_EITR_CNT_IGNR;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++) {
|
|
|
|
rx_que = &adapter->rx_queues[i];
|
|
|
|
E1000_WRITE_REG(hw, E1000_EITR(rx_que->msix), newitr);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
em_free_pci_resources(if_ctx_t ctx)
|
|
|
|
{
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct em_rx_queue *que = adapter->rx_queues;
|
|
|
|
device_t dev = iflib_get_dev(ctx);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Release all msix queue resources */
|
|
|
|
if (adapter->intr_type == IFLIB_INTR_MSIX)
|
|
|
|
iflib_irq_free(ctx, &adapter->irq);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++, que++) {
|
|
|
|
iflib_irq_free(ctx, &que->que_irq);
|
|
|
|
}
|
2006-02-15 08:39:50 +00:00
|
|
|
|
2008-02-29 21:50:11 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* First release all the interrupt resources */
|
|
|
|
if (adapter->memory != NULL) {
|
2007-05-04 00:00:12 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_MEMORY,
|
2017-01-10 03:23:22 +00:00
|
|
|
PCIR_BAR(0), adapter->memory);
|
|
|
|
adapter->memory = NULL;
|
|
|
|
}
|
2002-07-16 16:55:03 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->flash != NULL) {
|
2007-05-04 00:00:12 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_MEMORY,
|
2017-01-10 03:23:22 +00:00
|
|
|
EM_FLASH, adapter->flash);
|
|
|
|
adapter->flash = NULL;
|
|
|
|
}
|
|
|
|
if (adapter->ioport != NULL)
|
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT,
|
|
|
|
adapter->io_rid, adapter->ioport);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Setup MSI or MSI/X */
|
2008-02-29 21:50:11 +00:00
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_setup_msix(if_ctx_t ctx)
|
2007-11-20 21:41:22 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2007-11-20 21:41:22 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82574) {
|
|
|
|
em_enable_vectors_82574(ctx);
|
2013-08-12 22:54:38 +00:00
|
|
|
}
|
2008-02-29 21:50:11 +00:00
|
|
|
return (0);
|
2007-11-20 21:41:22 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Initialize the hardware to a configuration
|
|
|
|
* as specified by the adapter structure.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2016-02-05 17:14:37 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
lem_smartspeed(struct adapter *adapter)
|
2016-02-05 17:14:37 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
u16 phy_tmp;
|
|
|
|
|
|
|
|
if (adapter->link_active || (adapter->hw.phy.type != e1000_phy_igp) ||
|
|
|
|
adapter->hw.mac.autoneg == 0 ||
|
|
|
|
(adapter->hw.phy.autoneg_advertised & ADVERTISE_1000_FULL) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (adapter->smartspeed == 0) {
|
|
|
|
/* If Master/Slave config fault is asserted twice,
|
|
|
|
* we assume back-to-back */
|
|
|
|
e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
|
|
|
|
if (!(phy_tmp & SR_1000T_MS_CONFIG_FAULT))
|
|
|
|
return;
|
|
|
|
e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_tmp);
|
|
|
|
if (phy_tmp & SR_1000T_MS_CONFIG_FAULT) {
|
|
|
|
e1000_read_phy_reg(&adapter->hw,
|
|
|
|
PHY_1000T_CTRL, &phy_tmp);
|
|
|
|
if(phy_tmp & CR_1000T_MS_ENABLE) {
|
|
|
|
phy_tmp &= ~CR_1000T_MS_ENABLE;
|
|
|
|
e1000_write_phy_reg(&adapter->hw,
|
|
|
|
PHY_1000T_CTRL, phy_tmp);
|
|
|
|
adapter->smartspeed++;
|
|
|
|
if(adapter->hw.mac.autoneg &&
|
|
|
|
!e1000_copper_link_autoneg(&adapter->hw) &&
|
|
|
|
!e1000_read_phy_reg(&adapter->hw,
|
|
|
|
PHY_CONTROL, &phy_tmp)) {
|
|
|
|
phy_tmp |= (MII_CR_AUTO_NEG_EN |
|
|
|
|
MII_CR_RESTART_AUTO_NEG);
|
|
|
|
e1000_write_phy_reg(&adapter->hw,
|
|
|
|
PHY_CONTROL, phy_tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
} else if(adapter->smartspeed == EM_SMARTSPEED_DOWNSHIFT) {
|
|
|
|
/* If still no link, perhaps using 2/3 pair cable */
|
|
|
|
e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_tmp);
|
|
|
|
phy_tmp |= CR_1000T_MS_ENABLE;
|
|
|
|
e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_tmp);
|
|
|
|
if(adapter->hw.mac.autoneg &&
|
|
|
|
!e1000_copper_link_autoneg(&adapter->hw) &&
|
|
|
|
!e1000_read_phy_reg(&adapter->hw, PHY_CONTROL, &phy_tmp)) {
|
|
|
|
phy_tmp |= (MII_CR_AUTO_NEG_EN |
|
|
|
|
MII_CR_RESTART_AUTO_NEG);
|
|
|
|
e1000_write_phy_reg(&adapter->hw, PHY_CONTROL, phy_tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Restart process after EM_SMARTSPEED_MAX iterations */
|
|
|
|
if(adapter->smartspeed++ == EM_SMARTSPEED_MAX)
|
|
|
|
adapter->smartspeed = 0;
|
2016-02-05 17:14:37 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2016-02-05 17:14:37 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_reset(if_ctx_t ctx)
|
2016-02-05 17:14:37 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
device_t dev = iflib_get_dev(ctx);
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
2016-02-05 17:14:37 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2017-01-10 03:23:22 +00:00
|
|
|
u16 rx_buffer_size;
|
|
|
|
u32 pba;
|
2016-02-05 17:14:37 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
INIT_DEBUGOUT("em_reset: begin");
|
2003-03-21 21:47:31 +00:00
|
|
|
|
2006-08-03 09:20:11 +00:00
|
|
|
/* Set up smart power down as default off on newer adapters. */
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
if (!em_smart_pwr_down && (hw->mac.type == e1000_82571 ||
|
|
|
|
hw->mac.type == e1000_82572)) {
|
2008-02-29 21:50:11 +00:00
|
|
|
u16 phy_tmp = 0;
|
2006-08-03 09:20:11 +00:00
|
|
|
|
|
|
|
/* Speed up time to link by disabling smart power down. */
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_tmp);
|
2006-08-03 09:20:11 +00:00
|
|
|
phy_tmp &= ~IGP02E1000_PM_SPD;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_tmp);
|
2006-08-03 09:20:11 +00:00
|
|
|
}
|
|
|
|
|
2011-12-10 07:08:52 +00:00
|
|
|
/*
|
|
|
|
* Packet Buffer Allocation (PBA)
|
|
|
|
* Writing PBA sets the receive portion of the buffer
|
|
|
|
* the remainder is used for the transmit buffer.
|
|
|
|
*/
|
|
|
|
switch (hw->mac.type) {
|
|
|
|
/* Total Packet Buffer on these is 48K */
|
|
|
|
case e1000_82571:
|
|
|
|
case e1000_82572:
|
|
|
|
case e1000_80003es2lan:
|
|
|
|
pba = E1000_PBA_32K; /* 32K for Rx, 16K for Tx */
|
|
|
|
break;
|
|
|
|
case e1000_82573: /* 82573: Total Packet Buffer is 32K */
|
|
|
|
pba = E1000_PBA_12K; /* 12K for Rx, 20K for Tx */
|
|
|
|
break;
|
|
|
|
case e1000_82574:
|
|
|
|
case e1000_82583:
|
|
|
|
pba = E1000_PBA_20K; /* 20K for Rx, 20K for Tx */
|
|
|
|
break;
|
|
|
|
case e1000_ich8lan:
|
|
|
|
pba = E1000_PBA_8K;
|
|
|
|
break;
|
|
|
|
case e1000_ich9lan:
|
|
|
|
case e1000_ich10lan:
|
|
|
|
/* Boost Receive side for jumbo frames */
|
2013-02-21 00:25:45 +00:00
|
|
|
if (adapter->hw.mac.max_frame_size > 4096)
|
2011-12-10 07:08:52 +00:00
|
|
|
pba = E1000_PBA_14K;
|
|
|
|
else
|
|
|
|
pba = E1000_PBA_10K;
|
|
|
|
break;
|
|
|
|
case e1000_pchlan:
|
|
|
|
case e1000_pch2lan:
|
2013-02-21 00:25:45 +00:00
|
|
|
case e1000_pch_lpt:
|
2016-02-05 17:14:37 +00:00
|
|
|
case e1000_pch_spt:
|
2011-12-10 07:08:52 +00:00
|
|
|
pba = E1000_PBA_26K;
|
|
|
|
break;
|
|
|
|
default:
|
2013-02-21 00:25:45 +00:00
|
|
|
if (adapter->hw.mac.max_frame_size > 8192)
|
2011-12-10 07:08:52 +00:00
|
|
|
pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
|
|
|
|
else
|
|
|
|
pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
|
|
|
|
}
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_PBA, pba);
|
|
|
|
|
2005-11-24 01:44:49 +00:00
|
|
|
/*
|
2006-01-20 11:38:25 +00:00
|
|
|
* These parameters control the automatic generation (Tx) and
|
2005-11-24 01:44:49 +00:00
|
|
|
* response (Rx) to Ethernet PAUSE frames.
|
|
|
|
* - High water mark should allow for at least two frames to be
|
|
|
|
* received after sending an XOFF.
|
|
|
|
* - Low water mark works best when it is very near the high water mark.
|
2006-02-15 08:39:50 +00:00
|
|
|
* This allows the receiver to restart by sending XON when it has
|
2016-05-06 22:54:56 +00:00
|
|
|
* drained a bit. Here we use an arbitrary value of 1500 which will
|
2006-02-15 08:39:50 +00:00
|
|
|
* restart after one full frame is pulled from the buffer. There
|
|
|
|
* could be several smaller frames in the buffer and if so they will
|
|
|
|
* not trigger the XON until their total number reduces the buffer
|
|
|
|
* by 1500.
|
2005-11-24 01:44:49 +00:00
|
|
|
* - The pause time is fairly large at 1000 x 512ns = 512 usec.
|
|
|
|
*/
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 );
|
|
|
|
hw->fc.high_water = rx_buffer_size -
|
2013-02-21 00:25:45 +00:00
|
|
|
roundup2(adapter->hw.mac.max_frame_size, 1024);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
hw->fc.low_water = hw->fc.high_water - 1500;
|
2007-11-20 21:41:22 +00:00
|
|
|
|
2011-12-10 07:08:52 +00:00
|
|
|
if (adapter->fc) /* locally set flow control value? */
|
|
|
|
hw->fc.requested_mode = adapter->fc;
|
|
|
|
else
|
|
|
|
hw->fc.requested_mode = e1000_fc_full;
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
if (hw->mac.type == e1000_80003es2lan)
|
|
|
|
hw->fc.pause_time = 0xFFFF;
|
2006-04-06 17:09:03 +00:00
|
|
|
else
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
hw->fc.pause_time = EM_FC_PAUSE_TIME;
|
|
|
|
|
|
|
|
hw->fc.send_xon = TRUE;
|
2009-06-24 17:41:29 +00:00
|
|
|
|
2011-12-10 07:08:52 +00:00
|
|
|
/* Device specific overrides/settings */
|
|
|
|
switch (hw->mac.type) {
|
|
|
|
case e1000_pchlan:
|
|
|
|
/* Workaround: no TX flow ctrl for PCH */
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
hw->fc.requested_mode = e1000_fc_rx_pause;
|
2011-12-10 07:08:52 +00:00
|
|
|
hw->fc.pause_time = 0xFFFF; /* override */
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getmtu(ifp) > ETHERMTU) {
|
2011-12-10 07:08:52 +00:00
|
|
|
hw->fc.high_water = 0x3500;
|
|
|
|
hw->fc.low_water = 0x1500;
|
|
|
|
} else {
|
|
|
|
hw->fc.high_water = 0x5000;
|
|
|
|
hw->fc.low_water = 0x3000;
|
|
|
|
}
|
|
|
|
hw->fc.refresh_time = 0x1000;
|
|
|
|
break;
|
|
|
|
case e1000_pch2lan:
|
2013-02-21 00:25:45 +00:00
|
|
|
case e1000_pch_lpt:
|
2016-02-05 17:14:37 +00:00
|
|
|
case e1000_pch_spt:
|
2010-10-26 00:07:58 +00:00
|
|
|
hw->fc.high_water = 0x5C20;
|
|
|
|
hw->fc.low_water = 0x5048;
|
|
|
|
hw->fc.pause_time = 0x0650;
|
|
|
|
hw->fc.refresh_time = 0x0400;
|
|
|
|
/* Jumbos need adjusted PBA */
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getmtu(ifp) > ETHERMTU)
|
2010-10-26 00:07:58 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_PBA, 12);
|
|
|
|
else
|
|
|
|
E1000_WRITE_REG(hw, E1000_PBA, 26);
|
2011-12-10 07:08:52 +00:00
|
|
|
break;
|
|
|
|
case e1000_ich9lan:
|
|
|
|
case e1000_ich10lan:
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getmtu(ifp) > ETHERMTU) {
|
2011-12-10 07:08:52 +00:00
|
|
|
hw->fc.high_water = 0x2800;
|
|
|
|
hw->fc.low_water = hw->fc.high_water - 8;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* else fall thru */
|
|
|
|
default:
|
|
|
|
if (hw->mac.type == e1000_80003es2lan)
|
|
|
|
hw->fc.pause_time = 0xFFFF;
|
|
|
|
break;
|
2010-10-26 00:07:58 +00:00
|
|
|
}
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Issue a global reset */
|
|
|
|
e1000_reset_hw(hw);
|
|
|
|
E1000_WRITE_REG(hw, E1000_WUC, 0);
|
2010-11-24 22:24:07 +00:00
|
|
|
em_disable_aspm(adapter);
|
2011-12-10 07:08:52 +00:00
|
|
|
/* and a re-init */
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
if (e1000_init_hw(hw) < 0) {
|
2007-05-04 00:00:12 +00:00
|
|
|
device_printf(dev, "Hardware Initialization Failed\n");
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
return;
|
2002-06-03 22:30:51 +00:00
|
|
|
}
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_VET, ETHERTYPE_VLAN);
|
|
|
|
e1000_get_phy_info(hw);
|
|
|
|
e1000_check_for_link(hw);
|
2017-01-10 03:23:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define RSSKEYLEN 10
|
|
|
|
static void
|
|
|
|
em_initialize_rss_mapping(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
uint8_t rss_key[4 * RSSKEYLEN];
|
|
|
|
uint32_t reta = 0;
|
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Configure RSS key
|
|
|
|
*/
|
|
|
|
arc4rand(rss_key, sizeof(rss_key), 0);
|
|
|
|
for (i = 0; i < RSSKEYLEN; ++i) {
|
|
|
|
uint32_t rssrk = 0;
|
|
|
|
|
|
|
|
rssrk = EM_RSSRK_VAL(rss_key, i);
|
|
|
|
E1000_WRITE_REG(hw,E1000_RSSRK(i), rssrk);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Configure RSS redirect table in following fashion:
|
|
|
|
* (hash & ring_cnt_mask) == rdr_table[(hash & rdr_table_mask)]
|
|
|
|
*/
|
|
|
|
for (i = 0; i < sizeof(reta); ++i) {
|
|
|
|
uint32_t q;
|
|
|
|
|
|
|
|
q = (i % adapter->rx_num_queues) << 7;
|
|
|
|
reta |= q << (8 * i);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 32; ++i)
|
|
|
|
E1000_WRITE_REG(hw, E1000_RETA(i), reta);
|
|
|
|
|
|
|
|
E1000_WRITE_REG(hw, E1000_MRQC, E1000_MRQC_RSS_ENABLE_2Q |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV4_TCP |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV4 |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV6_TCP_EX |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV6_EX |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV6);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
igb_initialize_rss_mapping(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
int i;
|
|
|
|
int queue_id;
|
|
|
|
u32 reta;
|
|
|
|
u32 rss_key[10], mrqc, shift = 0;
|
|
|
|
|
|
|
|
/* XXX? */
|
|
|
|
if (adapter->hw.mac.type == e1000_82575)
|
|
|
|
shift = 6;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The redirection table controls which destination
|
|
|
|
* queue each bucket redirects traffic to.
|
|
|
|
* Each DWORD represents four queues, with the LSB
|
|
|
|
* being the first queue in the DWORD.
|
|
|
|
*
|
|
|
|
* This just allocates buckets to queues using round-robin
|
|
|
|
* allocation.
|
|
|
|
*
|
|
|
|
* NOTE: It Just Happens to line up with the default
|
|
|
|
* RSS allocation method.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Warning FM follows */
|
|
|
|
reta = 0;
|
|
|
|
for (i = 0; i < 128; i++) {
|
|
|
|
#ifdef RSS
|
|
|
|
queue_id = rss_get_indirection_to_bucket(i);
|
|
|
|
/*
|
|
|
|
* If we have more queues than buckets, we'll
|
|
|
|
* end up mapping buckets to a subset of the
|
|
|
|
* queues.
|
|
|
|
*
|
|
|
|
* If we have more buckets than queues, we'll
|
|
|
|
* end up instead assigning multiple buckets
|
|
|
|
* to queues.
|
|
|
|
*
|
|
|
|
* Both are suboptimal, but we need to handle
|
|
|
|
* the case so we don't go out of bounds
|
|
|
|
* indexing arrays and such.
|
|
|
|
*/
|
|
|
|
queue_id = queue_id % adapter->rx_num_queues;
|
|
|
|
#else
|
|
|
|
queue_id = (i % adapter->rx_num_queues);
|
|
|
|
#endif
|
|
|
|
/* Adjust if required */
|
|
|
|
queue_id = queue_id << shift;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The low 8 bits are for hash value (n+0);
|
|
|
|
* The next 8 bits are for hash value (n+1), etc.
|
|
|
|
*/
|
|
|
|
reta = reta >> 8;
|
|
|
|
reta = reta | ( ((uint32_t) queue_id) << 24);
|
|
|
|
if ((i & 3) == 3) {
|
|
|
|
E1000_WRITE_REG(hw, E1000_RETA(i >> 2), reta);
|
|
|
|
reta = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now fill in hash table */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MRQC: Multiple Receive Queues Command
|
|
|
|
* Set queuing to RSS control, number depends on the device.
|
|
|
|
*/
|
|
|
|
mrqc = E1000_MRQC_ENABLE_RSS_8Q;
|
|
|
|
|
|
|
|
#ifdef RSS
|
|
|
|
/* XXX ew typecasting */
|
|
|
|
rss_getkey((uint8_t *) &rss_key);
|
|
|
|
#else
|
|
|
|
arc4rand(&rss_key, sizeof(rss_key), 0);
|
|
|
|
#endif
|
|
|
|
for (i = 0; i < 10; i++)
|
|
|
|
E1000_WRITE_REG_ARRAY(hw,
|
|
|
|
E1000_RSSRK(0), i, rss_key[i]);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Configure the RSS fields to hash upon.
|
|
|
|
*/
|
|
|
|
mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV4_TCP);
|
|
|
|
mrqc |= (E1000_MRQC_RSS_FIELD_IPV6 |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV6_TCP);
|
|
|
|
mrqc |=( E1000_MRQC_RSS_FIELD_IPV4_UDP |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV6_UDP);
|
|
|
|
mrqc |=( E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
|
|
|
|
E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
|
|
|
|
|
|
|
|
E1000_WRITE_REG(hw, E1000_MRQC, mrqc);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Setup networking device structure and register an interface.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
2010-08-28 00:09:19 +00:00
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_setup_interface(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
if_softc_ctx_t scctx = adapter->shared;
|
|
|
|
uint64_t cap = 0;
|
|
|
|
|
2002-06-03 22:30:51 +00:00
|
|
|
INIT_DEBUGOUT("em_setup_interface: begin");
|
|
|
|
|
2015-08-16 19:43:44 +00:00
|
|
|
/* TSO parameters */
|
2015-08-31 19:12:10 +00:00
|
|
|
ifp->if_hw_tsomax = IP_MAXPACKET;
|
Fix and clean up usage of DMA and TSO segments:
- At Intel it is believed that most of their products support "only"
40 DMA segments so lower {EM,IGB}_MAX_SCATTER accordingly. Actually,
40 is more than plenty to handle full size TSO packets so it doesn't
make sense to further distinguish between MAC variants that really
can do 64 DMA segments. Moreover, capping at 40 DMA segments limits
the stack usage of {em,igb}_xmit() that - given the rare use of more
than these - previously hardly was justifiable, while still being
sufficient to avoid the problems seen with em(4) and EM_MAX_SCATTER
set to 32.
- In igb(4), pass the actually supported TSO parameters up the stack.
Previously, the defaults set in if_attach_internal() were applied,
i. e. a maximum of 35 TSO segments, which made supporting more than
these in the driver pointless. However, this might explain why no
problems were seen with IGB_MAX_SCATTER at 64.
- In em(4), take the 5 m_pullup(9) invocations performed by em_xmit()
in the TSO case into account when reporting TSO parameters upwards.
In the worst case, each of these calls will add another mbuf and,
thus, the requirement for an additional DMA segment. So for best
performance, it doesn't make sense to advertize a maximum of TSO
segments that typically will require defragmentation in em_xmit().
Again, this leaves enough room to handle full size TSO packets.
- Drop TSO macros from if_lem.h given that corresponding MACS don't
support TSO in the first place.
Reviewed by: erj, sbruno, jeffrey.e.pieper_intel.com
Approved by: erj
MFC after: 3 days
Differential Revision: https://reviews.freebsd.org/D5238
2016-02-23 01:19:26 +00:00
|
|
|
/* Take m_pullup(9)'s in em_xmit() w/ TSO into acount. */
|
|
|
|
ifp->if_hw_tsomaxsegcount = EM_MAX_SCATTER - 5;
|
2015-08-16 19:43:44 +00:00
|
|
|
ifp->if_hw_tsomaxsegsize = EM_TSO_SEG_SIZE;
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Single Queue */
|
|
|
|
if (adapter->tx_num_queues == 1) {
|
|
|
|
if_setsendqlen(ifp, scctx->isc_ntxd[0] - 1);
|
|
|
|
if_setsendqready(ifp);
|
|
|
|
}
|
2004-05-20 11:04:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
cap = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM | IFCAP_TSO4;
|
|
|
|
cap |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO | IFCAP_VLAN_MTU;
|
2002-12-23 19:11:23 +00:00
|
|
|
|
2003-04-18 17:36:13 +00:00
|
|
|
/*
|
2010-04-08 00:50:43 +00:00
|
|
|
* Tell the upper layer(s) we
|
|
|
|
* support full VLAN capability
|
2003-04-18 17:36:13 +00:00
|
|
|
*/
|
2014-06-02 18:52:03 +00:00
|
|
|
if_setifheaderlen(ifp, sizeof(struct ether_vlan_header));
|
2017-01-10 03:23:22 +00:00
|
|
|
if_setcapabilitiesbit(ifp, cap, 0);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2010-04-08 00:50:43 +00:00
|
|
|
/*
|
2011-12-10 07:08:52 +00:00
|
|
|
** Don't turn this on by default, if vlans are
|
2010-04-08 00:50:43 +00:00
|
|
|
** created on another pseudo device (eg. lagg)
|
|
|
|
** then vlan events are not passed thru, breaking
|
|
|
|
** operation, but with HW FILTER off it works. If
|
|
|
|
** using vlans directly on the em driver you can
|
|
|
|
** enable this and get full hardware tag filtering.
|
|
|
|
*/
|
2014-06-02 18:52:03 +00:00
|
|
|
if_setcapabilitiesbit(ifp, IFCAP_VLAN_HWFILTER,0);
|
2010-04-08 00:50:43 +00:00
|
|
|
|
2010-04-28 17:37:30 +00:00
|
|
|
/* Enable only WOL MAGIC by default */
|
2009-12-08 01:07:44 +00:00
|
|
|
if (adapter->wol) {
|
2014-06-02 18:52:03 +00:00
|
|
|
if_setcapabilitiesbit(ifp, IFCAP_WOL, 0);
|
|
|
|
if_setcapenablebit(ifp, IFCAP_WOL_MAGIC, 0);
|
2009-12-08 01:07:44 +00:00
|
|
|
}
|
|
|
|
|
2006-01-20 11:38:25 +00:00
|
|
|
/*
|
2002-06-03 22:30:51 +00:00
|
|
|
* Specify the media types supported by this adapter and register
|
|
|
|
* callbacks to update media and link information
|
|
|
|
*/
|
2007-11-20 21:41:22 +00:00
|
|
|
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
|
|
|
|
(adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) {
|
2007-05-04 00:00:12 +00:00
|
|
|
u_char fiber_type = IFM_1000_SX; /* default type */
|
2006-10-28 08:11:07 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82545)
|
|
|
|
fiber_type = IFM_1000_LX;
|
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | fiber_type | IFM_FDX, 0, NULL);
|
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | fiber_type, 0, NULL);
|
2002-06-03 22:30:51 +00:00
|
|
|
} else {
|
2017-01-10 03:23:22 +00:00
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_10_T, 0, NULL);
|
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
|
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_100_TX, 0, NULL);
|
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
|
2007-05-04 00:00:12 +00:00
|
|
|
if (adapter->hw.phy.type != e1000_phy_ife) {
|
2017-01-10 03:23:22 +00:00
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
|
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_1000_T, 0, NULL);
|
2006-08-09 20:10:35 +00:00
|
|
|
}
|
2002-06-03 22:30:51 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
ifmedia_add(adapter->media, IFM_ETHER | IFM_AUTO, 0, NULL);
|
|
|
|
ifmedia_set(adapter->media, IFM_ETHER | IFM_AUTO);
|
2010-08-28 00:09:19 +00:00
|
|
|
return (0);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2003-05-02 21:17:08 +00:00
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_tx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs, int ntxqs, int ntxqsets)
|
2006-02-15 08:39:50 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
if_softc_ctx_t scctx = adapter->shared;
|
|
|
|
int error = E1000_SUCCESS;
|
|
|
|
struct em_tx_queue *que;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
MPASS(adapter->tx_num_queues > 0);
|
|
|
|
MPASS(adapter->tx_num_queues == ntxqsets);
|
|
|
|
|
|
|
|
/* First allocate the top level queue structs */
|
|
|
|
if (!(adapter->tx_queues =
|
|
|
|
(struct em_tx_queue *) malloc(sizeof(struct em_tx_queue) *
|
|
|
|
adapter->tx_num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
|
|
|
|
device_printf(iflib_get_dev(ctx), "Unable to allocate queue memory\n");
|
|
|
|
return(ENOMEM);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0, que = adapter->tx_queues; i < adapter->tx_num_queues; i++, que++) {
|
|
|
|
/* Set up some basics */
|
|
|
|
struct tx_ring *txr = &que->txr;
|
|
|
|
txr->adapter = que->adapter = adapter;
|
|
|
|
txr->que = que;
|
|
|
|
que->me = txr->me = i;
|
|
|
|
|
|
|
|
/* Allocate transmit buffer memory */
|
|
|
|
if (!(txr->tx_buffers = (struct em_txbuffer *) malloc(sizeof(struct em_txbuffer) * scctx->isc_ntxd[0], M_DEVBUF, M_NOWAIT | M_ZERO))) {
|
|
|
|
device_printf(iflib_get_dev(ctx), "failed to allocate tx_buffer memory\n");
|
|
|
|
error = ENOMEM;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the virtual and physical address of the hardware queues */
|
|
|
|
txr->tx_base = (struct e1000_tx_desc *)vaddrs[i*ntxqs];
|
|
|
|
txr->tx_paddr = paddrs[i*ntxqs];
|
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
device_printf(iflib_get_dev(ctx), "allocated for %d tx_queues\n", adapter->tx_num_queues);
|
2006-02-15 08:39:50 +00:00
|
|
|
return (0);
|
2017-01-10 03:23:22 +00:00
|
|
|
fail:
|
|
|
|
em_if_queues_free(ctx);
|
2006-02-15 08:39:50 +00:00
|
|
|
return (error);
|
2003-05-02 21:17:08 +00:00
|
|
|
}
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
static int
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_rx_queues_alloc(if_ctx_t ctx, caddr_t *vaddrs, uint64_t *paddrs, int nrxqs, int nrxqsets)
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
int error = E1000_SUCCESS;
|
|
|
|
struct em_rx_queue *que;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
MPASS(adapter->rx_num_queues > 0);
|
|
|
|
MPASS(adapter->rx_num_queues == nrxqsets);
|
|
|
|
|
|
|
|
/* First allocate the top level queue structs */
|
|
|
|
if (!(adapter->rx_queues =
|
|
|
|
(struct em_rx_queue *) malloc(sizeof(struct em_rx_queue) *
|
|
|
|
adapter->rx_num_queues, M_DEVBUF, M_NOWAIT | M_ZERO))) {
|
|
|
|
device_printf(iflib_get_dev(ctx), "Unable to allocate queue memory\n");
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
error = ENOMEM;
|
2017-01-10 03:23:22 +00:00
|
|
|
goto fail;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (i = 0, que = adapter->rx_queues; i < nrxqsets; i++, que++) {
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Set up some basics */
|
2017-01-10 03:23:22 +00:00
|
|
|
struct rx_ring *rxr = &que->rxr;
|
|
|
|
rxr->adapter = que->adapter = adapter;
|
|
|
|
rxr->que = que;
|
|
|
|
que->me = rxr->me = i;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* get the virtual and physical address of the hardware queues */
|
|
|
|
rxr->rx_base = (union e1000_rx_desc_extended *)vaddrs[i*nrxqs];
|
|
|
|
rxr->rx_paddr = paddrs[i*nrxqs];
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
device_printf(iflib_get_dev(ctx), "allocated for %d rx_queues\n", adapter->rx_num_queues);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
fail:
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_queues_free(ctx);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
static void
|
|
|
|
em_if_queues_free(if_ctx_t ctx)
|
2006-10-28 08:11:07 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct em_tx_queue *tx_que = adapter->tx_queues;
|
|
|
|
struct em_rx_queue *rx_que = adapter->rx_queues;
|
2005-11-21 04:17:43 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (tx_que != NULL) {
|
|
|
|
for (int i = 0; i < adapter->tx_num_queues; i++, tx_que++) {
|
|
|
|
struct tx_ring *txr = &tx_que->txr;
|
|
|
|
if (txr->tx_buffers == NULL)
|
|
|
|
break;
|
2003-05-02 21:17:08 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
free(txr->tx_buffers, M_DEVBUF);
|
|
|
|
txr->tx_buffers = NULL;
|
|
|
|
}
|
|
|
|
free(adapter->tx_queues, M_DEVBUF);
|
|
|
|
adapter->tx_queues = NULL;
|
2007-11-20 21:41:22 +00:00
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (rx_que != NULL) {
|
|
|
|
free(adapter->rx_queues, M_DEVBUF);
|
|
|
|
adapter->rx_queues = NULL;
|
2005-11-21 04:17:43 +00:00
|
|
|
}
|
2003-05-02 21:17:08 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
em_release_hw_control(adapter);
|
2007-05-04 00:00:12 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->mta != NULL) {
|
|
|
|
free(adapter->mta, M_DEVBUF);
|
|
|
|
}
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Enable transmit unit.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_initialize_transmit_unit(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
if_softc_ctx_t scctx = adapter->shared;
|
|
|
|
struct em_tx_queue *que;
|
|
|
|
struct tx_ring *txr;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2017-01-10 03:23:22 +00:00
|
|
|
u32 tctl, txdctl = 0, tarc, tipg = 0;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
INIT_DEBUGOUT("em_initialize_transmit_unit: begin");
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int i = 0; i < adapter->tx_num_queues; i++, txr++) {
|
|
|
|
u64 bus_addr;
|
|
|
|
caddr_t offp, endp;
|
|
|
|
|
|
|
|
que = &adapter->tx_queues[i];
|
|
|
|
txr = &que->txr;
|
|
|
|
bus_addr = txr->tx_paddr;
|
|
|
|
|
|
|
|
/*Enable all queues */
|
|
|
|
em_init_tx_ring(que);
|
|
|
|
|
|
|
|
/* Clear checksum offload context. */
|
|
|
|
offp = (caddr_t)&txr->csum_flags;
|
|
|
|
endp = (caddr_t)(txr + 1);
|
|
|
|
bzero(offp, endp - offp);
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Base and Len of TX Ring */
|
|
|
|
E1000_WRITE_REG(hw, E1000_TDLEN(i),
|
2017-01-10 03:23:22 +00:00
|
|
|
scctx->isc_ntxd[0] * sizeof(struct e1000_tx_desc));
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_TDBAH(i),
|
|
|
|
(u32)(bus_addr >> 32));
|
|
|
|
E1000_WRITE_REG(hw, E1000_TDBAL(i),
|
|
|
|
(u32)bus_addr);
|
|
|
|
/* Init the HEAD/TAIL indices */
|
|
|
|
E1000_WRITE_REG(hw, E1000_TDT(i), 0);
|
|
|
|
E1000_WRITE_REG(hw, E1000_TDH(i), 0);
|
|
|
|
|
|
|
|
HW_DEBUGOUT2("Base = %x, Length = %x\n",
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TDBAL(i)),
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TDLEN(i)));
|
|
|
|
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
txdctl = 0; /* clear txdctl */
|
|
|
|
txdctl |= 0x1f; /* PTHRESH */
|
|
|
|
txdctl |= 1 << 8; /* HTHRESH */
|
|
|
|
txdctl |= 1 << 16;/* WTHRESH */
|
|
|
|
txdctl |= 1 << 22; /* Reserved bit 22 must always be 1 */
|
|
|
|
txdctl |= E1000_TXDCTL_GRAN;
|
|
|
|
txdctl |= 1 << 25; /* LWTHRESH */
|
|
|
|
|
|
|
|
E1000_WRITE_REG(hw, E1000_TXDCTL(i), txdctl);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
2002-06-03 22:30:51 +00:00
|
|
|
|
|
|
|
/* Set the default values for the Tx Inter Packet Gap timer */
|
2007-05-04 00:00:12 +00:00
|
|
|
switch (adapter->hw.mac.type) {
|
|
|
|
case e1000_80003es2lan:
|
|
|
|
tipg = DEFAULT_82543_TIPG_IPGR1;
|
|
|
|
tipg |= DEFAULT_80003ES2LAN_TIPG_IPGR2 <<
|
2006-04-06 17:09:03 +00:00
|
|
|
E1000_TIPG_IPGR2_SHIFT;
|
|
|
|
break;
|
2017-01-10 03:23:22 +00:00
|
|
|
case e1000_82542:
|
|
|
|
tipg = DEFAULT_82542_TIPG_IPGT;
|
|
|
|
tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
|
|
|
|
tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
|
|
|
|
break;
|
2006-02-15 08:39:50 +00:00
|
|
|
default:
|
2007-11-20 21:41:22 +00:00
|
|
|
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) ||
|
|
|
|
(adapter->hw.phy.media_type ==
|
2007-05-04 00:00:12 +00:00
|
|
|
e1000_media_type_internal_serdes))
|
|
|
|
tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
|
2006-02-15 08:39:50 +00:00
|
|
|
else
|
2007-05-04 00:00:12 +00:00
|
|
|
tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
|
|
|
|
tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
|
|
|
|
tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
|
2006-02-15 08:39:50 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TIPG, tipg);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TIDV, adapter->tx_int_delay.value);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if(adapter->hw.mac.type >= e1000_82540)
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TADV,
|
|
|
|
adapter->tx_abs_int_delay.value);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if ((adapter->hw.mac.type == e1000_82571) ||
|
|
|
|
(adapter->hw.mac.type == e1000_82572)) {
|
|
|
|
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
|
|
|
|
tarc |= TARC_SPEED_MODE_BIT;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
|
|
|
|
} else if (adapter->hw.mac.type == e1000_80003es2lan) {
|
|
|
|
/* errata: program both queues to unweighted RR */
|
|
|
|
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
|
|
|
|
tarc |= 1;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
|
|
|
|
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(1));
|
|
|
|
tarc |= 1;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
|
|
|
|
} else if (adapter->hw.mac.type == e1000_82574) {
|
|
|
|
tarc = E1000_READ_REG(&adapter->hw, E1000_TARC(0));
|
|
|
|
tarc |= TARC_ERRATA_BIT;
|
|
|
|
if ( adapter->tx_num_queues > 1) {
|
|
|
|
tarc |= (TARC_COMPENSATION_MODE | TARC_MQ_FIX);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TARC(1), tarc);
|
|
|
|
} else
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TARC(0), tarc);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->tx_int_delay.value > 0)
|
|
|
|
adapter->txd_cmd |= E1000_TXD_CMD_IDE;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* Program the Transmit Control Register */
|
|
|
|
tctl = E1000_READ_REG(&adapter->hw, E1000_TCTL);
|
|
|
|
tctl &= ~E1000_TCTL_CT;
|
|
|
|
tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN |
|
|
|
|
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT));
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type >= e1000_82571)
|
|
|
|
tctl |= E1000_TCTL_MULR;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/* This write will effectively turn on the transmit unit. */
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_TCTL, tctl);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (hw->mac.type == e1000_pch_spt) {
|
|
|
|
u32 reg;
|
|
|
|
reg = E1000_READ_REG(hw, E1000_IOSFPC);
|
|
|
|
reg |= E1000_RCTL_RDMTS_HEX;
|
|
|
|
E1000_WRITE_REG(hw, E1000_IOSFPC, reg);
|
|
|
|
reg = E1000_READ_REG(hw, E1000_TARC(0));
|
|
|
|
reg |= E1000_TARC0_CB_MULTIQ_3_REQ;
|
|
|
|
E1000_WRITE_REG(hw, E1000_TARC(0), reg);
|
|
|
|
}
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Enable receive unit.
|
2006-01-20 11:38:25 +00:00
|
|
|
*
|
2001-12-02 07:37:17 +00:00
|
|
|
**********************************************************************/
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_initialize_receive_unit(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
if_softc_ctx_t scctx = adapter->shared;
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2017-01-10 03:23:22 +00:00
|
|
|
struct em_rx_queue *que;
|
|
|
|
int i;
|
2016-01-07 16:42:48 +00:00
|
|
|
u32 rctl, rxcsum, rfctl;
|
2002-06-03 22:30:51 +00:00
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
INIT_DEBUGOUT("em_initialize_receive_units: begin");
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
/*
|
|
|
|
* Make sure receives are disabled while setting
|
|
|
|
* up the descriptor ring
|
|
|
|
*/
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
rctl = E1000_READ_REG(hw, E1000_RCTL);
|
2011-12-10 07:08:52 +00:00
|
|
|
/* Do not disable if ever enabled on this hardware */
|
|
|
|
if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
|
|
|
|
E1000_WRITE_REG(hw, E1000_RCTL, rctl & ~E1000_RCTL_EN);
|
2006-10-28 08:11:07 +00:00
|
|
|
|
2016-01-07 16:42:48 +00:00
|
|
|
/* Setup the Receive Control Register */
|
|
|
|
rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
|
|
|
|
rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
|
|
|
|
E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
|
|
|
|
(hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
|
|
|
|
|
|
|
|
/* Do not store bad packets */
|
|
|
|
rctl &= ~E1000_RCTL_SBP;
|
|
|
|
|
|
|
|
/* Enable Long Packet receive */
|
|
|
|
if (if_getmtu(ifp) > ETHERMTU)
|
|
|
|
rctl |= E1000_RCTL_LPE;
|
|
|
|
else
|
|
|
|
rctl &= ~E1000_RCTL_LPE;
|
|
|
|
|
|
|
|
/* Strip the CRC */
|
|
|
|
if (!em_disable_crc_stripping)
|
|
|
|
rctl |= E1000_RCTL_SECRC;
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->hw.mac.type >= e1000_82540) {
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RADV,
|
|
|
|
adapter->rx_abs_int_delay.value);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
/*
|
|
|
|
* Set the interrupt throttling rate. Value is calculated
|
|
|
|
* as DEFAULT_ITR = 1/(MAX_INTS_PER_SEC * 256ns)
|
|
|
|
*/
|
|
|
|
E1000_WRITE_REG(hw, E1000_ITR, DEFAULT_ITR);
|
|
|
|
}
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RDTR,
|
|
|
|
adapter->rx_int_delay.value);
|
2002-12-23 19:11:23 +00:00
|
|
|
|
2016-01-07 16:42:48 +00:00
|
|
|
/* Use extended rx descriptor formats */
|
|
|
|
rfctl = E1000_READ_REG(hw, E1000_RFCTL);
|
|
|
|
rfctl |= E1000_RFCTL_EXTEN;
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
/*
|
|
|
|
** When using MSIX interrupts we need to throttle
|
|
|
|
** using the EITR register (82574 only)
|
|
|
|
*/
|
2011-12-10 07:08:52 +00:00
|
|
|
if (hw->mac.type == e1000_82574) {
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
for (int i = 0; i < 4; i++)
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_EITR_82574(i),
|
|
|
|
DEFAULT_ITR);
|
2011-12-10 07:08:52 +00:00
|
|
|
/* Disable accelerated acknowledge */
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
rfctl |= E1000_RFCTL_ACK_DIS;
|
2011-12-10 07:08:52 +00:00
|
|
|
}
|
2016-01-07 16:42:48 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
|
2013-04-15 17:01:42 +00:00
|
|
|
rxcsum = E1000_READ_REG(hw, E1000_RXCSUM);
|
2017-01-10 03:23:22 +00:00
|
|
|
if (if_getcapenable(ifp) & IFCAP_RXCSUM &&
|
|
|
|
adapter->hw.mac.type >= e1000_82543) {
|
|
|
|
if (adapter->tx_num_queues > 1) {
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min) {
|
|
|
|
rxcsum |= E1000_RXCSUM_PCSD;
|
|
|
|
if (hw->mac.type != e1000_82575)
|
|
|
|
rxcsum |= E1000_RXCSUM_CRCOFL;
|
|
|
|
} else
|
|
|
|
rxcsum |= E1000_RXCSUM_TUOFL |
|
|
|
|
E1000_RXCSUM_IPOFL |
|
|
|
|
E1000_RXCSUM_PCSD;
|
|
|
|
} else {
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min)
|
|
|
|
rxcsum |= E1000_RXCSUM_IPPCSE;
|
|
|
|
else
|
|
|
|
rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPOFL;
|
|
|
|
if (adapter->hw.mac.type > e1000_82575)
|
|
|
|
rxcsum |= E1000_RXCSUM_CRCOFL;
|
|
|
|
}
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
} else
|
2013-04-15 17:01:42 +00:00
|
|
|
rxcsum &= ~E1000_RXCSUM_TUOFL;
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2013-04-15 17:01:42 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_RXCSUM, rxcsum);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->rx_num_queues > 1) {
|
|
|
|
if (adapter->hw.mac.type >= igb_mac_min)
|
|
|
|
igb_initialize_rss_mapping(adapter);
|
|
|
|
else
|
|
|
|
em_initialize_rss_mapping(adapter);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/*
|
|
|
|
** XXX TEMPORARY WORKAROUND: on some systems with 82573
|
|
|
|
** long latencies are observed, like Lenovo X60. This
|
|
|
|
** change eliminates the problem, but since having positive
|
|
|
|
** values in RDTR is a known source of problems on other
|
|
|
|
** platforms another solution is being sought.
|
|
|
|
*/
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
if (hw->mac.type == e1000_82573)
|
|
|
|
E1000_WRITE_REG(hw, E1000_RDTR, 0x20);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (i = 0, que = adapter->rx_queues; i < adapter->rx_num_queues; i++, que++) {
|
|
|
|
struct rx_ring *rxr = &que->rxr;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Setup the Base and Length of the Rx Descriptor Ring */
|
2017-01-10 03:23:22 +00:00
|
|
|
u64 bus_addr = rxr->rx_paddr;
|
|
|
|
#if 0
|
|
|
|
u32 rdt = adapter->rx_num_queues -1; /* default */
|
|
|
|
#endif
|
2013-05-09 16:57:02 +00:00
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_RDLEN(i),
|
2017-01-10 03:23:22 +00:00
|
|
|
scctx->isc_nrxd[0] * sizeof(union e1000_rx_desc_extended));
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32));
|
|
|
|
E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr);
|
|
|
|
/* Setup the Head and Tail Descriptor Pointers */
|
2011-12-10 07:08:52 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_RDH(i), 0);
|
2017-01-10 03:23:22 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_RDT(i), 0);
|
2006-10-28 08:11:07 +00:00
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
/*
|
|
|
|
* Set PTHRESH for improved jumbo performance
|
|
|
|
* According to 10.2.5.11 of Intel 82574 Datasheet,
|
|
|
|
* RXDCTL(1) is written whenever RXDCTL(0) is written.
|
|
|
|
* Only write to RXDCTL(1) if there is a need for different
|
|
|
|
* settings.
|
|
|
|
*/
|
2017-01-10 03:23:22 +00:00
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
if (((adapter->hw.mac.type == e1000_ich9lan) ||
|
|
|
|
(adapter->hw.mac.type == e1000_pch2lan) ||
|
|
|
|
(adapter->hw.mac.type == e1000_ich10lan)) &&
|
2014-06-02 18:52:03 +00:00
|
|
|
(if_getmtu(ifp) > ETHERMTU)) {
|
2010-10-26 00:07:58 +00:00
|
|
|
u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(0));
|
|
|
|
E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3);
|
2016-01-07 16:42:48 +00:00
|
|
|
} else if (adapter->hw.mac.type == e1000_82574) {
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int i = 0; i < adapter->rx_num_queues; i++) {
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
u32 rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(i));
|
2016-01-07 16:42:48 +00:00
|
|
|
rxdctl |= 0x20; /* PTHRESH */
|
|
|
|
rxdctl |= 4 << 8; /* HTHRESH */
|
|
|
|
rxdctl |= 4 << 16;/* WTHRESH */
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
rxdctl |= 1 << 24; /* Switch to granularity */
|
|
|
|
E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl);
|
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
} else if (adapter->hw.mac.type >= igb_mac_min) {
|
|
|
|
u32 psize, srrctl = 0;
|
|
|
|
|
|
|
|
if (ifp->if_mtu > ETHERMTU) {
|
|
|
|
rctl |= E1000_RCTL_LPE;
|
|
|
|
|
|
|
|
/* Set maximum packet len */
|
|
|
|
psize = scctx->isc_max_frame_size;
|
|
|
|
if (psize <= 4096) {
|
|
|
|
srrctl |= 4096 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
|
|
|
rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
|
|
|
|
} else if (psize > 4096) {
|
|
|
|
srrctl |= 8192 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
|
|
|
rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* are we on a vlan? */
|
|
|
|
if (ifp->if_vlantrunk != NULL)
|
|
|
|
psize += VLAN_TAG_SIZE;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RLPML, psize);
|
|
|
|
} else {
|
|
|
|
rctl &= ~E1000_RCTL_LPE;
|
|
|
|
srrctl |= 2048 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
|
|
|
|
rctl |= E1000_RCTL_SZ_2048;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If TX flow control is disabled and there's >1 queue defined,
|
|
|
|
* enable DROP.
|
|
|
|
*
|
|
|
|
* This drops frames rather than hanging the RX MAC for all queues.
|
|
|
|
*/
|
|
|
|
if ((adapter->rx_num_queues > 1) &&
|
|
|
|
(adapter->fc == e1000_fc_none ||
|
|
|
|
adapter->fc == e1000_fc_rx_pause)) {
|
|
|
|
srrctl |= E1000_SRRCTL_DROP_EN;
|
|
|
|
}
|
|
|
|
/* Setup the Base and Length of the Rx Descriptor Rings */
|
|
|
|
for (i = 0, que = adapter->rx_queues; i < adapter->rx_num_queues; i++, que++) {
|
|
|
|
struct rx_ring *rxr = &que->rxr;
|
|
|
|
u64 bus_addr = rxr->rx_paddr;
|
|
|
|
u32 rxdctl;
|
|
|
|
|
|
|
|
#ifdef notyet
|
|
|
|
/* Configure for header split? -- ignore for now */
|
|
|
|
rxr->hdr_split = igb_header_split;
|
|
|
|
#else
|
|
|
|
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
E1000_WRITE_REG(hw, E1000_RDLEN(i),
|
|
|
|
scctx->isc_nrxd[0] * sizeof(struct e1000_rx_desc));
|
|
|
|
E1000_WRITE_REG(hw, E1000_RDBAH(i),
|
|
|
|
(uint32_t)(bus_addr >> 32));
|
|
|
|
E1000_WRITE_REG(hw, E1000_RDBAL(i),
|
|
|
|
(uint32_t)bus_addr);
|
|
|
|
E1000_WRITE_REG(hw, E1000_SRRCTL(i), srrctl);
|
|
|
|
/* Enable this Queue */
|
|
|
|
rxdctl = E1000_READ_REG(hw, E1000_RXDCTL(i));
|
|
|
|
rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
|
|
|
|
rxdctl &= 0xFFF00000;
|
|
|
|
rxdctl |= IGB_RX_PTHRESH;
|
|
|
|
rxdctl |= IGB_RX_HTHRESH << 8;
|
|
|
|
rxdctl |= IGB_RX_WTHRESH << 16;
|
|
|
|
E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl);
|
|
|
|
}
|
2010-10-26 00:07:58 +00:00
|
|
|
}
|
2013-02-21 00:25:45 +00:00
|
|
|
if (adapter->hw.mac.type >= e1000_pch2lan) {
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getmtu(ifp) > ETHERMTU)
|
2010-10-26 00:07:58 +00:00
|
|
|
e1000_lv_jumbo_workaround_ich8lan(hw, TRUE);
|
|
|
|
else
|
|
|
|
e1000_lv_jumbo_workaround_ich8lan(hw, FALSE);
|
|
|
|
}
|
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Make sure VLAN Filters are off */
|
|
|
|
rctl &= ~E1000_RCTL_VFE;
|
2010-10-26 00:07:58 +00:00
|
|
|
|
|
|
|
if (adapter->rx_mbuf_sz == MCLBYTES)
|
|
|
|
rctl |= E1000_RCTL_SZ_2048;
|
|
|
|
else if (adapter->rx_mbuf_sz == MJUMPAGESIZE)
|
|
|
|
rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
|
|
|
|
else if (adapter->rx_mbuf_sz > MJUMPAGESIZE)
|
|
|
|
rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX;
|
|
|
|
|
2016-01-07 16:42:48 +00:00
|
|
|
/* ensure we clear use DTYPE of 00 here */
|
|
|
|
rctl &= ~0x00000C00;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
/* Write out the settings */
|
|
|
|
E1000_WRITE_REG(hw, E1000_RCTL, rctl);
|
2007-05-04 00:00:12 +00:00
|
|
|
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
return;
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2006-01-20 11:38:25 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_vlan_register(if_ctx_t ctx, u16 vtag)
|
2002-06-03 22:30:51 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2009-06-24 17:41:29 +00:00
|
|
|
u32 index, bit;
|
2008-11-26 23:57:23 +00:00
|
|
|
|
2009-06-24 17:41:29 +00:00
|
|
|
index = (vtag >> 5) & 0x7F;
|
|
|
|
bit = vtag & 0x1F;
|
2010-10-26 00:07:58 +00:00
|
|
|
adapter->shadow_vfta[index] |= (1 << bit);
|
2009-06-24 17:41:29 +00:00
|
|
|
++adapter->num_vlans;
|
2008-11-26 23:57:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_vlan_unregister(if_ctx_t ctx, u16 vtag)
|
2008-11-26 23:57:23 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2009-06-24 17:41:29 +00:00
|
|
|
u32 index, bit;
|
|
|
|
|
|
|
|
index = (vtag >> 5) & 0x7F;
|
|
|
|
bit = vtag & 0x1F;
|
2010-10-26 00:07:58 +00:00
|
|
|
adapter->shadow_vfta[index] &= ~(1 << bit);
|
2009-06-24 17:41:29 +00:00
|
|
|
--adapter->num_vlans;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
em_setup_vlan_hw_support(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
u32 reg;
|
|
|
|
|
|
|
|
/*
|
|
|
|
** We get here thru init_locked, meaning
|
|
|
|
** a soft reset, this has already cleared
|
|
|
|
** the VFTA and other state, so if there
|
|
|
|
** have been no vlan's registered do nothing.
|
|
|
|
*/
|
|
|
|
if (adapter->num_vlans == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
** A soft reset zero's out the VFTA, so
|
|
|
|
** we need to repopulate it now.
|
|
|
|
*/
|
|
|
|
for (int i = 0; i < EM_VFTA_SIZE; i++)
|
2010-10-26 00:07:58 +00:00
|
|
|
if (adapter->shadow_vfta[i] != 0)
|
2009-06-24 17:41:29 +00:00
|
|
|
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
|
2010-10-26 00:07:58 +00:00
|
|
|
i, adapter->shadow_vfta[i]);
|
2009-06-24 17:41:29 +00:00
|
|
|
|
|
|
|
reg = E1000_READ_REG(hw, E1000_CTRL);
|
|
|
|
reg |= E1000_CTRL_VME;
|
|
|
|
E1000_WRITE_REG(hw, E1000_CTRL, reg);
|
|
|
|
|
|
|
|
/* Enable the Filter Table */
|
|
|
|
reg = E1000_READ_REG(hw, E1000_RCTL);
|
|
|
|
reg &= ~E1000_RCTL_CFIEN;
|
|
|
|
reg |= E1000_RCTL_VFE;
|
|
|
|
E1000_WRITE_REG(hw, E1000_RCTL, reg);
|
2002-06-03 22:30:51 +00:00
|
|
|
}
|
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_enable_intr(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2008-02-29 21:50:11 +00:00
|
|
|
u32 ims_mask = IMS_ENABLE_MASK;
|
|
|
|
|
2010-04-10 07:26:51 +00:00
|
|
|
if (hw->mac.type == e1000_82574) {
|
2017-01-12 14:28:32 +00:00
|
|
|
E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
|
2015-08-16 19:43:44 +00:00
|
|
|
ims_mask |= adapter->ims;
|
2017-01-10 03:23:22 +00:00
|
|
|
} if (adapter->intr_type == IFLIB_INTR_MSIX && hw->mac.type >= igb_mac_min) {
|
|
|
|
u32 mask = (adapter->que_mask | adapter->link_mask);
|
|
|
|
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIAC, mask);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIAM, mask);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIMS, mask);
|
|
|
|
ims_mask = E1000_IMS_LSC;
|
|
|
|
}
|
|
|
|
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
E1000_WRITE_REG(hw, E1000_IMS, ims_mask);
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_disable_intr(if_ctx_t ctx)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if (adapter->intr_type == IFLIB_INTR_MSIX) {
|
|
|
|
if (hw->mac.type >= igb_mac_min)
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIMC, ~0);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_EIAC, 0);
|
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
|
|
|
|
}
|
2005-01-01 19:57:23 +00:00
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/*
|
|
|
|
* Bit of a misnomer, what this really means is
|
|
|
|
* to enable OS management of the system... aka
|
|
|
|
* to disable special hardware management features
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
em_init_manageability(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
/* A shared code workaround */
|
|
|
|
#define E1000_82542_MANC2H E1000_MANC2H
|
|
|
|
if (adapter->has_manage) {
|
|
|
|
int manc2h = E1000_READ_REG(&adapter->hw, E1000_MANC2H);
|
|
|
|
int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
|
|
|
|
|
|
|
|
/* disable hardware interception of ARP */
|
|
|
|
manc &= ~(E1000_MANC_ARP_EN);
|
|
|
|
|
|
|
|
/* enable receiving management packets to the host */
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
manc |= E1000_MANC_EN_MNG2HOST;
|
2007-05-04 00:00:12 +00:00
|
|
|
#define E1000_MNG2HOST_PORT_623 (1 << 5)
|
|
|
|
#define E1000_MNG2HOST_PORT_664 (1 << 6)
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
manc2h |= E1000_MNG2HOST_PORT_623;
|
|
|
|
manc2h |= E1000_MNG2HOST_PORT_664;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_MANC2H, manc2h);
|
2007-05-04 00:00:12 +00:00
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Give control back to hardware management
|
|
|
|
* controller if there is one.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
em_release_manageability(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
if (adapter->has_manage) {
|
|
|
|
int manc = E1000_READ_REG(&adapter->hw, E1000_MANC);
|
|
|
|
|
|
|
|
/* re-enable hardware interception of ARP */
|
|
|
|
manc |= E1000_MANC_ARP_EN;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
manc &= ~E1000_MANC_EN_MNG2HOST;
|
2007-05-04 00:00:12 +00:00
|
|
|
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_MANC, manc);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-12-08 01:07:44 +00:00
|
|
|
* em_get_hw_control sets the {CTRL_EXT|FWSM}:DRV_LOAD bit.
|
|
|
|
* For ASF and Pass Through versions of f/w this means
|
|
|
|
* that the driver is loaded. For AMT version type f/w
|
|
|
|
* this means that the network i/f is open.
|
2007-05-04 00:00:12 +00:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
em_get_hw_control(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
u32 ctrl_ext, swsm;
|
|
|
|
|
2009-12-08 01:07:44 +00:00
|
|
|
if (adapter->hw.mac.type == e1000_82573) {
|
2007-05-04 00:00:12 +00:00
|
|
|
swsm = E1000_READ_REG(&adapter->hw, E1000_SWSM);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_SWSM,
|
|
|
|
swsm | E1000_SWSM_DRV_LOAD);
|
2009-12-08 01:07:44 +00:00
|
|
|
return;
|
2007-05-04 00:00:12 +00:00
|
|
|
}
|
2009-12-08 01:07:44 +00:00
|
|
|
/* else */
|
|
|
|
ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
|
|
|
|
ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
|
|
|
|
return;
|
2007-05-04 00:00:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* em_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
|
2009-12-08 01:07:44 +00:00
|
|
|
* For ASF and Pass Through versions of f/w this means that
|
|
|
|
* the driver is no longer loaded. For AMT versions of the
|
|
|
|
* f/w this means that the network i/f is closed.
|
2007-05-04 00:00:12 +00:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
em_release_hw_control(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
u32 ctrl_ext, swsm;
|
|
|
|
|
2009-12-08 01:07:44 +00:00
|
|
|
if (!adapter->has_manage)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (adapter->hw.mac.type == e1000_82573) {
|
2007-05-04 00:00:12 +00:00
|
|
|
swsm = E1000_READ_REG(&adapter->hw, E1000_SWSM);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_SWSM,
|
|
|
|
swsm & ~E1000_SWSM_DRV_LOAD);
|
2009-12-08 01:07:44 +00:00
|
|
|
return;
|
2007-05-04 00:00:12 +00:00
|
|
|
}
|
2009-12-08 01:07:44 +00:00
|
|
|
/* else */
|
|
|
|
ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT,
|
|
|
|
ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
|
|
|
|
return;
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2003-06-05 17:51:38 +00:00
|
|
|
static int
|
2008-02-29 21:50:11 +00:00
|
|
|
em_is_valid_ether_addr(u8 *addr)
|
2003-06-05 17:51:38 +00:00
|
|
|
{
|
2006-02-15 08:39:50 +00:00
|
|
|
char zero_addr[6] = { 0, 0, 0, 0, 0, 0 };
|
2006-01-20 11:38:25 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
if ((addr[0] & 1) || (!bcmp(addr, zero_addr, ETHER_ADDR_LEN))) {
|
|
|
|
return (FALSE);
|
|
|
|
}
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
return (TRUE);
|
2003-06-05 17:51:38 +00:00
|
|
|
}
|
|
|
|
|
2009-12-08 01:07:44 +00:00
|
|
|
/*
|
|
|
|
** Parse the interface capabilities with regard
|
|
|
|
** to both system management and wake-on-lan for
|
|
|
|
** later use.
|
|
|
|
*/
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_get_wakeup(if_ctx_t ctx)
|
2009-12-08 01:07:44 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
device_t dev = iflib_get_dev(ctx);
|
2009-12-08 01:07:44 +00:00
|
|
|
u16 eeprom_data = 0, device_id, apme_mask;
|
|
|
|
|
|
|
|
adapter->has_manage = e1000_enable_mng_pass_thru(&adapter->hw);
|
|
|
|
apme_mask = EM_EEPROM_APME;
|
|
|
|
|
|
|
|
switch (adapter->hw.mac.type) {
|
2017-01-10 03:23:22 +00:00
|
|
|
case e1000_82542:
|
|
|
|
case e1000_82543:
|
|
|
|
break;
|
|
|
|
case e1000_82544:
|
|
|
|
e1000_read_nvm(&adapter->hw,
|
|
|
|
NVM_INIT_CONTROL2_REG, 1, &eeprom_data);
|
|
|
|
apme_mask = EM_82544_APME;
|
|
|
|
break;
|
|
|
|
case e1000_82546:
|
|
|
|
case e1000_82546_rev_3:
|
|
|
|
if (adapter->hw.bus.func == 1) {
|
|
|
|
e1000_read_nvm(&adapter->hw,
|
|
|
|
NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
e1000_read_nvm(&adapter->hw,
|
|
|
|
NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
|
|
|
|
break;
|
2009-12-08 01:07:44 +00:00
|
|
|
case e1000_82573:
|
|
|
|
case e1000_82583:
|
|
|
|
adapter->has_amt = TRUE;
|
|
|
|
/* Falls thru */
|
|
|
|
case e1000_82571:
|
|
|
|
case e1000_82572:
|
|
|
|
case e1000_80003es2lan:
|
|
|
|
if (adapter->hw.bus.func == 1) {
|
|
|
|
e1000_read_nvm(&adapter->hw,
|
|
|
|
NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
|
|
|
|
break;
|
|
|
|
} else
|
|
|
|
e1000_read_nvm(&adapter->hw,
|
|
|
|
NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
|
|
|
|
break;
|
|
|
|
case e1000_ich8lan:
|
|
|
|
case e1000_ich9lan:
|
|
|
|
case e1000_ich10lan:
|
|
|
|
case e1000_pchlan:
|
2010-10-26 00:07:58 +00:00
|
|
|
case e1000_pch2lan:
|
2017-01-12 14:47:44 +00:00
|
|
|
case e1000_pch_lpt:
|
|
|
|
case e1000_pch_spt:
|
2009-12-08 01:07:44 +00:00
|
|
|
apme_mask = E1000_WUC_APME;
|
|
|
|
adapter->has_amt = TRUE;
|
|
|
|
eeprom_data = E1000_READ_REG(&adapter->hw, E1000_WUC);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
e1000_read_nvm(&adapter->hw,
|
|
|
|
NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (eeprom_data & apme_mask)
|
|
|
|
adapter->wol = (E1000_WUFC_MAG | E1000_WUFC_MC);
|
|
|
|
/*
|
|
|
|
* We have the eeprom settings, now apply the special cases
|
|
|
|
* where the eeprom may be wrong or the board won't support
|
|
|
|
* wake on lan on a particular port
|
|
|
|
*/
|
|
|
|
device_id = pci_get_device(dev);
|
|
|
|
switch (device_id) {
|
2017-01-10 03:23:22 +00:00
|
|
|
case E1000_DEV_ID_82546GB_PCIE:
|
|
|
|
adapter->wol = 0;
|
|
|
|
break;
|
|
|
|
case E1000_DEV_ID_82546EB_FIBER:
|
|
|
|
case E1000_DEV_ID_82546GB_FIBER:
|
|
|
|
/* Wake events only supported on port A for dual fiber
|
|
|
|
* regardless of eeprom setting */
|
|
|
|
if (E1000_READ_REG(&adapter->hw, E1000_STATUS) &
|
|
|
|
E1000_STATUS_FUNC_1)
|
|
|
|
adapter->wol = 0;
|
|
|
|
break;
|
|
|
|
case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
|
|
|
|
/* if quad port adapter, disable WoL on all but port A */
|
|
|
|
if (global_quad_port_a != 0)
|
|
|
|
adapter->wol = 0;
|
|
|
|
/* Reset for multiple quad port adapters */
|
|
|
|
if (++global_quad_port_a == 4)
|
|
|
|
global_quad_port_a = 0;
|
|
|
|
break;
|
2009-12-08 01:07:44 +00:00
|
|
|
case E1000_DEV_ID_82571EB_FIBER:
|
|
|
|
/* Wake events only supported on port A for dual fiber
|
|
|
|
* regardless of eeprom setting */
|
|
|
|
if (E1000_READ_REG(&adapter->hw, E1000_STATUS) &
|
|
|
|
E1000_STATUS_FUNC_1)
|
|
|
|
adapter->wol = 0;
|
|
|
|
break;
|
|
|
|
case E1000_DEV_ID_82571EB_QUAD_COPPER:
|
|
|
|
case E1000_DEV_ID_82571EB_QUAD_FIBER:
|
|
|
|
case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
|
|
|
|
/* if quad port adapter, disable WoL on all but port A */
|
|
|
|
if (global_quad_port_a != 0)
|
|
|
|
adapter->wol = 0;
|
|
|
|
/* Reset for multiple quad port adapters */
|
|
|
|
if (++global_quad_port_a == 4)
|
|
|
|
global_quad_port_a = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
/*
|
|
|
|
* Enable PCI Wake On Lan capability
|
|
|
|
*/
|
2010-03-31 20:43:24 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_enable_wakeup(if_ctx_t ctx)
|
2007-05-04 00:00:12 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
device_t dev = iflib_get_dev(ctx);
|
|
|
|
if_t ifp = iflib_get_ifp(ctx);
|
2017-01-12 14:47:44 +00:00
|
|
|
u32 pmc, ctrl, ctrl_ext, rctl, wuc;
|
2009-12-08 01:07:44 +00:00
|
|
|
u16 status;
|
|
|
|
|
2011-03-23 13:10:15 +00:00
|
|
|
if ((pci_find_cap(dev, PCIY_PMG, &pmc) != 0))
|
2007-05-04 00:00:12 +00:00
|
|
|
return;
|
2009-12-08 01:07:44 +00:00
|
|
|
|
|
|
|
/* Advertise the wakeup capability */
|
|
|
|
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
|
|
|
|
ctrl |= (E1000_CTRL_SWDPIN2 | E1000_CTRL_SWDPIN3);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
|
2017-01-12 14:47:44 +00:00
|
|
|
wuc = E1000_READ_REG(&adapter->hw, E1000_WUC);
|
|
|
|
wuc |= E1000_WUC_PME_EN ;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_WUC, wuc);
|
2009-12-08 01:07:44 +00:00
|
|
|
|
|
|
|
if ((adapter->hw.mac.type == e1000_ich8lan) ||
|
|
|
|
(adapter->hw.mac.type == e1000_pchlan) ||
|
|
|
|
(adapter->hw.mac.type == e1000_ich9lan) ||
|
2011-03-18 18:54:00 +00:00
|
|
|
(adapter->hw.mac.type == e1000_ich10lan))
|
2011-12-10 07:08:52 +00:00
|
|
|
e1000_suspend_workarounds_ich8lan(&adapter->hw);
|
2009-12-08 01:07:44 +00:00
|
|
|
|
|
|
|
/* Keep the laser running on Fiber adapters */
|
|
|
|
if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
|
|
|
|
adapter->hw.phy.media_type == e1000_media_type_internal_serdes) {
|
|
|
|
ctrl_ext = E1000_READ_REG(&adapter->hw, E1000_CTRL_EXT);
|
|
|
|
ctrl_ext |= E1000_CTRL_EXT_SDP3_DATA;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_CTRL_EXT, ctrl_ext);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Determine type of Wakeup: note that wol
|
|
|
|
** is set with all bits on by default.
|
|
|
|
*/
|
2014-06-02 18:52:03 +00:00
|
|
|
if ((if_getcapenable(ifp) & IFCAP_WOL_MAGIC) == 0)
|
2009-12-08 01:07:44 +00:00
|
|
|
adapter->wol &= ~E1000_WUFC_MAG;
|
|
|
|
|
2014-06-02 18:52:03 +00:00
|
|
|
if ((if_getcapenable(ifp) & IFCAP_WOL_MCAST) == 0)
|
2009-12-08 01:07:44 +00:00
|
|
|
adapter->wol &= ~E1000_WUFC_MC;
|
|
|
|
else {
|
|
|
|
rctl = E1000_READ_REG(&adapter->hw, E1000_RCTL);
|
|
|
|
rctl |= E1000_RCTL_MPE;
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_RCTL, rctl);
|
|
|
|
}
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
if ((adapter->hw.mac.type == e1000_pchlan) ||
|
2017-01-12 14:47:44 +00:00
|
|
|
(adapter->hw.mac.type == e1000_pch2lan) ||
|
|
|
|
(adapter->hw.mac.type == e1000_pch_lpt) ||
|
|
|
|
(adapter->hw.mac.type == e1000_pch_spt)) {
|
2009-12-08 01:07:44 +00:00
|
|
|
if (em_enable_phy_wakeup(adapter))
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_WUC, E1000_WUC_PME_EN);
|
|
|
|
E1000_WRITE_REG(&adapter->hw, E1000_WUFC, adapter->wol);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (adapter->hw.phy.type == e1000_phy_igp_3)
|
|
|
|
e1000_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
|
|
|
|
|
|
|
|
/* Request PME */
|
|
|
|
status = pci_read_config(dev, pmc + PCIR_POWER_STATUS, 2);
|
|
|
|
status &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE);
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getcapenable(ifp) & IFCAP_WOL)
|
2009-12-08 01:07:44 +00:00
|
|
|
status |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
|
|
|
|
pci_write_config(dev, pmc + PCIR_POWER_STATUS, status, 2);
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-12-08 01:07:44 +00:00
|
|
|
/*
|
|
|
|
** WOL in the newer chipset interfaces (pchlan)
|
|
|
|
** require thing to be copied into the phy
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
em_enable_phy_wakeup(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
u32 mreg, ret = 0;
|
|
|
|
u16 preg;
|
|
|
|
|
|
|
|
/* copy MAC RARs to PHY RARs */
|
2010-10-26 00:07:58 +00:00
|
|
|
e1000_copy_rx_addrs_to_phy_ich8lan(hw);
|
2009-12-08 01:07:44 +00:00
|
|
|
|
|
|
|
/* copy MAC MTA to PHY MTA */
|
|
|
|
for (int i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
|
|
|
|
mreg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
|
|
|
|
e1000_write_phy_reg(hw, BM_MTA(i), (u16)(mreg & 0xFFFF));
|
|
|
|
e1000_write_phy_reg(hw, BM_MTA(i) + 1,
|
|
|
|
(u16)((mreg >> 16) & 0xFFFF));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* configure PHY Rx Control register */
|
|
|
|
e1000_read_phy_reg(&adapter->hw, BM_RCTL, &preg);
|
|
|
|
mreg = E1000_READ_REG(hw, E1000_RCTL);
|
|
|
|
if (mreg & E1000_RCTL_UPE)
|
|
|
|
preg |= BM_RCTL_UPE;
|
|
|
|
if (mreg & E1000_RCTL_MPE)
|
|
|
|
preg |= BM_RCTL_MPE;
|
|
|
|
preg &= ~(BM_RCTL_MO_MASK);
|
|
|
|
if (mreg & E1000_RCTL_MO_3)
|
|
|
|
preg |= (((mreg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
|
|
|
|
<< BM_RCTL_MO_SHIFT);
|
|
|
|
if (mreg & E1000_RCTL_BAM)
|
|
|
|
preg |= BM_RCTL_BAM;
|
|
|
|
if (mreg & E1000_RCTL_PMCF)
|
|
|
|
preg |= BM_RCTL_PMCF;
|
|
|
|
mreg = E1000_READ_REG(hw, E1000_CTRL);
|
|
|
|
if (mreg & E1000_CTRL_RFCE)
|
|
|
|
preg |= BM_RCTL_RFCE;
|
|
|
|
e1000_write_phy_reg(&adapter->hw, BM_RCTL, preg);
|
|
|
|
|
|
|
|
/* enable PHY wakeup in MAC register */
|
|
|
|
E1000_WRITE_REG(hw, E1000_WUC,
|
|
|
|
E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
|
|
|
|
E1000_WRITE_REG(hw, E1000_WUFC, adapter->wol);
|
|
|
|
|
|
|
|
/* configure and enable PHY wakeup in PHY registers */
|
|
|
|
e1000_write_phy_reg(&adapter->hw, BM_WUFC, adapter->wol);
|
|
|
|
e1000_write_phy_reg(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
|
|
|
|
|
|
|
|
/* activate PHY wakeup */
|
|
|
|
ret = hw->phy.ops.acquire(hw);
|
|
|
|
if (ret) {
|
|
|
|
printf("Could not acquire PHY\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
|
|
|
|
(BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
|
|
|
|
ret = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &preg);
|
|
|
|
if (ret) {
|
|
|
|
printf("Could not read PHY page 769\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
preg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
|
|
|
|
ret = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, preg);
|
|
|
|
if (ret)
|
|
|
|
printf("Could not set PHY Host Wakeup bit\n");
|
|
|
|
out:
|
|
|
|
hw->phy.ops.release(hw);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-03-31 20:43:24 +00:00
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_led_func(if_ctx_t ctx, int onoff)
|
2010-03-31 20:43:24 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
2010-03-31 20:43:24 +00:00
|
|
|
|
|
|
|
if (onoff) {
|
|
|
|
e1000_setup_led(&adapter->hw);
|
|
|
|
e1000_led_on(&adapter->hw);
|
|
|
|
} else {
|
|
|
|
e1000_led_off(&adapter->hw);
|
|
|
|
e1000_cleanup_led(&adapter->hw);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-24 22:24:07 +00:00
|
|
|
/*
|
|
|
|
** Disable the L0S and L1 LINK states
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
em_disable_aspm(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
int base, reg;
|
|
|
|
u16 link_cap,link_ctrl;
|
|
|
|
device_t dev = adapter->dev;
|
|
|
|
|
|
|
|
switch (adapter->hw.mac.type) {
|
|
|
|
case e1000_82573:
|
|
|
|
case e1000_82574:
|
|
|
|
case e1000_82583:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2011-03-23 13:10:15 +00:00
|
|
|
if (pci_find_cap(dev, PCIY_EXPRESS, &base) != 0)
|
2010-11-24 22:24:07 +00:00
|
|
|
return;
|
2012-09-18 22:04:59 +00:00
|
|
|
reg = base + PCIER_LINK_CAP;
|
2010-11-24 22:24:07 +00:00
|
|
|
link_cap = pci_read_config(dev, reg, 2);
|
2012-09-18 22:04:59 +00:00
|
|
|
if ((link_cap & PCIEM_LINK_CAP_ASPM) == 0)
|
2010-11-24 22:24:07 +00:00
|
|
|
return;
|
2012-09-18 22:04:59 +00:00
|
|
|
reg = base + PCIER_LINK_CTL;
|
2010-11-24 22:24:07 +00:00
|
|
|
link_ctrl = pci_read_config(dev, reg, 2);
|
2012-09-19 12:27:23 +00:00
|
|
|
link_ctrl &= ~PCIEM_LINK_CTL_ASPMC;
|
2010-11-24 22:24:07 +00:00
|
|
|
pci_write_config(dev, reg, link_ctrl, 2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2001-12-02 07:37:17 +00:00
|
|
|
/**********************************************************************
|
|
|
|
*
|
2006-01-20 11:38:25 +00:00
|
|
|
* Update the board statistics counters.
|
2001-12-02 07:37:17 +00:00
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
static void
|
2006-08-03 19:05:04 +00:00
|
|
|
em_update_stats_counters(struct adapter *adapter)
|
2001-12-02 07:37:17 +00:00
|
|
|
{
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2007-11-20 21:41:22 +00:00
|
|
|
if(adapter->hw.phy.media_type == e1000_media_type_copper ||
|
2007-05-04 00:00:12 +00:00
|
|
|
(E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
|
|
|
|
adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
|
|
|
|
adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
|
2006-08-03 19:05:04 +00:00
|
|
|
}
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
|
|
|
|
adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);
|
|
|
|
adapter->stats.scc += E1000_READ_REG(&adapter->hw, E1000_SCC);
|
|
|
|
adapter->stats.ecol += E1000_READ_REG(&adapter->hw, E1000_ECOL);
|
|
|
|
|
|
|
|
adapter->stats.mcc += E1000_READ_REG(&adapter->hw, E1000_MCC);
|
|
|
|
adapter->stats.latecol += E1000_READ_REG(&adapter->hw, E1000_LATECOL);
|
|
|
|
adapter->stats.colc += E1000_READ_REG(&adapter->hw, E1000_COLC);
|
|
|
|
adapter->stats.dc += E1000_READ_REG(&adapter->hw, E1000_DC);
|
|
|
|
adapter->stats.rlec += E1000_READ_REG(&adapter->hw, E1000_RLEC);
|
|
|
|
adapter->stats.xonrxc += E1000_READ_REG(&adapter->hw, E1000_XONRXC);
|
|
|
|
adapter->stats.xontxc += E1000_READ_REG(&adapter->hw, E1000_XONTXC);
|
2015-06-02 18:28:41 +00:00
|
|
|
adapter->stats.xoffrxc += E1000_READ_REG(&adapter->hw, E1000_XOFFRXC);
|
2007-05-04 00:00:12 +00:00
|
|
|
adapter->stats.xofftxc += E1000_READ_REG(&adapter->hw, E1000_XOFFTXC);
|
|
|
|
adapter->stats.fcruc += E1000_READ_REG(&adapter->hw, E1000_FCRUC);
|
|
|
|
adapter->stats.prc64 += E1000_READ_REG(&adapter->hw, E1000_PRC64);
|
|
|
|
adapter->stats.prc127 += E1000_READ_REG(&adapter->hw, E1000_PRC127);
|
|
|
|
adapter->stats.prc255 += E1000_READ_REG(&adapter->hw, E1000_PRC255);
|
|
|
|
adapter->stats.prc511 += E1000_READ_REG(&adapter->hw, E1000_PRC511);
|
|
|
|
adapter->stats.prc1023 += E1000_READ_REG(&adapter->hw, E1000_PRC1023);
|
|
|
|
adapter->stats.prc1522 += E1000_READ_REG(&adapter->hw, E1000_PRC1522);
|
|
|
|
adapter->stats.gprc += E1000_READ_REG(&adapter->hw, E1000_GPRC);
|
|
|
|
adapter->stats.bprc += E1000_READ_REG(&adapter->hw, E1000_BPRC);
|
|
|
|
adapter->stats.mprc += E1000_READ_REG(&adapter->hw, E1000_MPRC);
|
|
|
|
adapter->stats.gptc += E1000_READ_REG(&adapter->hw, E1000_GPTC);
|
2002-06-03 22:30:51 +00:00
|
|
|
|
|
|
|
/* For the 64-bit byte counters the low dword must be read first. */
|
|
|
|
/* Both registers clear on the read of the high dword */
|
|
|
|
|
2010-09-20 16:04:44 +00:00
|
|
|
adapter->stats.gorc += E1000_READ_REG(&adapter->hw, E1000_GORCL) +
|
|
|
|
((u64)E1000_READ_REG(&adapter->hw, E1000_GORCH) << 32);
|
|
|
|
adapter->stats.gotc += E1000_READ_REG(&adapter->hw, E1000_GOTCL) +
|
|
|
|
((u64)E1000_READ_REG(&adapter->hw, E1000_GOTCH) << 32);
|
2007-05-04 00:00:12 +00:00
|
|
|
|
|
|
|
adapter->stats.rnbc += E1000_READ_REG(&adapter->hw, E1000_RNBC);
|
|
|
|
adapter->stats.ruc += E1000_READ_REG(&adapter->hw, E1000_RUC);
|
|
|
|
adapter->stats.rfc += E1000_READ_REG(&adapter->hw, E1000_RFC);
|
|
|
|
adapter->stats.roc += E1000_READ_REG(&adapter->hw, E1000_ROC);
|
|
|
|
adapter->stats.rjc += E1000_READ_REG(&adapter->hw, E1000_RJC);
|
|
|
|
|
2007-11-20 21:41:22 +00:00
|
|
|
adapter->stats.tor += E1000_READ_REG(&adapter->hw, E1000_TORH);
|
|
|
|
adapter->stats.tot += E1000_READ_REG(&adapter->hw, E1000_TOTH);
|
2007-05-04 00:00:12 +00:00
|
|
|
|
|
|
|
adapter->stats.tpr += E1000_READ_REG(&adapter->hw, E1000_TPR);
|
|
|
|
adapter->stats.tpt += E1000_READ_REG(&adapter->hw, E1000_TPT);
|
|
|
|
adapter->stats.ptc64 += E1000_READ_REG(&adapter->hw, E1000_PTC64);
|
|
|
|
adapter->stats.ptc127 += E1000_READ_REG(&adapter->hw, E1000_PTC127);
|
|
|
|
adapter->stats.ptc255 += E1000_READ_REG(&adapter->hw, E1000_PTC255);
|
|
|
|
adapter->stats.ptc511 += E1000_READ_REG(&adapter->hw, E1000_PTC511);
|
|
|
|
adapter->stats.ptc1023 += E1000_READ_REG(&adapter->hw, E1000_PTC1023);
|
|
|
|
adapter->stats.ptc1522 += E1000_READ_REG(&adapter->hw, E1000_PTC1522);
|
|
|
|
adapter->stats.mptc += E1000_READ_REG(&adapter->hw, E1000_MPTC);
|
|
|
|
adapter->stats.bptc += E1000_READ_REG(&adapter->hw, E1000_BPTC);
|
|
|
|
|
2010-09-20 16:04:44 +00:00
|
|
|
/* Interrupt Counts */
|
|
|
|
|
|
|
|
adapter->stats.iac += E1000_READ_REG(&adapter->hw, E1000_IAC);
|
|
|
|
adapter->stats.icrxptc += E1000_READ_REG(&adapter->hw, E1000_ICRXPTC);
|
|
|
|
adapter->stats.icrxatc += E1000_READ_REG(&adapter->hw, E1000_ICRXATC);
|
|
|
|
adapter->stats.ictxptc += E1000_READ_REG(&adapter->hw, E1000_ICTXPTC);
|
|
|
|
adapter->stats.ictxatc += E1000_READ_REG(&adapter->hw, E1000_ICTXATC);
|
|
|
|
adapter->stats.ictxqec += E1000_READ_REG(&adapter->hw, E1000_ICTXQEC);
|
|
|
|
adapter->stats.ictxqmtc += E1000_READ_REG(&adapter->hw, E1000_ICTXQMTC);
|
|
|
|
adapter->stats.icrxdmtc += E1000_READ_REG(&adapter->hw, E1000_ICRXDMTC);
|
|
|
|
adapter->stats.icrxoc += E1000_READ_REG(&adapter->hw, E1000_ICRXOC);
|
|
|
|
|
2007-05-04 00:00:12 +00:00
|
|
|
if (adapter->hw.mac.type >= e1000_82543) {
|
|
|
|
adapter->stats.algnerrc +=
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_ALGNERRC);
|
|
|
|
adapter->stats.rxerrc +=
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_RXERRC);
|
|
|
|
adapter->stats.tncrs +=
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TNCRS);
|
|
|
|
adapter->stats.cexterr +=
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_CEXTERR);
|
|
|
|
adapter->stats.tsctc +=
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TSCTC);
|
|
|
|
adapter->stats.tsctfc +=
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TSCTFC);
|
2006-08-03 19:05:04 +00:00
|
|
|
}
|
2014-09-18 15:56:14 +00:00
|
|
|
}
|
2002-06-03 22:30:51 +00:00
|
|
|
|
2014-09-18 15:56:14 +00:00
|
|
|
static uint64_t
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_get_counter(if_ctx_t ctx, ift_counter cnt)
|
2014-09-18 15:56:14 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
|
|
|
struct ifnet *ifp = iflib_get_ifp(ctx);
|
2014-09-18 15:56:14 +00:00
|
|
|
|
|
|
|
switch (cnt) {
|
|
|
|
case IFCOUNTER_COLLISIONS:
|
|
|
|
return (adapter->stats.colc);
|
|
|
|
case IFCOUNTER_IERRORS:
|
|
|
|
return (adapter->dropped_pkts + adapter->stats.rxerrc +
|
|
|
|
adapter->stats.crcerrs + adapter->stats.algnerrc +
|
|
|
|
adapter->stats.ruc + adapter->stats.roc +
|
|
|
|
adapter->stats.mpc + adapter->stats.cexterr);
|
|
|
|
case IFCOUNTER_OERRORS:
|
|
|
|
return (adapter->stats.ecol + adapter->stats.latecol +
|
|
|
|
adapter->watchdog_events);
|
|
|
|
default:
|
|
|
|
return (if_get_counter_default(ifp, cnt));
|
|
|
|
}
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2010-09-20 16:04:44 +00:00
|
|
|
/* Export a single 32-bit register via a read-only sysctl. */
|
|
|
|
static int
|
|
|
|
em_sysctl_reg_handler(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
|
|
|
struct adapter *adapter;
|
|
|
|
u_int val;
|
|
|
|
|
|
|
|
adapter = oidp->oid_arg1;
|
|
|
|
val = E1000_READ_REG(&adapter->hw, oidp->oid_arg2);
|
|
|
|
return (sysctl_handle_int(oidp, &val, 0, req));
|
|
|
|
}
|
2001-12-02 07:37:17 +00:00
|
|
|
|
2010-06-16 20:57:41 +00:00
|
|
|
/*
|
|
|
|
* Add sysctl variables, one per statistic, to the system.
|
|
|
|
*/
|
2001-12-02 07:37:17 +00:00
|
|
|
static void
|
2010-06-16 20:57:41 +00:00
|
|
|
em_add_hw_stats(struct adapter *adapter)
|
2006-02-15 08:39:50 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
device_t dev = iflib_get_dev(adapter->ctx);
|
|
|
|
struct em_tx_queue *tx_que = adapter->tx_queues;
|
|
|
|
struct em_rx_queue *rx_que = adapter->rx_queues;
|
|
|
|
|
2010-06-16 20:57:41 +00:00
|
|
|
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
|
|
|
|
struct sysctl_oid *tree = device_get_sysctl_tree(dev);
|
|
|
|
struct sysctl_oid_list *child = SYSCTL_CHILDREN(tree);
|
|
|
|
struct e1000_hw_stats *stats = &adapter->stats;
|
|
|
|
|
2010-09-20 16:04:44 +00:00
|
|
|
struct sysctl_oid *stat_node, *queue_node, *int_node;
|
|
|
|
struct sysctl_oid_list *stat_list, *queue_list, *int_list;
|
2010-06-16 20:57:41 +00:00
|
|
|
|
2010-09-20 16:04:44 +00:00
|
|
|
#define QUEUE_NAME_LEN 32
|
|
|
|
char namebuf[QUEUE_NAME_LEN];
|
|
|
|
|
2010-06-16 20:57:41 +00:00
|
|
|
/* Driver Statistics */
|
|
|
|
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "dropped",
|
|
|
|
CTLFLAG_RD, &adapter->dropped_pkts,
|
|
|
|
"Driver dropped packets");
|
2016-01-13 21:47:27 +00:00
|
|
|
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "link_irq",
|
|
|
|
CTLFLAG_RD, &adapter->link_irq,
|
|
|
|
"Link MSIX IRQ Handled");
|
|
|
|
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "mbuf_defrag_fail",
|
|
|
|
CTLFLAG_RD, &adapter->mbuf_defrag_failed,
|
|
|
|
"Defragmenting mbuf chain failed");
|
2010-06-16 20:57:41 +00:00
|
|
|
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_dma_fail",
|
|
|
|
CTLFLAG_RD, &adapter->no_tx_dma_setup,
|
|
|
|
"Driver tx dma failure in xmit");
|
2010-09-20 16:04:44 +00:00
|
|
|
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "rx_overruns",
|
|
|
|
CTLFLAG_RD, &adapter->rx_overruns,
|
|
|
|
"RX overruns");
|
|
|
|
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "watchdog_timeouts",
|
|
|
|
CTLFLAG_RD, &adapter->watchdog_events,
|
|
|
|
"Watchdog timeouts");
|
|
|
|
|
|
|
|
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "device_control",
|
2011-01-18 21:14:23 +00:00
|
|
|
CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_CTRL,
|
2010-09-20 16:04:44 +00:00
|
|
|
em_sysctl_reg_handler, "IU",
|
|
|
|
"Device Control Register");
|
|
|
|
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_control",
|
2011-01-18 21:14:23 +00:00
|
|
|
CTLTYPE_UINT | CTLFLAG_RD, adapter, E1000_RCTL,
|
2010-09-20 16:04:44 +00:00
|
|
|
em_sysctl_reg_handler, "IU",
|
|
|
|
"Receiver Control Register");
|
2010-06-16 20:57:41 +00:00
|
|
|
SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_high_water",
|
|
|
|
CTLFLAG_RD, &adapter->hw.fc.high_water, 0,
|
|
|
|
"Flow Control High Watermark");
|
|
|
|
SYSCTL_ADD_UINT(ctx, child, OID_AUTO, "fc_low_water",
|
|
|
|
CTLFLAG_RD, &adapter->hw.fc.low_water, 0,
|
|
|
|
"Flow Control Low Watermark");
|
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int i = 0; i < adapter->tx_num_queues; i++, tx_que++) {
|
|
|
|
struct tx_ring *txr = &tx_que->txr;
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
snprintf(namebuf, QUEUE_NAME_LEN, "queue_tx_%d", i);
|
2010-09-20 16:04:44 +00:00
|
|
|
queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
CTLFLAG_RD, NULL, "TX Queue Name");
|
2010-09-20 16:04:44 +00:00
|
|
|
queue_list = SYSCTL_CHILDREN(queue_node);
|
|
|
|
|
|
|
|
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head",
|
2011-01-18 21:14:23 +00:00
|
|
|
CTLTYPE_UINT | CTLFLAG_RD, adapter,
|
|
|
|
E1000_TDH(txr->me),
|
2010-09-20 16:04:44 +00:00
|
|
|
em_sysctl_reg_handler, "IU",
|
|
|
|
"Transmit Descriptor Head");
|
|
|
|
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_tail",
|
2011-01-18 21:14:23 +00:00
|
|
|
CTLTYPE_UINT | CTLFLAG_RD, adapter,
|
|
|
|
E1000_TDT(txr->me),
|
2010-09-20 16:04:44 +00:00
|
|
|
em_sysctl_reg_handler, "IU",
|
|
|
|
"Transmit Descriptor Tail");
|
|
|
|
SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "tx_irq",
|
|
|
|
CTLFLAG_RD, &txr->tx_irq,
|
|
|
|
"Queue MSI-X Transmit Interrupts");
|
|
|
|
SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "no_desc_avail",
|
|
|
|
CTLFLAG_RD, &txr->no_desc_avail,
|
|
|
|
"Queue No Descriptor Available");
|
2017-01-10 03:23:22 +00:00
|
|
|
}
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int j = 0; j < adapter->rx_num_queues; j++, rx_que++) {
|
|
|
|
struct rx_ring *rxr = &rx_que->rxr;
|
|
|
|
snprintf(namebuf, QUEUE_NAME_LEN, "queue_rx_%d", j);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
queue_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, namebuf,
|
|
|
|
CTLFLAG_RD, NULL, "RX Queue Name");
|
|
|
|
queue_list = SYSCTL_CHILDREN(queue_node);
|
|
|
|
|
2010-09-20 16:04:44 +00:00
|
|
|
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_head",
|
2011-01-18 21:14:23 +00:00
|
|
|
CTLTYPE_UINT | CTLFLAG_RD, adapter,
|
|
|
|
E1000_RDH(rxr->me),
|
2010-09-20 16:04:44 +00:00
|
|
|
em_sysctl_reg_handler, "IU",
|
|
|
|
"Receive Descriptor Head");
|
|
|
|
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "rxd_tail",
|
2011-01-18 21:14:23 +00:00
|
|
|
CTLTYPE_UINT | CTLFLAG_RD, adapter,
|
|
|
|
E1000_RDT(rxr->me),
|
2010-09-20 16:04:44 +00:00
|
|
|
em_sysctl_reg_handler, "IU",
|
|
|
|
"Receive Descriptor Tail");
|
|
|
|
SYSCTL_ADD_ULONG(ctx, queue_list, OID_AUTO, "rx_irq",
|
|
|
|
CTLFLAG_RD, &rxr->rx_irq,
|
|
|
|
"Queue MSI-X Receive Interrupts");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* MAC stats get their own sub node */
|
2010-06-16 20:57:41 +00:00
|
|
|
|
|
|
|
stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "mac_stats",
|
|
|
|
CTLFLAG_RD, NULL, "Statistics");
|
|
|
|
stat_list = SYSCTL_CHILDREN(stat_node);
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "excess_coll",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &stats->ecol,
|
|
|
|
"Excessive collisions");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "single_coll",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &stats->scc,
|
|
|
|
"Single collisions");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "multiple_coll",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &stats->mcc,
|
|
|
|
"Multiple collisions");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "late_coll",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &stats->latecol,
|
|
|
|
"Late collisions");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "collision_count",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &stats->colc,
|
|
|
|
"Collision Count");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "symbol_errors",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.symerrs,
|
|
|
|
"Symbol Errors");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "sequence_errors",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.sec,
|
|
|
|
"Sequence Errors");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "defer_count",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.dc,
|
|
|
|
"Defer Count");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "missed_packets",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.mpc,
|
|
|
|
"Missed Packets");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_no_buff",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.rnbc,
|
|
|
|
"Receive No Buffers");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_undersize",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ruc,
|
|
|
|
"Receive Undersize");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_fragmented",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.rfc,
|
|
|
|
"Fragmented Packets Received ");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_oversize",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.roc,
|
|
|
|
"Oversized Packets Received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_jabber",
|
2010-09-20 16:04:44 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.rjc,
|
|
|
|
"Recevied Jabber");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "recv_errs",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.rxerrc,
|
|
|
|
"Receive Errors");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "crc_errs",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.crcerrs,
|
|
|
|
"CRC errors");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "alignment_errs",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.algnerrc,
|
|
|
|
"Alignment Errors");
|
|
|
|
/* On 82575 these are collision counts */
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "coll_ext_errs",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.cexterr,
|
|
|
|
"Collision/Carrier extension errors");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.xonrxc,
|
|
|
|
"XON Received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xon_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.xontxc,
|
|
|
|
"XON Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.xoffrxc,
|
|
|
|
"XOFF Received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "xoff_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.xofftxc,
|
|
|
|
"XOFF Transmitted");
|
|
|
|
|
|
|
|
/* Packet Reception Stats */
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.tpr,
|
|
|
|
"Total Packets Received ");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.gprc,
|
|
|
|
"Good Packets Received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.bprc,
|
|
|
|
"Broadcast Packets Received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.mprc,
|
|
|
|
"Multicast Packets Received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_64",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.prc64,
|
|
|
|
"64 byte frames received ");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_65_127",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.prc127,
|
|
|
|
"65-127 byte frames received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_128_255",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.prc255,
|
|
|
|
"128-255 byte frames received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_256_511",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.prc511,
|
|
|
|
"256-511 byte frames received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_512_1023",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.prc1023,
|
|
|
|
"512-1023 byte frames received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "rx_frames_1024_1522",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.prc1522,
|
|
|
|
"1023-1522 byte frames received");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_recvd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.gorc,
|
|
|
|
"Good Octets Received");
|
|
|
|
|
|
|
|
/* Packet Transmission Stats */
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_octets_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.gotc,
|
2010-09-20 16:04:44 +00:00
|
|
|
"Good Octets Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "total_pkts_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.tpt,
|
|
|
|
"Total Packets Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "good_pkts_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.gptc,
|
|
|
|
"Good Packets Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "bcast_pkts_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.bptc,
|
|
|
|
"Broadcast Packets Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "mcast_pkts_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.mptc,
|
|
|
|
"Multicast Packets Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_64",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ptc64,
|
|
|
|
"64 byte frames transmitted ");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_65_127",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ptc127,
|
|
|
|
"65-127 byte frames transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_128_255",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ptc255,
|
|
|
|
"128-255 byte frames transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_256_511",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ptc511,
|
|
|
|
"256-511 byte frames transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_512_1023",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ptc1023,
|
|
|
|
"512-1023 byte frames transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ptc1522,
|
|
|
|
"1024-1522 byte frames transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tso_txd",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.tsctc,
|
|
|
|
"TSO Contexts Transmitted");
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tso_ctx_fail",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.tsctfc,
|
|
|
|
"TSO Contexts Failed");
|
|
|
|
|
|
|
|
|
|
|
|
/* Interrupt Stats */
|
|
|
|
|
|
|
|
int_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "interrupts",
|
|
|
|
CTLFLAG_RD, NULL, "Interrupt Statistics");
|
|
|
|
int_list = SYSCTL_CHILDREN(int_node);
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "asserts",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.iac,
|
|
|
|
"Interrupt Assertion Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "rx_pkt_timer",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.icrxptc,
|
|
|
|
"Interrupt Cause Rx Pkt Timer Expire Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "rx_abs_timer",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.icrxatc,
|
|
|
|
"Interrupt Cause Rx Abs Timer Expire Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "tx_pkt_timer",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ictxptc,
|
|
|
|
"Interrupt Cause Tx Pkt Timer Expire Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "tx_abs_timer",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ictxatc,
|
|
|
|
"Interrupt Cause Tx Abs Timer Expire Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "tx_queue_empty",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ictxqec,
|
|
|
|
"Interrupt Cause Tx Queue Empty Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "tx_queue_min_thresh",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.ictxqmtc,
|
|
|
|
"Interrupt Cause Tx Queue Min Thresh Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "rx_desc_min_thresh",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.icrxdmtc,
|
|
|
|
"Interrupt Cause Rx Desc Min Thresh Count");
|
|
|
|
|
2011-01-12 19:53:23 +00:00
|
|
|
SYSCTL_ADD_UQUAD(ctx, int_list, OID_AUTO, "rx_overrun",
|
2010-06-16 20:57:41 +00:00
|
|
|
CTLFLAG_RD, &adapter->stats.icrxoc,
|
|
|
|
"Interrupt Cause Receiver Overrun Count");
|
2001-12-02 07:37:17 +00:00
|
|
|
}
|
|
|
|
|
2007-11-20 21:41:22 +00:00
|
|
|
/**********************************************************************
|
|
|
|
*
|
|
|
|
* This routine provides a way to dump out the adapter eeprom,
|
|
|
|
* often a useful debug/service tool. This only dumps the first
|
|
|
|
* 32 words, stuff that matters is in that extent.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
2003-06-05 17:51:38 +00:00
|
|
|
static int
|
2010-06-16 20:57:41 +00:00
|
|
|
em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS)
|
2003-06-05 17:51:38 +00:00
|
|
|
{
|
2011-12-10 07:08:52 +00:00
|
|
|
struct adapter *adapter = (struct adapter *)arg1;
|
2006-02-15 08:39:50 +00:00
|
|
|
int error;
|
|
|
|
int result;
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
result = -1;
|
|
|
|
error = sysctl_handle_int(oidp, &result, 0, req);
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
if (error || !req->newptr)
|
|
|
|
return (error);
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2007-11-20 21:41:22 +00:00
|
|
|
/*
|
|
|
|
* This value will cause a hex dump of the
|
|
|
|
* first 32 16-bit words of the EEPROM to
|
|
|
|
* the screen.
|
|
|
|
*/
|
2011-12-10 07:08:52 +00:00
|
|
|
if (result == 1)
|
2007-11-20 21:41:22 +00:00
|
|
|
em_print_nvm_info(adapter);
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2006-02-15 08:39:50 +00:00
|
|
|
return (error);
|
2003-06-05 17:51:38 +00:00
|
|
|
}
|
|
|
|
|
2010-06-16 20:57:41 +00:00
|
|
|
static void
|
|
|
|
em_print_nvm_info(struct adapter *adapter)
|
2003-06-05 17:51:38 +00:00
|
|
|
{
|
2010-06-16 20:57:41 +00:00
|
|
|
u16 eeprom_data;
|
|
|
|
int i, j, row = 0;
|
2003-06-05 17:51:38 +00:00
|
|
|
|
2010-06-16 20:57:41 +00:00
|
|
|
/* Its a bit crude, but it gets the job done */
|
|
|
|
printf("\nInterface EEPROM Dump:\n");
|
|
|
|
printf("Offset\n0x0000 ");
|
|
|
|
for (i = 0, j = 0; i < 32; i++, j++) {
|
|
|
|
if (j == 8) { /* Make the offset block */
|
|
|
|
j = 0; ++row;
|
|
|
|
printf("\n0x00%x0 ",row);
|
|
|
|
}
|
|
|
|
e1000_read_nvm(&adapter->hw, i, 1, &eeprom_data);
|
|
|
|
printf("%04x ", eeprom_data);
|
2006-02-15 08:39:50 +00:00
|
|
|
}
|
2010-06-16 20:57:41 +00:00
|
|
|
printf("\n");
|
2003-06-05 17:51:38 +00:00
|
|
|
}
|
2003-08-01 17:33:59 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
em_sysctl_int_delay(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
|
|
|
struct em_int_delay_info *info;
|
2006-08-03 19:05:04 +00:00
|
|
|
struct adapter *adapter;
|
2008-02-29 21:50:11 +00:00
|
|
|
u32 regval;
|
Update to igb and em:
em revision 7.0.0:
- Using driver devclass, seperate legacy (pre-pcie) code
into a seperate source file. This will at least help
protect against regression issues. It compiles along
with em, and is transparent to end use, devices in each
appear to be 'emX'. When using em in a modular form this
also allows the legacy stuff to be defined out.
- Add tx and rx rings as in igb, in the 82574 this becomes
actual multiqueue for the first time (2 queues) while in
other PCIE adapters its just make code cleaner.
- Add RX mbuf handling logic that matches igb, this will
eliminate packet drops due to temporary mbuf shortage.
igb revision 1.9.3:
- Following the ixgbe code, use a new approach in what
was called 'get_buf', the routine now has been made
independent of rxeof, it now does the update to the
engine TDT register, this design allows temporary
mbuf resources to become non-critical, not requiring
a packet to be discarded, instead it just returns and
does not increment the tail pointer.
- With the above change it was also unnecessary to keep
'spare' maps around, since we do not have the discard
issue.
- Performance tweaks and improvements to the code also.
MFC in a week
2010-03-29 23:36:34 +00:00
|
|
|
int error, usecs, ticks;
|
2003-08-01 17:33:59 +00:00
|
|
|
|
|
|
|
info = (struct em_int_delay_info *)arg1;
|
|
|
|
usecs = info->value;
|
|
|
|
error = sysctl_handle_int(oidp, &usecs, 0, req);
|
|
|
|
if (error != 0 || req->newptr == NULL)
|
2006-02-15 08:39:50 +00:00
|
|
|
return (error);
|
2007-05-04 00:00:12 +00:00
|
|
|
if (usecs < 0 || usecs > EM_TICKS_TO_USECS(65535))
|
2006-02-15 08:39:50 +00:00
|
|
|
return (EINVAL);
|
2003-08-01 17:33:59 +00:00
|
|
|
info->value = usecs;
|
2007-05-04 00:00:12 +00:00
|
|
|
ticks = EM_USECS_TO_TICKS(usecs);
|
2013-05-09 17:07:30 +00:00
|
|
|
if (info->offset == E1000_ITR) /* units are 256ns here */
|
|
|
|
ticks *= 4;
|
2005-10-20 09:55:49 +00:00
|
|
|
|
2006-08-03 19:05:04 +00:00
|
|
|
adapter = info->adapter;
|
2003-08-01 17:33:59 +00:00
|
|
|
|
2006-08-03 19:05:04 +00:00
|
|
|
regval = E1000_READ_OFFSET(&adapter->hw, info->offset);
|
2003-08-01 17:33:59 +00:00
|
|
|
regval = (regval & ~0xffff) | (ticks & 0xffff);
|
|
|
|
/* Handle a few special cases. */
|
|
|
|
switch (info->offset) {
|
|
|
|
case E1000_RDTR:
|
|
|
|
break;
|
|
|
|
case E1000_TIDV:
|
|
|
|
if (ticks == 0) {
|
2006-08-03 19:05:04 +00:00
|
|
|
adapter->txd_cmd &= ~E1000_TXD_CMD_IDE;
|
2003-08-01 17:33:59 +00:00
|
|
|
/* Don't write 0 into the TIDV register. */
|
|
|
|
regval++;
|
|
|
|
} else
|
2008-02-29 21:50:11 +00:00
|
|
|
adapter->txd_cmd |= E1000_TXD_CMD_IDE;
|
2003-08-01 17:33:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-08-03 19:05:04 +00:00
|
|
|
E1000_WRITE_OFFSET(&adapter->hw, info->offset, regval);
|
2006-02-15 08:39:50 +00:00
|
|
|
return (0);
|
2003-08-01 17:33:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-08-03 19:05:04 +00:00
|
|
|
em_add_int_delay_sysctl(struct adapter *adapter, const char *name,
|
2006-02-15 08:39:50 +00:00
|
|
|
const char *description, struct em_int_delay_info *info,
|
|
|
|
int offset, int value)
|
2003-08-01 17:33:59 +00:00
|
|
|
{
|
2006-08-03 19:05:04 +00:00
|
|
|
info->adapter = adapter;
|
2003-08-01 17:33:59 +00:00
|
|
|
info->offset = offset;
|
|
|
|
info->value = value;
|
2006-08-03 19:05:04 +00:00
|
|
|
SYSCTL_ADD_PROC(device_get_sysctl_ctx(adapter->dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
|
2003-08-01 17:33:59 +00:00
|
|
|
OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW,
|
|
|
|
info, 0, em_sysctl_int_delay, "I", description);
|
|
|
|
}
|
2006-10-28 08:11:07 +00:00
|
|
|
|
|
|
|
static void
|
2011-03-18 18:54:00 +00:00
|
|
|
em_set_sysctl_value(struct adapter *adapter, const char *name,
|
2010-10-26 00:07:58 +00:00
|
|
|
const char *description, int *limit, int value)
|
|
|
|
{
|
|
|
|
*limit = value;
|
|
|
|
SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev),
|
|
|
|
SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)),
|
2014-10-21 07:31:21 +00:00
|
|
|
OID_AUTO, name, CTLFLAG_RW, limit, value, description);
|
2010-10-26 00:07:58 +00:00
|
|
|
}
|
|
|
|
|
2011-12-10 07:08:52 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Set flow control using sysctl:
|
|
|
|
** Flow control values:
|
|
|
|
** 0 - off
|
|
|
|
** 1 - rx pause
|
|
|
|
** 2 - tx pause
|
|
|
|
** 3 - full
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
em_set_flowcntl(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
static int input = 3; /* default is full */
|
|
|
|
struct adapter *adapter = (struct adapter *) arg1;
|
|
|
|
|
|
|
|
error = sysctl_handle_int(oidp, &input, 0, req);
|
|
|
|
|
|
|
|
if ((error) || (req->newptr == NULL))
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
if (input == adapter->fc) /* no change? */
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
switch (input) {
|
|
|
|
case e1000_fc_rx_pause:
|
|
|
|
case e1000_fc_tx_pause:
|
|
|
|
case e1000_fc_full:
|
|
|
|
case e1000_fc_none:
|
|
|
|
adapter->hw.fc.requested_mode = input;
|
|
|
|
adapter->fc = input;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Do nothing */
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
adapter->hw.fc.current_mode = adapter->hw.fc.requested_mode;
|
|
|
|
e1000_force_mac_fc(&adapter->hw);
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2012-07-07 20:21:05 +00:00
|
|
|
/*
|
|
|
|
** Manage Energy Efficient Ethernet:
|
|
|
|
** Control values:
|
|
|
|
** 0/1 - enabled/disabled
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
em_sysctl_eee(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
|
|
|
struct adapter *adapter = (struct adapter *) arg1;
|
|
|
|
int error, value;
|
|
|
|
|
|
|
|
value = adapter->hw.dev_spec.ich8lan.eee_disable;
|
|
|
|
error = sysctl_handle_int(oidp, &value, 0, req);
|
|
|
|
if (error || req->newptr == NULL)
|
|
|
|
return (error);
|
|
|
|
adapter->hw.dev_spec.ich8lan.eee_disable = (value != 0);
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_init(adapter->ctx);
|
|
|
|
|
2012-07-07 20:21:05 +00:00
|
|
|
return (0);
|
|
|
|
}
|
2011-12-10 07:08:52 +00:00
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
static int
|
|
|
|
em_sysctl_debug_info(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
|
|
|
struct adapter *adapter;
|
|
|
|
int error;
|
|
|
|
int result;
|
This delta has a few important items:
PR 122839 is fixed in both em and in igb
Second, the issue on building modules since the static kernel
build changes is now resolved. I was not able to get the fancier
directory hierarchy working, but this works, both em and igb
build as modules now.
Third, there is now support in em for two new NICs, Hartwell
(or 82574) is a low cost PCIE dual port adapter that has MSIX,
for this release it uses 3 vectors only, RX, TX, and LINK. In
the next release I will add a second TX and RX queue. Also, there
is support here for ICH10, the followon to ICH9. Both of these are
early releases, general availability will follow soon.
Fourth: On Hartwell and ICH10 we now have IEEE 1588 PTP support,
I have implemented this in a provisional way so that early adopters
may try and comment on the functionality. The IOCTL structure may
change. This feature is off by default, you need to edit the Makefile
and add the EM_TIMESYNC define to get the code.
Enjoy all!!
2008-04-25 21:19:41 +00:00
|
|
|
|
2010-10-26 00:07:58 +00:00
|
|
|
result = -1;
|
|
|
|
error = sysctl_handle_int(oidp, &result, 0, req);
|
|
|
|
|
|
|
|
if (error || !req->newptr)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
if (result == 1) {
|
|
|
|
adapter = (struct adapter *)arg1;
|
|
|
|
em_print_debug_info(adapter);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** This routine is meant to be fluid, add whatever is
|
|
|
|
** needed for debugging a problem. -jfv
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
em_print_debug_info(struct adapter *adapter)
|
|
|
|
{
|
|
|
|
device_t dev = adapter->dev;
|
2017-01-10 03:23:22 +00:00
|
|
|
struct tx_ring *txr = &adapter->tx_queues->txr;
|
|
|
|
struct rx_ring *rxr = &adapter->rx_queues->rxr;
|
2010-10-26 00:07:58 +00:00
|
|
|
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getdrvflags(adapter->ifp) & IFF_DRV_RUNNING)
|
2010-10-26 00:07:58 +00:00
|
|
|
printf("Interface is RUNNING ");
|
|
|
|
else
|
|
|
|
printf("Interface is NOT RUNNING\n");
|
2011-12-10 07:08:52 +00:00
|
|
|
|
2014-06-02 18:52:03 +00:00
|
|
|
if (if_getdrvflags(adapter->ifp) & IFF_DRV_OACTIVE)
|
2010-10-26 00:07:58 +00:00
|
|
|
printf("and INACTIVE\n");
|
2011-12-10 07:08:52 +00:00
|
|
|
else
|
|
|
|
printf("and ACTIVE\n");
|
2010-10-26 00:07:58 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
for (int i = 0; i < adapter->tx_num_queues; i++, txr++) {
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
device_printf(dev, "TX Queue %d ------\n", i);
|
|
|
|
device_printf(dev, "hw tdh = %d, hw tdt = %d\n",
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TDH(i)),
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_TDT(i)));
|
2017-01-10 03:23:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
for (int j=0; j < adapter->rx_num_queues; j++, rxr++) {
|
|
|
|
device_printf(dev, "RX Queue %d ------\n", j);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
device_printf(dev, "hw rdh = %d, hw rdt = %d\n",
|
2017-01-10 03:23:22 +00:00
|
|
|
E1000_READ_REG(&adapter->hw, E1000_RDH(j)),
|
|
|
|
E1000_READ_REG(&adapter->hw, E1000_RDT(j)));
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
}
|
2010-10-26 00:07:58 +00:00
|
|
|
}
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
2017-01-10 03:23:22 +00:00
|
|
|
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
/*
|
|
|
|
* 82574 only:
|
|
|
|
* Write a new value to the EEPROM increasing the number of MSIX
|
|
|
|
* vectors from 3 to 5, for proper multiqueue support.
|
|
|
|
*/
|
|
|
|
static void
|
2017-01-10 03:23:22 +00:00
|
|
|
em_enable_vectors_82574(if_ctx_t ctx)
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
{
|
2017-01-10 03:23:22 +00:00
|
|
|
struct adapter *adapter = iflib_get_softc(ctx);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
2017-01-10 03:23:22 +00:00
|
|
|
device_t dev = iflib_get_dev(ctx);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
u16 edata;
|
|
|
|
|
|
|
|
e1000_read_nvm(hw, EM_NVM_PCIE_CTRL, 1, &edata);
|
|
|
|
printf("Current cap: %#06x\n", edata);
|
|
|
|
if (((edata & EM_NVM_MSIX_N_MASK) >> EM_NVM_MSIX_N_SHIFT) != 4) {
|
|
|
|
device_printf(dev, "Writing to eeprom: increasing "
|
|
|
|
"reported MSIX vectors from 3 to 5...\n");
|
|
|
|
edata &= ~(EM_NVM_MSIX_N_MASK);
|
|
|
|
edata |= 4 << EM_NVM_MSIX_N_SHIFT;
|
|
|
|
e1000_write_nvm(hw, EM_NVM_PCIE_CTRL, 1, &edata);
|
|
|
|
e1000_update_nvm_checksum(hw);
|
|
|
|
device_printf(dev, "Writing to eeprom: done\n");
|
|
|
|
}
|
|
|
|
}
|
2017-01-10 03:23:22 +00:00
|
|
|
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
|
|
|
|
#ifdef DDB
|
|
|
|
DB_COMMAND(em_reset_dev, em_ddb_reset_dev)
|
|
|
|
{
|
|
|
|
devclass_t dc;
|
|
|
|
int max_em;
|
|
|
|
|
|
|
|
dc = devclass_find("em");
|
|
|
|
max_em = devclass_get_maxunit(dc);
|
|
|
|
|
|
|
|
for (int index = 0; index < (max_em - 1); index++) {
|
|
|
|
device_t dev;
|
|
|
|
dev = devclass_get_device(dc, index);
|
|
|
|
if (device_get_driver(dev) == &em_driver) {
|
|
|
|
struct adapter *adapter = device_get_softc(dev);
|
2017-01-10 03:23:22 +00:00
|
|
|
em_if_init(adapter->ctx);
|
Change EM_MULTIQUEUE to a real kernconf entry and enable support for
up to 2 rx/tx queues for the 82574.
Program the 82574 to enable 5 msix vectors, assign 1 to each rx queue,
1 to each tx queue and 1 to the link handler.
Inspired by DragonFlyBSD, enable some RSS logic for handling tx queue
handling/processing.
Move multiqueue handler functions so that they line up better in a diff
review to if_igb.c
Always enqueue tx work to be done in em_mq_start, if unable to acquire
the TX lock, then this will be processed in the background later by the
taskqueue. Remove mbuf argument from em_start_mq_locked() as the work
is always enqueued. (stolen from igb)
Setup TARC, TXDCTL and RXDCTL registers for better performance and stability
in multiqueue and singlequeue implementations. Handle Intel errata 3 and
generic multiqueue behavior with the initialization of TARC(0) and TARC(1)
Bind interrupt threads to cpus in order. (stolen from igb)
Add 2 new DDB functions, one to display the queue(s) and their settings and
one to reset the adapter. Primarily used for debugging.
In the multiqueue configuration, bump RXD and TXD ring size to max for the
adapter (4096). Setup an RDTR of 64 and an RADV of 128 in multiqueue configuration
to cut down on the number of interrupts. RADV was arbitrarily set to 2x RDTR
and can be adjusted as needed.
Cleanup the display in top a bit to make it clearer where the taskqueue threads
are running and what they should be doing.
Ensure that both queues are processed by em_local_timer() by writing them both
to the IMS register to generate soft interrupts.
Ensure that an soft interrupt is generated when em_msix_link() is run so that
any races between assertion of the link/status interrupt and a rx/tx interrupt
are handled.
Document existing tuneables: hw.em.eee_setting, hw.em.msix, hw.em.smart_pwr_down, hw.em.sbp
Document use of hw.em.num_queues and the new kernel option EM_MULTIQUEUE
Thanks to Intel for their continued support of FreeBSD.
Reviewed by: erj jfv hiren gnn wblock
Obtained from: Intel Corporation
MFC after: 2 weeks
Relnotes: Yes
Sponsored by: Limelight Networks
Differential Revision: https://reviews.freebsd.org/D1994
2015-06-03 18:01:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DB_COMMAND(em_dump_queue, em_ddb_dump_queue)
|
|
|
|
{
|
|
|
|
devclass_t dc;
|
|
|
|
int max_em;
|
|
|
|
|
|
|
|
dc = devclass_find("em");
|
|
|
|
max_em = devclass_get_maxunit(dc);
|
|
|
|
|
|
|
|
for (int index = 0; index < (max_em - 1); index++) {
|
|
|
|
device_t dev;
|
|
|
|
dev = devclass_get_device(dc, index);
|
|
|
|
if (device_get_driver(dev) == &em_driver)
|
|
|
|
em_print_debug_info(device_get_softc(dev));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|