From owner-svn-src-projects@freebsd.org Thu Dec 3 04:32:39 2015 Return-Path: Delivered-To: svn-src-projects@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 F0A01A40E13 for ; Thu, 3 Dec 2015 04:32:39 +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 898D1187F; Thu, 3 Dec 2015 04:32:39 +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 tB34WcA7052847; Thu, 3 Dec 2015 04:32:38 GMT (envelope-from sbruno@FreeBSD.org) Received: (from sbruno@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tB34WcXn052844; Thu, 3 Dec 2015 04:32:38 GMT (envelope-from sbruno@FreeBSD.org) Message-Id: <201512030432.tB34WcXn052844@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: sbruno set sender to sbruno@FreeBSD.org using -f From: Sean Bruno Date: Thu, 3 Dec 2015 04:32:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r291673 - projects/intel_net_refactor/sys/contrib/dev/igb X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Dec 2015 04:32:40 -0000 Author: sbruno Date: Thu Dec 3 04:32:38 2015 New Revision: 291673 URL: https://svnweb.freebsd.org/changeset/base/291673 Log: Import version 2.4.3 of the Intel FreeBSD Driver, igb(4) from https://downloadcenter.intel.com into the contrib directory. Added: projects/intel_net_refactor/sys/contrib/dev/igb/ projects/intel_net_refactor/sys/contrib/dev/igb/Makefile (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/README (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_82575.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_82575.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_api.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_api.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_defines.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_hw.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_i210.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_i210.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_mac.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_mac.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_manage.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_manage.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_mbx.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_mbx.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_nvm.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_nvm.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_osdep.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_osdep.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_phy.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_phy.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_regs.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_vf.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/e1000_vf.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/if_igb.c (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/if_igb.h (contents, props changed) projects/intel_net_refactor/sys/contrib/dev/igb/igb.4 (contents, props changed) Added: projects/intel_net_refactor/sys/contrib/dev/igb/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/intel_net_refactor/sys/contrib/dev/igb/Makefile Thu Dec 3 04:32:38 2015 (r291673) @@ -0,0 +1,30 @@ +#$FreeBSD$ +.PATH: ${.CURDIR} +KMOD = if_igb +SRCS = device_if.h bus_if.h pci_if.h opt_bdg.h +SRCS += if_igb.c $(SHARED_SRCS) +SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c +SHARED_SRCS += e1000_osdep.c e1000_82575.c e1000_i210.c e1000_vf.c e1000_mbx.c +CFLAGS += -DSMP -DINET -DINET6 + +# DEVICE_POLLING gives you non-interrupt handling +#CFLAGS += -DDEVICE_POLLING + +# Some workloads seem to perform better using the legacy +# stack interface, while others will benefit from the +# MULTIQUEUE interface. +# IGB_LEGACY_TX gives you the older non-mq stack interface; +# it should be used with a single queue configuration +#CFLAGS += -DIGB_LEGACY_TX + +clean: + rm -f opt_bdg.h device_if.h bus_if.h pci_if.h setdef* + rm -f *.o *.kld *.ko + rm -f @ machine x86 export_syms + rm -f ${CLEANFILES} + +man: + mv /usr/share/man/man4/igb.4.gz /usr/share/man/man4/igbSAVE.4.gz + cp igb.4 /usr/share/man/man4/ + +.include Added: projects/intel_net_refactor/sys/contrib/dev/igb/README ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/intel_net_refactor/sys/contrib/dev/igb/README Thu Dec 3 04:32:38 2015 (r291673) @@ -0,0 +1,460 @@ +FreeBSD* Driver for Intel® Ethernet +=================================== +December 8, 2014 + + +Contents +======== + +- Overview +- Identifying Your Adapter +- Building and Installation +- Speed and Duplex Configuration +- Additional Configurations +- Known Limitations +- Support +- License + + +Overview +======== + +This file describes the FreeBSD* driver for Intel® Ethernet. +This driver has been developed for use with all community-suppported versions +of FreeBSD. + +For questions related to hardware requirements, refer to the documentation +supplied with your Gigabit adapter. All hardware requirements listed +apply to use with FreeBSD. + +NOTE: This release includes two gigabit FreeBSD base Drivers for Intel(R) + Ethernet. These drivers are em and igb. + + - The igb driver supports all 82575 and 82576-based gigabit network + connections. + - The em driver supports all other gigabit network connections. + + +Identifying Your Adapter +======================== + +For information on how to identify your adapter, go to the Adapter & +Driver ID Guide at: + + http://support.intel.com/support/go/network/adapter/proidguide.htm + +For the latest Intel network drivers for FreeBSD, see: + + http://downloadcenter.intel.com + +NOTE: Mobile adapters are not fully supported. + + +Building and Installation +========================= + +NOTE: This driver package is to be used only as a standalone archive and the +user should not attempt to incorporate it into the kernel source tree. + +In the instructions below, x.x.x is the driver version as indicated in the +name of the driver tar file. + +1. Move the base driver tar file to the directory of your choice. For + example, use /home/username/igb or /usr/local/src/igb. + +2. Untar/unzip the archive: + + tar xzvf igb-x.x.x.tar.gz + + This will create an igb-x.x.x directory. + +3. To create a loadable module, perform the following steps. + + a. To compile the module + + cd igb-x.x.x + make + + b. To install the compiled module to the system directory: + + make install + + c. If you want the driver to load automatically when the system is booted: + + 1. Edit /boot/loader.conf, and add the following line: + + if_igb_load="YES" + +4. To assign an IP address to the interface, enter the following: + + ifconfig igbX + +5. Verify that the interface works. Enter the following, where + is the IP address for another machine on the same subnet as the interface + that is being tested: + + ping + +6. To configure the IP address to remain after reboot, edit /etc/rc.conf, + and create the appropriate ifconfig_igb entry: + + ifconfig_igb="" + + Example usage: + + ifconfig_igb0="inet 192.168.10.1 netmask 255.255.255.0" + + NOTE: For assistance, see the ifconfig man page. + + +Speed and Duplex Configuration +============================== + +In addressing speed and duplex configuration issues, you need to +distinguish between copper-based adapters and fiber-based adapters. + +In the default mode, an Intel(R) Network Adapter using copper connections +will attempt to auto-negotiate with its link partner to determine the best +setting. If the adapter cannot establish link with the link partner using +auto-negotiation, you may need to manually configure the adapter and link +partner to identical settings to establish link and pass packets. This +should only be needed when attempting to link with an older switch that +does not support auto-negotiation or one that has been forced to a specific +speed or duplex mode. Your link partner must match the setting you choose. + +Speed and Duplex are configured through the ethtool* utility. ethtool is +included with all versions of Red Hat after Red Hat 7.2. For other Linux +distributions, download and install ethtool from the following website: + + http://ftp.kernel.org/pub/software/network/ethtool/ + +Caution: Only experienced network administrators should force speed and +duplex manually. The settings at the switch must always match the adapter +settings. Adapter performance may suffer or your adapter may not +operate if you configure the adapter differently from your switch. + +An Intel® Network Adapter using fiber-based connections, however, will not +attempt to auto-negotiate with its link partner since those adapters operate +only in full duplex and only at their native speed. + +By default, the adapter auto-negotiates the speed and duplex of the +connection. If there is a specific need, the ifconfig utility can be +used to configure the speed and duplex settings on the adapter. + +Example usage: + + ifconfig emX media 100baseTX mediaopt full-duplex + +NOTE: Only use mediaopt to set the driver to full-duplex. If mediaopt is + not specified and you are not running at gigabit speed, the driver + defaults to half-duplex. + +If the interface is currently forced to 100 full duplex, you must use this +command to change to half duplex: + + ifconfig emX media 100baseTX -mediaopt full-duplex + +This driver supports the following media type options: + +Media Type Description +---------- ----------- +autoselect Enables auto-negotiation for speed and duplex. + +10baseT/UTP Sets speed to 10 Mbps. Use the ifconfig mediaopt + option to select full-duplex mode. + +100baseTX Sets speed to 100 Mbps. Use the ifconfig mediaopt + option to select full-duplex mode. + +1000baseTX Sets speed to 1000 Mbps. In this case, the driver + supports only full-duplex mode. + +1000baseSX Sets speed to 1000 Mbps. In this case, the driver + supports only full-duplex mode. + +For more information on the ifconfig utility, see the ifconfig man page. + + +Additional Configurations +========================= + +The driver supports Transmit/Receive Checksum Offload and Jumbo Frames. + +Jumbo Frames +------------ +To enable Jumbo Frames, use the ifconfig utility to set the Maximum +Transport Unit (MTU) frame size above its default of 1500 bytes. + +The Jumbo Frames MTU range for Intel Adapters is 1500 to 9216. To modify +the setting, enter the following: + + ifconfig igbX mtu 9000 + +To confirm the MTU used between two specific devices, use: + + route get + +NOTES: +- Only enable Jumbo Frames if your network infrastructure supports them. +- To enable Jumbo Frames, increase the MTU size on the interface beyond + 1500. +- The Jumbo Frames setting on the switch must be set to at least 22 bytes + larger than that of the MTU. +- The maximum MTU setting for Jumbo Frames is 9216. This value coincides + with the maximum Jumbo Frames size of 9234 bytes. +- Using Jumbo frames at 10 or 100 Mbps is not supported and may result in + poor performance or loss of link. +- The following adapters do not support Jumbo Frames: + Intel®PRO/1000 Gigabit Server Adapter + Intel® PRO/1000 PM Network Connection + Intel® 82562V 10/100 Network Connection + Intel® 82566DM Gigabit Network Connection + Intel® 82566DC Gigabit Network Connection + Intel® 82566MM Gigabit Network Connection + Intel® 82566MC Gigabit Network Connection + Intel® 82562GT 10/100 Network Connection + Intel® 82562G 10/100 Network Connection + Intel® 82566DC-2 Gigabit Network Connection + Intel® 82562V-2 10/100 Network Connection + Intel® 82562G-2 10/100 Network Connection + Intel® 82562GT-2 10/100 Network Connection + Intel® 82567V-3 Gigabit Network Connection + +VLANs +----- +To create a new VLAN interface: + + ifconfig create + +To associate the VLAN interface with a physical interface and +assign a VLAN ID, IP address, and netmask: + + ifconfig netmask vlan + vlandev + +Example: + + ifconfig vlan10 10.0.0.1 netmask 255.255.255.0 vlan 10 vlandev igb0 + +In this example, all packets will be marked on egress with 802.1Q VLAN +tags, specifying a VLAN ID of 10. + +To remove a VLAN interface: + + ifconfig destroy + +Polling +------- +NOTES: +- Device Polling is only valid for non-SMP kernels. +- The driver has to be built into the kernel for Device Polling to be + enabled in the driver. + +To enable polling in the driver, add the following options to the kernel +configuration, and then recompile the kernel: + + options DEVICE_POLLING + options HZ=1000 + +At runtime use: + + ifconfig igbX polling (to turn polling on) + ifconfig igbX -polling (to turn it off) + +Checksum Offload +---------------- +Checksum offloading supports both TCP and UDP packets and is +supported for both transmit and receive. + +Checksum offloading can be enabled or disabled using ifconfig. +Both transmit and receive offloading will be either enabled or +disabled together. You cannot enable/disable one without the other. + +NOTE: Checksum offloading is not supported on 82542-based gigabit adapters. + +To enable checksum offloading: + + ifconfig igbX rxcsum + +To disable checksum offloading: + + ifconfig igbX -rxcsum + +To confirm the current setting: + + ifconfig igbX + +Look for the presence or absence of the following line: + + options=3 + +See the ifconfig man page for further information. + +TSO +--- +The FreeBSD driver offers support for TSO (TCP Segmentation Offload). + +You can enable/disable it in two ways/places: + + - sysctl net.inet.tcp.tso=0 (or 1 to enable it) + + Doing this disables TSO in the stack and will affect all adapters. + + - ifconfig igbX -tso + + Doing this will disable TSO only for this adapter. + +To enable: + + - ifconfig igbX tso + + NOTES: By default only PCI-Express adapters are ENABLED to do TSO. + Others can be enabled by the user at their own risk. + + TSO is not supported on 82547 and 82544-based adapters, + as well as older adapters. + + +MSI-X +----- +The FreeBSD driver offers MSIX support with 82574L-based network connections. +82574L-based network connections will use MSI-X by default. + +MSI or MSI-X can be turned off by an entry in /etc/sysctl.conf + + - hw.em.enable_msi=0 + + Unload and reload the driver. + + +LRO +--- +Large Receive Offload is available in the driver; it is on by default. + +It can be disabled by using: + + ifconfig -lro + +To enable: + + ifconfig lro + +EEE +--- +Valid Range: 0-1 +Default Value: 1 (enabled) + +A link between two EEE-compliant devices will result in periodic bursts of +data followed by long periods where in the link is in an idle state. This Low +Power Idle (LPI) state is supported in both 1Gbps and 100Mbps link speeds. + +NOTE: EEE support requires autonegotiation. + +DMAC +---- +Valid Range: 0, 1, 250, 500, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, + 9000, and 10000 +Default Value: 1 (enabled) + +Enables or disables DMA Coalescing feature. DMA (Direct Memory Access) allows +the network device to move packet data directly to the system's memory, +reducing CPU utilitzation. However, the frequency and random intervals at +which packets arrive do not allow the system to enter a lower power state. +DMA Coalescing allows the adapter to collect packets before it initiates a +DMA event. This may increase network latency but also increases the chances +that the system will enter a lower power state. + +InterruptThrottleRate (ITR) should be set to dynamic. This will impart the +greatest chance for your system to consume less power. DMA Coalescing is +effective in helping potentially saving the platform power only when it is +enabled across all active ports. + +A whitepaper containing information on how to best configure your platform +is available on the Intel website. + + +Known Limitations +================= + +For known hardware and troubleshooting issues, refer to the following website. + + http://support.intel.com/support/go/network/adapter/home.htm + +Either select the link for your adapter or perform a search for the adapter +number. The adapter's page lists many issues. For a complete list of hardware +issues download your adapter's user guide and read the Release Notes. + + +Detected Tx Unit Hang in Quad Port Adapters +------------------------------------------- +In some cases ports 3 and 4 won’t pass traffic. Ports 1 and 2 don't show +any errors and will pass traffic. + +This issue MAY be resolved by updating to the latest BIOS. You can +check your system's BIOS by downloading the Linux Firmware Developer Kit +that can be obtained at http://www.linuxfirmwarekit.org/ + + +There are known performance issues with this driver when running UDP traffic +with Jumbo Frames. +---------------------------------------------------------------------------- + + +82541/82547 can't link or is slow to link with some link partners +----------------------------------------------------------------- +There is a known compatibility issue where time to link is slow or link is not established between 82541/82547 controllers and some switches. Known switches include: + + - Planex FXG-08TE + - I-O Data ETG-SH8 + +The driver can be compiled with the following changes: + + Edit ./em.x.x.x/src/if_em.h to change the #define EM_MASTER_SLAVE + For example, change from: + + #define EM_MASTER_SLAVE e1000_ms_hw_default + to: + #define EM_MASTER_SLAVE 2 + +Use one of the following options: + + 1 = Master mode + 2 = Slave mode + 3 = Auto master/slave + Setting 2 is recommended. + +Recompile the module: + + cd em-x.x.x + make clean + make + +To install the compiled module in system directory: + + make install + + +Support +======= + +For general information and support, go to the Intel support website at: + + www.intel.com/support/ + +If an issue is identified, support is through email only at: + + freebsd@intel.com + + +License +======= + +This software program is released under the terms of a license agreement +between you ('Licensee') and Intel. Do not use or load this software or any +associated materials (collectively, the 'Software') until you have carefully +read the full terms and conditions of the LICENSE located in this software +package. By loading or using the Software, you agree to the terms of this +Agreement. If you do not agree with the terms of this Agreement, do not +install or use the Software. + +* Other names and brands may be claimed as the property of others. Added: projects/intel_net_refactor/sys/contrib/dev/igb/e1000_82575.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/intel_net_refactor/sys/contrib/dev/igb/e1000_82575.c Thu Dec 3 04:32:38 2015 (r291673) @@ -0,0 +1,3675 @@ +/****************************************************************************** + + Copyright (c) 2001-2013, Intel Corporation + 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. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +******************************************************************************/ +/*$FreeBSD$*/ + +/* + * 82575EB Gigabit Network Connection + * 82575EB Gigabit Backplane Connection + * 82575GB Gigabit Network Connection + * 82576 Gigabit Network Connection + * 82576 Quad Port Gigabit Mezzanine Adapter + * 82580 Gigabit Network Connection + * I350 Gigabit Network Connection + */ + +#include "e1000_api.h" +#include "e1000_i210.h" + +static s32 e1000_init_phy_params_82575(struct e1000_hw *hw); +static s32 e1000_init_mac_params_82575(struct e1000_hw *hw); +static s32 e1000_acquire_phy_82575(struct e1000_hw *hw); +static void e1000_release_phy_82575(struct e1000_hw *hw); +static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw); +static void e1000_release_nvm_82575(struct e1000_hw *hw); +static s32 e1000_check_for_link_82575(struct e1000_hw *hw); +static s32 e1000_check_for_link_media_swap(struct e1000_hw *hw); +static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw); +static s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, + u16 *duplex); +static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); +static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, + u16 *data); +static s32 e1000_reset_hw_82575(struct e1000_hw *hw); +static s32 e1000_reset_hw_82580(struct e1000_hw *hw); +static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw, + u32 offset, u16 *data); +static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, + u32 offset, u16 data); +static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, + bool active); +static s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, + bool active); +static s32 e1000_set_d0_lplu_state_82575(struct e1000_hw *hw, + bool active); +static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw); +static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw); +static s32 e1000_get_media_type_82575(struct e1000_hw *hw); +static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw); +static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data); +static s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, + u32 offset, u16 data); +static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); +static s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); +static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, + u16 *speed, u16 *duplex); +static s32 e1000_get_phy_id_82575(struct e1000_hw *hw); +static void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); +static bool e1000_sgmii_active_82575(struct e1000_hw *hw); +static s32 e1000_reset_init_script_82575(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw); +static void e1000_config_collision_dist_82575(struct e1000_hw *hw); +static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw); +static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw); +static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw); +static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw); +static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw); +static s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw); +static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw); +static s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, + u16 offset); +static s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, + u16 offset); +static s32 e1000_validate_nvm_checksum_i350(struct e1000_hw *hw); +static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw); +static void e1000_write_vfta_i350(struct e1000_hw *hw, u32 offset, u32 value); +static void e1000_clear_vfta_i350(struct e1000_hw *hw); + +static void e1000_i2c_start(struct e1000_hw *hw); +static void e1000_i2c_stop(struct e1000_hw *hw); +static s32 e1000_clock_in_i2c_byte(struct e1000_hw *hw, u8 *data); +static s32 e1000_clock_out_i2c_byte(struct e1000_hw *hw, u8 data); +static s32 e1000_get_i2c_ack(struct e1000_hw *hw); +static s32 e1000_clock_in_i2c_bit(struct e1000_hw *hw, bool *data); +static s32 e1000_clock_out_i2c_bit(struct e1000_hw *hw, bool data); +static void e1000_raise_i2c_clk(struct e1000_hw *hw, u32 *i2cctl); +static void e1000_lower_i2c_clk(struct e1000_hw *hw, u32 *i2cctl); +static s32 e1000_set_i2c_data(struct e1000_hw *hw, u32 *i2cctl, bool data); +static bool e1000_get_i2c_data(u32 *i2cctl); + +static const u16 e1000_82580_rxpbs_table[] = { + 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 }; +#define E1000_82580_RXPBS_TABLE_SIZE \ + (sizeof(e1000_82580_rxpbs_table) / \ + sizeof(e1000_82580_rxpbs_table[0])) + + +/** + * e1000_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO + * @hw: pointer to the HW structure + * + * Called to determine if the I2C pins are being used for I2C or as an + * external MDIO interface since the two options are mutually exclusive. + **/ +static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw) +{ + u32 reg = 0; + bool ext_mdio = FALSE; + + DEBUGFUNC("e1000_sgmii_uses_mdio_82575"); + + switch (hw->mac.type) { + case e1000_82575: + case e1000_82576: + reg = E1000_READ_REG(hw, E1000_MDIC); + ext_mdio = !!(reg & E1000_MDIC_DEST); + break; + case e1000_82580: + case e1000_i350: + case e1000_i354: + case e1000_i210: + case e1000_i211: + reg = E1000_READ_REG(hw, E1000_MDICNFG); + ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); + break; + default: + break; + } + return ext_mdio; +} + +/** + * e1000_init_phy_params_82575 - Init PHY func ptrs. + * @hw: pointer to the HW structure + **/ +static s32 e1000_init_phy_params_82575(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val = E1000_SUCCESS; + u32 ctrl_ext; + + DEBUGFUNC("e1000_init_phy_params_82575"); + + phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic; + phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic; + + if (hw->phy.media_type != e1000_media_type_copper) { + phy->type = e1000_phy_none; + goto out; + } + + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82575; + + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 100; + + phy->ops.acquire = e1000_acquire_phy_82575; + phy->ops.check_reset_block = e1000_check_reset_block_generic; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.get_cfg_done = e1000_get_cfg_done_82575; + phy->ops.release = e1000_release_phy_82575; + + ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); + + if (e1000_sgmii_active_82575(hw)) { + phy->ops.reset = e1000_phy_hw_reset_sgmii_82575; + ctrl_ext |= E1000_CTRL_I2C_ENA; + } else { + phy->ops.reset = e1000_phy_hw_reset_generic; + ctrl_ext &= ~E1000_CTRL_I2C_ENA; + } + + E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); + e1000_reset_mdicnfg_82580(hw); + + if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) { + phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575; + phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575; + } else { + switch (hw->mac.type) { + case e1000_82580: + case e1000_i350: + case e1000_i354: + phy->ops.read_reg = e1000_read_phy_reg_82580; + phy->ops.write_reg = e1000_write_phy_reg_82580; + break; + case e1000_i210: + case e1000_i211: + phy->ops.read_reg = e1000_read_phy_reg_gs40g; + phy->ops.write_reg = e1000_write_phy_reg_gs40g; + break; + default: + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.write_reg = e1000_write_phy_reg_igp; + } + } + + /* Set phy->phy_addr and phy->id. */ + ret_val = e1000_get_phy_id_82575(hw); + + /* Verify phy id and set remaining function pointers */ + switch (phy->id) { + case M88E1543_E_PHY_ID: + case M88E1512_E_PHY_ID: + case I347AT4_E_PHY_ID: + case M88E1112_E_PHY_ID: + case M88E1340M_E_PHY_ID: + case M88E1111_I_PHY_ID: + phy->type = e1000_phy_m88; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + if (phy->id == I347AT4_E_PHY_ID || + phy->id == M88E1112_E_PHY_ID || + phy->id == M88E1340M_E_PHY_ID) + phy->ops.get_cable_length = + e1000_get_cable_length_m88_gen2; + else if (phy->id == M88E1543_E_PHY_ID || + phy->id == M88E1512_E_PHY_ID) + phy->ops.get_cable_length = + e1000_get_cable_length_m88_gen2; + else + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + /* Check if this PHY is confgured for media swap. */ + if (phy->id == M88E1112_E_PHY_ID) { + u16 data; + + ret_val = phy->ops.write_reg(hw, + E1000_M88E1112_PAGE_ADDR, + 2); + if (ret_val) + goto out; + + ret_val = phy->ops.read_reg(hw, + E1000_M88E1112_MAC_CTRL_1, + &data); + if (ret_val) + goto out; + + data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >> + E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT; + if (data == E1000_M88E1112_AUTO_COPPER_SGMII || + data == E1000_M88E1112_AUTO_COPPER_BASEX) + hw->mac.ops.check_for_link = + e1000_check_for_link_media_swap; + } + if (phy->id == M88E1512_E_PHY_ID) { + ret_val = e1000_initialize_M88E1512_phy(hw); + if (ret_val) + goto out; + } + break; + case IGP03E1000_E_PHY_ID: + case IGP04E1000_E_PHY_ID: + phy->type = e1000_phy_igp_3; + phy->ops.check_polarity = e1000_check_polarity_igp; + phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.get_cable_length = e1000_get_cable_length_igp_2; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + break; + case I82580_I_PHY_ID: + case I350_I_PHY_ID: + phy->type = e1000_phy_82580; + phy->ops.check_polarity = e1000_check_polarity_82577; + phy->ops.force_speed_duplex = + e1000_phy_force_speed_duplex_82577; + phy->ops.get_cable_length = e1000_get_cable_length_82577; + phy->ops.get_info = e1000_get_phy_info_82577; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; + break; + case I210_I_PHY_ID: + phy->type = e1000_phy_i210; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + break; + default: + ret_val = -E1000_ERR_PHY; + goto out; + } + +out: + return ret_val; +} + +/** + * e1000_init_nvm_params_82575 - Init NVM func ptrs. + * @hw: pointer to the HW structure + **/ +s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = E1000_READ_REG(hw, E1000_EECD); + u16 size; + + DEBUGFUNC("e1000_init_nvm_params_82575"); + + size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> + E1000_EECD_SIZE_EX_SHIFT); + /* + * Added to a constant, "size" becomes the left-shift value + * for setting word_size. + */ + size += NVM_WORD_SIZE_BASE_SHIFT; + + /* Just in case size is out of range, cap it to the largest + * EEPROM size supported + */ + if (size > 15) + size = 15; + + nvm->word_size = 1 << size; + if (hw->mac.type < e1000_i210) { + nvm->opcode_bits = 8; + nvm->delay_usec = 1; + + switch (nvm->override) { + case e1000_nvm_override_spi_large: + nvm->page_size = 32; + nvm->address_bits = 16; + break; + case e1000_nvm_override_spi_small: + nvm->page_size = 8; + nvm->address_bits = 8; + break; + default: + nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; + nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? + 16 : 8; + break; + } + if (nvm->word_size == (1 << 15)) + nvm->page_size = 128; + + nvm->type = e1000_nvm_eeprom_spi; + } else { + nvm->type = e1000_nvm_flash_hw; + } + + /* Function Pointers */ + nvm->ops.acquire = e1000_acquire_nvm_82575; + nvm->ops.release = e1000_release_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = e1000_read_nvm_eerd; + else + nvm->ops.read = e1000_read_nvm_spi; + + nvm->ops.write = e1000_write_nvm_spi; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_82575; + + /* override generic family function pointers for specific descendants */ + switch (hw->mac.type) { + case e1000_82580: + nvm->ops.validate = e1000_validate_nvm_checksum_82580; + nvm->ops.update = e1000_update_nvm_checksum_82580; + break; + case e1000_i350: + case e1000_i354: + nvm->ops.validate = e1000_validate_nvm_checksum_i350; + nvm->ops.update = e1000_update_nvm_checksum_i350; + break; + default: + break; + } + + return E1000_SUCCESS; +} + +/** + * e1000_init_mac_params_82575 - Init MAC func ptrs. + * @hw: pointer to the HW structure + **/ +static s32 e1000_init_mac_params_82575(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; + + DEBUGFUNC("e1000_init_mac_params_82575"); + + /* Derives media type */ + e1000_get_media_type_82575(hw); + /* Set mta register count */ + mac->mta_reg_count = 128; + /* Set uta register count */ + mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128; + /* Set rar entry count */ + mac->rar_entry_count = E1000_RAR_ENTRIES_82575; + if (mac->type == e1000_82576) + mac->rar_entry_count = E1000_RAR_ENTRIES_82576; + if (mac->type == e1000_82580) + mac->rar_entry_count = E1000_RAR_ENTRIES_82580; + if (mac->type == e1000_i350 || mac->type == e1000_i354) + mac->rar_entry_count = E1000_RAR_ENTRIES_I350; + + /* Enable EEE default settings for EEE supported devices */ + if (mac->type >= e1000_i350) + dev_spec->eee_disable = FALSE; + + /* Allow a single clear of the SW semaphore on I210 and newer */ + if (mac->type >= e1000_i210) + dev_spec->clear_semaphore_once = TRUE; + + /* Set if part includes ASF firmware */ + mac->asf_firmware_present = TRUE; + /* FWSM register */ + mac->has_fwsm = TRUE; + /* ARC supported; valid only if manageability features are enabled. */ + mac->arc_subsystem_valid = + !!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK); + + /* Function pointers */ + + /* bus type/speed/width */ + mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; + /* reset */ + if (mac->type >= e1000_82580) + mac->ops.reset_hw = e1000_reset_hw_82580; + else + mac->ops.reset_hw = e1000_reset_hw_82575; + /* hw initialization */ + if ((mac->type == e1000_i210) || (mac->type == e1000_i211)) + mac->ops.init_hw = e1000_init_hw_i210; + else + mac->ops.init_hw = e1000_init_hw_82575; + /* link setup */ + mac->ops.setup_link = e1000_setup_link_generic; + /* physical interface link setup */ + mac->ops.setup_physical_interface = + (hw->phy.media_type == e1000_media_type_copper) + ? e1000_setup_copper_link_82575 : e1000_setup_serdes_link_82575; + /* physical interface shutdown */ + mac->ops.shutdown_serdes = e1000_shutdown_serdes_link_82575; + /* physical interface power up */ + mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575; + /* check for link */ + mac->ops.check_for_link = e1000_check_for_link_82575; + /* read mac address */ + mac->ops.read_mac_addr = e1000_read_mac_addr_82575; + /* configure collision distance */ + mac->ops.config_collision_dist = e1000_config_collision_dist_82575; + /* multicast address update */ + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; + if (hw->mac.type == e1000_i350 || mac->type == e1000_i354) { + /* writing VFTA */ + mac->ops.write_vfta = e1000_write_vfta_i350; + /* clearing VFTA */ + mac->ops.clear_vfta = e1000_clear_vfta_i350; + } else { + /* writing VFTA */ + mac->ops.write_vfta = e1000_write_vfta_generic; + /* clearing VFTA */ + mac->ops.clear_vfta = e1000_clear_vfta_generic; + } + if (hw->mac.type >= e1000_82580) + mac->ops.validate_mdi_setting = + e1000_validate_mdi_setting_crossover_generic; + /* ID LED init */ + mac->ops.id_led_init = e1000_id_led_init_generic; + /* blink LED */ + mac->ops.blink_led = e1000_blink_led_generic; + /* setup LED */ + mac->ops.setup_led = e1000_setup_led_generic; + /* cleanup LED */ + mac->ops.cleanup_led = e1000_cleanup_led_generic; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***