Overview
Request 6032 (accepted)
- Update to new version r8168-8.052.01
- Remove patches now upstream
* skb_gso_segment.patch
* r8168-support-linux-6.1.0.patch
- Port patches
* r8168-configuration.patch
* r8168-kernel_version.patch
* r8168-support-dev0x8136.patch
* r8168-support-linux-5.19.patch
* r8168-support-linux-L15.5.patch
- Add r8168.keyring and signature of tar ball to check tar ball
- Add patch r8168-gcc14.patch
* Avoid gcc14 trouble
* Switch from deprecated strlcpy() to strscpy()
- Use %patch -P N instead of deprecated %patchN.
- Created by bitstreamout about 1 year ago
- In state accepted
-
Package maintainer:
bitstreamout
r8168.changes
Changed
-------------------------------------------------------------------
+Wed Mar 13 12:12:43 UTC 2024 - Dr. Werner Fink <werner@suse.de>
+
+- Update to new version r8168-8.052.01
+- Remove patches now upstream
+ * skb_gso_segment.patch
+ * r8168-support-linux-6.1.0.patch
+- Port patches
+ * r8168-configuration.patch
+ * r8168-kernel_version.patch
+ * r8168-support-dev0x8136.patch
+ * r8168-support-linux-5.19.patch
+ * r8168-support-linux-L15.5.patch
+- Add r8168.keyring and signature of tar ball to check tar ball
+- Add patch r8168-gcc14.patch
+ * Avoid gcc14 trouble
+ * Switch from deprecated strlcpy() to strscpy()
+
+-------------------------------------------------------------------
+Wed Mar 13 11:26:04 UTC 2024 - Dr. Werner Fink <werner@suse.de>
+
+- Use %patch -P N instead of deprecated %patchN.
+
+-------------------------------------------------------------------
Thu Oct 19 08:29:04 UTC 2023 - Dr. Werner Fink <werner@suse.de>
- Dynamic adaption of patch skb_gso_segment.patch means if net/gso.h
r8168.spec
Changed
#!BuildIgnore: enough-build-resources
Name: r8168
-Version: 8.051.02
+Version: 8.052.01
Release: 0
Summary: Device driver for RealTek Gigabit Ethernet controllers
License: GPL-2.0-or-later
Source0: https://github.com/mtorromeo/r8168/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz
Source1: preamble
Source2: Module.supported
+Source3: https://github.com/mtorromeo/r8168/releases/download/%{version}/%{name}-%{version}.tar.gz.asc
+Source4: r8168.keyring
Patch0: r8168-kernel_version.patch
Patch1: r8168-configuration.patch
Patch2: r8168-support-linux-5.19.patch
-Patch3: r8168-support-linux-6.1.0.patch
+Patch3: r8168-gcc14.patch
Patch4: r8168-support-dev0x8136.patch
Patch5: r8168-support-linux-L15.5.patch
-Patch6: skb_gso_segment.patch
BuildRequires: kernel-source
BuildRequires: kernel-syms
BuildRequires: libelf-devel
%prep
%setup -q
-%patch0 -b .p0
-%patch1 -b .p1
-%patch2 -p1 -b .p2
-%patch3 -p1 -b .p3
-%patch4 -p1 -b .p4
+%patch -P 0 -b .p0
+%patch -P 1 -b .p1
+%patch -P 2 -p1 -b .p2
+%patch -P 3 -b .p3
+%patch -P 4 -p1 -b .p4
if test -e /usr/src/linux/include/linux/ethtool.h
then
argc=$(sed -rn '/\*get_ringparam/,/;$/p' /usr/src/linux/include/linux/ethtool.h | wc -l)
if test -n "$argc" -a "$argc" -eq 4
then
-%patch5 -b .p5
+%patch -P 5 -b .p5
fi
fi
if test -e /usr/src/linux/include/net/gso.h
then
version=$(uname -r|sed -r 's/-.*//;s/\./,/g')
- sed -ri "/KERNEL_VERSION/{s/\(6,4,10\)/(${version})/}" %{PATCH6}
+ sed -ri "/KERNEL_VERSION/{s/\(6,4,10\)/(${version})/}" src/r8168_n.c
fi
-%patch6 -p1 -b .p6
cp %{S:1} .
cp %{S:2} .
r8168-configuration.patch
Changed
--- src/Makefile
+++ src/Makefile 2022-05-10 10:26:59.851240712 +0000
-@@ -48,6 +48,7 @@ CONFIG_CTAP_SHORT_OFF = n
+@@ -52,6 +52,7 @@ CONFIG_CTAP_SHORT_OFF = n
ifneq ($(KERNELRELEASE),)
obj-m := r8168.o
r8168-objs := r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o
r8168-gcc14.patch
Added
+---
+ src/r8168_n.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- src/r8168_n.c
++++ src/r8168_n.c 2024-03-13 12:25:52.886342182 +0000
+@@ -6312,7 +6312,7 @@ rtl8168_get_drvinfo(struct net_device *d
+ info->eedump_len = tp->eeprom_len;
+ BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version));
+ if (rtl_fw)
+- strlcpy(info->fw_version, rtl_fw->version,
++ strscpy(info->fw_version, rtl_fw->version,
+ sizeof(info->fw_version));
+ }
+
+@@ -28103,7 +28103,8 @@ rtl8168_link_timer(struct timer_list *t)
+ }
+ */
+
+-int rtl8168_enable_msix(struct rtl8168_private *tp)
++static int
++rtl8168_enable_msix(struct rtl8168_private *tp)
+ {
+ int i, nvecs = 0;
+ struct msix_entry msix_entR8168_MAX_MSIX_VEC;
r8168-kernel_version.patch
Changed
2 files changed, 18 insertions(+), 1 deletion(-)
--- src/r8168.h
-+++ src/r8168.h 2022-05-10 10:26:28.831787721 +0000
-@@ -121,6 +121,10 @@ do { \
++++ src/r8168.h 2024-03-13 11:51:59.011947503 +0000
+@@ -133,6 +133,10 @@ do { \
} while (0)
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
#if defined(skb_vlan_tag_present) && !defined(vlan_tx_tag_present)
#define vlan_tx_tag_present skb_vlan_tag_present
--- src/r8168_n.c
-+++ src/r8168_n.c 2022-05-10 10:26:28.871787016 +0000
++++ src/r8168_n.c 2024-03-13 11:57:02.890342590 +0000
@@ -61,11 +61,16 @@
#include <linux/rtnetlink.h>
#include <linux/completion.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37)
#include <linux/prefetch.h>
#endif
-@@ -571,8 +576,12 @@ static void rtl8168_set_rx_mode(struct n
+@@ -590,8 +595,12 @@ static void rtl8168_set_rx_mode(struct n
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
static void rtl8168_tx_timeout(struct net_device *dev, unsigned int txqueue);
#else
#endif
+#endif
static struct net_device_stats *rtl8168_get_stats(struct net_device *dev);
- static int rtl8168_rx_interrupt(struct net_device *, struct rtl8168_private *, napi_budget);
- static int rtl8168_change_mtu(struct net_device *dev, int new_mtu);
-@@ -28985,8 +28994,12 @@ static void
+ static int rtl8168_rx_interrupt(struct net_device *, struct rtl8168_private *, struct rtl8168_rx_ring *, napi_budget);
+ #ifdef CONFIG_R8168_NAPI
+@@ -30765,8 +30774,12 @@ static void
rtl8168_tx_timeout(struct net_device *dev, unsigned int txqueue)
#else
static void
+#endif
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
-@@ -29672,7 +29685,7 @@ process_pkt:
- if (rtl8168_rx_vlan_skb(tp, desc, skb) < 0)
- rtl8168_rx_skb(tp, skb);
+@@ -31502,7 +31515,7 @@ rtl8168_rx_interrupt(struct net_device *
+
+ if (rtl8168_rx_vlan_skb(tp, desc, skb) < 0)
+ rtl8168_rx_skb(tp, skb, ring_index);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0)
- dev->last_rx = jiffies;
+ dev->last_rx = jiffies;
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
- RTLDEV->stats.rx_bytes += pkt_size;
+ RTLDEV->stats.rx_bytes += pkt_size;
r8168-support-dev0x8136.patch
Changed
index 28d7636..cbf43d1 100755
--- a/src/r8168_n.c
+++ b/src/r8168_n.c
-@@ -411,6 +411,7 @@ static const struct {
+@@ -430,6 +430,7 @@ static const struct {
static struct pci_device_id rtl8168_pci_tbl = {
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), },
r8168-support-linux-5.19.patch
Changed
--- r8168-8.050.03/src/r8168_n.c
+++ r8168-8.050.03/src/r8168_n.c
-@@ -121,6 +121,15 @@
+@@ -126,6 +126,15 @@
#define FIRMWARE_8168FP_3 "rtl_nic/rtl8168fp-3.fw"
#define FIRMWARE_8168FP_4 "rtl_nic/rtl8168fp-4.fw"
r8168-support-linux-6.1.0.patch
Deleted
-From 39dd0fd2e5dc45cd63113f33a9890e36c304916d Mon Sep 17 00:00:00 2001
-From: zu1k <i@zu1k.com>
-Date: Sat, 29 Oct 2022 21:57:39 +0800
-Subject: PATCH Adapted for Linux 6.1
-
----
- src/r8168.h | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/r8168.h b/src/r8168.h
-index 662974a..baf48c6 100755
---- a/src/r8168.h
-+++ b/src/r8168.h
-@@ -570,7 +570,11 @@ typedef int *napi_budget;
- typedef struct napi_struct *napi_ptr;
- typedef int napi_budget;
-
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0)
-+#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function)
-+#else
- #define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight)
-+#endif
- #define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget)
- #define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr)
- #define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev;
r8168-support-linux-L15.5.patch
Changed
1 file changed, 6 insertions(+), 6 deletions(-)
--- src/r8168_n.c
-+++ src/r8168_n.c 2023-05-10 10:40:25.454736974 +0000
-@@ -5964,7 +5964,7 @@ rtl8168_wait_for_quiescence(struct net_d
++++ src/r8168_n.c 2024-03-13 12:10:07.947820999 +0000
+@@ -6986,7 +6986,7 @@ rtl8168_set_ring_size(struct rtl8168_pri
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
static void rtl8168_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
-@@ -5972,7 +5972,7 @@ static void rtl8168_get_ringparam(struct
+@@ -6994,7 +6994,7 @@ static void rtl8168_get_ringparam(struct
#else
static void rtl8168_get_ringparam(struct net_device *dev,
struct ethtool_ringparam *ring)
{
struct rtl8168_private *tp = netdev_priv(dev);
-@@ -5982,7 +5982,7 @@ static void rtl8168_get_ringparam(struct
- ring->tx_pending = tp->num_tx_desc;
+@@ -7004,7 +7004,7 @@ static void rtl8168_get_ringparam(struct
+ ring->tx_pending = tp->tx_ring0.num_tx_desc;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0)
static int rtl8168_set_ringparam(struct net_device *dev,
struct ethtool_ringparam *ring,
struct kernel_ethtool_ringparam *kernel_ring,
-@@ -5990,7 +5990,7 @@ static int rtl8168_set_ringparam(struct
+@@ -7012,7 +7012,7 @@ static int rtl8168_set_ringparam(struct
#else
static int rtl8168_set_ringparam(struct net_device *dev,
struct ethtool_ringparam *ring)
{
struct rtl8168_private *tp = netdev_priv(dev);
u32 new_rx_count, new_tx_count;
-@@ -25420,11 +25420,11 @@ rtl8168_release_board(struct pci_dev *pd
+@@ -26644,11 +26644,11 @@ rtl8168_release_board(struct pci_dev *pd
static void
rtl8168_hw_address_set(struct net_device *dev, u8 mac_addrMAC_ADDR_LEN)
{
skb_gso_segment.patch
Deleted
-From fc2e0d28c79d3f6ef052d85a7cb146610554ff22 Mon Sep 17 00:00:00 2001
-From: safocl <safocl88@gmail.com>
-Date: Sun, 13 Aug 2023 04:23:03 +0400
-Subject: PATCH Fix missing skb_gso_segment function declaration This
- motivation from this issue(https://github.com/mtorromeo/r8168/issues/54)
-
----
- src/r8168_n.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/src/r8168_n.c b/src/r8168_n.c
-index 7e9e2ea..3855910 100755
---- a/src/r8168_n.c
-+++ b/src/r8168_n.c
-@@ -86,6 +86,10 @@
- #include <linux/mdio.h>
- #endif
-
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10)
-+#include <net/gso.h>
-+#endif
-+
- #include <asm/io.h>
- #include <asm/irq.h>
-
r8168-8.052.01.tar.gz.asc
Added
+-----BEGIN PGP SIGNATURE-----
+
+iHUEABYIAB0WIQQMrarPcPZMZU4TGzERZ1x0NCnd7wUCZRk1EAAKCRARZ1x0NCnd
+761TAPsHdh+FI5/eoR1/vSKJ8nCBXVmP6xR9q5bHvknbyzcGJAD/Zq5BWgkYnfBR
+M3Ow6FM7EZ7+iAlkIRAavYHASGXERQ4=
+=QvU5
+-----END PGP SIGNATURE-----
r8168-8.051.02.tar.gz/Makefile -> r8168-8.052.01.tar.gz/Makefile
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/Makefile -> r8168-8.052.01.tar.gz/src/Makefile
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
CONFIG_DYNAMIC_ASPM = y
ENABLE_USE_FIRMWARE_FILE = n
CONFIG_CTAP_SHORT_OFF = n
+ENABLE_MULTIPLE_TX_QUEUE = n
+ENABLE_RSS_SUPPORT = n
+ENABLE_LIB_SUPPORT = n
+DISABLE_WOL_SUPPORT = n
ifneq ($(KERNELRELEASE),)
obj-m := r8168.o
r8168-objs += r8168_dash.o
EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT
endif
- EXTRA_CFLAGS += -DCONFIG_R8168_NAPI
+ ifneq ($(ENABLE_RSS_SUPPORT), y)
+ EXTRA_CFLAGS += -DCONFIG_R8168_NAPI
+ endif
EXTRA_CFLAGS += -DCONFIG_R8168_VLAN
ifeq ($(CONFIG_DOWN_SPEED_100), y)
EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100
ifeq ($(CONFIG_CTAP_SHORT_OFF), y)
EXTRA_CFLAGS += -DCONFIG_CTAP_SHORT_OFF
endif
+ ifeq ($(ENABLE_MULTIPLE_TX_QUEUE), y)
+ EXTRA_CFLAGS += -DENABLE_MULTIPLE_TX_QUEUE
+ endif
+ ifeq ($(ENABLE_RSS_SUPPORT), y)
+ r8168-objs += r8168_rss.o
+ EXTRA_CFLAGS += -DENABLE_RSS_SUPPORT
+ endif
+ ifeq ($(ENABLE_LIB_SUPPORT), y)
+ r8168-objs += r8168_lib.o
+ EXTRA_CFLAGS += -DENABLE_LIB_SUPPORT
+ endif
+ ifeq ($(DISABLE_WOL_SUPPORT), y)
+ EXTRA_CFLAGS += -DDISABLE_WOL_SUPPORT
+ endif
else
BASEDIR := /lib/modules/$(shell uname -r)
KERNELDIR ?= $(BASEDIR)/build
r8168-8.051.02.tar.gz/src/Makefile_linux24x -> r8168-8.052.01.tar.gz/src/Makefile_linux24x
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/r8168.h -> r8168-8.052.01.tar.gz/src/r8168.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
***********************************************************************************/
#include <linux/ethtool.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
#include "r8168_dash.h"
#include "r8168_realwow.h"
#include "r8168_fiber.h"
+#include "r8168_rss.h"
+#ifdef ENABLE_LIB_SUPPORT
+#include "r8168_lib.h"
+#endif
+
+/*
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)&& !defined(ENABLE_LIB_SUPPORT)
+#define RTL_USE_NEW_INTR_API
+#endif
+*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
typedef int netdev_tx_t;
#endif
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)
-#define RTL_ALLOC_SKB_INTR(tp, length) dev_alloc_skb(length)
+#define RTL_ALLOC_SKB_INTR(napi, length) dev_alloc_skb(length)
+#define R8168_USE_NAPI_ALLOC_SKB 0
#ifdef CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0)
#undef RTL_ALLOC_SKB_INTR
-#define RTL_ALLOC_SKB_INTR(tp, length) napi_alloc_skb(&tp->napi, length)
+#define RTL_ALLOC_SKB_INTR(napi, length) napi_alloc_skb(napi, length)
+#undef R8168_USE_NAPI_ALLOC_SKB
+#define R8168_USE_NAPI_ALLOC_SKB 1
#endif
#endif
#ifndef NET_IP_ALIGN
#define NET_IP_ALIGN 2
#endif
-#define RTK_RX_ALIGN 8
+#define RTK_RX_ALIGN NET_IP_ALIGN
#ifdef CONFIG_R8168_NAPI
#define NAPI_SUFFIX "-NAPI"
#else
#define DASH_SUFFIX ""
#endif
+#if defined(ENABLE_RSS_SUPPORT)
+#define RSS_SUFFIX "-RSS"
+#else
+#define RSS_SUFFIX ""
+#endif
-#define RTL8168_VERSION "8.051.02" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX
+#define RTL8168_VERSION "8.052.01" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX RSS_SUFFIX
#define MODULENAME "r8168"
#define PFX MODULENAME ": "
#define GPL_CLAIM "\
-r8168 Copyright (C) 2022 Realtek NIC software team <nicfae@realtek.com> \n \
+r8168 Copyright (C) 2023 Realtek NIC software team <nicfae@realtek.com> \n \
This program comes with ABSOLUTELY NO WARRANTY; for details, please see <http://www.gnu.org/licenses/>. \n \
This is free software, and you are welcome to redistribute it under certain conditions; see <http://www.gnu.org/licenses/>. \n"
#define R8168_PCI_REGS_SIZE (0x100)
#define R8168_NAPI_WEIGHT 64
+#define R8168_MAX_MSIX_VEC 4
+
#define RTL8168_TX_TIMEOUT (6 * HZ)
#define RTL8168_LINK_TIMEOUT (1 * HZ)
#define RTL8168_ESD_TIMEOUT (2 * HZ)
#define MIN_NUM_TX_DESC 32 /* Minimum number of Tx descriptor registers */
#define MIN_NUM_RX_DESC 32 /* Minimum number of Rx descriptor registers */
-#define NUM_TX_DESC 256 /* Number of Tx descriptor registers */
-#define NUM_RX_DESC 256 /* Number of Rx descriptor registers */
+#define NUM_TX_DESC 1024 /* Number of Tx descriptor registers */
+#define NUM_RX_DESC 1024 /* Number of Rx descriptor registers */
-#define RX_BUF_SIZE 0x05F3 /* 0x05F3 = 1522bye + 1 */
+#define RX_BUF_SIZE 0x05F2 /* 0x05F2 = 1522bye */
+#define R8168_MAX_TX_QUEUES (2)
+#define R8168_MAX_RX_QUEUES (4)
+#define R8168_MAX_QUEUES R8168_MAX_RX_QUEUES
+#define R8168_MULTI_TX_Q(tp) (rtl8168_tot_tx_rings(tp) > 1)
+#define R8168_MULTI_RX_Q(tp) (rtl8168_tot_rx_rings(tp) > 1)
+#define R8168_MULTI_RX_4Q(tp) (rtl8168_tot_rx_rings(tp) > 3)
+#define R8168_MULTI_RSS_4Q(tp) (tp->num_hw_tot_en_rx_rings > 3)
#define OCP_STD_PHY_BASE 0xa400
typedef struct napi_struct *napi_ptr;
typedef int napi_budget;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
+#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add_weight(ndev, &priv->napi, function, weight)
+#else
#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight)
+#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
#define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget)
#define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr)
#define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev;
ERIAR = 0x74,
EPHY_RXER_NUM = 0x7C,
EPHYAR = 0x80,
+ IntrMask1 = 0x84,
+ IntrMask2 = 0x85,
+ IntrStatus1 = 0x86,
+ IntrStatus2 = 0x87,
TimeInt2 = 0x8C,
+ Rss_indir_tbl = 0x90,
OCPDR = 0xB0,
MACOCP = 0xB0,
OCPAR = 0xB4,
SecMAC0 = 0xB4,
SecMAC4 = 0xB8,
PHYOCP = 0xB8,
+ IntrMask3 = 0xC0,
+ IntrStatus3 = 0xC1,
DBG_reg = 0xD1,
TwiCmdReg = 0xD2,
MCUCmd_reg = 0xD3,
CMAC_IBIMR0 = 0xFA,
CMAC_IBISR0 = 0xFB,
FuncForceEvent = 0xFC,
+
+ /* ERI */
+ RSS_KEY_8168 = 0x90,
+ RSS_CTRL_8168 = 0xB8,
+ Q_NUM_CTRL_8168 = 0xC0,
+
+ /* MAC OCP */
+ EEE_TXIDLE_TIMER_8168 = 0xe048,
};
enum RTL8168_register_content {
TxOK = 0x0004,
RxErr = 0x0002,
RxOK = 0x0001,
+ RxDU1 = 0x0002,
+ RxOK1 = 0x0001,
/* RxStatusDesc */
RxRWT = (1 << 22),
RxCfg_fet_multi_en = (1 << 14),
RxCfg_half_refetch = (1 << 13),
RxCfg_9356SEL = (1 << 6),
+ RxCfg_rx_desc_v2_en = (1 << 24),
/* TxConfigBits */
TxInterFrameGapShift = 24,
BIT_31 = (1 << 31)
};
+#define RTL8168_CP_NUM 4
+#define RTL8168_MAX_SUPPORT_cp_len 110
+
+enum rtl8168_cp_status {
+ rtl8168_cp_normal = 0,
+ rtl8168_cp_short,
+ rtl8168_cp_open,
+ rtl8168_cp_mismatch,
+ rtl8168_cp_unknown
+};
+
enum effuse {
EFUSE_NOT_SUPPORT = 0,
EFUSE_SUPPORT_V1,
u64 addr;
};
+struct RxDescV2 {
+ u32 opts1;
+ u32 opts2;
+ u64 addr;
+ u32 rsvd1;
+ u32 RSSResult;
+ u64 rsvd2;
+};
+
+//Rx Desc Type
+enum rx_desc_ring_type {
+ RX_DESC_RING_TYPE_UNKNOWN=0,
+ RX_DESC_RING_TYPE_1,
+ RX_DESC_RING_TYPE_2,
+ RX_DESC_RING_TYPE_3,
+ RX_DESC_RING_TYPE_MAX
+};
+
+enum rx_desc_len {
+ RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)),
+ RX_DESC_LEN_TYPE_2 = (sizeof(struct RxDescV2))
+};
+
struct ring_info {
struct sk_buff *skb;
u32 len;
u32 pci_sn_h;
};
+enum r8168_flag {
+ R8168_FLAG_DOWN = 0,
+ R8168_FLAG_TASK_RESET_PENDING,
+ R8168_FLAG_TASK_ESD_CHECK_PENDING,
+ R8168_FLAG_TASK_LINKCHG_CHECK_PENDING,
+ R8168_FLAG_MAX
+};
+
/* Flow Control Settings */
enum rtl8168_fc_mode {
rtl8168_fc_none = 0,
rtl8168_fc_default
};
-struct rtl8168_private {
- void __iomem *mmio_addr; /* memory map physical address */
- struct pci_dev *pci_dev; /* Index of PCI device */
- struct net_device *dev;
+struct rtl8168_tx_ring {
+ void* priv;
+ u32 index;
+ u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
+ u32 dirty_tx;
+ u32 num_tx_desc; /* Number of Tx descriptor registers */
+ u32 tdu; /* Tx descriptor unavailable count */
+ struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
+ dma_addr_t TxPhyAddr;
+ u32 TxDescAllocSize;
+ struct ring_info tx_skbNUM_TX_DESC; /* Tx data buffers */
+
+ u16 tdsar_reg; /* Transmit Descriptor Start Address */
+};
+
+struct rtl8168_rx_ring {
+ void* priv;
+ u32 index;
+ u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
+ u32 dirty_rx;
+ u32 rdu; /* Rx descriptor unavailable count */
+ //struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */
+ //u32 RxDescAllocSize;
+ u64 RxDescPhyAddrMAX_NUM_RX_DESC; /* Rx desc physical address*/
+ //dma_addr_t RxPhyAddr;
+ struct sk_buff *Rx_skbuffMAX_NUM_RX_DESC; /* Rx data buffers */
+
+ //u16 rdsar_reg; /* Receive Descriptor Start Address */
+};
+
+struct r8168_napi {
#ifdef CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
struct napi_struct napi;
#endif
#endif
+ void* priv;
+ int index;
+};
+
+struct r8168_irq {
+ irq_handler_t handler;
+ unsigned int vector;
+ u8 requested;
+ char nameIFNAMSIZ + 10;
+};
+
+#pragma pack(1)
+struct rtl8168_regs {
+ //00
+ u8 mac_id6;
+ u16 reg_06;
+ u8 mar8;
+ //10
+ u64 dtccr;
+ u16 ledsel0;
+ u16 legreg;
+ u32 tctr3;
+ //20
+ u32 txq0_dsc_st_addr_0;
+ u32 txq0_dsc_st_addr_2;
+ u64 reg_28;
+ //30
+ u16 rit;
+ u16 ritc;
+ u16 reg_34;
+ u8 reg_36;
+ u8 command;
+ u32 imr0;
+ u32 isr0;
+ //40
+ u32 tcr;
+ u32 rcr;
+ u32 tctr0;
+ u32 tctr1;
+ //50
+ u8 cr93c46;
+ u8 config0;
+ u8 config1;
+ u8 config2;
+ u8 config3;
+ u8 config4;
+ u8 config5;
+ u8 tdfnr;
+ u32 timer_int0;
+ u32 timer_int1;
+ //60
+ u32 gphy_mdcmdio;
+ u32 csidr;
+ u32 csiar;
+ u16 phy_status;
+ u8 config6;
+ u8 pmch;
+ //70
+ u32 eridr;
+ u32 eriar;
+ u16 config7;
+ u16 reg_7a;
+ u32 ephy_rxerr_cnt;
+ //80
+ u32 ephy_mdcmdio;
+ u16 ledsel2;
+ u16 ledsel1;
+ u32 tctr2;
+ u32 timer_int2;
+ //90
+ u8 tppoll0;
+ u8 reg_91;
+ u16 reg_92;
+ u16 led_feature;
+ u16 ledsel3;
+ u16 eee_led_config;
+ u16 reg_9a;
+ u32 reg_9c;
+ //a0
+ u32 reg_a0;
+ u32 reg_a4;
+ u32 reg_a8;
+ u32 reg_ac;
+ //b0
+ u32 patch_dbg;
+ u32 reg_b4;
+ u32 gphy_ocp;
+ u32 reg_bc;
+ //c0
+ u32 reg_c0;
+ u32 reg_c4;
+ u32 reg_c8;
+ u16 otp_cmd;
+ u16 otp_pg_config;
+ //d0
+ u16 phy_pwr;
+ u8 twsi_ctrl;
+ u8 oob_ctrl;
+ u16 mac_dbgo;
+ u16 mac_dbg;
+ u16 reg_d8;
+ u16 rms;
+ u32 efuse_data;
+ //e0
+ u16 cplus_cmd;
+ u16 reg_e2;
+ u32 rxq0_dsc_st_addr_0;
+ u32 rxq0_dsc_st_addr_2;
+ u16 reg_ec;
+ u16 tx10midle_cnt;
+ //f0
+ u16 misc0;
+ u16 misc1;
+ u32 timer_int3;
+ u32 cmac_ib;
+ u16 reg_fc;
+ u16 sw_rst;
+};
+#pragma pack()
+
+struct rtl8168_regs_save {
+ union {
+ u8 mac_ioR8168_MAC_REGS_SIZE;
+
+ struct rtl8168_regs mac_reg;
+ };
+ u16 pcie_phyR8168_EPHY_REGS_SIZE/2;
+ u16 eth_phyR8168_PHY_REGS_SIZE/2;
+ u32 eri_regR8168_ERI_REGS_SIZE/4;
+ u32 pci_regR8168_PCI_REGS_SIZE/4;
+
+ //ktime_t begin_ktime;
+ //ktime_t end_ktime;
+ //u64 duration_ns;
+
+
+ u16 int_miti_rxq0;
+
+ u8 int_config;
+ u32 imr_new;
+ u32 isr_new;
+
+ u8 tdu_status;
+ u16 rdu_status;
+
+ u32 rss_ctrl;
+ u8 rss_keyRTL8168_RSS_KEY_SIZE;
+ u8 rss_i_tableRTL8168_MAX_INDIRECTION_TABLE_ENTRIES;
+ u16 rss_queue_num_sel_r;
+};
+
+struct rtl8168_counters {
+ /* legacy */
+ u64 tx_packets;
+ u64 rx_packets;
+ u64 tx_errors;
+ u32 rx_errors;
+ u16 rx_missed;
+ u16 align_errors;
+ u32 tx_one_collision;
+ u32 tx_multi_collision;
+ u64 rx_unicast;
+ u64 rx_broadcast;
+ u32 rx_multicast;
+ u16 tx_aborted;
+ u16 tx_underrun;
+};
+
+struct rtl8168_private {
+ void __iomem *mmio_addr; /* memory map physical address */
+ struct pci_dev *pci_dev; /* Index of PCI device */
+ struct pci_dev *pdev_cmac; /* Index of PCI device */
+ struct net_device *dev;
+ struct r8168_napi r8168napiR8168_MAX_MSIX_VEC;
+ struct r8168_irq irq_tblR8168_MAX_MSIX_VEC;
+ unsigned int irq_nvecs;
+ unsigned int max_irq_nvecs;
+ unsigned int min_irq_nvecs;
+ unsigned int hw_supp_irq_nvecs;
struct net_device_stats stats; /* statistics of net device */
- spinlock_t lock; /* spin lock flag */
u32 msg_enable;
u32 tx_tcp_csum_cmd;
u32 tx_udp_csum_cmd;
int max_jumbo_frame_size;
int chipset;
u32 mcfg;
- u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
- u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
- u32 dirty_rx;
- u32 dirty_tx;
+ //u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
+ // u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
+ //u32 dirty_rx;
+ //u32 dirty_tx;
u32 num_rx_desc; /* Number of Rx descriptor registers */
- u32 num_tx_desc; /* Number of Tx descriptor registers */
- struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
+ //u32 num_tx_desc; /* Number of Tx descriptor registers */
+ //struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */
- dma_addr_t TxPhyAddr;
+ //dma_addr_t TxPhyAddr;
dma_addr_t RxPhyAddr;
- u32 TxDescAllocSize;
+ //u32 TxDescAllocSize;
u32 RxDescAllocSize;
- struct sk_buff *Rx_skbuffMAX_NUM_RX_DESC; /* Rx data buffers */
- struct ring_info tx_skbMAX_NUM_TX_DESC; /* Tx data buffers */
+ //struct sk_buff *Rx_skbuffMAX_NUM_RX_DESC; /* Rx data buffers */
+ //struct ring_info tx_skbMAX_NUM_TX_DESC; /* Tx data buffers */
unsigned rx_buf_sz;
- struct timer_list esd_timer;
- struct timer_list link_timer;
+ u16 HwSuppNumTxQueues; // Number of tx ring that hardware can support
+ u16 HwSuppNumRxQueues; // Number of rx ring that hardware can support
+ unsigned int num_tx_rings; // Number of tx ring that non-ring-lib driver used
+ unsigned int num_rx_rings; // Number of rx ring that non-ring-lib driver used
+ struct rtl8168_tx_ring tx_ringR8168_MAX_TX_QUEUES; // non-ring-lib tx ring
+ struct rtl8168_rx_ring rx_ringR8168_MAX_RX_QUEUES; // non-ring-lib rx ring
+#ifdef ENABLE_LIB_SUPPORT
+ struct blocking_notifier_head lib_nh;
+ struct rtl8168_ring lib_tx_ringR8168_MAX_TX_QUEUES; // ring-lib tx ring
+ struct rtl8168_ring lib_rx_ringR8168_MAX_RX_QUEUES; // ring-lib rx ring
+#endif
+ u16 num_hw_tot_en_rx_rings; // Number of rx ring that hardware enabled
+ //struct timer_list esd_timer;
+ //struct timer_list link_timer;
struct pci_resource pci_cfg_space;
unsigned int esd_flag;
unsigned int pci_cfg_is_read;
u16 cp_cmd;
u16 intr_mask;
u16 timer_intr_mask;
- int irq;
+ u16 isr_regR8168_MAX_MSIX_VEC;
+ u16 imr_regR8168_MAX_MSIX_VEC;
int phy_auto_nego_reg;
int phy_1000_ctrl_reg;
u8 org_mac_addrNODE_ADDRESS_SIZE;
unsigned int (*phy_reset_pending)(struct net_device *);
unsigned int (*link_ok)(struct net_device *);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct task;
+ struct work_struct reset_task;
+ struct work_struct esd_task;
+ struct work_struct linkchg_task;
#else
- struct delayed_work task;
+ struct delayed_work reset_task;
+ struct delayed_work esd_task;
+ struct delayed_work linkchg_task;
#endif
+ DECLARE_BITMAP(task_flags, R8168_FLAG_MAX);
unsigned features;
u8 org_pci_offset_99;
u16 BackupPhyFuseDout_47_32;
u16 BackupPhyFuseDout_63_48;
+ u8 ring_lib_enabled;
+
const char *fw_name;
struct rtl8168_fw *rtl_fw;
u32 ocp_base;
u8 DASH;
u8 dash_printer_enabled;
u8 HwPkgDet;
- void __iomem *mapped_cmac_ioaddr; /* mapped cmac memory map physical address */
void __iomem *cmac_ioaddr; /* cmac memory map physical address */
#ifdef ENABLE_DASH_SUPPORT
//Realwow--------------
#endif //ENABLE_REALWOW_SUPPORT
- u32 eee_adv_t;
- u8 eee_enabled;
+ struct ethtool_eee eee;
u32 dynamic_aspm_packet_count;
//Procfs support
struct proc_dir_entry *proc_dir;
#endif
+ u8 HwSuppRxDescType;
+ u8 InitRxDescType;
+ u16 RxDescLength; //V1 16 Byte V2 32 Bytes
+
+ u8 HwSuppRssVer;
+ u8 EnableRss;
+ u16 HwSuppIndirTblEntries;
+#ifdef ENABLE_RSS_SUPPORT
+ u32 rss_flags;
+ /* Receive Side Scaling settings */
+#define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
+ u8 rss_keyRTL8168_RSS_KEY_SIZE;
+#define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128
+ u8 rss_indir_tblRTL8168_MAX_INDIRECTION_TABLE_ENTRIES;
+ u32 rss_options;
+#endif
+ u32 rx_fifo_of; /* Rx fifo overflow count */
};
+#ifdef ENABLE_LIB_SUPPORT
+static inline unsigned int
+rtl8168_num_lib_tx_rings(struct rtl8168_private *tp)
+{
+ int count, i;
+
+ for (count = 0, i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++)
+ if(tp->lib_tx_ringi.enabled)
+ count++;
+
+ return count;
+}
+
+static inline unsigned int
+rtl8168_num_lib_rx_rings(struct rtl8168_private *tp)
+{
+ int count, i;
+
+ for (count = 0, i = tp->num_rx_rings; i < tp->HwSuppNumRxQueues; i++)
+ if(tp->lib_rx_ringi.enabled)
+ count++;
+
+ return count;
+}
+
+static inline bool
+rtl8168_lib_tx_ring_released(struct rtl8168_private *tp)
+{
+ int i;
+ bool released = 0;
+
+ for (i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_ring *ring = &tp->lib_tx_ringi;
+ if (ring->allocated)
+ goto exit;
+ }
+
+ released = 1;
+
+exit:
+ return released;
+}
+
+static inline bool
+rtl8168_lib_rx_ring_released(struct rtl8168_private *tp)
+{
+ int i;
+ bool released = 0;
+
+ for (i = tp->num_rx_rings; i < tp->HwSuppNumRxQueues; i++) {
+ struct rtl8168_ring *ring = &tp->lib_rx_ringi;
+ if (ring->allocated)
+ goto exit;
+ }
+
+ released = 1;
+
+exit:
+ return released;
+}
+
+#else
+
+static inline unsigned int
+rtl8168_num_lib_tx_rings(struct rtl8168_private *tp)
+{
+ return 0;
+}
+
+static inline unsigned int
+rtl8168_num_lib_rx_rings(struct rtl8168_private *tp)
+{
+ return 0;
+}
+
+static inline bool
+rtl8168_lib_tx_ring_released(struct rtl8168_private *tp)
+{
+ return 1;
+}
+
+static inline bool
+rtl8168_lib_rx_ring_released(struct rtl8168_private *tp)
+{
+ return 1;
+}
+#endif
+
+static inline unsigned int
+rtl8168_tot_tx_rings(struct rtl8168_private *tp)
+{
+ return tp->num_tx_rings + rtl8168_num_lib_tx_rings(tp);
+}
+
+static inline unsigned int
+rtl8168_tot_rx_rings(struct rtl8168_private *tp)
+{
+ return tp->num_rx_rings + rtl8168_num_lib_rx_rings(tp);
+}
+
+static inline bool
+rtl8168_lib_all_ring_released(struct rtl8168_private *tp)
+{
+ return (rtl8168_lib_tx_ring_released(tp) &&
+ rtl8168_lib_rx_ring_released(tp));
+}
+
enum eetype {
EEPROM_TYPE_NONE=0,
EEPROM_TYPE_93C46,
CFG_METHOD_33,
CFG_METHOD_34,
CFG_METHOD_35,
+ CFG_METHOD_36,
+ CFG_METHOD_37,
CFG_METHOD_MAX,
CFG_METHOD_DEFAULT = 0xFF
};
#define NIC_RAMCODE_VERSION_CFG_METHOD_23 (0x0015)
#define NIC_RAMCODE_VERSION_CFG_METHOD_26 (0x0012)
#define NIC_RAMCODE_VERSION_CFG_METHOD_28 (0x0019)
-#define NIC_RAMCODE_VERSION_CFG_METHOD_29 (0x0055)
+#define NIC_RAMCODE_VERSION_CFG_METHOD_29 (0x0083)
#define NIC_RAMCODE_VERSION_CFG_METHOD_31 (0x0003)
-#define NIC_RAMCODE_VERSION_CFG_METHOD_35 (0x0019)
+#define NIC_RAMCODE_VERSION_CFG_METHOD_35 (0x0027)
+#define NIC_RAMCODE_VERSION_CFG_METHOD_36 (0x0000)
//hwoptimize
#define HW_PATCH_SOC_LAN (BIT_0)
#define HW_PATCH_SAMSUNG_LAN_DONGLE (BIT_2)
+static const u8 other_q_intr_mask = (RxOK1 | RxDU1);
+
#define HW_PHY_STATUS_INI 1
#define HW_PHY_STATUS_EXT_INI 2
#define HW_PHY_STATUS_LAN_ON 3
void rtl8168_dash2_disable_rx(struct rtl8168_private *tp);
void rtl8168_dash2_enable_rx(struct rtl8168_private *tp);
void rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev);
+void rtl8168_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz);
+
+static inline struct RxDesc*
+rtl8168_get_rxdesc(struct rtl8168_private *tp, struct RxDesc *RxDescBase, u32 const cur_rx, u32 const q_num)
+{
+ u8 *desc = (u8*)RxDescBase;
+ u32 offset;
+
+ WARN_ON_ONCE(q_num >= tp->num_hw_tot_en_rx_rings);
+
+ if (tp->InitRxDescType == RX_DESC_RING_TYPE_2)
+ offset = (cur_rx * tp->num_hw_tot_en_rx_rings) + q_num;
+ else
+ offset = cur_rx;
+
+ offset *= tp->RxDescLength;
+ desc += offset;
+
+ return (struct RxDesc*)desc;
+}
+
+static inline void
+rtl8168_disable_interrupt_by_vector(struct rtl8168_private *tp,
+ u32 message_id)
+{
+ if (message_id >= R8168_MAX_MSIX_VEC)
+ return;
+
+ if (message_id == 0) {
+ RTL_W16(tp, tp->imr_reg0, 0x0000);
+#ifdef ENABLE_DASH_SUPPORT
+ if (tp->DASH)
+ rtl8168_disable_dash2_interrupt(tp);
+#endif
+ } else
+ RTL_W8(tp, tp->imr_regmessage_id, 0x00);
+}
+
+static inline void
+rtl8168_enable_interrupt_by_vector(struct rtl8168_private *tp,
+ u32 message_id)
+{
+ if (message_id >= R8168_MAX_MSIX_VEC)
+ return;
+
+ if (message_id == 0) {
+ RTL_W16(tp, tp->imr_reg0, tp->intr_mask);
+#ifdef ENABLE_DASH_SUPPORT
+ if (tp->DASH)
+ rtl8168_enable_dash2_interrupt(tp);
+#endif
+ } else {
+ RTL_W8(tp, tp->imr_regmessage_id, other_q_intr_mask);
+ }
+}
+
+int rtl8168_open(struct net_device *dev);
+int rtl8168_close(struct net_device *dev);
+void rtl8168_hw_config(struct net_device *dev);
+void rtl8168_hw_start(struct net_device *dev);
+void rtl8168_hw_reset(struct net_device *dev);
+void rtl8168_tx_clear(struct rtl8168_private *tp);
+void rtl8168_rx_clear(struct rtl8168_private *tp);
+int rtl8168_init_ring(struct net_device *dev);
+int rtl8168_dump_tally_counter(struct rtl8168_private *tp, dma_addr_t paddr);
+void rtl8168_enable_napi(struct rtl8168_private *tp);
+void _rtl8168_wait_for_quiescence(struct net_device *dev);
+
+#ifndef ENABLE_LIB_SUPPORT
+static inline void rtl8168_lib_reset_prepare(struct rtl8168_private *tp) { }
+static inline void rtl8168_lib_reset_complete(struct rtl8168_private *tp) { }
+#endif
#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0 )
#define HW_SUPP_SERDES_PHY(_M) ((_M)->HwSuppSerDesPhyVer > 0)
#define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0)
#define HW_SUPPORT_UPS_MODE(_M) ((_M)->HwSuppUpsVer > 0)
+#define HW_RSS_SUPPORT_RSS(_M) ((_M)->HwSuppRssVer > 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
#define netdev_mc_count(dev) ((dev)->mc_count)
r8168-8.051.02.tar.gz/src/r8168_asf.c -> r8168-8.052.01.tar.gz/src/r8168_asf.c
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
struct rtl8168_private *tp = netdev_priv(dev);
void *user_data = ifr->ifr_data;
struct asf_ioctl_struct asf_usrdata;
- unsigned long flags;
if (tp->mcfg != CFG_METHOD_7 && tp->mcfg != CFG_METHOD_8)
return -EOPNOTSUPP;
if (copy_from_user(&asf_usrdata, user_data, sizeof(struct asf_ioctl_struct)))
return -EFAULT;
- spin_lock_irqsave(&tp->lock, flags);
-
switch (asf_usrdata.offset) {
case HBPeriod:
rtl8168_asf_hbperiod(tp, asf_usrdata.arg, asf_usrdata.u.data);
rtl8168_asf_key_access(tp, asf_usrdata.arg, KR, asf_usrdata.u.data);
break;
default:
- spin_unlock_irqrestore(&tp->lock, flags);
return -EOPNOTSUPP;
}
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (copy_to_user(user_data, &asf_usrdata, sizeof(struct asf_ioctl_struct)))
return -EFAULT;
r8168-8.051.02.tar.gz/src/r8168_asf.h -> r8168-8.052.01.tar.gz/src/r8168_asf.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/r8168_dash.h -> r8168-8.052.01.tar.gz/src/r8168_dash.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/r8168_fiber.h -> r8168-8.052.01.tar.gz/src/r8168_fiber.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/r8168_firmware.c -> r8168-8.052.01.tar.gz/src/r8168_firmware.c
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/r8168_firmware.h -> r8168-8.052.01.tar.gz/src/r8168_firmware.h
Changed
# r8168 is the Linux device driver released for Realtek 2.5Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/r8168_n.c -> r8168-8.052.01.tar.gz/src/r8168_n.c
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
#include <linux/mdio.h>
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10)
+#include <net/gso.h>
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10) */
+
#include <asm/io.h>
#include <asm/irq.h>
#define FIRMWARE_8168H_1 "rtl_nic/rtl8168h-1.fw"
#define FIRMWARE_8168H_2 "rtl_nic/rtl8168h-2.fw"
#define FIRMWARE_8168H_3 "rtl_nic/rtl8168h-3.fw"
+#define FIRMWARE_8168H_4 "rtl_nic/rtl8168h-4.fw"
#define FIRMWARE_8168FP_3 "rtl_nic/rtl8168fp-3.fw"
#define FIRMWARE_8168FP_4 "rtl_nic/rtl8168fp-4.fw"
CFG_METHOD_33 = {"RTL8168FP/8111FP", FIRMWARE_8168FP_4},
CFG_METHOD_34 = {"RTL8168FP/8111FP", FIRMWARE_8168FP_4},
CFG_METHOD_35 = {"RTL8168H/8111H", FIRMWARE_8168H_3},
+ CFG_METHOD_36 = {"RTL8168H/8111H", FIRMWARE_8168H_4},
+ CFG_METHOD_37 = {"RTL8168M/8111M", FIRMWARE_8168H_2},
CFG_METHOD_DEFAULT = {"Unknown", },
};
_R("RTL8168G/8111G",
CFG_METHOD_21,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168G/8111G",
CFG_METHOD_22,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168EP/8111EP",
CFG_METHOD_23,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168GU/8111GU",
CFG_METHOD_24,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168GU/8111GU",
CFG_METHOD_25,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("8411B",
CFG_METHOD_26,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168EP/8111EP",
CFG_METHOD_27,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168EP/8111EP",
CFG_METHOD_28,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168H/8111H",
CFG_METHOD_29,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168H/8111H",
CFG_METHOD_30,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168FP/8111FP",
CFG_METHOD_31,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168FP/8111FP",
CFG_METHOD_32,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168FP/8111FP",
CFG_METHOD_33,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168FP/8111FP",
CFG_METHOD_34,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168H/8111H",
CFG_METHOD_35,
- RxCfg_128_int_en | RxEarly_off_V2 | Rx_Single_fetch_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ 0xff7e5880,
+ Jumbo_Frame_9k),
+
+ _R("RTL8168H/8111H",
+ CFG_METHOD_36,
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
+ 0xff7e5880,
+ Jumbo_Frame_9k),
+
+ _R("RTL8168M/8111M",
+ CFG_METHOD_37,
+ RxCfg_128_int_en | RxEarly_off_V2 | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
MODULE_DEVICE_TABLE(pci, rtl8168_pci_tbl);
-static int rx_copybreak = 0;
static int use_dac = 1;
static int timer_count = 0x2600;
static int dynamic_aspm_packet_threshold = 10;
#else
static int s0_magic_packet = 0;
#endif
+#ifdef DISABLE_WOL_SUPPORT
+static int disable_wol_support = 1;
+#else
+static int disable_wol_support = 0;
+#endif
MODULE_AUTHOR("Realtek and the Linux r8168 crew <netdev@vger.kernel.org>");
MODULE_DESCRIPTION("RealTek RTL-8168 Gigabit Ethernet driver");
module_param(s5_keep_curr_mac, int, 0);
MODULE_PARM_DESC(s5_keep_curr_mac, "Enable Shutdown Keep Current MAC Address.");
-module_param(rx_copybreak, int, 0);
-MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
-
module_param(use_dac, int, 0);
MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot.");
module_param(dynamic_aspm_packet_threshold, int, 0);
MODULE_PARM_DESC(dynamic_aspm_packet_threshold, "Dynamic ASPM packet threshold.");
+module_param(disable_wol_support, int, 0);
+MODULE_PARM_DESC(disable_wol_support, "Disable PM support.");
+
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
module_param_named(debug, debug.msg_enable, int, 0);
MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)");
MODULE_FIRMWARE(FIRMWARE_8168H_1);
MODULE_FIRMWARE(FIRMWARE_8168H_2);
MODULE_FIRMWARE(FIRMWARE_8168H_3);
+MODULE_FIRMWARE(FIRMWARE_8168H_4);
MODULE_FIRMWARE(FIRMWARE_8168FP_3);
MODULE_FIRMWARE(FIRMWARE_8168FP_4);
#endif
static void rtl8168_sleep_rx_enable(struct net_device *dev);
static void rtl8168_dsm(struct net_device *dev, int dev_state);
+/*
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
static void rtl8168_esd_timer(unsigned long __opaque);
#else
#else
static void rtl8168_link_timer(struct timer_list *t);
#endif
-static void rtl8168_tx_clear(struct rtl8168_private *tp);
-static void rtl8168_rx_clear(struct rtl8168_private *tp);
+*/
-static int rtl8168_open(struct net_device *dev);
static netdev_tx_t rtl8168_start_xmit(struct sk_buff *skb, struct net_device *dev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance);
#endif
static void rtl8168_rx_desc_offset0_init(struct rtl8168_private *, int);
-static int rtl8168_init_ring(struct net_device *dev);
-static void rtl8168_hw_config(struct net_device *dev);
-static void rtl8168_hw_start(struct net_device *dev);
-static int rtl8168_close(struct net_device *dev);
static void rtl8168_set_rx_mode(struct net_device *dev);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
static void rtl8168_tx_timeout(struct net_device *dev, unsigned int txqueue);
static void rtl8168_tx_timeout(struct net_device *dev);
#endif
static struct net_device_stats *rtl8168_get_stats(struct net_device *dev);
-static int rtl8168_rx_interrupt(struct net_device *, struct rtl8168_private *, napi_budget);
+static int rtl8168_rx_interrupt(struct net_device *, struct rtl8168_private *, struct rtl8168_rx_ring *, napi_budget);
+#ifdef CONFIG_R8168_NAPI
+static int rtl8168_poll_msix_ring(napi_ptr napi, napi_budget budget);
+static int rtl8168_poll_msix_rx(napi_ptr napi, napi_budget budget);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static irqreturn_t rtl8168_interrupt_msix(int irq, void *dev_instance, struct pt_regs *regs);
+#else
+static irqreturn_t rtl8168_interrupt_msix(int irq, void *dev_instance);
+#endif
+static void rtl8168_wait_for_quiescence(struct net_device *dev);
static int rtl8168_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8168_down(struct net_device *dev);
static u16 rtl8168_get_hw_phy_mcu_code_ver(struct rtl8168_private *tp);
-static void rtl8168_hw_reset(struct net_device *dev);
-
static void rtl8168_phy_power_up(struct net_device *dev);
static void rtl8168_phy_power_down(struct net_device *dev);
static int rtl8168_set_speed(struct net_device *dev, u8 autoneg, u32 speed, u8 duplex, u32 adv);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
static void rtl8168_reset_task(void *_data);
+static void rtl8168_esd_task(void *_data);
+static void rtl8168_linkchg_task(void *_data);
#else
static void rtl8168_reset_task(struct work_struct *work);
+static void rtl8168_esd_task(struct work_struct *work);
+static void rtl8168_linkchg_task(struct work_struct *work);
#endif
+static void rtl8168_schedule_reset_work(struct rtl8168_private *tp);
+static void rtl8168_schedule_esd_work(struct rtl8168_private *tp);
+static void rtl8168_schedule_linkchg_work(struct rtl8168_private *tp);
+static void rtl8168_init_all_schedule_work(struct rtl8168_private *tp);
+static void rtl8168_cancel_all_schedule_work(struct rtl8168_private *tp);
static inline struct device *tp_to_dev(struct rtl8168_private *tp)
{
}
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
-struct rtl8168_counters {
- u64 tx_packets;
- u64 rx_packets;
- u64 tx_errors;
- u32 rx_errors;
- u16 rx_missed;
- u16 align_errors;
- u32 tx_one_collision;
- u32 tx_multi_collision;
- u64 rx_unicast;
- u64 rx_broadcast;
- u32 rx_multicast;
- u16 tx_aborted;
- u16 tx_underrun;
-};
+int rtl8168_dump_tally_counter(struct rtl8168_private *tp, dma_addr_t paddr)
+{
+ u32 cmd;
+ u32 WaitCnt;
+ int retval = -1;
+
+ RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32);
+ cmd = (u64)paddr & DMA_BIT_MASK(32);
+ RTL_W32(tp, CounterAddrLow, cmd);
+ RTL_W32(tp, CounterAddrLow, cmd | CounterDump);
+
+ WaitCnt = 0;
+ while (RTL_R32(tp, CounterAddrLow) & CounterDump) {
+ udelay(10);
+
+ WaitCnt++;
+ if (WaitCnt > 20)
+ break;
+ }
+
+ if (WaitCnt <= 20)
+ retval = 0;
+
+ return retval;
+}
+
+static u32 rtl8168_convert_link_speed(u16 status)
+{
+ u32 speed = SPEED_UNKNOWN;
+
+ if (status & LinkStatus) {
+ if (status & _1000bpsF)
+ speed = SPEED_1000;
+ else if (status & _100bps)
+ speed = SPEED_100;
+ else if (status & _10bps)
+ speed = SPEED_10;
+ }
+
+ return speed;
+}
+
+static int rtl8168_vcd_test(struct rtl8168_private *tp)
+{
+ u16 val;
+ u32 wait_cnt;
+ int ret = -1;
+
+ rtl8168_mdio_write(tp, 0x1f, 0x0a43);
+ rtl8168_mdio_write(tp, 0x13, 0x8169);
+ rtl8168_mdio_write(tp, 0x14, 0x18c1);
+ rtl8168_mdio_write(tp, 0x13, 0x816b);
+ rtl8168_mdio_write(tp, 0x14, 0xc7b0);
+ rtl8168_mdio_write(tp, 0x13, 0x816d);
+ rtl8168_mdio_write(tp, 0x14, 0x5933);
+ rtl8168_mdio_write(tp, 0x13, 0x816f);
+ rtl8168_mdio_write(tp, 0x14, 0xb920);
+ rtl8168_mdio_write(tp, 0x13, 0x8171);
+ rtl8168_mdio_write(tp, 0x14, 0xee07);
+ rtl8168_mdio_write(tp, 0x13, 0x8162);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x13, 0x8173);
+ rtl8168_mdio_write(tp, 0x14, 0x0304);
+ rtl8168_mdio_write(tp, 0x1f, 0x0000);
+
+ rtl8168_mdio_write(tp, 0x1f, 0x0a42);
+ rtl8168_clear_eth_phy_bit(tp, 0x11, BIT(0));
+ rtl8168_set_eth_phy_bit(tp, 0x11, 0x00f0);
+ rtl8168_set_eth_phy_bit(tp, 0x11, BIT(0));
+
+ wait_cnt = 0;
+ do {
+ mdelay(1);
+ val = rtl8168_mdio_read(tp, 0x11);
+ wait_cnt++;
+ } while (!(val & BIT_15) && (wait_cnt < 5000));
+
+ if (wait_cnt == 5000)
+ goto exit;
+
+ ret = 0;
+
+exit:
+ rtl8168_mdio_write(tp, 0x1f, 0x0000);
+
+ return ret;
+}
+
+static void rtl8168_get_cp_len(struct rtl8168_private *tp,
+ u16 cp_lenRTL8168_CP_NUM)
+{
+ int i;
+ u16 status;
+ u16 tmp_cp_len = 0;
+
+ status = RTL_R8(tp, PHYstatus);
+ if (status & LinkStatus) {
+ if (status & _10bps) {
+ tmp_cp_len = 0;
+ } else if (status & _1000bpsF) {
+ rtl8168_mdio_write(tp, 0x1f, 0x0a88);
+ tmp_cp_len = rtl8168_mdio_read(tp, 0x10);
+ } else
+ goto exit;
+ } else
+ goto exit;
+
+ tmp_cp_len &= 0xff;
+ for (i=0; i<RTL8168_CP_NUM; i++)
+ cp_leni = tmp_cp_len;
+
+exit:
+ rtl8168_mdio_write(tp, 0x1f, 0x0000);
+
+ for (i=0; i<RTL8168_CP_NUM; i++)
+ if (cp_leni > RTL8168_MAX_SUPPORT_cp_len)
+ cp_leni = RTL8168_MAX_SUPPORT_cp_len;
+
+ return;
+}
+
+static int __rtl8168_get_cp_status(u16 val)
+{
+ switch (val) {
+ case 0x0060:
+ return rtl8168_cp_normal;
+ case 0x0048:
+ return rtl8168_cp_open;
+ case 0x0050:
+ return rtl8168_cp_short;
+ case 0x0042:
+ case 0x0044:
+ return rtl8168_cp_mismatch;
+ default:
+ return rtl8168_cp_normal;
+ }
+}
+
+static int _rtl8168_get_cp_status(struct rtl8168_private *tp, u8 pair_num)
+{
+ u16 val;
+ int cp_status = rtl8168_cp_unknown;
+
+ if (pair_num > 3)
+ goto exit;
+
+ rtl8168_mdio_write(tp, 0x1f, 0x0a43);
+ rtl8168_mdio_write(tp, 0x13, 0x802b + 4 * pair_num);
+ val = rtl8168_mdio_read(tp, 0x14);
+ rtl8168_mdio_write(tp, 0x1f, 0x0000);
+
+ cp_status = __rtl8168_get_cp_status(val);
+
+exit:
+ return cp_status;
+}
+
+static const char * rtl8168_get_cp_status_string(int cp_status)
+{
+ switch(cp_status) {
+ case rtl8168_cp_normal:
+ return "normal ";
+ case rtl8168_cp_short:
+ return "short ";
+ case rtl8168_cp_open:
+ return "open ";
+ case rtl8168_cp_mismatch:
+ return "mismatch";
+ default:
+ return "unknown ";
+ }
+}
+
+static u16 rtl8168_get_cp_pp(struct rtl8168_private *tp, u8 pair_num)
+{
+ u16 pp = 0;
+
+ if (pair_num > 3)
+ goto exit;
+
+ rtl8168_mdio_write(tp, 0x1f, 0x0a43);
+ rtl8168_mdio_write(tp, 0x13, 0x802d + 4 * pair_num);
+ pp = rtl8168_mdio_read(tp, 0x14);
+ rtl8168_mdio_write(tp, 0x1f, 0x0000);
+
+ pp &= 0x3fff;
+ pp /= 80;
+
+exit:
+ return pp;
+}
+
+static void rtl8168_get_cp_status(struct rtl8168_private *tp,
+ int cp_statusRTL8168_CP_NUM)
+{
+ int i;
+
+ for (i =0; i<RTL8168_CP_NUM; i++)
+ cp_statusi = _rtl8168_get_cp_status(tp, i);
+}
#ifdef ENABLE_R8168_PROCFS
/****************************************************************************
{
struct net_device *dev = m->private;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
seq_puts(m, "\nDump Driver Variable\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
seq_puts(m, "Variable\tValue\n----------\t-----\n");
seq_printf(m, "MODULENAME\t%s\n", MODULENAME);
seq_printf(m, "driver version\t%s\n", RTL8168_VERSION);
seq_printf(m, "chipset\t%d\n", tp->chipset);
seq_printf(m, "chipset_name\t%s\n", rtl_chip_infotp->chipset.name);
seq_printf(m, "mtu\t%d\n", dev->mtu);
- seq_printf(m, "NUM_RX_DESC\t0x%x\n", tp->num_rx_desc);
- seq_printf(m, "cur_rx\t0x%x\n", tp->cur_rx);
- seq_printf(m, "dirty_rx\t0x%x\n", tp->dirty_rx);
- seq_printf(m, "NUM_TX_DESC\t0x%x\n", tp->num_tx_desc);
- seq_printf(m, "cur_tx\t0x%x\n", tp->cur_tx);
- seq_printf(m, "dirty_tx\t0x%x\n", tp->dirty_tx);
+ seq_printf(m, "num_rx_desc\t0x%x\n", tp->num_rx_desc);
+ seq_printf(m, "cur_rx0\t0x%x\n", tp->rx_ring0.cur_rx);
+ seq_printf(m, "dirty_rx0\t0x%x\n", tp->rx_ring0.dirty_rx);
+ seq_printf(m, "rdu0\t0x%x\n", tp->rx_ring0.rdu);
+ seq_printf(m, "cur_rx1\t0x%x\n", tp->rx_ring1.cur_rx);
+ seq_printf(m, "dirty_rx1\t0x%x\n", tp->rx_ring1.dirty_rx);
+ seq_printf(m, "rdu1\t0x%x\n", tp->rx_ring1.rdu);
+ seq_printf(m, "cur_rx2\t0x%x\n", tp->rx_ring2.cur_rx);
+ seq_printf(m, "dirty_rx2\t0x%x\n", tp->rx_ring2.dirty_rx);
+ seq_printf(m, "rdu2\t0x%x\n", tp->rx_ring2.rdu);
+ seq_printf(m, "cur_rx3\t0x%x\n", tp->rx_ring3.cur_rx);
+ seq_printf(m, "dirty_rx3\t0x%x\n", tp->rx_ring3.dirty_rx);
+ seq_printf(m, "rdu3\t0x%x\n", tp->rx_ring3.rdu);
+ seq_printf(m, "rx_fifo_of\t0x%x\n", tp->rx_fifo_of);
+ seq_printf(m, "num_tx_desc\t0x%x\n", tp->tx_ring0.num_tx_desc);
+ seq_printf(m, "cur_tx0\t0x%x\n", tp->tx_ring0.cur_tx);
+ seq_printf(m, "dirty_tx0\t0x%x\n", tp->tx_ring0.dirty_tx);
+ seq_printf(m, "tdu0\t0x%x\n", tp->tx_ring0.tdu);
+ seq_printf(m, "cur_tx1\t0x%x\n", tp->tx_ring1.cur_tx);
+ seq_printf(m, "dirty_tx1\t0x%x\n", tp->tx_ring1.dirty_tx);
+ seq_printf(m, "tdu1\t0x%x\n", tp->tx_ring1.tdu);
seq_printf(m, "rx_buf_sz\t0x%x\n", tp->rx_buf_sz);
seq_printf(m, "esd_flag\t0x%x\n", tp->esd_flag);
seq_printf(m, "pci_cfg_is_read\t0x%x\n", tp->pci_cfg_is_read);
seq_printf(m, "aspm\t0x%x\n", aspm);
seq_printf(m, "s5wol\t0x%x\n", s5wol);
seq_printf(m, "s5_keep_curr_mac\t0x%x\n", s5_keep_curr_mac);
- seq_printf(m, "eee_enable\t0x%x\n", tp->eee_enabled);
+ seq_printf(m, "eee_enable\t0x%x\n", tp->eee.eee_enabled);
seq_printf(m, "hwoptimize\t0x%lx\n", hwoptimize);
seq_printf(m, "proc_init_num\t0x%x\n", proc_init_num);
seq_printf(m, "s0_magic_packet\t0x%x\n", s0_magic_packet);
+ seq_printf(m, "disable_wol_support\t0x%x\n", disable_wol_support);
seq_printf(m, "HwSuppMagicPktVer\t0x%x\n", tp->HwSuppMagicPktVer);
seq_printf(m, "HwSuppUpsVer\t0x%x\n", tp->HwSuppUpsVer);
seq_printf(m, "HwSuppEsdVer\t0x%x\n", tp->HwSuppEsdVer);
seq_printf(m, "HwSuppCheckPhyDisableModeVer\t0x%x\n", tp->HwSuppCheckPhyDisableModeVer);
seq_printf(m, "HwPkgDet\t0x%x\n", tp->HwPkgDet);
+ seq_printf(m, "InitRxDescType\t0x%x\n", tp->InitRxDescType);
+ seq_printf(m, "RxDescLength\t0x%x\n", tp->RxDescLength);
+ seq_printf(m, "num_rx_rings\t0x%x\n", tp->num_rx_rings);
+ seq_printf(m, "num_tx_rings\t0x%x\n", tp->num_tx_rings);
+ seq_printf(m, "tot_rx_rings\t0x%x\n", rtl8168_tot_rx_rings(tp));
+ seq_printf(m, "tot_tx_rings\t0x%x\n", rtl8168_tot_tx_rings(tp));
+ seq_printf(m, "HwSuppNumTxQueues\t0x%x\n", tp->HwSuppNumTxQueues);
+ seq_printf(m, "HwSuppNumRxQueues\t0x%x\n", tp->HwSuppNumRxQueues);
+ seq_printf(m, "num_hw_tot_en_rx_rings\t0x%x\n", tp->num_hw_tot_en_rx_rings);
+ seq_printf(m, "EnableRss\t0x%x\n", tp->EnableRss);
+ seq_printf(m, "min_irq_nvecs\t0x%x\n", tp->min_irq_nvecs);
+ seq_printf(m, "max_irq_nvecs\t0x%x\n", tp->max_irq_nvecs);
+ seq_printf(m, "irq_nvecs\t0x%x\n", tp->irq_nvecs);
+ seq_printf(m, "hw_supp_irq_nvecs\t0x%x\n", tp->hw_supp_irq_nvecs);
+ seq_printf(m, "ring_lib_enabled\t0x%x\n", tp->ring_lib_enabled);
seq_printf(m, "random_mac\t0x%x\n", tp->random_mac);
seq_printf(m, "org_mac_addr\t%pM\n", tp->org_mac_addr);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
seq_printf(m, "perm_addr\t%pM\n", dev->perm_addr);
#endif
seq_printf(m, "dev_addr\t%pM\n", dev->dev_addr);
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
seq_putc(m, '\n');
return 0;
struct rtl8168_private *tp = netdev_priv(dev);
struct rtl8168_counters *counters;
dma_addr_t paddr;
- u32 cmd;
- u32 WaitCnt;
- unsigned long flags;
seq_puts(m, "\nDump Tally Counter\n");
- //ASSERT_RTNL();
+ rtnl_lock();
counters = tp->tally_vaddr;
paddr = tp->tally_paddr;
if (!counters) {
seq_puts(m, "\nDump Tally Counter Fail\n");
- return 0;
+ goto out_unlock;
}
- spin_lock_irqsave(&tp->lock, flags);
- RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32);
- cmd = (u64)paddr & DMA_BIT_MASK(32);
- RTL_W32(tp, CounterAddrLow, cmd);
- RTL_W32(tp, CounterAddrLow, cmd | CounterDump);
-
- WaitCnt = 0;
- while (RTL_R32(tp, CounterAddrLow) & CounterDump) {
- udelay(10);
-
- WaitCnt++;
- if (WaitCnt > 20)
- break;
- }
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtl8168_dump_tally_counter(tp, paddr);
seq_puts(m, "Statistics\tValue\n----------\t-----\n");
seq_printf(m, "tx_packets\t%lld\n", le64_to_cpu(counters->tx_packets));
seq_printf(m, "tx_aborted\t%d\n", le16_to_cpu(counters->tx_aborted));
seq_printf(m, "tx_underrun\t%d\n", le16_to_cpu(counters->tx_underrun));
+out_unlock:
+ rtnl_unlock();
+
seq_putc(m, '\n');
return 0;
}
u8 byte_rd;
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
- unsigned long flags;
seq_puts(m, "\nDump MAC Registers\n");
seq_puts(m, "Offset\tValue\n------\t-----\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
seq_printf(m, "\n0x%02x:\t", n);
seq_printf(m, "%02x ", byte_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
seq_putc(m, '\n');
return 0;
int i, n, max = R8168_EPHY_REGS_SIZE/2;
u16 word_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
seq_puts(m, "\nDump PCIE PHY\n");
seq_puts(m, "\nOffset\tValue\n------\t-----\n ");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
seq_printf(m, "\n0x%02x:\t", n);
seq_printf(m, "%04x ", word_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
seq_putc(m, '\n');
return 0;
int i, n, max = R8168_PHY_REGS_SIZE/2;
u16 word_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
seq_puts(m, "\nDump Ethernet PHY\n");
seq_puts(m, "\nOffset\tValue\n------\t-----\n ");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
seq_puts(m, "\n####################page 0##################\n ");
rtl8168_mdio_write(tp, 0x1f, 0x0000);
for (n = 0; n < max;) {
seq_printf(m, "%04x ", word_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
seq_putc(m, '\n');
return 0;
int i, n, max = R8168_ERI_REGS_SIZE;
u32 dword_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
switch (tp->mcfg) {
case CFG_METHOD_1:
seq_puts(m, "\nDump Extended Registers\n");
seq_puts(m, "\nOffset\tValue\n------\t-----\n ");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
seq_printf(m, "\n0x%02x:\t", n);
seq_printf(m, "%08x ", dword_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
seq_putc(m, '\n');
return 0;
int i, n, max = R8168_PCI_REGS_SIZE;
u32 dword_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
seq_puts(m, "\nDump PCI Registers\n");
seq_puts(m, "\nOffset\tValue\n------\t-----\n ");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
seq_printf(m, "\n0x%03x:\t", n);
pci_read_config_dword(tp->pci_dev, n, &dword_rd);
seq_printf(m, "\n0x%03x:\t%08x ", n, dword_rd);
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtnl_unlock();
+
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static int proc_get_cable_info(struct seq_file *m, void *v)
+{
+ int i;
+ u16 status;
+ int cp_statusRTL8168_CP_NUM = {0};
+ u16 cp_lenRTL8168_CP_NUM = {0};
+ struct net_device *dev = m->private;
+ struct rtl8168_private *tp = netdev_priv(dev);
+ const char *pair_strRTL8168_CP_NUM = {"1-2", "3-6", "4-5", "7-8"};
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_30:
+ case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
+ /* support */
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ rtnl_lock();
+
+ rtl8168_mdio_write(tp, 0x1f, 0x0000);
+ if (rtl8168_mdio_read(tp, MII_BMCR) & BMCR_PDOWN) {
+ rtnl_unlock();
+ return -EIO;
+ }
+
+ status = RTL_R8(tp, PHYstatus);
+ if (status & LinkStatus)
+ seq_printf(m, "\nlink speed:%d",
+ rtl8168_convert_link_speed(status));
+ else
+ seq_puts(m, "\nlink status:off");
+
+ rtl8168_get_cp_len(tp, cp_len);
+
+ rtl8168_vcd_test(tp);
+
+ rtl8168_get_cp_status(tp, cp_status);
+
+ seq_puts(m, "\npair\tlength\tstatus \tpp\n");
+
+ for (i =0; i<RTL8168_CP_NUM; i++) {
+ seq_printf(m, "%s\t%d\t%s\t",
+ pair_stri, cp_leni,
+ rtl8168_get_cp_status_string(cp_statusi));
+ if (cp_statusi == rtl8168_cp_normal)
+ seq_printf(m, "none\n");
+ else
+ seq_printf(m, "%dm\n", rtl8168_get_cp_pp(tp, i));
+ }
+
+ tp->phy_reset_enable(dev);
+
+ rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising);
+
+ rtnl_unlock();
+
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static int proc_dump_rx_desc(struct seq_file *m, void *v)
+{
+ int i;
+ u32 *pdword;
+ struct net_device *dev = m->private;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ if (!tp->RxDescArray)
+ return -EOPNOTSUPP;
+
+ rtnl_lock();
+
+ seq_printf(m, "\ndump rx desc:%d\n", tp->num_rx_desc);
+
+ pdword = (u32*)tp->RxDescArray;
+ for (i=0; i<(tp->RxDescAllocSize/4); i++) {
+ if (!(i % 4))
+ seq_printf(m, "\n%04x ", i);
+ seq_printf(m, "%08x ", pdwordi);
+ }
+
+ rtnl_unlock();
+
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static int proc_dump_rx_desc_2(struct seq_file *m, void *v)
+{
+ int i, j, k;
+ u32 *pdword;
+ struct net_device *dev = m->private;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ if (!tp->RxDescArray)
+ return -EOPNOTSUPP;
+
+ rtnl_lock();
+
+ for (k=0; k<tp->num_hw_tot_en_rx_rings; k++) {
+ seq_printf(m, "\ndump Q%d rx desc:%d\n", k, tp->num_rx_desc);
+ for (j=0; j<tp->num_rx_desc; j++) {
+ pdword = (u32*)rtl8168_get_rxdesc(tp,
+ tp->RxDescArray,
+ j, k);
+ for (i=0; i<(tp->RxDescLength/4); i++) {
+ if (!(i % 4))
+ seq_printf(m, "\n%04llx ",
+ ((u64)pdword + (i * 4) -
+ (u64)tp->RxDescArray));
+ seq_printf(m, "%08x ", pdwordi);
+ }
+ }
+
+ seq_putc(m, '\n');
+ }
+
+ rtnl_unlock();
+
+ seq_putc(m, '\n');
+ return 0;
+}
+
+void _proc_dump_tx_desc(struct seq_file *m, struct TxDesc *desc_base,
+ u32 alloc_size, u32 num_desc)
+{
+ int i;
+ u32 *pdword;
+
+ if (desc_base == NULL ||
+ alloc_size == 0 ||
+ num_desc == 0)
+ return;
+
+ pdword = (u32*)desc_base;
+ for (i=0; i<(alloc_size/4); i++) {
+ if (!(i % 4))
+ seq_printf(m, "\n%04x ", i);
+ seq_printf(m, "%08x ", pdwordi);
+ }
+
+ seq_putc(m, '\n');
+ return;
+}
+
+static int proc_dump_tx_desc(struct seq_file *m, void *v)
+{
+ int i;
+ struct net_device *dev = m->private;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ for (i=0; i<tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ if (!ring->TxDescArray)
+ continue;
+ seq_printf(m, "\ndump Q%d tx desc:%d\n", i, ring->num_tx_desc);
+ _proc_dump_tx_desc(m, ring->TxDescArray,
+ ring->TxDescAllocSize,
+ ring->num_tx_desc);
+ }
+
+#ifdef ENABLE_LIB_SUPPORT
+ for (i=0; i<tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_ring *ring = &tp->lib_tx_ringi;
+ if (!ring->desc_addr)
+ continue;
+ seq_printf(m, "\ndump lib Q%d tx desc:%d\n", i, ring->ring_size);
+ _proc_dump_tx_desc(m, ring->desc_addr,
+ ring->desc_size,
+ ring->ring_size);
+ }
+#endif //ENABLE_LIB_SUPPORT
+
+ rtnl_unlock();
+
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static int proc_dump_msix_tbl(struct seq_file *m, void *v)
+{
+ int i, j;
+ struct net_device *dev = m->private;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_8:
+ return -EOPNOTSUPP;
+ default:
+ break;
+ }
+
+ rtnl_lock();
+
+ seq_printf(m, "\ndump MSI-X Table. Total Entry %d. \n",
+ tp->hw_supp_irq_nvecs);
+
+ for (i=0; i<tp->hw_supp_irq_nvecs; i++) {
+ seq_printf(m, "\n%04x ", i);
+ for (j=0; j<4; j++)
+ seq_printf(m, "%08x ",
+ rtl8168_eri_read(
+ tp, i*0x10 + 4 * j, 4,
+ ERIAR_MSIX));
+ }
+
+ rtnl_unlock();
seq_putc(m, '\n');
return 0;
{
struct net_device *dev = data;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
int len = 0;
len += snprintf(page + len, count - len,
"\nDump Driver Driver\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
len += snprintf(page + len, count - len,
"Variable\tValue\n----------\t-----\n");
"chipset\t%d\n"
"chipset_name\t%s\n"
"mtu\t%d\n"
- "NUM_RX_DESC\t0x%x\n"
- "cur_rx\t0x%x\n"
- "dirty_rx\t0x%x\n"
- "NUM_TX_DESC\t0x%x\n"
- "cur_tx\t0x%x\n"
- "dirty_tx\t0x%x\n"
+ "num_rx_desc\t0x%x\n"
+ "cur_rx0\t0x%x\n"
+ "dirty_rx0\t0x%x\n"
+ "rdu0\t0x%x\n"
+ "cur_rx1\t0x%x\n"
+ "dirty_rx1\t0x%x\n"
+ "rdu1\t0x%x\n"
+ "cur_rx2\t0x%x\n"
+ "dirty_rx2\t0x%x\n"
+ "rdu2\t0x%x\n"
+ "cur_rx3\t0x%x\n"
+ "dirty_rx3\t0x%x\n"
+ "rdu3\t0x%x\n"
+ "rx_fifo_of\t0x%x\n"
+ "num_tx_desc\t0x%x\n"
+ "cur_tx0\t0x%x\n"
+ "dirty_tx0\t0x%x\n"
+ "tdu0\t0x%x\n"
+ "cur_tx1\t0x%x\n"
+ "dirty_tx1\t0x%x\n"
+ "tdu0\t1x%x\n"
"rx_buf_sz\t0x%x\n"
"esd_flag\t0x%x\n"
"pci_cfg_is_read\t0x%x\n"
"hwoptimize\t0x%lx\n"
"proc_init_num\t0x%x\n"
"s0_magic_packet\t0x%x\n"
+ "disable_wol_support\t0x%x\n"
"HwSuppMagicPktVer\t0x%x\n"
"HwSuppUpsVer\t0x%x\n"
"HwSuppEsdVer\t0x%x\n"
"HwSuppCheckPhyDisableModeVer\t0x%x\n"
"HwPkgDet\t0x%x\n"
+ "InitRxDescType\t0x%x\n"
+ "RxDescLength\t0x%x\n"
+ "num_rx_rings\t0x%x\n"
+ "num_tx_rings\t0x%x\n"
+ "tot_rx_rings\t0x%x\n"
+ "tot_tx_rings\t0x%x\n"
+ "tot_rx_desc_rings\t0x%x\n"
+ "HwSuppNumTxQueues\t0x%x\n"
+ "HwSuppNumRxQueues\t0x%x\n"
+ "num_hw_tot_en_rx_rings\t0x%x\n"
+ "EnableRss\t0x%x\n"
+ "min_irq_nvecs\t0x%x\n"
+ "max_irq_nvecs\t0x%x\n"
+ "irq_nvecs\t0x%x\n"
+ "hw_supp_irq_nvecs\t0x%x\n"
+ "ring_lib_enabled\t0x%x\n"
"random_mac\t0x%x\n"
"org_mac_addr\t%pM\n"
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
rtl_chip_infotp->chipset.name,
dev->mtu,
tp->num_rx_desc,
- tp->cur_rx,
- tp->dirty_rx,
- tp->num_tx_desc,
- tp->cur_tx,
- tp->dirty_tx,
+ tp->rx_ring0.cur_rx,
+ tp->rx_ring0.dirty_rx,
+ tp->rx_ring0.rdu,
+ tp->rx_ring1.cur_rx,
+ tp->rx_ring1.dirty_rx,
+ tp->rx_ring1.rdu,
+ tp->rx_ring2.cur_rx,
+ tp->rx_ring2.dirty_rx,
+ tp->rx_ring2.rdu,
+ tp->rx_ring3.cur_rx,
+ tp->rx_ring3.dirty_rx,
+ tp->rx_ring3.rdu,
+ tp->rx_fifo_of,
+ tp->tx_ring0.num_tx_desc,
+ tp->tx_ring0.cur_tx,
+ tp->tx_ring0.dirty_tx,
+ tp->tx_ring0.tdu,
+ tp->tx_ring1.cur_tx,
+ tp->tx_ring1.dirty_tx,
+ tp->tx_ring1.tdu,
tp->rx_buf_sz,
tp->esd_flag,
tp->pci_cfg_is_read,
aspm,
s5wol,
s5_keep_curr_mac,
- tp->eee_enabled,
+ tp->eee.eee_enabled,
hwoptimize,
proc_init_num,
s0_magic_packet,
+ disable_wol_support,
tp->HwSuppMagicPktVer,
tp->HwSuppUpsVer,
tp->HwSuppEsdVer,
tp->HwSuppCheckPhyDisableModeVer,
tp->HwPkgDet,
+ tp->InitRxDescType,
+ tp->RxDescLength,
+ tp->num_rx_rings,
+ tp->num_tx_rings,
+ rtl8168_tot_rx_rings(tp),
+ rtl8168_tot_tx_rings(tp),
+ tp->HwSuppNumTxQueues,
+ tp->HwSuppNumRxQueues,
+ tp->num_hw_tot_en_rx_rings,
+ tp->EnableRss,
+ tp->min_irq_nvecs,
+ tp->max_irq_nvecs,
+ tp->irq_nvecs,
+ tp->hw_supp_irq_nvecs,
+ tp->ring_lib_enabled,
tp->random_mac,
tp->org_mac_addr,
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
#endif
dev->dev_addr
);
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
len += snprintf(page + len, count - len, "\n");
dma_addr_t paddr;
u32 cmd;
u32 WaitCnt;
- unsigned long flags;
int len = 0;
len += snprintf(page + len, count - len,
"\nDump Tally Counter\n");
- //ASSERT_RTNL();
+ rtnl_lock();
counters = tp->tally_vaddr;
paddr = tp->tally_paddr;
if (!counters) {
len += snprintf(page + len, count - len,
"\nDump Tally Counter Fail\n");
- goto out;
+ goto out_unlock;
}
- spin_lock_irqsave(&tp->lock, flags);
- RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32);
- cmd = (u64)paddr & DMA_BIT_MASK(32);
- RTL_W32(tp, CounterAddrLow, cmd);
- RTL_W32(tp, CounterAddrLow, cmd | CounterDump);
-
- WaitCnt = 0;
- while (RTL_R32(tp, CounterAddrLow) & CounterDump) {
- udelay(10);
-
- WaitCnt++;
- if (WaitCnt > 20)
- break;
- }
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtl8168_dump_tally_counter(tp, paddr);
len += snprintf(page + len, count - len,
"Statistics\tValue\n----------\t-----\n");
);
len += snprintf(page + len, count - len, "\n");
-out:
+out_unlock:
+ rtnl_unlock();
+
*eof = 1;
return len;
}
u8 byte_rd;
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
- unsigned long flags;
int len = 0;
len += snprintf(page + len, count - len,
"\nDump MAC Registers\n"
"Offset\tValue\n------\t-----\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
len += snprintf(page + len, count - len,
"\n0x%02x:\t",
byte_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
len += snprintf(page + len, count - len, "\n");
int i, n, max = R8168_EPHY_REGS_SIZE/2;
u16 word_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
int len = 0;
len += snprintf(page + len, count - len,
"\nDump PCIE PHY\n"
"Offset\tValue\n------\t-----\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
len += snprintf(page + len, count - len,
"\n0x%02x:\t",
word_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
len += snprintf(page + len, count - len, "\n");
int i, n, max = R8168_PHY_REGS_SIZE/2;
u16 word_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
int len = 0;
len += snprintf(page + len, count - len,
"\nDump Ethernet PHY\n"
"Offset\tValue\n------\t-----\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
len += snprintf(page + len, count - len,
"\n####################page 0##################\n");
rtl8168_mdio_write(tp, 0x1f, 0x0000);
word_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
len += snprintf(page + len, count - len, "\n");
int i, n, max = R8168_ERI_REGS_SIZE;
u32 dword_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
int len = 0;
switch (tp->mcfg) {
"\nDump Extended Registers\n"
"Offset\tValue\n------\t-----\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
len += snprintf(page + len, count - len,
"\n0x%02x:\t",
dword_rd);
}
}
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
len += snprintf(page + len, count - len, "\n");
out:
int i, n, max = R8168_PCI_REGS_SIZE;
u32 dword_rd;
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
int len = 0;
len += snprintf(page + len, count - len,
"\nDump PCI Registers\n"
"Offset\tValue\n------\t-----\n");
- spin_lock_irqsave(&tp->lock, flags);
+ rtnl_lock();
+
for (n = 0; n < max;) {
len += snprintf(page + len, count - len,
"\n0x%03x:\t",
"\n0x%03x:\t%08x ",
n,
dword_rd);
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ rtnl_unlock();
len += snprintf(page + len, count - len, "\n");
*eof = 1;
return len;
}
-#endif
+
+static int proc_get_cable_info(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int i;
+ u16 status;
+ int len = 0;
+ struct net_device *dev = data;
+ int cp_statusRTL8168_CP_NUM = {0};
+ u16 cp_lenRTL8168_CP_NUM = {0};
+ struct rtl8168_private *tp = netdev_priv(dev);
+ const char *pair_strRTL8168_CP_NUM = {"1-2", "3-6", "4-5", "7-8"};
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_30:
+ case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
+ /* support */
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ rtnl_lock();
+
+ status = RTL_R8(tp, PHYstatus);
+ if (status & LinkStatus)
+ len += snprintf(page + len, count - len,
+ "\nlink speed:%d",
+ rtl8168_convert_link_speed(status));
+ else
+ len += snprintf(page + len, count - len,
+ "\nlink status:off");
+
+ rtl8168_get_cp(tp, cp_len, cp_status);
+
+ len += snprintf(page + len, count - len,
+ "\npair\tlength\tstatus \tpp\n");
+
+ for (i =0; i<RTL8168_CP_NUM; i++) {
+ len += snprintf(page + len, count - len,
+ "%s\t%d\t%s\t",
+ pair_stri, cp_leni,
+ rtl8168_get_cp_status_string(cp_statusi));
+ if (cp_statusi == rtl8168_cp_normal)
+ len += snprintf(page + len, count - len, "none\n");
+ else
+ len += snprintf(page + len, count - len, "%dm\n",
+ rtl8168_get_cp_pp(tp, i));
+ }
+
+ rtnl_unlock();
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *eof = 1;
+ return len;
+}
+
+static int proc_dump_rx_desc(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int i;
+ int len = 0;
+ u32 *pdword;
+ struct net_device *dev = data;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ if (!tp->RxDescArray)
+ return -EOPNOTSUPP;
+
+ rtnl_lock();
+
+ len += snprintf(page + len, count - len,
+ "\ndump rx desc:%d",
+ tp->num_rx_desc);
+
+ pdword = (u32*)tp->RxDescArray;
+ for (i=0; i<(tp->RxDescAllocSize/4); i++) {
+ if (!(i % 4))
+ len += snprintf(page + len, count - len,
+ "\n%04x ",
+ i);
+ len += snprintf(page + len, count - len,
+ "%08x ",
+ pdwordi);
+ }
+
+ rtnl_unlock();
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_dump_rx_desc_2(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int i, j, k;
+ int len = 0;
+ u32 *pdword;
+ struct net_device *dev = data;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ if (!tp->RxDescArray)
+ return -EOPNOTSUPP;
+
+ rtnl_lock();
+
+ for (k=0; k<tp->num_hw_tot_en_rx_rings; k++) {
+ len += snprintf(page + len, count - len,
+ "\ndump Q%d rx desc:%d",
+ k,
+ tp->num_rx_desc);
+ for (j=0; j<tp->num_rx_desc; j++) {
+ pdword = (u32*)rtl8168_get_rxdesc(tp,
+ tp->RxDescArray,
+ j, k);
+ for (i=0; i<(tp->RxDescLength/4); i++) {
+ if (!(i % 4))
+ len += snprintf(page + len, count - len,
+ "\n%04llx ",
+ ((u64)pdword + (i * 4) -
+ (u64)tp->RxDescArray));
+ len += snprintf(page + len, count - len,
+ "%08x ",
+ pdwordi);
+ }
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+ }
+
+ rtnl_unlock();
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *eof = 1;
+
+ return len;
+}
+
+void _proc_dump_tx_desc(char *page, int *page_len, int *count,
+ struct TxDesc *desc_base,
+ u32 alloc_size, u32 num_desc)
+{
+ int i;
+ int len = 0;
+ u32 *pdword;
+
+ if (desc_base == NULL ||
+ alloc_size == 0 ||
+ num_desc == 0)
+ return;
+
+ len = *page_len;
+ pdword = (u32*)desc_base;
+ for (i=0; i<(alloc_size/4); i++) {
+ if (!(i % 4))
+ len += snprintf(page + len, *count - len,
+ "\n%04x ",
+ i);
+ len += snprintf(page + len, *count - len,
+ "%08x ",
+ pdwordi);
+ }
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *page_len = len;
+ return;
+}
+
+static int proc_dump_tx_desc(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int i;
+ int len = 0;
+ u32 *pdword;
+ struct net_device *dev = data;
+ struct rtl8168_private *tp = netdev_priv(dev);
+ struct rtl8168_tx_ring *ring = &tp->tx_ring0;
+
+ if (!ring->TxDescArray)
+ return -EOPNOTSUPP;
+
+ rtnl_lock();
+
+ for (i=0; i<tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ if (!ring->TxDescArray)
+ continue;
+ len += snprintf(page + len, count - len,
+ "\ndump Q%d tx desc:%d",
+ i,
+ ring->num_tx_desc);
+ _proc_dump_tx_desc(page, &len, &count,
+ ring->TxDescArray,
+ ring->TxDescAllocSize,
+ ring->num_tx_desc);
+ }
+
+#ifdef ENABLE_LIB_SUPPORT
+ for (i=0; i<tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_ring *ring = &tp->lib_tx_ringi;
+ if (!ring->desc_addr)
+ continue;
+ len += snprintf(page + len, count - len,
+ "\ndump lib Q%d tx desc:%d",
+ i,
+ ring->ring_size);
+ _proc_dump_tx_desc(page, &len, ring->desc_addr,
+ ring->desc_size,
+ ring->ring_size);
+ }
+#endif //ENABLE_LIB_SUPPORT
+
+ rtnl_unlock();
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_dump_tx_desc(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int i;
+ struct net_device *dev = m->private;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_8:
+ return -EOPNOTSUPP;
+ default:
+ break;
+ }
+
+ rtnl_lock();
+
+ len += snprintf(page + len, count - len,
+ "\ndump MSI-X Table. Total Entry %d. \n",
+ R8168_MAX_MSIX_VEC);
+
+ for (i=0; i<R8168_MAX_MSIX_VEC; i++) {
+ len += snprintf(page + len, count - len,
+ "\n%04x ",
+ i);
+ len += snprintf(page + len, count - len,
+ "%08x ",
+ rtl8168_eri_read(tp, i*0x10, 4,
+ ERIAR_MSIX));
+ len += snprintf(page + len, count - len,
+ "%08x ",
+ rtl8168_eri_read(tp, i*0x10 + 4, 4,
+ ERIAR_MSIX));
+ len += snprintf(page + len, count - len,
+ "%08x ",
+ rtl8168_eri_read(tp, i*0x10 + 8, 4,
+ ERIAR_MSIX));
+ len += snprintf(page + len, count - len,
+ "%08x ",
+ rtl8168_eri_read(tp, i*0x10 + 12, 4,
+ ERIAR_MSIX));
+ }
+
+ rtnl_unlock();
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *eof = 1;
+
+ return len;
+}
+
+static int proc_dump_msix_tbl(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int i, j;
+ int len = 0;
+ struct net_device *dev = data;
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ rtnl_lock();
+
+ len += snprintf(page + len, count - len,
+ "\ndump MSI-X Table. Total Entry %d. \n",
+ tp->hw_supp_irq_nvecs);
+
+ for (i=0; i<tp->hw_supp_irq_nvecs; i++) {
+ len += snprintf(page + len, count - len,
+ "\n%04x ", i);
+ for (j=0; j<4; j++)
+ len += snprintf(page + len, count - len, "%08x ",
+ rtl8168_eri_read(tp, i*0x10 + 4*j, 4,
+ ERIAR_MSIX));
+ }
+
+ rtnl_unlock();
+
+ len += snprintf(page + len, count - len, "\n");
+
+ *eof = 1;
+ return 0;
+}
+#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+
static void rtl8168_proc_module_init(void)
{
//create /proc/net/r8168
{ "eth_phy", &proc_get_eth_phy },
{ "ext_regs", &proc_get_extended_registers },
{ "pci_regs", &proc_get_pci_registers },
+ { "cdt", &proc_get_cable_info },
+ { "tx_desc", &proc_dump_tx_desc },
+ { "rx_desc", &proc_dump_rx_desc },
+ { "rx_desc_2", &proc_dump_rx_desc_2 },
+ { "msix_tbl", &proc_dump_msix_tbl },
{ "" }
};
);
}
-void rtl8168_set_eth_phy_bit(struct rtl8168_private *tp, u8 addr, u16 mask)
+void rtl8168_set_eth_phy_bit(struct rtl8168_private *tp, u8 addr, u16 mask)
{
ClearAndSetEthPhyBit(tp,
addr,
static u8 rtl8168_check_ephy_addr(struct rtl8168_private *tp, int addr)
{
- if ( tp->mcfg != CFG_METHOD_35) goto exit;
+ if (tp->mcfg != CFG_METHOD_35 && tp->mcfg != CFG_METHOD_36)
+ goto exit;
if (addr & (BIT_6 | BIT_5))
rtl8168_clear_and_set_mcu_ocp_bit(tp, 0xDE28,
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) | BIT_3);
mdelay(2);
break;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_3);
mdelay(2);
break;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
for (i = 0; i < 10; i++) {
udelay(100);
if (RTL_R32(tp, TxConfig) & BIT_11)
}
}
+static int rtl8168_wait_dash_fw_ready(struct rtl8168_private *tp)
+{
+ int rc = -1;
+
+ if (!HW_DASH_SUPPORT_DASH(tp))
+ goto out;
+
+ if (!tp->DASH)
+ goto out;
+
+ if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
+ int timeout;
+
+ for (timeout = 0; timeout < 10; timeout++) {
+ mdelay(10);
+ if (rtl8168_ocp_read(tp, 0x124, 1) & BIT_0) {
+ rc = 1;
+ goto out;
+ }
+ }
+ } else {
+ u32 reg;
+ int timeout;
+
+ if (tp->mcfg == CFG_METHOD_13)
+ reg = 0xB8;
+ else
+ reg = 0x10;
+
+ for (timeout = 0; timeout < 10; timeout++) {
+ mdelay(10);
+ if (rtl8168_ocp_read(tp, reg, 2) & BIT_11) {
+ rc = 1;
+ goto out;
+ }
+ }
+ }
+
+ rc = 0;
+
+out:
+ return rc;
+}
+
static void rtl8168_driver_start(struct rtl8168_private *tp)
{
//change other device state to D0.
break;
}
- if (!tp->DASH)
- return;
-
if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
- int timeout;
u32 tmp_value;
rtl8168_ocp_write(tp, 0x180, 1, OOB_CMD_DRIVER_START);
tmp_value |= BIT_0;
rtl8168_ocp_write(tp, 0x30, 1, tmp_value);
- for (timeout = 0; timeout < 10; timeout++) {
- mdelay(10);
- if (rtl8168_ocp_read(tp, 0x124, 1) & BIT_0)
- break;
- }
+ rtl8168_wait_dash_fw_ready(tp);
} else {
- int timeout;
- u32 reg;
- if (tp->mcfg == CFG_METHOD_13) {
+ if (tp->mcfg == CFG_METHOD_13)
RTL_W8(tp, TwiCmdReg, RTL_R8(tp, TwiCmdReg) | ( BIT_7 ));
- }
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
- if (tp->mcfg == CFG_METHOD_13)
- reg = 0xB8;
- else
- reg = 0x10;
-
- for (timeout = 0; timeout < 10; timeout++) {
- mdelay(10);
- if (rtl8168_ocp_read(tp, reg, 2) & BIT_11)
- break;
- }
+ rtl8168_wait_dash_fw_ready(tp);
}
}
static void rtl8168_driver_stop(struct rtl8168_private *tp)
{
- if (!tp->DASH)
- goto update_device_state;
-
if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
struct net_device *dev = tp->dev;
- int timeout;
u32 tmp_value;
rtl8168_dash2_disable_txrx(dev);
tmp_value |= BIT_0;
rtl8168_ocp_write(tp, 0x30, 1, tmp_value);
- for (timeout = 0; timeout < 10; timeout++) {
- mdelay(10);
- if (!(rtl8168_ocp_read(tp, 0x124, 1) & BIT_0))
- break;
- }
+ rtl8168_wait_dash_fw_ready(tp);
} else {
- int timeout;
- u32 reg;
-
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
- if (tp->mcfg == CFG_METHOD_13)
- reg = 0xB8;
- else
- reg = 0x10;
-
- for (timeout = 0; timeout < 10; timeout++) {
- mdelay(10);
- if ((rtl8168_ocp_read(tp, reg, 2) & BIT_11) == 0)
- break;
- }
+ rtl8168_wait_dash_fw_ready(tp);
- if (tp->mcfg == CFG_METHOD_13) {
+ if (tp->mcfg == CFG_METHOD_13)
RTL_W8(tp, TwiCmdReg, RTL_R8(tp, TwiCmdReg) & ~( BIT_7 ));
- }
}
-update_device_state:
//change other device state to D3.
switch (tp->mcfg) {
case CFG_METHOD_23:
}
}
+
+static inline u16 rtl8168_get_isr_by_vector(struct rtl8168_private *tp,
+ u32 message_id)
+{
+ if (message_id >= R8168_MAX_MSIX_VEC)
+ return 0;
+
+ if (message_id == 0)
+ return RTL_R16(tp, tp->isr_reg0);
+ else
+ return RTL_R8(tp, tp->isr_regmessage_id);
+}
+
+static inline void rtl8168_clear_isr_by_vector(struct rtl8168_private *tp,
+ u32 message_id, u16 val)
+{
+ if (message_id >= R8168_MAX_MSIX_VEC)
+ return;
+
+ if (message_id == 0) {
+ RTL_W16(tp, tp->isr_reg0, val);
+
+ if (val & RxDescUnavail)
+ tp->rx_ringmessage_id.rdu++;
+ if (val & TxDescUnavail)
+ tp->tx_ringmessage_id.tdu++;
+ } else {
+ RTL_W8(tp, tp->isr_regmessage_id, val);
+
+ if (val & RxDU1)
+ tp->rx_ringmessage_id.rdu++;
+ }
+}
+
+static inline void rtl8168_self_clear_isr_by_vector(struct rtl8168_private *tp,
+ u32 message_id)
+{
+ u16 val;
+
+ if (message_id >= R8168_MAX_MSIX_VEC)
+ return;
+
+ val = rtl8168_get_isr_by_vector(tp, message_id);
+ if ((message_id == 0) && (val & RxFIFOOver))
+ tp->rx_fifo_of++;
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_9 ... CFG_METHOD_37:
+ /* RX_OVERFLOW RE-START mechanism now HW handles it automatically*/
+ if (message_id == 0)
+ val &= ~RxFIFOOver;
+ break;
+ default:
+ break;
+ }
+ rtl8168_clear_isr_by_vector(tp, message_id, val);
+}
+
#ifdef ENABLE_DASH_SUPPORT
inline void
#endif
static inline void
-rtl8168_enable_hw_interrupt(struct rtl8168_private *tp)
+rtl8168_enable_interrupt(struct rtl8168_private *tp)
{
- RTL_W16(tp, IntrMask, tp->intr_mask);
+ int i;
+ for (i=0; i<tp->num_rx_rings; i++)
+ rtl8168_enable_interrupt_by_vector(tp, i);
+}
-#ifdef ENABLE_DASH_SUPPORT
- if (tp->DASH)
- rtl8168_enable_dash2_interrupt(tp);
-#endif
+static inline void
+rtl8168_enable_lib_interrupt(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i=1; i<rtl8168_tot_rx_rings(tp); i++)
+ rtl8168_enable_interrupt_by_vector(tp, i);
}
static inline void
-rtl8168_disable_hw_interrupt(struct rtl8168_private *tp)
+rtl8168_disable_interrupt(struct rtl8168_private *tp)
{
- RTL_W16(tp, IntrMask, 0x0000);
+ int i;
-#ifdef ENABLE_DASH_SUPPORT
- if (tp->DASH)
- rtl8168_disable_dash2_interrupt(tp);
-#endif
+ for (i=0; i<tp->num_rx_rings; i++)
+ rtl8168_disable_interrupt_by_vector(tp, i);
}
+static inline void
+rtl8168_disable_lib_interrupt(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i=1; i<rtl8168_tot_rx_rings(tp); i++)
+ rtl8168_disable_interrupt_by_vector(tp, i);
+}
+
+static inline void
+rtl8168_disable_all_interrupt(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i=0; i<tp->hw_supp_irq_nvecs; i++)
+ rtl8168_disable_interrupt_by_vector(tp, i);
+}
static inline void
rtl8168_switch_to_hw_interrupt(struct rtl8168_private *tp)
{
RTL_W32(tp, TimeInt0, 0x0000);
- rtl8168_enable_hw_interrupt(tp);
+ rtl8168_enable_interrupt(tp);
+
+ rtl8168_enable_lib_interrupt(tp);
}
static inline void
if (tp->use_timer_interrrupt) {
RTL_W32(tp, TimeInt0, timer_count);
RTL_W32(tp, TCTR, timer_count);
- RTL_W16(tp, IntrMask, tp->timer_intr_mask);
+ RTL_W16(tp, tp->imr_reg0, tp->timer_intr_mask);
#ifdef ENABLE_DASH_SUPPORT
if (tp->DASH)
static void
rtl8168_irq_mask_and_ack(struct rtl8168_private *tp)
{
- rtl8168_disable_hw_interrupt(tp);
+ rtl8168_disable_all_interrupt(tp);
#ifdef ENABLE_DASH_SUPPORT
if (tp->DASH) {
if (tp->dash_printer_enabled) {
- RTL_W16(tp, IntrStatus, RTL_R16(tp, IntrStatus) &
- ~(ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET));
+ rtl8168_clear_isr_by_vector(tp, 0,
+ rtl8168_get_hw_isr_by_vector(tp, 0) &
+ ~(ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET));
} else {
if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
RTL_CMAC_W8(tp, CMAC_IBISR0, RTL_CMAC_R8(tp, CMAC_IBISR0));
}
}
} else {
- RTL_W16(tp, IntrStatus, RTL_R16(tp, IntrStatus));
+ rtl8168_self_clear_isr_by_vector(tp, 0);
}
#else
- RTL_W16(tp, IntrStatus, RTL_R16(tp, IntrStatus));
+ rtl8168_self_clear_isr_by_vector(tp, 0);
#endif
+ if (tp->hw_supp_irq_nvecs > 1) {
+ int i;
+ for (i=1; i<tp->hw_supp_irq_nvecs; i++)
+ rtl8168_self_clear_isr_by_vector(tp, i);
+ }
+}
+
+static void
+rtl8168_disable_rx_packet_filter(struct rtl8168_private *tp)
+{
+
+ RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) &
+ ~(AcceptErr | AcceptRunt |AcceptBroadcast | AcceptMulticast |
+ AcceptMyPhys | AcceptAllPhys));
}
static void
struct rtl8168_private *tp = netdev_priv(dev);
int i;
- RTL_W32(tp, RxConfig, (RX_DMA_BURST << RxCfgDMAShift));
+ rtl8168_disable_rx_packet_filter(tp);
rtl8168_enable_rxdvgate(dev);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
mdelay(2);
break;
default:
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
RTL_W32(tp, TimeInt1, 0x0000);
RTL_W32(tp, TimeInt2, 0x0000);
RTL_W32(tp, TimeInt3, 0x0000);
}
}
-static void
+void
rtl8168_hw_reset(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
+ rtl8168_lib_reset_prepare(tp);
+
/* Disable interrupts */
rtl8168_irq_mask_and_ack(tp);
rtl8168_nic_reset(dev);
}
+static void rtl8168_doorbell(struct rtl8168_tx_ring *ring)
+{
+ struct rtl8168_private *tp = ring->priv;
+
+ if (ring->index > 0)
+ RTL_W8(tp, TxPoll, HPQ);
+ else
+ RTL_W8(tp, TxPoll, NPQ);
+}
+
static void rtl8168_mac_loopback_test(struct rtl8168_private *tp)
{
+ struct rtl8168_tx_ring *tx_ring = &tp->tx_ring0;
+ struct rtl8168_rx_ring *rx_ring = &tp->rx_ring0;
struct pci_dev *pdev = tp->pci_dev;
struct net_device *dev = tp->dev;
struct sk_buff *skb, *rx_skb;
pattern = 0x5A;
len = 60;
type = htons(ETH_P_IP);
- txd = tp->TxDescArray;
- rxd = tp->RxDescArray;
- rx_skb = tp->Rx_skbuff0;
+ txd = tx_ring->TxDescArray;
+ rxd = rtl8168_get_rxdesc(tp, tp->RxDescArray, 0, rx_ring->index);
+ rx_skb = rx_ring->Rx_skbuff0;
RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) & ~0x00060000) | 0x00020000);
do {
RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | AcceptMyPhys);
smp_wmb();
- RTL_W8(tp, TxPoll, NPQ); /* set polling bit */
+ rtl8168_doorbell(tx_ring); /* set polling bit */
for (i = 0; i < 50; i++) {
udelay(200);
rtl8168_disable_rxdvgate(dev);
RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
}
- tp->dirty_tx++;
- tp->dirty_rx++;
- tp->cur_tx++;
- tp->cur_rx++;
+ tx_ring->dirty_tx++;
+ rx_ring->dirty_rx++;
+ tx_ring->cur_tx++;
+ rx_ring->cur_rx++;
dma_unmap_single(&pdev->dev, le64_to_cpu(mapping),
len, DMA_TO_DEVICE);
RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) & ~0x00060000);
dev_kfree_skb_any(skb);
- RTL_W16(tp, IntrStatus, 0xFFBF);
+ rtl8168_clear_isr_by_vector(tp, 0, 0xFFBF);
}
static unsigned int
rtl8168_xmii_link_ok(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned int retval;
+ u8 status;
- retval = (RTL_R8(tp, PHYstatus) & LinkStatus) ? 1 : 0;
+ status = RTL_R8(tp, PHYstatus);
+ if (status == 0xff)
+ return 0;
- return retval;
+ return (status & LinkStatus) ? 1 : 0;
}
static int
void rtl8168_init_ring_indexes(struct rtl8168_private *tp)
{
- tp->dirty_tx = 0;
- tp->dirty_rx = 0;
- tp->cur_tx = 0;
- tp->cur_rx = 0;
+ int i;
+
+ for (i = 0; i < tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ ring->dirty_tx = ring->cur_tx = 0;
+ ring->index = i;
+ ring->priv = tp;
+ }
+
+ for (i = 0; i < tp->HwSuppNumRxQueues; i++) {
+ struct rtl8168_rx_ring *ring = &tp->rx_ringi;
+ ring->dirty_rx = ring->cur_rx = 0;
+ ring->index = i;
+ ring->priv = tp;
+ }
+
+#ifdef ENABLE_LIB_SUPPORT
+ for (i = 0; i < tp->HwSuppNumTxQueues; i++) {
+ struct rtl8168_ring *ring = &tp->lib_tx_ringi;
+ ring->direction = RTL8168_CH_DIR_TX;
+ ring->queue_num = i;
+ ring->private = tp;
+ }
+
+ for (i = 0; i < tp->HwSuppNumRxQueues; i++) {
+ struct rtl8168_ring *ring = &tp->lib_rx_ringi;
+ ring->direction = RTL8168_CH_DIR_RX;
+ ring->queue_num = i;
+ ring->private = tp;
+ }
+#endif
}
static void
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0x1EA, 1, ERIAR_ExGMAC);
csi_tmp |= BIT_0;
rtl8168_eri_write(tp, 0x1EA, 1, csi_tmp, ERIAR_ExGMAC);
csi_tmp |= (BIT_10 | BIT_11);
rtl8168_eri_write(tp, 0xD4, 4, csi_tmp, ERIAR_ExGMAC);
break;
- case CFG_METHOD_21 ... CFG_METHOD_35:
+ case CFG_METHOD_21 ... CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0xD4, 4, ERIAR_ExGMAC);
csi_tmp |= (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12);
rtl8168_eri_write(tp, 0xD4, 4, csi_tmp, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_10 | BIT_11);
rtl8168_eri_write(tp, 0xD4, 4, csi_tmp, ERIAR_ExGMAC);
break;
- case CFG_METHOD_21 ... CFG_METHOD_35:
+ case CFG_METHOD_21 ... CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0xD4, 4, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12);
rtl8168_eri_write(tp, 0xD4, 4, csi_tmp, ERIAR_ExGMAC);
//
if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
rtl8168_enable_dash2_interrupt(tp);
- RTL_W16(tp, IntrMask, (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET));
+ RTL_W16(tp, tp->imr_reg0, (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET));
} else {
- RTL_W16(tp, IntrMask, (ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK));
+ RTL_W16(tp, tp->imr_reg0, (ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK));
}
}
}
#endif
static void
-rtl8168_check_link_status(struct net_device *dev)
+rtl8168_link_on_patch(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
- int link_status_on;
-
-#ifdef ENABLE_FIBER_SUPPORT
- rtl8168_check_fiber_link_status(tp);
-#endif //ENABLE_FIBER_SUPPORT
-
- link_status_on = tp->link_ok(dev);
- if (tp->mcfg == CFG_METHOD_11)
- rtl8168dp_10mbps_gphy_para(dev);
-
- if (netif_carrier_ok(dev) != link_status_on) {
- if (link_status_on) {
- rtl8168_hw_config(dev);
+ rtl8168_hw_config(dev);
- if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19 || tp->mcfg == CFG_METHOD_20) {
- if (RTL_R8(tp, PHYstatus) & _1000bpsF) {
- rtl8168_eri_write(tp, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0x1dc, 4, 0x0000001f, ERIAR_ExGMAC);
- } else if (RTL_R8(tp, PHYstatus) & _100bps) {
- rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0x1dc, 4, 0x0000001f, ERIAR_ExGMAC);
- } else {
- rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0x1dc, 4, 0x0000002d, ERIAR_ExGMAC);
- }
- } else if ((tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) && netif_running(dev)) {
- if (tp->mcfg == CFG_METHOD_16 && (RTL_R8(tp, PHYstatus) & _10bps)) {
- RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | AcceptAllPhys);
- } else if (tp->mcfg == CFG_METHOD_17) {
- if (RTL_R8(tp, PHYstatus) & _1000bpsF) {
- rtl8168_eri_write(tp, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
- } else if (RTL_R8(tp, PHYstatus) & _100bps) {
- rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
- } else {
- rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0x1dc, 4, 0x0000003f, ERIAR_ExGMAC);
- }
- }
- } else if ((tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) && tp->eee_enabled == 1) {
- /*Full -Duplex mode*/
- if (RTL_R8(tp, PHYstatus)&FullDup) {
- rtl8168_mdio_write(tp, 0x1F, 0x0006);
- rtl8168_mdio_write(tp, 0x00, 0x5a30);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- if (RTL_R8(tp, PHYstatus) & (_10bps | _100bps))
- RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) & ~BIT_19) | BIT_25);
-
- } else {
- rtl8168_mdio_write(tp, 0x1F, 0x0006);
- rtl8168_mdio_write(tp, 0x00, 0x5a00);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- if (RTL_R8(tp, PHYstatus) & (_10bps | _100bps))
- RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) & ~BIT_19) | (InterFrameGap << TxInterFrameGapShift));
- }
- } else if ((tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
- tp->mcfg == CFG_METHOD_23 || tp->mcfg == CFG_METHOD_24 ||
- tp->mcfg == CFG_METHOD_25 || tp->mcfg == CFG_METHOD_26 ||
- tp->mcfg == CFG_METHOD_27 || tp->mcfg == CFG_METHOD_28 ||
- tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
- tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
- tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) &&
- netif_running(dev)) {
- if (RTL_R8(tp, PHYstatus)&FullDup)
- RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | (BIT_24 | BIT_25)) & ~BIT_19);
- else
- RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | BIT_25) & ~(BIT_19 | BIT_24));
+ if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19 || tp->mcfg == CFG_METHOD_20) {
+ if (RTL_R8(tp, PHYstatus) & _1000bpsF) {
+ rtl8168_eri_write(tp, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0x1dc, 4, 0x0000001f, ERIAR_ExGMAC);
+ } else if (RTL_R8(tp, PHYstatus) & _100bps) {
+ rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0x1dc, 4, 0x0000001f, ERIAR_ExGMAC);
+ } else {
+ rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0x1dc, 4, 0x0000002d, ERIAR_ExGMAC);
+ }
+ } else if ((tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) && netif_running(dev)) {
+ if (tp->mcfg == CFG_METHOD_16 && (RTL_R8(tp, PHYstatus) & _10bps)) {
+ RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | AcceptAllPhys);
+ } else if (tp->mcfg == CFG_METHOD_17) {
+ if (RTL_R8(tp, PHYstatus) & _1000bpsF) {
+ rtl8168_eri_write(tp, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
+ } else if (RTL_R8(tp, PHYstatus) & _100bps) {
+ rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
+ } else {
+ rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0x1dc, 4, 0x0000003f, ERIAR_ExGMAC);
}
+ }
+ } else if ((tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) && tp->eee.eee_enabled == 1) {
+ /*Full -Duplex mode*/
+ if (RTL_R8(tp, PHYstatus)&FullDup) {
+ rtl8168_mdio_write(tp, 0x1F, 0x0006);
+ rtl8168_mdio_write(tp, 0x00, 0x5a30);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+ if (RTL_R8(tp, PHYstatus) & (_10bps | _100bps))
+ RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) & ~BIT_19) | BIT_25);
- if (tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
- tp->mcfg == CFG_METHOD_27 || tp->mcfg == CFG_METHOD_28 ||
- tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
- tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) {
- /*half mode*/
- if (!(RTL_R8(tp, PHYstatus)&FullDup)) {
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- rtl8168_mdio_write(tp, MII_ADVERTISE, rtl8168_mdio_read(tp, MII_ADVERTISE)&~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM));
- }
- }
+ } else {
+ rtl8168_mdio_write(tp, 0x1F, 0x0006);
+ rtl8168_mdio_write(tp, 0x00, 0x5a00);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+ if (RTL_R8(tp, PHYstatus) & (_10bps | _100bps))
+ RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) & ~BIT_19) | (InterFrameGap << TxInterFrameGapShift));
+ }
+ } else if ((tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
+ tp->mcfg == CFG_METHOD_23 || tp->mcfg == CFG_METHOD_24 ||
+ tp->mcfg == CFG_METHOD_25 || tp->mcfg == CFG_METHOD_26 ||
+ tp->mcfg == CFG_METHOD_27 || tp->mcfg == CFG_METHOD_28 ||
+ tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
+ tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
+ tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) && netif_running(dev)) {
+ if (RTL_R8(tp, PHYstatus)&FullDup)
+ RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | (BIT_24 | BIT_25)) & ~BIT_19);
+ else
+ RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | BIT_25) & ~(BIT_19 | BIT_24));
+ }
- if ((tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
- tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) &&
- (RTL_R8(tp, PHYstatus) & _10bps)) {
- u32 csi_tmp;
-
- csi_tmp = rtl8168_eri_read(tp, 0x1D0, 1, ERIAR_ExGMAC);
- csi_tmp |= BIT_1;
- rtl8168_eri_write(tp, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC);
- }
+ if (tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
+ tp->mcfg == CFG_METHOD_27 || tp->mcfg == CFG_METHOD_28 ||
+ tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
+ tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) {
+ /*half mode*/
+ if (!(RTL_R8(tp, PHYstatus)&FullDup)) {
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+ rtl8168_mdio_write(tp, MII_ADVERTISE, rtl8168_mdio_read(tp, MII_ADVERTISE)&~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM));
+ }
+ }
+
+ if ((tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
+ tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) &&
+ (RTL_R8(tp, PHYstatus) & _10bps)) {
+ u32 csi_tmp;
- rtl8168_hw_start(dev);
+ csi_tmp = rtl8168_eri_read(tp, 0x1D0, 1, ERIAR_ExGMAC);
+ csi_tmp |= BIT_1;
+ rtl8168_eri_write(tp, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC);
+ }
- netif_carrier_on(dev);
+ rtl8168_hw_start(dev);
- netif_wake_queue(dev);
+ netif_carrier_on(dev);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- tp->phy_reg_aner = rtl8168_mdio_read(tp, MII_EXPANSION);
- tp->phy_reg_anlpar = rtl8168_mdio_read(tp, MII_LPA);
- tp->phy_reg_gbsr = rtl8168_mdio_read(tp, MII_STAT1000);
+ netif_tx_wake_all_queues(dev);
- if (netif_msg_ifup(tp))
- printk(KERN_INFO PFX "%s: link up\n", dev->name);
- } else {
- if (netif_msg_ifdown(tp))
- printk(KERN_INFO PFX "%s: link down\n", dev->name);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+ tp->phy_reg_aner = rtl8168_mdio_read(tp, MII_EXPANSION);
+ tp->phy_reg_anlpar = rtl8168_mdio_read(tp, MII_LPA);
+ tp->phy_reg_gbsr = rtl8168_mdio_read(tp, MII_STAT1000);
+}
- tp->phy_reg_aner = 0;
- tp->phy_reg_anlpar = 0;
- tp->phy_reg_gbsr = 0;
+static void
+rtl8168_link_down_patch(struct net_device *dev)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
- netif_stop_queue(dev);
+ tp->phy_reg_aner = 0;
+ tp->phy_reg_anlpar = 0;
+ tp->phy_reg_gbsr = 0;
- netif_carrier_off(dev);
+ netif_carrier_off(dev);
- rtl8168_hw_reset(dev);
+ netif_tx_disable(dev);
- rtl8168_tx_clear(tp);
+ rtl8168_hw_reset(dev);
- rtl8168_rx_clear(tp);
+ rtl8168_tx_clear(tp);
- rtl8168_init_ring(dev);
+ rtl8168_rx_clear(tp);
- if (dynamic_aspm) {
- rtl8168_enable_cfg9346_write(tp);
- rtl8168_hw_aspm_clkreq_enable(tp, true);
- rtl8168_disable_cfg9346_write(tp);
- }
+ rtl8168_init_ring(dev);
- rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising);
+ if (dynamic_aspm) {
+ rtl8168_enable_cfg9346_write(tp);
+ rtl8168_hw_aspm_clkreq_enable(tp, true);
+ rtl8168_disable_cfg9346_write(tp);
+ }
- switch (tp->mcfg) {
- case CFG_METHOD_21:
- case CFG_METHOD_22:
- case CFG_METHOD_23:
- case CFG_METHOD_24:
- case CFG_METHOD_25:
- case CFG_METHOD_27:
- case CFG_METHOD_28:
- case CFG_METHOD_31:
- case CFG_METHOD_32:
- case CFG_METHOD_33:
- case CFG_METHOD_34:
- if (tp->org_pci_offset_99 & BIT_2)
- tp->issue_offset_99_event = TRUE;
- break;
- }
+ switch (tp->mcfg) {
+ case CFG_METHOD_21:
+ case CFG_METHOD_22:
+ case CFG_METHOD_23:
+ case CFG_METHOD_24:
+ case CFG_METHOD_25:
+ case CFG_METHOD_27:
+ case CFG_METHOD_28:
+ case CFG_METHOD_31:
+ case CFG_METHOD_32:
+ case CFG_METHOD_33:
+ case CFG_METHOD_34:
+ if (tp->org_pci_offset_99 & BIT_2)
+ tp->issue_offset_99_event = TRUE;
+ break;
+ }
#ifdef ENABLE_DASH_SUPPORT
- if (tp->DASH) {
- NICChkTypeEnableDashInterrupt(tp);
- }
+ if (tp->DASH) {
+ NICChkTypeEnableDashInterrupt(tp);
+ }
#endif
+}
+
+static void
+rtl8168_check_link_status(struct net_device *dev)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+ int link_status_on;
+
+#ifdef ENABLE_FIBER_SUPPORT
+ rtl8168_check_fiber_link_status(tp);
+#endif //ENABLE_FIBER_SUPPORT
+
+ link_status_on = tp->link_ok(dev);
+
+ if (tp->mcfg == CFG_METHOD_11)
+ rtl8168dp_10mbps_gphy_para(dev);
+
+ if (netif_carrier_ok(dev) != link_status_on) {
+ if (link_status_on) {
+ rtl8168_link_on_patch(dev);
+
+ if (netif_msg_ifup(tp))
+ printk(KERN_INFO PFX "%s: link up\n", dev->name);
+ } else {
+ if (netif_msg_ifdown(tp))
+ printk(KERN_INFO PFX "%s: link down\n", dev->name);
+
+ rtl8168_link_down_patch(dev);
}
}
tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
val = rtl8168_mdio_read_phy_ocp(tp, 0x0C41, 0x13);
if (val != 0x0050) {
rtl8168_set_phy_mcu_patch_request(tp);
tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
val = rtl8168_mdio_read_phy_ocp(tp, 0x0C41, 0x13);
if (val != 0x0500) {
rtl8168_set_phy_mcu_patch_request(tp);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0x3F2, 2, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_0 | BIT_1);
rtl8168_eri_write(tp, 0x3F2, 2, csi_tmp, ERIAR_ExGMAC);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_csi_fun0_write_byte(tp, 0x99, 0x00);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_csi_fun0_write_byte(tp, 0x99, tp->org_pci_offset_99);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0x3F2, 2, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_0 | BIT_1);
if (tp->org_pci_offset_99 & (BIT_5 | BIT_6))
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0x3F2, 2, ERIAR_ExGMAC);
csi_tmp &= ~( BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12 | BIT_13 | BIT_14 | BIT_15 );
csi_tmp |= ( BIT_9 | BIT_10 | BIT_13 | BIT_14 | BIT_15 );
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
if (tp->org_pci_offset_99 & BIT_2)
- rtl8168_mac_ocp_write(tp, 0xE0A2, rtl8168_mac_ocp_read(tp, 0xE0A2) | BIT_0);
+ rtl8168_mac_ocp_write(tp, 0xE0A2, rtl8168_mac_ocp_read(tp, 0xE0A2) | BIT_0);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_eri_write(tp, 0x2E8, 2, 0x9003, ERIAR_ExGMAC);
rtl8168_eri_write(tp, 0x2EA, 2, 0x9003, ERIAR_ExGMAC);
rtl8168_eri_write(tp, 0x2EC, 2, 0x9003, ERIAR_ExGMAC);
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
if (tp->org_pci_offset_99 & BIT_2)
RTL_W8(tp, 0xB6, RTL_R8(tp, 0xB6) | BIT_0);
break;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0x1E2, 1, ERIAR_ExGMAC);
csi_tmp &= ~BIT_2;
rtl8168_eri_write(tp, 0x1E2, 1, csi_tmp, ERIAR_ExGMAC);
switch (tp->mcfg) {
case CFG_METHOD_35:
+ case CFG_METHOD_36:
csi_tmp = rtl8168_eri_read(tp, 0x1E8, 2, ERIAR_ExGMAC);
csi_tmp &= ~(0xFFF0);
csi_tmp |= 0x0640;
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0x1E2, 1, ERIAR_ExGMAC);
csi_tmp |= BIT_2;
rtl8168_eri_write(tp, 0x1E2, 1, csi_tmp, ERIAR_ExGMAC);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
if (tp->org_pci_offset_99 & BIT_2)
rtl8168_issue_offset_99_event(tp);
rtl8168_disable_pci_offset_99(tp);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_disable_pci_offset_180(tp);
break;
}
}
static void
+rtl8168_set_rx_q_num(struct rtl8168_private *tp,
+ unsigned int num_rx_queues)
+{
+ u16 q_ctrl;
+ u16 rx_q_num;
+
+ if (tp->HwSuppRxDescType != RX_DESC_RING_TYPE_2)
+ return;
+
+ if (num_rx_queues > tp->HwSuppNumRxQueues ||
+ num_rx_queues < 1)
+ num_rx_queues = 1;
+
+ rx_q_num = (u16)ilog2(num_rx_queues);
+ rx_q_num &= (BIT_0 | BIT_1 | BIT_2);
+ rx_q_num <<= 2;
+ q_ctrl = rtl8168_eri_read(tp, Q_NUM_CTRL_8168, 2, ERIAR_ExGMAC);
+ q_ctrl &= ~(BIT_2 | BIT_3 | BIT_4);
+ q_ctrl |= rx_q_num;
+ rtl8168_eri_write(tp, Q_NUM_CTRL_8168, 2, q_ctrl, ERIAR_ExGMAC);
+}
+
+void
+rtl8168_set_rx_vlan_filter(struct rtl8168_private *tp)
+{
+ int i;
+
+ if (tp->HwSuppRxDescType != RX_DESC_RING_TYPE_2)
+ return;
+
+ for (i = 1; i < 16; i++) {
+ rtl8168_eri_write(tp, 0xf0 + 8*i, 4, 0xffff0000, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0xf4 + 8*i, 4, 0xffffffff, ERIAR_ExGMAC);
+ }
+}
+
+static void
rtl8168_hw_d3_para(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
- RTL_W16(tp, RxMaxSize, RX_BUF_SIZE);
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_26:
+ RTL_W16(tp, RxMaxSize, RX_BUF_SIZE + 1);
+ break;
+ default:
+ RTL_W16(tp, RxMaxSize, RX_BUF_SIZE);
+ break;
+ }
if (tp->HwSuppAspmClkIntrLock) {
RTL_W8(tp, 0xF1, RTL_R8(tp, 0xF1) & ~BIT_7);
#ifdef ENABLE_REALWOW_SUPPORT
rtl8168_set_realwow_d3_para(dev);
#endif
+ rtl8168_set_rx_q_num(tp, 1);
if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19 || tp->mcfg == CFG_METHOD_20) {
rtl8168_eri_write(tp, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
switch (tp->mcfg) {
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_set_mcu_ocp_bit(tp, 0xD438, BIT_3);
- rtl8168_set_mcu_ocp_bit(tp, 0xDE38, BIT_2);
+ rtl8168_set_mcu_ocp_bit(tp, 0xD438, BIT_2);
rtl8168_clear_mcu_ocp_bit(tp, 0xDE28, (BIT_1 | BIT_0));
rtl8168_set_mcu_ocp_bit(tp, 0xD438, (BIT_1 | BIT_0));
break;
tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35)
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37)
if (!tp->dash_printer_enabled)
rtl8168_disable_ocp_phy_power_saving(dev);
struct rtl8168_private *tp = netdev_priv(dev);
u8 options;
u32 csi_tmp;
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
+ if (disable_wol_support)
+ goto out;
tp->wol_opts = 0;
options = RTL_R8(tp, Config1);
if (!(options & PMEnable))
- goto out_unlock;
+ goto out;
options = RTL_R8(tp, Config3);
if (options & LinkUp)
if (options & MWF)
tp->wol_opts |= WAKE_MCAST;
-out_unlock:
+out:
tp->wol_enabled = (tp->wol_opts || tp->dash_printer_enabled) ? WOL_ENABLED : WOL_DISABLED;
-
- spin_unlock_irqrestore(&tp->lock, flags);
}
static void
tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36) {
rtl8168_enable_cfg9346_write(tp);
RTL_W8(tp, Config2, RTL_R8(tp, Config2) | PMSTS_En);
rtl8168_disable_cfg9346_write(tp);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~BIT_7);
break;
}
case CFG_METHOD_14 ... CFG_METHOD_15:
RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) & ~BIT_6);
break;
- case CFG_METHOD_16 ... CFG_METHOD_35:
+ case CFG_METHOD_16 ... CFG_METHOD_36:
RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) & ~BIT_6);
RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_6);
break;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | BIT_7 | BIT_6);
break;
}
{
struct rtl8168_private *tp = netdev_priv(dev);
u8 options;
- unsigned long flags;
- wol->wolopts = 0;
+ wol->wolopts = wol->supported = 0;
- if (tp->mcfg == CFG_METHOD_DEFAULT) {
- wol->supported = 0;
+ if (disable_wol_support)
return;
- } else {
- wol->supported = WAKE_ANY;
- }
- spin_lock_irqsave(&tp->lock, flags);
+ wol->supported = WAKE_ANY;
options = RTL_R8(tp, Config1);
if (!(options & PMEnable))
- goto out_unlock;
+ return;
wol->wolopts = tp->wol_opts;
-
-out_unlock:
- spin_unlock_irqrestore(&tp->lock, flags);
}
static int
struct ethtool_wolinfo *wol)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
- if (tp->mcfg == CFG_METHOD_DEFAULT)
+ if (disable_wol_support)
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
-
tp->wol_opts = wol->wolopts;
tp->wol_enabled = (tp->wol_opts || tp->dash_printer_enabled) ? WOL_ENABLED : WOL_DISABLED;
- spin_unlock_irqrestore(&tp->lock, flags);
-
device_set_wakeup_enable(tp_to_dev(tp), tp->wol_enabled);
return 0;
strcpy(info->driver, MODULENAME);
strcpy(info->version, RTL8168_VERSION);
- strcpy(info->bus_info, pci_name(tp->pci_dev));
+ strncpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info) - 1);
info->regdump_len = R8168_REGS_DUMP_SIZE;
info->eedump_len = tp->eeprom_len;
BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version));
if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36) {
//Disable Giga Lite
rtl8168_mdio_write(tp, 0x1F, 0x0A42);
rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_9);
giga_ctrl |= ADVERTISE_1000FULL;
//flow control
- if (dev->mtu <= ETH_DATA_LEN && tp->fcpause == rtl8168_fc_full)
- auto_nego |= ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM;
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_20:
+ if (dev->mtu <= ETH_DATA_LEN && tp->fcpause == rtl8168_fc_full)
+ auto_nego |= ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM;
+ break;
+ default:
+ if (tp->fcpause == rtl8168_fc_full)
+ auto_nego |= ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM;
+ break;
+ }
tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
#endif
)
{
- struct rtl8168_private *tp = netdev_priv(dev);
int ret;
- unsigned long flags;
u8 autoneg;
u32 speed;
u8 duplex;
if (advertising & ~supported)
return -EINVAL;
- spin_lock_irqsave(&tp->lock, flags);
ret = rtl8168_set_speed(dev, autoneg, speed, duplex, advertising);
- spin_unlock_irqrestore(&tp->lock, flags);
return ret;
}
{
struct rtl8168_private *tp = netdev_priv(dev);
u32 ret;
- unsigned long flags;
- spin_lock_irqsave(&tp->lock, flags);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
ret = ((dev->features & NETIF_F_IP_CSUM) != 0);
#else
ret = ((dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) != 0);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
- spin_unlock_irqrestore(&tp->lock, flags);
return ret;
}
{
struct rtl8168_private *tp = netdev_priv(dev);
u32 ret;
- unsigned long flags;
- spin_lock_irqsave(&tp->lock, flags);
ret = tp->cp_cmd & RxChkSum;
- spin_unlock_irqrestore(&tp->lock, flags);
return ret;
}
u32 data)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
if (tp->mcfg == CFG_METHOD_DEFAULT)
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
-
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
if (data)
dev->features |= NETIF_F_IP_CSUM;
dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
- spin_unlock_irqrestore(&tp->lock, flags);
-
return 0;
}
u32 data)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
if (tp->mcfg == CFG_METHOD_DEFAULT)
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
-
if (data)
tp->cp_cmd |= RxChkSum;
else
RTL_W16(tp, CPlusCmd, tp->cp_cmd);
- spin_unlock_irqrestore(&tp->lock, flags);
-
return 0;
}
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
struct vlan_group *grp)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
- spin_lock_irqsave(&tp->lock, flags);
tp->vlgrp = grp;
if (tp->vlgrp)
tp->cp_cmd |= RxVlan;
tp->cp_cmd &= ~RxVlan;
RTL_W16(tp, CPlusCmd, tp->cp_cmd);
RTL_R16(tp, CPlusCmd);
- spin_unlock_irqrestore(&tp->lock, flags);
}
#endif
unsigned short vid)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
- spin_lock_irqsave(&tp->lock, flags);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
if (tp->vlgrp)
tp->vlgrp->vlan_devicesvid = NULL;
#else
vlan_group_set_device(tp->vlgrp, vid, NULL);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
- spin_unlock_irqrestore(&tp->lock, flags);
}
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
static netdev_features_t rtl8168_fix_features(struct net_device *dev,
netdev_features_t features)
{
- struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
if (dev->mtu > MSS_MAX)
features &= ~NETIF_F_ALL_TSO;
if (dev->mtu > ETH_DATA_LEN) {
features &= ~NETIF_F_ALL_TSO;
features &= ~NETIF_F_ALL_CSUM;
}
- spin_unlock_irqrestore(&tp->lock, flags);
return features;
}
else
tp->cp_cmd &= ~RxChkSum;
- if (dev->features & NETIF_F_HW_VLAN_RX)
+ if (features & NETIF_F_HW_VLAN_RX)
tp->cp_cmd |= RxVlan;
else
tp->cp_cmd &= ~RxVlan;
static int rtl8168_set_features(struct net_device *dev,
netdev_features_t features)
{
- struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
-
features &= NETIF_F_RXALL | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX;
- spin_lock_irqsave(&tp->lock, flags);
if (features ^ dev->features)
rtl8168_hw_set_features(dev, features);
- spin_unlock_irqrestore(&tp->lock, flags);
return 0;
}
u32 speed = 0;
u16 bmcr, bmsr, anlpar, ctrl1000 = 0, stat1000 = 0;
u32 supported, advertising, lp_advertising;
- unsigned long flags;
supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
advertising = ADVERTISED_TP;
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
bmcr = rtl8168_mdio_read(tp, MII_BMCR);
bmsr = rtl8168_mdio_read(tp, MII_BMSR);
anlpar = rtl8168_mdio_read(tp, MII_LPA);
ctrl1000 = rtl8168_mdio_read(tp, MII_CTRL1000);
stat1000 = rtl8168_mdio_read(tp, MII_STAT1000);
- spin_unlock_irqrestore(&tp->lock, flags);
if (bmcr & BMCR_ANENABLE) {
advertising |= ADVERTISED_Autoneg;
void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
u8 *data = p;
- unsigned long flags;
if (regs->len < R8168_REGS_DUMP_SIZE)
return /* -EINVAL */;
memset(p, 0, regs->len);
- spin_lock_irqsave(&tp->lock, flags);
for (i = 0; i < R8168_MAC_REGS_SIZE; i++)
*data++ = readb(ioaddr + i);
data = (u8*)p + 256;
}
break;
}
- spin_unlock_irqrestore(&tp->lock, flags);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
static void
-rtl8168_wait_for_quiescence(struct net_device *dev)
+rtl8168_set_ring_size(struct rtl8168_private *tp, u32 rx, u32 tx)
{
- struct rtl8168_private *tp = netdev_priv(dev);
-
- synchronize_irq(tp->irq);
-
- /* Wait for any pending NAPI task to complete */
-#ifdef CONFIG_R8168_NAPI
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- RTL_NAPI_DISABLE(dev, &tp->napi);
-#endif
-#endif //CONFIG_R8168_NAPI
+ int i;
- rtl8168_irq_mask_and_ack(tp);
+ tp->num_rx_desc = rx;
-#ifdef CONFIG_R8168_NAPI
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- RTL_NAPI_ENABLE(dev, &tp->napi);
-#endif
-#endif //CONFIG_R8168_NAPI
+ for (i = 0; i < tp->num_tx_rings; i++)
+ tp->tx_ringi.num_tx_desc = tx;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
ring->rx_max_pending = MAX_NUM_TX_DESC;
ring->tx_max_pending = MAX_NUM_RX_DESC;
ring->rx_pending = tp->num_rx_desc;
- ring->tx_pending = tp->num_tx_desc;
+ ring->tx_pending = tp->tx_ring0.num_tx_desc;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0)
MIN_NUM_RX_DESC, MAX_NUM_RX_DESC);
if ((new_rx_count == tp->num_rx_desc) &&
- (new_tx_count == tp->num_tx_desc)) {
+ (new_tx_count == tp->tx_ring0.num_tx_desc)) {
/* nothing to do */
return 0;
}
rtl8168_close(dev);
}
- tp->num_rx_desc = new_rx_count;
- tp->num_tx_desc = new_tx_count;
+ rtl8168_set_ring_size(tp, new_rx_count, new_tx_count);
if (netif_running(dev))
rc = rtl8168_open(dev);
struct rtl8168_private *tp = netdev_priv(dev);
struct rtl8168_counters *counters;
dma_addr_t paddr;
- u32 cmd;
- u32 WaitCnt;
- unsigned long flags;
ASSERT_RTNL();
if (!counters)
return;
- spin_lock_irqsave(&tp->lock, flags);
- RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32);
- cmd = (u64)paddr & DMA_BIT_MASK(32);
- RTL_W32(tp, CounterAddrLow, cmd);
- RTL_W32(tp, CounterAddrLow, cmd | CounterDump);
-
- WaitCnt = 0;
- while (RTL_R32(tp, CounterAddrLow) & CounterDump) {
- udelay(10);
-
- WaitCnt++;
- if (WaitCnt > 20)
- break;
- }
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtl8168_dump_tally_counter(tp, paddr);
data0 = le64_to_cpu(counters->tx_packets);
data1 = le64_to_cpu(counters->rx_packets);
}
#endif
-static int rtl8168_enable_EEE(struct rtl8168_private *tp)
+static void
+rtl8168_set_eee_lpi_timer(struct rtl8168_private *tp)
+{
+ u16 dev_lpi_timer;
+
+ dev_lpi_timer = tp->eee.tx_lpi_timer;
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_29:
+ case CFG_METHOD_30:
+ case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
+ rtl8168_mac_ocp_write(tp, EEE_TXIDLE_TIMER_8168, dev_lpi_timer);
+ break;
+ default:
+ break;
+ }
+}
+
+static int rtl8168_enable_eee(struct rtl8168_private *tp)
{
int ret;
u16 data;
u32 csi_tmp;
+ struct ethtool_eee *eee = &tp->eee;
+ u16 eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
ret = 0;
switch (tp->mcfg) {
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
csi_tmp = rtl8168_eri_read(tp, 0x1B0, 4, ERIAR_ExGMAC);
csi_tmp |= BIT_1 | BIT_0;
rtl8168_eri_write(tp, 0x1B0, 4, csi_tmp, ERIAR_ExGMAC);
data = rtl8168_mdio_read(tp, 0x11);
rtl8168_mdio_write(tp, 0x11, data | BIT_4);
rtl8168_mdio_write(tp, 0x1F, 0x0A5D);
- rtl8168_mdio_write(tp, 0x10, tp->eee_adv_t);
+ rtl8168_mdio_write(tp, 0x10, eee_adv_t);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
break;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_mdio_write(tp, 0x1F, 0x0A4A);
rtl8168_set_eth_phy_bit(tp, 0x11, BIT_9);
rtl8168_mdio_write(tp, 0x1F, 0x0A42);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_set_phy_mcu_patch_request(tp);
break;
}
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
data = rtl8168_mac_ocp_read(tp, 0xE052);
data &= ~(BIT_0);
rtl8168_mac_ocp_write(tp, 0xE052, data);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_clear_phy_mcu_patch_request(tp);
break;
}
return ret;
}
-static int rtl8168_disable_EEE(struct rtl8168_private *tp)
+static int rtl8168_disable_eee(struct rtl8168_private *tp)
{
int ret;
u16 data;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
csi_tmp = rtl8168_eri_read(tp, 0x1B0, 4, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_1 | BIT_0);
rtl8168_eri_write(tp, 0x1B0, 4, csi_tmp, ERIAR_ExGMAC);
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
data = rtl8168_mdio_read(tp, 0x11);
- rtl8168_mdio_write(tp, 0x11, data & ~BIT_4);
+ if (tp->mcfg == CFG_METHOD_36)
+ rtl8168_mdio_write(tp, 0x11, data | BIT_4);
+ else
+ rtl8168_mdio_write(tp, 0x11, data & ~BIT_4);
rtl8168_mdio_write(tp, 0x1F, 0x0A5D);
rtl8168_mdio_write(tp, 0x10, 0x0000);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_mdio_write(tp, 0x1F, 0x0A42);
rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_7);
rtl8168_mdio_write(tp, 0x1F, 0x0A4A);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_set_phy_mcu_patch_request(tp);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
data = rtl8168_mac_ocp_read(tp, 0xE052);
data &= ~(BIT_0);
rtl8168_mac_ocp_write(tp, 0xE052, data);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
rtl8168_clear_phy_mcu_patch_request(tp);
break;
}
static int rtl_nway_reset(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
int ret, bmcr;
- spin_lock_irqsave(&tp->lock, flags);
-
- if (unlikely(tp->rtk_enable_diag)) {
- spin_unlock_irqrestore(&tp->lock, flags);
+ if (unlikely(tp->rtk_enable_diag))
return -EBUSY;
- }
/* if autoneg is off, it's an error */
rtl8168_mdio_write(tp, 0x1F, 0x0000);
ret = -EINVAL;
}
- spin_unlock_irqrestore(&tp->lock, flags);
-
return ret;
}
+static bool
+rtl8168_support_eee(struct rtl8168_private *tp)
+{
+ switch (tp->mcfg) {
+ case CFG_METHOD_21 ... CFG_METHOD_36:
+ return 1;
+ default:
+ return 0;
+ }
+}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)
+static u32
+rtl8168_device_lpi_t_to_ethtool_lpi_t(struct rtl8168_private *tp , u32 lpi_timer)
+{
+ u32 to_us;
+ u8 status;
+
+ //Giga: lpi_timer * 8ns
+ //100M : lpi_timer * 80ns
+ to_us = 0;
+ status = RTL_R8(tp, PHYstatus);
+ if (status & LinkStatus) {
+ /*link on*/
+ if (status & _1000bpsF)
+ to_us = lpi_timer * 8;
+ else if (status & _100bps)
+ to_us = lpi_timer * 80;
+ }
+
+ //ns to us
+ to_us /= 1000;
+
+ return to_us;
+}
+
static int
-rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *eee)
+rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata)
{
struct rtl8168_private *tp = netdev_priv(net);
- u32 lp, adv, supported = 0;
- unsigned long flags;
+ struct ethtool_eee *eee = &tp->eee;
+ u32 lp, adv, tx_lpi_timer, supported = 0;
u16 val;
- switch (tp->mcfg) {
- case CFG_METHOD_21 ... CFG_METHOD_35:
- break;
- default:
+ if (!rtl8168_support_eee(tp))
return -EOPNOTSUPP;
- }
- spin_lock_irqsave(&tp->lock, flags);
-
- if (unlikely(tp->rtk_enable_diag)) {
- spin_unlock_irqrestore(&tp->lock, flags);
+ if (unlikely(tp->rtk_enable_diag))
return -EBUSY;
- }
- rtl8168_mdio_write(tp, 0x1F, 0x0A5C);
- val = rtl8168_mdio_read(tp, 0x12);
- supported = mmd_eee_cap_to_ethtool_sup_t(val);
+ /* Get Supported EEE */
+ supported = eee->supported;
- rtl8168_mdio_write(tp, 0x1F, 0x0A5D);
- val = rtl8168_mdio_read(tp, 0x10);
- adv = mmd_eee_adv_to_ethtool_adv_t(val);
+ /* Get advertisement EEE */
+ adv = eee->advertised;
+ /* Get LP advertisement EEE */
+ rtl8168_mdio_write(tp, 0x1F, 0x0A5D);
val = rtl8168_mdio_read(tp, 0x11);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
+ /* Get EEE Tx LPI timer*/
+ tx_lpi_timer = rtl8168_device_lpi_t_to_ethtool_lpi_t(tp, eee->tx_lpi_timer);
+
val = rtl8168_eri_read(tp, 0x1B0, 2, ERIAR_ExGMAC);
val &= BIT_1 | BIT_0;
rtl8168_mdio_write(tp, 0x1F, 0x0000);
- spin_unlock_irqrestore(&tp->lock, flags);
-
- eee->eee_enabled = !!val;
- eee->eee_active = !!(supported & adv & lp);
- eee->supported = supported;
- eee->advertised = adv;
- eee->lp_advertised = lp;
+ edata->eee_enabled = !!val;
+ edata->eee_active = !!(supported & adv & lp);
+ edata->supported = supported;
+ edata->advertised = adv;
+ edata->lp_advertised = lp;
+ edata->tx_lpi_enabled = edata->eee_enabled;
+ edata->tx_lpi_timer = tx_lpi_timer;
return 0;
}
static int
-rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *eee)
+rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata)
{
struct rtl8168_private *tp = netdev_priv(net);
- unsigned long flags;
+ struct ethtool_eee *eee = &tp->eee;
+ u32 advertising;
+ int rc = 0;
- switch (tp->mcfg) {
- case CFG_METHOD_21 ... CFG_METHOD_35:
- break;
- default:
+ if (!rtl8168_support_eee(tp))
return -EOPNOTSUPP;
- }
if (HW_SUPP_SERDES_PHY(tp) ||
!HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp) ||
tp->DASH)
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
-
if (unlikely(tp->rtk_enable_diag)) {
- spin_unlock_irqrestore(&tp->lock, flags);
- return -EBUSY;
+ dev_printk(KERN_WARNING, tp_to_dev(tp), "Diag Enabled\n");
+ rc = -EBUSY;
+ goto out;
}
- tp->eee_enabled = eee->eee_enabled;
- tp->eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
+ if (tp->autoneg != AUTONEG_ENABLE) {
+ dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE requires autoneg\n");
+ rc = -EINVAL;
+ goto out;
+ }
- if (tp->eee_enabled)
- rtl8168_enable_EEE(tp);
- else
- rtl8168_disable_EEE(tp);
+ advertising = tp->advertising;
+ if (!edata->advertised) {
+ edata->advertised = advertising & eee->supported;
+ } else if (edata->advertised & ~advertising) {
+ dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of autoneg advertised speeds %x\n",
+ edata->advertised, advertising);
+ rc = -EINVAL;
+ goto out;
+ }
- spin_unlock_irqrestore(&tp->lock, flags);
+ if (edata->advertised & ~eee->supported) {
+ dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of support %x\n",
+ edata->advertised, eee->supported);
+ rc = -EINVAL;
+ goto out;
+ }
+
+ eee->advertised = edata->advertised;
+ eee->eee_enabled = edata->eee_enabled;
+
+ if (eee->eee_enabled)
+ rtl8168_enable_eee(tp);
+ else
+ rtl8168_disable_eee(tp);
rtl_nway_reset(net);
- return 0;
+ return rc;
+
+out:
+
+ return rc;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
.get_eeprom = rtl_get_eeprom,
.get_eeprom_len = rtl_get_eeprom_len,
+#ifdef ENABLE_RSS_SUPPORT
+ .get_rxnfc = rtl8168_get_rxnfc,
+ .set_rxnfc = rtl8168_set_rxnfc,
+ .get_rxfh_indir_size = rtl8168_rss_indir_size,
+ .get_rxfh_key_size = rtl8168_get_rxfh_key_size,
+ .get_rxfh = rtl8168_get_rxfh,
+ .set_rxfh = rtl8168_set_rxfh,
+#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
.get_ts_info = ethtool_op_get_ts_info,
#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
};
#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
-#if 0
-
-static int rtl8168_enable_green_feature(struct rtl8168_private *tp)
-{
- u16 gphy_val;
- unsigned long flags;
-
- switch (tp->mcfg) {
- case CFG_METHOD_14:
- case CFG_METHOD_15:
- rtl8168_mdio_write(tp, 0x1F, 0x0003);
- gphy_val = rtl8168_mdio_read(tp, 0x10) | 0x0400;
- rtl8168_mdio_write(tp, 0x10, gphy_val);
- gphy_val = rtl8168_mdio_read(tp, 0x19) | 0x0001;
- rtl8168_mdio_write(tp, 0x19, gphy_val);
- rtl8168_mdio_write(tp, 0x1F, 0x0005);
- gphy_val = rtl8168_mdio_read(tp, 0x01) & ~0x0100;
- rtl8168_mdio_write(tp, 0x01, gphy_val);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- rtl8168_mdio_write(tp, 0x00, 0x9200);
- mdelay(20);
- break;
-
- case CFG_METHOD_17:
- case CFG_METHOD_18:
- case CFG_METHOD_19:
- case CFG_METHOD_20:
- rtl8168_mdio_write(tp, 0x1f, 0x0003);
- gphy_val = rtl8168_mdio_read(tp, 0x10);
- gphy_val |= BIT_10;
- rtl8168_mdio_write(tp, 0x10, gphy_val);
- gphy_val = rtl8168_mdio_read(tp, 0x19);
- gphy_val |= BIT_0;
- rtl8168_mdio_write(tp, 0x19, gphy_val);
- rtl8168_mdio_write(tp, 0x1F, 0x0005);
- gphy_val = rtl8168_mdio_read(tp, 0x01);
- gphy_val |= BIT_8;
- rtl8168_mdio_write(tp, 0x01, gphy_val);
- rtl8168_mdio_write(tp, 0x1f, 0x0000);
- rtl8168_mdio_write(tp, 0x00, 0x9200);
- break;
- case CFG_METHOD_21:
- case CFG_METHOD_23:
- case CFG_METHOD_24:
- case CFG_METHOD_25:
- case CFG_METHOD_26:
- case CFG_METHOD_27:
- case CFG_METHOD_28:
- rtl8168_mdio_write(tp, 0x1F, 0x0A43);
- rtl8168_mdio_write(tp, 0x13, 0x8011);
- rtl8168_set_eth_phy_bit( tp, 0x14, BIT_14 );
- rtl8168_mdio_write(tp, 0x1F, 0x0A40);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- rtl8168_mdio_write(tp, 0x00, 0x9200);
- break;
- case CFG_METHOD_29:
- case CFG_METHOD_30:
- case CFG_METHOD_31:
- case CFG_METHOD_32:
- case CFG_METHOD_33:
- case CFG_METHOD_34:
- case CFG_METHOD_35:
- rtl8168_mdio_write(tp, 0x1F, 0x0A43);
- rtl8168_mdio_write(tp, 0x13, 0x8045);
- rtl8168_mdio_write(tp, 0x14, 0x0000);
- rtl8168_mdio_write(tp, 0x13, 0x804d);
- rtl8168_mdio_write(tp, 0x14, 0x1222);
- rtl8168_mdio_write(tp, 0x13, 0x805d);
- rtl8168_mdio_write(tp, 0x14, 0x0022);
- rtl8168_mdio_write(tp, 0x13, 0x8011);
- rtl8168_set_eth_phy_bit( tp, 0x14, BIT_15 );
- rtl8168_mdio_write(tp, 0x1F, 0x0A40);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- rtl8168_mdio_write(tp, 0x00, 0x9200);
- break;
- default:
- dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support Green Feature\n");
- break;
- }
-
- return 0;
-}
-
-static int rtl8168_disable_green_feature(struct rtl8168_private *tp)
-{
- u16 gphy_val;
- unsigned long flags;
-
- switch (tp->mcfg) {
- case CFG_METHOD_14:
- case CFG_METHOD_15:
- rtl8168_mdio_write(tp, 0x1F, 0x0005);
- gphy_val = rtl8168_mdio_read(tp, 0x01) | 0x0100;
- rtl8168_mdio_write(tp, 0x01, gphy_val);
- rtl8168_mdio_write(tp, 0x1F, 0x0003);
- gphy_val = rtl8168_mdio_read(tp, 0x10) & ~0x0400;
- rtl8168_mdio_write(tp, 0x10, gphy_val);
- gphy_val = rtl8168_mdio_read(tp, 0x19) & ~0x0001;
- rtl8168_mdio_write(tp, 0x19, gphy_val);
- rtl8168_mdio_write(tp, 0x1F, 0x0002);
- gphy_val = rtl8168_mdio_read(tp, 0x06) & ~0x7000;
- gphy_val |= 0x3000;
- rtl8168_mdio_write(tp, 0x06, gphy_val);
- gphy_val = rtl8168_mdio_read(tp, 0x0D) & 0x0700;
- gphy_val |= 0x0500;
- rtl8168_mdio_write(tp, 0x0D, gphy_val);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- break;
-
- case CFG_METHOD_17:
- case CFG_METHOD_18:
- case CFG_METHOD_19:
- case CFG_METHOD_20:
- rtl8168_mdio_write(tp, 0x1f, 0x0003);
- gphy_val = rtl8168_mdio_read(tp, 0x19);
- gphy_val &= ~BIT_0;
- rtl8168_mdio_write(tp, 0x19, gphy_val);
- gphy_val = rtl8168_mdio_read(tp, 0x10);
- gphy_val &= ~BIT_10;
- rtl8168_mdio_write(tp, 0x10, gphy_val);
- rtl8168_mdio_write(tp, 0x1f, 0x0000);
- break;
- case CFG_METHOD_21:
- case CFG_METHOD_23:
- case CFG_METHOD_24:
- case CFG_METHOD_25:
- case CFG_METHOD_26:
- case CFG_METHOD_27:
- case CFG_METHOD_28:
- rtl8168_mdio_write(tp, 0x1F, 0x0A43);
- rtl8168_mdio_write(tp, 0x13, 0x8011);
- rtl8168_clear_eth_phy_bit( tp, 0x14, BIT_14 );
- rtl8168_mdio_write(tp, 0x1F, 0x0A40);
- rtl8168_mdio_write(tp, 0x00, 0x9200);
- break;
- case CFG_METHOD_29:
- case CFG_METHOD_30:
- case CFG_METHOD_31:
- case CFG_METHOD_32:
- case CFG_METHOD_33:
- case CFG_METHOD_34:
- case CFG_METHOD_35:
- rtl8168_mdio_write(tp, 0x1F, 0x0A43);
- rtl8168_mdio_write(tp, 0x13, 0x8045);
- rtl8168_mdio_write(tp, 0x14, 0x2444);
- rtl8168_mdio_write(tp, 0x13, 0x804d);
- rtl8168_mdio_write(tp, 0x14, 0x2444);
- rtl8168_mdio_write(tp, 0x13, 0x805d);
- rtl8168_mdio_write(tp, 0x14, 0x2444);
- rtl8168_mdio_write(tp, 0x13, 0x8011);
- rtl8168_set_eth_phy_bit( tp, 0x14, BIT_15 );
- rtl8168_mdio_write(tp, 0x1F, 0x0A40);
- rtl8168_mdio_write(tp, 0x1F, 0x0000);
- rtl8168_mdio_write(tp, 0x00, 0x9200);
- break;
- default:
- dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support Green Feature\n");
- break;
- }
-
- return 0;
-}
-
-#endif
-
static void rtl8168_get_mac_version(struct rtl8168_private *tp)
{
u32 reg,val32;
tp->HwIcVerUnknown = TRUE;
}
- if (tp->mcfg == CFG_METHOD_30 &&
- (rtl8168_mac_ocp_read(tp, 0xD006) & 0xFF00) == 0x0100)
- tp->mcfg = CFG_METHOD_35;
+ if (tp->mcfg == CFG_METHOD_30) {
+ if ((rtl8168_mac_ocp_read(tp, 0xD006) & 0xFF00) ==
+ 0x0100)
+ tp->mcfg = CFG_METHOD_35;
+ else if ((rtl8168_mac_ocp_read(tp, 0xD006) & 0xFF00) ==
+ 0x0300)
+ tp->mcfg = CFG_METHOD_36;
+ }
+
+ tp->efuse_ver = EFUSE_SUPPORT_V3;
+ break;
+ case 0x6C000000:
+ if (ICVerID == 0x00000000) {
+ tp->mcfg = CFG_METHOD_37;
+ } else {
+ tp->mcfg = CFG_METHOD_37;
+ tp->HwIcVerUnknown = TRUE;
+ }
tp->efuse_ver = EFUSE_SUPPORT_V3;
break;
{
u16 reg = (u16)((DwCmd & 0x00FE0000) >> 17);
u32 DummyPos = rtl8168_calc_efuse_dummy_bit(reg);
- u32 DeCodeDwCmd = DwCmd;
+ u32 DeCodeDwCmd;
u32 Dw17BitData;
-
if (tp->efuse_ver < 3) {
DeCodeDwCmd = (DwCmd>>(DummyPos+1))<<DummyPos;
if (DummyPos > 0) {
//record fail case
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
rtl8168_mdio_write(tp, 0x13, 0x801C);
- PhyRegValue = 0;
PhyRegValue = watch_dog & 0x03;
PhyRegValue <<= 14;
if (uc_response) PhyRegValue |= BIT_13;
struct rtl8168_private *tp = netdev_priv(dev);
u16 data16;
- RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys));
+ rtl8168_disable_rx_packet_filter(tp);
if (HW_SUPP_SERDES_PHY(tp)) {
if (tp->HwSuppSerDesPhyVer == 1) {
break;
case CFG_METHOD_29:
case CFG_METHOD_30:
- case CFG_METHOD_35: {
+ case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37: {
u32 csi_tmp;
csi_tmp = rtl8168_eri_read(tp, 0x174, 2, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_8);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_disable_now_is_oob(tp);
data16 = rtl8168_mac_ocp_read(tp, 0xE8DE) & ~BIT_14;
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mac_ocp_write(tp, 0xFC38, 0x0000);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mac_ocp_write(tp, 0xFC28, 0x0000);
rtl8168_mac_ocp_write(tp, 0xFC2A, 0x0000);
rtl8168_mac_ocp_write(tp, 0xFC2C, 0x0000);
struct rtl8168_private *tp = netdev_priv(dev);
u16 i;
static const u16 mcu_patch_code_8168h_3 = {
- 0xE008, 0xE00A, 0xE00C, 0xE00E, 0xE010, 0xE039, 0xE03B, 0xE064, 0xC602,
- 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602,
- 0xBE00, 0x0000, 0xC727, 0x76E2, 0x49EE, 0xF1FD, 0x1E00, 0x8EE0, 0x1E1C,
- 0x8EE2, 0x76E2, 0x49EE, 0xF1FE, 0xC61D, 0x8EE0, 0x1E1D, 0x486F, 0x8EE2,
- 0x76E2, 0x49EE, 0xF12C, 0xC716, 0x76E0, 0x48E8, 0x48E9, 0x48EA, 0x48EB,
- 0x48EC, 0x9EE0, 0xC709, 0xC609, 0x9EF4, 0xC608, 0x9EF6, 0xB007, 0xC602,
- 0xBE00, 0x0ACC, 0xE000, 0x03BF, 0x07FF, 0xDE24, 0x3200, 0xE096, 0xC602,
- 0xBE00, 0x0000, 0x8EE6, 0xC726, 0x76E2, 0x49EE, 0xF1FD, 0x1E00, 0x8EE0,
- 0x1E1C, 0x8EE2, 0x76E2, 0x49EE, 0xF1FE, 0xC61C, 0x8EE0, 0x1E1D, 0x486F,
- 0x8EE2, 0x76E2, 0x49EE, 0xF1FE, 0xC715, 0x76E0, 0x48E8, 0x48E9, 0x48EA,
- 0x48EB, 0x48EC, 0x9EE0, 0xC708, 0xC608, 0x9EF4, 0xC607, 0x9EF6, 0xC602,
- 0xBE00, 0x0ABE, 0xE000, 0x03BF, 0x07FF, 0xDE24, 0x3200, 0xE096, 0xC602,
- 0xBE00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xE008, 0xE00A, 0xE00C, 0xE00E, 0xE010, 0xE03E, 0xE040, 0xE069, 0xC602,
+ 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC002, 0xB800, 0x0000, 0xC602,
+ 0xBE00, 0x0000, 0xC72B, 0x76E2, 0x49EE, 0xF1FD, 0x1E00, 0x9EE0, 0x1E1C,
+ 0x9EE2, 0x76E2, 0x49EE, 0xF1FE, 0xC621, 0x9EE0, 0x1E1D, 0x486F, 0x9EE2,
+ 0x76E2, 0x49EE, 0xF1FE, 0xC71A, 0x76E0, 0x48E8, 0x48E9, 0x48EA, 0x48EB,
+ 0x48EC, 0x9EE0, 0xC70D, 0xC60D, 0x9EF4, 0xC60C, 0x9EF6, 0xC70E, 0x76E0,
+ 0x4863, 0x9EE0, 0xB007, 0xC602, 0xBE00, 0x0ACC, 0xE000, 0x03BF, 0x07FF,
+ 0xDE24, 0x3200, 0xE096, 0xD438, 0xC602, 0xBE00, 0x0000, 0x8EE6, 0xC726,
+ 0x76E2, 0x49EE, 0xF1FD, 0x1E00, 0x8EE0, 0x1E1C, 0x8EE2, 0x76E2, 0x49EE,
+ 0xF1FE, 0xC61C, 0x8EE0, 0x1E1D, 0x486F, 0x8EE2, 0x76E2, 0x49EE, 0xF1FE,
+ 0xC715, 0x76E0, 0x48E8, 0x48E9, 0x48EA, 0x48EB, 0x48EC, 0x9EE0, 0xC708,
+ 0xC608, 0x9EF4, 0xC607, 0x9EF6, 0xC602, 0xBE00, 0x0ABE, 0xE000, 0x03BF,
+ 0x07FF, 0xDE24, 0x3200, 0xE096, 0xC602, 0xBE00, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x6838, 0x0A16, 0x0901, 0x101C
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6838, 0x0A17, 0x0613, 0x0D26
};
rtl8168_hw_disable_mac_mcu_bps(dev);
}
static void
+rtl8168_set_mac_mcu_8168h_4(struct net_device *dev)
+{
+ rtl8168_hw_disable_mac_mcu_bps(dev);
+}
+
+static void
rtl8168_set_mac_mcu_8168fp_1(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
rtl8168_mac_ocp_write(tp, 0xFC34, 0x0A68);
rtl8168_mac_ocp_write(tp, 0xFC36, 0x0A84);
- } else if (tp->HwPkgDet == 0x6) {
+ } else if (tp->HwPkgDet == 0x05 || tp->HwPkgDet == 0x06) {
static const u16 mcu_patch_code_8168fp_1_2 = {
0xE008, 0xE00A, 0xE031, 0xE033, 0xE035, 0xE144, 0xE166, 0xE168, 0xC502,
0xBD00, 0x0000, 0xC725, 0x75E0, 0x48D0, 0x9DE0, 0xC722, 0x75E0, 0x1C78,
breakPointEnabled = 0x00FC;
else if (tp->HwPkgDet == 0x0F)
breakPointEnabled = 0x00FF;
- else if (tp->HwPkgDet == 0x06)
+ else if (tp->HwPkgDet == 0x05 || tp->HwPkgDet == 0x06)
breakPointEnabled = 0x0022;
rtl8168_mac_ocp_write(tp, 0xFC38, breakPointEnabled);
rtl8168_set_mac_mcu_8168h_1(dev);
break;
case CFG_METHOD_30:
+ case CFG_METHOD_37:
rtl8168_set_mac_mcu_8168h_2(dev);
break;
case CFG_METHOD_31:
case CFG_METHOD_35:
rtl8168_set_mac_mcu_8168h_3(dev);
break;
+ case CFG_METHOD_36:
+ rtl8168_set_mac_mcu_8168h_4(dev);
+ break;
}
}
#endif
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mac_ocp_write(tp, 0xE63E, rtl8168_mac_ocp_read( tp, 0xE63E) & ~(BIT_3 | BIT_2 | BIT_1));
rtl8168_mac_ocp_write(tp, 0xE63E, rtl8168_mac_ocp_read( tp, 0xE63E) | (BIT_0));
rtl8168_mac_ocp_write(tp, 0xE63E, rtl8168_mac_ocp_read( tp, 0xE63E) & ~(BIT_0));
break;
}
- switch (tp->mcfg) {
- case CFG_METHOD_16:
- case CFG_METHOD_17:
- case CFG_METHOD_18:
- case CFG_METHOD_19:
- case CFG_METHOD_20:
- if (aspm) {
- RTL_W8(tp, 0x6E, RTL_R8(tp, 0x6E) | BIT_6);
- rtl8168_eri_write(tp, 0x1AE, 2, 0x0403, ERIAR_ExGMAC);
- }
- break;
- case CFG_METHOD_21:
- case CFG_METHOD_22:
- case CFG_METHOD_29:
- case CFG_METHOD_30:
- case CFG_METHOD_35:
- if (aspm) {
- if ((rtl8168_mac_ocp_read(tp, 0xDC00) & BIT_3) || (RTL_R8(tp, Config0) & 0x07)) {
- RTL_W8(tp, 0x6E, RTL_R8(tp, 0x6E) | BIT_6);
- rtl8168_eri_write(tp, 0x1AE, 2, 0x0403, ERIAR_ExGMAC);
- }
- }
- break;
- }
-
if (tp->mcfg == CFG_METHOD_10 || tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15)
RTL_W8(tp, 0xF3, RTL_R8(tp, 0xF3) | BIT_2);
tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35)
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37)
if (!tp->dash_printer_enabled)
rtl8168_disable_ocp_phy_power_saving(dev);
break;
case CFG_METHOD_29:
case CFG_METHOD_30:
+ case CFG_METHOD_37:
ClearPCIePhyBit(tp, 0x1E, BIT_11);
SetPCIePhyBit(tp, 0x1E, BIT_0);
break;
case CFG_METHOD_35:
- rtl8168_clear_mcu_ocp_bit(tp, 0xDE38, BIT_2);
+ rtl8168_clear_mcu_ocp_bit(tp, 0xD438, BIT_2);
ClearPCIePhyBit(tp, 0x24, BIT_9);
rtl8168_clear_mcu_ocp_bit(tp, 0xDE28, (BIT_1 | BIT_0));
- rtl8168_set_mcu_ocp_bit(tp, 0xDE38, BIT_2);
+ rtl8168_set_mcu_ocp_bit(tp, 0xD438, BIT_2);
+
+ break;
+ case CFG_METHOD_36:
+ rtl8168_clear_mcu_ocp_bit(tp, 0xD438, BIT_2);
+
+ rtl8168_clear_mcu_ocp_bit(tp, 0xDE28, (BIT_1 | BIT_0));
+
+ rtl8168_set_mcu_ocp_bit(tp, 0xD438, BIT_2);
break;
}
int retval = TRUE;
switch (tp->mcfg) {
- case CFG_METHOD_21 ... CFG_METHOD_35:
+ case CFG_METHOD_21 ... CFG_METHOD_37:
rtl8168_mdio_write(tp,0x1f, 0x0B82);
rtl8168_set_eth_phy_bit(tp, 0x10, BIT_4);
int retval = TRUE;
switch (tp->mcfg) {
- case CFG_METHOD_21 ... CFG_METHOD_35:
+ case CFG_METHOD_21 ... CFG_METHOD_37:
rtl8168_mdio_write(tp, 0x1f, 0x0B82);
rtl8168_clear_eth_phy_bit(tp, 0x10, BIT_4);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
rtl8168_mdio_write(tp, 0x13, 0x801E);
hw_ram_code_ver = rtl8168_mdio_read(tp, 0x14);
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
rtl8168_mdio_write(tp, 0x13, 0x801E);
rtl8168_mdio_write(tp, 0x14, tp->sw_ram_code_ver);
PhyRegValue &= ~(BIT_11);
rtl8168_mdio_write(tp, 0x14, PhyRegValue);
- retval = rtl8168_set_phy_mcu_patch_request(tp);
+ rtl8168_set_phy_mcu_patch_request(tp);
rtl8168_mdio_write(tp, 0x1f, 0x0A40);
rtl8168_mdio_write(tp, 0x10, 0x0140);
PhyRegValue |= (BIT_11|BIT_12);
rtl8168_mdio_write(tp, 0x11, PhyRegValue);
- retval = rtl8168_clear_phy_mcu_patch_request(tp);
+ rtl8168_clear_phy_mcu_patch_request(tp);
rtl8168_mdio_write(tp, 0x1f, 0x0A40);
rtl8168_mdio_write(tp, 0x10, 0x1040);
PhyRegValue |= (BIT_11);
rtl8168_mdio_write(tp, 0x14, PhyRegValue);
- retval = rtl8168_set_phy_mcu_patch_request(tp);
+ rtl8168_set_phy_mcu_patch_request(tp);
rtl8168_mdio_write(tp, 0x1f, 0x0A20);
PhyRegValue = rtl8168_mdio_read(tp, 0x13);
}
}
- retval = rtl8168_clear_phy_mcu_patch_request(tp);
+ rtl8168_clear_phy_mcu_patch_request(tp);
mdelay(2);
break;
rtl8168_mdio_write(tp, 0x13, 0x0000);
rtl8168_mdio_write(tp, 0x14, 0x0000);
rtl8168_mdio_write(tp, 0x1f, 0x0B82);
- gphy_val = rtl8168_mdio_read(tp, 0x17);
+ gphy_val = rtl8168_mdio_read(tp, 0x17);
gphy_val &= ~(BIT_0);
rtl8168_mdio_write(tp, 0x17, gphy_val);
rtl8168_mdio_write(tp, 0x1f, 0x0A43);
rtl8168_mdio_write(tp, 0x13, 0xA014);
rtl8168_mdio_write(tp, 0x14, 0x2c04);
rtl8168_mdio_write(tp, 0x14, 0x2c09);
- rtl8168_mdio_write(tp, 0x14, 0x2c09);
- rtl8168_mdio_write(tp, 0x14, 0x2c09);
+ rtl8168_mdio_write(tp, 0x14, 0x2c0d);
+ rtl8168_mdio_write(tp, 0x14, 0x2c12);
rtl8168_mdio_write(tp, 0x14, 0xad01);
rtl8168_mdio_write(tp, 0x14, 0xad01);
rtl8168_mdio_write(tp, 0x14, 0xad01);
rtl8168_mdio_write(tp, 0x14, 0xad01);
rtl8168_mdio_write(tp, 0x14, 0x236c);
+ rtl8168_mdio_write(tp, 0x14, 0xd03c);
+ rtl8168_mdio_write(tp, 0x14, 0xd1aa);
+ rtl8168_mdio_write(tp, 0x14, 0xc010);
+ rtl8168_mdio_write(tp, 0x14, 0x2745);
+ rtl8168_mdio_write(tp, 0x14, 0x33de);
+ rtl8168_mdio_write(tp, 0x14, 0x16ba);
+ rtl8168_mdio_write(tp, 0x14, 0x31ee);
+ rtl8168_mdio_write(tp, 0x14, 0x2712);
+ rtl8168_mdio_write(tp, 0x14, 0x274e);
+ rtl8168_mdio_write(tp, 0x14, 0xc2bb);
+ rtl8168_mdio_write(tp, 0x14, 0xd500);
+ rtl8168_mdio_write(tp, 0x14, 0xc426);
+ rtl8168_mdio_write(tp, 0x14, 0xd01d);
+ rtl8168_mdio_write(tp, 0x14, 0xd1c3);
+ rtl8168_mdio_write(tp, 0x14, 0x401c);
+ rtl8168_mdio_write(tp, 0x14, 0xd501);
+ rtl8168_mdio_write(tp, 0x14, 0xc2b3);
+ rtl8168_mdio_write(tp, 0x14, 0xd500);
+ rtl8168_mdio_write(tp, 0x14, 0xd00b);
+ rtl8168_mdio_write(tp, 0x14, 0xd1c3);
+ rtl8168_mdio_write(tp, 0x14, 0x401c);
+ rtl8168_mdio_write(tp, 0x14, 0x241a);
rtl8168_mdio_write(tp, 0x13, 0xA01A);
rtl8168_mdio_write(tp, 0x14, 0x0000);
rtl8168_mdio_write(tp, 0x13, 0xA006);
- rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x14, 0x0414);
rtl8168_mdio_write(tp, 0x13, 0xA004);
- rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x14, 0x074c);
rtl8168_mdio_write(tp, 0x13, 0xA002);
- rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x14, 0x0744);
rtl8168_mdio_write(tp, 0x13, 0xA000);
- rtl8168_mdio_write(tp, 0x14, 0x136b);
+ rtl8168_mdio_write(tp, 0x14, 0xf36b);
rtl8168_mdio_write(tp, 0x13, 0xB820);
rtl8168_mdio_write(tp, 0x14, 0x0210);
rtl8168_mdio_write(tp, 0x14, 0x0000);
rtl8168_mdio_write(tp, 0x13, 0xA014);
rtl8168_mdio_write(tp, 0x14, 0x1800);
- rtl8168_mdio_write(tp, 0x14, 0x8002);
+ rtl8168_mdio_write(tp, 0x14, 0x8010);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8014);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8022);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8022);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8022);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8022);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8022);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x8022);
rtl8168_mdio_write(tp, 0x14, 0x2b5d);
rtl8168_mdio_write(tp, 0x14, 0x0c68);
rtl8168_mdio_write(tp, 0x14, 0x1800);
rtl8168_mdio_write(tp, 0x14, 0x0b3c);
+ rtl8168_mdio_write(tp, 0x14, 0xc2bb);
+ rtl8168_mdio_write(tp, 0x14, 0xd500);
+ rtl8168_mdio_write(tp, 0x14, 0xc426);
+ rtl8168_mdio_write(tp, 0x14, 0xd01d);
+ rtl8168_mdio_write(tp, 0x14, 0xd1c3);
+ rtl8168_mdio_write(tp, 0x14, 0x401c);
+ rtl8168_mdio_write(tp, 0x14, 0xd501);
+ rtl8168_mdio_write(tp, 0x14, 0xc2b3);
+ rtl8168_mdio_write(tp, 0x14, 0xd500);
+ rtl8168_mdio_write(tp, 0x14, 0xd00b);
+ rtl8168_mdio_write(tp, 0x14, 0xd1c3);
+ rtl8168_mdio_write(tp, 0x14, 0x401c);
+ rtl8168_mdio_write(tp, 0x14, 0x1800);
+ rtl8168_mdio_write(tp, 0x14, 0x0478);
+ rtl8168_mdio_write(tp, 0x13, 0xA026);
+ rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x13, 0xA024);
+ rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x13, 0xA022);
+ rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x13, 0xA020);
+ rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x13, 0xA006);
+ rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x13, 0xA004);
+ rtl8168_mdio_write(tp, 0x14, 0x0fff);
+ rtl8168_mdio_write(tp, 0x13, 0xA002);
+ rtl8168_mdio_write(tp, 0x14, 0x0472);
rtl8168_mdio_write(tp, 0x13, 0xA000);
rtl8168_mdio_write(tp, 0x14, 0x0b3a);
rtl8168_mdio_write(tp, 0x13, 0xA008);
- rtl8168_mdio_write(tp, 0x14, 0x0100);
+ rtl8168_mdio_write(tp, 0x14, 0x0300);
rtl8168_mdio_write(tp, 0x13, 0xB820);
rtl8168_mdio_write(tp, 0x14, 0x0010);
rtl8168_set_phy_mcu_8168h_1(dev);
break;
case CFG_METHOD_30:
+ case CFG_METHOD_37:
rtl8168_set_phy_mcu_8168h_2(dev);
break;
case CFG_METHOD_35:
rtl8168_set_phy_mcu_8168h_3(dev);
break;
+ case CFG_METHOD_36:
+ break;
}
if (require_disable_phy_disable_mode)
rtl8168_mdio_write(tp, 0x06, rtl8168_mdio_read(tp, 0x06) & ~BIT_8);
rtl8168_mdio_write(tp, 0x1f, 0x0000);
+
+ rtl8168_mdio_write(tp, 0x1F, 0x0007);
+ rtl8168_mdio_write(tp, 0x1E, 0x0023);
+ rtl8168_clear_eth_phy_bit(tp, 0x17, BIT_1);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+
+
if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) {
rtl8168_mdio_write(tp, 0x1f, 0x0005);
rtl8168_mdio_write(tp, 0x05, 0x8b85);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
}
}
- } else if (tp->mcfg == CFG_METHOD_30) {
+ } else if (tp->mcfg == CFG_METHOD_30 || tp->mcfg == CFG_METHOD_37) {
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
rtl8168_mdio_write(tp, 0x13, 0x808A);
ClearAndSetEthPhyBit( tp,
BIT_12);
}
+
+ rtl8168_mdio_write(tp, 0x1F, 0x0C41);
+ rtl8168_clear_eth_phy_bit(tp, 0x15, BIT_1);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+
+
+ rtl8168_mdio_write(tp, 0x1F, 0x0A43);
+ rtl8168_set_eth_phy_bit(tp, 0x10, BIT_0);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+
+
if (aspm) {
if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) {
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
rtl8168_mdio_write(tp, 0x1F, 0x0A43);
rtl8168_mdio_write(tp, 0x13, 0x8011);
- rtl8168_set_eth_phy_bit(tp, 0x14, BIT_11);
+ rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_11);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
rtl8168_mdio_write(tp, 0x1F, 0x0A44);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
}
}
+ } else if (tp->mcfg == CFG_METHOD_36) {
+ rtl8168_mdio_write(tp, 0x1F, 0x0A44);
+ rtl8168_set_eth_phy_bit(tp, 0x11, BIT_11);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+
+
+ rtl8168_mdio_write(tp, 0x1F, 0x0C41);
+ rtl8168_clear_eth_phy_bit(tp, 0x15, BIT_1);
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+
+
+ if (aspm) {
+ if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) {
+ rtl8168_mdio_write(tp, 0x1F, 0x0A43);
+ rtl8168_set_eth_phy_bit( tp, 0x10, BIT_2 );
+ rtl8168_mdio_write(tp, 0x1F, 0x0000);
+ }
+ }
}
#ifdef ENABLE_FIBER_SUPPORT
} else if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36) {
//enable EthPhyPPSW
rtl8168_mdio_write(tp, 0x1F, 0x0A44);
rtl8168_set_eth_phy_bit( tp, 0x11, BIT_7 );
tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
if (aspm)
rtl8168_enable_ocp_phy_power_saving(dev);
}
rtl8168_mdio_write(tp, 0x1F, 0x0000);
if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) {
- if (tp->eee_enabled)
- rtl8168_enable_EEE(tp);
+ if (tp->eee.eee_enabled)
+ rtl8168_enable_eee(tp);
else
- rtl8168_disable_EEE(tp);
+ rtl8168_disable_eee(tp);
}
}
+/*
static inline void rtl8168_delete_esd_timer(struct net_device *dev, struct timer_list *timer)
{
del_timer_sync(timer);
#endif
mod_timer(timer, jiffies + RTL8168_LINK_TIMEOUT);
}
+*/
#ifdef CONFIG_NET_POLL_CONTROLLER
/*
rtl8168_netpoll(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
+ int i;
+ for (i = 0; i < tp->irq_nvecs; i++) {
+ struct r8168_irq *irq = &tp->irq_tbli;
+ struct r8168_napi *r8168napi = &tp->r8168napii;
- disable_irq(tp->irq);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
- rtl8168_interrupt(tp->irq, dev, NULL);
+ disable_irq(irq->vector);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
+ irq->handler(irq->vector, r8168napi);
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+ irq->handler(irq->vector, r8168napi, NULL);
#else
- rtl8168_interrupt(tp->irq, dev);
+ irq->handler(irq->vector, r8168napi);
#endif
- enable_irq(tp->irq);
+ enable_irq(irq->vector);
+ }
}
-#endif
+
+#endif //CONFIG_NET_POLL_CONTROLLER
static void
rtl8168_get_bios_setting(struct net_device *dev)
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->bios_setting = RTL_R32(tp, 0x8c);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
RTL_W32(tp, 0x8C, tp->bios_setting);
break;
}
}
static void
+rtl8168_setup_mqs_reg(struct rtl8168_private *tp)
+{
+ //tx
+ tp->tx_ring0.tdsar_reg = TxDescStartAddrLow;
+ tp->tx_ring1.tdsar_reg = TxHDescStartAddrLow;
+
+ tp->isr_reg0 = IntrStatus;
+ tp->isr_reg1 = IntrStatus1;
+ tp->isr_reg2 = IntrStatus2;
+ tp->isr_reg3 = IntrStatus3;
+
+ tp->imr_reg0 = IntrMask;
+ tp->imr_reg1 = IntrMask1;
+ tp->imr_reg2 = IntrMask2;
+ tp->imr_reg3 = IntrMask3;
+}
+
+static void
rtl8168_init_software_variable(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
rtl8168_get_bios_setting(dev);
- tp->num_rx_desc = NUM_RX_DESC;
- tp->num_tx_desc = NUM_TX_DESC;
+#ifdef ENABLE_LIB_SUPPORT
+ tp->ring_lib_enabled = 1;
+#endif
+
+ if (tp->mcfg == CFG_METHOD_DEFAULT)
+ disable_wol_support = 1;
switch (tp->mcfg) {
case CFG_METHOD_11:
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->HwSuppNowIsOobVer = 1;
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->HwSuppPhyOcpVer = 1;
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
tp->HwSuppUpsVer = 1;
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->HwSuppAspmClkIntrLock = 1;
break;
}
u64 CmacMemPhysAddress;
void __iomem *cmac_ioaddr = NULL;
struct pci_dev *pdev_cmac;
+ int ret;
pdev_cmac = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
+ ret = pci_enable_device(pdev_cmac);
+ if (ret < 0) {
+ dev_err(&pdev_cmac->dev, "eable device fail %d\n", ret);
+ goto err1;
+ }
+
+ ret = pci_request_regions(pdev_cmac, MODULENAME);
+ if (ret < 0) {
+ dev_err(&pdev_cmac->dev, "could not request regions %d\n", ret);
+ goto err2;
+ }
//map CMAC IO space
CmacMemPhysAddress = pci_resource_start(pdev_cmac, 2);
if (netif_msg_probe(tp))
dev_err(&pdev->dev, "cannot remap CMAC MMIO, aborting\n");
#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ pci_release_regions(pdev_cmac);
+err2:
+ pci_disable_device(pdev_cmac);
+err1:
tp->DASH = 0;
} else {
- tp->mapped_cmac_ioaddr = cmac_ioaddr;
+ pci_set_master(pdev_cmac);
+ tp->cmac_ioaddr = cmac_ioaddr;
+ tp->pdev_cmac = pdev_cmac;
}
}
if (HW_DASH_SUPPORT_TYPE_2(tp))
tp->cmac_ioaddr = tp->mmio_addr;
- else if (HW_DASH_SUPPORT_TYPE_3(tp))
- tp->cmac_ioaddr = tp->mapped_cmac_ioaddr;
switch (tp->mcfg) {
case CFG_METHOD_1:
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->org_pci_offset_99 = rtl8168_csi_fun0_read_byte(tp, 0x99);
tp->org_pci_offset_99 &= ~(BIT_5|BIT_6);
break;
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->org_pci_offset_180 = rtl8168_csi_fun0_read_byte(tp, 0x180);
break;
case CFG_METHOD_31:
break;
}
- if (timer_count == 0 || tp->mcfg == CFG_METHOD_DEFAULT)
+ if (timer_count == 0 || tp->mcfg == CFG_METHOD_DEFAULT ||
+ (tp->features & RTL_FEATURE_MSIX))
tp->use_timer_interrrupt = FALSE;
switch (tp->mcfg) {
}
switch (tp->mcfg) {
- case CFG_METHOD_30: {
+ case CFG_METHOD_30:
+ case CFG_METHOD_37: {
u16 ioffset_p3, ioffset_p2, ioffset_p1, ioffset_p0;
u16 TmpUshort;
case CFG_METHOD_31:
case CFG_METHOD_32:
case CFG_METHOD_33:
- case CFG_METHOD_34: {
+ case CFG_METHOD_34:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37: {
u16 rg_saw_cnt;
rtl8168_mdio_write(tp, 0x1F, 0x0C42);
case CFG_METHOD_19:
case CFG_METHOD_20:
case CFG_METHOD_30:
+ case CFG_METHOD_37:
tp->RequiredSecLanDonglePatch = TRUE;
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->HwSuppMagicPktVer = WAKEUP_MAGIC_PACKET_V2;
break;
case CFG_METHOD_DEFAULT:
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
tp->HwSuppCheckPhyDisableModeVer = 2;
break;
case CFG_METHOD_23:
break;
case CFG_METHOD_29:
case CFG_METHOD_30:
+ case CFG_METHOD_37:
tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_29;
break;
case CFG_METHOD_31:
case CFG_METHOD_35:
tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_35;
break;
+ case CFG_METHOD_36:
+ tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_36;
+ break;
}
if (tp->HwIcVerUnknown) {
tp->NotWrMcuPatchCode = TRUE;
}
+ switch (tp->mcfg) {
+ case CFG_METHOD_16 ... CFG_METHOD_37:
+ tp->HwSuppRxDescType = RX_DESC_RING_TYPE_2;
+ break;
+ default:
+ tp->HwSuppRxDescType = RX_DESC_RING_TYPE_1;
+ break;
+ }
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_29:
+ case CFG_METHOD_30:
+ case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
+ tp->HwSuppNumTxQueues = 2;
+ tp->HwSuppNumRxQueues = 4;
+ break;
+ default:
+ tp->HwSuppNumTxQueues = 1;
+ tp->HwSuppNumRxQueues = 1;
+ break;
+ }
+
+ tp->num_tx_rings = 1;
+#ifdef ENABLE_MULTIPLE_TX_QUEUE
+#ifndef ENABLE_LIB_SUPPORT
+ tp->num_tx_rings = tp->HwSuppNumTxQueues;
+#endif
+#endif
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_29:
+ case CFG_METHOD_30:
+ case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
+ tp->HwSuppRssVer = 2;
+ tp->HwSuppIndirTblEntries = RTL8168_MAX_INDIRECTION_TABLE_ENTRIES;
+ break;
+ }
+
+ tp->num_rx_rings = 1;
+#ifdef ENABLE_RSS_SUPPORT
+ if (HW_RSS_SUPPORT_RSS(tp)) {
+#ifdef ENABLE_LIB_SUPPORT
+ tp->EnableRss = 1;
+#else
+ u8 rss_queue_num = netif_get_num_default_rss_queues();
+ tp->num_rx_rings = (tp->HwSuppNumRxQueues > rss_queue_num)?
+ rss_queue_num : tp->HwSuppNumRxQueues;
+ if (tp->num_rx_rings >= 2)
+ tp->EnableRss = 1;
+#endif
+ }
+#endif
+ if (!tp->EnableRss || tp->num_rx_rings < 1)
+ tp->num_rx_rings = 1;
+
+#ifdef ENABLE_LIB_SUPPORT
+ tp->num_hw_tot_en_rx_rings = 2;
+#else
+ tp->num_hw_tot_en_rx_rings = tp->num_rx_rings;
+#endif //ENABLE_LIB_SUPPORT
+
+ rtl8168_setup_mqs_reg(tp);
+
+ rtl8168_set_ring_size(tp, NUM_RX_DESC, NUM_TX_DESC);
+
+ tp->InitRxDescType = RX_DESC_RING_TYPE_1;
+ if (tp->EnableRss)
+ tp->InitRxDescType = RX_DESC_RING_TYPE_2;
+
+ tp->RxDescLength = RX_DESC_LEN_TYPE_1;
+ if (tp->InitRxDescType == RX_DESC_RING_TYPE_2)
+ tp->RxDescLength = RX_DESC_LEN_TYPE_2;
+
tp->NicCustLedValue = RTL_R16(tp, CustomLED);
rtl8168_get_hw_wol(dev);
dev->min_mtu = ETH_MIN_MTU;
dev->max_mtu = tp->max_jumbo_frame_size;
#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
- tp->eee_enabled = eee_enable;
- tp->eee_adv_t = MDIO_EEE_1000T | MDIO_EEE_100TX;
+
+ if (rtl8168_support_eee(tp)) {
+ struct ethtool_eee *eee = &tp->eee;
+
+ eee->eee_enabled = eee_enable;
+ eee->supported = SUPPORTED_100baseT_Full |
+ SUPPORTED_1000baseT_Full;
+ eee->advertised = mmd_eee_adv_to_ethtool_adv_t(MDIO_EEE_1000T | MDIO_EEE_100TX);
+ eee->tx_lpi_enabled = eee_enable;
+ eee->tx_lpi_timer = dev->mtu + ETH_HLEN + 0x20;
+ }
#ifdef ENABLE_FIBER_SUPPORT
if (HW_FIBER_MODE_ENABLED(tp))
rtl8168_set_fiber_mode_software_variable(tp);
#endif //ENABLE_FIBER_SUPPORT
+
+#ifdef ENABLE_RSS_SUPPORT
+ if (tp->EnableRss)
+ rtl8168_init_rss(tp);
+#endif
}
static void
FreeAllocatedDashShareMemory(dev);
#endif
- if (tp->mapped_cmac_ioaddr != NULL)
- iounmap(tp->mapped_cmac_ioaddr);
+ if (tp->pdev_cmac) {
+ iounmap(tp->cmac_ioaddr);
+ pci_clear_master(tp->pdev_cmac);
+ pci_release_regions(tp->pdev_cmac);
+ pci_disable_device(tp->pdev_cmac);
+ tp->pdev_cmac = NULL;
+ }
iounmap(ioaddr);
pci_release_regions(pdev);
tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 ||
tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 ||
+ tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
*(u32*)&mac_addr0 = rtl8168_eri_read(tp, 0xE0, 4, ERIAR_ExGMAC);
*(u16*)&mac_addr4 = rtl8168_eri_read(tp, 0xE4, 2, ERIAR_ExGMAC);
} else {
tp->mcfg == CFG_METHOD_32 ||
tp->mcfg == CFG_METHOD_33 ||
tp->mcfg == CFG_METHOD_34 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 ||
+ tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
*pUshort++ = rtl8168_eeprom_read_sc(tp, 1);
*pUshort++ = rtl8168_eeprom_read_sc(tp, 2);
*pUshort = rtl8168_eeprom_read_sc(tp, 3);
/* keep the original MAC address */
memcpy(tp->org_mac_addr, dev->dev_addr, MAC_ADDR_LEN);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ memcpy(dev->perm_addr, dev->dev_addr, MAC_ADDR_LEN);
#endif
return 0;
}
{
struct rtl8168_private *tp = netdev_priv(dev);
struct sockaddr *addr = p;
- unsigned long flags;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_hw_address_set(dev, addr->sa_data);
rtl8168_rar_set(tp, dev->dev_addr);
- spin_unlock_irqrestore(&tp->lock, flags);
-
return 0;
}
struct rtl8168_private *tp = netdev_priv(dev);
struct mii_ioctl_data *data = if_mii(ifr);
int ret;
- unsigned long flags;
ret = 0;
switch (cmd) {
break;
case SIOCGMIIREG:
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
data->val_out = rtl8168_mdio_read(tp, data->reg_num);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
case SIOCSMIIREG:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_write(tp, 0x1F, 0x0000);
rtl8168_mdio_write(tp, data->reg_num, data->val_in);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
#ifdef ETHTOOL_OPS_COMPAT
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mdio_write(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN);
break;
case CFG_METHOD_21:
assert(ioaddr_out != NULL);
/* dev zeroed in alloc_etherdev */
- dev = alloc_etherdev(sizeof (*tp));
+ dev = alloc_etherdev_mq(sizeof (*tp), R8168_MAX_QUEUES);
if (dev == NULL) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
if (netif_msg_drv(&debug))
}
static void
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
-rtl8168_esd_timer(unsigned long __opaque)
-#else
-rtl8168_esd_timer(struct timer_list *t)
-#endif
+rtl8168_esd_checker(struct rtl8168_private *tp)
{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
- struct net_device *dev = (struct net_device *)__opaque;
- struct rtl8168_private *tp = netdev_priv(dev);
- struct timer_list *timer = &tp->esd_timer;
-#else
- struct rtl8168_private *tp = from_timer(tp, t, esd_timer);
struct net_device *dev = tp->dev;
- struct timer_list *timer = t;
-#endif
struct pci_dev *pdev = tp->pci_dev;
- unsigned long timeout = RTL8168_ESD_TIMEOUT;
- unsigned long flags;
u8 cmd;
u16 io_base_l;
u16 mem_base_l;
u32 pci_sn_l;
u32 pci_sn_h;
- spin_lock_irqsave(&tp->lock, flags);
-
if (unlikely(tp->rtk_enable_diag))
- goto out_unlock;
+ goto exit;
tp->esd_flag = 0;
pci_read_config_byte(pdev, PCI_COMMAND, &cmd);
if (cmd == 0xff) {
printk(KERN_ERR "%s: pci link is down \n.", dev->name);
- goto out_unlock;
+ goto exit;
}
}
if (tp->esd_flag != 0) {
printk(KERN_ERR "%s: esd_flag = 0x%04x\n.\n", dev->name, tp->esd_flag);
- netif_stop_queue(dev);
netif_carrier_off(dev);
+ netif_tx_disable(dev);
rtl8168_hw_reset(dev);
rtl8168_tx_clear(tp);
rtl8168_rx_clear(tp);
tp->esd_flag = 0;
}
-out_unlock:
- spin_unlock_irqrestore(&tp->lock, flags);
+exit:
+ return;
+}
+
+/*
+static void
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
+rtl8168_esd_timer(unsigned long __opaque)
+#else
+rtl8168_esd_timer(struct timer_list *t)
+#endif
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
+ struct net_device *dev = (struct net_device *)__opaque;
+ struct rtl8168_private *tp = netdev_priv(dev);
+ struct timer_list *timer = &tp->esd_timer;
+#else
+ struct rtl8168_private *tp = from_timer(tp, t, esd_timer);
+ //struct net_device *dev = tp->dev;
+ struct timer_list *timer = t;
+#endif
+ rtl8168_esd_checker(tp);
mod_timer(timer, jiffies + timeout);
}
+*/
+/*
static void
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0)
rtl8168_link_timer(unsigned long __opaque)
struct net_device *dev = tp->dev;
struct timer_list *timer = t;
#endif
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_check_link_status(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
mod_timer(timer, jiffies + RTL8168_LINK_TIMEOUT);
}
+*/
-static int rtl8168_enable_msix(struct rtl8168_private *tp)
+int rtl8168_enable_msix(struct rtl8168_private *tp)
{
- int nvecs = 0;
- struct msix_entry msix_ent1 = {0};
+ int i, nvecs = 0;
+ struct msix_entry msix_entR8168_MAX_MSIX_VEC;
+ //struct net_device *dev = tp->dev;
+ //const int len = sizeof(tp->irq_tbl0.name);
+
+ for (i = 0; i < R8168_MAX_MSIX_VEC; i++) {
+ msix_enti.entry = i;
+ msix_enti.vector = 0;
+ }
nvecs = pci_enable_msix_range(tp->pci_dev, msix_ent,
- 1, 1);
+ tp->min_irq_nvecs, tp->max_irq_nvecs);
if (nvecs < 0)
goto out;
- tp->irq = msix_ent0.vector;
+ for (i = 0; i < nvecs; i++) {
+ struct r8168_irq *irq = &tp->irq_tbli;
+ irq->vector = msix_enti.vector;
+ //snprintf(irq->name, len, "%s-%d", dev->name, i);
+ //irq->handler = rtl8168_interrupt_msix;
+ }
+
out:
return nvecs;
}
/* Cfg9346_Unlock assumed. */
-static unsigned rtl8168_try_msi(struct pci_dev *pdev, struct rtl8168_private *tp)
+static int rtl8168_try_msi(struct rtl8168_private *tp)
{
+ struct pci_dev *pdev = tp->pci_dev;
+ unsigned int hw_supp_irq_nvecs;
unsigned msi = 0;
+ int nvecs = 1;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
+ switch (tp->mcfg) {
+ case CFG_METHOD_4 ... CFG_METHOD_8:
+ hw_supp_irq_nvecs = 2;
+ break;
+ case CFG_METHOD_9 ... CFG_METHOD_37:
+ hw_supp_irq_nvecs = 4;
+ break;
+ default:
+ hw_supp_irq_nvecs = 1;
+ break;
+ }
+ tp->hw_supp_irq_nvecs = clamp_val(hw_supp_irq_nvecs, 1,
+ R8168_MAX_MSIX_VEC);
+
+ tp->max_irq_nvecs = 1;
+ tp->min_irq_nvecs = 1;
+
+#ifdef ENABLE_RSS_SUPPORT
+ if (!pci_enable_msi(pdev))
+ msi |= RTL_FEATURE_MSI;
+ else
+ dev_info(&pdev->dev, "Default use INTx.\n");
+#else
switch (tp->mcfg) {
case CFG_METHOD_1:
case CFG_METHOD_2:
dev_info(&pdev->dev, "Default use INTx.\n");
break;
default:
- if (rtl8168_enable_msix(tp) > 0)
+#if defined(RTL_USE_NEW_INTR_API)
+ if ((nvecs = pci_alloc_irq_vectors(pdev, tp->min_irq_nvecs, tp->max_irq_nvecs, PCI_IRQ_MSIX)) > 0)
+ msi |= RTL_FEATURE_MSIX;
+ else if ((nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES)) > 0 &&
+ pci_dev_msi_enabled(pdev))
+ msi |= RTL_FEATURE_MSI;
+#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
+ if ((nvecs = rtl8168_enable_msix(tp)) > 0)
msi |= RTL_FEATURE_MSIX;
else if (!pci_enable_msi(pdev))
msi |= RTL_FEATURE_MSI;
- else
- dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
+#endif
break;
}
-#endif
+#endif //ENABLE_RSS_SUPPORT
+ if (!(msi & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)))
+ dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
- if (msi & RTL_FEATURE_MSIX)
- goto out;
+ if (!(msi & RTL_FEATURE_MSIX) || nvecs < 1)
+ nvecs = 1;
- tp->irq = pdev->irq;
+ tp->irq_nvecs = nvecs;
-out:
- return msi;
+ tp->features |= msi;
+
+ return nvecs;
}
static void rtl8168_disable_msi(struct pci_dev *pdev, struct rtl8168_private *tp)
{
- if (tp->features & RTL_FEATURE_MSIX) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
+ if (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))
+ pci_free_irq_vectors(pdev);
+#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
+ if (tp->features & (RTL_FEATURE_MSIX))
pci_disable_msix(pdev);
+ else if (tp->features & (RTL_FEATURE_MSI))
+ pci_disable_msi(pdev);
#endif
- tp->features &= ~RTL_FEATURE_MSIX;
- }
+ tp->features &= ~(RTL_FEATURE_MSI | RTL_FEATURE_MSIX);
+}
- if (tp->features & RTL_FEATURE_MSI) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)
- pci_disable_msi(pdev);
+static int rtl8168_get_irq(struct pci_dev *pdev)
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
+ return pci_irq_vector(pdev, 0);
+#else
+ return pdev->irq;
#endif
- tp->features &= ~RTL_FEATURE_MSI;
- }
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
};
#endif
+#ifdef CONFIG_R8168_NAPI
+
+void rtl8168_enable_napi(struct rtl8168_private *tp)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ int i;
+
+ for (i = 0; i < tp->irq_nvecs; i++)
+ RTL_NAPI_ENABLE(tp->dev, &tp->r8168napii.napi);
+#endif
+}
+
+static void rtl8168_disable_napi(struct rtl8168_private *tp)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ int i;
+
+ for (i = 0; i < tp->irq_nvecs; i++)
+ RTL_NAPI_DISABLE(tp->dev, &tp->r8168napii.napi);
+#endif
+}
+
+static void rtl8168_del_napi(struct rtl8168_private *tp)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ int i;
+
+ for (i = 0; i < tp->irq_nvecs; i++)
+ RTL_NAPI_DEL((&tp->r8168napii));
+#endif
+}
+#endif //CONFIG_R8168_NAPI
+
+static void rtl8168_init_napi(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i=0; i<tp->irq_nvecs; i++) {
+ struct r8168_napi *r8168napi = &tp->r8168napii;
+#ifdef CONFIG_R8168_NAPI
+ int (*poll)(struct napi_struct *, int);
+
+ if (tp->features & RTL_FEATURE_MSIX) {
+ if (i == 0)
+ poll = rtl8168_poll_msix_ring;
+ else
+ poll = rtl8168_poll_msix_rx;
+ } else {
+ poll = rtl8168_poll;
+ }
+
+ RTL_NAPI_CONFIG(tp->dev, r8168napi, poll, R8168_NAPI_WEIGHT);
+#endif
+
+ r8168napi->priv = tp;
+ r8168napi->index = i;
+ }
+}
+
+static int
+rtl8168_set_real_num_queue(struct rtl8168_private *tp)
+{
+ int retval = 0;
+
+ retval = netif_set_real_num_tx_queues(tp->dev, tp->num_tx_rings);
+ if (retval < 0)
+ goto exit;
+
+ retval = netif_set_real_num_rx_queues(tp->dev, tp->num_rx_rings);
+ if (retval < 0)
+ goto exit;
+
+exit:
+ return retval;
+}
+
static int __devinit
rtl8168_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
tp->phy_reset_pending = rtl8168_xmii_reset_pending;
tp->link_ok = rtl8168_xmii_link_ok;
- tp->features |= rtl8168_try_msi(pdev, tp);
+ rc = rtl8168_try_msi(tp);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Can't allocate interrupt\n");
+ goto err_out_1;
+ }
+
+ rtl8168_init_software_variable(dev);
RTL_NET_DEVICE_OPS(rtl8168_netdev_ops);
#endif
dev->watchdog_timeo = RTL8168_TX_TIMEOUT;
- dev->irq = tp->irq;
+ dev->irq = rtl8168_get_irq(pdev);
dev->base_addr = (unsigned long) ioaddr;
-#ifdef CONFIG_R8168_NAPI
- RTL_NAPI_CONFIG(dev, tp, rtl8168_poll, R8168_NAPI_WEIGHT);
-#endif
+ rtl8168_init_napi(tp);
#ifdef CONFIG_R8168_VLAN
if (tp->mcfg != CFG_METHOD_DEFAULT) {
- dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ dev->features |= NETIF_F_HW_VLAN_TX;
+#ifndef ENABLE_LIB_SUPPORT
+ dev->features |= NETIF_F_HW_VLAN_RX;
+#endif //!ENABLE_LIB_SUPPORT
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
dev->vlan_rx_kill_vid = rtl8168_vlan_rx_kill_vid;
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_HIGHDMA;
if ((tp->mcfg != CFG_METHOD_16) && (tp->mcfg != CFG_METHOD_17)) {
- //dev->features |= NETIF_F_TSO;
dev->hw_features |= NETIF_F_TSO;
dev->vlan_features |= NETIF_F_TSO;
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_26:
+ /* nothing to do */
+ break;
+ default:
+ dev->features |= NETIF_F_SG | NETIF_F_TSO;
+ break;
+ };
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
dev->features |= NETIF_F_IPV6_CSUM;
if ((tp->mcfg != CFG_METHOD_16) && (tp->mcfg != CFG_METHOD_17)) {
dev->hw_features |= NETIF_F_TSO6;
- //dev->features |= NETIF_F_TSO6;
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_26:
+ /* nothing to do */
+ break;
+ default:
+ dev->features |= NETIF_F_TSO6;
+ break;
+ };
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0)
netif_set_tso_max_size(dev, LSO_64K);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
}
- spin_lock_init(&tp->lock);
-
- rtl8168_init_software_variable(dev);
+#ifdef ENABLE_RSS_SUPPORT
+ if (tp->EnableRss) {
+ dev->hw_features |= NETIF_F_RXHASH;
+ dev->features |= NETIF_F_RXHASH;
+ }
+#endif
#ifdef ENABLE_DASH_SUPPORT
if (tp->DASH)
AllocateDashShareMemory(dev);
#endif
+#ifdef ENABLE_LIB_SUPPORT
+ BLOCKING_INIT_NOTIFIER_HEAD(&tp->lib_nh);
+#endif
+ rtl8168_init_all_schedule_work(tp);
+
+ rc = rtl8168_set_real_num_queue(tp);
+ if (rc < 0)
+ goto err_out;
+
rtl8168_exit_oob(dev);
rtl8168_hw_init(dev);
/* Get production from EEPROM */
if (((tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
tp->mcfg == CFG_METHOD_25 || tp->mcfg == CFG_METHOD_29 ||
- tp->mcfg == CFG_METHOD_30 || tp->mcfg == CFG_METHOD_35) &&
+ tp->mcfg == CFG_METHOD_30 || tp->mcfg == CFG_METHOD_35 ||
+ tp->mcfg == CFG_METHOD_36 || tp->mcfg == CFG_METHOD_37) &&
(rtl8168_mac_ocp_read(tp, 0xDC00) & BIT_3)) ||
((tp->mcfg == CFG_METHOD_26) && (rtl8168_mac_ocp_read(tp, 0xDC00) & BIT_4)))
tp->eeprom_type = EEPROM_TYPE_NONE;
tp->tally_vaddr = NULL;
}
#ifdef CONFIG_R8168_NAPI
- RTL_NAPI_DEL(tp);
+ rtl8168_del_napi(tp);
#endif
rtl8168_disable_msi(pdev, tp);
+
+err_out_1:
rtl8168_release_board(pdev, dev);
goto out;
assert(dev != NULL);
assert(tp != NULL);
+ set_bit(R8168_FLAG_DOWN, tp->task_flags);
+
+ rtl8168_cancel_all_schedule_work(tp);
+
#ifdef CONFIG_R8168_NAPI
- RTL_NAPI_DEL(tp);
+ rtl8168_del_napi(tp);
#endif
if (HW_DASH_SUPPORT_DASH(tp))
rtl8168_driver_stop(tp);
pci_set_drvdata(pdev, NULL);
}
+static void rtl8168_free_irq(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i=0; i<tp->irq_nvecs; i++) {
+ struct r8168_irq *irq = &tp->irq_tbli;
+ struct r8168_napi *r8168napi = &tp->r8168napii;
+
+ if (irq->requested) {
+ irq->requested = 0;
+#if defined(RTL_USE_NEW_INTR_API)
+ pci_free_irq(tp->pci_dev, i, r8168napi);
+#else
+ free_irq(irq->vector, r8168napi);
+#endif
+ }
+ }
+}
+
+static int rtl8168_alloc_irq(struct rtl8168_private *tp)
+{
+ struct net_device *dev = tp->dev;
+ int rc = 0;
+ struct r8168_irq *irq;
+ struct r8168_napi *r8168napi;
+ int i = 0;
+ const int len = sizeof(tp->irq_tbl0.name);
+
+#if defined(RTL_USE_NEW_INTR_API)
+ for (i=0; i<tp->irq_nvecs; i++) {
+ irq = &tp->irq_tbli;
+ if (tp->features & RTL_FEATURE_MSIX)
+ irq->handler = rtl8168_interrupt_msix;
+ else
+ irq->handler = rtl8168_interrupt;
+
+ r8168napi = &tp->r8168napii;
+ snprintf(irq->name, len, "%s-%d", dev->name, i);
+ rc = pci_request_irq(tp->pci_dev, i, irq->handler, NULL, r8168napi,
+ irq->name);
+ if (rc)
+ break;
+
+ irq->vector = pci_irq_vector(tp->pci_dev, i);
+ irq->requested = 1;
+ }
+#else
+ unsigned long irq_flags = 0;
+#ifdef ENABLE_LIB_SUPPORT
+ if (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))
+ irq_flags |= IRQF_NO_SUSPEND;
+#endif //ENABLE_LIB_SUPPORT
+ if (tp->features & RTL_FEATURE_MSIX) {
+ for (i=0; i<tp->irq_nvecs; i++) {
+ irq = &tp->irq_tbli;
+ irq->handler = rtl8168_interrupt_msix;
+ r8168napi = &tp->r8168napii;
+ snprintf(irq->name, len, "%s-%d", dev->name, i);
+ rc = request_irq(irq->vector, irq->handler, irq_flags, irq->name, r8168napi);
+
+ if (rc)
+ break;
+
+ irq->requested = 1;
+ }
+ } else {
+ irq = &tp->irq_tbl0;
+ irq->handler = rtl8168_interrupt;
+ r8168napi = &tp->r8168napi0;
+ snprintf(irq->name, len, "%s-0", dev->name);
+ irq->vector = dev->irq;
+ irq_flags |= (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)) ? 0 : SA_SHIRQ;
+ rc = request_irq(irq->vector, irq->handler, irq_flags, irq->name, r8168napi);
+
+ if (rc == 0)
+ irq->requested = 1;
+ }
+#endif
+ if (rc)
+ rtl8168_free_irq(tp);
+
+ return rc;
+}
+
static void
rtl8168_set_rxbufsize(struct rtl8168_private *tp,
struct net_device *dev)
{
unsigned int mtu = dev->mtu;
- tp->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 + 1 : RX_BUF_SIZE;
+ tp->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
+
+ switch (tp->mcfg) {
+ case CFG_METHOD_1 ... CFG_METHOD_26:
+ tp->rx_buf_sz += 1;
+ break;
+ default:
+ break;
+ }
+}
+
+static int rtl8168_alloc_tx_desc(struct rtl8168_private *tp)
+{
+ struct pci_dev *pdev = tp->pci_dev;
+ struct rtl8168_tx_ring *ring;
+ int i;
+
+ for (i = 0; i < tp->num_tx_rings; i++) {
+ ring = &tp->tx_ringi;
+ ring->TxDescAllocSize = (ring->num_tx_desc + 1) * sizeof(struct TxDesc);
+ ring->TxDescArray = dma_alloc_coherent(&pdev->dev,
+ ring->TxDescAllocSize,
+ &ring->TxPhyAddr,
+ GFP_KERNEL);
+
+ if (!ring->TxDescArray)
+ return -1;
+ }
+
+ return 0;
+}
+
+static int rtl8168_alloc_rx_desc(struct rtl8168_private *tp)
+{
+ struct pci_dev *pdev = tp->pci_dev;
+
+ if (tp->InitRxDescType == RX_DESC_RING_TYPE_2)
+ tp->RxDescAllocSize = ((tp->num_rx_desc + 1) * tp->num_hw_tot_en_rx_rings)
+ * tp->RxDescLength;
+ else
+ tp->RxDescAllocSize = (tp->num_rx_desc + 1) * tp->RxDescLength;
+
+ tp->RxDescArray = dma_alloc_coherent(&pdev->dev, tp->RxDescAllocSize,
+ &tp->RxPhyAddr, GFP_KERNEL);
+ if (!tp->RxDescArray)
+ return -1;
+
+ return 0;
+}
+
+static void rtl8168_free_tx_desc(struct rtl8168_private *tp)
+{
+ struct rtl8168_tx_ring *ring;
+ struct pci_dev *pdev = tp->pci_dev;
+ int i;
+
+ for (i = 0; i < tp->num_tx_rings; i++) {
+ ring = &tp->tx_ringi;
+ if (ring->TxDescArray) {
+ dma_free_coherent(&pdev->dev,
+ ring->TxDescAllocSize,
+ ring->TxDescArray,
+ ring->TxPhyAddr);
+ ring->TxDescArray = NULL;
+ }
+ }
+}
+
+static void rtl8168_free_rx_desc(struct rtl8168_private *tp)
+{
+ struct pci_dev *pdev = tp->pci_dev;
+
+ if (tp->RxDescArray) {
+ dma_free_coherent(&pdev->dev, tp->RxDescAllocSize, tp->RxDescArray,
+ tp->RxPhyAddr);
+ tp->RxDescArray = NULL;
+ }
+}
+
+static void rtl8168_free_alloc_resources(struct rtl8168_private *tp)
+{
+ rtl8168_free_rx_desc(tp);
+
+ rtl8168_free_tx_desc(tp);
}
#ifdef ENABLE_USE_FIRMWARE_FILE
}
#endif
-static int rtl8168_open(struct net_device *dev)
+int rtl8168_open(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
- unsigned long flags;
int retval;
retval = -ENOMEM;
* Rx and Tx descriptors needs 256 bytes alignment.
* pci_alloc_consistent provides more.
*/
- tp->TxDescAllocSize = (tp->num_tx_desc + 1) * sizeof(struct TxDesc);
- tp->TxDescArray = dma_alloc_coherent(&pdev->dev,
- tp->TxDescAllocSize,
- &tp->TxPhyAddr, GFP_KERNEL);
- if (!tp->TxDescArray)
- goto err_free_all_allocated_mem;
-
- tp->RxDescAllocSize = (tp->num_rx_desc + 1) * sizeof(struct RxDesc);
- tp->RxDescArray = dma_alloc_coherent(&pdev->dev,
- tp->RxDescAllocSize,
- &tp->RxPhyAddr, GFP_KERNEL);
- if (!tp->RxDescArray)
+ if (rtl8168_alloc_tx_desc(tp) < 0 || rtl8168_alloc_rx_desc(tp) < 0)
goto err_free_all_allocated_mem;
retval = rtl8168_init_ring(dev);
if (retval < 0)
goto err_free_all_allocated_mem;
- retval = request_irq(tp->irq, rtl8168_interrupt, (tp->features &
- (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)) ? 0 :
- SA_SHIRQ, dev->name, dev);
+ retval = rtl8168_alloc_irq(tp);
if (retval<0)
goto err_free_all_allocated_mem;
dev->base_addr,
dev->dev_addr0, dev->dev_addr1,
dev->dev_addr2, dev->dev_addr3,
- dev->dev_addr4, dev->dev_addr5, tp->irq);
+ dev->dev_addr4, dev->dev_addr5, dev->irq);
}
#ifdef ENABLE_USE_FIRMWARE_FILE
rtl8168_request_firmware(tp);
#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- INIT_WORK(&tp->task, rtl8168_reset_task, dev);
-#else
- INIT_DELAYED_WORK(&tp->task, rtl8168_reset_task);
-#endif
-
+ /*
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ INIT_WORK(&tp->task, rtl8168_reset_task, dev);
+ #else
+ INIT_DELAYED_WORK(&tp->task, rtl8168_reset_task);
+ #endif
+ */
pci_set_master(pdev);
#ifdef CONFIG_R8168_NAPI
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- RTL_NAPI_ENABLE(dev, &tp->napi);
+ rtl8168_enable_napi(tp);
#endif
-#endif
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_exit_oob(dev);
rtl8168_hw_init(dev);
rtl8168_dsm(dev, DSM_IF_UP);
- rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising);
+ clear_bit(R8168_FLAG_DOWN, tp->task_flags);
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising);
- if (tp->esd_flag == 0)
- rtl8168_request_esd_timer(dev);
+ if (tp->esd_flag == 0) {
+ //rtl8168_request_esd_timer(dev);
+ rtl8168_schedule_esd_work(tp);
+ }
- rtl8168_request_link_timer(dev);
+ //rtl8168_request_link_timer(dev);
+ rtl8168_schedule_linkchg_work(tp);
out:
return retval;
err_free_all_allocated_mem:
- if (tp->RxDescArray != NULL) {
- dma_free_coherent(&pdev->dev,
- tp->RxDescAllocSize,
- tp->RxDescArray,
- tp->RxPhyAddr);
- tp->RxDescArray = NULL;
- }
-
- if (tp->TxDescArray != NULL) {
- dma_free_coherent(&pdev->dev,
- tp->TxDescAllocSize,
- tp->TxDescArray,
- tp->TxPhyAddr);
- tp->TxDescArray = NULL;
- }
+ rtl8168_free_alloc_resources(tp);
goto out;
}
break;
}
-
}
static void
mc_filter1 = swab32(tmp);
tp->rtl8168_rx_config = rtl_chip_infotp->chipset.RCR_Cfg;
+ switch (tp->mcfg) {
+ case CFG_METHOD_21 ... CFG_METHOD_35:
+ if (tp->EnableRss)
+ tp->rtl8168_rx_config &= ~Rx_Single_fetch_V2;
+ else
+ tp->rtl8168_rx_config |= Rx_Single_fetch_V2;
+ break;
+ default:
+ break;
+ }
+ if (tp->InitRxDescType == RX_DESC_RING_TYPE_2)
+ tp->rtl8168_rx_config |= RxCfg_rx_desc_v2_en;
tmp = tp->rtl8168_rx_config | rx_mode | (RTL_R32(tp, RxConfig) & rtl_chip_infotp->chipset.RxConfigMask);
RTL_W32(tp, RxConfig, tmp);
static void
rtl8168_set_rx_mode(struct net_device *dev)
{
- struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_hw_set_rx_packet_filter(dev);
-
- spin_unlock_irqrestore(&tp->lock, flags);
}
-static void
+void
rtl8168_hw_config(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
dev->features |= NETIF_F_IP_CSUM;
}
#endif
-
- RTL_W32(tp, RxConfig, (RX_DMA_BURST << RxCfgDMAShift));
+ rtl8168_disable_rx_packet_filter(tp);
rtl8168_hw_reset(dev);
rtl8168_hw_aspm_clkreq_enable(tp, false);
}
+ rtl8168_set_eee_lpi_timer(tp);
+
//clear io_rdy_l23
switch (tp->mcfg) {
case CFG_METHOD_20:
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~BIT_1);
break;
}
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
csi_tmp = rtl8168_eri_read(tp, 0xDE, 1, ERIAR_ExGMAC);
csi_tmp &= BIT_0;
rtl8168_eri_write(tp, 0xDE, 1, csi_tmp, ERIAR_ExGMAC);
} else if (tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22 ||
tp->mcfg == CFG_METHOD_24 || tp->mcfg == CFG_METHOD_25 ||
tp->mcfg == CFG_METHOD_26 || tp->mcfg == CFG_METHOD_29 ||
- tp->mcfg == CFG_METHOD_30 || tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_30 || tp->mcfg == CFG_METHOD_35 ||
+ tp->mcfg == CFG_METHOD_36 || tp->mcfg == CFG_METHOD_37) {
set_offset70F(tp, 0x27);
set_offset79(tp, 0x50);
if (tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22)
set_offset711(tp, 0x04);
rtl8168_eri_write(tp, 0xC8, 4, 0x00080002, ERIAR_ExGMAC);
+#ifdef ENABLE_LIB_SUPPORT
+ rtl8168_eri_write(tp, 0xCC, 1, 0x60, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, 0xD0, 1, 0x70, ERIAR_ExGMAC);
+#else
rtl8168_eri_write(tp, 0xCC, 1, 0x38, ERIAR_ExGMAC);
rtl8168_eri_write(tp, 0xD0, 1, 0x48, ERIAR_ExGMAC);
+#endif //ENABLE_LIB_SUPPORT
rtl8168_eri_write(tp, 0xE8, 4, 0x00100006, ERIAR_ExGMAC);
RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | BIT_7);
csi_tmp |= BIT_0;
rtl8168_eri_write(tp, 0xDC, 1, csi_tmp, ERIAR_ExGMAC);
- if (tp->mcfg == CFG_METHOD_35)
+ if (tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36)
rtl8168_set_mcu_ocp_bit(tp, 0xD438, (BIT_1 | BIT_0));
if (tp->mcfg == CFG_METHOD_26) {
mac_ocp_data |= BIT_0;
rtl8168_mac_ocp_write(tp, 0xD3C4, mac_ocp_data);
} else if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
if (tp->RequireAdjustUpsTxLinkPulseTiming) {
mac_ocp_data = rtl8168_mac_ocp_read(tp, 0xD412);
RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) | BIT_7);
- rtl8168_eri_write(tp, 0xC0, 2, 0x0000, ERIAR_ExGMAC);
- rtl8168_eri_write(tp, 0xB8, 4, 0x00000000, ERIAR_ExGMAC);
+ rtl8168_eri_write(tp, RSS_CTRL_8168, 4, 0x00000000, ERIAR_ExGMAC);
if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
rtl8168_mac_ocp_write(tp, 0xE054, 0x0000);
rtl8168_eri_write(tp, 0x5F0, 2, 0x4000, ERIAR_ExGMAC);
}
if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
csi_tmp = rtl8168_eri_read(tp, 0xDC, 4, ERIAR_ExGMAC);
csi_tmp |= (BIT_2 | BIT_3 | BIT_4);
rtl8168_eri_write(tp, 0xDC, 4, csi_tmp, ERIAR_ExGMAC);
tp->mcfg == CFG_METHOD_24 || tp->mcfg == CFG_METHOD_25) {
rtl8168_mac_ocp_write(tp, 0xC140, 0xFFFF);
} else if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
rtl8168_mac_ocp_write(tp, 0xC140, 0xFFFF);
rtl8168_mac_ocp_write(tp, 0xC142, 0xFFFF);
}
rtl8168_eri_write(tp, 0x1B0, 4, csi_tmp, ERIAR_ExGMAC);
if (tp->mcfg == CFG_METHOD_29 || tp->mcfg == CFG_METHOD_30 ||
- tp->mcfg == CFG_METHOD_35) {
+ tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36 ||
+ tp->mcfg == CFG_METHOD_37) {
csi_tmp = rtl8168_eri_read(tp, 0x2FC, 1, ERIAR_ExGMAC);
csi_tmp &= ~(BIT_2);
rtl8168_eri_write(tp, 0x2FC, 1, csi_tmp, ERIAR_ExGMAC);
rtl8168_eri_write(tp, 0x2FC, 1, csi_tmp, ERIAR_ExGMAC);
}
- csi_tmp = rtl8168_eri_read(tp, 0x1D0, 1, ERIAR_ExGMAC);
- csi_tmp |= BIT_1;
- rtl8168_eri_write(tp, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC);
+ if (tp->mcfg != CFG_METHOD_37) {
+ csi_tmp = rtl8168_eri_read(tp, 0x1D0, 1, ERIAR_ExGMAC);
+ csi_tmp |= BIT_1;
+ rtl8168_eri_write(tp, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC);
+ }
} else if (tp->mcfg == CFG_METHOD_23 || tp->mcfg == CFG_METHOD_27 ||
tp->mcfg == CFG_METHOD_28) {
set_offset70F(tp, 0x27);
rtl8168_eri_write(tp, 0x5F0, 2, 0x4000, ERIAR_ExGMAC);
rtl8168_oob_mutex_unlock(tp);
+ csi_tmp = rtl8168_eri_read(tp, 0xDC, 4, ERIAR_ExGMAC);
+ csi_tmp |= (BIT_2 | BIT_3);
+ rtl8168_eri_write(tp, 0xDC, 4, csi_tmp, ERIAR_ExGMAC);
+
if (tp->mcfg == CFG_METHOD_32 || tp->mcfg == CFG_METHOD_33 ||
tp->mcfg == CFG_METHOD_34) {
csi_tmp = rtl8168_eri_read(tp, 0xD4, 4, ERIAR_ExGMAC);
}
}
+ rtl8168_set_rx_q_num(tp, tp->num_hw_tot_en_rx_rings);
+
+ rtl8168_set_rx_vlan_filter(tp);
+#ifdef ENABLE_RSS_SUPPORT
+#ifdef ENABLE_LIB_SUPPORT
+ /* if lib queue not exist, default use rx queue 0 */
+ if (rtl8168_num_lib_rx_rings(tp) == 0)
+ memset(tp->rss_indir_tbl, 0x0, sizeof(tp->rss_indir_tbl));
+#endif //ENABLE_LIB_SUPPORT
+ rtl8168_config_rss(tp);
+#endif //ENABLE_RSS_SUPPORT
rtl8168_hw_clear_timer_int(dev);
rtl8168_enable_exit_l1_mask(tp);
case CFG_METHOD_29:
case CFG_METHOD_30:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_mac_ocp_write(tp, 0xE098, 0x0AA2);
break;
case CFG_METHOD_31:
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_disable_pci_offset_99(tp);
if (aspm) {
if (tp->org_pci_offset_99 & (BIT_2 | BIT_5 | BIT_6))
case CFG_METHOD_33:
case CFG_METHOD_34:
case CFG_METHOD_35:
+ case CFG_METHOD_36:
+ case CFG_METHOD_37:
rtl8168_disable_pci_offset_180(tp);
if (aspm) {
if (tp->org_pci_offset_180 & (BIT_0|BIT_1))
case CFG_METHOD_20:
case CFG_METHOD_21:
case CFG_METHOD_22:
- case CFG_METHOD_23:
case CFG_METHOD_24:
case CFG_METHOD_25:
- case CFG_METHOD_26:
- case CFG_METHOD_27:
- case CFG_METHOD_28:
- case CFG_METHOD_29:
- case CFG_METHOD_30:
- case CFG_METHOD_31:
- case CFG_METHOD_32:
- case CFG_METHOD_33:
- case CFG_METHOD_34:
- case CFG_METHOD_35: {
+ case CFG_METHOD_26: {
int timeout;
for (timeout = 0; timeout < 10; timeout++) {
if ((rtl8168_eri_read(tp, 0x1AE, 2, ERIAR_ExGMAC) & BIT_13)==0)
udelay(10);
}
-static void
+void
rtl8168_hw_start(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
+#ifdef ENABLE_LIB_SUPPORT
+ rtl8168_init_lib_ring(tp);
+#endif
+
RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb);
- rtl8168_enable_hw_interrupt(tp);
+ rtl8168_enable_interrupt(tp);
+
+ rtl8168_lib_reset_complete(tp);
}
static int
{
struct rtl8168_private *tp = netdev_priv(dev);
int ret = 0;
- unsigned long flags;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
if (new_mtu < ETH_MIN_MTU)
new_mtu = tp->max_jumbo_frame_size;
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)
- spin_lock_irqsave(&tp->lock, flags);
dev->mtu = new_mtu;
- spin_unlock_irqrestore(&tp->lock, flags);
+
+ tp->eee.tx_lpi_timer = dev->mtu + ETH_HLEN + 0x20;
if (!netif_running(dev))
goto out;
rtl8168_down(dev);
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_set_rxbufsize(tp, dev);
ret = rtl8168_init_ring(dev);
- if (ret < 0) {
- spin_unlock_irqrestore(&tp->lock, flags);
+ if (ret < 0)
goto err_out;
- }
#ifdef CONFIG_R8168_NAPI
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- RTL_NAPI_ENABLE(dev, &tp->napi);
-#endif
+ rtl8168_enable_napi(tp);
#endif//CONFIG_R8168_NAPI
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- rtl8168_hw_config(dev);
-
- rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising);
-
- spin_unlock_irqrestore(&tp->lock, flags);
+ if (tp->link_ok(dev))
+ rtl8168_link_on_patch(dev);
+ else
+ rtl8168_link_down_patch(dev);
- mod_timer(&tp->esd_timer, jiffies + RTL8168_ESD_TIMEOUT);
- mod_timer(&tp->link_timer, jiffies + RTL8168_LINK_TIMEOUT);
+ //mod_timer(&tp->esd_timer, jiffies + RTL8168_ESD_TIMEOUT);
+ //mod_timer(&tp->link_timer, jiffies + RTL8168_LINK_TIMEOUT);
out:
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
netdev_update_features(dev);
static void
rtl8168_free_rx_skb(struct rtl8168_private *tp,
+ struct rtl8168_rx_ring *ring,
struct sk_buff **sk_buff,
- struct RxDesc *desc)
+ struct RxDesc *desc,
+ const u32 cur_rx)
{
struct pci_dev *pdev = tp->pci_dev;
- dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
+ dma_unmap_single(&pdev->dev, ring->RxDescPhyAddrcur_rx, tp->rx_buf_sz,
DMA_FROM_DEVICE);
dev_kfree_skb(*sk_buff);
*sk_buff = NULL;
rtl8168_make_unusable_by_asic(desc);
}
-static inline void
+void
rtl8168_mark_to_asic(struct RxDesc *desc,
u32 rx_buf_sz)
{
u32 eor = le32_to_cpu(desc->opts1) & RingEnd;
- desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz);
+ WRITE_ONCE(desc->opts1, cpu_to_le32(DescOwn | eor | rx_buf_sz));
}
static inline void
rtl8168_map_to_asic(struct RxDesc *desc,
+ struct rtl8168_rx_ring *ring,
dma_addr_t mapping,
- u32 rx_buf_sz)
+ u32 rx_buf_sz,
+ const u32 cur_rx)
{
+ ring->RxDescPhyAddrcur_rx = mapping;
desc->addr = cpu_to_le64(mapping);
wmb();
rtl8168_mark_to_asic(desc, rx_buf_sz);
static int
rtl8168_alloc_rx_skb(struct rtl8168_private *tp,
+ struct rtl8168_rx_ring *ring,
struct sk_buff **sk_buff,
struct RxDesc *desc,
int rx_buf_sz,
+ const u32 cur_rx,
u8 in_intr)
{
struct sk_buff *skb;
int ret = 0;
if (in_intr)
- skb = RTL_ALLOC_SKB_INTR(tp, rx_buf_sz + RTK_RX_ALIGN);
+ skb = RTL_ALLOC_SKB_INTR(&tp->r8168napiring->index.napi,
+ rx_buf_sz + RTK_RX_ALIGN);
else
skb = dev_alloc_skb(rx_buf_sz + RTK_RX_ALIGN);
if (unlikely(!skb))
goto err_out;
- skb_reserve(skb, RTK_RX_ALIGN);
+ if (!in_intr || !R8168_USE_NAPI_ALLOC_SKB)
+ skb_reserve(skb, RTK_RX_ALIGN);
mapping = dma_map_single(tp_to_dev(tp), skb->data, rx_buf_sz,
DMA_FROM_DEVICE);
}
*sk_buff = skb;
- rtl8168_map_to_asic(desc, mapping, rx_buf_sz);
+ rtl8168_map_to_asic(desc, ring, mapping, rx_buf_sz, cur_rx);
out:
return ret;
}
static void
-rtl8168_rx_clear(struct rtl8168_private *tp)
+_rtl8168_rx_clear(struct rtl8168_private *tp, struct rtl8168_rx_ring *ring)
{
int i;
for (i = 0; i < tp->num_rx_desc; i++) {
- if (tp->Rx_skbuffi)
- rtl8168_free_rx_skb(tp, tp->Rx_skbuff + i,
- tp->RxDescArray + i);
+ if (ring->Rx_skbuffi) {
+ rtl8168_free_rx_skb(tp,
+ ring,
+ ring->Rx_skbuff + i,
+ rtl8168_get_rxdesc(tp,
+ tp->RxDescArray,
+ i,
+ ring->index),
+ i);
+ ring->Rx_skbuffi = NULL;
+ }
}
}
+void
+rtl8168_rx_clear(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i = 0; i < tp->num_rx_rings; i++)
+ _rtl8168_rx_clear(tp, &tp->rx_ringi);
+}
+
static u32
rtl8168_rx_fill(struct rtl8168_private *tp,
+ struct rtl8168_rx_ring *ring,
struct net_device *dev,
u32 start,
u32 end,
for (cur = start; end - cur > 0; cur++) {
int ret, i = cur % tp->num_rx_desc;
- if (tp->Rx_skbuffi)
+ if (ring->Rx_skbuffi)
continue;
- ret = rtl8168_alloc_rx_skb(tp, tp->Rx_skbuff + i,
- tp->RxDescArray + i,
+ ret = rtl8168_alloc_rx_skb(tp,
+ ring,
+ ring->Rx_skbuff + i,
+ rtl8168_get_rxdesc(tp,
+ tp->RxDescArray,
+ i, ring->index),
tp->rx_buf_sz,
+ i,
in_intr);
if (ret < 0)
break;
static void
rtl8168_desc_addr_fill(struct rtl8168_private *tp)
{
- if (!tp->TxPhyAddr || !tp->RxPhyAddr)
- return;
+ int i;
+
+ for (i = 0; i < tp->num_tx_rings; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ RTL_W32(tp, ring->tdsar_reg, ((u64)ring->TxPhyAddr & DMA_BIT_MASK(32)));
+ RTL_W32(tp, ring->tdsar_reg + 4, ((u64)ring->TxPhyAddr >> 32));
+ }
+
+#ifdef ENABLE_LIB_SUPPORT
+ /*
+ * The lib tx q1 polling may be set after tx is disabled. If lib tx q1
+ * is released, after enable tx, device will try to access invalid tx q1
+ * desc base address. Set tx q1 desc base address to tx q0 desc base
+ * address to let device to access the valid address and clear tx q1
+ * polling bit after enable tx.
+ */
+ if (rtl8168_lib_tx_ring_released(tp)) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ring0;
+ u16 tdsar_reg = TxHDescStartAddrLow;
+ RTL_W32(tp, tdsar_reg, ((u64)ring->TxPhyAddr & DMA_BIT_MASK(32)));
+ RTL_W32(tp, tdsar_reg + 4, ((u64)ring->TxPhyAddr >> 32));
+ }
+#endif
- RTL_W32(tp, TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_BIT_MASK(32)));
- RTL_W32(tp, TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
RTL_W32(tp, RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_BIT_MASK(32)));
- RTL_W32(tp, RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
+ RTL_W32(tp, RxDescAddrLow + 4, ((u64) tp->RxPhyAddr >> 32));
}
static void
rtl8168_tx_desc_init(struct rtl8168_private *tp)
{
- int i = 0;
+ int i;
- memset(tp->TxDescArray, 0x0, tp->TxDescAllocSize);
+ for (i = 0; i < tp->num_tx_rings; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ memset(ring->TxDescArray, 0x0, ring->TxDescAllocSize);
- for (i = 0; i < tp->num_tx_desc; i++) {
- if (i == (tp->num_tx_desc - 1))
- tp->TxDescArrayi.opts1 = cpu_to_le32(RingEnd);
+ ring->TxDescArrayring->num_tx_desc - 1.opts1 = cpu_to_le32(RingEnd);
}
}
static void
rtl8168_rx_desc_offset0_init(struct rtl8168_private *tp, int own)
{
- int i = 0;
+ struct rtl8168_rx_ring *ring = &tp->rx_ring0;
+ struct RxDesc *desc;
int ownbit = 0;
+ int i;
if (tp->RxDescArray == NULL)
return;
ownbit = DescOwn;
for (i = 0; i < tp->num_rx_desc; i++) {
+ desc = rtl8168_get_rxdesc(tp, tp->RxDescArray, i,
+ ring->index);
if (i == (tp->num_rx_desc - 1))
- tp->RxDescArrayi.opts1 = cpu_to_le32((ownbit | RingEnd) | (unsigned long)tp->rx_buf_sz);
+ desc->opts1 = cpu_to_le32((ownbit | RingEnd) | (unsigned long)tp->rx_buf_sz);
else
- tp->RxDescArrayi.opts1 = cpu_to_le32(ownbit | (unsigned long)tp->rx_buf_sz);
+ desc->opts1 = cpu_to_le32(ownbit | (unsigned long)tp->rx_buf_sz);
}
}
static void
rtl8168_rx_desc_init(struct rtl8168_private *tp)
{
+ if (!tp->RxDescArray)
+ return;
+
+ if (rtl8168_num_lib_rx_rings(tp) > 0)
+ return;
+
memset(tp->RxDescArray, 0x0, tp->RxDescAllocSize);
}
-static int
+int
rtl8168_init_ring(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
+ int i;
rtl8168_init_ring_indexes(tp);
- memset(tp->tx_skb, 0x0, sizeof(tp->tx_skb));
- memset(tp->Rx_skbuff, 0x0, sizeof(tp->Rx_skbuff));
-
rtl8168_tx_desc_init(tp);
rtl8168_rx_desc_init(tp);
- if (rtl8168_rx_fill(tp, dev, 0, tp->num_rx_desc, 0) != tp->num_rx_desc)
- goto err_out;
+ for (i = 0; i < tp->num_tx_rings; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ memset(ring->tx_skb, 0x0, sizeof(ring->tx_skb));
+ }
+
+ for (i = 0; i < tp->num_rx_rings; i++) {
+ struct rtl8168_rx_ring *ring = &tp->rx_ringi;
+
+ memset(ring->Rx_skbuff, 0x0, sizeof(ring->Rx_skbuff));
+ if (rtl8168_rx_fill(tp, ring, dev, 0, tp->num_rx_desc, 0) != tp->num_rx_desc)
+ goto err_out;
+
+ rtl8168_mark_as_last_descriptor(rtl8168_get_rxdesc(tp,
+ tp->RxDescArray,
+ tp->num_rx_desc - 1,
+ ring->index));
+ }
- rtl8168_mark_as_last_descriptor(tp->RxDescArray + tp->num_rx_desc - 1);
return 0;
tx_skb->len = 0;
}
-static void rtl8168_tx_clear_range(struct rtl8168_private *tp, u32 start,
- unsigned int n)
+static void
+rtl8168_tx_clear_range(struct rtl8168_private *tp,
+ struct rtl8168_tx_ring *ring,
+ u32 start,
+ unsigned int n)
{
unsigned int i;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
#endif
for (i = 0; i < n; i++) {
- unsigned int entry = (start + i) % tp->num_tx_desc;
- struct ring_info *tx_skb = tp->tx_skb + entry;
+ unsigned int entry = (start + i) % ring->num_tx_desc;
+ struct ring_info *tx_skb = ring->tx_skb + entry;
unsigned int len = tx_skb->len;
if (len) {
struct sk_buff *skb = tx_skb->skb;
rtl8168_unmap_tx_skb(tp->pci_dev, tx_skb,
- tp->TxDescArray + entry);
+ ring->TxDescArray + entry);
if (skb) {
RTLDEV->stats.tx_dropped++;
dev_kfree_skb_any(skb);
}
}
-static void
+void
rtl8168_tx_clear(struct rtl8168_private *tp)
{
- rtl8168_tx_clear_range(tp, tp->dirty_tx, tp->num_tx_desc);
- tp->cur_tx = tp->dirty_tx = 0;
+ int i;
+
+ for (i = 0; i < tp->num_tx_rings; i++) {
+ struct rtl8168_tx_ring *ring = &tp->tx_ringi;
+ rtl8168_tx_clear_range(tp, ring, ring->dirty_tx, ring->num_tx_desc);
+ ring->cur_tx = ring->dirty_tx = 0;
+ }
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void rtl8168_schedule_work(struct net_device *dev, void (*task)(void *))
+static void rtl8168_schedule_reset_work(struct rtl8168_private *tp)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- struct rtl8168_private *tp = netdev_priv(dev);
+ set_bit(R8168_FLAG_TASK_RESET_PENDING, tp->task_flags);
+ schedule_delayed_work(&tp->reset_task, 4);
+#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+}
+
+static void rtl8168_schedule_esd_work(struct rtl8168_private *tp)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ set_bit(R8168_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags);
+ schedule_delayed_work(&tp->esd_task, RTL8168_ESD_TIMEOUT);
+#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+}
- INIT_WORK(&tp->task, task, dev);
- schedule_delayed_work(&tp->task, 4);
+static void rtl8168_schedule_linkchg_work(struct rtl8168_private *tp)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
+ set_bit(R8168_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags);
+ schedule_delayed_work(&tp->linkchg_task, RTL8168_LINK_TIMEOUT);
#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
}
-#define rtl8168_cancel_schedule_work(a)
+#define rtl8168_cancel_schedule_reset_work(a)
+#define rtl8168_cancel_schedule_esd_work(a)
+#define rtl8168_cancel_schedule_linkchg_work(a)
#else
-static void rtl8168_schedule_work(struct net_device *dev, work_func_t task)
+static void rtl8168_schedule_reset_work(struct rtl8168_private *tp)
{
- struct rtl8168_private *tp = netdev_priv(dev);
+ set_bit(R8168_FLAG_TASK_RESET_PENDING, tp->task_flags);
+ schedule_delayed_work(&tp->reset_task, 4);
+}
+
+static void rtl8168_cancel_schedule_reset_work(struct rtl8168_private *tp)
+{
+ struct work_struct *work = &tp->reset_task.work;
- INIT_DELAYED_WORK(&tp->task, task);
- schedule_delayed_work(&tp->task, 4);
+ if (!work->func) return;
+
+ cancel_delayed_work_sync(&tp->reset_task);
}
-static void rtl8168_cancel_schedule_work(struct net_device *dev)
+static void rtl8168_schedule_esd_work(struct rtl8168_private *tp)
{
- struct rtl8168_private *tp = netdev_priv(dev);
- struct work_struct *work = &tp->task.work;
+ set_bit(R8168_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags);
+ schedule_delayed_work(&tp->esd_task, RTL8168_ESD_TIMEOUT);
+}
- if (!work->func)
- return;
+static void rtl8168_cancel_schedule_esd_work(struct rtl8168_private *tp)
+{
+ struct work_struct *work = &tp->esd_task.work;
+
+ if (!work->func) return;
- cancel_delayed_work_sync(&tp->task);
+ cancel_delayed_work_sync(&tp->esd_task);
}
-#endif
-#if 0
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void rtl8168_reinit_task(void *_data)
-#else
-static void rtl8168_reinit_task(struct work_struct *work)
+static void rtl8168_schedule_linkchg_work(struct rtl8168_private *tp)
+{
+ set_bit(R8168_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags);
+ schedule_delayed_work(&tp->linkchg_task, RTL8168_LINK_TIMEOUT);
+}
+
+static void rtl8168_cancel_schedule_linkchg_work(struct rtl8168_private *tp)
+{
+ struct work_struct *work = &tp->linkchg_task.work;
+
+ if (!work->func) return;
+
+ cancel_delayed_work_sync(&tp->linkchg_task);
+}
#endif
+
+static void rtl8168_init_all_schedule_work(struct rtl8168_private *tp)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct net_device *dev = _data;
+ INIT_WORK(&tp->reset_task, rtl8168_reset_task, dev);
+ INIT_WORK(&tp->esd_task, rtl8168_esd_task, dev);
+ INIT_WORK(&tp->linkchg_task, rtl8168_linkchg_task, dev);
#else
- struct rtl8168_private *tp =
- container_of(work, struct rtl8168_private, task.work);
- struct net_device *dev = tp->dev;
+ INIT_DELAYED_WORK(&tp->reset_task, rtl8168_reset_task);
+ INIT_DELAYED_WORK(&tp->esd_task, rtl8168_esd_task);
+ INIT_DELAYED_WORK(&tp->linkchg_task, rtl8168_linkchg_task);
#endif
- int ret;
-
- if (netif_running(dev)) {
- rtl8168_wait_for_quiescence(dev);
- rtl8168_close(dev);
- }
+}
- ret = rtl8168_open(dev);
- if (unlikely(ret < 0)) {
- if (unlikely(net_ratelimit())) {
- struct rtl8168_private *tp = netdev_priv(dev);
+static void rtl8168_cancel_all_schedule_work(struct rtl8168_private *tp)
+{
+ rtl8168_cancel_schedule_reset_work(tp);
+ rtl8168_cancel_schedule_esd_work(tp);
+ rtl8168_cancel_schedule_linkchg_work(tp);
+}
- if (netif_msg_drv(tp)) {
- printk(PFX KERN_ERR
- "%s: reinit failure (status = %d)."
- " Rescheduling.\n", dev->name, ret);
- }
- }
- rtl8168_schedule_work(dev, rtl8168_reinit_task);
+static void
+rtl8168_wait_for_irq_complete(struct rtl8168_private *tp)
+{
+ if (tp->features & RTL_FEATURE_MSIX) {
+ int i;
+ for (i = 0; i < tp->irq_nvecs; i++)
+ synchronize_irq(tp->irq_tbli.vector);
+ } else {
+ synchronize_irq(tp->dev->irq);
}
}
+
+void
+_rtl8168_wait_for_quiescence(struct net_device *dev)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ /* Wait for any pending NAPI task to complete */
+#ifdef CONFIG_R8168_NAPI
+ rtl8168_disable_napi(tp);
+#endif//CONFIG_R8168_NAPI
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,67)
+ /* Give a racing hard_start_xmit a few cycles to complete. */
+ synchronize_net();
#endif
+ rtl8168_irq_mask_and_ack(tp);
+
+ rtl8168_wait_for_irq_complete(tp);
+}
+
+static void
+rtl8168_wait_for_quiescence(struct net_device *dev)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ //suppress unused variable
+ (void)(tp);
+
+ _rtl8168_wait_for_quiescence(dev);
+
+#ifdef CONFIG_R8168_NAPI
+ rtl8168_enable_napi(tp);
+#endif //CONFIG_R8168_NAPI
+}
+
+static int rtl8168_rx_nostuck(struct rtl8168_private *tp)
+{
+ int i, ret = 1;
+ for (i = 0; i < tp->num_rx_rings; i++)
+ ret &= (tp->rx_ringi.dirty_rx == tp->rx_ringi.cur_rx);
+ return ret;
+}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
static void rtl8168_reset_task(void *_data)
static void rtl8168_reset_task(struct work_struct *work)
{
struct rtl8168_private *tp =
- container_of(work, struct rtl8168_private, task.work);
+ container_of(work, struct rtl8168_private, reset_task.work);
struct net_device *dev = tp->dev;
#endif
u32 budget = ~(u32)0;
- unsigned long flags;
+ int i;
- if (!netif_running(dev))
- return;
+ rtnl_lock();
+
+ if (!netif_running(dev) ||
+ test_bit(R8168_FLAG_DOWN, tp->task_flags) ||
+ !test_and_clear_bit(R8168_FLAG_TASK_RESET_PENDING, tp->task_flags))
+ goto out_unlock;
rtl8168_wait_for_quiescence(dev);
+ for (i = 0; i < tp->num_rx_rings; i++) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- rtl8168_rx_interrupt(dev, tp, &budget);
+ rtl8168_rx_interrupt(dev, tp, &tp->rx_ringi, &budget);
#else
- rtl8168_rx_interrupt(dev, tp, budget);
-#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ rtl8168_rx_interrupt(dev, tp, &tp->rx_ringi, budget);
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ }
- spin_lock_irqsave(&tp->lock, flags);
+ netif_carrier_off(dev);
+ netif_tx_disable(dev);
+ rtl8168_hw_reset(dev);
rtl8168_tx_clear(tp);
- if (tp->dirty_rx == tp->cur_rx) {
+ if (rtl8168_rx_nostuck(tp)) {
rtl8168_rx_clear(tp);
rtl8168_init_ring(dev);
rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising);
- spin_unlock_irqrestore(&tp->lock, flags);
} else {
- spin_unlock_irqrestore(&tp->lock, flags);
if (unlikely(net_ratelimit())) {
struct rtl8168_private *tp = netdev_priv(dev);
"%s: Rx buffers shortage\n", dev->name);
}
}
- rtl8168_schedule_work(dev, rtl8168_reset_task);
+ rtl8168_schedule_reset_work(tp);
}
+
+out_unlock:
+ rtnl_unlock();
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void rtl8168_esd_task(void *_data)
+{
+ struct net_device *dev = _data;
+ struct rtl8168_private *tp = netdev_priv(dev);
+#else
+static void rtl8168_esd_task(struct work_struct *work)
+{
+ struct rtl8168_private *tp =
+ container_of(work, struct rtl8168_private, esd_task.work);
+ struct net_device *dev = tp->dev;
+#endif
+ rtnl_lock();
+
+ if (!netif_running(dev) ||
+ test_bit(R8168_FLAG_DOWN, tp->task_flags) ||
+ !test_and_clear_bit(R8168_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags))
+ goto out_unlock;
+
+ rtl8168_esd_checker(tp);
+
+ rtl8168_schedule_esd_work(tp);
+
+out_unlock:
+ rtnl_unlock();
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static void rtl8168_linkchg_task(void *_data)
+{
+ struct net_device *dev = _data;
+ //struct rtl8168_private *tp = netdev_priv(dev);
+#else
+static void rtl8168_linkchg_task(struct work_struct *work)
+{
+ struct rtl8168_private *tp =
+ container_of(work, struct rtl8168_private, linkchg_task.work);
+ struct net_device *dev = tp->dev;
+#endif
+ rtnl_lock();
+
+ if (!netif_running(dev) ||
+ test_bit(R8168_FLAG_DOWN, tp->task_flags) ||
+ !test_and_clear_bit(R8168_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags))
+ goto out_unlock;
+
+ rtl8168_check_link_status(dev);
+
+ rtl8168_schedule_linkchg_work(tp);
+
+out_unlock:
+ rtnl_unlock();
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)
#endif
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&tp->lock, flags);
- netif_stop_queue(dev);
- netif_carrier_off(dev);
- rtl8168_hw_reset(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
/* Let's wait a bit while any (async) irq lands on */
- rtl8168_schedule_work(dev, rtl8168_reset_task);
+ rtl8168_schedule_reset_work(tp);
}
static u32
-rtl8168_get_txd_opts1(struct rtl8168_private *tp,
+rtl8168_get_txd_opts1(struct rtl8168_tx_ring *ring,
u32 opts1,
u32 len,
unsigned int entry)
{
u32 status = opts1 | len;
- if (entry == tp->num_tx_desc - 1)
+ if (entry == ring->num_tx_desc - 1)
status |= RingEnd;
return status;
static int
rtl8168_xmit_frags(struct rtl8168_private *tp,
+ struct rtl8168_tx_ring *ring,
struct sk_buff *skb,
const u32 *opts)
{
struct TxDesc *txd = NULL;
const unsigned char nr_frags = info->nr_frags;
- entry = tp->cur_tx;
+ entry = ring->cur_tx;
for (cur_frag = 0; cur_frag < nr_frags; cur_frag++) {
skb_frag_t *frag = info->frags + cur_frag;
dma_addr_t mapping;
u32 status, len;
void *addr;
- entry = (entry + 1) % tp->num_tx_desc;
+ entry = (entry + 1) % ring->num_tx_desc;
- txd = tp->TxDescArray + entry;
+ txd = ring->TxDescArray + entry;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0)
len = frag->size;
addr = ((void *) page_address(frag->page)) + frag->page_offset;
}
/* anti gcc 2.95.3 bugware (sic) */
- status = rtl8168_get_txd_opts1(tp, opts0, len, entry);
+ status = rtl8168_get_txd_opts1(ring, opts0, len, entry);
if (cur_frag == (nr_frags - 1)) {
- tp->tx_skbentry.skb = skb;
+ ring->tx_skbentry.skb = skb;
status |= LastFrag;
}
txd->addr = cpu_to_le64(mapping);
- tp->tx_skbentry.len = len;
+ ring->tx_skbentry.len = len;
txd->opts2 = cpu_to_le32(opts1);
wmb();
return cur_frag;
err_out:
- rtl8168_tx_clear_range(tp, tp->cur_tx + 1, cur_frag);
+ rtl8168_tx_clear_range(tp, ring, ring->cur_tx + 1, cur_frag);
return -EIO;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
/* r8169_csum_workaround()
- * The hw limits the value the transport offset. When the offset is out of the
- * range, calculate the checksum by sw.
- */
+ * The hw limits the value the transport offset. When the offset is out of the
+ * range, calculate the checksum by sw.
+ */
static void r8168_csum_workaround(struct rtl8168_private *tp,
struct sk_buff *skb)
{
#endif
static bool rtl8168_tx_slots_avail(struct rtl8168_private *tp,
- unsigned int nr_frags)
+ struct rtl8168_tx_ring *ring)
{
- unsigned int slots_avail = tp->dirty_tx + tp->num_tx_desc - tp->cur_tx;
+ unsigned int slots_avail = READ_ONCE(ring->dirty_tx) + ring->num_tx_desc
+ - READ_ONCE(ring->cur_tx);
/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
- return slots_avail > nr_frags;
+ return slots_avail > MAX_SKB_FRAGS;
}
static netdev_tx_t
u32 len;
u32 opts2;
netdev_tx_t ret = NETDEV_TX_OK;
- unsigned long flags, large_send;
+ unsigned long large_send;
int frags;
+ const u16 queue_mapping = skb_get_queue_mapping(skb);
+ struct rtl8168_tx_ring *ring;
+ bool stop_queue;
- spin_lock_irqsave(&tp->lock, flags);
+ assert(queue_mapping < tp->num_tx_rings);
- if (unlikely(!rtl8168_tx_slots_avail(tp, skb_shinfo(skb)->nr_frags))) {
+ ring = &tp->tx_ringqueue_mapping;
+
+ if (unlikely(!rtl8168_tx_slots_avail(tp, ring))) {
if (netif_msg_drv(tp)) {
printk(KERN_ERR
"%s: BUG! Tx Ring full when queue awake!\n",
goto err_stop;
}
- entry = tp->cur_tx % tp->num_tx_desc;
- txd = tp->TxDescArray + entry;
+ entry = ring->cur_tx % ring->num_tx_desc;
+ txd = ring->TxDescArray + entry;
if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) {
if (netif_msg_drv(tp)) {
case __constant_htons(ETH_P_IPV6):
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
if (msdn_giant_send_check(skb)) {
- spin_unlock_irqrestore(&tp->lock, flags);
r8168_csum_workaround(tp, skb);
goto out;
}
goto err_dma_0;
}
- frags = rtl8168_xmit_frags(tp, skb, opts);
+ frags = rtl8168_xmit_frags(tp, ring, skb, opts);
if (unlikely(frags < 0))
goto err_dma_0;
if (frags) {
} else {
len = skb->len;
- tp->tx_skbentry.skb = skb;
+ ring->tx_skbentry.skb = skb;
opts0 |= FirstFrag | LastFrag;
}
- opts0 = rtl8168_get_txd_opts1(tp, opts0, len, entry);
+ opts0 = rtl8168_get_txd_opts1(ring, opts0, len, entry);
mapping = dma_map_single(tp_to_dev(tp), skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) {
if (unlikely(net_ratelimit()))
netif_err(tp, drv, dev, "Failed to map TX DMA!\n");
goto err_dma_1;
}
- tp->tx_skbentry.len = len;
+ ring->tx_skbentry.len = len;
txd->addr = cpu_to_le64(mapping);
txd->opts2 = cpu_to_le32(opts1);
wmb();
skb_tx_timestamp(skb);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0)
- tp->cur_tx += frags + 1;
+ /* rtl_tx needs to see descriptor changes before updated ring->cur_tx */
+ smp_wmb();
- wmb();
+ WRITE_ONCE(ring->cur_tx, ring->cur_tx + frags + 1);
+
+ stop_queue = !rtl8168_tx_slots_avail(tp, ring);
+ if (unlikely(stop_queue)) {
+ /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
+ * not miss a ring update when it notices a stopped queue.
+ */
+ smp_wmb();
+ netif_stop_subqueue(dev, queue_mapping);
+ }
- RTL_W8(tp, TxPoll, NPQ); /* set polling bit */
+ rtl8168_doorbell(ring); /* set polling bit */
- if (!rtl8168_tx_slots_avail(tp, MAX_SKB_FRAGS)) {
- netif_stop_queue(dev);
- smp_rmb();
- if (rtl8168_tx_slots_avail(tp, MAX_SKB_FRAGS))
- netif_wake_queue(dev);
+ if (unlikely(stop_queue)) {
+ /* Sync with rtl_tx:
+ * - publish queue status and cur_tx ring index (write barrier)
+ * - refresh dirty_tx ring index (read barrier).
+ * May the current thread have a pessimistic view of the ring
+ * status and forget to wake up queue, a racing rtl_tx thread
+ * can't.
+ */
+ smp_mb();
+ if (rtl8168_tx_slots_avail(tp, ring))
+ netif_start_subqueue(dev, queue_mapping);
}
- spin_unlock_irqrestore(&tp->lock, flags);
out:
return ret;
err_dma_1:
- tp->tx_skbentry.skb = NULL;
- rtl8168_tx_clear_range(tp, tp->cur_tx + 1, frags);
+ ring->tx_skbentry.skb = NULL;
+ rtl8168_tx_clear_range(tp, ring, ring->cur_tx + 1, frags);
err_dma_0:
RTLDEV->stats.tx_dropped++;
- spin_unlock_irqrestore(&tp->lock, flags);
dev_kfree_skb_any(skb);
ret = NETDEV_TX_OK;
goto out;
err_stop:
- netif_stop_queue(dev);
+ netif_tx_disable(dev);
ret = NETDEV_TX_BUSY;
RTLDEV->stats.tx_dropped++;
-
- spin_unlock_irqrestore(&tp->lock, flags);
goto out;
}
static void
-rtl8168_tx_interrupt(struct net_device *dev,
- struct rtl8168_private *tp)
+rtl8168_tx_interrupt(struct rtl8168_tx_ring *ring)
{
+ struct rtl8168_private *tp = ring->priv;
+ struct net_device *dev = tp->dev;
unsigned int dirty_tx, tx_left;
assert(dev != NULL);
assert(tp != NULL);
- dirty_tx = tp->dirty_tx;
+#ifdef ENABLE_LIB_SUPPORT
+ if (ring->index > 0) {
+ rtl8168_lib_tx_interrupt(tp);
+ return;
+ }
+#endif
+ dirty_tx = ring->dirty_tx;
smp_rmb();
- tx_left = tp->cur_tx - dirty_tx;
+ tx_left = READ_ONCE(ring->cur_tx) - dirty_tx;
tp->dynamic_aspm_packet_count += tx_left;
while (tx_left > 0) {
- unsigned int entry = dirty_tx % tp->num_tx_desc;
- struct ring_info *tx_skb = tp->tx_skb + entry;
+ unsigned int entry = dirty_tx % ring->num_tx_desc;
+ struct ring_info *tx_skb = ring->tx_skb + entry;
u32 len = tx_skb->len;
u32 status;
rmb();
- status = le32_to_cpu(tp->TxDescArrayentry.opts1);
+ status = le32_to_cpu(ring->TxDescArrayentry.opts1);
if (status & DescOwn)
break;
rtl8168_unmap_tx_skb(tp->pci_dev,
tx_skb,
- tp->TxDescArray + entry);
+ ring->TxDescArray + entry);
if (tx_skb->skb!=NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
tp->dynamic_aspm_packet_count -= tx_left;
- if (tp->dirty_tx != dirty_tx) {
- tp->dirty_tx = dirty_tx;
+ if (ring->dirty_tx != dirty_tx) {
+ WRITE_ONCE(ring->dirty_tx, dirty_tx);
smp_wmb();
if (netif_queue_stopped(dev) &&
- (rtl8168_tx_slots_avail(tp, MAX_SKB_FRAGS))) {
- netif_wake_queue(dev);
+ (rtl8168_tx_slots_avail(tp, ring))) {
+ netif_start_subqueue(dev, ring->index);
}
smp_rmb();
- if (tp->cur_tx != dirty_tx)
- RTL_W8(tp, TxPoll, NPQ);
+ if (ring->cur_tx != dirty_tx)
+ rtl8168_doorbell(ring);
}
}
+static void
+rtl8168_tx_all_interrupt(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i = 0; i < rtl8168_tot_tx_rings(tp); i++)
+ rtl8168_tx_interrupt(&tp->tx_ringi);
+}
+
static inline int
rtl8168_fragmented_frame(u32 status)
{
}
}
+/*
static inline int
rtl8168_try_rx_copy(struct rtl8168_private *tp,
+ struct rtl8168_rx_ring *ring,
struct sk_buff **sk_buff,
int pkt_size,
struct RxDesc *desc,
{
int ret = -1;
- if (pkt_size < rx_copybreak) {
- struct sk_buff *skb;
+ struct sk_buff *skb;
- skb = RTL_ALLOC_SKB_INTR(tp, pkt_size + RTK_RX_ALIGN);
- if (skb) {
- u8 *data;
+ skb = RTL_ALLOC_SKB_INTR(&tp->r8168napiring->index.napi,
+ pkt_size + RTK_RX_ALIGN);
+ if (skb) {
+ u8 *data;
- data = sk_buff0->data;
- skb_reserve(skb, RTK_RX_ALIGN);
+ data = sk_buff0->data;
+ skb_reserve(skb, RTK_RX_ALIGN);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37)
- prefetch(data - RTK_RX_ALIGN);
+ prefetch(data - RTK_RX_ALIGN);
#endif
- eth_copy_and_sum(skb, data, pkt_size, 0);
- *sk_buff = skb;
- rtl8168_mark_to_asic(desc, rx_buf_sz);
- ret = 0;
- }
+ eth_copy_and_sum(skb, data, pkt_size, 0);
+ *sk_buff = skb;
+ rtl8168_mark_to_asic(desc, rx_buf_sz);
+ ret = 0;
}
+
return ret;
}
+*/
static inline void
rtl8168_rx_skb(struct rtl8168_private *tp,
- struct sk_buff *skb)
+ struct sk_buff *skb,
+ u32 ring_index)
{
#ifdef CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
netif_receive_skb(skb);
#else
- napi_gro_receive(&tp->napi, skb);
+ napi_gro_receive(&tp->r8168napiring_index.napi, skb);
#endif
#else
netif_rx(skb);
static int
rtl8168_rx_interrupt(struct net_device *dev,
struct rtl8168_private *tp,
+ struct rtl8168_rx_ring *ring,
napi_budget budget)
{
unsigned int cur_rx, rx_left;
- unsigned int delta, count = 0;
+ unsigned int count = 0;
+ u32 ring_index = ring->index;
unsigned int entry;
struct RxDesc *desc;
u32 status;
u32 rx_quota;
+ u64 rx_buf_phy_addr;
assert(dev != NULL);
assert(tp != NULL);
- if (tp->RxDescArray == NULL)
+ if (!tp->RxDescArray)
goto rx_out;
+#ifdef ENABLE_LIB_SUPPORT
+ if (ring->index > 0) {
+ rtl8168_lib_rx_interrupt(tp);
+ goto rx_out;
+ }
+#endif
rx_quota = RTL_RX_QUOTA(budget);
- cur_rx = tp->cur_rx;
- entry = cur_rx % tp->num_rx_desc;
- desc = tp->RxDescArray + entry;
- rx_left = tp->num_rx_desc + tp->dirty_rx - cur_rx;
+ cur_rx = ring->cur_rx;
+ rx_left = tp->num_rx_desc + ring->dirty_rx - cur_rx;
rx_left = rtl8168_rx_quota(rx_left, (u32)rx_quota);
- for (; rx_left > 0; rx_left--) {
+ for (; rx_left > 0; rx_left--, cur_rx++) {
+ int pkt_size;
+ const void *rx_buf;
+ struct sk_buff *skb;
+
+ entry = cur_rx % tp->num_rx_desc;
+ desc = rtl8168_get_rxdesc(tp, tp->RxDescArray, entry, ring_index);
status = le32_to_cpu(desc->opts1);
if (status & DescOwn)
break;
RTLDEV->stats.rx_length_errors++;
if (status & RxCRC)
RTLDEV->stats.rx_crc_errors++;
- if (dev->features & NETIF_F_RXALL)
- goto process_pkt;
- rtl8168_mark_to_asic(desc, tp->rx_buf_sz);
- } else {
- struct sk_buff *skb;
- int pkt_size;
+ if (!(dev->features & NETIF_F_RXALL))
+ goto release_descriptor;
+ }
-process_pkt:
- pkt_size = status & 0x00003fff;
- if (likely(!(dev->features & NETIF_F_RXFCS)))
- pkt_size -= ETH_FCS_LEN;
-
- /*
- * The driver does not support incoming fragmented
- * frames. They are seen as a symptom of over-mtu
- * sized frames.
- */
- if (unlikely(rtl8168_fragmented_frame(status)) ||
- unlikely(pkt_size > tp->rx_buf_sz)) {
- RTLDEV->stats.rx_dropped++;
- RTLDEV->stats.rx_length_errors++;
- rtl8168_mark_to_asic(desc, tp->rx_buf_sz);
- continue;
- }
+ pkt_size = status & 0x00003fff;
+ if (likely(!(dev->features & NETIF_F_RXFCS)))
+ pkt_size -= ETH_FCS_LEN;
- skb = tp->Rx_skbuffentry;
+ /*
+ * The driver does not support incoming fragmented
+ * frames. They are seen as a symptom of over-mtu
+ * sized frames.
+ */
+ if (unlikely(rtl8168_fragmented_frame(status)) ||
+ unlikely(pkt_size > tp->rx_buf_sz)) {
+ RTLDEV->stats.rx_dropped++;
+ RTLDEV->stats.rx_length_errors++;
+ goto release_descriptor;
+ }
+
+ skb = RTL_ALLOC_SKB_INTR(&tp->r8168napiring_index.napi, pkt_size + RTK_RX_ALIGN);
+ if (!skb) {
+ RTLDEV->stats.rx_dropped++;
+ RTLDEV->stats.rx_length_errors++;
+ //netdev_err(tp->dev, "Failed to allocate RX skb!\n");
+ goto release_descriptor;
+ }
+
+ rx_buf_phy_addr = ring->RxDescPhyAddrentry;
+ dma_sync_single_for_cpu(tp_to_dev(tp),
+ rx_buf_phy_addr, tp->rx_buf_sz,
+ DMA_FROM_DEVICE);
- dma_sync_single_for_cpu(tp_to_dev(tp),
- le64_to_cpu(desc->addr), tp->rx_buf_sz,
- DMA_FROM_DEVICE);
-
- if (rtl8168_try_rx_copy(tp, &skb, pkt_size,
- desc, tp->rx_buf_sz)) {
- tp->Rx_skbuffentry = NULL;
- dma_unmap_single(tp_to_dev(tp), le64_to_cpu(desc->addr),
- tp->rx_buf_sz, DMA_FROM_DEVICE);
- } else {
- dma_sync_single_for_device(tp_to_dev(tp), le64_to_cpu(desc->addr),
- tp->rx_buf_sz, DMA_FROM_DEVICE);
- }
+ rx_buf = ring->Rx_skbuffentry->data;
+ if (!R8168_USE_NAPI_ALLOC_SKB)
+ skb_reserve(skb, RTK_RX_ALIGN);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37)
+ prefetch(rx_buf);
+#endif
+ eth_copy_and_sum(skb, rx_buf, pkt_size, 0);
- if (tp->cp_cmd & RxChkSum)
- rtl8168_rx_csum(tp, skb, desc);
+ dma_sync_single_for_device(tp_to_dev(tp), rx_buf_phy_addr,
+ tp->rx_buf_sz, DMA_FROM_DEVICE);
- skb->dev = dev;
- skb_put(skb, pkt_size);
- skb->protocol = eth_type_trans(skb, dev);
+#ifdef ENABLE_RSS_SUPPORT
+ rtl8168_rx_hash(tp, (struct RxDescV2 *)desc, skb);
+#endif
+ if (tp->cp_cmd & RxChkSum)
+ rtl8168_rx_csum(tp, skb, desc);
+
+ skb->dev = dev;
+ skb_put(skb, pkt_size);
+ skb->protocol = eth_type_trans(skb, dev);
- if (skb->pkt_type == PACKET_MULTICAST)
- RTLDEV->stats.multicast++;
+ if (skb->pkt_type == PACKET_MULTICAST)
+ RTLDEV->stats.multicast++;
- if (rtl8168_rx_vlan_skb(tp, desc, skb) < 0)
- rtl8168_rx_skb(tp, skb);
+ if (rtl8168_rx_vlan_skb(tp, desc, skb) < 0)
+ rtl8168_rx_skb(tp, skb, ring_index);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
- dev->last_rx = jiffies;
+ dev->last_rx = jiffies;
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0)
- RTLDEV->stats.rx_bytes += pkt_size;
- RTLDEV->stats.rx_packets++;
- }
+ RTLDEV->stats.rx_bytes += pkt_size;
+ RTLDEV->stats.rx_packets++;
- cur_rx++;
- entry = cur_rx % tp->num_rx_desc;
- desc = tp->RxDescArray + entry;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37)
- prefetch(desc);
-#endif
+release_descriptor:
+ rtl8168_mark_to_asic(desc, tp->rx_buf_sz);
}
- count = cur_rx - tp->cur_rx;
- tp->cur_rx = cur_rx;
+ count = cur_rx - ring->cur_rx;
+ ring->cur_rx = cur_rx;
+ ring->dirty_rx += count;
- delta = rtl8168_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, 1);
- if (!delta && count && netif_msg_intr(tp))
- printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name);
- tp->dirty_rx += delta;
-
- tp->dynamic_aspm_packet_count += delta;
-
- /*
- * FIXME: until there is periodic timer to try and refill the ring,
- * a temporary shortage may definitely kill the Rx process.
- * - disable the asic to try and avoid an overflow and kick it again
- * after refill ?
- * - how do others driver handle this condition (Uh oh...).
- */
- if ((tp->dirty_rx + tp->num_rx_desc == tp->cur_rx) && netif_msg_intr(tp))
- printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name);
+ tp->dynamic_aspm_packet_count += count;
rx_out:
return count;
static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance)
#endif
{
- struct net_device *dev = (struct net_device *) dev_instance;
- struct rtl8168_private *tp = netdev_priv(dev);
- int status;
+ struct r8168_napi *r8168napi = dev_instance;
+ struct rtl8168_private *tp = r8168napi->priv;
+ struct net_device *dev = tp->dev;
+ u8 other_q_status = 0;
int handled = 0;
+ int status;
+ int i;
do {
- status = RTL_R16(tp, IntrStatus);
-
+ status = RTL_R16(tp, tp->isr_reg0);
+#ifdef ENABLE_RSS_SUPPORT
+ if (R8168_MULTI_RX_Q(tp)) {
+ for (i=1; i<rtl8168_tot_rx_rings(tp); i++)
+ other_q_status |= RTL_R8(tp, tp->isr_regi);
+ }
+#endif
if (!(tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))) {
/* hotplug/major error/no more work/shared irq */
- if ((status == 0xFFFF) || !status)
+ if ((status == 0xFFFF) || (!status && !other_q_status))
break;
- if (!(status & (tp->intr_mask | tp->timer_intr_mask)))
+ if (!(status & (tp->intr_mask | tp->timer_intr_mask)) &&
+ !(other_q_status & other_q_intr_mask))
break;
}
handled = 1;
- rtl8168_disable_hw_interrupt(tp);
+ rtl8168_disable_interrupt(tp);
+ rtl8168_disable_lib_interrupt(tp);
switch (tp->mcfg) {
- case CFG_METHOD_9:
- case CFG_METHOD_10:
- case CFG_METHOD_11:
- case CFG_METHOD_12:
- case CFG_METHOD_13:
- case CFG_METHOD_14:
- case CFG_METHOD_15:
- case CFG_METHOD_16:
- case CFG_METHOD_17:
- case CFG_METHOD_18:
- case CFG_METHOD_19:
- case CFG_METHOD_20:
- case CFG_METHOD_21:
- case CFG_METHOD_22:
- case CFG_METHOD_23:
- case CFG_METHOD_24:
- case CFG_METHOD_25:
- case CFG_METHOD_26:
- case CFG_METHOD_27:
- case CFG_METHOD_28:
- case CFG_METHOD_29:
- case CFG_METHOD_30:
- case CFG_METHOD_31:
- case CFG_METHOD_32:
- case CFG_METHOD_33:
- case CFG_METHOD_34:
- case CFG_METHOD_35:
+ case CFG_METHOD_9 ... CFG_METHOD_37:
/* RX_OVERFLOW RE-START mechanism now HW handles it automatically*/
- RTL_W16(tp, IntrStatus, status&~RxFIFOOver);
+ rtl8168_clear_isr_by_vector(tp, 0, status&~RxFIFOOver);
break;
default:
- RTL_W16(tp, IntrStatus, status);
+ rtl8168_clear_isr_by_vector(tp, 0, status);
break;
}
//Work around for rx fifo overflow
if (unlikely(status & RxFIFOOver)) {
if (tp->mcfg == CFG_METHOD_1) {
- netif_stop_queue(dev);
+ netif_tx_disable(dev);
udelay(300);
rtl8168_hw_reset(dev);
rtl8168_tx_clear(tp);
rtl8168_init_ring(dev);
rtl8168_hw_config(dev);
rtl8168_hw_start(dev);
- netif_wake_queue(dev);
+ netif_tx_wake_all_queues(dev);
}
+ tp->rx_fifo_of++;
+ }
+
+ if (other_q_status) {
+ for (i=1; i<rtl8168_tot_rx_rings(tp); i++)
+ rtl8168_clear_isr_by_vector(tp, i, other_q_status);
}
#ifdef ENABLE_DASH_SUPPORT
#endif
#ifdef CONFIG_R8168_NAPI
- if (status & tp->intr_mask || tp->keep_intr_cnt-- > 0) {
- if (status & tp->intr_mask)
+ if ((status & tp->intr_mask) ||
+ (other_q_status & other_q_intr_mask) ||
+ tp->keep_intr_cnt-- > 0) {
+ if ((status & tp->intr_mask) ||
+ (other_q_status & other_q_intr_mask))
tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT;
- if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &tp->napi)))
- __RTL_NETIF_RX_SCHEDULE(dev, &tp->napi);
+ if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &tp->r8168napi0.napi)))
+ __RTL_NETIF_RX_SCHEDULE(dev, &tp->r8168napi0.napi);
else if (netif_msg_intr(tp))
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
rtl8168_switch_to_hw_interrupt(tp);
}
#else
- if (status & tp->intr_mask || tp->keep_intr_cnt-- > 0) {
+ if ((status & tp->intr_mask) ||
+ (other_q_status & other_q_intr_mask) ||
+ tp->keep_intr_cnt-- > 0) {
+ u32 const max_rx_queue =
+ (other_q_status & other_q_intr_mask) > 0 ?
+ rtl8168_tot_rx_rings(tp) : 1;
u32 budget = ~(u32)0;
- if (status & tp->intr_mask)
+ if ((status & tp->intr_mask) ||
+ (other_q_status & other_q_intr_mask))
tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT;
- rtl8168_tx_interrupt(dev, tp);
+ rtl8168_tx_all_interrupt(tp);
+ for (i = 0; i < max_rx_queue; i++) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- rtl8168_rx_interrupt(dev, tp, &budget);
+ rtl8168_rx_interrupt(dev, tp, &tp->rx_ringi, &budget);
#else
- rtl8168_rx_interrupt(dev, tp, budget);
-#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ rtl8168_rx_interrupt(dev, tp, &tp->rx_ringi, budget);
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ }
#ifdef ENABLE_DASH_SUPPORT
if ( tp->DASH ) {
return IRQ_RETVAL(handled);
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+static irqreturn_t rtl8168_interrupt_msix(int irq, void *dev_instance, struct pt_regs *regs)
+#else
+static irqreturn_t rtl8168_interrupt_msix(int irq, void *dev_instance)
+#endif
+{
+ struct r8168_napi *r8168napi = dev_instance;
+ struct rtl8168_private *tp = r8168napi->priv;
+ struct net_device *dev = tp->dev;
+ int message_id = r8168napi->index;
+#ifndef CONFIG_R8168_NAPI
+ u32 budget = ~(u32)0;
+#endif
+
+ do {
+#if defined(RTL_USE_NEW_INTR_API)
+ if (!tp->irq_tblmessage_id.requested)
+ break;
+#endif
+ /*
+ * Other rx queue may incur interrupt due to rdu.
+ * Skip its interrupt here or its queue will be initialized
+ * incorrectly.
+ */
+ if (message_id >= tp->num_rx_rings)
+ break;
+
#ifdef CONFIG_R8168_NAPI
-static int rtl8168_poll(napi_ptr napi, napi_budget budget)
+ if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &r8168napi->napi))) {
+ rtl8168_disable_interrupt_by_vector(tp, message_id);
+ __RTL_NETIF_RX_SCHEDULE(dev, &r8168napi->napi);
+ } else if (netif_msg_intr(tp))
+ printk(KERN_INFO "%s: interrupt message id %d in poll_msix\n",
+ dev->name, message_id);
+ rtl8168_self_clear_isr_by_vector(tp, message_id);
+#else
+ if (message_id == 0)
+ rtl8168_tx_all_interrupt(tp);
+
+ if (message_id < tp->num_rx_rings) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ rtl8168_rx_interrupt(dev, tp, &tp->rx_ringmessage_id, &budget);
+#else
+ rtl8168_rx_interrupt(dev, tp, &tp->rx_ringmessage_id, budget);
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ }
+
+ rtl8168_enable_interrupt_by_vector(tp, message_id);
+#endif
+
+ } while (false);
+
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_R8168_NAPI
+static int rtl8168_poll_vector(napi_ptr napi, napi_budget budget, bool all_rx_q)
{
- struct rtl8168_private *tp = RTL_GET_PRIV(napi, struct rtl8168_private);
+ struct r8168_napi *r8168napi = RTL_GET_PRIV(napi, struct r8168_napi);
+ struct rtl8168_private *tp = r8168napi->priv;
+ const int message_id = r8168napi->index;
RTL_GET_NETDEV(tp)
unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev);
- unsigned int work_done;
- unsigned long flags;
+ unsigned int work_done = 0;
+ int i;
- spin_lock_irqsave(&tp->lock, flags);
- rtl8168_tx_interrupt(dev, tp);
- spin_unlock_irqrestore(&tp->lock, flags);
+ if (message_id == 0)
+ rtl8168_tx_all_interrupt(tp);
- work_done = rtl8168_rx_interrupt(dev, tp, budget);
+ if (all_rx_q)
+ for (i = 0; i < tp->num_rx_rings; i++)
+ work_done += rtl8168_rx_interrupt(dev, tp, &tp->rx_ringi, budget);
+ else
+ work_done += rtl8168_rx_interrupt(dev, tp, &tp->rx_ringmessage_id, budget);
RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget);
if (work_done < work_to_do) {
#ifdef ENABLE_DASH_SUPPORT
- if ( tp->DASH ) {
- struct net_device *dev = tp->dev;
+ if (message_id == 0) {
+ if ( tp->DASH ) {
+ struct net_device *dev = tp->dev;
- spin_lock_irqsave(&tp->lock, flags);
- HandleDashInterrupt(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
+ HandleDashInterrupt(dev);
+ }
}
#endif
* write is safe - FR
*/
smp_wmb();
+ //if (message_id == 0)
+ // rtl8168_switch_to_timer_interrupt(tp);
+ //else
+ rtl8168_enable_interrupt_by_vector(tp, message_id);
+ }
- rtl8168_switch_to_timer_interrupt(tp);
+ return RTL_NAPI_RETURN_VALUE;
+}
+
+static int rtl8168_poll(napi_ptr napi, napi_budget budget)
+{
+ return rtl8168_poll_vector(napi, budget, 1);
+}
+
+static int rtl8168_poll_msix_ring(napi_ptr napi, napi_budget budget)
+{
+ return rtl8168_poll_vector(napi, budget, 0);
+}
+static int rtl8168_poll_msix_rx(napi_ptr napi, napi_budget budget)
+{
+ struct r8168_napi *r8168napi = RTL_GET_PRIV(napi, struct r8168_napi);
+ struct rtl8168_private *tp = r8168napi->priv;
+ const int message_id = r8168napi->index;
+ RTL_GET_NETDEV(tp)
+ unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev);
+ unsigned int work_done = 0;
+
+ work_done += rtl8168_rx_interrupt(dev, tp, &tp->rx_ringmessage_id, budget);
+
+ RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget);
+
+ if (work_done < work_to_do) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
+ if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE)
+ return RTL_NAPI_RETURN_VALUE;
+#else
+ RTL_NETIF_RX_COMPLETE(dev, napi, work_done);
+#endif
+ /*
+ * 20040426: the barrier is not strictly required but the
+ * behavior of the irq handler could be less predictable
+ * without it. Btw, the lack of flush for the posted pci
+ * write is safe - FR
+ */
+ smp_wmb();
+ //if (message_id == 0)
+ // rtl8168_switch_to_timer_interrupt(tp);
+ //else
+ rtl8168_enable_interrupt_by_vector(tp, message_id);
}
return RTL_NAPI_RETURN_VALUE;
static void rtl8168_down(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
-
- rtl8168_delete_esd_timer(dev, &tp->esd_timer);
-
- rtl8168_delete_link_timer(dev, &tp->link_timer);
-
-#ifdef CONFIG_R8168_NAPI
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
- RTL_NAPI_DISABLE(dev, &tp->napi);
-#endif
-#endif//CONFIG_R8168_NAPI
- netif_stop_queue(dev);
+ //rtl8168_delete_esd_timer(dev, &tp->esd_timer);
+ //rtl8168_delete_link_timer(dev, &tp->link_timer);
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11)
- /* Give a racing hard_start_xmit a few cycles to complete. */
- synchronize_rcu(); /* FIXME: should this be synchronize_irq()? */
-#endif
+ netif_carrier_off(dev);
- spin_lock_irqsave(&tp->lock, flags);
+ netif_tx_disable(dev);
- netif_carrier_off(dev);
+ _rtl8168_wait_for_quiescence(dev);
rtl8168_dsm(dev, DSM_IF_DOWN);
rtl8168_hw_reset(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtl8168_tx_clear(tp);
- synchronize_irq(tp->irq);
+ rtl8168_rx_clear(tp);
+}
- spin_lock_irqsave(&tp->lock, flags);
+static int rtl8168_resource_freed(struct rtl8168_private *tp)
+{
+ int i;
- rtl8168_tx_clear(tp);
+ for (i = 0; i < tp->num_tx_rings; i++)
+ if (tp->tx_ringi.TxDescArray) return 0;
- rtl8168_rx_clear(tp);
+ if (tp->RxDescArray)
+ return 0;
- spin_unlock_irqrestore(&tp->lock, flags);
+ return 1;
}
-static int rtl8168_close(struct net_device *dev)
+int rtl8168_close(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
- struct pci_dev *pdev = tp->pci_dev;
- unsigned long flags;
- if (tp->TxDescArray!=NULL && tp->RxDescArray!=NULL) {
- rtl8168_cancel_schedule_work(dev);
+ if (!rtl8168_resource_freed(tp)) {
+ set_bit(R8168_FLAG_DOWN, tp->task_flags);
rtl8168_down(dev);
pci_clear_master(tp->pci_dev);
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_hw_d3_para(dev);
rtl8168_powerdown_pll(dev);
rtl8168_sleep_rx_enable(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
-
- free_irq(tp->irq, dev);
+ rtl8168_free_irq(tp);
- dma_free_coherent(&pdev->dev,
- tp->RxDescAllocSize,
- tp->RxDescArray,
- tp->RxPhyAddr);
- dma_free_coherent(&pdev->dev,
- tp->TxDescAllocSize,
- tp->TxDescArray,
- tp->TxPhyAddr);
- tp->TxDescArray = NULL;
- tp->RxDescArray = NULL;
+ rtl8168_free_alloc_resources(tp);
} else {
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_hw_d3_para(dev);
rtl8168_powerdown_pll(dev);
-
- spin_unlock_irqrestore(&tp->lock, flags);
}
return 0;
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8168_private *tp = netdev_priv(dev);
+ rtnl_lock();
+
if (HW_DASH_SUPPORT_DASH(tp))
rtl8168_driver_stop(tp);
rtl8168_close(dev);
rtl8168_disable_msi(pdev, tp);
+ rtnl_unlock();
+
if (system_state == SYSTEM_POWER_OFF) {
pci_clear_master(tp->pci_dev);
rtl8168_sleep_rx_enable(dev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
struct rtl8168_private *tp = netdev_priv(dev);
#endif
- if (netif_running(dev)) {
-// spin_lock_irqsave(&tp->lock, flags);
-// spin_unlock_irqrestore(&tp->lock, flags);
- }
-
return &RTLDEV->stats;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
static int
rtl8168_suspend(struct pci_dev *pdev, u32 state)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+static int
+rtl8168_suspend(struct device *device)
#else
static int
rtl8168_suspend(struct pci_dev *pdev, pm_message_t state)
#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+ struct pci_dev *pdev = to_pci_dev(device);
+#endif
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8168_private *tp = netdev_priv(dev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
u32 pci_pm_state = pci_choose_state(pdev, state);
#endif
- unsigned long flags;
-
if (!netif_running(dev))
goto out;
- rtl8168_cancel_schedule_work(dev);
+ //rtl8168_cancel_schedule_work(dev);
- rtl8168_delete_esd_timer(dev, &tp->esd_timer);
+ //rtl8168_delete_esd_timer(dev, &tp->esd_timer);
- rtl8168_delete_link_timer(dev, &tp->link_timer);
+ //rtl8168_delete_link_timer(dev, &tp->link_timer);
- netif_stop_queue(dev);
+ rtnl_lock();
+
+ set_bit(R8168_FLAG_DOWN, tp->task_flags);
netif_carrier_off(dev);
- netif_device_detach(dev);
+ netif_tx_disable(dev);
- spin_lock_irqsave(&tp->lock, flags);
+ netif_device_detach(dev);
rtl8168_dsm(dev, DSM_NIC_GOTO_D3);
rtl8168_sleep_rx_enable(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
+ rtnl_unlock();
out:
- if (HW_DASH_SUPPORT_DASH(tp)) {
- spin_lock_irqsave(&tp->lock, flags);
+ if (HW_DASH_SUPPORT_DASH(tp))
rtl8168_driver_stop(tp);
- spin_unlock_irqrestore(&tp->lock, flags);
- }
+
+ pci_disable_device(pdev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
pci_save_state(pdev, &pci_pm_state);
#else
pci_save_state(pdev);
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled);
-// pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#endif
+
+ pci_prepare_to_sleep(pdev);
return 0;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
static int
rtl8168_resume(struct pci_dev *pdev)
+#else
+static int
+rtl8168_resume(struct device *device)
+#endif
{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+ struct pci_dev *pdev = to_pci_dev(device);
+#endif
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8168_private *tp = netdev_priv(dev);
- unsigned long flags;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
u32 pci_pm_state = PCI_D0;
#endif
+ int err;
+
+ rtnl_lock();
- pci_set_power_state(pdev, PCI_D0);
+ err = pci_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n");
+ goto out_unlock;
+ }
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
pci_restore_state(pdev, &pci_pm_state);
#else
#endif
pci_enable_wake(pdev, PCI_D0, 0);
- spin_lock_irqsave(&tp->lock, flags);
-
/* restore last modified mac address */
rtl8168_rar_set(tp, dev->dev_addr);
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (!netif_running(dev)) {
if (HW_DASH_SUPPORT_DASH(tp)) {
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_driver_start(tp);
- spin_unlock_irqrestore(&tp->lock, flags);
}
- goto out;
+ goto out_unlock;
}
pci_set_master(pdev);
- spin_lock_irqsave(&tp->lock, flags);
-
rtl8168_exit_oob(dev);
rtl8168_dsm(dev, DSM_NIC_RESUME_D3);
rtl8168_hw_config(dev);
- spin_unlock_irqrestore(&tp->lock, flags);
+ clear_bit(R8168_FLAG_DOWN, tp->task_flags);
+
+ rtl8168_schedule_reset_work(tp);
+
+ rtl8168_schedule_esd_work(tp);
- rtl8168_schedule_work(dev, rtl8168_reset_task);
+ rtl8168_schedule_linkchg_work(tp);
+ //mod_timer(&tp->esd_timer, jiffies + RTL8168_ESD_TIMEOUT);
+ //mod_timer(&tp->link_timer, jiffies + RTL8168_LINK_TIMEOUT);
+out_unlock:
netif_device_attach(dev);
- mod_timer(&tp->esd_timer, jiffies + RTL8168_ESD_TIMEOUT);
- mod_timer(&tp->link_timer, jiffies + RTL8168_LINK_TIMEOUT);
-out:
- return 0;
+ rtnl_unlock();
+
+ return err;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+
+static struct dev_pm_ops rtl8168_pm_ops = {
+ .suspend = rtl8168_suspend,
+ .resume = rtl8168_resume,
+ .freeze = rtl8168_suspend,
+ .thaw = rtl8168_resume,
+ .poweroff = rtl8168_suspend,
+ .restore = rtl8168_resume,
+};
+
+#define RTL8168_PM_OPS (&rtl8168_pm_ops)
+
+#endif
+
+#else /* !CONFIG_PM */
+
+#define RTL8168_PM_OPS NULL
+
#endif /* CONFIG_PM */
static struct pci_driver rtl8168_pci_driver = {
.shutdown = rtl8168_shutdown,
#endif
#ifdef CONFIG_PM
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
.suspend = rtl8168_suspend,
.resume = rtl8168_resume,
+#else /* CONFIG_PM */
+ .driver.pm = RTL8168_PM_OPS,
#endif
+#endif /* CONFIG_PM */
};
static int __init
r8168-8.051.02.tar.gz/src/r8168_realwow.h -> r8168-8.052.01.tar.gz/src/r8168_realwow.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.052.01.tar.gz/src/r8168_rss.c
Added
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+################################################################################
+#
+# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
+# controllers with PCI-Express interface.
+#
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# Author:
+# Realtek NIC software team <nicfae@realtek.com>
+# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
+#
+################################################################################
+*/
+
+/************************************************************************************
+ * This product is covered by one or more of the following patents:
+ * US6,570,884, US6,115,776, and US6,327,625.
+ ***********************************************************************************/
+
+#include <linux/version.h>
+#include "r8168.h"
+
+enum rtl8168_rss_register_content {
+ /* RSS */
+ RSS_CTRL_TCP_IPV4_SUPP = (1 << 0),
+ RSS_CTRL_IPV4_SUPP = (1 << 1),
+ RSS_CTRL_TCP_IPV6_SUPP = (1 << 2),
+ RSS_CTRL_IPV6_SUPP = (1 << 3),
+ RSS_CTRL_IPV6_EXT_SUPP = (1 << 4),
+ RSS_CTRL_TCP_IPV6_EXT_SUPP = (1 << 5),
+ RSS_HALF_SUPP = (1 << 7),
+ RSS_QUAD_CPU_EN = (1 << 16),
+ RSS_HQ_Q_SUP_R = (1 << 31),
+};
+
+static int rtl8168_get_rss_hash_opts(struct rtl8168_private *tp,
+ struct ethtool_rxnfc *cmd)
+{
+ cmd->data = 0;
+
+ /* Report default options for RSS */
+ switch (cmd->flow_type) {
+ case TCP_V4_FLOW:
+ cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ /* fallthrough */
+ case IPV4_FLOW:
+ cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+ break;
+ case TCP_V6_FLOW:
+ cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ /* fallthrough */
+ case IPV6_FLOW:
+ cmd->data |= RXH_IP_SRC | RXH_IP_DST;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+ int ret = -EOPNOTSUPP;
+
+ netif_info(tp, drv, tp->dev, "rss get rxnfc\n");
+
+ if (!(dev->features & NETIF_F_RXHASH))
+ return ret;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXRINGS:
+ cmd->data = rtl8168_tot_rx_rings(tp);
+ ret = 0;
+ break;
+ case ETHTOOL_GRXFH:
+ ret = rtl8168_get_rss_hash_opts(tp, cmd);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp)
+{
+ return tp->HwSuppIndirTblEntries;
+}
+
+#define RSS_MASK_BITS_OFFSET (8)
+static int _rtl8168_set_rss_hash_opt(struct rtl8168_private *tp)
+{
+ u32 hash_mask_len;
+ u32 rss_ctrl;
+
+ /* Perform hash on these packet types */
+ rss_ctrl = RSS_CTRL_TCP_IPV4_SUPP
+ | RSS_CTRL_IPV4_SUPP
+ | RSS_CTRL_IPV6_SUPP
+ | RSS_CTRL_IPV6_EXT_SUPP
+ | RSS_CTRL_TCP_IPV6_SUPP
+ | RSS_CTRL_TCP_IPV6_EXT_SUPP;
+
+ if (R8168_MULTI_RSS_4Q(tp))
+ rss_ctrl |= RSS_QUAD_CPU_EN;
+
+ hash_mask_len = ilog2(rtl8168_rss_indir_tbl_entries(tp));
+ hash_mask_len &= (BIT_0 | BIT_1 | BIT_2);
+ rss_ctrl |= hash_mask_len << RSS_MASK_BITS_OFFSET;
+
+ rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC);
+
+ return 0;
+}
+
+static int rtl8168_set_rss_hash_opt(struct rtl8168_private *tp,
+ struct ethtool_rxnfc *nfc)
+{
+ u32 rss_flags = tp->rss_flags;
+
+ netif_info(tp, drv, tp->dev, "rss set hash\n");
+
+ /*
+ * RSS does not support anything other than hashing
+ * to queues on src and dst IPs and ports
+ */
+ if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3))
+ return -EINVAL;
+
+ switch (nfc->flow_type) {
+ case TCP_V4_FLOW:
+ case TCP_V6_FLOW:
+ if (!(nfc->data & RXH_IP_SRC) ||
+ !(nfc->data & RXH_IP_DST) ||
+ !(nfc->data & RXH_L4_B_0_1) ||
+ !(nfc->data & RXH_L4_B_2_3))
+ return -EINVAL;
+ break;
+ case SCTP_V4_FLOW:
+ case AH_ESP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ case SCTP_V6_FLOW:
+ case AH_ESP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ case IP_USER_FLOW:
+ case ETHER_FLOW:
+ /* RSS is not supported for these protocols */
+ if (nfc->data) {
+ netif_err(tp, drv, tp->dev, "Command parameters not supported\n");
+ return -EINVAL;
+ }
+ return 0;
+ default:
+ return -EINVAL;
+ }
+
+ /* if we changed something we need to update flags */
+ if (rss_flags != tp->rss_flags) {
+ u32 rss_ctrl = rtl8168_eri_read(tp, RSS_CTRL_8168, 4, ERIAR_ExGMAC);
+
+ tp->rss_flags = rss_flags;
+
+ /* Perform hash on these packet types */
+ rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP
+ | RSS_CTRL_IPV4_SUPP
+ | RSS_CTRL_IPV6_SUPP
+ | RSS_CTRL_IPV6_EXT_SUPP
+ | RSS_CTRL_TCP_IPV6_SUPP
+ | RSS_CTRL_TCP_IPV6_EXT_SUPP;
+
+ if (R8168_MULTI_RSS_4Q(tp))
+ rss_ctrl |= RSS_QUAD_CPU_EN;
+ else
+ rss_ctrl &= ~RSS_QUAD_CPU_EN;
+
+ rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC);
+ }
+
+ return 0;
+}
+
+int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+ int ret = -EOPNOTSUPP;
+
+ netif_info(tp, drv, tp->dev, "rss set rxnfc\n");
+
+ if (!(dev->features & NETIF_F_RXHASH))
+ return ret;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_SRXFH:
+ ret = rtl8168_set_rss_hash_opt(tp, cmd);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static u32 _rtl8168_get_rxfh_key_size(struct rtl8168_private *tp)
+{
+ return sizeof(tp->rss_key);
+}
+
+u32 rtl8168_get_rxfh_key_size(struct net_device *dev)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ netif_info(tp, drv, tp->dev, "rss get key size\n");
+
+ if (!(dev->features & NETIF_F_RXHASH))
+ return 0;
+
+ return _rtl8168_get_rxfh_key_size(tp);
+}
+
+u32 rtl8168_rss_indir_size(struct net_device *dev)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ netif_info(tp, drv, tp->dev, "rss get indir tbl size\n");
+
+ if (!(dev->features & NETIF_F_RXHASH))
+ return 0;
+
+ return rtl8168_rss_indir_tbl_entries(tp);
+}
+
+static void rtl8168_get_reta(struct rtl8168_private *tp, u32 *indir)
+{
+ int i, reta_size = rtl8168_rss_indir_tbl_entries(tp);
+
+ for (i = 0; i < reta_size; i++)
+ indiri = tp->rss_indir_tbli;
+}
+
+int rtl8168_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
+ u8 *hfunc)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+
+ netif_info(tp, drv, tp->dev, "rss get rxfh\n");
+
+ if (!(dev->features & NETIF_F_RXHASH))
+ return -EOPNOTSUPP;
+
+ if (hfunc)
+ *hfunc = ETH_RSS_HASH_TOP;
+
+ if (indir)
+ rtl8168_get_reta(tp, indir);
+
+ if (key)
+ memcpy(key, tp->rss_key, RTL8168_RSS_KEY_SIZE);
+
+ return 0;
+}
+
+static u32 rtl8168_rss_key_reg(struct rtl8168_private *tp)
+{
+ return RSS_KEY_8168;
+}
+
+static u32 rtl8168_rss_indir_tbl_reg(struct rtl8168_private *tp)
+{
+ return Rss_indir_tbl;
+}
+
+static void rtl8168_store_reta(struct rtl8168_private *tp)
+{
+ u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
+ u16 indir_tbl_reg = rtl8168_rss_indir_tbl_reg(tp);
+ u32 hw_indirRTL8168_RSS_INDIR_TBL_SIZE = {0};
+ u8 *indir = tp->rss_indir_tbl;
+ u32 bit_on_cnt = 0x00000001;
+ u32 i, j;
+
+ /* Mapping redirection table to HW */
+ for (i = 0, j = 0; i < reta_entries; i++) {
+ if ((indiri & 2) && R8168_MULTI_RSS_4Q(tp))
+ hw_indirj + 4 |= bit_on_cnt;
+ if (indiri & 1)
+ hw_indirj |= bit_on_cnt;
+
+ if (bit_on_cnt == 0x80000000) {
+ bit_on_cnt = 0x00000001;
+ j++;
+ continue;
+ }
+ bit_on_cnt <<= 1;
+ }
+
+ /* Write redirection table to HW */
+ for (i = 0; i < RTL8168_RSS_INDIR_TBL_SIZE; i++)
+ RTL_W32(tp, indir_tbl_reg + i*4, hw_indiri);
+}
+
+static void rtl8168_store_rss_key(struct rtl8168_private *tp)
+{
+ const u16 rss_key_reg = rtl8168_rss_key_reg(tp);
+ u32 i, rss_key_size = _rtl8168_get_rxfh_key_size(tp);
+ u32 *rss_key = (u32*)tp->rss_key;
+
+ /* Write redirection table to HW */
+ for (i = 0; i < rss_key_size; i+=4)
+ rtl8168_eri_write(tp, rss_key_reg + i, 4, *rss_key++, ERIAR_ExGMAC);
+}
+
+int rtl8168_set_rxfh(struct net_device *dev, const u32 *indir,
+ const u8 *key, const u8 hfunc)
+{
+ struct rtl8168_private *tp = netdev_priv(dev);
+ u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
+ int i;
+
+ netif_info(tp, drv, tp->dev, "rss set rxfh\n");
+
+ /* We require at least one supported parameter to be changed and no
+ * change in any of the unsupported parameters
+ */
+ if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
+ return -EOPNOTSUPP;
+
+ /* Fill out the redirection table */
+ if (indir) {
+ int max_queues = tp->num_rx_rings;
+
+ /* Verify user input. */
+ for (i = 0; i < reta_entries; i++)
+ if (indiri >= max_queues)
+ return -EINVAL;
+
+ for (i = 0; i < reta_entries; i++)
+ tp->rss_indir_tbli = indiri;
+ }
+
+ /* Fill out the rss hash key */
+ if (key)
+ memcpy(tp->rss_key, key, RTL8168_RSS_KEY_SIZE);
+
+ rtl8168_store_reta(tp);
+
+ rtl8168_store_rss_key(tp);
+
+ return 0;
+}
+
+static u32 rtl8168_get_rx_desc_hash(struct rtl8168_private *tp,
+ struct RxDescV2 *desc)
+{
+ if (!desc->RSSResult)
+ udelay(1);
+ return le32_to_cpu(desc->RSSResult);
+}
+
+#define RXS_8168_RSS_IPV4 BIT(17)
+#define RXS_8168_RSS_IPV6 BIT(18)
+#define RXS_8168_RSS_TCP BIT(19)
+#define RTL8168_RXS_RSS_L3_TYPE_MASK (RXS_8168_RSS_IPV4 | RXS_8168_RSS_IPV6)
+#define RTL8168_RXS_RSS_L4_TYPE_MASK (RXS_8168_RSS_TCP)
+void rtl8168_rx_hash(struct rtl8168_private *tp,
+ struct RxDescV2 *desc,
+ struct sk_buff *skb)
+{
+ u32 rss_header_info;
+
+ if (!(tp->dev->features & NETIF_F_RXHASH))
+ return;
+
+ rss_header_info = le32_to_cpu(desc->opts2);
+
+ if (!(rss_header_info & RTL8168_RXS_RSS_L3_TYPE_MASK))
+ return;
+
+ skb_set_hash(skb, rtl8168_get_rx_desc_hash(tp, desc),
+ (RTL8168_RXS_RSS_L4_TYPE_MASK & rss_header_info) ?
+ PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
+}
+
+void rtl8168_disable_rss(struct rtl8168_private *tp)
+{
+ rtl8168_eri_write(tp, RSS_CTRL_8168, 4, 0x00000000, ERIAR_ExGMAC);
+}
+
+void _rtl8168_config_rss(struct rtl8168_private *tp)
+{
+ _rtl8168_set_rss_hash_opt(tp);
+
+ rtl8168_store_reta(tp);
+
+ rtl8168_store_rss_key(tp);
+}
+
+void rtl8168_config_rss(struct rtl8168_private *tp)
+{
+ if (!HW_RSS_SUPPORT_RSS(tp))
+ return;
+
+ if (!tp->EnableRss) {
+ rtl8168_disable_rss(tp);
+ return;
+ }
+
+ _rtl8168_config_rss(tp);
+}
+
+void rtl8168_init_rss(struct rtl8168_private *tp)
+{
+ int i;
+
+ for (i = 0; i < rtl8168_rss_indir_tbl_entries(tp); i++)
+ tp->rss_indir_tbli = ethtool_rxfh_indir_default(i, tp->num_rx_rings);
+
+ netdev_rss_key_fill(tp->rss_key, RTL8168_RSS_KEY_SIZE);
+}
r8168-8.052.01.tar.gz/src/r8168_rss.h
Added
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+################################################################################
+#
+# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet
+# controllers with PCI-Express interface.
+#
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# Author:
+# Realtek NIC software team <nicfae@realtek.com>
+# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
+#
+################################################################################
+*/
+
+/************************************************************************************
+ * This product is covered by one or more of the following patents:
+ * US6,570,884, US6,115,776, and US6,327,625.
+ ***********************************************************************************/
+
+#ifndef _LINUX_RTL8168_RSS_H
+#define _LINUX_RTL8168_RSS_H
+
+#include <linux/netdevice.h>
+#include <linux/types.h>
+
+#define RTL8168_RSS_INDIR_TBL_SIZE 8
+#define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
+#define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128
+
+struct rtl8168_private;
+struct RxDescV2;
+
+int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs);
+int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
+u32 rtl8168_get_rxfh_key_size(struct net_device *netdev);
+u32 rtl8168_rss_indir_size(struct net_device *netdev);
+int rtl8168_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
+ u8 *hfunc);
+int rtl8168_set_rxfh(struct net_device *netdev, const u32 *indir,
+ const u8 *key, const u8 hfunc);
+void rtl8168_rx_hash(struct rtl8168_private *tp,
+ struct RxDescV2 *desc,
+ struct sk_buff *skb);
+void _rtl8168_config_rss(struct rtl8168_private *tp);
+void rtl8168_config_rss(struct rtl8168_private *tp);
+void rtl8168_init_rss(struct rtl8168_private *tp);
+u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp);
+void rtl8168_disable_rss(struct rtl8168_private *tp);
+
+#endif /* _LINUX_RTL8168_RSS_H */
r8168-8.051.02.tar.gz/src/rtl_eeprom.c -> r8168-8.052.01.tar.gz/src/rtl_eeprom.c
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/rtl_eeprom.h -> r8168-8.052.01.tar.gz/src/rtl_eeprom.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168-8.051.02.tar.gz/src/rtltool.c -> r8168-8.052.01.tar.gz/src/rtltool.c
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
{
struct rtltool_cmd my_cmd;
- unsigned long flags;
int ret;
if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd)))
break;
}
break;
-
case RTLTOOL_WRITE_MAC:
if (my_cmd.len==1)
writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset);
ret = -EOPNOTSUPP;
break;
}
-
break;
-
case RTLTOOL_READ_PHY:
- spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_mdio_prot_read(tp, my_cmd.offset);
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
-
break;
-
case RTLTOOL_WRITE_PHY:
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_prot_write(tp, my_cmd.offset, my_cmd.data);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
-
case RTLTOOL_READ_EPHY:
- spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_ephy_read(tp, my_cmd.offset);
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
-
break;
-
case RTLTOOL_WRITE_EPHY:
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_ephy_write(tp, my_cmd.offset, my_cmd.data);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
-
case RTLTOOL_READ_ERI:
my_cmd.data = 0;
if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) {
- spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_eri_read(tp, my_cmd.offset, my_cmd.len, ERIAR_ExGMAC);
- spin_unlock_irqrestore(&tp->lock, flags);
} else {
ret = -EOPNOTSUPP;
break;
ret = -EFAULT;
break;
}
-
break;
-
case RTLTOOL_WRITE_ERI:
if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) {
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_eri_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data, ERIAR_ExGMAC);
- spin_unlock_irqrestore(&tp->lock, flags);
} else {
ret = -EOPNOTSUPP;
break;
}
break;
-
case RTLTOOL_READ_PCI:
my_cmd.data = 0;
if (my_cmd.len==1)
break;
}
break;
-
case RTLTOOL_WRITE_PCI:
if (my_cmd.len==1)
pci_write_config_byte(tp->pci_dev, my_cmd.offset,
ret = -EOPNOTSUPP;
break;
}
-
break;
-
case RTLTOOL_READ_EEPROM:
- spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_eeprom_read_sc(tp, my_cmd.offset);
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
-
break;
-
case RTLTOOL_WRITE_EEPROM:
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_eeprom_write_sc(tp, my_cmd.offset, my_cmd.data);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
-
case RTL_READ_OOB_MAC:
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_oob_mutex_lock(tp);
my_cmd.data = rtl8168_ocp_read(tp, my_cmd.offset, 4);
rtl8168_oob_mutex_unlock(tp);
- spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
-
case RTL_WRITE_OOB_MAC:
if (my_cmd.len == 0 || my_cmd.len > 4)
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_oob_mutex_lock(tp);
rtl8168_ocp_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data);
rtl8168_oob_mutex_unlock(tp);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
-
case RTL_ENABLE_PCI_DIAG:
- spin_lock_irqsave(&tp->lock, flags);
tp->rtk_enable_diag = 1;
- spin_unlock_irqrestore(&tp->lock, flags);
-
dprintk("enable rtk diag\n");
break;
-
case RTL_DISABLE_PCI_DIAG:
- spin_lock_irqsave(&tp->lock, flags);
tp->rtk_enable_diag = 0;
- spin_unlock_irqrestore(&tp->lock, flags);
-
dprintk("disable rtk diag\n");
break;
-
case RTL_READ_MAC_OCP:
if (my_cmd.offset % 2)
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_mac_ocp_read(tp, my_cmd.offset);
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
-
case RTL_WRITE_MAC_OCP:
if ((my_cmd.offset % 2) || (my_cmd.len != 2))
return -EOPNOTSUPP;
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_mac_ocp_write(tp, my_cmd.offset, (u16)my_cmd.data);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
-
case RTL_DIRECT_READ_PHY_OCP:
- spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_mdio_prot_direct_read_phy_ocp(tp, my_cmd.offset);
- spin_unlock_irqrestore(&tp->lock, flags);
-
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
-
break;
-
case RTL_DIRECT_WRITE_PHY_OCP:
- spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data);
- spin_unlock_irqrestore(&tp->lock, flags);
break;
-
default:
ret = -EOPNOTSUPP;
break;
r8168-8.051.02.tar.gz/src/rtltool.h -> r8168-8.052.01.tar.gz/src/rtltool.h
Changed
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
-# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
+# Copyright(c) 2023 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
r8168.keyring
Added
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEWjorXBYJKwYBBAHaRw8BAQdAjGKRKfCsgqRDija1BdhFQyhl7v8ooFB9n0+B
+fFFwIUq0N01hc3NpbWlsaWFubyBUb3Jyb21lbyA8bWFzc2ltaWxpYW5vLnRvcnJv
+bWVvQGdtYWlsLmNvbT6I0AQTFggAeAIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIX
+gAUJEJ7XDhYhBAytqs9w9kxlThMbMRFnXHQ0Kd3vBQJjhKA5ORSAAAAAABAAIHBy
+b29mQGFyaWFkbmUuaWRodHRwczovL2Zvc3N0b2Rvbi5vcmcvQG10b3Jyb21lbwAK
+CRARZ1x0NCnd74sYAP9cd+GQFHYUdC8h5rinC8zlLfCSRmK4RmpynORvNUoHlwD/
+VHc1QKQygGJHkGUR/BzBwhvy9V8VFUXLHEkix/5EAgy4MwRaOiyTFgkrBgEEAdpH
+DwEBB0ALDo3UpmTEMnSfibzebWay/yHw5PQ3M6dikohuznLdD4h+BBgWCAAmAhsg
+FiEEDK2qz3D2TGVOExsxEWdcdDQp3e8FAmFzE3sFCRCe6GgACgkQEWdcdDQp3e+l
+MgEAqNJOWIvlmwvgDUnM49o9Xy+ev0ApfCcpd+M9Viv3HmwA/RFNVLW5Q3ClhUPd
+RHRSgOI/txQSMCX24h1R4g5Ck3kPuDgEWjorXBIKKwYBBAGXVQEFAQEHQG8U6zt8
+dY35U3jMoulSJrEfc2IawNGNum7hdNwGarUhAwEIB4h+BBgWCAAmAhsMFiEEDK2q
+z3D2TGVOExsxEWdcdDQp3e8FAmFzE3sFCRCe6Z8ACgkQEWdcdDQp3e/FnQD/ROjp
+SAtLo4A2PbQ9Awk4V/dW2iSGXT+c946xwd6v+toA/R3VhNaxQpVjqpwLYYhV2T+E
+8i1/tU0JWRZh4/DUvY0P
+=mnMt
+-----END PGP PUBLIC KEY BLOCK-----
r8168
============================ rpmlint session starts ============================ rpmlint: 2.6.1 configuration: /opt/testing/lib64/python3.13/rpmlint/configdefaults.toml /opt/testing/share/rpmlint/cron-whitelist.toml /opt/testing/share/rpmlint/dbus-services.toml /opt/testing/share/rpmlint/device-files-whitelist.toml /opt/testing/share/rpmlint/licenses.toml /opt/testing/share/rpmlint/opensuse.toml /opt/testing/share/rpmlint/pam-modules.toml /opt/testing/share/rpmlint/permissions-whitelist.toml /opt/testing/share/rpmlint/pie-executables.toml /opt/testing/share/rpmlint/polkit-rules-whitelist.toml /opt/testing/share/rpmlint/scoring.toml /opt/testing/share/rpmlint/security.toml /opt/testing/share/rpmlint/sudoers-whitelist.toml /opt/testing/share/rpmlint/sysctl-whitelist.toml /opt/testing/share/rpmlint/systemd-tmpfiles.toml /opt/testing/share/rpmlint/users-groups.toml /opt/testing/share/rpmlint/world-writable-whitelist.toml /opt/testing/share/rpmlint/zypper-plugins.toml checks: 41, packages: 3 r8168-kmp-default.x86_64: E: suse-zypp-packageand packageand(kernel-default:r8168) The 'packageand(package1:package2)' syntax is obsolete, please use boolean dependencies like: 'Supplements: (package1 and package2)' r8168.spec: W: no-%check-section The spec file does not contain an %check section. Please check if the package has a testsuite and what it takes to enable the testsuite as part of the package build. If it is not possible to run it in the build environment (OBS/koji) or no testsuite exists, then please ignore this warning. You should not insert an empty %check section. Check time report (>1% & >0.1s): Check Duration (in s) Fraction (in %) Checked files ExtractRpm 0.3 86.9 TOTAL 0.4 100.0 3 packages and 0 specfiles checked; 1 errors, 1 warnings, 15 filtered, 1 badness; has taken 0.4 s
Request History
bitstreamout created request about 1 year ago
- Update to new version r8168-8.052.01
- Remove patches now upstream
* skb_gso_segment.patch
* r8168-support-linux-6.1.0.patch
- Port patches
* r8168-configuration.patch
* r8168-kernel_version.patch
* r8168-support-dev0x8136.patch
* r8168-support-linux-5.19.patch
* r8168-support-linux-L15.5.patch
- Add r8168.keyring and signature of tar ball to check tar ball
- Add patch r8168-gcc14.patch
* Avoid gcc14 trouble
* Switch from deprecated strlcpy() to strscpy()
- Use %patch -P N instead of deprecated %patchN.
bitstreamout accepted request about 1 year ago
Fine