From owner-svn-src-stable@freebsd.org Thu Feb 11 16:16:12 2016 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5CD8EAA5978; Thu, 11 Feb 2016 16:16:12 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 2526E1A9; Thu, 11 Feb 2016 16:16:12 +0000 (UTC) (envelope-from sbruno@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u1BGGB9e026010; Thu, 11 Feb 2016 16:16:11 GMT (envelope-from sbruno@FreeBSD.org) Received: (from sbruno@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u1BGGBXI026007; Thu, 11 Feb 2016 16:16:11 GMT (envelope-from sbruno@FreeBSD.org) Message-Id: <201602111616.u1BGGBXI026007@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sbruno set sender to sbruno@FreeBSD.org using -f From: Sean Bruno Date: Thu, 11 Feb 2016 16:16:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r295524 - in stable/10/sys: conf dev/ixgbe modules/ix modules/ixv X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Feb 2016 16:16:12 -0000 Author: sbruno Date: Thu Feb 11 16:16:10 2016 New Revision: 295524 URL: https://svnweb.freebsd.org/changeset/base/295524 Log: MFC r292674 Update ixgbe(4) to Intel FreeBSD Networking Group version 3.1.13-k. MFC r292571 and r292697 Add support for X552 and X550T. MFC r293334 Fix SFP module insertion post boot. MFC r293338 Fix VF handling of VLANs for Amazon Cloud. Reviewed by: erj smh ngie jeffrey.e.pieper@intel.com Approved by: re (marius) Relnotes: Yes Sponsored by: Intel Corporation and Limelight Networks Differential Revision: https://reviews.freebsd.org/D5117 Added: stable/10/sys/dev/ixgbe/ixgbe_osdep.c (contents, props changed) Deleted: stable/10/sys/dev/ixgbe/LICENSE Modified: stable/10/sys/conf/files stable/10/sys/dev/ixgbe/if_ix.c stable/10/sys/dev/ixgbe/if_ixv.c stable/10/sys/dev/ixgbe/ix_txrx.c stable/10/sys/dev/ixgbe/ixgbe.h stable/10/sys/dev/ixgbe/ixgbe_82598.c stable/10/sys/dev/ixgbe/ixgbe_82599.c stable/10/sys/dev/ixgbe/ixgbe_api.c stable/10/sys/dev/ixgbe/ixgbe_api.h stable/10/sys/dev/ixgbe/ixgbe_common.c stable/10/sys/dev/ixgbe/ixgbe_dcb.c stable/10/sys/dev/ixgbe/ixgbe_osdep.h stable/10/sys/dev/ixgbe/ixgbe_phy.c stable/10/sys/dev/ixgbe/ixgbe_phy.h stable/10/sys/dev/ixgbe/ixgbe_type.h stable/10/sys/dev/ixgbe/ixgbe_vf.c stable/10/sys/dev/ixgbe/ixgbe_x540.c stable/10/sys/dev/ixgbe/ixgbe_x550.c stable/10/sys/dev/ixgbe/ixgbe_x550.h stable/10/sys/modules/ix/Makefile stable/10/sys/modules/ixv/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/conf/files ============================================================================== --- stable/10/sys/conf/files Thu Feb 11 15:27:14 2016 (r295523) +++ stable/10/sys/conf/files Thu Feb 11 16:16:10 2016 (r295524) @@ -1728,6 +1728,8 @@ dev/ixgbe/ix_txrx.c optional ix inet | compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_phy.c optional ix inet | ixv inet | ixgbe inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" +dev/ixgbe/ixgbe_osdep.c optional ix inet | ixv inet | ixgbe inet \ + compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_api.c optional ix inet | ixv inet | ixgbe inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_common.c optional ix inet | ixv inet | ixgbe inet \ Modified: stable/10/sys/dev/ixgbe/if_ix.c ============================================================================== --- stable/10/sys/dev/ixgbe/if_ix.c Thu Feb 11 15:27:14 2016 (r295523) +++ stable/10/sys/dev/ixgbe/if_ix.c Thu Feb 11 16:16:10 2016 (r295524) @@ -46,14 +46,10 @@ #endif /********************************************************************* - * Set this to one to display debug statistics - *********************************************************************/ -int ixgbe_display_debug_stats = 0; - -/********************************************************************* * Driver version *********************************************************************/ -char ixgbe_driver_version[] = "3.1.0"; +char ixgbe_driver_version[] = "3.1.13-k"; + /********************************************************************* * PCI Device ID Table @@ -94,9 +90,11 @@ static ixgbe_vendor_info_t ixgbe_vendor_ {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X540T1, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550T, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550T1, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KR, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_KX4, 0, 0, 0}, {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_10G_T, 0, 0, 0}, + {IXGBE_INTEL_VENDOR_ID, IXGBE_DEV_ID_X550EM_X_SFP, 0, 0, 0}, /* required last entry */ {0, 0, 0, 0, 0} }; @@ -130,7 +128,7 @@ static void ixgbe_media_status(struc static int ixgbe_media_change(struct ifnet *); static void ixgbe_identify_hardware(struct adapter *); static int ixgbe_allocate_pci_resources(struct adapter *); -static void ixgbe_get_slot_info(struct ixgbe_hw *); +static void ixgbe_get_slot_info(struct adapter *); static int ixgbe_allocate_msix(struct adapter *); static int ixgbe_allocate_legacy(struct adapter *); static int ixgbe_setup_msix(struct adapter *); @@ -141,7 +139,6 @@ static void ixgbe_config_gpie(struct ada static void ixgbe_config_dmac(struct adapter *); static void ixgbe_config_delay_values(struct adapter *); static void ixgbe_config_link(struct adapter *); -static void ixgbe_check_eee_support(struct adapter *); static void ixgbe_check_wol_support(struct adapter *); static int ixgbe_setup_low_power_mode(struct adapter *); static void ixgbe_rearm_queues(struct adapter *, u64); @@ -150,6 +147,7 @@ static void ixgbe_initialize_transmi static void ixgbe_initialize_receive_units(struct adapter *); static void ixgbe_enable_rx_drop(struct adapter *); static void ixgbe_disable_rx_drop(struct adapter *); +static void ixgbe_initialize_rss_mapping(struct adapter *); static void ixgbe_enable_intr(struct adapter *); static void ixgbe_disable_intr(struct adapter *); @@ -170,19 +168,24 @@ static void ixgbe_add_hw_stats(struc /* Sysctl handlers */ static void ixgbe_set_sysctl_value(struct adapter *, const char *, - const char *, int *, int); + const char *, int *, int); static int ixgbe_set_flowcntl(SYSCTL_HANDLER_ARGS); static int ixgbe_set_advertise(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_thermal_test(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_dmac(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_phy_temp(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_phy_overtemp_occurred(SYSCTL_HANDLER_ARGS); +#ifdef IXGBE_DEBUG +static int ixgbe_sysctl_power_state(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_print_rss_config(SYSCTL_HANDLER_ARGS); +#endif static int ixgbe_sysctl_wol_enable(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_wufc(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_eee_enable(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_eee_negotiated(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_eee_rx_lpi_status(SYSCTL_HANDLER_ARGS); static int ixgbe_sysctl_eee_tx_lpi_status(SYSCTL_HANDLER_ARGS); +static int ixgbe_sysctl_eee_tx_lpi_delay(SYSCTL_HANDLER_ARGS); /* Support for pluggable optic modules */ static bool ixgbe_sfp_probe(struct adapter *); @@ -446,9 +449,13 @@ ixgbe_attach(device_t dev) /* Allocate, clear, and link in our adapter structure */ adapter = device_get_softc(dev); - adapter->dev = adapter->osdep.dev = dev; + adapter->dev = dev; hw = &adapter->hw; +#ifdef DEV_NETMAP + adapter->init_locked = ixgbe_init_locked; + adapter->stop_locked = ixgbe_stop; +#endif /* Core Lock Init*/ IXGBE_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); @@ -531,18 +538,18 @@ ixgbe_attach(device_t dev) adapter->sfp_probe = TRUE; error = 0; } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev,"Unsupported SFP+ module detected!\n"); + device_printf(dev, "Unsupported SFP+ module detected!\n"); error = EIO; goto err_late; } else if (error) { - device_printf(dev,"Unable to initialize the shared code\n"); + device_printf(dev, "Unable to initialize the shared code\n"); error = EIO; goto err_late; } /* Make sure we have a good EEPROM before we read from it */ if (ixgbe_validate_eeprom_checksum(&adapter->hw, &csum) < 0) { - device_printf(dev,"The EEPROM Checksum Is Not Valid\n"); + device_printf(dev, "The EEPROM Checksum Is Not Valid\n"); error = EIO; goto err_late; } @@ -552,24 +559,21 @@ ixgbe_attach(device_t dev) case IXGBE_ERR_EEPROM_VERSION: device_printf(dev, "This device is a pre-production adapter/" "LOM. Please be aware there may be issues associated " - "with your hardware.\n If you are experiencing problems " + "with your hardware.\nIf you are experiencing problems " "please contact your Intel or hardware representative " "who provided you with this hardware.\n"); break; case IXGBE_ERR_SFP_NOT_SUPPORTED: - device_printf(dev,"Unsupported SFP+ Module\n"); + device_printf(dev, "Unsupported SFP+ Module\n"); error = EIO; goto err_late; case IXGBE_ERR_SFP_NOT_PRESENT: - device_printf(dev,"No SFP+ Module found\n"); + device_printf(dev, "No SFP+ Module found\n"); /* falls thru */ default: break; } - /* Detect and set physical type */ - ixgbe_setup_optics(adapter); - if ((adapter->msix > 1) && (ixgbe_enable_msix)) error = ixgbe_allocate_msix(adapter); else @@ -591,11 +595,12 @@ ixgbe_attach(device_t dev) ixgbe_unregister_vlan, adapter, EVENTHANDLER_PRI_FIRST); /* Check PCIE slot type/speed/width */ - ixgbe_get_slot_info(hw); - + ixgbe_get_slot_info(adapter); - /* Set an initial default flow control value */ + /* Set an initial default flow control & dmac value */ adapter->fc = ixgbe_fc_full; + adapter->dmac = 0; + adapter->eee_enabled = 0; #ifdef PCI_IOV if ((hw->mac.type != ixgbe_mac_82598EB) && (adapter->msix > 1)) { @@ -621,7 +626,6 @@ ixgbe_attach(device_t dev) /* Check for certain supported features */ ixgbe_check_wol_support(adapter); - ixgbe_check_eee_support(adapter); /* Add sysctls */ ixgbe_add_device_sysctls(adapter); @@ -682,6 +686,7 @@ ixgbe_detach(device_t dev) } #endif /* PCI_IOV */ + ether_ifdetach(adapter->ifp); /* Stop the adapter */ IXGBE_CORE_LOCK(adapter); ixgbe_setup_low_power_mode(adapter); @@ -723,7 +728,6 @@ ixgbe_detach(device_t dev) if (adapter->vlan_detach != NULL) EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach); - ether_ifdetach(adapter->ifp); callout_drain(&adapter->timer); #ifdef DEV_NETMAP netmap_detach(adapter->ifp); @@ -778,10 +782,6 @@ ixgbe_suspend(device_t dev) error = ixgbe_setup_low_power_mode(adapter); - /* Save state and power down */ - pci_save_state(dev); - pci_set_powerstate(dev, PCI_POWERSTATE_D3); - IXGBE_CORE_UNLOCK(adapter); return (error); @@ -799,9 +799,6 @@ ixgbe_resume(device_t dev) IXGBE_CORE_LOCK(adapter); - pci_set_powerstate(dev, PCI_POWERSTATE_D0); - pci_restore_state(dev); - /* Read & clear WUS register */ wus = IXGBE_READ_REG(hw, IXGBE_WUS); if (wus) @@ -820,7 +817,6 @@ ixgbe_resume(device_t dev) IXGBE_CORE_UNLOCK(adapter); - INIT_DEBUGOUT("ixgbe_resume: end"); return (0); } @@ -864,7 +860,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c ifp->if_flags |= IFF_UP; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) ixgbe_init(adapter); -#if defined(INET) +#ifdef INET if (!(ifp->if_flags & IFF_NOARP)) arp_ifinit(ifp, ifa); #endif @@ -922,10 +918,21 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c break; case SIOCSIFCAP: { - int mask = ifr->ifr_reqcap ^ ifp->if_capenable; IOCTL_DEBUGOUT("ioctl: SIOCSIFCAP (Set Capabilities)"); - if (mask & IFCAP_HWCSUM) - ifp->if_capenable ^= IFCAP_HWCSUM; + + int mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if (!mask) + break; + + /* HW cannot turn these on/off separately */ + if (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) { + ifp->if_capenable ^= IFCAP_RXCSUM; + ifp->if_capenable ^= IFCAP_RXCSUM_IPV6; + } + if (mask & IFCAP_TXCSUM) + ifp->if_capenable ^= IFCAP_TXCSUM; + if (mask & IFCAP_TXCSUM_IPV6) + ifp->if_capenable ^= IFCAP_TXCSUM_IPV6; if (mask & IFCAP_TSO4) ifp->if_capenable ^= IFCAP_TSO4; if (mask & IFCAP_TSO6) @@ -938,6 +945,7 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c ifp->if_capenable ^= IFCAP_VLAN_HWFILTER; if (mask & IFCAP_VLAN_HWTSO) ifp->if_capenable ^= IFCAP_VLAN_HWTSO; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { IXGBE_CORE_LOCK(adapter); ixgbe_init_locked(adapter); @@ -981,6 +989,42 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c return (error); } +/* + * Set the various hardware offload abilities. + * + * This takes the ifnet's if_capenable flags (e.g. set by the user using + * ifconfig) and indicates to the OS via the ifnet's if_hwassist field what + * mbuf offload flags the driver will understand. + */ +static void +ixgbe_set_if_hwassist(struct adapter *adapter) +{ + struct ifnet *ifp = adapter->ifp; + + ifp->if_hwassist = 0; +#if __FreeBSD_version >= 1000000 + if (ifp->if_capenable & IFCAP_TSO4) + ifp->if_hwassist |= CSUM_IP_TSO; + if (ifp->if_capenable & IFCAP_TSO6) + ifp->if_hwassist |= CSUM_IP6_TSO; + if (ifp->if_capenable & IFCAP_TXCSUM) + ifp->if_hwassist |= (CSUM_IP | CSUM_IP_UDP | CSUM_IP_TCP | + CSUM_IP_SCTP); + if (ifp->if_capenable & IFCAP_TXCSUM_IPV6) + ifp->if_hwassist |= (CSUM_IP6_UDP | CSUM_IP6_TCP | + CSUM_IP6_SCTP); +#else + if (ifp->if_capenable & IFCAP_TSO) + ifp->if_hwassist |= CSUM_TSO; + if (ifp->if_capenable & IFCAP_TXCSUM) { + ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); + struct ixgbe_hw *hw = &adapter->hw; + if (hw->mac.type != ixgbe_mac_82598EB) + ifp->if_hwassist |= CSUM_SCTP; + } +#endif +} + /********************************************************************* * Init entry point * @@ -1003,6 +1047,7 @@ ixgbe_init_locked(struct adapter *adapte struct rx_ring *rxr; u32 txdctl, mhadd; u32 rxdctl, rxctrl; + int err = 0; #ifdef PCI_IOV enum ixgbe_iov_mode mode; #endif @@ -1031,17 +1076,8 @@ ixgbe_init_locked(struct adapter *adapte ixgbe_set_rar(hw, 0, hw->mac.addr, adapter->pool, 1); hw->addr_ctrl.rar_used_count = 1; - /* Set the various hardware offload abilities */ - ifp->if_hwassist = 0; - if (ifp->if_capenable & IFCAP_TSO) - ifp->if_hwassist |= CSUM_TSO; - if (ifp->if_capenable & IFCAP_TXCSUM) { - ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); -#if __FreeBSD_version >= 800000 - if (hw->mac.type != ixgbe_mac_82598EB) - ifp->if_hwassist |= CSUM_SCTP; -#endif - } + /* Set hardware offload abilities from ifnet flags */ + ixgbe_set_if_hwassist(adapter); /* Prepare transmit descriptors and buffers */ if (ixgbe_setup_transmit_structures(adapter)) { @@ -1059,10 +1095,7 @@ ixgbe_init_locked(struct adapter *adapte /* Setup Multicast table */ ixgbe_set_multi(adapter); - /* - ** Determine the correct mbuf pool - ** for doing jumbo frames - */ + /* Determine the correct mbuf pool, based on frame size */ if (adapter->max_frame_size <= MCLBYTES) adapter->rx_mbuf_sz = MCLBYTES; else @@ -1198,7 +1231,7 @@ ixgbe_init_locked(struct adapter *adapte * need to be kick-started */ if (hw->phy.type == ixgbe_phy_none) { - int err = hw->phy.ops.identify(hw); + err = hw->phy.ops.identify(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { device_printf(dev, "Unsupported SFP+ module type was detected.\n"); @@ -1210,7 +1243,11 @@ ixgbe_init_locked(struct adapter *adapte IXGBE_WRITE_REG(hw, IXGBE_EITR(adapter->vector), IXGBE_LINK_ITR); /* Configure Energy Efficient Ethernet for supported devices */ - ixgbe_setup_eee(hw, adapter->eee_enabled); + if (hw->mac.ops.setup_eee) { + err = hw->mac.ops.setup_eee(hw, adapter->eee_enabled); + if (err) + device_printf(dev, "Error setting up EEE: %d\n", err); + } /* Config/Enable Link */ ixgbe_config_link(adapter); @@ -1280,7 +1317,7 @@ ixgbe_config_gpie(struct adapter *adapte /* * Thermal Failure Detection (X540) - * Link Detection (X557) + * Link Detection (X552 SFP+, X552/X557-AT) */ if (hw->mac.type == ixgbe_mac_X540 || hw->device_id == IXGBE_DEV_ID_X550EM_X_SFP || @@ -1588,6 +1625,9 @@ ixgbe_msix_link(void *arg) ++adapter->link_irq; + /* Pause other interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_OTHER); + /* First get the cause */ reg_eicr = IXGBE_READ_REG(hw, IXGBE_EICS); /* Be sure the queue bits are not cleared */ @@ -1596,8 +1636,10 @@ ixgbe_msix_link(void *arg) IXGBE_WRITE_REG(hw, IXGBE_EICR, reg_eicr); /* Link status change */ - if (reg_eicr & IXGBE_EICR_LSC) + if (reg_eicr & IXGBE_EICR_LSC) { + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); taskqueue_enqueue(adapter->tq, &adapter->link_task); + } if (adapter->hw.mac.type != ixgbe_mac_82598EB) { #ifdef IXGBE_FDIR @@ -1611,14 +1653,14 @@ ixgbe_msix_link(void *arg) } else #endif if (reg_eicr & IXGBE_EICR_ECC) { - device_printf(adapter->dev, "\nCRITICAL: ECC ERROR!! " + device_printf(adapter->dev, "CRITICAL: ECC ERROR!! " "Please Reboot!!\n"); IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_ECC); } /* Check for over temp condition */ if (reg_eicr & IXGBE_EICR_TS) { - device_printf(adapter->dev, "\nCRITICAL: OVER TEMP!! " + device_printf(adapter->dev, "CRITICAL: OVER TEMP!! " "PHY IS SHUT DOWN!!\n"); device_printf(adapter->dev, "System shutdown required!\n"); IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS); @@ -1660,6 +1702,7 @@ ixgbe_msix_link(void *arg) taskqueue_enqueue(adapter->tq, &adapter->phy_task); } + /* Re-enable other interrupts */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); return; } @@ -1753,6 +1796,7 @@ ixgbe_media_status(struct ifnet * ifp, s ** XXX: These need to use the proper media types once ** they're added. */ +#ifndef IFM_ETH_XTYPE if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) switch (adapter->link_speed) { case IXGBE_LINK_SPEED_10GB_FULL: @@ -1778,6 +1822,33 @@ ixgbe_media_status(struct ifnet * ifp, s ifmr->ifm_active |= IFM_1000_CX | IFM_FDX; break; } +#else + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + ifmr->ifm_active |= IFM_10G_KR | IFM_FDX; + break; + case IXGBE_LINK_SPEED_2_5GB_FULL: + ifmr->ifm_active |= IFM_2500_KX | IFM_FDX; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + ifmr->ifm_active |= IFM_1000_KX | IFM_FDX; + break; + } + else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4 + || layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) + switch (adapter->link_speed) { + case IXGBE_LINK_SPEED_10GB_FULL: + ifmr->ifm_active |= IFM_10G_KX4 | IFM_FDX; + break; + case IXGBE_LINK_SPEED_2_5GB_FULL: + ifmr->ifm_active |= IFM_2500_KX | IFM_FDX; + break; + case IXGBE_LINK_SPEED_1GB_FULL: + ifmr->ifm_active |= IFM_1000_KX | IFM_FDX; + break; + } +#endif /* If nothing is recognized... */ if (IFM_SUBTYPE(ifmr->ifm_active) == 0) @@ -1820,13 +1891,14 @@ ixgbe_media_change(struct ifnet * ifp) return (EINVAL); if (hw->phy.media_type == ixgbe_media_type_backplane) - return (EPERM); + return (ENODEV); /* ** We don't actually need to check against the supported ** media types of the adapter; ifmedia will take care of ** that for us. */ +#ifndef IFM_ETH_XTYPE switch (IFM_SUBTYPE(ifm->ifm_media)) { case IFM_AUTO: case IFM_10G_T: @@ -1852,6 +1924,33 @@ ixgbe_media_change(struct ifnet * ifp) default: goto invalid; } +#else + switch (IFM_SUBTYPE(ifm->ifm_media)) { + case IFM_AUTO: + case IFM_10G_T: + speed |= IXGBE_LINK_SPEED_100_FULL; + case IFM_10G_LRM: + case IFM_10G_KR: + case IFM_10G_LR: + case IFM_10G_KX4: + speed |= IXGBE_LINK_SPEED_1GB_FULL; + case IFM_10G_TWINAX: + speed |= IXGBE_LINK_SPEED_10GB_FULL; + break; + case IFM_1000_T: + speed |= IXGBE_LINK_SPEED_100_FULL; + case IFM_1000_LX: + case IFM_1000_SX: + case IFM_1000_KX: + speed |= IXGBE_LINK_SPEED_1GB_FULL; + break; + case IFM_100_TX: + speed |= IXGBE_LINK_SPEED_100_FULL; + break; + default: + goto invalid; + } +#endif hw->mac.autotry_restart = TRUE; hw->mac.ops.setup_link(hw, speed, TRUE); @@ -2392,7 +2491,7 @@ ixgbe_allocate_msix(struct adapter *adap return (error); } #if __FreeBSD_version >= 800504 - bus_describe_intr(dev, que->res, que->tag, "que %d", i); + bus_describe_intr(dev, que->res, que->tag, "q%d", i); #endif que->msix = vector; adapter->active_queues |= (u64)(1 << que->msix); @@ -2443,8 +2542,8 @@ ixgbe_allocate_msix(struct adapter *adap device_get_nameunit(adapter->dev), cpu_id); #else - taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", - device_get_nameunit(adapter->dev)); + taskqueue_start_threads(&que->tq, 1, PI_NET, "%s:q%d", + device_get_nameunit(adapter->dev), i); #endif } @@ -2522,7 +2621,7 @@ ixgbe_setup_msix(struct adapter *adapter } /* Figure out a reasonable auto config value */ - queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus; + queues = (mp_ncpus > (msgs - 1)) ? (msgs - 1) : mp_ncpus; #ifdef RSS /* If we're doing RSS, clamp at the number of RSS buckets */ @@ -2532,6 +2631,9 @@ ixgbe_setup_msix(struct adapter *adapter if (ixgbe_num_queues != 0) queues = ixgbe_num_queues; + /* Set max queues to 8 when autoconfiguring */ + else if ((ixgbe_num_queues == 0) && (queues > 8)) + queues = 8; /* reflect correct sysctl value */ ixgbe_num_queues = queues; @@ -2568,12 +2670,12 @@ msi: rid, adapter->msix_mem); adapter->msix_mem = NULL; } - msgs = 1; - if (pci_alloc_msi(dev, &msgs) == 0) { - device_printf(adapter->dev,"Using an MSI interrupt\n"); + msgs = 1; + if (pci_alloc_msi(dev, &msgs) == 0) { + device_printf(adapter->dev, "Using an MSI interrupt\n"); return (msgs); } - device_printf(adapter->dev,"Using a Legacy interrupt\n"); + device_printf(adapter->dev, "Using a Legacy interrupt\n"); return (0); } @@ -2589,22 +2691,24 @@ ixgbe_allocate_pci_resources(struct adap &rid, RF_ACTIVE); if (!(adapter->pci_mem)) { - device_printf(dev,"Unable to allocate bus resource: memory\n"); + device_printf(dev, "Unable to allocate bus resource: memory\n"); return (ENXIO); } + /* Save bus_space values for READ/WRITE_REG macros */ adapter->osdep.mem_bus_space_tag = rman_get_bustag(adapter->pci_mem); adapter->osdep.mem_bus_space_handle = rman_get_bushandle(adapter->pci_mem); + /* Set hw values for shared code */ adapter->hw.hw_addr = (u8 *) &adapter->osdep.mem_bus_space_handle; + adapter->hw.back = adapter; - /* Legacy defaults */ + /* Default to 1 queue if MSI-X setup fails */ adapter->num_queues = 1; - adapter->hw.back = &adapter->osdep; /* - ** Now setup MSI or MSI/X, should + ** Now setup MSI or MSI-X, should ** return us the number of supported ** vectors. (Will be 1 for MSI) */ @@ -2729,13 +2833,22 @@ ixgbe_setup_interface(device_t dev, stru */ ifp->if_hdrlen = sizeof(struct ether_vlan_header); - ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_TSO | IFCAP_VLAN_HWCSUM; - ifp->if_capabilities |= IFCAP_JUMBO_MTU; - ifp->if_capabilities |= IFCAP_LRO; - ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING + /* Set capability flags */ + ifp->if_capabilities |= IFCAP_RXCSUM + | IFCAP_TXCSUM + | IFCAP_RXCSUM_IPV6 + | IFCAP_TXCSUM_IPV6 + | IFCAP_TSO4 + | IFCAP_TSO6 + | IFCAP_LRO + | IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_HWTSO + | IFCAP_VLAN_HWCSUM + | IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU | IFCAP_HWSTATS; + + /* Enable the above capabilities by default */ ifp->if_capenable = ifp->if_capabilities; /* @@ -2755,9 +2868,10 @@ ixgbe_setup_interface(device_t dev, stru ifmedia_init(&adapter->media, IFM_IMASK, ixgbe_media_change, ixgbe_media_status); + adapter->phy_layer = ixgbe_get_supported_physical_layer(&adapter->hw); ixgbe_add_media_types(adapter); - /* Autoselect media by default */ + /* Set autoselect media by default */ ifmedia_set(&adapter->media, IFM_ETHER | IFM_AUTO); return (0); @@ -2770,7 +2884,7 @@ ixgbe_add_media_types(struct adapter *ad device_t dev = adapter->dev; int layer; - layer = adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); + layer = adapter->phy_layer; /* Media types with matching FreeBSD media defines */ if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_T) @@ -2784,20 +2898,28 @@ ixgbe_add_media_types(struct adapter *ad layer & IXGBE_PHYSICAL_LAYER_SFP_ACTIVE_DA) ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_TWINAX, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR) + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_LR) { ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_LR, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) + if (hw->phy.multispeed_fiber) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_LX, 0, NULL); + } + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_SR) { ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_SR, 0, NULL); + if (hw->phy.multispeed_fiber) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL); + } else if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL); if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_CX4) ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_CX4, 0, NULL); - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_SX) - ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_SX, 0, NULL); - /* - ** Other (no matching FreeBSD media type): - ** To workaround this, we'll assign these completely - ** inappropriate media types. - */ +#ifdef IFM_ETH_XTYPE + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_KR, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KX4) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_10G_KX4, 0, NULL); + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_KX) + ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_KX, 0, NULL); +#else if (layer & IXGBE_PHYSICAL_LAYER_10GBASE_KR) { device_printf(dev, "Media supported: 10GbaseKR\n"); device_printf(dev, "10GbaseKR mapped to 10GbaseSR\n"); @@ -2813,10 +2935,9 @@ ixgbe_add_media_types(struct adapter *ad device_printf(dev, "1000baseKX mapped to 1000baseCX\n"); ifmedia_add(&adapter->media, IFM_ETHER | IFM_1000_CX, 0, NULL); } - if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_BX) { - /* Someday, someone will care about you... */ +#endif + if (layer & IXGBE_PHYSICAL_LAYER_1000BASE_BX) device_printf(dev, "Media supported: 1000baseBX\n"); - } if (hw->device_id == IXGBE_DEV_ID_82598AT) { ifmedia_add(&adapter->media, @@ -2838,12 +2959,7 @@ ixgbe_config_link(struct adapter *adapte sfp = ixgbe_is_sfp(hw); if (sfp) { - if (hw->phy.multispeed_fiber) { - hw->mac.ops.setup_sfp(hw); - ixgbe_enable_tx_laser(hw); - taskqueue_enqueue(adapter->tq, &adapter->msf_task); - } else - taskqueue_enqueue(adapter->tq, &adapter->mod_task); + taskqueue_enqueue(adapter->tq, &adapter->mod_task); } else { if (hw->mac.ops.check_link) err = ixgbe_check_link(hw, &adapter->link_speed, @@ -2877,7 +2993,6 @@ ixgbe_initialize_transmit_units(struct a struct ixgbe_hw *hw = &adapter->hw; /* Setup the Base and Length of the Tx Descriptor Ring */ - for (int i = 0; i < adapter->num_queues; i++, txr++) { u64 tdba = txr->txdma.dma_paddr; u32 txctrl = 0; @@ -2897,12 +3012,15 @@ ixgbe_initialize_transmit_units(struct a txr->tail = IXGBE_TDT(j); /* Disable Head Writeback */ + /* + * Note: for X550 series devices, these registers are actually + * prefixed with TPH_ isntead of DCA_, but the addresses and + * fields remain the same. + */ switch (hw->mac.type) { case ixgbe_mac_82598EB: txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j)); break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: default: txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j)); break; @@ -2912,8 +3030,6 @@ ixgbe_initialize_transmit_units(struct a case ixgbe_mac_82598EB: IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl); break; - case ixgbe_mac_82599EB: - case ixgbe_mac_X540: default: IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl); break; @@ -2946,7 +3062,7 @@ ixgbe_initialize_transmit_units(struct a } static void -ixgbe_initialise_rss_mapping(struct adapter *adapter) +ixgbe_initialize_rss_mapping(struct adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 reta = 0, mrqc, rss_key[10]; @@ -3081,7 +3197,6 @@ ixgbe_initialize_receive_units(struct ad u32 bufsz, fctrl, srrctl, rxcsum; u32 hlreg; - /* * Make sure receives are disabled while * setting up the descriptor ring @@ -3146,11 +3261,11 @@ ixgbe_initialize_receive_units(struct ad srrctl &= ~IXGBE_SRRCTL_DROP_EN; } - IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl); + IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(j), srrctl); /* Setup the HW Rx Head and Tail Descriptor Pointers */ - IXGBE_WRITE_REG(hw, IXGBE_RDH(i), 0); - IXGBE_WRITE_REG(hw, IXGBE_RDT(i), 0); + IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0); + IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0); /* Set the driver rx tail address */ rxr->tail = IXGBE_RDT(rxr->me); @@ -3166,7 +3281,7 @@ ixgbe_initialize_receive_units(struct ad rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); - ixgbe_initialise_rss_mapping(adapter); + ixgbe_initialize_rss_mapping(adapter); if (adapter->num_queues > 1) { /* RSS and RX IPP Checksum are mutually exclusive */ @@ -3176,6 +3291,7 @@ ixgbe_initialize_receive_units(struct ad if (ifp->if_capenable & IFCAP_RXCSUM) rxcsum |= IXGBE_RXCSUM_PCSD; + /* This is useful for calculating UDP/IP fragment checksums */ if (!(rxcsum & IXGBE_RXCSUM_PCSD)) rxcsum |= IXGBE_RXCSUM_IPPCSE; @@ -3397,9 +3513,10 @@ ixgbe_disable_intr(struct adapter *adapt ** the slot this adapter is plugged into. */ static void -ixgbe_get_slot_info(struct ixgbe_hw *hw) +ixgbe_get_slot_info(struct adapter *adapter) { - device_t dev = ((struct ixgbe_osdep *)hw->back)->dev; + device_t dev = adapter->dev; + struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_mac_info *mac = &hw->mac; u16 link; u32 offset; @@ -3606,12 +3723,12 @@ ixgbe_sfp_probe(struct adapter *adapter) goto out; ret = hw->phy.ops.reset(hw); if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) { - device_printf(dev,"Unsupported SFP+ module detected!"); - printf(" Reload driver with supported module.\n"); + device_printf(dev, "Unsupported SFP+ module detected!"); + device_printf(dev, "Reload driver with supported module.\n"); adapter->sfp_probe = FALSE; goto out; } else - device_printf(dev,"SFP+ module detected!\n"); + device_printf(dev, "SFP+ module detected!\n"); /* We now have supported optics */ adapter->sfp_probe = FALSE; /* Set the optics type so system reports correctly */ @@ -3630,10 +3747,14 @@ static void ixgbe_handle_link(void *context, int pending) { struct adapter *adapter = context; + struct ixgbe_hw *hw = &adapter->hw; - ixgbe_check_link(&adapter->hw, + ixgbe_check_link(hw, &adapter->link_speed, &adapter->link_up, 0); ixgbe_update_link_status(adapter); + + /* Re-enable link interrupts */ + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_LSC); } /* @@ -3644,23 +3765,66 @@ ixgbe_handle_mod(void *context, int pend { struct adapter *adapter = context; struct ixgbe_hw *hw = &adapter->hw; + enum ixgbe_phy_type orig_type = hw->phy.type; device_t dev = adapter->dev; u32 err; + IXGBE_CORE_LOCK(adapter); + + /* Check to see if the PHY type changed */ + if (hw->phy.ops.identify) { + hw->phy.type = ixgbe_phy_unknown; + hw->phy.ops.identify(hw); + } + + if (hw->phy.type != orig_type) { + device_printf(dev, "Detected phy_type %d\n", hw->phy.type); + + if (hw->phy.type == ixgbe_phy_none) { + hw->phy.sfp_type = ixgbe_sfp_type_unknown; + goto out; + } + + /* Try to do the initialization that was skipped before */ + if (hw->phy.ops.init) + hw->phy.ops.init(hw); + if (hw->phy.ops.reset) + hw->phy.ops.reset(hw); + } + err = hw->phy.ops.identify_sfp(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { device_printf(dev, "Unsupported SFP+ module type was detected.\n"); - return; + goto out; } err = hw->mac.ops.setup_sfp(hw); if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { device_printf(dev, "Setup failure - unsupported SFP+ module type.\n"); - return; + goto out; } - taskqueue_enqueue(adapter->tq, &adapter->msf_task); + if (hw->phy.multispeed_fiber) + taskqueue_enqueue(adapter->tq, &adapter->msf_task); +out: + /* Update media type */ + switch (hw->mac.ops.get_media_type(hw)) { + case ixgbe_media_type_fiber: + adapter->optics = IFM_10G_SR; + break; + case ixgbe_media_type_copper: + adapter->optics = IFM_10G_TWINAX; + break; + case ixgbe_media_type_cx4: + adapter->optics = IFM_10G_CX4; + break; + default: + adapter->optics = 0; + break; + } + + IXGBE_CORE_UNLOCK(adapter); return; } @@ -3675,13 +3839,10 @@ ixgbe_handle_msf(void *context, int pend struct ixgbe_hw *hw = &adapter->hw; u32 autoneg; bool negotiate; - int err; - err = hw->phy.ops.identify_sfp(hw); - if (!err) { - ixgbe_setup_optics(adapter); - INIT_DEBUGOUT1("ixgbe_sfp_probe: flags: %X\n", adapter->optics); - } + IXGBE_CORE_LOCK(adapter); + /* get_supported_phy_layer will call hw->phy.ops.identify_sfp() */ + adapter->phy_layer = ixgbe_get_supported_physical_layer(hw); autoneg = hw->phy.autoneg_advertised; if ((!autoneg) && (hw->mac.ops.get_link_capabilities)) @@ -3689,8 +3850,10 @@ ixgbe_handle_msf(void *context, int pend if (hw->mac.ops.setup_link) hw->mac.ops.setup_link(hw, autoneg, TRUE); + /* Adjust media types shown in ifconfig */ ifmedia_removeall(&adapter->media); ixgbe_add_media_types(adapter); + IXGBE_CORE_UNLOCK(adapter); return; } @@ -3768,18 +3931,6 @@ ixgbe_config_dmac(struct adapter *adapte } /* - * Checks whether the adapter supports Energy Efficient Ethernet - * or not, based on device ID. - */ -static void -ixgbe_check_eee_support(struct adapter *adapter) -{ - struct ixgbe_hw *hw = &adapter->hw; - - adapter->eee_enabled = !!(hw->mac.ops.setup_eee); -} - -/* * Checks whether the adapter's ports are capable of * Wake On LAN by reading the adapter's NVM. * @@ -3797,8 +3948,8 @@ ixgbe_check_wol_support(struct adapter * ixgbe_get_device_caps(hw, &dev_caps); if ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0_1) || ((dev_caps & IXGBE_DEVICE_CAPS_WOL_PORT0) && - hw->bus.func == 0)) - adapter->wol_support = hw->wol_enabled = 1; + hw->bus.func == 0)) + adapter->wol_support = hw->wol_enabled = 1; /* Save initial wake up filter configuration */ adapter->wufc = IXGBE_READ_REG(hw, IXGBE_WUFC); @@ -4145,14 +4296,24 @@ ixgbe_add_device_sysctls(struct adapter CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_thermal_test, "I", "Thermal Test"); - /* for X550 devices */ +#ifdef IXGBE_DEBUG + /* testing sysctls (for all devices) */ + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "power_state", + CTLTYPE_INT | CTLFLAG_RW, adapter, 0, + ixgbe_sysctl_power_state, "I", "PCI Power State"); + + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "print_rss_config", + CTLTYPE_STRING | CTLFLAG_RD, adapter, 0, + ixgbe_sysctl_print_rss_config, "A", "Prints RSS Configuration"); +#endif + /* for X550 series devices */ if (hw->mac.type >= ixgbe_mac_X550) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "dmac", CTLTYPE_INT | CTLFLAG_RW, adapter, 0, ixgbe_sysctl_dmac, "I", "DMA Coalesce"); - /* for X550T and X550EM backplane devices */ - if (hw->mac.ops.setup_eee) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***