From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) by dpdk.org (Postfix) with ESMTP id BDE8B1B918 for ; Tue, 18 Dec 2018 09:21:04 +0100 (CET) Received: by mail-pl1-f176.google.com with SMTP id u18so7475778plq.7 for ; Tue, 18 Dec 2018 00:21:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nfware-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=VZaNV/NqeuxiKTkx718KbkH+8v6k1FCkfKXneEMbM5k=; b=K8nQ3QVcXq3elY2XY1M0xsXWg+s0TFC+a+1i8MAQxm8aeLvkSy6cxzY85lYyKtAWex 8uotLeLO6M/hDLD+4IjOEJjbaJCl3z51bpXCvQpTITgosGHku98vpSv8BJ4AuXa30osd NgN10Z0yfItJoAzG79kUijeQQh3yBlaFdfWzLPpQvr7xJLVa8EZvKNFvGlF1475U4cRR ZOBfmEWVqbaWx1frUQOD7/Kk6+bOTHYQvZab6wDEznet+ctefdaGvJ36dN4nY7N1SWjs tk1SUVcVQKbXJFxMT5iXcDg9GzDKYNFk0q3k9cZaKmxHxNzymOKc6BPWp+1yMCu6jubI Y0wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=VZaNV/NqeuxiKTkx718KbkH+8v6k1FCkfKXneEMbM5k=; b=De5jiIBH9I3wa/hgn5zKEZLmSUfHRYSlWrEGZPDB+UpuSbV3QyaL1R57O2aFrXMU94 avsKRtzfp+RHUwaJQBy6imiJUBHokMmFRWVlo9dfkXPbcfAq0S917eUwqZ+oeI1mLKnq 3IwTLvtIusWBa/vfqDZD4rTR45x6cFRuma0ux+X5xM6fJN4mUgCtdgGZf4HQcMvItQX4 vtEAjn+VZfr7etlgxpelUMYKFuopv5AIMK9xqpGysmOy6znRgtFbPUmPzVSMqxWNBn69 QE5n4VzFt1DmIIao00impIe/FXKZ8LNKQe4nNHmRy6wN40JTjEO7MhQaJAltg3oGwKbi gylA== X-Gm-Message-State: AA+aEWZVfKK5O3KvK8TzRh4i13wKAuUJqSBXeKFzLWhL35PQ2xV99sHe tiKo+mPf7yL+MUh4lx49L3/U08KyM07wLzFGzcFnpA== X-Google-Smtp-Source: AFSGD/X2WR5AXIpQrGOJlOsEQZNe2BsH4lGU+CuzbJJl2ZG0ubUzaYoN8wZS0Ro8caLg2XZTiwL7MuUGgG3TLQdF5ls= X-Received: by 2002:a17:902:bd4a:: with SMTP id b10mr15657941plx.232.1545121263102; Tue, 18 Dec 2018 00:21:03 -0800 (PST) MIME-Version: 1.0 References: <20181218012539.52921-1-ferruh.yigit@intel.com> In-Reply-To: <20181218012539.52921-1-ferruh.yigit@intel.com> From: Igor Ryzhov Date: Tue, 18 Dec 2018 11:20:51 +0300 Message-ID: To: Ferruh Yigit Cc: dev@dpdk.org, Thomas Monjalon , John McNamara , Marko Kovacevic Content-Type: text/plain; charset="UTF-8" X-Content-Filtered-By: Mailman/MimeDel 2.1.15 Subject: Re: [dpdk-dev] [RFC] kni: remove ethtool support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Dec 2018 08:21:05 -0000 Hi Ferruh, Please, look at my patch http://patches.dpdk.org/patch/48454/ and consider rebasing your patch over mine. As we discussed with Stephen, KNI needs to supply ethtool_ops with .get_link function, to properly support link status. So we should save ethtool_ops and implement .get_link using standard ethtool_op_get_link. Best regards, Igor On Tue, Dec 18, 2018 at 4:28 AM Ferruh Yigit wrote: > Current design requires kernel drivers and they need to be probed by Linux > up to some level so that they can be usable by DPDK for ethtool support, > this requires maintaining the Linux drivers in DPDK. Also ethtool support > is limited and hard, if not impossible, to expand to other PMDs. Since KNI > ethtool support is not used commonly, if not used at all, removing the > support for the sake of simplicity and maintenance. Signed-off-by: Ferruh > Yigit --- config/common_base | 1 - > .../sample_app_ug/kernel_nic_interface.rst | 10 - examples/kni/main.c | 9 - > kernel/linux/kni/Kbuild | 4 +- kernel/linux/kni/Makefile | 26 +- > kernel/linux/kni/ethtool/README | 71 - > kernel/linux/kni/ethtool/igb/e1000_82575.c | 3650 ------ > kernel/linux/kni/ethtool/igb/e1000_82575.h | 494 - > kernel/linux/kni/ethtool/igb/e1000_api.c | 1144 -- > kernel/linux/kni/ethtool/igb/e1000_api.h | 142 - > kernel/linux/kni/ethtool/igb/e1000_defines.h | 1365 -- > kernel/linux/kni/ethtool/igb/e1000_hw.h | 778 -- > kernel/linux/kni/ethtool/igb/e1000_i210.c | 894 -- > kernel/linux/kni/ethtool/igb/e1000_i210.h | 76 - > kernel/linux/kni/ethtool/igb/e1000_mac.c | 2081 ---- > kernel/linux/kni/ethtool/igb/e1000_mac.h | 65 - > kernel/linux/kni/ethtool/igb/e1000_manage.c | 539 - > kernel/linux/kni/ethtool/igb/e1000_manage.h | 74 - > kernel/linux/kni/ethtool/igb/e1000_mbx.c | 510 - > kernel/linux/kni/ethtool/igb/e1000_mbx.h | 72 - > kernel/linux/kni/ethtool/igb/e1000_nvm.c | 950 -- > kernel/linux/kni/ethtool/igb/e1000_nvm.h | 60 - > kernel/linux/kni/ethtool/igb/e1000_osdep.h | 121 - > kernel/linux/kni/ethtool/igb/e1000_phy.c | 3392 ----- > kernel/linux/kni/ethtool/igb/e1000_phy.h | 241 - > kernel/linux/kni/ethtool/igb/e1000_regs.h | 631 - > kernel/linux/kni/ethtool/igb/igb.h | 844 -- > kernel/linux/kni/ethtool/igb/igb_ethtool.c | 2851 ----- > kernel/linux/kni/ethtool/igb/igb_main.c | 10344 ---------------- > kernel/linux/kni/ethtool/igb/igb_param.c | 832 -- > kernel/linux/kni/ethtool/igb/igb_regtest.h | 234 - > kernel/linux/kni/ethtool/igb/igb_vmdq.c | 421 - > kernel/linux/kni/ethtool/igb/igb_vmdq.h | 31 - > kernel/linux/kni/ethtool/igb/kcompat.h | 3945 ------ > kernel/linux/kni/ethtool/igb/meson.build | 16 - > kernel/linux/kni/ethtool/ixgbe/ixgbe.h | 912 -- > kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c | 1281 -- > kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h | 29 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c | 2299 ---- > kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h | 43 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c | 1142 -- > kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h | 153 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c | 4067 ------ > kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h | 125 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h | 153 - > .../linux/kni/ethtool/ixgbe/ixgbe_ethtool.c | 2894 ----- > kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h | 76 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c | 2951 ----- > kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h | 90 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h | 117 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c | 1832 --- > kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h | 122 - > kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h | 3239 ----- > kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c | 922 -- > kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h | 43 - > kernel/linux/kni/ethtool/ixgbe/kcompat.c | 1231 -- > kernel/linux/kni/ethtool/ixgbe/kcompat.h | 3140 ----- > kernel/linux/kni/ethtool/ixgbe/meson.build | 13 - > kernel/linux/kni/ethtool/meson.build | 5 - kernel/linux/kni/kni_dev.h | 8 - > kernel/linux/kni/kni_ethtool.c | 229 - kernel/linux/kni/kni_misc.c | 82 +- > kernel/linux/kni/meson.build | 9 +- lib/librte_kni/rte_kni.c | 5 - > lib/librte_kni/rte_kni.h | 4 +- 65 files changed, 15 insertions(+), 64119 > deletions(-) delete mode 100644 kernel/linux/kni/ethtool/README delete mode > 100644 kernel/linux/kni/ethtool/igb/e1000_82575.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_82575.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_api.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_api.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_defines.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_hw.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_i210.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_i210.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_mac.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_mac.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_manage.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_manage.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_mbx.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_mbx.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_nvm.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_nvm.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_osdep.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_phy.c delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_phy.h delete mode 100644 > kernel/linux/kni/ethtool/igb/e1000_regs.h delete mode 100644 > kernel/linux/kni/ethtool/igb/igb.h delete mode 100644 > kernel/linux/kni/ethtool/igb/igb_ethtool.c delete mode 100644 > kernel/linux/kni/ethtool/igb/igb_main.c delete mode 100644 > kernel/linux/kni/ethtool/igb/igb_param.c delete mode 100644 > kernel/linux/kni/ethtool/igb/igb_regtest.h delete mode 100644 > kernel/linux/kni/ethtool/igb/igb_vmdq.c delete mode 100644 > kernel/linux/kni/ethtool/igb/igb_vmdq.h delete mode 100644 > kernel/linux/kni/ethtool/igb/kcompat.h delete mode 100644 > kernel/linux/kni/ethtool/igb/meson.build delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_82598.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_82599.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_api.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_api.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_common.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_common.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_dcb.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_ethtool.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_fcoe.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_main.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_mbx.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_osdep.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_phy.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_type.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/ixgbe_x540.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/kcompat.c delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/kcompat.h delete mode 100644 > kernel/linux/kni/ethtool/ixgbe/meson.build delete mode 100644 > kernel/linux/kni/ethtool/meson.build delete mode 100644 > kernel/linux/kni/kni_ethtool.c diff --git a/config/common_base > b/config/common_base index d12ae98bc..8c1a330e0 100644 --- > a/config/common_base +++ b/config/common_base @@ -890,7 +890,6 @@ > CONFIG_RTE_PIPELINE_STATS_COLLECT=n CONFIG_RTE_LIBRTE_KNI=n > CONFIG_RTE_LIBRTE_PMD_KNI=n CONFIG_RTE_KNI_KMOD=n > -CONFIG_RTE_KNI_KMOD_ETHTOOL=n CONFIG_RTE_KNI_PREEMPT_DEFAULT=y # diff > --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst > b/doc/guides/sample_app_ug/kernel_nic_interface.rst index > 6acdf0fff..2d07ff241 100644 --- > a/doc/guides/sample_app_ug/kernel_nic_interface.rst +++ > b/doc/guides/sample_app_ug/kernel_nic_interface.rst @@ -262,16 +262,6 @@ > Change the MTU size: # ifconfig vEth0_0 mtu 1450 -If DPDK is compiled with > ``CONFIG_RTE_KNI_KMOD_ETHTOOL=y`` and an Intel -NIC is used, the user can > use ``ethtool`` on the KNI interface as if it -were a normal Linux kernel > interface. - -Displaying the NIC registers: - -.. code-block:: console - - > # ethtool -d vEth0_0 - When the ``kni`` application is closed, all the KNI > interfaces are deleted from the Linux kernel. diff --git > a/examples/kni/main.c b/examples/kni/main.c index e37b1ad36..c468ffd19 > 100644 --- a/examples/kni/main.c +++ b/examples/kni/main.c @@ -885,19 > +885,10 @@ kni_alloc(uint16_t port_id) if (i == 0) { struct rte_kni_ops > ops; struct rte_eth_dev_info dev_info; - const struct rte_pci_device > *pci_dev; - const struct rte_bus *bus = NULL; memset(&dev_info, 0, > sizeof(dev_info)); rte_eth_dev_info_get(port_id, &dev_info); - if > (dev_info.device) - bus = rte_bus_find_by_device(dev_info.device); - if > (bus && !strcmp(bus->name, "pci")) { - pci_dev = > RTE_DEV_TO_PCI(dev_info.device); - conf.addr = pci_dev->addr; - conf.id = > pci_dev->id; - } /* Get the interface default mac address */ > rte_eth_macaddr_get(port_id, (struct ether_addr *)&conf.mac_addr); diff > --git a/kernel/linux/kni/Kbuild b/kernel/linux/kni/Kbuild index > de5c27f32..e5452d6c0 100644 --- a/kernel/linux/kni/Kbuild +++ > b/kernel/linux/kni/Kbuild @@ -3,6 +3,4 @@ ccflags-y := $(MODULE_CFLAGS) > obj-m := rte_kni.o -rte_kni-y := $(patsubst $(src)/%.c,%.o,$(wildcard > $(src)/*.c)) \ - $(patsubst $(src)/%.c,%.o,$(wildcard > $(src)/ethtool/ixgbe/*.c)) \ - $(patsubst $(src)/%.c,%.o,$(wildcard > $(src)/ethtool/igb/*.c)) +rte_kni-y := $(patsubst $(src)/%.c,%.o,$(wildcard > $(src)/*.c)) diff --git a/kernel/linux/kni/Makefile > b/kernel/linux/kni/Makefile index 282be7b68..595bac261 100644 --- > a/kernel/linux/kni/Makefile +++ b/kernel/linux/kni/Makefile @@ -12,7 +12,7 > @@ MODULE = rte_kni # CFLAGS # MODULE_CFLAGS += -I$(SRCDIR) --param > max-inline-insns-single=50 -MODULE_CFLAGS += -I$(RTE_OUTPUT)/include > -I$(SRCDIR)/ethtool/ixgbe -I$(SRCDIR)/ethtool/igb +MODULE_CFLAGS += > -I$(RTE_OUTPUT)/include MODULE_CFLAGS += -include > $(RTE_OUTPUT)/include/rte_config.h MODULE_CFLAGS += -Wall -Werror @@ -30,29 > +30,5 @@ endif # SRCS-y := kni_misc.c SRCS-y += kni_net.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += kni_ethtool.c - > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_main.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_api.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_common.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_ethtool.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_82599.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_82598.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_x540.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/ixgbe_phy.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/ixgbe/kcompat.c - > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_82575.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_i210.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_api.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_mac.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_manage.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_mbx.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_nvm.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/e1000_phy.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_ethtool.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_main.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_param.c > -SRCS-$(CONFIG_RTE_KNI_KMOD_ETHTOOL) += ethtool/igb/igb_vmdq.c include > $(RTE_SDK)/mk/rte.module.mk diff --git a/kernel/linux/kni/ethtool/README > b/kernel/linux/kni/ethtool/README deleted file mode 100644 index > af36738ad..000000000 --- a/kernel/linux/kni/ethtool/README +++ /dev/null @@ > -1,71 +0,0 @@ -.. SPDX-License-Identifier: BSD-3-Clause - Copyright(c) > 2010-2014 Intel Corporation. - -Description - -In order to support ethtool > in Kernel NIC Interface, the standard Linux kernel -drivers of ixgbe/igb > are needed to be reused here. ixgbe-3.9.17 is the version -modified from in > kernel NIC interface kernel module to support ixgbe NIC, and -igb-3.4.8 is > the version modified from in kernel NIC interface kernel module to -support > igb NIC. - -The source code package of ixgbe can be downloaded from > sourceforge.net as below. -http://sourceforge.net/projects/e1000/files/ixgbe%20stable/ > -Below > source files are copied or modified from ixgbe. - -ixgbe_82598.h > -ixgbe_82599.c -ixgbe_82599.h -ixgbe_api.c -ixgbe_api.h -ixgbe_common.c > -ixgbe_common.h -ixgbe_dcb.h -ixgbe_ethtool.c -ixgbe_fcoe.h -ixgbe.h > -ixgbe_main.c -ixgbe_mbx.h -ixgbe_osdep.h -ixgbe_phy.c -ixgbe_phy.h > -ixgbe_sriov.h -ixgbe_type.h -kcompat.c -kcompat.h - -The source code > package of igb can be downloaded from sourceforge.net as below. -http://sourceforge.net/projects/e1000/files/igb%20stable/ > -Below > source files are copied or modified from igb. - -e1000_82575.c > -e1000_82575.h -e1000_api.c -e1000_api.h -e1000_defines.h -e1000_hw.h > -e1000_mac.c -e1000_mac.h -e1000_manage.c -e1000_manage.h -e1000_mbx.c > -e1000_mbx.h -e1000_nvm.c -e1000_nvm.h -e1000_osdep.h -e1000_phy.c > -e1000_phy.h -e1000_regs.h -igb_ethtool.c -igb.h -igb_main.c -igb_param.c > -igb_procfs.c -igb_regtest.h -igb_sysfs.c -igb_vmdq.c -igb_vmdq.h > -kcompat.c -kcompat_ethtool.c -kcompat.h - diff --git > a/kernel/linux/kni/ethtool/igb/e1000_82575.c > b/kernel/linux/kni/ethtool/igb/e1000_82575.c deleted file mode 100644 index > 98346709d..000000000 --- a/kernel/linux/kni/ethtool/igb/e1000_82575.c +++ > /dev/null @@ -1,3650 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 > -/******************************************************************************* > - - Intel(R) Gigabit Ethernet Linux driver - Copyright(c) 2007-2013 Intel > Corporation. - - Contact Information: - e1000-devel Mailing List - Intel > Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - > -*******************************************************************************/ > - -/* - * 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_init_hw_82575(struct e1000_hw *hw); -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(u16)) - - -/** - * > 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 > 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->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 configured 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; - } - 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 */ - > 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; - /* turn on/off LED */ - > mac->ops.led_on = e1000_led_on_generic; - mac->ops.led_off = > e1000_led_off_generic; - /* clear hardware counters */ - > mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575; - /* link info */ - > mac->ops.get_link_up_info = e1000_get_link_up_info_82575; - /* get thermal > sensor data */ - mac->ops.get_thermal_sensor_data = - > e1000_get_thermal_sensor_data_generic; - > mac->ops.init_thermal_sensor_thresh = - > e1000_init_thermal_sensor_thresh_generic; - /* acquire SW_FW sync */ - > mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_82575; - > mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575; - if (mac->type > >= e1000_i210) { - mac->ops.acquire_swfw_sync = > e1000_acquire_swfw_sync_i210; - mac->ops.release_swfw_sync = > e1000_release_swfw_sync_i210; - } - - /* set lan id for port to determine > which phy lock to use */ - hw->mac.ops.set_lan_id(hw); - - return > E1000_SUCCESS; -} - -/** - * e1000_init_function_pointers_82575 - Init func > ptrs. - * @hw: pointer to the HW structure - * - * Called to initialize all > function pointers and parameters. - **/ -void > e1000_init_function_pointers_82575(struct e1000_hw *hw) -{ - > DEBUGFUNC("e1000_init_function_pointers_82575"); - - > hw->mac.ops.init_params = e1000_init_mac_params_82575; - > hw->nvm.ops.init_params = e1000_init_nvm_params_82575; - > hw->phy.ops.init_params = e1000_init_phy_params_82575; - > hw->mbx.ops.init_params = e1000_init_mbx_params_pf; -} - -/** - * > e1000_acquire_phy_82575 - Acquire rights to access PHY - * @hw: pointer to > the HW structure - * - * Acquire access rights to the correct PHY. - **/ > -static s32 e1000_acquire_phy_82575(struct e1000_hw *hw) -{ - u16 mask = > E1000_SWFW_PHY0_SM; - - DEBUGFUNC("e1000_acquire_phy_82575"); - - if > (hw->bus.func == E1000_FUNC_1) - mask = E1000_SWFW_PHY1_SM; - else if > (hw->bus.func == E1000_FUNC_2) - mask = E1000_SWFW_PHY2_SM; - else if > (hw->bus.func == E1000_FUNC_3) - mask = E1000_SWFW_PHY3_SM; - - return > hw->mac.ops.acquire_swfw_sync(hw, mask); -} - -/** - * > e1000_release_phy_82575 - Release rights to access PHY - * @hw: pointer to > the HW structure - * - * A wrapper to release access rights to the correct > PHY. - **/ -static void e1000_release_phy_82575(struct e1000_hw *hw) -{ - > u16 mask = E1000_SWFW_PHY0_SM; - - DEBUGFUNC("e1000_release_phy_82575"); - > - if (hw->bus.func == E1000_FUNC_1) - mask = E1000_SWFW_PHY1_SM; - else if > (hw->bus.func == E1000_FUNC_2) - mask = E1000_SWFW_PHY2_SM; - else if > (hw->bus.func == E1000_FUNC_3) - mask = E1000_SWFW_PHY3_SM; - - > hw->mac.ops.release_swfw_sync(hw, mask); -} - -/** - * > e1000_read_phy_reg_sgmii_82575 - Read PHY register using sgmii - * @hw: > pointer to the HW structure - * @offset: register offset to be read - * > @data: pointer to the read data - * - * Reads the PHY register at offset > using the serial gigabit media independent - * interface and stores the > retrieved information in data. - **/ -static s32 > e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, - u16 > *data) -{ - s32 ret_val = -E1000_ERR_PARAM; - - > DEBUGFUNC("e1000_read_phy_reg_sgmii_82575"); - - if (offset > > E1000_MAX_SGMII_PHY_REG_ADDR) { - DEBUGOUT1("PHY Address %u is out of > range\n", offset); - goto out; - } - - ret_val = hw->phy.ops.acquire(hw); - > if (ret_val) - goto out; - - ret_val = e1000_read_phy_reg_i2c(hw, offset, > data); - - hw->phy.ops.release(hw); - -out: - return ret_val; -} - -/** - * > e1000_write_phy_reg_sgmii_82575 - Write PHY register using sgmii - * @hw: > pointer to the HW structure - * @offset: register offset to write to - * > @data: data to write at register offset - * - * Writes the data to PHY > register at the offset using the serial gigabit - * media independent > interface. - **/ -static s32 e1000_write_phy_reg_sgmii_82575(struct > e1000_hw *hw, u32 offset, - u16 data) -{ - s32 ret_val = -E1000_ERR_PARAM; > - - DEBUGFUNC("e1000_write_phy_reg_sgmii_82575"); - - if (offset > > E1000_MAX_SGMII_PHY_REG_ADDR) { - DEBUGOUT1("PHY Address %d is out of > range\n", offset); - goto out; - } - - ret_val = hw->phy.ops.acquire(hw); - > if (ret_val) - goto out; - - ret_val = e1000_write_phy_reg_i2c(hw, offset, > data); - - hw->phy.ops.release(hw); - -out: - return ret_val; -} - -/** - * > e1000_get_phy_id_82575 - Retrieve PHY addr and id - * @hw: pointer to the > HW structure - * - * Retrieves the PHY address and ID for both PHY's which > do and do not use - * sgmi interface. - **/ -static s32 > e1000_get_phy_id_82575(struct e1000_hw *hw) -{ - struct e1000_phy_info *phy > = &hw->phy; - s32 ret_val = E1000_SUCCESS; - u16 phy_id; - u32 ctrl_ext; - > u32 mdic; - - DEBUGFUNC("e1000_get_phy_id_82575"); - - /* i354 devices can > have a PHY that needs an extra read for id */ - if (hw->mac.type == > e1000_i354) - e1000_get_phy_id(hw); - - - /* - * For SGMII PHYs, we try the > list of possible addresses until - * we find one that works. For non-SGMII > PHYs - * (e.g. integrated copper PHYs), an address of 1 should - * work. > The result of this function should mean phy->phy_addr - * and phy->id are > set correctly. - */ - if (!e1000_sgmii_active_82575(hw)) { - phy->addr = 1; > - ret_val = e1000_get_phy_id(hw); - goto out; - } - - if > (e1000_sgmii_uses_mdio_82575(hw)) { - switch (hw->mac.type) { - case > e1000_82575: - case e1000_82576: - mdic = E1000_READ_REG(hw, E1000_MDIC); - > mdic &= E1000_MDIC_PHY_MASK; - phy->addr = mdic >> E1000_MDIC_PHY_SHIFT; - > break; - case e1000_82580: - case e1000_i350: - case e1000_i354: - case > e1000_i210: - case e1000_i211: - mdic = E1000_READ_REG(hw, E1000_MDICNFG); > - mdic &= E1000_MDICNFG_PHY_MASK; - phy->addr = mdic >> > E1000_MDICNFG_PHY_SHIFT; - break; - default: - ret_val = -E1000_ERR_PHY; - > goto out; - break; - } - ret_val = e1000_get_phy_id(hw); - goto out; - } - > - /* Power on sgmii phy if it is disabled */ - ctrl_ext = > E1000_READ_REG(hw, E1000_CTRL_EXT); - E1000_WRITE_REG(hw, E1000_CTRL_EXT, - > ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); - E1000_WRITE_FLUSH(hw); - > msec_delay(300); - - /* - * The address field in the I2CCMD register is 3 > bits and 0 is invalid. - * Therefore, we need to test 1-7 - */ - for > (phy->addr = 1; phy->addr < 8; phy->addr++) { - ret_val = > e1000_read_phy_reg_sgmii_82575(hw, PHY_ID1, &phy_id); - if (ret_val == > E1000_SUCCESS) { - DEBUGOUT2("Vendor ID 0x%08X read at address %u\n", - > phy_id, phy->addr); - /* - * At the time of this writing, The M88 part is - > * the only supported SGMII PHY product. - */ - if (phy_id == M88_VENDOR) - > break; - } else { - DEBUGOUT1("PHY address %u was unreadable\n", - > phy->addr); - } - } - - /* A valid PHY type couldn't be found. */ - if > (phy->addr == 8) { - phy->addr = 0; - ret_val = -E1000_ERR_PHY; - } else { > - ret_val = e1000_get_phy_id(hw); - } - - /* restore previous sfp cage > power state */ - E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); - -out: - > return ret_val; -} - -/** - * e1000_phy_hw_reset_sgmii_82575 - Performs a > PHY reset - * @hw: pointer to the HW structure - * - * Resets the PHY using > the serial gigabit media independent interface. - **/ -static s32 > e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw) -{ - s32 ret_val = > E1000_SUCCESS; - - DEBUGFUNC("e1000_phy_hw_reset_sgmii_82575"); - - /* - * > This isn't a true "hard" reset, but is the only reset - * available to us > at this time. - */ - - DEBUGOUT("Soft resetting SGMII attached PHY...\n"); > - - if (!(hw->phy.ops.write_reg)) - goto out; - - /* - * SFP documentation > requires the following to configure the SPF module - * to work on SGMII. No > further documentation is given. - */ - ret_val = hw->phy.ops.write_reg(hw, > 0x1B, 0x8084); - if (ret_val) - goto out; - - ret_val = > hw->phy.ops.commit(hw); - -out: - return ret_val; -} - -/** - * > e1000_set_d0_lplu_state_82575 - Set Low Power Linkup D0 state - * @hw: > pointer to the HW structure - * @active: true to enable LPLU, false to > disable - * - * Sets the LPLU D0 state according to the active flag. When - > * activating LPLU this function also disables smart speed - * and vice > versa. LPLU will not be activated unless the - * device autonegotiation > advertisement meets standards of - * either 10 or 10/100 or 10/100/1000 at > all duplexes. - * This is a function pointer entry point only called by - * > PHY setup routines. - **/ -static s32 e1000_set_d0_lplu_state_82575(struct > e1000_hw *hw, bool active) -{ - struct e1000_phy_info *phy = &hw->phy; - > s32 ret_val = E1000_SUCCESS; - u16 data; - - > DEBUGFUNC("e1000_set_d0_lplu_state_82575"); - - if > (!(hw->phy.ops.read_reg)) - goto out; - - ret_val = phy->ops.read_reg(hw, > IGP02E1000_PHY_POWER_MGMT, &data); - if (ret_val) - goto out; - - if > (active) { - data |= IGP02E1000_PM_D0_LPLU; - ret_val = > phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, - data); - if (ret_val) - > goto out; - - /* When LPLU is enabled, we should disable SmartSpeed */ - > ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &data); - > data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = phy->ops.write_reg(hw, > IGP01E1000_PHY_PORT_CONFIG, - data); - if (ret_val) - goto out; - } else { > - data &= ~IGP02E1000_PM_D0_LPLU; - ret_val = phy->ops.write_reg(hw, > IGP02E1000_PHY_POWER_MGMT, - data); - /* - * LPLU and SmartSpeed are > mutually exclusive. LPLU is used - * during Dx states where the power > conservation is most - * important. During driver activity we should enable > - * SmartSpeed, so performance is maintained. - */ - if (phy->smart_speed > == e1000_smart_speed_on) { - ret_val = phy->ops.read_reg(hw, - > IGP01E1000_PHY_PORT_CONFIG, - &data); - if (ret_val) - goto out; - - data > |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = phy->ops.write_reg(hw, - > IGP01E1000_PHY_PORT_CONFIG, - data); - if (ret_val) - goto out; - } else if > (phy->smart_speed == e1000_smart_speed_off) { - ret_val = > phy->ops.read_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); - if > (ret_val) - goto out; - - data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val > = phy->ops.write_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); - if > (ret_val) - goto out; - } - } - -out: - return ret_val; -} - -/** - * > e1000_set_d0_lplu_state_82580 - Set Low Power Linkup D0 state - * @hw: > pointer to the HW structure - * @active: true to enable LPLU, false to > disable - * - * Sets the LPLU D0 state according to the active flag. When - > * activating LPLU this function also disables smart speed - * and vice > versa. LPLU will not be activated unless the - * device autonegotiation > advertisement meets standards of - * either 10 or 10/100 or 10/100/1000 at > all duplexes. - * This is a function pointer entry point only called by - * > PHY setup routines. - **/ -static s32 e1000_set_d0_lplu_state_82580(struct > e1000_hw *hw, bool active) -{ - struct e1000_phy_info *phy = &hw->phy; - > s32 ret_val = E1000_SUCCESS; - u32 data; - - > DEBUGFUNC("e1000_set_d0_lplu_state_82580"); - - data = E1000_READ_REG(hw, > E1000_82580_PHY_POWER_MGMT); - - if (active) { - data |= > E1000_82580_PM_D0_LPLU; - - /* When LPLU is enabled, we should disable > SmartSpeed */ - data &= ~E1000_82580_PM_SPD; - } else { - data &= > ~E1000_82580_PM_D0_LPLU; - - /* - * LPLU and SmartSpeed are mutually > exclusive. LPLU is used - * during Dx states where the power conservation > is most - * important. During driver activity we should enable - * > SmartSpeed, so performance is maintained. - */ - if (phy->smart_speed == > e1000_smart_speed_on) - data |= E1000_82580_PM_SPD; - else if > (phy->smart_speed == e1000_smart_speed_off) - data &= ~E1000_82580_PM_SPD; > - } - - E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, data); - return > ret_val; -} - -/** - * e1000_set_d3_lplu_state_82580 - Sets low power link > up state for D3 - * @hw: pointer to the HW structure - * @active: boolean > used to enable/disable lplu - * - * Success returns 0, Failure returns 1 - > * - * The low power link up (lplu) state is set to the power management > level D3 - * and SmartSpeed is disabled when active is true, else clear > lplu for D3 - * and enable Smartspeed. LPLU and Smartspeed are mutually > exclusive. LPLU - * is used during Dx states where the power conservation > is most important. - * During driver activity, SmartSpeed should be enabled > so performance is - * maintained. - **/ -s32 > e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active) -{ - struct > e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; - u32 data; > - - DEBUGFUNC("e1000_set_d3_lplu_state_82580"); - - data = > E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT); - - if (!active) { - data > &= ~E1000_82580_PM_D3_LPLU; - /* - * LPLU and SmartSpeed are mutually > exclusive. LPLU is used - * during Dx states where the power conservation > is most - * important. During driver activity we should enable - * > SmartSpeed, so performance is maintained. - */ - if (phy->smart_speed == > e1000_smart_speed_on) - data |= E1000_82580_PM_SPD; - else if > (phy->smart_speed == e1000_smart_speed_off) - data &= ~E1000_82580_PM_SPD; > - } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || - > (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || - > (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { - data |= > E1000_82580_PM_D3_LPLU; - /* When LPLU is enabled, we should disable > SmartSpeed */ - data &= ~E1000_82580_PM_SPD; - } - - E1000_WRITE_REG(hw, > E1000_82580_PHY_POWER_MGMT, data); - return ret_val; -} - -/** - * > e1000_acquire_nvm_82575 - Request for access to EEPROM - * @hw: pointer to > the HW structure - * - * Acquire the necessary semaphores for exclusive > access to the EEPROM. - * Set the EEPROM access request bit and wait for > EEPROM access grant bit. - * Return successful if access grant bit set, > else clear the request for - * EEPROM access and return -E1000_ERR_NVM > (-1). - **/ -static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw) -{ - > s32 ret_val; - - DEBUGFUNC("e1000_acquire_nvm_82575"); - - ret_val = > e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); - if (ret_val) - goto > out; - - /* - * Check if there is some access - * error this access may > hook on - */ - if (hw->mac.type == e1000_i350) { - u32 eecd = > E1000_READ_REG(hw, E1000_EECD); - if (eecd & (E1000_EECD_BLOCKED | > E1000_EECD_ABORT | - E1000_EECD_TIMEOUT)) { - /* Clear all access error > flags */ - E1000_WRITE_REG(hw, E1000_EECD, eecd | - E1000_EECD_ERROR_CLR); > - DEBUGOUT("Nvm bit banging access error detected and cleared.\n"); - } - } > - if (hw->mac.type == e1000_82580) { - u32 eecd = E1000_READ_REG(hw, > E1000_EECD); - if (eecd & E1000_EECD_BLOCKED) { - /* Clear access error > flag */ - E1000_WRITE_REG(hw, E1000_EECD, eecd | - E1000_EECD_BLOCKED); - > DEBUGOUT("Nvm bit banging access error detected and cleared.\n"); - } - } - > - - ret_val = e1000_acquire_nvm_generic(hw); - if (ret_val) - > e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); - -out: - return > ret_val; -} - -/** - * e1000_release_nvm_82575 - Release exclusive access > to EEPROM - * @hw: pointer to the HW structure - * - * Stop any current > commands to the EEPROM and clear the EEPROM request bit, - * then release > the semaphores acquired. - **/ -static void e1000_release_nvm_82575(struct > e1000_hw *hw) -{ - DEBUGFUNC("e1000_release_nvm_82575"); - - > e1000_release_nvm_generic(hw); - - e1000_release_swfw_sync_82575(hw, > E1000_SWFW_EEP_SM); -} - -/** - * e1000_acquire_swfw_sync_82575 - Acquire > SW/FW semaphore - * @hw: pointer to the HW structure - * @mask: specifies > which semaphore to acquire - * - * Acquire the SW/FW semaphore to access > the PHY or NVM. The mask - * will also specify which port we're acquiring > the lock for. - **/ -static s32 e1000_acquire_swfw_sync_82575(struct > e1000_hw *hw, u16 mask) -{ - u32 swfw_sync; - u32 swmask = mask; - u32 > fwmask = mask << 16; - s32 ret_val = E1000_SUCCESS; - s32 i = 0, timeout = > 200; /* FIXME: find real value to use here */ - - > DEBUGFUNC("e1000_acquire_swfw_sync_82575"); - - while (i < timeout) { - if > (e1000_get_hw_semaphore_generic(hw)) { - ret_val = -E1000_ERR_SWFW_SYNC; - > goto out; - } - - swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); - if > (!(swfw_sync & (fwmask | swmask))) - break; - - /* - * Firmware currently > using resource (fwmask) - * or other software thread using resource > (swmask) - */ - e1000_put_hw_semaphore_generic(hw); - msec_delay_irq(5); - > i++; - } - - if (i == timeout) { - DEBUGOUT("Driver can't access resource, > SW_FW_SYNC timeout.\n"); - ret_val = -E1000_ERR_SWFW_SYNC; - goto out; - } > - - swfw_sync |= swmask; - E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, > swfw_sync); - - e1000_put_hw_semaphore_generic(hw); - -out: - return > ret_val; -} - -/** - * e1000_release_swfw_sync_82575 - Release SW/FW > semaphore - * @hw: pointer to the HW structure - * @mask: specifies which > semaphore to acquire - * - * Release the SW/FW semaphore used to access the > PHY or NVM. The mask - * will also specify which port we're releasing the > lock for. - **/ -static void e1000_release_swfw_sync_82575(struct e1000_hw > *hw, u16 mask) -{ - u32 swfw_sync; - - > DEBUGFUNC("e1000_release_swfw_sync_82575"); - - while > (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS) - ; /* Empty */ - - > swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); - swfw_sync &= ~mask; - > E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); - - > e1000_put_hw_semaphore_generic(hw); -} - -/** - * e1000_get_cfg_done_82575 > - Read config done bit - * @hw: pointer to the HW structure - * - * Read > the management control register for the config done bit for - * completion > status. NOTE: silicon which is EEPROM-less will fail trying - * to read the > config done bit, so an error is *ONLY* logged and returns - * > E1000_SUCCESS. If we were to return with error, EEPROM-less silicon - * > would not be able to be reset or change link. - **/ -static s32 > e1000_get_cfg_done_82575(struct e1000_hw *hw) -{ - s32 timeout = > PHY_CFG_TIMEOUT; - s32 ret_val = E1000_SUCCESS; - u32 mask = > E1000_NVM_CFG_DONE_PORT_0; - - DEBUGFUNC("e1000_get_cfg_done_82575"); - - > if (hw->bus.func == E1000_FUNC_1) - mask = E1000_NVM_CFG_DONE_PORT_1; - > else if (hw->bus.func == E1000_FUNC_2) - mask = E1000_NVM_CFG_DONE_PORT_2; > - else if (hw->bus.func == E1000_FUNC_3) - mask = > E1000_NVM_CFG_DONE_PORT_3; - while (timeout) { - if (E1000_READ_REG(hw, > E1000_EEMNGCTL) & mask) - break; - msec_delay(1); - timeout--; - } - if > (!timeout) - DEBUGOUT("MNG configuration cycle has not completed.\n"); - - > /* If EEPROM is not marked present, init the PHY manually */ - if > (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) && - (hw->phy.type == > e1000_phy_igp_3)) - e1000_phy_init_script_igp3(hw); - - return ret_val; -} > - -/** - * e1000_get_link_up_info_82575 - Get link speed/duplex info - * > @hw: pointer to the HW structure - * @speed: stores the current speed - * > @duplex: stores the current duplex - * - * This is a wrapper function, if > using the serial gigabit media independent - * interface, use PCS to > retrieve the link speed and duplex information. - * Otherwise, use the > generic function to get the link speed and duplex info. - **/ -static s32 > e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, - u16 > *duplex) -{ - s32 ret_val; - - DEBUGFUNC("e1000_get_link_up_info_82575"); - > - if (hw->phy.media_type != e1000_media_type_copper) - ret_val = > e1000_get_pcs_speed_and_duplex_82575(hw, speed, - duplex); - else - ret_val > = e1000_get_speed_and_duplex_copper_generic(hw, speed, - duplex); - - > return ret_val; -} - -/** - * e1000_check_for_link_82575 - Check for link - > * @hw: pointer to the HW structure - * - * If sgmii is enabled, then use > the pcs register to determine link, otherwise - * use the generic interface > for determining link. - **/ -static s32 e1000_check_for_link_82575(struct > e1000_hw *hw) -{ - s32 ret_val; - u16 speed, duplex; - - > DEBUGFUNC("e1000_check_for_link_82575"); - - if (hw->phy.media_type != > e1000_media_type_copper) { - ret_val = > e1000_get_pcs_speed_and_duplex_82575(hw, &speed, - &duplex); - /* - * Use > this flag to determine if link needs to be checked or - * not. If we have > link clear the flag so that we do not - * continue to check for link. - */ > - hw->mac.get_link_status = !hw->mac.serdes_has_link; - - /* - * Configure > Flow Control now that Auto-Neg has completed. - * First, we need to restore > the desired flow control - * settings because we may have had to re-autoneg > with a - * different link partner. - */ - ret_val = > e1000_config_fc_after_link_up_generic(hw); - if (ret_val) - DEBUGOUT("Error > configuring flow control\n"); - } else { - ret_val = > e1000_check_for_copper_link_generic(hw); - } - - return ret_val; -} - -/** > - * e1000_check_for_link_media_swap - Check which M88E1112 interface linked > - * @hw: pointer to the HW structure - * - * Poll the M88E1112 interfaces > to see which interface achieved link. - */ -static s32 > e1000_check_for_link_media_swap(struct e1000_hw *hw) -{ - struct > e1000_phy_info *phy = &hw->phy; - s32 ret_val; - u16 data; - u8 port = 0; - > - DEBUGFUNC("e1000_check_for_link_media_swap"); - - /* Check the copper > medium. */ - ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 0); > - if (ret_val) - return ret_val; - - ret_val = phy->ops.read_reg(hw, > E1000_M88E1112_STATUS, &data); - if (ret_val) - return ret_val; - - if > (data & E1000_M88E1112_STATUS_LINK) - port = E1000_MEDIA_PORT_COPPER; - - > /* Check the other medium. */ - ret_val = phy->ops.write_reg(hw, > E1000_M88E1112_PAGE_ADDR, 1); - if (ret_val) - return ret_val; - - ret_val > = phy->ops.read_reg(hw, E1000_M88E1112_STATUS, &data); - if (ret_val) - > return ret_val; - - if (data & E1000_M88E1112_STATUS_LINK) - port = > E1000_MEDIA_PORT_OTHER; - - /* Determine if a swap needs to happen. */ - if > (port && (hw->dev_spec._82575.media_port != port)) { - > hw->dev_spec._82575.media_port = port; - hw->dev_spec._82575.media_changed > = true; - } else { - ret_val = e1000_check_for_link_82575(hw); - } - - > return E1000_SUCCESS; -} - -/** - * e1000_power_up_serdes_link_82575 - > Power up the serdes link after shutdown - * @hw: pointer to the HW > structure - **/ -static void e1000_power_up_serdes_link_82575(struct > e1000_hw *hw) -{ - u32 reg; - - > DEBUGFUNC("e1000_power_up_serdes_link_82575"); - - if ((hw->phy.media_type > != e1000_media_type_internal_serdes) && - !e1000_sgmii_active_82575(hw)) - > return; - - /* Enable PCS to turn on link */ - reg = E1000_READ_REG(hw, > E1000_PCS_CFG0); - reg |= E1000_PCS_CFG_PCS_EN; - E1000_WRITE_REG(hw, > E1000_PCS_CFG0, reg); - - /* Power up the laser */ - reg = > E1000_READ_REG(hw, E1000_CTRL_EXT); - reg &= ~E1000_CTRL_EXT_SDP3_DATA; - > E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); - - /* flush the write to verify > completion */ - E1000_WRITE_FLUSH(hw); - msec_delay(1); -} - -/** - * > e1000_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex - * > @hw: pointer to the HW structure - * @speed: stores the current speed - * > @duplex: stores the current duplex - * - * Using the physical coding > sub-layer (PCS), retrieve the current speed and - * duplex, then store the > values in the pointers provided. - **/ -static s32 > e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, - u16 *speed, u16 > *duplex) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 pcs; - u32 > status; - - DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575"); - - /* - * > Read the PCS Status register for link state. For non-copper mode, - * the > status register is not accurate. The PCS status register is - * used > instead. - */ - pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT); - - /* - * The > link up bit determines when link is up on autoneg. - */ - if (pcs & > E1000_PCS_LSTS_LINK_OK) { - mac->serdes_has_link = true; - - /* Detect and > store PCS speed */ - if (pcs & E1000_PCS_LSTS_SPEED_1000) - *speed = > SPEED_1000; - else if (pcs & E1000_PCS_LSTS_SPEED_100) - *speed = > SPEED_100; - else - *speed = SPEED_10; - - /* Detect and store PCS duplex > */ - if (pcs & E1000_PCS_LSTS_DUPLEX_FULL) - *duplex = FULL_DUPLEX; - else > - *duplex = HALF_DUPLEX; - - /* Check if it is an I354 2.5Gb backplane > connection. */ - if (mac->type == e1000_i354) { - status = > E1000_READ_REG(hw, E1000_STATUS); - if ((status & E1000_STATUS_2P5_SKU) && > - !(status & E1000_STATUS_2P5_SKU_OVER)) { - *speed = SPEED_2500; - *duplex > = FULL_DUPLEX; - DEBUGOUT("2500 Mbs, "); - DEBUGOUT("Full Duplex\n"); - } - > } - - } else { - mac->serdes_has_link = false; - *speed = 0; - *duplex = 0; > - } - - return E1000_SUCCESS; -} - -/** - * > e1000_shutdown_serdes_link_82575 - Remove link during power down - * @hw: > pointer to the HW structure - * - * In the case of serdes shut down sfp and > PCS on driver unload - * when management pass through is not enabled. - **/ > -void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw) -{ - u32 reg; - > - DEBUGFUNC("e1000_shutdown_serdes_link_82575"); - - if > ((hw->phy.media_type != e1000_media_type_internal_serdes) && - > !e1000_sgmii_active_82575(hw)) - return; - - if > (!e1000_enable_mng_pass_thru(hw)) { - /* Disable PCS to turn off link */ - > reg = E1000_READ_REG(hw, E1000_PCS_CFG0); - reg &= ~E1000_PCS_CFG_PCS_EN; - > E1000_WRITE_REG(hw, E1000_PCS_CFG0, reg); - - /* shutdown the laser */ - > reg = E1000_READ_REG(hw, E1000_CTRL_EXT); - reg |= > E1000_CTRL_EXT_SDP3_DATA; - E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); - - > /* flush the write to verify completion */ - E1000_WRITE_FLUSH(hw); - > msec_delay(1); - } - - return; -} - -/** - * e1000_reset_hw_82575 - Reset > hardware - * @hw: pointer to the HW structure - * - * This resets the > hardware into a known state. - **/ -static s32 e1000_reset_hw_82575(struct > e1000_hw *hw) -{ - u32 ctrl; - s32 ret_val; - - > DEBUGFUNC("e1000_reset_hw_82575"); - - /* - * Prevent the PCI-E bus from > sticking if there is no TLP connection - * on the last TLP read/write > transaction when MAC is reset. - */ - ret_val = > e1000_disable_pcie_master_generic(hw); - if (ret_val) - DEBUGOUT("PCI-E > Master disable polling has failed.\n"); - - /* set the completion timeout > for interface */ - ret_val = e1000_set_pcie_completion_timeout(hw); - if > (ret_val) - DEBUGOUT("PCI-E Set completion timeout has failed.\n"); - - > DEBUGOUT("Masking off all interrupts\n"); - E1000_WRITE_REG(hw, E1000_IMC, > 0xffffffff); - - E1000_WRITE_REG(hw, E1000_RCTL, 0); - E1000_WRITE_REG(hw, > E1000_TCTL, E1000_TCTL_PSP); - E1000_WRITE_FLUSH(hw); - - msec_delay(10); - > - ctrl = E1000_READ_REG(hw, E1000_CTRL); - - DEBUGOUT("Issuing a global > reset to MAC\n"); - E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); > - - ret_val = e1000_get_auto_rd_done_generic(hw); - if (ret_val) { - /* - * > When auto config read does not complete, do not - * return with an error. > This can happen in situations - * where there is no eeprom and prevents > getting link. - */ - DEBUGOUT("Auto Read Done did not complete\n"); - } - - > /* If EEPROM is not present, run manual init scripts */ - if > (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES)) - > e1000_reset_init_script_82575(hw); - - /* Clear any pending interrupt > events. */ - E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); - > E1000_READ_REG(hw, E1000_ICR); - - /* Install any alternate MAC address > into RAR0 */ - ret_val = e1000_check_alt_mac_addr_generic(hw); - - return > ret_val; -} - -/** - * e1000_init_hw_82575 - Initialize hardware - * @hw: > pointer to the HW structure - * - * This inits the hardware readying it for > operation. - **/ -static s32 e1000_init_hw_82575(struct e1000_hw *hw) -{ - > struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - u16 i, rar_count = > mac->rar_entry_count; - - DEBUGFUNC("e1000_init_hw_82575"); - - /* > Initialize identification LED */ - ret_val = mac->ops.id_led_init(hw); - if > (ret_val) { - DEBUGOUT("Error initializing identification LED\n"); - /* > This is not fatal and we should not stop init due to this */ - } - - /* > Disabling VLAN filtering */ - DEBUGOUT("Initializing the IEEE VLAN\n"); - > mac->ops.clear_vfta(hw); - - /* Setup the receive address */ - > e1000_init_rx_addrs_generic(hw, rar_count); - - /* Zero out the Multicast > HASH table */ - DEBUGOUT("Zeroing the MTA\n"); - for (i = 0; i < > mac->mta_reg_count; i++) - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); - - > /* Zero out the Unicast HASH table */ - DEBUGOUT("Zeroing the UTA\n"); - > for (i = 0; i < mac->uta_reg_count; i++) - E1000_WRITE_REG_ARRAY(hw, > E1000_UTA, i, 0); - - /* Setup link and flow control */ - ret_val = > mac->ops.setup_link(hw); - - /* Set the default MTU size */ - > hw->dev_spec._82575.mtu = 1500; - - /* - * Clear all of the statistics > registers (clear on read). It is - * important that we do this after we > have tried to establish link - * because the symbol error count will > increment wildly if there - * is no link. - */ - > e1000_clear_hw_cntrs_82575(hw); - - return ret_val; -} - -/** - * > e1000_setup_copper_link_82575 - Configure copper link settings - * @hw: > pointer to the HW structure - * - * Configures the link for auto-neg or > forced speed and duplex. Then we check - * for link, once link is > established calls to configure collision distance - * and flow control are > called. - **/ -static s32 e1000_setup_copper_link_82575(struct e1000_hw > *hw) -{ - u32 ctrl; - s32 ret_val; - u32 phpm_reg; - - > DEBUGFUNC("e1000_setup_copper_link_82575"); - - ctrl = E1000_READ_REG(hw, > E1000_CTRL); - ctrl |= E1000_CTRL_SLU; - ctrl &= ~(E1000_CTRL_FRCSPD | > E1000_CTRL_FRCDPX); - E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - - /* Clear > Go Link Disconnect bit on supported devices */ - switch (hw->mac.type) { - > case e1000_82580: - case e1000_i350: - case e1000_i210: - case e1000_i211: > - phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT); - phpm_reg &= > ~E1000_82580_PM_GO_LINKD; - E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, > phpm_reg); - break; - default: - break; - } - - ret_val = > e1000_setup_serdes_link_82575(hw); - if (ret_val) - goto out; - - if > (e1000_sgmii_active_82575(hw) && !hw->phy.reset_disable) { - /* allow time > for SFP cage time to power up phy */ - msec_delay(300); - - ret_val = > hw->phy.ops.reset(hw); - if (ret_val) { - DEBUGOUT("Error resetting the > PHY.\n"); - goto out; - } - } - switch (hw->phy.type) { - case > e1000_phy_i210: - case e1000_phy_m88: - switch (hw->phy.id) { - case > I347AT4_E_PHY_ID: - case M88E1112_E_PHY_ID: - case M88E1340M_E_PHY_ID: - > case M88E1543_E_PHY_ID: - case I210_I_PHY_ID: - ret_val = > e1000_copper_link_setup_m88_gen2(hw); - break; - default: - ret_val = > e1000_copper_link_setup_m88(hw); - break; - } - break; - case > e1000_phy_igp_3: - ret_val = e1000_copper_link_setup_igp(hw); - break; - > case e1000_phy_82580: - ret_val = e1000_copper_link_setup_82577(hw); - > break; - default: - ret_val = -E1000_ERR_PHY; - break; - } - - if (ret_val) > - goto out; - - ret_val = e1000_setup_copper_link_generic(hw); -out: - > return ret_val; -} - -/** - * e1000_setup_serdes_link_82575 - Setup link > for serdes - * @hw: pointer to the HW structure - * - * Configure the > physical coding sub-layer (PCS) link. The PCS link is - * used on copper > connections where the serialized gigabit media independent - * interface > (sgmii), or serdes fiber is being used. Configures the link - * for > auto-negotiation or forces speed/duplex. - **/ -static s32 > e1000_setup_serdes_link_82575(struct e1000_hw *hw) -{ - u32 ctrl_ext, > ctrl_reg, reg, anadv_reg; - bool pcs_autoneg; - s32 ret_val = > E1000_SUCCESS; - u16 data; - - DEBUGFUNC("e1000_setup_serdes_link_82575"); > - - if ((hw->phy.media_type != e1000_media_type_internal_serdes) && - > !e1000_sgmii_active_82575(hw)) - return ret_val; - - /* - * On the 82575, > SerDes loopback mode persists until it is - * explicitly turned off or a > power cycle is performed. A read to - * the register does not indicate its > status. Therefore, we ensure - * loopback mode is disabled during > initialization. - */ - E1000_WRITE_REG(hw, E1000_SCTL, > E1000_SCTL_DISABLE_SERDES_LOOPBACK); - - /* power on the sfp cage if > present */ - ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); - ctrl_ext &= > ~E1000_CTRL_EXT_SDP3_DATA; - E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); > - - ctrl_reg = E1000_READ_REG(hw, E1000_CTRL); - ctrl_reg |= > E1000_CTRL_SLU; - - /* set both sw defined pins on 82575/82576*/ - if > (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) - ctrl_reg |= > E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1; - - reg = E1000_READ_REG(hw, > E1000_PCS_LCTL); - - /* default pcs_autoneg to the same setting as mac > autoneg */ - pcs_autoneg = hw->mac.autoneg; - - switch (ctrl_ext & > E1000_CTRL_EXT_LINK_MODE_MASK) { - case E1000_CTRL_EXT_LINK_MODE_SGMII: - > /* sgmii mode lets the phy handle forcing speed/duplex */ - pcs_autoneg = > true; - /* autoneg time out should be disabled for SGMII mode */ - reg &= > ~(E1000_PCS_LCTL_AN_TIMEOUT); - break; - case > E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: - /* disable PCS autoneg and support > parallel detect only */ - pcs_autoneg = false; - /* fall through to default > case */ - default: - if (hw->mac.type == e1000_82575 || - hw->mac.type == > e1000_82576) { - ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data); - if > (ret_val) { - DEBUGOUT("NVM Read Error\n"); - return ret_val; - } - - if > (data & E1000_EEPROM_PCS_AUTONEG_DISABLE_BIT) - pcs_autoneg = false; - } - > - /* - * non-SGMII modes only supports a speed of 1000/Full for the - * > link so it is best to just force the MAC and let the pcs - * link either > autoneg or be forced to 1000/Full - */ - ctrl_reg |= E1000_CTRL_SPD_1000 | > E1000_CTRL_FRCSPD | - E1000_CTRL_FD | E1000_CTRL_FRCDPX; - - /* set speed > of 1000/Full if speed/duplex is forced */ - reg |= E1000_PCS_LCTL_FSV_1000 > | E1000_PCS_LCTL_FDV_FULL; - break; - } - - E1000_WRITE_REG(hw, E1000_CTRL, > ctrl_reg); - - /* - * New SerDes mode allows for forcing speed or > autonegotiating speed - * at 1gb. Autoneg should be default set by most > drivers. This is the - * mode that will be compatible with older link > partners and switches. - * However, both are supported by the hardware and > some drivers/tools. - */ - reg &= ~(E1000_PCS_LCTL_AN_ENABLE | > E1000_PCS_LCTL_FLV_LINK_UP | - E1000_PCS_LCTL_FSD | > E1000_PCS_LCTL_FORCE_LINK); - - if (pcs_autoneg) { - /* Set PCS register > for autoneg */ - reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */ - > E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */ - - /* Disable force flow > control for autoneg */ - reg &= ~E1000_PCS_LCTL_FORCE_FCTRL; - - /* > Configure flow control advertisement for autoneg */ - anadv_reg = > E1000_READ_REG(hw, E1000_PCS_ANADV); - anadv_reg &= ~(E1000_TXCW_ASM_DIR | > E1000_TXCW_PAUSE); - - switch (hw->fc.requested_mode) { - case > e1000_fc_full: - case e1000_fc_rx_pause: - anadv_reg |= E1000_TXCW_ASM_DIR; > - anadv_reg |= E1000_TXCW_PAUSE; - break; - case e1000_fc_tx_pause: - > anadv_reg |= E1000_TXCW_ASM_DIR; - break; - default: - break; - } - - > E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg); - - DEBUGOUT1("Configuring > Autoneg:PCS_LCTL=0x%08X\n", reg); - } else { - /* Set PCS register for > forced link */ - reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ - - /* Force > flow control for forced link */ - reg |= E1000_PCS_LCTL_FORCE_FCTRL; - - > DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); - } - - > E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg); - - if (!pcs_autoneg && > !e1000_sgmii_active_82575(hw)) - e1000_force_mac_fc_generic(hw); - - return > ret_val; -} - -/** - * e1000_get_media_type_82575 - derives current media > type. - * @hw: pointer to the HW structure - * - * The media type is chosen > reflecting few settings. - * The following are taken into account: - * - > link mode set in the current port Init Control Word #3 - * - current link > mode settings in CSR register - * - MDIO vs. I2C PHY control interface > chosen - * - SFP module media type - **/ -static s32 > e1000_get_media_type_82575(struct e1000_hw *hw) -{ - struct > e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; - s32 ret_val = > E1000_SUCCESS; - u32 ctrl_ext = 0; - u32 link_mode = 0; - - /* Set internal > phy as default */ - dev_spec->sgmii_active = false; - > dev_spec->module_plugged = false; - - /* Get CSR setting */ - ctrl_ext = > E1000_READ_REG(hw, E1000_CTRL_EXT); - - /* extract link mode setting */ - > link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK; - - switch > (link_mode) { - case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: - > hw->phy.media_type = e1000_media_type_internal_serdes; - break; - case > E1000_CTRL_EXT_LINK_MODE_GMII: - hw->phy.media_type = > e1000_media_type_copper; - break; - case E1000_CTRL_EXT_LINK_MODE_SGMII: - > /* Get phy control interface type set (MDIO vs. I2C)*/ - if > (e1000_sgmii_uses_mdio_82575(hw)) { - hw->phy.media_type = > e1000_media_type_copper; - dev_spec->sgmii_active = true; - break; - } - /* > fall through for I2C based SGMII */ - case > E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES: - /* read media type from SFP EEPROM > */ - ret_val = e1000_set_sfp_media_type_82575(hw); - if ((ret_val != > E1000_SUCCESS) || - (hw->phy.media_type == e1000_media_type_unknown)) { - > /* - * If media type was not identified then return media - * type defined > by the CTRL_EXT settings. - */ - hw->phy.media_type = > e1000_media_type_internal_serdes; - - if (link_mode == > E1000_CTRL_EXT_LINK_MODE_SGMII) { - hw->phy.media_type = > e1000_media_type_copper; - dev_spec->sgmii_active = true; - } - - break; - > } - - /* do not change link mode for 100BaseFX */ - if > (dev_spec->eth_flags.e100_base_fx) - break; - - /* change current link mode > setting */ - ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK; - - if > (hw->phy.media_type == e1000_media_type_copper) - ctrl_ext |= > E1000_CTRL_EXT_LINK_MODE_SGMII; - else - ctrl_ext |= > E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; - - E1000_WRITE_REG(hw, > E1000_CTRL_EXT, ctrl_ext); - - break; - } - - return ret_val; -} - -/** - * > e1000_set_sfp_media_type_82575 - derives SFP module media type. - * @hw: > pointer to the HW structure - * - * The media type is chosen based on SFP > module. - * compatibility flags retrieved from SFP ID EEPROM. - **/ -static > s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw) -{ - s32 ret_val = > E1000_ERR_CONFIG; - u32 ctrl_ext = 0; - struct e1000_dev_spec_82575 > *dev_spec = &hw->dev_spec._82575; - struct sfp_e1000_flags *eth_flags = > &dev_spec->eth_flags; - u8 tranceiver_type = 0; - s32 timeout = 3; - - /* > Turn I2C interface ON and power on sfp cage */ - ctrl_ext = > E1000_READ_REG(hw, E1000_CTRL_EXT); - ctrl_ext &= > ~E1000_CTRL_EXT_SDP3_DATA; - E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | > E1000_CTRL_I2C_ENA); - - E1000_WRITE_FLUSH(hw); - - /* Read SFP module data > */ - while (timeout) { - ret_val = e1000_read_sfp_data_byte(hw, - > E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET), - > &tranceiver_type); - if (ret_val == E1000_SUCCESS) - break; - > msec_delay(100); - timeout--; - } - if (ret_val != E1000_SUCCESS) - goto > out; - - ret_val = e1000_read_sfp_data_byte(hw, - > E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET), - (u8 *)eth_flags); > - if (ret_val != E1000_SUCCESS) - goto out; - - /* Check if there is some > SFP module plugged and powered */ - if ((tranceiver_type == > E1000_SFF_IDENTIFIER_SFP) || - (tranceiver_type == > E1000_SFF_IDENTIFIER_SFF)) { - dev_spec->module_plugged = true; - if > (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) { - > hw->phy.media_type = e1000_media_type_internal_serdes; - } else if > (eth_flags->e100_base_fx) { - dev_spec->sgmii_active = true; - > hw->phy.media_type = e1000_media_type_internal_serdes; - } else if > (eth_flags->e1000_base_t) { - dev_spec->sgmii_active = true; - > hw->phy.media_type = e1000_media_type_copper; - } else { - > hw->phy.media_type = e1000_media_type_unknown; - DEBUGOUT("PHY module has > not been recognized\n"); - goto out; - } - } else { - hw->phy.media_type = > e1000_media_type_unknown; - } - ret_val = E1000_SUCCESS; -out: - /* Restore > I2C interface setting */ - E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); - > return ret_val; -} - -/** - * e1000_valid_led_default_82575 - Verify a > valid default LED config - * @hw: pointer to the HW structure - * @data: > pointer to the NVM (EEPROM) - * - * Read the EEPROM for the current default > LED configuration. If the - * LED configuration is not valid, set to a > valid LED configuration. - **/ -static s32 > e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data) -{ - s32 > ret_val; - - DEBUGFUNC("e1000_valid_led_default_82575"); - - ret_val = > hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); - if (ret_val) { - > DEBUGOUT("NVM Read Error\n"); - goto out; - } - - if (*data == > ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) { - switch > (hw->phy.media_type) { - case e1000_media_type_internal_serdes: - *data = > ID_LED_DEFAULT_82575_SERDES; - break; - case e1000_media_type_copper: - > default: - *data = ID_LED_DEFAULT; - break; - } - } -out: - return ret_val; > -} - -/** - * e1000_sgmii_active_82575 - Return sgmii state - * @hw: > pointer to the HW structure - * - * 82575 silicon has a serialized gigabit > media independent interface (sgmii) - * which can be enabled for use in the > embedded applications. Simply - * return the current state of the sgmii > interface. - **/ -static bool e1000_sgmii_active_82575(struct e1000_hw *hw) > -{ - struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; - return > dev_spec->sgmii_active; -} - -/** - * e1000_reset_init_script_82575 - Inits > HW defaults after reset - * @hw: pointer to the HW structure - * - * Inits > recommended HW defaults after a reset when there is no EEPROM - * detected. > This is only for the 82575. - **/ -static s32 > e1000_reset_init_script_82575(struct e1000_hw *hw) -{ - > DEBUGFUNC("e1000_reset_init_script_82575"); - - if (hw->mac.type == > e1000_82575) { - DEBUGOUT("Running reset init script for 82575\n"); - /* > SerDes configuration via SERDESCTRL */ - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x00, 0x0C); - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x01, 0x78); - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x1B, 0x23); - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCTL, 0x23, 0x15); - - /* CCM > configuration via CCMCTL register */ - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x14, 0x00); - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_CCMCTL, 0x10, 0x00); - - /* > PCIe lanes configuration */ - e1000_write_8bit_ctrl_reg_generic(hw, > E1000_GIOCTL, 0x00, 0xEC); - e1000_write_8bit_ctrl_reg_generic(hw, > E1000_GIOCTL, 0x61, 0xDF); - e1000_write_8bit_ctrl_reg_generic(hw, > E1000_GIOCTL, 0x34, 0x05); - e1000_write_8bit_ctrl_reg_generic(hw, > E1000_GIOCTL, 0x2F, 0x81); - - /* PCIe PLL Configuration */ - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x02, 0x47); - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x14, 0x00); - > e1000_write_8bit_ctrl_reg_generic(hw, E1000_SCCTL, 0x10, 0x00); - } - - > return E1000_SUCCESS; -} - -/** - * e1000_read_mac_addr_82575 - Read device > MAC address - * @hw: pointer to the HW structure - **/ -static s32 > e1000_read_mac_addr_82575(struct e1000_hw *hw) -{ - s32 ret_val = > E1000_SUCCESS; - - DEBUGFUNC("e1000_read_mac_addr_82575"); - - /* - * If > there's an alternate MAC address place it in RAR0 - * so that it will > override the Si installed default perm - * address. - */ - ret_val = > e1000_check_alt_mac_addr_generic(hw); - if (ret_val) - goto out; - - > ret_val = e1000_read_mac_addr_generic(hw); - -out: - return ret_val; -} - > -/** - * e1000_config_collision_dist_82575 - Configure collision distance - > * @hw: pointer to the HW structure - * - * Configures the collision > distance to the default value and is used - * during link setup. - **/ > -static void e1000_config_collision_dist_82575(struct e1000_hw *hw) -{ - > u32 tctl_ext; - - DEBUGFUNC("e1000_config_collision_dist_82575"); - - > tctl_ext = E1000_READ_REG(hw, E1000_TCTL_EXT); - - tctl_ext &= > ~E1000_TCTL_EXT_COLD; - tctl_ext |= E1000_COLLISION_DISTANCE << > E1000_TCTL_EXT_COLD_SHIFT; - - E1000_WRITE_REG(hw, E1000_TCTL_EXT, > tctl_ext); - E1000_WRITE_FLUSH(hw); -} - -/** - * > e1000_power_down_phy_copper_82575 - Remove link during PHY power down - * > @hw: pointer to the HW structure - * - * In the case of a PHY power down to > save power, or to turn off link during a - * driver unload, or wake on lan > is not enabled, remove the link. - **/ -static void > e1000_power_down_phy_copper_82575(struct e1000_hw *hw) -{ - struct > e1000_phy_info *phy = &hw->phy; - - if (!(phy->ops.check_reset_block)) - > return; - - /* If the management interface is not enabled, then power down > */ - if (!(e1000_enable_mng_pass_thru(hw) || > phy->ops.check_reset_block(hw))) - e1000_power_down_phy_copper(hw); - - > return; -} - -/** - * e1000_clear_hw_cntrs_82575 - Clear device specific > hardware counters - * @hw: pointer to the HW structure - * - * Clears the > hardware counters by reading the counter registers. - **/ -static void > e1000_clear_hw_cntrs_82575(struct e1000_hw *hw) -{ - > DEBUGFUNC("e1000_clear_hw_cntrs_82575"); - - > e1000_clear_hw_cntrs_base_generic(hw); - - E1000_READ_REG(hw, E1000_PRC64); > - E1000_READ_REG(hw, E1000_PRC127); - E1000_READ_REG(hw, E1000_PRC255); - > E1000_READ_REG(hw, E1000_PRC511); - E1000_READ_REG(hw, E1000_PRC1023); - > E1000_READ_REG(hw, E1000_PRC1522); - E1000_READ_REG(hw, E1000_PTC64); - > E1000_READ_REG(hw, E1000_PTC127); - E1000_READ_REG(hw, E1000_PTC255); - > E1000_READ_REG(hw, E1000_PTC511); - E1000_READ_REG(hw, E1000_PTC1023); - > E1000_READ_REG(hw, E1000_PTC1522); - - E1000_READ_REG(hw, E1000_ALGNERRC); > - E1000_READ_REG(hw, E1000_RXERRC); - E1000_READ_REG(hw, E1000_TNCRS); - > E1000_READ_REG(hw, E1000_CEXTERR); - E1000_READ_REG(hw, E1000_TSCTC); - > E1000_READ_REG(hw, E1000_TSCTFC); - - E1000_READ_REG(hw, E1000_MGTPRC); - > E1000_READ_REG(hw, E1000_MGTPDC); - E1000_READ_REG(hw, E1000_MGTPTC); - - > E1000_READ_REG(hw, E1000_IAC); - E1000_READ_REG(hw, E1000_ICRXOC); - - > E1000_READ_REG(hw, E1000_ICRXPTC); - E1000_READ_REG(hw, E1000_ICRXATC); - > E1000_READ_REG(hw, E1000_ICTXPTC); - E1000_READ_REG(hw, E1000_ICTXATC); - > E1000_READ_REG(hw, E1000_ICTXQEC); - E1000_READ_REG(hw, E1000_ICTXQMTC); - > E1000_READ_REG(hw, E1000_ICRXDMTC); - - E1000_READ_REG(hw, E1000_CBTMPC); - > E1000_READ_REG(hw, E1000_HTDPMC); - E1000_READ_REG(hw, E1000_CBRMPC); - > E1000_READ_REG(hw, E1000_RPTHC); - E1000_READ_REG(hw, E1000_HGPTC); - > E1000_READ_REG(hw, E1000_HTCBDPC); - E1000_READ_REG(hw, E1000_HGORCL); - > E1000_READ_REG(hw, E1000_HGORCH); - E1000_READ_REG(hw, E1000_HGOTCL); - > E1000_READ_REG(hw, E1000_HGOTCH); - E1000_READ_REG(hw, E1000_LENERRS); - - > /* This register should not be read in copper configurations */ - if > ((hw->phy.media_type == e1000_media_type_internal_serdes) || - > e1000_sgmii_active_82575(hw)) - E1000_READ_REG(hw, E1000_SCVPC); -} - -/** > - * e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable - * @hw: > pointer to the HW structure - * - * After rx enable if managability is > enabled then there is likely some - * bad data at the start of the fifo and > possibly in the DMA fifo. This - * function clears the fifos and flushes > any packets that came in as rx was - * being enabled. - **/ -void > e1000_rx_fifo_flush_82575(struct e1000_hw *hw) -{ - u32 rctl, rlpml, > rxdctl[4], rfctl, temp_rctl, rx_enabled; - int i, ms_wait; - - > DEBUGFUNC("e1000_rx_fifo_workaround_82575"); - if (hw->mac.type != > e1000_82575 || - !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN)) > - return; - - /* Disable all Rx queues */ - for (i = 0; i < 4; i++) { - > rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i)); - E1000_WRITE_REG(hw, > E1000_RXDCTL(i), - rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE); - } - /* Poll > all queues to verify they have shut down */ - for (ms_wait = 0; ms_wait < > 10; ms_wait++) { - msec_delay(1); - rx_enabled = 0; - for (i = 0; i < 4; > i++) - rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i)); - if > (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE)) - break; - } - - if (ms_wait == > 10) - DEBUGOUT("Queue disable timed out after 10ms\n"); - - /* Clear RLPML, > RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all - * incoming packets are > rejected. Set enable and wait 2ms so that - * any packet that was coming in > as RCTL.EN was set is flushed - */ - rfctl = E1000_READ_REG(hw, > E1000_RFCTL); - E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF); > - - rlpml = E1000_READ_REG(hw, E1000_RLPML); - E1000_WRITE_REG(hw, > E1000_RLPML, 0); - - rctl = E1000_READ_REG(hw, E1000_RCTL); - temp_rctl = > rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP); - temp_rctl |= E1000_RCTL_LPE; - > - E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl); - E1000_WRITE_REG(hw, > E1000_RCTL, temp_rctl | E1000_RCTL_EN); - E1000_WRITE_FLUSH(hw); - > msec_delay(2); - - /* Enable Rx queues that were previously enabled and > restore our - * previous state - */ - for (i = 0; i < 4; i++) - > E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]); - E1000_WRITE_REG(hw, > E1000_RCTL, rctl); - E1000_WRITE_FLUSH(hw); - - E1000_WRITE_REG(hw, > E1000_RLPML, rlpml); - E1000_WRITE_REG(hw, E1000_RFCTL, rfctl); - - /* > Flush receive errors generated by workaround */ - E1000_READ_REG(hw, > E1000_ROC); - E1000_READ_REG(hw, E1000_RNBC); - E1000_READ_REG(hw, > E1000_MPC); -} - -/** - * e1000_set_pcie_completion_timeout - set pci-e > completion timeout - * @hw: pointer to the HW structure - * - * The > defaults for 82575 and 82576 should be in the range of 50us to 50ms, - * > however the hardware default for these parts is 500us to 1ms which is less > - * than the 10ms recommended by the pci-e spec. To address this we need to > - * increase the value to either 10ms to 200ms for capability version 1 > config, - * or 16ms to 55ms for version 2. - **/ -static s32 > e1000_set_pcie_completion_timeout(struct e1000_hw *hw) -{ - u32 gcr = > E1000_READ_REG(hw, E1000_GCR); - s32 ret_val = E1000_SUCCESS; - u16 > pcie_devctl2; - - /* only take action if timeout value is defaulted to 0 */ > - if (gcr & E1000_GCR_CMPL_TMOUT_MASK) - goto out; - - /* - * if > capababilities version is type 1 we can write the - * timeout of 10ms to > 200ms through the GCR register - */ - if (!(gcr & E1000_GCR_CAP_VER2)) { - > gcr |= E1000_GCR_CMPL_TMOUT_10ms; - goto out; - } - - /* - * for version 2 > capabilities we need to write the config space - * directly in order to set > the completion timeout value for - * 16ms to 55ms - */ - ret_val = > e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, - &pcie_devctl2); - if > (ret_val) - goto out; - - pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms; - - > ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2, - > &pcie_devctl2); -out: - /* disable completion timeout resend */ - gcr &= > ~E1000_GCR_CMPL_TMOUT_RESEND; - - E1000_WRITE_REG(hw, E1000_GCR, gcr); - > return ret_val; -} - -/** - * e1000_vmdq_set_anti_spoofing_pf - enable or > disable anti-spoofing - * @hw: pointer to the hardware struct - * @enable: > state to enter, either enabled or disabled - * @pf: Physical Function pool > - do not set anti-spoofing for the PF - * - * enables/disables L2 switch > anti-spoofing functionality. - **/ -void > e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf) > -{ - u32 reg_val, reg_offset; - - switch (hw->mac.type) { - case > e1000_82576: - reg_offset = E1000_DTXSWC; - break; - case e1000_i350: - > case e1000_i354: - reg_offset = E1000_TXSWC; - break; - default: - return; > - } - - reg_val = E1000_READ_REG(hw, reg_offset); - if (enable) { - reg_val > |= (E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - /* The > PF can spoof - it has to in order to - * support emulation mode NICs - */ - > reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS)); - } else { - reg_val &= > ~(E1000_DTXSWC_MAC_SPOOF_MASK | - E1000_DTXSWC_VLAN_SPOOF_MASK); - } - > E1000_WRITE_REG(hw, reg_offset, reg_val); -} - -/** - * > e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback - * @hw: > pointer to the hardware struct - * @enable: state to enter, either enabled > or disabled - * - * enables/disables L2 switch loopback functionality. - > **/ -void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable) -{ - > u32 dtxswc; - - switch (hw->mac.type) { - case e1000_82576: - dtxswc = > E1000_READ_REG(hw, E1000_DTXSWC); - if (enable) - dtxswc |= > E1000_DTXSWC_VMDQ_LOOPBACK_EN; - else - dtxswc &= > ~E1000_DTXSWC_VMDQ_LOOPBACK_EN; - E1000_WRITE_REG(hw, E1000_DTXSWC, > dtxswc); - break; - case e1000_i350: - case e1000_i354: - dtxswc = > E1000_READ_REG(hw, E1000_TXSWC); - if (enable) - dtxswc |= > E1000_DTXSWC_VMDQ_LOOPBACK_EN; - else - dtxswc &= > ~E1000_DTXSWC_VMDQ_LOOPBACK_EN; - E1000_WRITE_REG(hw, E1000_TXSWC, dtxswc); > - break; - default: - /* Currently no other hardware supports loopback */ - > break; - } - - -} - -/** - * e1000_vmdq_set_replication_pf - enable or > disable vmdq replication - * @hw: pointer to the hardware struct - * > @enable: state to enter, either enabled or disabled - * - * > enables/disables replication of packets across multiple pools. - **/ -void > e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable) -{ - u32 > vt_ctl = E1000_READ_REG(hw, E1000_VT_CTL); - - if (enable) - vt_ctl |= > E1000_VT_CTL_VM_REPL_EN; - else - vt_ctl &= ~E1000_VT_CTL_VM_REPL_EN; - - > E1000_WRITE_REG(hw, E1000_VT_CTL, vt_ctl); -} - -/** - * > e1000_read_phy_reg_82580 - Read 82580 MDI control register - * @hw: pointer > to the HW structure - * @offset: register offset to be read - * @data: > pointer to the read data - * - * Reads the MDI control register in the PHY > at offset and stores the - * information read to data. - **/ -static s32 > e1000_read_phy_reg_82580(struct e1000_hw *hw, u32 offset, u16 *data) -{ - > s32 ret_val; - - DEBUGFUNC("e1000_read_phy_reg_82580"); - - ret_val = > hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - - ret_val = > e1000_read_phy_reg_mdic(hw, offset, data); - - hw->phy.ops.release(hw); - > -out: - return ret_val; -} - -/** - * e1000_write_phy_reg_82580 - Write > 82580 MDI control register - * @hw: pointer to the HW structure - * > @offset: register offset to write to - * @data: data to write to register > at offset - * - * Writes data to MDI control register in the PHY at offset. > - **/ -static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw, u32 > offset, u16 data) -{ - s32 ret_val; - - > DEBUGFUNC("e1000_write_phy_reg_82580"); - - ret_val = > hw->phy.ops.acquire(hw); - if (ret_val) - goto out; - - ret_val = > e1000_write_phy_reg_mdic(hw, offset, data); - - hw->phy.ops.release(hw); - > -out: - return ret_val; -} - -/** - * e1000_reset_mdicnfg_82580 - Reset > MDICNFG destination and com_mdio bits - * @hw: pointer to the HW structure > - * - * This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based > on - * the values found in the EEPROM. This addresses an issue in which > these - * bits are not restored from EEPROM after reset. - **/ -static s32 > e1000_reset_mdicnfg_82580(struct e1000_hw *hw) -{ - s32 ret_val = > E1000_SUCCESS; - u32 mdicnfg; - u16 nvm_data = 0; - - > DEBUGFUNC("e1000_reset_mdicnfg_82580"); - - if (hw->mac.type != > e1000_82580) - goto out; - if (!e1000_sgmii_active_82575(hw)) - goto out; - > - ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + - > NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, - &nvm_data); - if (ret_val) { > - DEBUGOUT("NVM Read Error\n"); - goto out; - } - - mdicnfg = > E1000_READ_REG(hw, E1000_MDICNFG); - if (nvm_data & NVM_WORD24_EXT_MDIO) - > mdicnfg |= E1000_MDICNFG_EXT_MDIO; - if (nvm_data & NVM_WORD24_COM_MDIO) - > mdicnfg |= E1000_MDICNFG_COM_MDIO; - E1000_WRITE_REG(hw, E1000_MDICNFG, > mdicnfg); -out: - return ret_val; -} - -/** - * e1000_reset_hw_82580 - > Reset hardware - * @hw: pointer to the HW structure - * - * This resets > function or entire device (all ports, etc.) - * to a known state. - **/ > -static s32 e1000_reset_hw_82580(struct e1000_hw *hw) -{ - s32 ret_val = > E1000_SUCCESS; - /* BH SW mailbox bit in SW_FW_SYNC */ - u16 swmbsw_mask = > E1000_SW_SYNCH_MB; - u32 ctrl; - bool global_device_reset = > hw->dev_spec._82575.global_device_reset; - - > DEBUGFUNC("e1000_reset_hw_82580"); - - > hw->dev_spec._82575.global_device_reset = false; - - /* 82580 does not > reliably do global_device_reset due to hw errata */ - if (hw->mac.type == > e1000_82580) - global_device_reset = false; - - /* Get current control > state. */ - ctrl = E1000_READ_REG(hw, E1000_CTRL); - - /* - * Prevent the > PCI-E bus from sticking if there is no TLP connection - * on the last TLP > read/write transaction when MAC is reset. - */ - ret_val = > e1000_disable_pcie_master_generic(hw); - if (ret_val) - DEBUGOUT("PCI-E > Master disable polling has failed.\n"); - - DEBUGOUT("Masking off all > interrupts\n"); - E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); - > E1000_WRITE_REG(hw, E1000_RCTL, 0); - E1000_WRITE_REG(hw, E1000_TCTL, > E1000_TCTL_PSP); - E1000_WRITE_FLUSH(hw); - - msec_delay(10); - - /* > Determine whether or not a global dev reset is requested */ - if > (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw, - swmbsw_mask)) - > global_device_reset = false; - - if (global_device_reset && > !(E1000_READ_REG(hw, E1000_STATUS) & - E1000_STAT_DEV_RST_SET)) - ctrl |= > E1000_CTRL_DEV_RST; - else - ctrl |= E1000_CTRL_RST; - - > E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - E1000_WRITE_FLUSH(hw); - - /* Add > delay to insure DEV_RST has time to complete */ - if (global_device_reset) > - msec_delay(5); - - ret_val = e1000_get_auto_rd_done_generic(hw); - if > (ret_val) { - /* - * When auto config read does not complete, do not - * > return with an error. This can happen in situations - * where there is no > eeprom and prevents getting link. - */ - DEBUGOUT("Auto Read Done did not > complete\n"); - } - - /* clear global device reset status bit */ - > E1000_WRITE_REG(hw, E1000_STATUS, E1000_STAT_DEV_RST_SET); - - /* Clear any > pending interrupt events. */ - E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); > - E1000_READ_REG(hw, E1000_ICR); - - ret_val = > e1000_reset_mdicnfg_82580(hw); - if (ret_val) - DEBUGOUT("Could not reset > MDICNFG based on EEPROM\n"); - - /* Install any alternate MAC address into > RAR0 */ - ret_val = e1000_check_alt_mac_addr_generic(hw); - - /* Release > semaphore */ - if (global_device_reset) - hw->mac.ops.release_swfw_sync(hw, > swmbsw_mask); - - return ret_val; -} - -/** - * e1000_rxpbs_adjust_82580 - > adjust RXPBS value to reflect actual Rx PBA size - * @data: data received > by reading RXPBS register - * - * The 82580 uses a table based approach for > packet buffer allocation sizes. - * This function converts the retrieved > value into the correct table value - * 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 - * > 0x0 36 72 144 1 2 4 8 16 - * 0x8 35 70 140 rsv rsv rsv rsv rsv - */ -u16 > e1000_rxpbs_adjust_82580(u32 data) -{ - u16 ret_val = 0; - - if (data < > E1000_82580_RXPBS_TABLE_SIZE) - ret_val = e1000_82580_rxpbs_table[data]; - > - return ret_val; -} - -/** - * e1000_validate_nvm_checksum_with_offset - > Validate EEPROM - * checksum - * @hw: pointer to the HW structure - * > @offset: offset in words of the checksum protected region - * - * > Calculates the EEPROM checksum by reading/adding each word of the EEPROM - > * and then verifies that the sum of the EEPROM is equal to 0xBABA. - **/ > -s32 e1000_validate_nvm_checksum_with_offset(struct e1000_hw *hw, u16 > offset) -{ - s32 ret_val = E1000_SUCCESS; - u16 checksum = 0; - u16 i, > nvm_data; - - DEBUGFUNC("e1000_validate_nvm_checksum_with_offset"); - - for > (i = offset; i < ((NVM_CHECKSUM_REG + offset) + 1); i++) { - ret_val = > hw->nvm.ops.read(hw, i, 1, &nvm_data); - if (ret_val) { - DEBUGOUT("NVM > Read Error\n"); - goto out; - } - checksum += nvm_data; - } - - if > (checksum != (u16) NVM_SUM) { - DEBUGOUT("NVM Checksum Invalid\n"); - > ret_val = -E1000_ERR_NVM; - goto out; - } - -out: - return ret_val; -} - > -/** - * e1000_update_nvm_checksum_with_offset - Update EEPROM - * checksum > - * @hw: pointer to the HW structure - * @offset: offset in words of the > checksum protected region - * - * Updates the EEPROM checksum by > reading/adding each word of the EEPROM - * up to the checksum. Then > calculates the EEPROM checksum and writes the - * value to the EEPROM. - > **/ -s32 e1000_update_nvm_checksum_with_offset(struct e1000_hw *hw, u16 > offset) -{ - s32 ret_val; - u16 checksum = 0; - u16 i, nvm_data; - - > DEBUGFUNC("e1000_update_nvm_checksum_with_offset"); - - for (i = offset; i > < (NVM_CHECKSUM_REG + offset); i++) { - ret_val = hw->nvm.ops.read(hw, i, > 1, &nvm_data); - if (ret_val) { - DEBUGOUT("NVM Read Error while updating > checksum.\n"); - goto out; - } - checksum += nvm_data; - } - checksum = > (u16) NVM_SUM - checksum; - ret_val = hw->nvm.ops.write(hw, > (NVM_CHECKSUM_REG + offset), 1, - &checksum); - if (ret_val) - > DEBUGOUT("NVM Write Error while updating checksum.\n"); - -out: - return > ret_val; -} - -/** - * e1000_validate_nvm_checksum_82580 - Validate EEPROM > checksum - * @hw: pointer to the HW structure - * - * Calculates the EEPROM > section checksum by reading/adding each word of - * the EEPROM and then > verifies that the sum of the EEPROM is - * equal to 0xBABA. - **/ -static > s32 e1000_validate_nvm_checksum_82580(struct e1000_hw *hw) -{ - s32 ret_val > = E1000_SUCCESS; - u16 eeprom_regions_count = 1; - u16 j, nvm_data; - u16 > nvm_offset; - - DEBUGFUNC("e1000_validate_nvm_checksum_82580"); - - ret_val > = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); - if > (ret_val) { - DEBUGOUT("NVM Read Error\n"); - goto out; - } - - if > (nvm_data & NVM_COMPATIBILITY_BIT_MASK) { - /* if chekcsums compatibility > bit is set validate checksums - * for all 4 ports. */ - > eeprom_regions_count = 4; - } - - for (j = 0; j < eeprom_regions_count; > j++) { - nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); - ret_val = > e1000_validate_nvm_checksum_with_offset(hw, - nvm_offset); - if (ret_val != > E1000_SUCCESS) - goto out; - } - -out: - return ret_val; -} - -/** - * > e1000_update_nvm_checksum_82580 - Update EEPROM checksum - * @hw: pointer > to the HW structure - * - * Updates the EEPROM section checksums for all 4 > ports by reading/adding - * each word of the EEPROM up to the checksum. > Then calculates the EEPROM - * checksum and writes the value to the EEPROM. > - **/ -static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw) -{ - > s32 ret_val; - u16 j, nvm_data; - u16 nvm_offset; - - > DEBUGFUNC("e1000_update_nvm_checksum_82580"); - - ret_val = > hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data); - if (ret_val) > { - DEBUGOUT("NVM Read Error while updating checksum compatibility > bit.\n"); - goto out; - } - - if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) > { - /* set compatibility bit to validate checksums appropriately */ - > nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK; - ret_val = > hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1, - &nvm_data); - if > (ret_val) { - DEBUGOUT("NVM Write Error while updating checksum > compatibility bit.\n"); - goto out; - } - } - - for (j = 0; j < 4; j++) { - > nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); - ret_val = > e1000_update_nvm_checksum_with_offset(hw, nvm_offset); - if (ret_val) - > goto out; - } - -out: - return ret_val; -} - -/** - * > e1000_validate_nvm_checksum_i350 - Validate EEPROM checksum - * @hw: > pointer to the HW structure - * - * Calculates the EEPROM section checksum > by reading/adding each word of - * the EEPROM and then verifies that the > sum of the EEPROM is - * equal to 0xBABA. - **/ -static s32 > e1000_validate_nvm_checksum_i350(struct e1000_hw *hw) -{ - s32 ret_val = > E1000_SUCCESS; - u16 j; - u16 nvm_offset; - - > DEBUGFUNC("e1000_validate_nvm_checksum_i350"); - - for (j = 0; j < 4; j++) > { - nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); - ret_val = > e1000_validate_nvm_checksum_with_offset(hw, - nvm_offset); - if (ret_val != > E1000_SUCCESS) - goto out; - } - -out: - return ret_val; -} - -/** - * > e1000_update_nvm_checksum_i350 - Update EEPROM checksum - * @hw: pointer to > the HW structure - * - * Updates the EEPROM section checksums for all 4 > ports by reading/adding - * each word of the EEPROM up to the checksum. > Then calculates the EEPROM - * checksum and writes the value to the EEPROM. > - **/ -static s32 e1000_update_nvm_checksum_i350(struct e1000_hw *hw) -{ - > s32 ret_val = E1000_SUCCESS; - u16 j; - u16 nvm_offset; - - > DEBUGFUNC("e1000_update_nvm_checksum_i350"); - - for (j = 0; j < 4; j++) { > - nvm_offset = NVM_82580_LAN_FUNC_OFFSET(j); - ret_val = > e1000_update_nvm_checksum_with_offset(hw, nvm_offset); - if (ret_val != > E1000_SUCCESS) - goto out; - } - -out: - return ret_val; -} - -/** - * > __e1000_access_emi_reg - Read/write EMI register - * @hw: pointer to the HW > structure - * @addr: EMI address to program - * @data: pointer to value to > read/write from/to the EMI address - * @read: boolean flag to indicate read > or write - **/ -static s32 __e1000_access_emi_reg(struct e1000_hw *hw, u16 > address, - u16 *data, bool read) -{ - s32 ret_val = E1000_SUCCESS; - - > DEBUGFUNC("__e1000_access_emi_reg"); - - ret_val = > hw->phy.ops.write_reg(hw, E1000_EMIADD, address); - if (ret_val) - return > ret_val; - - if (read) - ret_val = hw->phy.ops.read_reg(hw, E1000_EMIDATA, > data); - else - ret_val = hw->phy.ops.write_reg(hw, E1000_EMIDATA, *data); > - - return ret_val; -} - -/** - * e1000_read_emi_reg - Read Extended > Management Interface register - * @hw: pointer to the HW structure - * > @addr: EMI address to program - * @data: value to be read from the EMI > address - **/ -s32 e1000_read_emi_reg(struct e1000_hw *hw, u16 addr, u16 > *data) -{ - DEBUGFUNC("e1000_read_emi_reg"); - - return > __e1000_access_emi_reg(hw, addr, data, true); -} - -/** - * > e1000_set_eee_i350 - Enable/disable EEE support - * @hw: pointer to the HW > structure - * - * Enable/disable EEE based on setting in dev_spec > structure. - * - **/ -s32 e1000_set_eee_i350(struct e1000_hw *hw) -{ - s32 > ret_val = E1000_SUCCESS; - u32 ipcnfg, eeer; - - > DEBUGFUNC("e1000_set_eee_i350"); - - if ((hw->mac.type < e1000_i350) || - > (hw->phy.media_type != e1000_media_type_copper)) - goto out; - ipcnfg = > E1000_READ_REG(hw, E1000_IPCNFG); - eeer = E1000_READ_REG(hw, E1000_EEER); > - - /* enable or disable per user setting */ - if > (!(hw->dev_spec._82575.eee_disable)) { - u32 eee_su = E1000_READ_REG(hw, > E1000_EEE_SU); - - ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | > E1000_IPCNFG_EEE_100M_AN); - eeer |= (E1000_EEER_TX_LPI_EN | > E1000_EEER_RX_LPI_EN | - E1000_EEER_LPI_FC); - - /* This bit should not be > set in normal operation. */ - if (eee_su & E1000_EEE_SU_LPI_CLK_STP) - > DEBUGOUT("LPI Clock Stop Bit should not be set!\n"); - } else { - ipcnfg &= > ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); - eeer &= > ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | - E1000_EEER_LPI_FC); - } - > E1000_WRITE_REG(hw, E1000_IPCNFG, ipcnfg); - E1000_WRITE_REG(hw, > E1000_EEER, eeer); - E1000_READ_REG(hw, E1000_IPCNFG); - E1000_READ_REG(hw, > E1000_EEER); -out: - - return ret_val; -} - -/** - * e1000_set_eee_i354 - > Enable/disable EEE support - * @hw: pointer to the HW structure - * - * > Enable/disable EEE legacy mode based on setting in dev_spec structure. - * > - **/ -s32 e1000_set_eee_i354(struct e1000_hw *hw) -{ - struct > e1000_phy_info *phy = &hw->phy; - s32 ret_val = E1000_SUCCESS; - u16 > phy_data; - - DEBUGFUNC("e1000_set_eee_i354"); - - if ((hw->phy.media_type > != e1000_media_type_copper) || - ((phy->id != M88E1543_E_PHY_ID))) - goto > out; - - if (!hw->dev_spec._82575.eee_disable) { - /* Switch to PHY page > 18. */ - ret_val = phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 18); - > if (ret_val) - goto out; - - ret_val = phy->ops.read_reg(hw, > E1000_M88E1543_EEE_CTRL_1, - &phy_data); - if (ret_val) - goto out; - - > phy_data |= E1000_M88E1543_EEE_CTRL_1_MS; - ret_val = > phy->ops.write_reg(hw, E1000_M88E1543_EEE_CTRL_1, - phy_data); - if > (ret_val) - goto out; - - /* Return the PHY to page 0. */ - ret_val = > phy->ops.write_reg(hw, E1000_M88E1543_PAGE_ADDR, 0); - if (ret_val) - goto > out; - - /* Turn on EEE advertisement. */ - ret_val = > e1000_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354, - E1000_EEE_ADV_DEV_I354, > - &phy_data); - if (ret_val) - goto out; - - phy_data |= > E1000_EEE_ADV_100_SUPPORTED | - E1000_EEE_ADV_1000_SUPPORTED; - ret_val = > e1000_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354, - > E1000_EEE_ADV_DEV_I354, - phy_data); - } else { - /* Turn off EEE > advertisement. */ - ret_val = e1000_read_xmdio_reg(hw, > E1000_EEE_ADV_ADDR_I354, - E1000_EEE_ADV_DEV_I354, - &phy_data); - if > (ret_val) - goto out; - - phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED | - > E1000_EEE_ADV_1000_SUPPORTED); - ret_val = e1000_write_xmdio_reg(hw, > E1000_EEE_ADV_ADDR_I354, - E1000_EEE_ADV_DEV_I354, - phy_data); - } - -out: > - return ret_val; -} - -/** - * e1000_get_eee_status_i354 - Get EEE status > - * @hw: pointer to the HW structure - * @status: EEE status - * - * Get > EEE status by guessing based on whether Tx or Rx LPI indications have - * > been received. - **/ -s32 e1000_get_eee_status_i354(struct e1000_hw *hw, > bool *status) -{ - struct e1000_phy_info *phy = &hw->phy; - s32 ret_val = > E1000_SUCCESS; - u16 phy_data; - - DEBUGFUNC("e1000_get_eee_status_i354"); > - - /* Check if EEE is supported on this device. */ - if > ((hw->phy.media_type != e1000_media_type_copper) || - ((phy->id != > M88E1543_E_PHY_ID))) - goto out; - - ret_val = e1000_read_xmdio_reg(hw, > E1000_PCS_STATUS_ADDR_I354, - E1000_PCS_STATUS_DEV_I354, - &phy_data); - if > (ret_val) - goto out; - - *status = phy_data & > (E1000_PCS_STATUS_TX_LPI_RCVD | - E1000_PCS_STATUS_RX_LPI_RCVD) ? true : > false; - -out: - return ret_val; -} - -/* Due to a hw errata, if the host > tries to configure the VFTA register - * while performing queries from the > BMC or DMA, then the VFTA in some - * cases won't be written. - */ - -/** - > * e1000_clear_vfta_i350 - Clear VLAN filter table - * @hw: pointer to the > HW structure - * - * Clears the register array which contains the VLAN > filter table by - * setting all the values to 0. - **/ -void > e1000_clear_vfta_i350(struct e1000_hw *hw) -{ - u32 offset; - int i; - - > DEBUGFUNC("e1000_clear_vfta_350"); - - for (offset = 0; offset < > E1000_VLAN_FILTER_TBL_SIZE; offset++) { - for (i = 0; i < 10; i++) - > E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); - - > E1000_WRITE_FLUSH(hw); - } -} - -/** - * e1000_write_vfta_i350 - Write > value to VLAN filter table - * @hw: pointer to the HW structure - * > @offset: register offset in VLAN filter table - * @value: register value > written to VLAN filter table - * - * Writes value at the given offset in > the regi