From 7086a36e68067cdc9bd3013e3a71c4908748468f Mon Sep 17 00:00:00 2001 From: Revanth Kumar Uppala Date: Wed, 24 Apr 2024 16:32:27 +0530 Subject: [PATCH] r8168: update driver to 8.053.00 - Update realtek r8168 driver version to 8.053.00 - This update adds support till K6.8 Bug 4471899 Change-Id: I77734753b8ad9ca108afccda609d29ea73c848f5 Signed-off-by: Revanth Kumar Uppala Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3123343 Reviewed-by: Brad Griffis GVS: buildbot_gerritrpt --- drivers/net/ethernet/realtek/Makefile | 101 +- drivers/net/ethernet/realtek/r8168/Makefile | 195 + .../net/ethernet/realtek/{ => r8168}/r8168.h | 804 +- .../ethernet/realtek/{ => r8168}/r8168_asf.c | 16 +- .../ethernet/realtek/{ => r8168}/r8168_asf.h | 2 +- .../ethernet/realtek/{ => r8168}/r8168_dash.h | 3 +- .../realtek/{ => r8168}/r8168_fiber.h | 2 +- .../realtek/{ => r8168}/r8168_firmware.c | 2 +- .../realtek/{ => r8168}/r8168_firmware.h | 2 +- .../ethernet/realtek/{ => r8168}/r8168_n.c | 8226 ++++++++++------- .../realtek/{ => r8168}/r8168_realwow.h | 2 +- .../net/ethernet/realtek/r8168/r8168_rss.c | 500 + .../net/ethernet/realtek/r8168/r8168_rss.h | 72 + .../ethernet/realtek/{ => r8168}/rtl_eeprom.c | 13 +- .../ethernet/realtek/{ => r8168}/rtl_eeprom.h | 2 +- .../ethernet/realtek/{ => r8168}/rtltool.c | 69 +- .../ethernet/realtek/{ => r8168}/rtltool.h | 2 +- 17 files changed, 6618 insertions(+), 3395 deletions(-) create mode 100755 drivers/net/ethernet/realtek/r8168/Makefile rename drivers/net/ethernet/realtek/{ => r8168}/r8168.h (73%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_asf.c (97%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_asf.h (99%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_dash.h (98%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_fiber.h (97%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_firmware.c (99%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_firmware.h (97%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_n.c (86%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/r8168_realwow.h (98%) mode change 100644 => 100755 create mode 100755 drivers/net/ethernet/realtek/r8168/r8168_rss.c create mode 100755 drivers/net/ethernet/realtek/r8168/r8168_rss.h rename drivers/net/ethernet/realtek/{ => r8168}/rtl_eeprom.c (96%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/rtl_eeprom.h (97%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/rtltool.c (82%) mode change 100644 => 100755 rename drivers/net/ethernet/realtek/{ => r8168}/rtltool.h (97%) mode change 100644 => 100755 diff --git a/drivers/net/ethernet/realtek/Makefile b/drivers/net/ethernet/realtek/Makefile index b797755b..f3211809 100644 --- a/drivers/net/ethernet/realtek/Makefile +++ b/drivers/net/ethernet/realtek/Makefile @@ -1,100 +1,7 @@ -# 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) 2022 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 . -# -# Author: -# Realtek NIC software team -# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan -# -################################################################################ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved. -################################################################################ -# This product is covered by one or more of the following patents: -# US6,570,884, US6,115,776, and US6,327,625. -################################################################################ - -CONFIG_SOC_LAN = n -ENABLE_FIBER_SUPPORT = n -ENABLE_REALWOW_SUPPORT = n -ENABLE_DASH_SUPPORT = n -ENABLE_DASH_PRINTER_SUPPORT = n -CONFIG_DOWN_SPEED_100 = n -CONFIG_ASPM = y -ENABLE_S5WOL = y -ENABLE_S5_KEEP_CURR_MAC = n -ENABLE_EEE = y -ENABLE_S0_MAGIC_PACKET = n -CONFIG_DYNAMIC_ASPM = y -ENABLE_USE_FIRMWARE_FILE = n -CONFIG_CTAP_SHORT_OFF = n - -obj-m += r8168.o - -r8168-objs += r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o -ifeq ($(CONFIG_SOC_LAN), y) - EXTRA_CFLAGS += -DCONFIG_SOC_LAN -endif -ifeq ($(ENABLE_FIBER_SUPPORT), y) - r8168-objs += r8168_fiber.o - EXTRA_CFLAGS += -DENABLE_FIBER_SUPPORT -endif -ifeq ($(ENABLE_REALWOW_SUPPORT), y) - r8168-objs += r8168_realwow.o - EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT -endif -ifeq ($(ENABLE_DASH_SUPPORT), y) - r8168-objs += r8168_dash.o - EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -endif -ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y) - r8168-objs += r8168_dash.o - EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT -endif -EXTRA_CFLAGS += -DCONFIG_R8168_NAPI -EXTRA_CFLAGS += -DCONFIG_R8168_VLAN -ifeq ($(CONFIG_DOWN_SPEED_100), y) - EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100 -endif -ifeq ($(CONFIG_ASPM), y) - EXTRA_CFLAGS += -DCONFIG_ASPM -endif -ifeq ($(ENABLE_S5WOL), y) - EXTRA_CFLAGS += -DENABLE_S5WOL -endif -ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y) - EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC -endif -ifeq ($(ENABLE_EEE), y) - EXTRA_CFLAGS += -DENABLE_EEE -endif -ifeq ($(ENABLE_S0_MAGIC_PACKET), y) - EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET -endif -ifeq ($(CONFIG_DYNAMIC_ASPM), y) - EXTRA_CFLAGS += -DCONFIG_DYNAMIC_ASPM -endif -ifeq ($(ENABLE_USE_FIRMWARE_FILE), y) - r8168-objs += r8168_firmware.o - EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE -endif -ifeq ($(CONFIG_CTAP_SHORT_OFF), y) - EXTRA_CFLAGS += -DCONFIG_CTAP_SHORT_OFF +ifeq ($(shell expr \( $(VERSION) \) \* 10000 + \( $(PATCHLEVEL) \) \* 100 + \( $(SUBLEVEL) \) \<= 60804), 1) +obj-m += r8168/ endif diff --git a/drivers/net/ethernet/realtek/r8168/Makefile b/drivers/net/ethernet/realtek/r8168/Makefile new file mode 100755 index 00000000..6b27dbc7 --- /dev/null +++ b/drivers/net/ethernet/realtek/r8168/Makefile @@ -0,0 +1,195 @@ +# 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) 2024 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 . +# +# Author: +# Realtek NIC software team +# 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. +################################################################################ + +CONFIG_SOC_LAN = n +ENABLE_FIBER_SUPPORT = n +ENABLE_REALWOW_SUPPORT = n +ENABLE_DASH_SUPPORT = n +ENABLE_DASH_PRINTER_SUPPORT = n +CONFIG_DOWN_SPEED_100 = n +CONFIG_ASPM = y +ENABLE_S5WOL = y +ENABLE_S5_KEEP_CURR_MAC = n +ENABLE_EEE = y +ENABLE_S0_MAGIC_PACKET = n +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_n.o r8168_asf.o rtl_eeprom.o rtltool.o + ifeq ($(CONFIG_SOC_LAN), y) + EXTRA_CFLAGS += -DCONFIG_SOC_LAN + endif + ifeq ($(ENABLE_FIBER_SUPPORT), y) + r8168-objs += r8168_fiber.o + EXTRA_CFLAGS += -DENABLE_FIBER_SUPPORT + endif + ifeq ($(ENABLE_REALWOW_SUPPORT), y) + r8168-objs += r8168_realwow.o + EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT + endif + ifeq ($(ENABLE_DASH_SUPPORT), y) + r8168-objs += r8168_dash.o + EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT + endif + ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y) + r8168-objs += r8168_dash.o + EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT + endif + 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 + endif + ifeq ($(CONFIG_ASPM), y) + EXTRA_CFLAGS += -DCONFIG_ASPM + endif + ifeq ($(ENABLE_S5WOL), y) + EXTRA_CFLAGS += -DENABLE_S5WOL + endif + ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y) + EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC + endif + ifeq ($(ENABLE_EEE), y) + EXTRA_CFLAGS += -DENABLE_EEE + endif + ifeq ($(ENABLE_S0_MAGIC_PACKET), y) + EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET + endif + ifeq ($(CONFIG_DYNAMIC_ASPM), y) + EXTRA_CFLAGS += -DCONFIG_DYNAMIC_ASPM + endif + ifeq ($(ENABLE_USE_FIRMWARE_FILE), y) + r8168-objs += r8168_firmware.o + EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE + endif + 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 + PWD :=$(shell pwd) + DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net/ethernet -name realtek -type d) + ifeq ($(DRIVERDIR),) + DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net -name realtek -type d) + endif + ifeq ($(DRIVERDIR),) + DRIVERDIR := $(BASEDIR)/kernel/drivers/net + endif + RTKDIR := $(subst $(BASEDIR)/,,$(DRIVERDIR)) + + KERNEL_GCC_VERSION := $(shell cat /proc/version | sed -n 's/.*gcc version \([[:digit:]]\.[[:digit:]]\.[[:digit:]]\).*/\1/p') + CCVERSION = $(shell $(CC) -dumpversion) + + KVER = $(shell uname -r) + KMAJ = $(shell echo $(KVER) | \ + sed -e 's/^\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*.*/\1/') + KMIN = $(shell echo $(KVER) | \ + sed -e 's/^[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*.*/\1/') + KREV = $(shell echo $(KVER) | \ + sed -e 's/^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/') + + kver_ge = $(shell \ + echo test | awk '{if($(KMAJ) < $(1)) {print 0} else { \ + if($(KMAJ) > $(1)) {print 1} else { \ + if($(KMIN) < $(2)) {print 0} else { \ + if($(KMIN) > $(2)) {print 1} else { \ + if($(KREV) < $(3)) {print 0} else { print 1 } \ + }}}}}' \ + ) + +.PHONY: all +all: print_vars clean modules install + +print_vars: + @echo + @echo "CC: " $(CC) + @echo "CCVERSION: " $(CCVERSION) + @echo "KERNEL_GCC_VERSION: " $(KERNEL_GCC_VERSION) + @echo "KVER: " $(KVER) + @echo "KMAJ: " $(KMAJ) + @echo "KMIN: " $(KMIN) + @echo "KREV: " $(KREV) + @echo "BASEDIR: " $(BASEDIR) + @echo "DRIVERDIR: " $(DRIVERDIR) + @echo "PWD: " $(PWD) + @echo "RTKDIR: " $(RTKDIR) + @echo + +.PHONY:modules +modules: +#ifeq ($(call kver_ge,5,0,0),1) + $(MAKE) -C $(KERNELDIR) M=$(PWD) modules +#else +# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules +#endif + +.PHONY:clean +clean: +#ifeq ($(call kver_ge,5,0,0),1) + $(MAKE) -C $(KERNELDIR) M=$(PWD) clean +#else +# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean +#endif + +.PHONY:install +install: +#ifeq ($(call kver_ge,5,0,0),1) + $(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install +#else +# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install +#endif + +endif diff --git a/drivers/net/ethernet/realtek/r8168.h b/drivers/net/ethernet/realtek/r8168/r8168.h old mode 100644 new mode 100755 similarity index 73% rename from drivers/net/ethernet/realtek/r8168.h rename to drivers/net/ethernet/realtek/r8168/r8168.h index 4f5de483..a56399f7 --- a/drivers/net/ethernet/realtek/r8168.h +++ b/drivers/net/ethernet/realtek/r8168/r8168.h @@ -5,7 +5,7 @@ # 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) 2024 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 @@ -32,12 +32,85 @@ * US6,570,884, US6,115,776, and US6,327,625. ***********************************************************************************/ -#include - #include +#include +#include #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 +*/ + +#ifndef fallthrough +#define fallthrough +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) +static inline +ssize_t strscpy(char *dest, const char *src, size_t count) +{ + long res = 0; + + if (count == 0) + return -E2BIG; + + while (count) { + char c; + + c = src[res]; + dest[res] = c; + if (!c) + return res; + res++; + count--; + } + + /* Hit buffer length without finding a NUL; force NUL-termination. */ + if (res) + dest[res-1] = '\0'; + + return -E2BIG; +} +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) +static inline unsigned char *skb_checksum_start(const struct sk_buff *skb) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) + return skb->head + skb->csum_start; +#else /* < 2.6.22 */ + return skb_transport_header(skb); +#endif +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, + unsigned int bytes) +{} +static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue, + unsigned int pkts, + unsigned int bytes) +{} +static inline void netdev_tx_reset_queue(struct netdev_queue *q) {} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0) +#define netdev_xmit_more() (0) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) +#define netif_testing_on(dev) +#define netif_testing_off(dev) +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) typedef int netdev_tx_t; @@ -132,11 +205,14 @@ do { \ #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 @@ -162,6 +238,10 @@ do { \ #define ENABLE_R8168_PROCFS #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#define ENABLE_R8168_SYSFS +#endif + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) #define NETIF_F_HW_VLAN_RX NETIF_F_HW_VLAN_CTAG_RX #define NETIF_F_HW_VLAN_TX NETIF_F_HW_VLAN_CTAG_TX @@ -321,7 +401,7 @@ do { \ #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" @@ -345,20 +425,25 @@ do { \ #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.10m_pll" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX +#define RTL8168_VERSION "8.053.00" 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 \n \ +r8168 Copyright (C) 2024 Realtek NIC software team \n \ This program comes with ABSOLUTELY NO WARRANTY; for details, please see . \n \ This is free software, and you are welcome to redistribute it under certain conditions; see . \n" #ifdef RTL8168_DEBUG #define assert(expr) \ if(!(expr)) { \ - printk( "Assertion failed! %s,%s,%s,line=%d\n", \ + printk("Assertion failed! %s,%s,%s,line=%d\n", \ #expr,__FILE__,__FUNCTION__,__LINE__); \ } #define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) @@ -430,9 +515,12 @@ This is free software, and you are welcome to redistribute it under certain cond #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 RTL8168_DASH_TIMEOUT (0) #define MAX_NUM_TX_DESC 1024 /* Maximum number of Tx descriptor registers */ #define MAX_NUM_RX_DESC 1024 /* Maximum number of Rx descriptor registers */ @@ -440,10 +528,17 @@ This is free software, and you are welcome to redistribute it under certain cond #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 @@ -521,9 +616,9 @@ This is free software, and you are welcome to redistribute it under certain cond /*****************************************************************************/ //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) -#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \ - (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \ - ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ))) +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)) || \ + ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)))) /* copied from linux kernel 2.6.20 include/linux/netdev.h */ #define NETDEV_ALIGN 32 #define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) @@ -568,13 +663,11 @@ typedef int *napi_budget; typedef struct napi_struct *napi_ptr; typedef int napi_budget; -#if defined(NV_NETIF_NAPI_ADD_WEIGHT_PRESENT) /* Linux v6.1 */ -#define RTL_NAPI_CONFIG(ndev, priv, function, weight) \ - netif_napi_add_weight(ndev, &priv->napi, function, weight) +#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 +#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; @@ -610,6 +703,23 @@ typedef int napi_budget; #define RTL_NAPI_DEL(priv) netif_napi_del(&priv->napi) #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +/*****************************************************************************/ +#ifdef CONFIG_R8168_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) napi_consume_skb(skb, budget) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); +#else +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) +#else //CONFIG_R8168_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); +#else +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); +#endif +#endif //CONFIG_R8168_NAPI + /*****************************************************************************/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) #ifdef __CHECKER__ @@ -644,7 +754,7 @@ extern void __chk_io_ptr(void __iomem *); /*****************************************************************************/ /* 2.5.28 => 2.4.23 */ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28)) static inline void _kc_synchronize_irq(void) { @@ -665,12 +775,12 @@ static inline void _kc_synchronize_irq(void) /*****************************************************************************/ /* 2.6.4 => 2.6.0 */ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)) #define MODULE_VERSION(_version) MODULE_INFO(version, _version) #endif /* 2.6.4 => 2.6.0 */ /*****************************************************************************/ /* 2.6.0 => 2.5.28 */ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) #define MODULE_INFO(version, _version) #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT #define CONFIG_E1000_DISABLE_PACKET_SPLIT 1 @@ -701,13 +811,13 @@ static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr) /*****************************************************************************/ /* 2.4.22 => 2.4.17 */ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)) #define pci_name(x) ((x)->slot_name) #endif /* 2.4.22 => 2.4.17 */ /*****************************************************************************/ /* 2.6.5 => 2.6.0 */ -#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)) #define pci_dma_sync_single_for_cpu pci_dma_sync_single #define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu #endif /* 2.6.5 => 2.6.0 */ @@ -1103,13 +1213,20 @@ enum RTL8168_registers { 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, @@ -1130,6 +1247,14 @@ enum RTL8168_registers { 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 { @@ -1145,6 +1270,8 @@ enum RTL8168_register_content { TxOK = 0x0004, RxErr = 0x0002, RxOK = 0x0001, + RxDU1 = 0x0002, + RxOK1 = 0x0001, /* RxStatusDesc */ RxRWT = (1 << 22), @@ -1189,6 +1316,7 @@ enum RTL8168_register_content { 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, @@ -1443,6 +1571,17 @@ enum bits { 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, @@ -1463,9 +1602,34 @@ struct RxDesc { 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; + unsigned int bytecount; + unsigned short gso_segs; u8 __pad[sizeof(void *) - sizeof(u32)]; }; @@ -1489,6 +1653,29 @@ struct pci_resource { u32 pci_sn_h; }; +enum r8168_dash_req_flag { + R8168_RCV_REQ_SYS_OK = 0, + R8168_RCV_REQ_DASH_OK, + R8168_SEND_REQ_HOST_OK, + R8168_CMAC_RESET, + R8168_CMAC_DISALE_RX_FLAG_MAX, + R8168_DASH_REQ_FLAG_MAX +}; + +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_TASK_DASH_CHECK_PENDING, + R8168_FLAG_MAX +}; + +enum r8168_sysfs_flag { + R8168_SYSFS_RTL_ADV = 0, + R8168_SYSFS_FLAG_MAX +}; + /* Flow Control Settings */ enum rtl8168_fc_mode { rtl8168_fc_none = 0, @@ -1498,17 +1685,224 @@ enum rtl8168_fc_mode { 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; + struct net_device *netdev; + 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_skb[NUM_TX_DESC]; /* Tx data buffers */ + + u16 tdsar_reg; /* Transmit Descriptor Start Address */ +}; + +struct rtl8168_rx_ring { + void* priv; + struct net_device *netdev; + 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 RxDescPhyAddr[MAX_NUM_RX_DESC]; /* Rx desc physical address*/ + //dma_addr_t RxPhyAddr; + struct sk_buff *Rx_skbuff[MAX_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 name[IFNAMSIZ + 10]; +}; + +#pragma pack(1) +struct rtl8168_regs { + //00 + u8 mac_id[6]; + u16 reg_06; + u8 mar[8]; + //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_io[R8168_MAC_REGS_SIZE]; + + struct rtl8168_regs mac_reg; + }; + u16 pcie_phy[R8168_EPHY_REGS_SIZE/2]; + u16 eth_phy[R8168_PHY_REGS_SIZE/2]; + u32 eri_reg[R8168_ERI_REGS_SIZE/4]; + u32 pci_reg[R8168_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_key[RTL8168_RSS_KEY_SIZE]; + u8 rss_i_table[RTL8168_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 r8168napi[R8168_MAX_MSIX_VEC]; + struct r8168_irq irq_tbl[R8168_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; @@ -1517,23 +1911,35 @@ struct rtl8168_private { 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_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ - struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */ + //struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ + //struct ring_info tx_skb[MAX_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_ring[R8168_MAX_TX_QUEUES]; // non-ring-lib tx ring + struct rtl8168_rx_ring rx_ring[R8168_MAX_RX_QUEUES]; // non-ring-lib rx ring +#ifdef ENABLE_LIB_SUPPORT + struct blocking_notifier_head lib_nh; + struct rtl8168_ring lib_tx_ring[R8168_MAX_TX_QUEUES]; // ring-lib tx ring + struct rtl8168_ring lib_rx_ring[R8168_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; @@ -1541,7 +1947,8 @@ struct rtl8168_private { u16 cp_cmd; u16 intr_mask; u16 timer_intr_mask; - int irq; + u16 isr_reg[R8168_MAX_MSIX_VEC]; + u16 imr_reg[R8168_MAX_MSIX_VEC]; int phy_auto_nego_reg; int phy_1000_ctrl_reg; u8 org_mac_addr[NODE_ADDRESS_SIZE]; @@ -1574,10 +1981,17 @@ struct rtl8168_private { 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; + struct work_struct dash_task; #else - struct delayed_work task; + struct delayed_work reset_task; + struct delayed_work esd_task; + struct delayed_work linkchg_task; + struct delayed_work dash_task; #endif + DECLARE_BITMAP(task_flags, R8168_FLAG_MAX); unsigned features; u8 org_pci_offset_99; @@ -1648,6 +2062,8 @@ struct rtl8168_private { u16 BackupPhyFuseDout_47_32; u16 BackupPhyFuseDout_63_48; + u8 ring_lib_enabled; + const char *fw_name; struct rtl8168_fw *rtl_fw; u32 ocp_base; @@ -1657,8 +2073,8 @@ struct rtl8168_private { 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 */ + DECLARE_BITMAP(dash_req_flags, R8168_DASH_REQ_FLAG_MAX); #ifdef ENABLE_DASH_SUPPORT u16 AfterRecvFromFwBufLen; @@ -1666,51 +2082,45 @@ struct rtl8168_private { u16 AfterSendToFwBufLen; u8 AfterSendToFwBuf[SEND_TO_FW_BUF_SIZE]; u16 SendToFwBufferLen; - u32 SizeOfSendToFwBuffer ; - u32 SizeOfSendToFwBufferMemAlloc ; - u32 NumOfSendToFwBuffer ; + u32 SizeOfSendToFwBuffer; + u32 SizeOfSendToFwBufferMemAlloc; + u32 NumOfSendToFwBuffer; u8 OobReq; u8 OobAck; u32 OobReqComplete; u32 OobAckComplete; - u8 RcvFwReqSysOkEvt; - u8 RcvFwDashOkEvt; - u8 SendFwHostOkEvt; - - u8 DashFwDisableRx; - - void *SendToFwBuffer ; - dma_addr_t SendToFwBufferPhy ; + void *SendToFwBuffer; + dma_addr_t SendToFwBufferPhy; u8 SendingToFw; PTX_DASH_SEND_FW_DESC TxDashSendFwDesc; dma_addr_t TxDashSendFwDescPhy; u32 SizeOfTxDashSendFwDescMemAlloc; - u32 SizeOfTxDashSendFwDesc ; - u32 NumTxDashSendFwDesc ; - u32 CurrNumTxDashSendFwDesc ; - u32 LastSendNumTxDashSendFwDesc ; + u32 SizeOfTxDashSendFwDesc; + u32 NumTxDashSendFwDesc; + u32 CurrNumTxDashSendFwDesc; + u32 LastSendNumTxDashSendFwDesc; - u32 NumRecvFromFwBuffer ; - u32 SizeOfRecvFromFwBuffer ; - u32 SizeOfRecvFromFwBufferMemAlloc ; - void *RecvFromFwBuffer ; - dma_addr_t RecvFromFwBufferPhy ; + u32 NumRecvFromFwBuffer; + u32 SizeOfRecvFromFwBuffer; + u32 SizeOfRecvFromFwBufferMemAlloc; + void *RecvFromFwBuffer; + dma_addr_t RecvFromFwBufferPhy; PRX_DASH_FROM_FW_DESC RxDashRecvFwDesc; dma_addr_t RxDashRecvFwDescPhy; u32 SizeOfRxDashRecvFwDescMemAlloc; - u32 SizeOfRxDashRecvFwDesc ; - u32 NumRxDashRecvFwDesc ; - u32 CurrNumRxDashRecvFwDesc ; + u32 SizeOfRxDashRecvFwDesc; + u32 NumRxDashRecvFwDesc; + u32 CurrNumRxDashRecvFwDesc; u8 DashReqRegValue; u16 HostReqValue; u32 CmacResetIsrCounter; - u8 CmacResetIntr ; - u8 CmacResetting ; - u8 CmacOobIssueCmacReset ; + u8 CmacResetIntr; + u8 CmacResetting; + u8 CmacOobIssueCmacReset; u32 CmacResetbyFwCnt; #if defined(ENABLE_DASH_PRINTER_SUPPORT) @@ -1733,17 +2143,152 @@ struct rtl8168_private { //Realwow-------------- #endif //ENABLE_REALWOW_SUPPORT - u32 eee_adv_t; - u8 eee_enabled; + struct ethtool_eee eee; u32 dynamic_aspm_packet_count; #ifdef ENABLE_R8168_PROCFS //Procfs support struct proc_dir_entry *proc_dir; + struct proc_dir_entry *proc_dir_debug; + struct proc_dir_entry *proc_dir_test; #endif +#ifdef ENABLE_R8168_SYSFS + //sysfs support + DECLARE_BITMAP(sysfs_flag, R8168_SYSFS_FLAG_MAX); + u32 testmode; +#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_key[RTL8168_RSS_KEY_SIZE]; +#define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128 + u8 rss_indir_tbl[RTL8168_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_ring[i].enabled) + count++; + + return count; +} + +static inline unsigned int +rtl8168_num_lib_rx_rings(struct rtl8168_private *tp) +{ + int count, i; + + for (count = 0, i = 1; i < tp->HwSuppNumRxQueues; i++) + if(tp->lib_rx_ring[i].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_ring[i]; + 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 = 1; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8168_ring *ring = &tp->lib_rx_ring[i]; + 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 struct netdev_queue *txring_txq(const struct rtl8168_tx_ring *ring) +{ + return netdev_get_tx_queue(ring->netdev, ring->index); +} + +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, @@ -1787,6 +2332,8 @@ enum mcfg { CFG_METHOD_33, CFG_METHOD_34, CFG_METHOD_35, + CFG_METHOD_36, + CFG_METHOD_37, CFG_METHOD_MAX, CFG_METHOD_DEFAULT = 0xFF }; @@ -1825,14 +2372,17 @@ enum mcfg { #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 @@ -1870,11 +2420,109 @@ void rtl8168_dash2_enable_tx(struct rtl8168_private *tp); 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); -#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0 ) +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; +} + +#ifdef ENABLE_DASH_SUPPORT + +static inline void +rtl8168_enable_dash2_interrupt(struct rtl8168_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBIMR0, (ISRIMR_DASH_TYPE2_ROK | ISRIMR_DASH_TYPE2_TOK | ISRIMR_DASH_TYPE2_TDU | ISRIMR_DASH_TYPE2_RDU | ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE)); + } +} + +static inline void +rtl8168_disable_dash2_interrupt(struct rtl8168_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBIMR0, 0); + } +} +#endif + +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_reg[0], 0x0000); +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8168_disable_dash2_interrupt(tp); +#endif + } else + RTL_W8(tp, tp->imr_reg[message_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_reg[0], tp->intr_mask); +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8168_enable_dash2_interrupt(tp); +#endif + } else { + RTL_W8(tp, tp->imr_reg[message_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) diff --git a/drivers/net/ethernet/realtek/r8168_asf.c b/drivers/net/ethernet/realtek/r8168/r8168_asf.c old mode 100644 new mode 100755 similarity index 97% rename from drivers/net/ethernet/realtek/r8168_asf.c rename to drivers/net/ethernet/realtek/r8168/r8168_asf.c index 29d7f5ae..ed999d61 --- a/drivers/net/ethernet/realtek/r8168_asf.c +++ b/drivers/net/ethernet/realtek/r8168/r8168_asf.c @@ -5,7 +5,7 @@ # 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) 2024 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 @@ -60,7 +60,6 @@ int rtl8168_asf_ioctl(struct net_device *dev, 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; @@ -68,8 +67,6 @@ int rtl8168_asf_ioctl(struct net_device *dev, 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); @@ -192,12 +189,9 @@ int rtl8168_asf_ioctl(struct net_device *dev, 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; @@ -390,10 +384,10 @@ void rtl8168_asf_rw_systemid(struct rtl8168_private *tp, int arg, unsigned int * int i; if (arg == ASF_GET) - for (i = 0; i < SYSID_LEN ; i++) + for (i = 0; i < SYSID_LEN; i++) data[i] = rtl8168_eri_read(tp, SysID + i, RW_ONE_BYTE, ERIAR_ASF); else /* arg == ASF_SET */ - for (i = 0; i < SYSID_LEN ; i++) + for (i = 0; i < SYSID_LEN; i++) rtl8168_eri_write(tp, SysID + i, RW_ONE_BYTE, data[i], ERIAR_ASF); } @@ -414,9 +408,9 @@ void rtl8168_asf_rw_uuid(struct rtl8168_private *tp, int arg, unsigned int *data int i, j; if (arg == ASF_GET) - for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++) + for (i = UUID_LEN - 1, j = 0; i >= 0; i--, j++) data[j] = rtl8168_eri_read(tp, UUID + i, RW_ONE_BYTE, ERIAR_ASF); else /* arg == ASF_SET */ - for (i = UUID_LEN - 1, j = 0; i >= 0 ; i--, j++) + for (i = UUID_LEN - 1, j = 0; i >= 0; i--, j++) rtl8168_eri_write(tp, UUID + i, RW_ONE_BYTE, data[j], ERIAR_ASF); } diff --git a/drivers/net/ethernet/realtek/r8168_asf.h b/drivers/net/ethernet/realtek/r8168/r8168_asf.h old mode 100644 new mode 100755 similarity index 99% rename from drivers/net/ethernet/realtek/r8168_asf.h rename to drivers/net/ethernet/realtek/r8168/r8168_asf.h index 4c532ec2..b1fdd94b --- a/drivers/net/ethernet/realtek/r8168_asf.h +++ b/drivers/net/ethernet/realtek/r8168/r8168_asf.h @@ -5,7 +5,7 @@ # 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) 2024 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 diff --git a/drivers/net/ethernet/realtek/r8168_dash.h b/drivers/net/ethernet/realtek/r8168/r8168_dash.h old mode 100644 new mode 100755 similarity index 98% rename from drivers/net/ethernet/realtek/r8168_dash.h rename to drivers/net/ethernet/realtek/r8168/r8168_dash.h index 09477530..2c2174e1 --- a/drivers/net/ethernet/realtek/r8168_dash.h +++ b/drivers/net/ethernet/realtek/r8168/r8168_dash.h @@ -5,7 +5,7 @@ # 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) 2024 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 @@ -247,6 +247,7 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2; #define RTL_CMAC_R32(tp, reg) ((unsigned long) readl (tp->cmac_ioaddr + (reg))) int rtl8168_dash_ioctl(struct net_device *dev, struct ifreq *ifr); +bool CheckDashInterrupt(struct net_device *dev, u16 status); void HandleDashInterrupt(struct net_device *dev); int AllocateDashShareMemory(struct net_device *dev); void FreeAllocatedDashShareMemory(struct net_device *dev); diff --git a/drivers/net/ethernet/realtek/r8168_fiber.h b/drivers/net/ethernet/realtek/r8168/r8168_fiber.h old mode 100644 new mode 100755 similarity index 97% rename from drivers/net/ethernet/realtek/r8168_fiber.h rename to drivers/net/ethernet/realtek/r8168/r8168_fiber.h index 6a01b399..9e18cbf8 --- a/drivers/net/ethernet/realtek/r8168_fiber.h +++ b/drivers/net/ethernet/realtek/r8168/r8168_fiber.h @@ -5,7 +5,7 @@ # 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) 2024 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 diff --git a/drivers/net/ethernet/realtek/r8168_firmware.c b/drivers/net/ethernet/realtek/r8168/r8168_firmware.c old mode 100644 new mode 100755 similarity index 99% rename from drivers/net/ethernet/realtek/r8168_firmware.c rename to drivers/net/ethernet/realtek/r8168/r8168_firmware.c index 285498b5..f4b331a1 --- a/drivers/net/ethernet/realtek/r8168_firmware.c +++ b/drivers/net/ethernet/realtek/r8168/r8168_firmware.c @@ -5,7 +5,7 @@ # 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) 2024 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 diff --git a/drivers/net/ethernet/realtek/r8168_firmware.h b/drivers/net/ethernet/realtek/r8168/r8168_firmware.h old mode 100644 new mode 100755 similarity index 97% rename from drivers/net/ethernet/realtek/r8168_firmware.h rename to drivers/net/ethernet/realtek/r8168/r8168_firmware.h index 0954333f..8906e63c --- a/drivers/net/ethernet/realtek/r8168_firmware.h +++ b/drivers/net/ethernet/realtek/r8168/r8168_firmware.h @@ -5,7 +5,7 @@ # 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) 2024 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 diff --git a/drivers/net/ethernet/realtek/r8168_n.c b/drivers/net/ethernet/realtek/r8168/r8168_n.c old mode 100644 new mode 100755 similarity index 86% rename from drivers/net/ethernet/realtek/r8168_n.c rename to drivers/net/ethernet/realtek/r8168/r8168_n.c index aee003a5..ad63f42c --- a/drivers/net/ethernet/realtek/r8168_n.c +++ b/drivers/net/ethernet/realtek/r8168/r8168_n.c @@ -5,7 +5,7 @@ # 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) 2024 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 @@ -40,8 +40,6 @@ * Redefine it to just asm to enable successful compilation. */ -#include - #include #include #include @@ -83,6 +81,10 @@ #include #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10) +#include +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,10) */ + #include #include @@ -97,10 +99,6 @@ #include #endif -#if defined(NV_NET_GSO_H_PRESENT) -#include -#endif - #define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw" #define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw" #define FIRMWARE_8168E_1 "rtl_nic/rtl8168e-1.fw" @@ -119,13 +117,10 @@ #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" -/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). - The RTL chips use a 64 element hash table based on the Ethernet CRC. */ -static const int multicast_filter_limit = 32; - static const struct { const char *name; const char *fw_name; @@ -166,6 +161,8 @@ static const struct { [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", }, }; @@ -301,91 +298,103 @@ static const struct { _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), @@ -412,7 +421,6 @@ static struct pci_device_id rtl8168_pci_tbl[] = { 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; @@ -465,6 +473,11 @@ static int s0_magic_packet = 1; #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 "); MODULE_DESCRIPTION("RealTek RTL-8168 Gigabit Ethernet driver"); @@ -493,9 +506,6 @@ MODULE_PARM_DESC(s5wol, "Enable Shutdown Wake On Lan."); 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."); @@ -514,6 +524,9 @@ MODULE_PARM_DESC(s0_magic_packet, "Enable S0 Magic Packet."); 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)"); @@ -539,6 +552,7 @@ MODULE_FIRMWARE(FIRMWARE_8168EP_3); 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 @@ -548,6 +562,7 @@ MODULE_VERSION(RTL8168_VERSION); 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 @@ -558,10 +573,8 @@ static void rtl8168_link_timer(unsigned long __opaque); #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); @@ -569,10 +582,6 @@ static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance, struct pt_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); @@ -580,7 +589,17 @@ 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); @@ -592,8 +611,6 @@ static void rtl8168_rx_desc_init(struct rtl8168_private *tp); 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); @@ -607,9 +624,21 @@ static int rtl8168_poll(napi_ptr napi, napi_budget budget); #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); +static void rtl8168_dash_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); +static void rtl8168_dash_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); +void rtl8168_schedule_dash_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) { @@ -761,7 +790,7 @@ struct _kc_ethtool_ops { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) #ifndef SET_ETHTOOL_OPS #define SET_ETHTOOL_OPS(netdev,ops) \ - ( (netdev)->ethtool_ops = (ops) ) + ((netdev)->ethtool_ops = (ops)) #endif //SET_ETHTOOL_OPS #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) @@ -927,21 +956,234 @@ static inline struct mii_ioctl_data *if_mii(struct ifreq *rq) } #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 bool +rtl8168_sysfs_testmode_on(struct rtl8168_private *tp) +{ +#ifdef ENABLE_R8168_SYSFS + return !!tp->testmode; +#else + return 1; +#endif +} + +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, + int cp_len[RTL8168_CP_NUM]) +{ + int i; + u16 status; + int tmp_cp_len; + + status = RTL_R8(tp, PHYstatus); + if (status & LinkStatus) { + if (status & _10bps) { + tmp_cp_len = -1; + } else if (status & (_100bps | _1000bpsF)) { + rtl8168_mdio_write(tp, 0x1f, 0x0a88); + tmp_cp_len = rtl8168_mdio_read(tp, 0x10); + } else + tmp_cp_len = 0; + } else + tmp_cp_len = 0; + + if (tmp_cp_len > 0) + tmp_cp_len &= 0xff; + for (i=0; i RTL8168_MAX_SUPPORT_CP_LEN) + cp_len[i] = 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_status[RTL8168_CP_NUM], + bool poe_mode) +{ + u16 status; + int i; + + status = RTL_R8(tp, PHYstatus); + if (status & LinkStatus && !(status & (_10bps | _100bps))) { + for (i=0; iprivate; 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_info[tp->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_ring[0].cur_rx); + seq_printf(m, "dirty_rx0\t0x%x\n", tp->rx_ring[0].dirty_rx); + seq_printf(m, "rdu0\t0x%x\n", tp->rx_ring[0].rdu); + seq_printf(m, "cur_rx1\t0x%x\n", tp->rx_ring[1].cur_rx); + seq_printf(m, "dirty_rx1\t0x%x\n", tp->rx_ring[1].dirty_rx); + seq_printf(m, "rdu1\t0x%x\n", tp->rx_ring[1].rdu); + seq_printf(m, "cur_rx2\t0x%x\n", tp->rx_ring[2].cur_rx); + seq_printf(m, "dirty_rx2\t0x%x\n", tp->rx_ring[2].dirty_rx); + seq_printf(m, "rdu2\t0x%x\n", tp->rx_ring[2].rdu); + seq_printf(m, "cur_rx3\t0x%x\n", tp->rx_ring[3].cur_rx); + seq_printf(m, "dirty_rx3\t0x%x\n", tp->rx_ring[3].dirty_rx); + seq_printf(m, "rdu3\t0x%x\n", tp->rx_ring[3].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_ring[0].num_tx_desc); + seq_printf(m, "cur_tx0\t0x%x\n", tp->tx_ring[0].cur_tx); + seq_printf(m, "dirty_tx0\t0x%x\n", tp->tx_ring[0].dirty_tx); + seq_printf(m, "tdu0\t0x%x\n", tp->tx_ring[0].tdu); + seq_printf(m, "cur_tx1\t0x%x\n", tp->tx_ring[1].cur_tx); + seq_printf(m, "dirty_tx1\t0x%x\n", tp->tx_ring[1].dirty_tx); + seq_printf(m, "tdu1\t0x%x\n", tp->tx_ring[1].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); @@ -1030,22 +1287,39 @@ static int proc_get_driver_variable(struct seq_file *m, void *v) 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; @@ -1057,36 +1331,19 @@ static int proc_get_tally_counter(struct seq_file *m, void *v) 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)); @@ -1103,6 +1360,9 @@ static int proc_get_tally_counter(struct seq_file *m, void *v) 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; } @@ -1114,12 +1374,12 @@ static int proc_get_registers(struct seq_file *m, void *v) 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); @@ -1128,7 +1388,8 @@ static int proc_get_registers(struct seq_file *m, void *v) seq_printf(m, "%02x ", byte_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); seq_putc(m, '\n'); return 0; @@ -1140,12 +1401,12 @@ static int proc_get_pcie_phy(struct seq_file *m, void *v) 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); @@ -1154,7 +1415,8 @@ static int proc_get_pcie_phy(struct seq_file *m, void *v) seq_printf(m, "%04x ", word_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); seq_putc(m, '\n'); return 0; @@ -1166,12 +1428,12 @@ static int proc_get_eth_phy(struct seq_file *m, void *v) 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;) { @@ -1182,7 +1444,8 @@ static int proc_get_eth_phy(struct seq_file *m, void *v) seq_printf(m, "%04x ", word_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); seq_putc(m, '\n'); return 0; @@ -1194,7 +1457,6 @@ static int proc_get_extended_registers(struct seq_file *m, void *v) 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: @@ -1208,7 +1470,8 @@ static int proc_get_extended_registers(struct seq_file *m, void *v) 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); @@ -1217,7 +1480,8 @@ static int proc_get_extended_registers(struct seq_file *m, void *v) seq_printf(m, "%08x ", dword_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); seq_putc(m, '\n'); return 0; @@ -1229,12 +1493,12 @@ static int proc_get_pci_registers(struct seq_file *m, void *v) 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); @@ -1251,7 +1515,253 @@ static int proc_get_pci_registers(struct seq_file *m, void *v) 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, bool poe_mode) +{ + int i; + u16 status; + int cp_status[RTL8168_CP_NUM] = {0}; + int cp_len[RTL8168_CP_NUM] = {0}; + struct net_device *dev = m->private; + struct rtl8168_private *tp = netdev_priv(dev); + const char *pair_str[RTL8168_CP_NUM] = {"1-2", "3-6", "4-5", "7-8"}; + int ret; + + switch (tp->mcfg) { + case CFG_METHOD_30: + /* support */ + break; + default: + ret = -EOPNOTSUPP; + goto error_out; + } + + rtnl_lock(); + + if (!rtl8168_sysfs_testmode_on(tp)) { + seq_puts(m, "\nPlease turn on ""/sys/class/net//rtk_adv/testmode"".\n\n"); + ret = 0; + goto error_unlock; + } + + rtl8168_mdio_write(tp, 0x1f, 0x0000); + if (rtl8168_mdio_read(tp, MII_BMCR) & BMCR_PDOWN) { + ret = -EIO; + goto error_unlock; + } + + netif_testing_on(dev); + + 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_get_cp_status(tp, cp_status, poe_mode); + + seq_puts(m, "\npair\tlength\tstatus \tpp\n"); + + for (i=0; iprivate; + 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 ", pdword[i]); + } + + 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; knum_hw_tot_en_rx_rings; k++) { + seq_printf(m, "\ndump Q%d rx desc:%d\n", k, tp->num_rx_desc); + for (j=0; jnum_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 ", pdword[i]); + } + } + + seq_putc(m, '\n'); + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static 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 ", pdword[i]); + } + + 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; iHwSuppNumTxQueues; i++) { + struct rtl8168_tx_ring *ring = &tp->tx_ring[i]; + 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; iHwSuppNumTxQueues; i++) { + struct rtl8168_ring *ring = &tp->lib_tx_ring[i]; + 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; + void __iomem *ioaddr; + 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; + } + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(tp->pci_dev, 4), pci_resource_len(tp->pci_dev, 4)); + if (!ioaddr) + return -EFAULT; + + rtnl_lock(); + + seq_printf(m, "\ndump MSI-X Table. Total Entry %d. \n", tp->hw_supp_irq_nvecs); + + for (i=0; ihw_supp_irq_nvecs; i++) { + seq_printf(m, "\n%04x ", i); + for (j=0; j<4; j++) + seq_printf(m, "%08x ", + readl(ioaddr + i*0x10 + 4*j)); + } + + rtnl_unlock(); + + iounmap(ioaddr); seq_putc(m, '\n'); return 0; @@ -1264,13 +1774,13 @@ static int proc_get_driver_variable(char *page, char **start, { 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"); @@ -1280,12 +1790,27 @@ static int proc_get_driver_variable(char *page, char **start, "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" @@ -1346,11 +1871,28 @@ static int proc_get_driver_variable(char *page, char **start, "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) @@ -1363,11 +1905,26 @@ static int proc_get_driver_variable(char *page, char **start, rtl_chip_info[tp->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_ring[0].cur_rx, + tp->rx_ring[0].dirty_rx, + tp->rx_ring[0].rdu, + tp->rx_ring[1].cur_rx, + tp->rx_ring[1].dirty_rx, + tp->rx_ring[1].rdu, + tp->rx_ring[2].cur_rx, + tp->rx_ring[2].dirty_rx, + tp->rx_ring[2].rdu, + tp->rx_ring[3].cur_rx, + tp->rx_ring[3].dirty_rx, + tp->rx_ring[3].rdu, + tp->rx_fifo_of, + tp->tx_ring[0].num_tx_desc, + tp->tx_ring[0].cur_tx, + tp->tx_ring[0].dirty_tx, + tp->tx_ring[0].tdu, + tp->tx_ring[1].cur_tx, + tp->tx_ring[1].dirty_tx, + tp->tx_ring[1].tdu, tp->rx_buf_sz, tp->esd_flag, tp->pci_cfg_is_read, @@ -1424,23 +1981,39 @@ static int proc_get_driver_variable(char *page, char **start, 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) dev->perm_addr, #endif - dev->dev_addr - ); - spin_unlock_irqrestore(&tp->lock, flags); + dev->dev_addr); + + rtnl_unlock(); len += snprintf(page + len, count - len, "\n"); @@ -1458,37 +2031,22 @@ static int proc_get_tally_counter(char *page, char **start, 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"); @@ -1519,11 +2077,12 @@ static int proc_get_tally_counter(char *page, char **start, le64_to_cpu(counters->rx_broadcast), le32_to_cpu(counters->rx_multicast), le16_to_cpu(counters->tx_aborted), - le16_to_cpu(counters->tx_underrun) - ); + le16_to_cpu(counters->tx_underrun)); len += snprintf(page + len, count - len, "\n"); -out: +out_unlock: + rtnl_unlock(); + *eof = 1; return len; } @@ -1537,14 +2096,14 @@ static int proc_get_registers(char *page, char **start, 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", @@ -1557,7 +2116,8 @@ static int proc_get_registers(char *page, char **start, byte_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); len += snprintf(page + len, count - len, "\n"); @@ -1573,14 +2133,14 @@ static int proc_get_pcie_phy(char *page, char **start, 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", @@ -1593,7 +2153,8 @@ static int proc_get_pcie_phy(char *page, char **start, word_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); len += snprintf(page + len, count - len, "\n"); @@ -1609,14 +2170,14 @@ static int proc_get_eth_phy(char *page, char **start, 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); @@ -1632,7 +2193,8 @@ static int proc_get_eth_phy(char *page, char **start, word_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); len += snprintf(page + len, count - len, "\n"); @@ -1648,7 +2210,6 @@ static int proc_get_extended_registers(char *page, char **start, 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) { @@ -1666,7 +2227,8 @@ static int proc_get_extended_registers(char *page, char **start, "\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", @@ -1679,7 +2241,8 @@ static int proc_get_extended_registers(char *page, char **start, dword_rd); } } - spin_unlock_irqrestore(&tp->lock, flags); + + rtnl_unlock(); len += snprintf(page + len, count - len, "\n"); out: @@ -1695,14 +2258,14 @@ static int proc_get_pci_registers(char *page, char **start, 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", @@ -1728,14 +2291,371 @@ static int proc_get_pci_registers(char *page, char **start, "\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, + bool poe_mode) +{ + int i; + u16 status; + int len = 0; + struct net_device *dev = data; + int cp_status[RTL8168_CP_NUM] = {0}; + int cp_len[RTL8168_CP_NUM] = {0}; + struct rtl8168_private *tp = netdev_priv(dev); + const char *pair_str[RTL8168_CP_NUM] = {"1-2", "3-6", "4-5", "7-8"}; + + switch (tp->mcfg) { + case CFG_METHOD_30: + /* support */ + break; + default: + return -EOPNOTSUPP; + } + + rtnl_lock(); + + if (!rtl8168_sysfs_testmode_on(tp)) { + len += snprintf(page + len, count - len, + "\nPlease turn on ""/sys/class/net//rtk_adv/testmode"".\n\n"); + goto out_unlock; + } + + 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_len(tp, cp_len); + + rtl8168_get_cp_status(tp, cp_status, poe_mode); + + len += snprintf(page + len, count - len, + "\npair\tlength\tstatus \tpp\n"); + + for (i=0; iRxDescArray) + 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 ", + pdword[i]); + } + + 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; knum_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; jnum_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 ", + pdword[i]); + } + } + + 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 ", + pdword[i]); + } + + 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_ring[0]; + + if (!ring->TxDescArray) + return -EOPNOTSUPP; + + rtnl_lock(); + + for (i=0; iHwSuppNumTxQueues; i++) { + struct rtl8168_tx_ring *ring = &tp->tx_ring[i]; + 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; iHwSuppNumTxQueues; i++) { + struct rtl8168_ring *ring = &tp->lib_tx_ring[i]; + 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; imcfg) { + case CFG_METHOD_1 ... CFG_METHOD_8: + return -EOPNOTSUPP; + default: + break; + } + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(tp->pci_dev, 4), pci_resource_len(tp->pci_dev, 4)); + if (!ioaddr) + return -EFAULT; + + rtnl_lock(); + + len += snprintf(page + len, count - len, + "\ndump MSI-X Table. Total Entry %d. \n", + tp->hw_supp_irq_nvecs); + + for (i=0; ihw_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 ", + readl(ioaddr + i*0x10 + 4*j)); + } + + 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 @@ -1755,11 +2675,11 @@ static void rtl8168_proc_module_init(void) static int rtl8168_proc_open(struct inode *inode, struct file *file) { struct net_device *dev = proc_get_parent_data(inode); -#if defined(NV_PDE_DATA_LOWER_CASE_PRESENT) /* Linux v5.17 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) int (*show)(struct seq_file *, void *) = pde_data(inode); #else int (*show)(struct seq_file *, void *) = PDE_DATA(inode); -#endif //NV_PDE_DATA_LOWER_CASE_PRESENT +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) return single_open(file, show, dev); } @@ -1786,7 +2706,7 @@ static const struct file_operations rtl8168_proc_fops = { * Table of proc files we need to create. */ struct rtl8168_proc_file { - char name[12]; + char name[16]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) int (*show)(struct seq_file *, void *); #else @@ -1794,7 +2714,7 @@ struct rtl8168_proc_file { #endif }; -static const struct rtl8168_proc_file rtl8168_proc_files[] = { +static const struct rtl8168_proc_file rtl8168_debug_proc_files[] = { { "driver_var", &proc_get_driver_variable }, { "tally", &proc_get_tally_counter }, { "registers", &proc_get_registers }, @@ -1802,58 +2722,134 @@ static const struct rtl8168_proc_file rtl8168_proc_files[] = { { "eth_phy", &proc_get_eth_phy }, { "ext_regs", &proc_get_extended_registers }, { "pci_regs", &proc_get_pci_registers }, + { "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 }, { "" } }; +static const struct rtl8168_proc_file rtl8168_test_proc_files[] = { + { "cdt", &proc_get_cable_info }, + { "cdt_poe", &proc_get_poe_cable_info }, + { "" } +}; + +#define R8168_PROC_DEBUG_DIR "debug" +#define R8168_PROC_TEST_DIR "test" + static void rtl8168_proc_init(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(dev); const struct rtl8168_proc_file *f; struct proc_dir_entry *dir; - if (rtl8168_proc && !tp->proc_dir) { + if (!rtl8168_proc) + return; + + if (tp->proc_dir_debug || tp->proc_dir_test) + return; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) - dir = proc_mkdir_data(dev->name, 0, rtl8168_proc, dev); - if (!dir) { - printk("Unable to initialize /proc/net/%s/%s\n", - MODULENAME, dev->name); - return; - } - - tp->proc_dir = dir; - proc_init_num++; - - for (f = rtl8168_proc_files; f->name[0]; f++) { - if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, - &rtl8168_proc_fops, f->show)) { - printk("Unable to initialize " - "/proc/net/%s/%s/%s\n", - MODULENAME, dev->name, f->name); - return; - } - } -#else - dir = proc_mkdir(dev->name, rtl8168_proc); - if (!dir) { - printk("Unable to initialize /proc/net/%s/%s\n", - MODULENAME, dev->name); - return; - } - - tp->proc_dir = dir; - proc_init_num++; - - for (f = rtl8168_proc_files; f->name[0]; f++) { - if (!create_proc_read_entry(f->name, S_IFREG | S_IRUGO, - dir, f->show, dev)) { - printk("Unable to initialize " - "/proc/net/%s/%s/%s\n", - MODULENAME, dev->name, f->name); - return; - } - } -#endif + dir = proc_mkdir_data(dev->name, 0, rtl8168_proc, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s\n", + MODULENAME, dev->name); + return; } + tp->proc_dir = dir; + proc_init_num++; + + /* create debug entry */ + dir = proc_mkdir_data(R8168_PROC_DEBUG_DIR, 0, tp->proc_dir, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_DEBUG_DIR); + return; + } + + tp->proc_dir_debug = dir; + for (f = rtl8168_debug_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8168_proc_fops, f->show)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_DEBUG_DIR, + f->name); + return; + } + } + + /* create test entry */ + dir = proc_mkdir_data(R8168_PROC_TEST_DIR, 0, tp->proc_dir, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_TEST_DIR); + return; + } + + tp->proc_dir_test = dir; + for (f = rtl8168_test_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8168_proc_fops, f->show)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_TEST_DIR, + f->name); + return; + } + } +#else + dir = proc_mkdir(dev->name, rtl8168_proc); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s\n", + MODULENAME, dev->name); + return; + } + + tp->proc_dir = dir; + proc_init_num++; + + /* create debug entry */ + dir = proc_mkdir(R8168_PROC_DEBUG_DIR, tp->proc_dir); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_DEBUG_DIR); + return; + } + + tp->proc_dir_debug = dir; + for (f = rtl8168_debug_proc_files; f->name[0]; f++) { + if (!create_proc_read_entry(f->name, S_IFREG | S_IRUGO, + dir, f->show, dev)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_DEBUG_DIR, + f->name); + return; + } + } + + /* create test entry */ + dir = proc_mkdir(R8168_PROC_TEST_DIR, tp->proc_dir); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_TEST_DIR); + return; + } + + tp->proc_dir_test = dir; + for (f = rtl8168_test_proc_files; f->name[0]; f++) { + if (!create_proc_read_entry(f->name, S_IFREG | S_IRUGO, + dir, f->show, dev)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s/%s\n", + MODULENAME, dev->name, R8168_PROC_TEST_DIR, + f->name); + return; + } + } +#endif } static void rtl8168_proc_remove(struct net_device *dev) @@ -1863,33 +2859,119 @@ static void rtl8168_proc_remove(struct net_device *dev) if (tp->proc_dir) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) remove_proc_subtree(dev->name, rtl8168_proc); - proc_init_num--; - #else const struct rtl8168_proc_file *f; struct rtl8168_private *tp = netdev_priv(dev); - for (f = rtl8168_proc_files; f->name[0]; f++) - remove_proc_entry(f->name, tp->proc_dir); + if (tp->proc_dir_debug) { + for (f = rtl8168_debug_proc_files; f->name[0]; f++) + remove_proc_entry(f->name, tp->proc_dir_debug); + remove_proc_entry(R8168_PROC_DEBUG_DIR, tp->proc_dir); + } + + if (tp->proc_dir_test) { + for (f = rtl8168_test_proc_files; f->name[0]; f++) + remove_proc_entry(f->name, tp->proc_dir_test); + remove_proc_entry(R8168_PROC_TEST_DIR, tp->proc_dir); + } remove_proc_entry(dev->name, rtl8168_proc); - proc_init_num--; #endif + proc_init_num--; + + tp->proc_dir_debug = NULL; + tp->proc_dir_test = NULL; tp->proc_dir = NULL; } } #endif //ENABLE_R8168_PROCFS +#ifdef ENABLE_R8168_SYSFS +/**************************************************************************** +* -----------------------------SYSFS STUFF------------------------- +***************************************************************************** +*/ +static ssize_t testmode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct net_device *netdev = to_net_dev(dev); + struct rtl8168_private *tp = netdev_priv(netdev); + + sprintf(buf, "%u\n", tp->testmode); + + return strlen(buf); +} + +static ssize_t testmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct net_device *netdev = to_net_dev(dev); + struct rtl8168_private *tp = netdev_priv(netdev); + u32 testmode; + + if (sscanf(buf, "%u\n", &testmode) != 1) + return -EINVAL; + + if (tp->testmode != testmode) { + rtnl_lock(); + tp->testmode = testmode; + rtnl_unlock(); + } + + return count; +} + +static DEVICE_ATTR_RW(testmode); + +static struct attribute *rtk_adv_attrs[] = { + &dev_attr_testmode.attr, + NULL +}; + +static struct attribute_group rtk_adv_grp = { + .name = "rtl_adv", + .attrs = rtk_adv_attrs, +}; + +static void rtl8168_sysfs_init(struct net_device *dev) +{ + struct rtl8168_private *tp = netdev_priv(dev); + int ret; + + /* init rtl_adv */ +#ifdef ENABLE_LIB_SUPPORT + tp->testmode = 0; +#else + tp->testmode = 1; +#endif //ENABLE_LIB_SUPPORT + + ret = sysfs_create_group(&dev->dev.kobj, &rtk_adv_grp); + if (ret < 0) + netif_warn(tp, probe, dev, "create rtk_adv_grp fail\n"); + else + set_bit(R8168_SYSFS_RTL_ADV, tp->sysfs_flag); +} + +static void rtl8168_sysfs_remove(struct net_device *dev) +{ + struct rtl8168_private *tp = netdev_priv(dev); + + if (test_and_clear_bit(R8168_SYSFS_RTL_ADV, tp->sysfs_flag)) + sysfs_remove_group(&dev->dev.kobj, &rtk_adv_grp); +} +#endif //ENABLE_R8168_SYSFS + static inline u16 map_phy_ocp_addr(u16 PageNum, u8 RegNum) { u16 OcpPageNum = 0; u8 OcpRegNum = 0; u16 OcpPhyAddress = 0; - if ( PageNum == 0 ) { - OcpPageNum = OCP_STD_PHY_BASE_PAGE + ( RegNum / 8 ); - OcpRegNum = 0x10 + ( RegNum % 8 ); + if (PageNum == 0) { + OcpPageNum = OCP_STD_PHY_BASE_PAGE + (RegNum / 8); + OcpRegNum = 0x10 + (RegNum % 8); } else { OcpPageNum = PageNum; OcpRegNum = RegNum; @@ -1897,7 +2979,7 @@ static inline u16 map_phy_ocp_addr(u16 PageNum, u8 RegNum) OcpPageNum <<= 4; - if ( OcpRegNum < 16 ) { + if (OcpRegNum < 16) { OcpPhyAddress = 0; } else { OcpRegNum -= 16; @@ -1981,9 +3063,8 @@ static void mdio_real_write(struct rtl8168_private *tp, { int i; - if (RegAddr == 0x1F) { + if (RegAddr == 0x1F) tp->cur_page = value; - } if (tp->mcfg == CFG_METHOD_11) { RTL_W32(tp, OCPDR, OCPDR_Write | @@ -2114,7 +3195,7 @@ static u32 rtl8168_mdio_real_read_phy_ocp(struct rtl8168_private *tp, } static u32 mdio_real_read(struct rtl8168_private *tp, - u32 RegAddr) + u32 RegAddr) { int i, value = 0; @@ -2207,17 +3288,15 @@ void rtl8168_clear_eth_phy_bit(struct rtl8168_private *tp, u8 addr, u16 mask) ClearAndSetEthPhyBit(tp, addr, mask, - 0 - ); + 0); } -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, 0, - mask - ); + mask); } void rtl8168_mac_ocp_write(struct rtl8168_private *tp, u16 reg_addr, u16 value) @@ -2297,8 +3376,7 @@ rtl8168_clear_mcu_ocp_bit( rtl8168_clear_and_set_mcu_ocp_bit(tp, addr, mask, - 0 - ); + 0); } static void @@ -2311,8 +3389,7 @@ rtl8168_set_mcu_ocp_bit( rtl8168_clear_and_set_mcu_ocp_bit(tp, addr, 0, - mask - ); + mask); } static u32 real_ocp_read(struct rtl8168_private *tp, u16 addr, u8 len) @@ -2580,18 +3657,18 @@ void rtl8168_dash2_disable_tx(struct rtl8168_private *tp) u8 TmpUchar; //Disable oob Tx - RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) & ~( BIT_0 )); + RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) & ~(BIT_0)); WaitCnt = 0; //wait oob tx disable do { TmpUchar = RTL_CMAC_R8(tp, CMAC_IBISR0); - if ( TmpUchar & ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE ) { + if (TmpUchar & ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE) { break; } - udelay( 50 ); + udelay(50); WaitCnt++; } while(WaitCnt < 2000); @@ -2605,9 +3682,8 @@ void rtl8168_dash2_enable_tx(struct rtl8168_private *tp) if (!tp->DASH) return; - if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) | BIT_0); - } } void rtl8168_dash2_disable_rx(struct rtl8168_private *tp) @@ -2615,9 +3691,8 @@ void rtl8168_dash2_disable_rx(struct rtl8168_private *tp) if (!tp->DASH) return; - if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { - RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) & ~( BIT_0 )); - } + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) + RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) & ~(BIT_0)); } void rtl8168_dash2_enable_rx(struct rtl8168_private *tp) @@ -2625,9 +3700,8 @@ void rtl8168_dash2_enable_rx(struct rtl8168_private *tp) if (!tp->DASH) return; - if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) | BIT_0); - } } static void rtl8168_dash2_disable_txrx(struct net_device *dev) @@ -2635,14 +3709,15 @@ static void rtl8168_dash2_disable_txrx(struct net_device *dev) struct rtl8168_private *tp = netdev_priv(dev); if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { - rtl8168_dash2_disable_tx( tp ); - rtl8168_dash2_disable_rx( tp ); + rtl8168_dash2_disable_tx(tp); + rtl8168_dash2_disable_rx(tp); } } 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, @@ -2720,20 +3795,18 @@ static void ClearAndSetPCIePhyBit(struct rtl8168_private *tp, u8 addr, u16 clear static void ClearPCIePhyBit(struct rtl8168_private *tp, u8 addr, u16 mask) { - ClearAndSetPCIePhyBit( tp, - addr, - mask, - 0 - ); + ClearAndSetPCIePhyBit(tp, + addr, + mask, + 0); } -static void SetPCIePhyBit( struct rtl8168_private *tp, u8 addr, u16 mask) +static void SetPCIePhyBit(struct rtl8168_private *tp, u8 addr, u16 mask) { - ClearAndSetPCIePhyBit( tp, - addr, - 0, - mask - ); + ClearAndSetPCIePhyBit(tp, + addr, + 0, + mask); } static u32 @@ -2755,9 +3828,8 @@ rtl8168_csi_other_fun_read(struct rtl8168_private *tp, multi_fun_sel_bit = 0; } - if ( multi_fun_sel_bit > 7 ) { + if (multi_fun_sel_bit > 7) return 0xffffffff; - } cmd |= multi_fun_sel_bit << 16; @@ -2793,13 +3865,11 @@ rtl8168_csi_other_fun_write(struct rtl8168_private *tp, tp->mcfg != CFG_METHOD_26 && 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) { + tp->mcfg != CFG_METHOD_34) multi_fun_sel_bit = 0; - } - if ( multi_fun_sel_bit > 7 ) { + if (multi_fun_sel_bit > 7) return; - } cmd |= multi_fun_sel_bit << 16; @@ -2899,7 +3969,7 @@ rtl8168_csi_fun0_write_byte(struct rtl8168_private *tp, TmpUlong = rtl8168_csi_other_fun_read(tp, 0, RegAlignAddr); TmpUlong &= ~(0xFF << (8*ShiftByte)); TmpUlong |= (value << (8*ShiftByte)); - rtl8168_csi_other_fun_write( tp, 0, RegAlignAddr, TmpUlong ); + rtl8168_csi_other_fun_write(tp, 0, RegAlignAddr, TmpUlong); } else { struct pci_dev *pdev = tp->pci_dev; @@ -3198,6 +4268,8 @@ rtl8168_enable_rxdvgate(struct net_device *dev) 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; @@ -3225,6 +4297,8 @@ rtl8168_disable_rxdvgate(struct net_device *dev) 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; @@ -3315,6 +4389,8 @@ rtl8168_wait_txrx_fifo_empty(struct net_device *dev) 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) @@ -3332,6 +4408,50 @@ rtl8168_wait_txrx_fifo_empty(struct net_device *dev) } } +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. @@ -3351,11 +4471,7 @@ static void rtl8168_driver_start(struct rtl8168_private *tp) 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); @@ -3363,42 +4479,22 @@ static void rtl8168_driver_start(struct rtl8168_private *tp) 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) { - RTL_W8(tp, TwiCmdReg, RTL_R8(tp, TwiCmdReg) | ( BIT_7 )); - } + 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); @@ -3408,34 +4504,16 @@ static void rtl8168_driver_stop(struct rtl8168_private *tp) 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); + rtl8168_wait_dash_fw_ready(tp); + 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; - } - - if (tp->mcfg == CFG_METHOD_13) { - RTL_W8(tp, TwiCmdReg, RTL_R8(tp, TwiCmdReg) & ~( BIT_7 )); - } + 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: @@ -3452,60 +4530,116 @@ update_device_state: } } -#ifdef ENABLE_DASH_SUPPORT -inline void -rtl8168_enable_dash2_interrupt(struct rtl8168_private *tp) +static inline u16 rtl8168_get_isr_by_vector(struct rtl8168_private *tp, + u32 message_id) { - if (!tp->DASH) + if (message_id >= R8168_MAX_MSIX_VEC) + return 0; + + if (message_id == 0) + return RTL_R16(tp, tp->isr_reg[0]); + else + return RTL_R8(tp, tp->isr_reg[message_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 (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { - RTL_CMAC_W8(tp, CMAC_IBIMR0, ( ISRIMR_DASH_TYPE2_ROK | ISRIMR_DASH_TYPE2_TOK | ISRIMR_DASH_TYPE2_TDU | ISRIMR_DASH_TYPE2_RDU | ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE )); + if (message_id == 0) { + RTL_W16(tp, tp->isr_reg[0], val); + + if (val & RxDescUnavail) + tp->rx_ring[message_id].rdu++; + if (val & TxDescUnavail) + tp->tx_ring[message_id].tdu++; + } else { + RTL_W8(tp, tp->isr_reg[message_id], val); + + if (val & RxDU1) + tp->rx_ring[message_id].rdu++; } } -static inline void -rtl8168_disable_dash2_interrupt(struct rtl8168_private *tp) +static inline void rtl8168_self_clear_isr_by_vector(struct rtl8168_private *tp, + u32 message_id) { - if (!tp->DASH) + u16 val; + + if (message_id >= R8168_MAX_MSIX_VEC) return; - if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { - RTL_CMAC_W8(tp, CMAC_IBIMR0, 0); + 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; } -} -#endif - -static inline void -rtl8168_enable_hw_interrupt(struct rtl8168_private *tp) -{ - RTL_W16(tp, IntrMask, tp->intr_mask); - -#ifdef ENABLE_DASH_SUPPORT - if (tp->DASH) - rtl8168_enable_dash2_interrupt(tp); -#endif + rtl8168_clear_isr_by_vector(tp, message_id, val); } static inline void -rtl8168_disable_hw_interrupt(struct rtl8168_private *tp) +rtl8168_enable_interrupt(struct rtl8168_private *tp) { - RTL_W16(tp, IntrMask, 0x0000); - -#ifdef ENABLE_DASH_SUPPORT - if (tp->DASH) - rtl8168_disable_dash2_interrupt(tp); -#endif + int i; + for (i=0; inum_rx_rings; i++) + rtl8168_enable_interrupt_by_vector(tp, i); } +static inline void +rtl8168_enable_lib_interrupt(struct rtl8168_private *tp) +{ + int i; + + for (i=0; inum_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=0; ihw_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 @@ -3514,7 +4648,7 @@ rtl8168_switch_to_timer_interrupt(struct rtl8168_private *tp) 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_reg[0], tp->timer_intr_mask); #ifdef ENABLE_DASH_SUPPORT if (tp->DASH) @@ -3528,23 +4662,38 @@ rtl8168_switch_to_timer_interrupt(struct rtl8168_private *tp) 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_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; ihw_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 @@ -3553,7 +4702,7 @@ rtl8168_nic_reset(struct net_device *dev) 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); @@ -3579,7 +4728,8 @@ rtl8168_nic_reset(struct net_device *dev) case CFG_METHOD_12: case CFG_METHOD_13: for (i = 0; i < 2000; i++) { - if (!(RTL_R8(tp, TxPoll) & NPQ)) break; + if (!(RTL_R8(tp, TxPoll) & NPQ)) + break; udelay(100); } break; @@ -3598,6 +4748,8 @@ rtl8168_nic_reset(struct net_device *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: @@ -3632,11 +4784,14 @@ rtl8168_nic_reset(struct net_device *dev) } for (i = 0; i < 5; i++) { - if ( rtl8168_ocp_read(tp, 0x034, 1) == 0) + if (rtl8168_ocp_read(tp, 0x034, 1) == 0) break; } break; } + + /* reset rcr */ + RTL_W32(tp, RxConfig, (RX_DMA_BURST << RxCfgDMAShift)); } static void @@ -3681,6 +4836,8 @@ rtl8168_hw_clear_timer_int(struct net_device *dev) 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); @@ -3688,11 +4845,13 @@ rtl8168_hw_clear_timer_int(struct net_device *dev) } } -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); @@ -3701,8 +4860,20 @@ rtl8168_hw_reset(struct net_device *dev) 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_ring[0]; + struct rtl8168_rx_ring *rx_ring = &tp->rx_ring[0]; struct pci_dev *pdev = tp->pci_dev; struct net_device *dev = tp->dev; struct sk_buff *skb, *rx_skb; @@ -3721,9 +4892,9 @@ static void rtl8168_mac_loopback_test(struct rtl8168_private *tp) pattern = 0x5A; len = 60; type = htons(ETH_P_IP); - txd = tp->TxDescArray; - rxd = tp->RxDescArray; - rx_skb = tp->Rx_skbuff[0]; + txd = tx_ring->TxDescArray; + rxd = rtl8168_get_rxdesc(tp, tp->RxDescArray, 0, rx_ring->index); + rx_skb = rx_ring->Rx_skbuff[0]; RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) & ~0x00060000) | 0x00020000); do { @@ -3753,7 +4924,7 @@ static void rtl8168_mac_loopback_test(struct rtl8168_private *tp) 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); @@ -3762,7 +4933,7 @@ static void rtl8168_mac_loopback_test(struct rtl8168_private *tp) break; } - RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys)); + rtl8168_disable_rx_packet_filter(tp); rx_len = rx_cmd & 0x3FFF; rx_len -= 4; @@ -3784,15 +4955,15 @@ static void rtl8168_mac_loopback_test(struct rtl8168_private *tp) 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 @@ -3811,11 +4982,13 @@ 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 @@ -3874,10 +5047,42 @@ rtl8168dp_10mbps_gphy_para(struct net_device *dev) 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_ring[i]; + ring->dirty_tx = ring->cur_tx = 0; + ring->index = i; + ring->priv = tp; + ring->netdev = tp->dev; + + /* reset BQL for queue */ + netdev_tx_reset_queue(txring_txq(ring)); + } + + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8168_rx_ring *ring = &tp->rx_ring[i]; + ring->dirty_rx = ring->cur_rx = 0; + ring->index = i; + ring->priv = tp; + ring->netdev = tp->dev; + } + +#ifdef ENABLE_LIB_SUPPORT + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8168_ring *ring = &tp->lib_tx_ring[i]; + 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_ring[i]; + ring->direction = RTL8168_CH_DIR_RX; + ring->queue_num = i; + ring->private = tp; + } +#endif } static void @@ -3910,6 +5115,8 @@ rtl8168_issue_offset_99_event(struct rtl8168_private *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, 0x1EA, 1, ERIAR_ExGMAC); csi_tmp |= BIT_0; rtl8168_eri_write(tp, 0x1EA, 1, csi_tmp, ERIAR_ExGMAC); @@ -3948,7 +5155,7 @@ rtl8168_enable_exit_l1_mask(struct rtl8168_private *tp) 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); @@ -3975,7 +5182,7 @@ rtl8168_disable_exit_l1_mask(struct rtl8168_private *tp) 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); @@ -4010,14 +5217,162 @@ NICChkTypeEnableDashInterrupt(struct rtl8168_private *tp) // 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_reg[0], (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_reg[0], (ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK)); } } } #endif +static void +rtl8168_link_on_patch(struct net_device *dev) +{ + struct rtl8168_private *tp = netdev_priv(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.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 || 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_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; + + csi_tmp = rtl8168_eri_read(tp, 0x1D0, 1, ERIAR_ExGMAC); + csi_tmp |= BIT_1; + rtl8168_eri_write(tp, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC); + } + + rtl8168_hw_start(dev); + + netif_carrier_on(dev); + + netif_tx_wake_all_queues(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); +} + +static void +rtl8168_link_down_patch(struct net_device *dev) +{ + struct rtl8168_private *tp = netdev_priv(dev); + + tp->phy_reg_aner = 0; + tp->phy_reg_anlpar = 0; + tp->phy_reg_gbsr = 0; + + netif_carrier_off(dev); + + netif_tx_disable(dev); + + rtl8168_hw_reset(dev); + + rtl8168_tx_clear(tp); + + rtl8168_rx_clear(tp); + + rtl8168_init_ring(dev); + + 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; + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + NICChkTypeEnableDashInterrupt(tp); + } +#endif +} + static void rtl8168_check_link_status(struct net_device *dev) { @@ -4035,96 +5390,7 @@ rtl8168_check_link_status(struct net_device *dev) if (netif_carrier_ok(dev) != link_status_on) { if (link_status_on) { - 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_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; - - csi_tmp = rtl8168_eri_read(tp, 0x1D0, 1, ERIAR_ExGMAC); - csi_tmp |= BIT_1; - rtl8168_eri_write(tp, 0x1D0, 1, csi_tmp, ERIAR_ExGMAC); - } - - rtl8168_hw_start(dev); - - netif_carrier_on(dev); - - netif_wake_queue(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); + rtl8168_link_on_patch(dev); if (netif_msg_ifup(tp)) printk(KERN_INFO PFX "%s: link up\n", dev->name); @@ -4132,52 +5398,7 @@ rtl8168_check_link_status(struct net_device *dev) if (netif_msg_ifdown(tp)) printk(KERN_INFO PFX "%s: link down\n", dev->name); - tp->phy_reg_aner = 0; - tp->phy_reg_anlpar = 0; - tp->phy_reg_gbsr = 0; - - netif_stop_queue(dev); - - netif_carrier_off(dev); - - rtl8168_hw_reset(dev); - - rtl8168_tx_clear(tp); - - rtl8168_rx_clear(tp); - - rtl8168_init_ring(dev); - - if (dynamic_aspm) { - rtl8168_enable_cfg9346_write(tp); - rtl8168_hw_aspm_clkreq_enable(tp, true); - rtl8168_disable_cfg9346_write(tp); - } - - rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); - - 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); - } -#endif + rtl8168_link_down_patch(dev); } } @@ -4257,7 +5478,8 @@ rtl8168_enable_ocp_phy_power_saving(struct net_device *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); @@ -4279,7 +5501,8 @@ rtl8168_disable_ocp_phy_power_saving(struct net_device *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 != 0x0500) { rtl8168_set_phy_mcu_patch_request(tp); @@ -4324,6 +5547,8 @@ rtl8168_disable_pci_offset_99(struct rtl8168_private *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); @@ -4341,6 +5566,8 @@ rtl8168_disable_pci_offset_99(struct rtl8168_private *tp) 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; } @@ -4362,6 +5589,8 @@ rtl8168_enable_pci_offset_99(struct rtl8168_private *tp) 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; } @@ -4382,6 +5611,8 @@ rtl8168_enable_pci_offset_99(struct rtl8168_private *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); if (tp->org_pci_offset_99 & (BIT_5 | BIT_6)) @@ -4424,9 +5655,11 @@ rtl8168_init_pci_offset_99(struct rtl8168_private *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_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 ); + 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); rtl8168_eri_write(tp, 0x3F2, 2, csi_tmp, ERIAR_ExGMAC); csi_tmp = rtl8168_eri_read(tp, 0x3F5, 1, ERIAR_ExGMAC); csi_tmp |= BIT_6 | BIT_7; @@ -4457,8 +5690,10 @@ rtl8168_init_pci_offset_99(struct rtl8168_private *tp) 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; } @@ -4485,6 +5720,8 @@ rtl8168_init_pci_offset_99(struct rtl8168_private *tp) 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); @@ -4513,6 +5750,8 @@ rtl8168_init_pci_offset_99(struct rtl8168_private *tp) 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; @@ -4539,6 +5778,8 @@ rtl8168_disable_pci_offset_180(struct rtl8168_private *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, 0x1E2, 1, ERIAR_ExGMAC); csi_tmp &= ~BIT_2; rtl8168_eri_write(tp, 0x1E2, 1, csi_tmp, ERIAR_ExGMAC); @@ -4586,6 +5827,7 @@ rtl8168_enable_pci_offset_180(struct rtl8168_private *tp) 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; @@ -4606,6 +5848,8 @@ rtl8168_enable_pci_offset_180(struct rtl8168_private *tp) 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); @@ -4647,6 +5891,8 @@ rtl8168_set_pci_99_180_exit_driver_para(struct net_device *dev) 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); @@ -4666,17 +5912,63 @@ rtl8168_set_pci_99_180_exit_driver_para(struct net_device *dev) 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); +} + +static 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); @@ -4690,6 +5982,7 @@ rtl8168_hw_d3_para(struct net_device *dev) #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); @@ -4733,8 +6026,9 @@ rtl8168_hw_d3_para(struct net_device *dev) 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; @@ -4746,7 +6040,8 @@ rtl8168_hw_d3_para(struct net_device *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) if (!tp->dash_printer_enabled) rtl8168_disable_ocp_phy_power_saving(dev); @@ -4800,15 +6095,14 @@ rtl8168_get_hw_wol(struct net_device *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) @@ -4834,10 +6128,8 @@ rtl8168_get_hw_wol(struct net_device *dev) 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 @@ -5048,7 +6340,7 @@ rtl8168_powerdown_pll(struct net_device *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) { rtl8168_enable_cfg9346_write(tp); RTL_W8(tp, Config2, RTL_R8(tp, Config2) | PMSTS_En); rtl8168_disable_cfg9346_write(tp); @@ -5113,6 +6405,7 @@ rtl8168_powerdown_pll(struct net_device *dev) 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; } @@ -5122,7 +6415,7 @@ rtl8168_powerdown_pll(struct net_device *dev) 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; @@ -5158,6 +6451,7 @@ static void rtl8168_powerup_pll(struct net_device *dev) 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; } @@ -5172,27 +6466,19 @@ rtl8168_get_wol(struct net_device *dev, { 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 @@ -5200,19 +6486,14 @@ rtl8168_set_wol(struct net_device *dev, 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; @@ -5225,9 +6506,9 @@ rtl8168_get_drvinfo(struct net_device *dev, struct rtl8168_private *tp = netdev_priv(dev); struct rtl8168_fw *rtl_fw = tp->rtl_fw; - strcpy(info->driver, MODULENAME); - strcpy(info->version, RTL8168_VERSION); - strcpy(info->bus_info, pci_name(tp->pci_dev)); + strscpy(info->driver, MODULENAME, sizeof(info->driver)); + strscpy(info->version, RTL8168_VERSION, sizeof(info->version)); + strscpy(info->bus_info, pci_name(tp->pci_dev), sizeof(info->bus_info)); info->regdump_len = R8168_REGS_DUMP_SIZE; info->eedump_len = tp->eeprom_len; BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); @@ -5258,7 +6539,7 @@ rtl8168_set_speed_xmii(struct net_device *dev, 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); @@ -5300,8 +6581,16 @@ rtl8168_set_speed_xmii(struct net_device *dev, 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; @@ -5357,9 +6646,7 @@ rtl8168_set_settings(struct net_device *dev, #endif ) { - struct rtl8168_private *tp = netdev_priv(dev); int ret; - unsigned long flags; u8 autoneg; u32 speed; u8 duplex; @@ -5384,9 +6671,7 @@ rtl8168_set_settings(struct net_device *dev, 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; } @@ -5397,15 +6682,12 @@ rtl8168_get_tx_csum(struct net_device *dev) { 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; } @@ -5415,11 +6697,8 @@ rtl8168_get_rx_csum(struct net_device *dev) { 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; } @@ -5429,13 +6708,10 @@ rtl8168_set_tx_csum(struct net_device *dev, 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; @@ -5451,8 +6727,6 @@ rtl8168_set_tx_csum(struct net_device *dev, 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; } @@ -5461,13 +6735,10 @@ rtl8168_set_rx_csum(struct net_device *dev, 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 @@ -5475,8 +6746,6 @@ rtl8168_set_rx_csum(struct net_device *dev, RTL_W16(tp, CPlusCmd, tp->cp_cmd); - spin_unlock_irqrestore(&tp->lock, flags); - return 0; } #endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) @@ -5511,9 +6780,7 @@ rtl8168_vlan_rx_register(struct net_device *dev, 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; @@ -5521,7 +6788,6 @@ rtl8168_vlan_rx_register(struct net_device *dev, tp->cp_cmd &= ~RxVlan; RTL_W16(tp, CPlusCmd, tp->cp_cmd); RTL_R16(tp, CPlusCmd); - spin_unlock_irqrestore(&tp->lock, flags); } #endif @@ -5532,16 +6798,13 @@ rtl8168_vlan_rx_kill_vid(struct net_device *dev, 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_devices[vid] = 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) @@ -5595,17 +6858,12 @@ rtl8168_rx_vlan_skb(struct rtl8168_private *tp, 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; } @@ -5629,7 +6887,7 @@ static int rtl8168_hw_set_features(struct net_device *dev, 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; @@ -5643,21 +6901,42 @@ static int rtl8168_hw_set_features(struct net_device *dev, 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; } #endif +static u8 rtl8168_get_mdi_status(struct rtl8168_private *tp) +{ + u32 val; + + if (!tp->link_ok(tp->dev)) + return ETH_TP_MDI_INVALID; + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_20: + rtl8168_mdio_write(tp, 0x1F, 0x0000); + val = rtl8168_mdio_read(tp, 0x11); + if (val & BIT_6) + return ETH_TP_MDI_X; + else + return ETH_TP_MDI; + default: + rtl8168_mdio_write(tp, 0x1F, 0x0A43); + val = rtl8168_mdio_read(tp, 0x1A); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + if (val & BIT_1) + return ETH_TP_MDI; + else + return ETH_TP_MDI_X; + }; +} + static void rtl8168_gset_xmii(struct net_device *dev, #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) struct ethtool_cmd *cmd @@ -5672,7 +6951,6 @@ static void rtl8168_gset_xmii(struct net_device *dev, 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 | @@ -5686,14 +6964,12 @@ static void rtl8168_gset_xmii(struct net_device *dev, 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; @@ -5757,6 +7033,7 @@ static void rtl8168_gset_xmii(struct net_device *dev, cmd->speed = speed; cmd->duplex = duplex; cmd->port = PORT_TP; + cmd->eth_tp_mdix = rtl8168_get_mdi_status(tp); #else ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, supported); @@ -5768,6 +7045,7 @@ static void rtl8168_gset_xmii(struct net_device *dev, cmd->base.speed = speed; cmd->base.duplex = duplex; cmd->base.port = PORT_TP; + cmd->base.eth_tp_mdix = rtl8168_get_mdi_status(tp); #endif } @@ -5795,14 +7073,12 @@ static void rtl8168_get_regs(struct net_device *dev, struct ethtool_regs *regs, 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; @@ -5833,7 +7109,6 @@ static void rtl8168_get_regs(struct net_device *dev, struct ethtool_regs *regs, } break; } - spin_unlock_irqrestore(&tp->lock, flags); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) @@ -5929,30 +7204,18 @@ static int rtl8168_get_sset_count(struct net_device *dev, int sset) #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); + int i; - synchronize_irq(tp->irq); + tp->num_rx_desc = rx; - /* 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 - - rtl8168_irq_mask_and_ack(tp); - -#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_ring[i].num_tx_desc = tx; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -#if defined(NV_ETHTOOL_OPS_GET_SET_RINGPARAM_HAS_RINGPARAM_AND_EXTACT_ARGS) /* Linux v5.17 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) static void rtl8168_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, struct kernel_ethtool_ringparam *kernel_ring, @@ -5960,17 +7223,17 @@ static void rtl8168_get_ringparam(struct net_device *dev, #else static void rtl8168_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) -#endif //NV_ETHTOOL_OPS_GET_SET_RINGPARAM_HAS_RINGPARAM_AND_EXTACT_ARGS +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) { struct rtl8168_private *tp = netdev_priv(dev); 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_ring[0].num_tx_desc; } -#if defined(NV_ETHTOOL_OPS_GET_SET_RINGPARAM_HAS_RINGPARAM_AND_EXTACT_ARGS) /* Linux v5.17 */ +#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, @@ -5978,7 +7241,7 @@ static int rtl8168_set_ringparam(struct net_device *dev, #else static int rtl8168_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring) -#endif //NV_ETHTOOL_OPS_GET_SET_RINGPARAM_HAS_RINGPARAM_AND_EXTACT_ARGS +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) { struct rtl8168_private *tp = netdev_priv(dev); u32 new_rx_count, new_tx_count; @@ -5994,7 +7257,7 @@ static int rtl8168_set_ringparam(struct net_device *dev, 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_ring[0].num_tx_desc)) { /* nothing to do */ return 0; } @@ -6004,8 +7267,7 @@ static int rtl8168_set_ringparam(struct net_device *dev, 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); @@ -6023,9 +7285,6 @@ rtl8168_get_ethtool_stats(struct net_device *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(); @@ -6034,21 +7293,7 @@ rtl8168_get_ethtool_stats(struct net_device *dev, 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); data[0] = le64_to_cpu(counters->tx_packets); data[1] = le64_to_cpu(counters->rx_packets); @@ -6197,11 +7442,171 @@ static int _kc_ethtool_op_set_sg(struct net_device *dev, u32 data) } #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 bool rtl8168_is_adv_eee_enabled(struct rtl8168_private *tp) +{ + bool enabled = false; + + switch (tp->mcfg) { + //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_36: + rtl8168_mdio_write(tp, 0x1F, 0x0A43); + if (rtl8168_mdio_read(tp, 0x10) & BIT_15) + enabled = true; + rtl8168_mdio_write(tp, 0x1F, 0x0000); + break; + default: + break; + } + + return enabled; +} + +static void rtl8168_disable_adv_eee(struct rtl8168_private *tp) +{ + bool lock_mutex; + bool lock_phy; + u16 data; + + switch (tp->mcfg) { + //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_36: + break; + default: + return; + } + + switch (tp->mcfg) { + case CFG_METHOD_23: + case CFG_METHOD_27: + case CFG_METHOD_28: + case CFG_METHOD_31: + case CFG_METHOD_32: + case CFG_METHOD_33: + case CFG_METHOD_34: + lock_mutex = true; + break; + default: + lock_mutex = false; + break; + } + + if (lock_mutex) + rtl8168_oob_mutex_lock(tp); + + if (rtl8168_is_adv_eee_enabled(tp)) + lock_phy = true; + else + lock_phy = false; + + if (lock_phy) + rtl8168_set_phy_mcu_patch_request(tp); + + switch (tp->mcfg) { + case CFG_METHOD_25: + rtl8168_eri_write(tp, 0x1EA, 1, 0x00, ERIAR_ExGMAC); + + rtl8168_mdio_write(tp, 0x1F, 0x0A42); + data = rtl8168_mdio_read(tp, 0x16); + data &= ~(BIT_1); + rtl8168_mdio_write(tp, 0x16, data); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + break; + case CFG_METHOD_26: + data = rtl8168_mac_ocp_read(tp, 0xE052); + data &= ~(BIT_0); + rtl8168_mac_ocp_write(tp, 0xE052, data); + + rtl8168_mdio_write(tp, 0x1F, 0x0A42); + data = rtl8168_mdio_read(tp, 0x16); + data &= ~(BIT_1); + rtl8168_mdio_write(tp, 0x16, data); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + break; + case CFG_METHOD_27: + case CFG_METHOD_28: + data = rtl8168_mac_ocp_read(tp, 0xE052); + data &= ~(BIT_0); + rtl8168_mac_ocp_write(tp, 0xE052, data); + 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: + case CFG_METHOD_36: + data = rtl8168_mac_ocp_read(tp, 0xE052); + data &= ~(BIT_0); + rtl8168_mac_ocp_write(tp, 0xE052, data); + + rtl8168_mdio_write(tp, 0x1F, 0x0A43); + data = rtl8168_mdio_read(tp, 0x10) & ~(BIT_15); + rtl8168_mdio_write(tp, 0x10, data); + + rtl8168_mdio_write(tp, 0x1F, 0x0A44); + data = rtl8168_mdio_read(tp, 0x11) & ~(BIT_12 | BIT_13 | BIT_14); + rtl8168_mdio_write(tp, 0x11, data); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + break; + } + + if (lock_phy) + rtl8168_clear_phy_mcu_patch_request(tp); + + if (lock_mutex) + rtl8168_oob_mutex_unlock(tp); +} + +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) { @@ -6296,6 +7701,7 @@ static int rtl8168_enable_EEE(struct rtl8168_private *tp) 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); @@ -6303,7 +7709,7 @@ static int rtl8168_enable_EEE(struct rtl8168_private *tp) 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; @@ -6321,6 +7727,7 @@ static int rtl8168_enable_EEE(struct rtl8168_private *tp) 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); @@ -6330,156 +7737,12 @@ static int rtl8168_enable_EEE(struct rtl8168_private *tp) } /*Advanced EEE*/ - switch (tp->mcfg) { - case CFG_METHOD_23: - case CFG_METHOD_27: - case CFG_METHOD_28: - case CFG_METHOD_31: - case CFG_METHOD_32: - case CFG_METHOD_33: - case CFG_METHOD_34: - rtl8168_oob_mutex_lock(tp); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_24: - case CFG_METHOD_25: - case CFG_METHOD_26: - 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_set_phy_mcu_patch_request(tp); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_25: - rtl8168_eri_write(tp, 0x1EA, 1, 0xFA, ERIAR_ExGMAC); - - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - data = rtl8168_mdio_read(tp, 0x10); - if (data & BIT_10) { - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - data = rtl8168_mdio_read(tp, 0x16); - data &= ~(BIT_1); - rtl8168_mdio_write(tp, 0x16, data); - } else { - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - data = rtl8168_mdio_read(tp, 0x16); - data |= BIT_1; - rtl8168_mdio_write(tp, 0x16, data); - } - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - case CFG_METHOD_26: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data |= BIT_0; - rtl8168_mac_ocp_write(tp, 0xE052, data); - data = rtl8168_mac_ocp_read(tp, 0xE056); - data &= 0xFF0F; - data |= (BIT_4 | BIT_5 | BIT_6); - rtl8168_mac_ocp_write(tp, 0xE056, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - data = rtl8168_mdio_read(tp, 0x10); - if (data & BIT_10) { - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - data = rtl8168_mdio_read(tp, 0x16); - data &= ~(BIT_1); - rtl8168_mdio_write(tp, 0x16, data); - } else { - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - data = rtl8168_mdio_read(tp, 0x16); - data |= BIT_1; - rtl8168_mdio_write(tp, 0x16, data); - } - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - case CFG_METHOD_27: - case CFG_METHOD_28: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data &= ~BIT_0; - rtl8168_mac_ocp_write(tp, 0xE052, data); - data = rtl8168_mac_ocp_read(tp, 0xE056); - data &= 0xFF0F; - data |= (BIT_4 | BIT_5 | BIT_6); - rtl8168_mac_ocp_write(tp, 0xE056, data); - break; - case CFG_METHOD_29: - case CFG_METHOD_30: - case CFG_METHOD_35: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data &= ~(BIT_0); - rtl8168_mac_ocp_write(tp, 0xE052, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - data = rtl8168_mdio_read(tp, 0x10) | BIT_15; - rtl8168_mdio_write(tp, 0x10, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A44); - data = rtl8168_mdio_read(tp, 0x11) | BIT_13 | BIT_14; - data &= ~(BIT_12); - rtl8168_mdio_write(tp, 0x11, data); - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - case CFG_METHOD_31: - case CFG_METHOD_32: - case CFG_METHOD_33: - case CFG_METHOD_34: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data &= ~(BIT_0); - if (tp->HwPkgDet == 0x0F) - data |= BIT_0; - rtl8168_mac_ocp_write(tp, 0xE052, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - data = rtl8168_mdio_read(tp, 0x10) | BIT_15; - rtl8168_mdio_write(tp, 0x10, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A44); - data = rtl8168_mdio_read(tp, 0x11) | BIT_13 | BIT_14; - data &= ~(BIT_12); - rtl8168_mdio_write(tp, 0x11, data); - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_24: - case CFG_METHOD_25: - case CFG_METHOD_26: - 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_clear_phy_mcu_patch_request(tp); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_23: - case CFG_METHOD_27: - case CFG_METHOD_28: - case CFG_METHOD_31: - case CFG_METHOD_32: - case CFG_METHOD_33: - case CFG_METHOD_34: - rtl8168_oob_mutex_unlock(tp); - break; - } + rtl8168_disable_adv_eee(tp); return ret; } -static int rtl8168_disable_EEE(struct rtl8168_private *tp) +static int rtl8168_disable_eee(struct rtl8168_private *tp) { int ret; u16 data; @@ -6579,12 +7842,16 @@ static int rtl8168_disable_EEE(struct rtl8168_private *tp) 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); @@ -6600,6 +7867,7 @@ static int rtl8168_disable_EEE(struct rtl8168_private *tp) 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); @@ -6609,108 +7877,7 @@ static int rtl8168_disable_EEE(struct rtl8168_private *tp) } /*Advanced EEE*/ - switch (tp->mcfg) { - case CFG_METHOD_23: - case CFG_METHOD_27: - case CFG_METHOD_28: - case CFG_METHOD_31: - case CFG_METHOD_32: - case CFG_METHOD_33: - case CFG_METHOD_34: - rtl8168_oob_mutex_lock(tp); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_24: - case CFG_METHOD_25: - case CFG_METHOD_26: - 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_set_phy_mcu_patch_request(tp); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_25: - rtl8168_eri_write(tp, 0x1EA, 1, 0x00, ERIAR_ExGMAC); - - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - data = rtl8168_mdio_read(tp, 0x16); - data &= ~(BIT_1); - rtl8168_mdio_write(tp, 0x16, data); - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - case CFG_METHOD_26: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data &= ~(BIT_0); - rtl8168_mac_ocp_write(tp, 0xE052, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - data = rtl8168_mdio_read(tp, 0x16); - data &= ~(BIT_1); - rtl8168_mdio_write(tp, 0x16, data); - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - case CFG_METHOD_27: - case CFG_METHOD_28: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data &= ~(BIT_0); - rtl8168_mac_ocp_write(tp, 0xE052, data); - 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: - data = rtl8168_mac_ocp_read(tp, 0xE052); - data &= ~(BIT_0); - rtl8168_mac_ocp_write(tp, 0xE052, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - data = rtl8168_mdio_read(tp, 0x10) & ~(BIT_15); - rtl8168_mdio_write(tp, 0x10, data); - - rtl8168_mdio_write(tp, 0x1F, 0x0A44); - data = rtl8168_mdio_read(tp, 0x11) & ~(BIT_12 | BIT_13 | BIT_14); - rtl8168_mdio_write(tp, 0x11, data); - rtl8168_mdio_write(tp, 0x1F, 0x0000); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_24: - case CFG_METHOD_25: - case CFG_METHOD_26: - 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_clear_phy_mcu_patch_request(tp); - break; - } - - switch (tp->mcfg) { - case CFG_METHOD_23: - case CFG_METHOD_27: - case CFG_METHOD_28: - case CFG_METHOD_31: - case CFG_METHOD_32: - case CFG_METHOD_33: - case CFG_METHOD_34: - rtl8168_oob_mutex_unlock(tp); - break; - } + rtl8168_disable_adv_eee(tp); return ret; } @@ -6718,15 +7885,10 @@ static int rtl8168_disable_EEE(struct rtl8168_private *tp) 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); @@ -6740,132 +7902,164 @@ static int rtl_nway_reset(struct net_device *dev) 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 -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ -rtl_ethtool_get_eee(struct net_device *net, struct ethtool_keee *eee) -#else -rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *eee) -#endif +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); -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ - supported = val; -#else - supported = mmd_eee_cap_to_ethtool_sup_t(val); -#endif + /* Get Supported EEE */ + supported = eee->supported; + /* Get advertisement EEE */ + adv = eee->advertised; + + /* Get LP advertisement EEE */ rtl8168_mdio_write(tp, 0x1F, 0x0A5D); - val = rtl8168_mdio_read(tp, 0x10); -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ - adv = val; -#else - adv = mmd_eee_adv_to_ethtool_adv_t(val); -#endif - val = rtl8168_mdio_read(tp, 0x11); -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ - lp = val; -#else lp = mmd_eee_adv_to_ethtool_adv_t(val); -#endif + + /* 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); -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ - mii_eee_cap1_mod_linkmode_t(eee->supported, supported); - mii_eee_cap1_mod_linkmode_t(eee->advertised, adv); - mii_eee_cap1_mod_linkmode_t(eee->lp_advertised, lp); -#else - eee->supported = supported; - eee->advertised = adv; - eee->lp_advertised = lp; -#endif + 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 -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ -rtl_ethtool_set_eee(struct net_device *net, struct ethtool_keee *eee) -#else -rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *eee) -#endif +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; -#if defined(NV_ETHTOOL_KEEE_STRUCT_PRESENT) /* Linux v6.9 */ - tp->eee_adv_t = linkmode_to_mii_eee_cap1_t(eee->advertised); -#else - tp->eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); -#endif + 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); + 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; + } + + 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); - - spin_unlock_irqrestore(&tp->lock, flags); + rtl8168_disable_eee(tp); rtl_nway_reset(net); - return 0; + return rc; + +out: + + return rc; } #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +static void rtl8168_get_channels(struct net_device *dev, + struct ethtool_channels *channel) +{ + struct rtl8168_private *tp = netdev_priv(dev); + + channel->max_rx = tp->HwSuppNumRxQueues; + channel->max_tx = tp->HwSuppNumTxQueues; + channel->rx_count = tp->num_rx_rings; + channel->tx_count = tp->num_tx_rings; +} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */ + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) static const struct ethtool_ops rtl8168_ethtool_ops = { .get_drvinfo = rtl8168_get_drvinfo, @@ -6917,6 +8111,14 @@ static const struct ethtool_ops rtl8168_ethtool_ops = { #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) @@ -6924,175 +8126,13 @@ static const struct ethtool_ops rtl8168_ethtool_ops = { .get_eee = rtl_ethtool_get_eee, .set_eee = rtl_ethtool_set_eee, #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + .get_channels = rtl8168_get_channels, +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */ .nway_reset = rtl_nway_reset, }; #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; @@ -7265,9 +8305,24 @@ static void rtl8168_get_mac_version(struct rtl8168_private *tp) 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; @@ -7334,10 +8389,9 @@ static u32 rtl8168_decode_efuse_cmd(struct rtl8168_private *tp, u32 DwCmd) { 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))< 0) { @@ -7455,7 +8509,7 @@ static void rtl8168_tally_counter_clear(struct rtl8168_private *tp) { if (tp->mcfg == CFG_METHOD_1 || tp->mcfg == CFG_METHOD_2 || - tp->mcfg == CFG_METHOD_3 ) + tp->mcfg == CFG_METHOD_3) return; if (!tp->tally_paddr) @@ -7669,7 +8723,6 @@ rtl8168_test_phy_ocp_v3(struct rtl8168_private *tp) //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; @@ -7756,17 +8809,15 @@ rtl8168_wait_phy_ups_resume(struct net_device *dev, u16 PhyState) void rtl8168_enable_now_is_oob(struct rtl8168_private *tp) { - if ( tp->HwSuppNowIsOobVer == 1 ) { + if (tp->HwSuppNowIsOobVer == 1) RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) | Now_is_oob); - } } void rtl8168_disable_now_is_oob(struct rtl8168_private *tp) { - if ( tp->HwSuppNowIsOobVer == 1 ) { + if (tp->HwSuppNowIsOobVer == 1) RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) & ~Now_is_oob); - } } static void @@ -7791,13 +8842,11 @@ rtl8168_exit_oob(struct net_device *dev) 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) { + if (HW_SUPP_SERDES_PHY(tp)) + if (tp->HwSuppSerDesPhyVer == 1) rtl8168_switch_to_sgmii_mode(tp); - } - } if (HW_DASH_SUPPORT_DASH(tp)) { rtl8168_driver_start(tp); @@ -7855,7 +8904,9 @@ rtl8168_exit_oob(struct net_device *dev) 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); @@ -7893,6 +8944,8 @@ rtl8168_exit_oob(struct net_device *dev) 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; @@ -7938,6 +8991,8 @@ rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev) 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; } @@ -7958,6 +9013,8 @@ rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev) 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); @@ -7986,220 +9043,220 @@ rtl8168_set_mac_mcu_8168g_1(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - rtl8168_mac_ocp_write( tp, 0xF800, 0xE008 ); - rtl8168_mac_ocp_write( tp, 0xF802, 0xE01B ); - rtl8168_mac_ocp_write( tp, 0xF804, 0xE022 ); - rtl8168_mac_ocp_write( tp, 0xF806, 0xE094 ); - rtl8168_mac_ocp_write( tp, 0xF808, 0xE097 ); - rtl8168_mac_ocp_write( tp, 0xF80A, 0xE09A ); - rtl8168_mac_ocp_write( tp, 0xF80C, 0xE0B3 ); - rtl8168_mac_ocp_write( tp, 0xF80E, 0xE0BA ); - rtl8168_mac_ocp_write( tp, 0xF810, 0x49D2 ); - rtl8168_mac_ocp_write( tp, 0xF812, 0xF10D ); - rtl8168_mac_ocp_write( tp, 0xF814, 0x766C ); - rtl8168_mac_ocp_write( tp, 0xF816, 0x49E2 ); - rtl8168_mac_ocp_write( tp, 0xF818, 0xF00A ); - rtl8168_mac_ocp_write( tp, 0xF81A, 0x1EC0 ); - rtl8168_mac_ocp_write( tp, 0xF81C, 0x8EE1 ); - rtl8168_mac_ocp_write( tp, 0xF81E, 0xC60A ); - rtl8168_mac_ocp_write( tp, 0xF820, 0x77C0 ); - rtl8168_mac_ocp_write( tp, 0xF822, 0x4870 ); - rtl8168_mac_ocp_write( tp, 0xF824, 0x9FC0 ); - rtl8168_mac_ocp_write( tp, 0xF826, 0x1EA0 ); - rtl8168_mac_ocp_write( tp, 0xF828, 0xC707 ); - rtl8168_mac_ocp_write( tp, 0xF82A, 0x8EE1 ); - rtl8168_mac_ocp_write( tp, 0xF82C, 0x9D6C ); - rtl8168_mac_ocp_write( tp, 0xF82E, 0xC603 ); - rtl8168_mac_ocp_write( tp, 0xF830, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF832, 0xB416 ); - rtl8168_mac_ocp_write( tp, 0xF834, 0x0076 ); - rtl8168_mac_ocp_write( tp, 0xF836, 0xE86C ); - rtl8168_mac_ocp_write( tp, 0xF838, 0xC406 ); - rtl8168_mac_ocp_write( tp, 0xF83A, 0x7580 ); - rtl8168_mac_ocp_write( tp, 0xF83C, 0x4852 ); - rtl8168_mac_ocp_write( tp, 0xF83E, 0x8D80 ); - rtl8168_mac_ocp_write( tp, 0xF840, 0xC403 ); - rtl8168_mac_ocp_write( tp, 0xF842, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF844, 0xD3E0 ); - rtl8168_mac_ocp_write( tp, 0xF846, 0x02C8 ); - rtl8168_mac_ocp_write( tp, 0xF848, 0x8918 ); - rtl8168_mac_ocp_write( tp, 0xF84A, 0xE815 ); - rtl8168_mac_ocp_write( tp, 0xF84C, 0x1100 ); - rtl8168_mac_ocp_write( tp, 0xF84E, 0xF011 ); - rtl8168_mac_ocp_write( tp, 0xF850, 0xE812 ); - rtl8168_mac_ocp_write( tp, 0xF852, 0x4990 ); - rtl8168_mac_ocp_write( tp, 0xF854, 0xF002 ); - rtl8168_mac_ocp_write( tp, 0xF856, 0xE817 ); - rtl8168_mac_ocp_write( tp, 0xF858, 0xE80E ); - rtl8168_mac_ocp_write( tp, 0xF85A, 0x4992 ); - rtl8168_mac_ocp_write( tp, 0xF85C, 0xF002 ); - rtl8168_mac_ocp_write( tp, 0xF85E, 0xE80E ); - rtl8168_mac_ocp_write( tp, 0xF860, 0xE80A ); - rtl8168_mac_ocp_write( tp, 0xF862, 0x4993 ); - rtl8168_mac_ocp_write( tp, 0xF864, 0xF002 ); - rtl8168_mac_ocp_write( tp, 0xF866, 0xE818 ); - rtl8168_mac_ocp_write( tp, 0xF868, 0xE806 ); - rtl8168_mac_ocp_write( tp, 0xF86A, 0x4991 ); - rtl8168_mac_ocp_write( tp, 0xF86C, 0xF002 ); - rtl8168_mac_ocp_write( tp, 0xF86E, 0xE838 ); - rtl8168_mac_ocp_write( tp, 0xF870, 0xC25E ); - rtl8168_mac_ocp_write( tp, 0xF872, 0xBA00 ); - rtl8168_mac_ocp_write( tp, 0xF874, 0xC056 ); - rtl8168_mac_ocp_write( tp, 0xF876, 0x7100 ); - rtl8168_mac_ocp_write( tp, 0xF878, 0xFF80 ); - rtl8168_mac_ocp_write( tp, 0xF87A, 0x7100 ); - rtl8168_mac_ocp_write( tp, 0xF87C, 0x4892 ); - rtl8168_mac_ocp_write( tp, 0xF87E, 0x4813 ); - rtl8168_mac_ocp_write( tp, 0xF880, 0x8900 ); - rtl8168_mac_ocp_write( tp, 0xF882, 0xE00A ); - rtl8168_mac_ocp_write( tp, 0xF884, 0x7100 ); - rtl8168_mac_ocp_write( tp, 0xF886, 0x4890 ); - rtl8168_mac_ocp_write( tp, 0xF888, 0x4813 ); - rtl8168_mac_ocp_write( tp, 0xF88A, 0x8900 ); - rtl8168_mac_ocp_write( tp, 0xF88C, 0xC74B ); - rtl8168_mac_ocp_write( tp, 0xF88E, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF890, 0x48C2 ); - rtl8168_mac_ocp_write( tp, 0xF892, 0x4841 ); - rtl8168_mac_ocp_write( tp, 0xF894, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF896, 0xC746 ); - rtl8168_mac_ocp_write( tp, 0xF898, 0x74FC ); - rtl8168_mac_ocp_write( tp, 0xF89A, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF89C, 0xF120 ); - rtl8168_mac_ocp_write( tp, 0xF89E, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF8A0, 0xF11E ); - rtl8168_mac_ocp_write( tp, 0xF8A2, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF8A4, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF8A6, 0xF01B ); - rtl8168_mac_ocp_write( tp, 0xF8A8, 0x49C6 ); - rtl8168_mac_ocp_write( tp, 0xF8AA, 0xF119 ); - rtl8168_mac_ocp_write( tp, 0xF8AC, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF8AE, 0x49C4 ); - rtl8168_mac_ocp_write( tp, 0xF8B0, 0xF013 ); - rtl8168_mac_ocp_write( tp, 0xF8B2, 0xC536 ); - rtl8168_mac_ocp_write( tp, 0xF8B4, 0x74B0 ); - rtl8168_mac_ocp_write( tp, 0xF8B6, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF8B8, 0xF1FD ); - rtl8168_mac_ocp_write( tp, 0xF8BA, 0xC537 ); - rtl8168_mac_ocp_write( tp, 0xF8BC, 0xC434 ); - rtl8168_mac_ocp_write( tp, 0xF8BE, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF8C0, 0xC435 ); - rtl8168_mac_ocp_write( tp, 0xF8C2, 0x1C13 ); - rtl8168_mac_ocp_write( tp, 0xF8C4, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xF8C6, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xF8C8, 0xC52B ); - rtl8168_mac_ocp_write( tp, 0xF8CA, 0x74B0 ); - rtl8168_mac_ocp_write( tp, 0xF8CC, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF8CE, 0xF1FD ); - rtl8168_mac_ocp_write( tp, 0xF8D0, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF8D2, 0x48C4 ); - rtl8168_mac_ocp_write( tp, 0xF8D4, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF8D6, 0x7100 ); - rtl8168_mac_ocp_write( tp, 0xF8D8, 0x4893 ); - rtl8168_mac_ocp_write( tp, 0xF8DA, 0x8900 ); - rtl8168_mac_ocp_write( tp, 0xF8DC, 0xFF80 ); - rtl8168_mac_ocp_write( tp, 0xF8DE, 0xC520 ); - rtl8168_mac_ocp_write( tp, 0xF8E0, 0x74B0 ); - rtl8168_mac_ocp_write( tp, 0xF8E2, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF8E4, 0xF11C ); - rtl8168_mac_ocp_write( tp, 0xF8E6, 0xC71E ); - rtl8168_mac_ocp_write( tp, 0xF8E8, 0x74FC ); - rtl8168_mac_ocp_write( tp, 0xF8EA, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF8EC, 0xF118 ); - rtl8168_mac_ocp_write( tp, 0xF8EE, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF8F0, 0xF116 ); - rtl8168_mac_ocp_write( tp, 0xF8F2, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF8F4, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF8F6, 0xF013 ); - rtl8168_mac_ocp_write( tp, 0xF8F8, 0x48C3 ); - rtl8168_mac_ocp_write( tp, 0xF8FA, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF8FC, 0xC516 ); - rtl8168_mac_ocp_write( tp, 0xF8FE, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xF900, 0x49CE ); - rtl8168_mac_ocp_write( tp, 0xF902, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xF904, 0xC411 ); - rtl8168_mac_ocp_write( tp, 0xF906, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF908, 0xC411 ); - rtl8168_mac_ocp_write( tp, 0xF90A, 0x1C13 ); - rtl8168_mac_ocp_write( tp, 0xF90C, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xF90E, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xF910, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xF912, 0x49CF ); - rtl8168_mac_ocp_write( tp, 0xF914, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xF916, 0x7100 ); - rtl8168_mac_ocp_write( tp, 0xF918, 0x4891 ); - rtl8168_mac_ocp_write( tp, 0xF91A, 0x8900 ); - rtl8168_mac_ocp_write( tp, 0xF91C, 0xFF80 ); - rtl8168_mac_ocp_write( tp, 0xF91E, 0xE400 ); - rtl8168_mac_ocp_write( tp, 0xF920, 0xD3E0 ); - rtl8168_mac_ocp_write( tp, 0xF922, 0xE000 ); - rtl8168_mac_ocp_write( tp, 0xF924, 0x0481 ); - rtl8168_mac_ocp_write( tp, 0xF926, 0x0C81 ); - rtl8168_mac_ocp_write( tp, 0xF928, 0xDE20 ); - rtl8168_mac_ocp_write( tp, 0xF92A, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xF92C, 0x0992 ); - rtl8168_mac_ocp_write( tp, 0xF92E, 0x1B76 ); - rtl8168_mac_ocp_write( tp, 0xF930, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF932, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF934, 0x059C ); - rtl8168_mac_ocp_write( tp, 0xF936, 0x1B76 ); - rtl8168_mac_ocp_write( tp, 0xF938, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF93A, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF93C, 0x065A ); - rtl8168_mac_ocp_write( tp, 0xF93E, 0xB400 ); - rtl8168_mac_ocp_write( tp, 0xF940, 0x18DE ); - rtl8168_mac_ocp_write( tp, 0xF942, 0x2008 ); - rtl8168_mac_ocp_write( tp, 0xF944, 0x4001 ); - rtl8168_mac_ocp_write( tp, 0xF946, 0xF10F ); - rtl8168_mac_ocp_write( tp, 0xF948, 0x7342 ); - rtl8168_mac_ocp_write( tp, 0xF94A, 0x1880 ); - rtl8168_mac_ocp_write( tp, 0xF94C, 0x2008 ); - rtl8168_mac_ocp_write( tp, 0xF94E, 0x0009 ); - rtl8168_mac_ocp_write( tp, 0xF950, 0x4018 ); - rtl8168_mac_ocp_write( tp, 0xF952, 0xF109 ); - rtl8168_mac_ocp_write( tp, 0xF954, 0x7340 ); - rtl8168_mac_ocp_write( tp, 0xF956, 0x25BC ); - rtl8168_mac_ocp_write( tp, 0xF958, 0x130F ); - rtl8168_mac_ocp_write( tp, 0xF95A, 0xF105 ); - rtl8168_mac_ocp_write( tp, 0xF95C, 0xC00A ); - rtl8168_mac_ocp_write( tp, 0xF95E, 0x7300 ); - rtl8168_mac_ocp_write( tp, 0xF960, 0x4831 ); - rtl8168_mac_ocp_write( tp, 0xF962, 0x9B00 ); - rtl8168_mac_ocp_write( tp, 0xF964, 0xB000 ); - rtl8168_mac_ocp_write( tp, 0xF966, 0x7340 ); - rtl8168_mac_ocp_write( tp, 0xF968, 0x8320 ); - rtl8168_mac_ocp_write( tp, 0xF96A, 0xC302 ); - rtl8168_mac_ocp_write( tp, 0xF96C, 0xBB00 ); - rtl8168_mac_ocp_write( tp, 0xF96E, 0x0C12 ); - rtl8168_mac_ocp_write( tp, 0xF970, 0xE860 ); - rtl8168_mac_ocp_write( tp, 0xF972, 0xC406 ); - rtl8168_mac_ocp_write( tp, 0xF974, 0x7580 ); - rtl8168_mac_ocp_write( tp, 0xF976, 0x4851 ); - rtl8168_mac_ocp_write( tp, 0xF978, 0x8D80 ); - rtl8168_mac_ocp_write( tp, 0xF97A, 0xC403 ); - rtl8168_mac_ocp_write( tp, 0xF97C, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF97E, 0xD3E0 ); - rtl8168_mac_ocp_write( tp, 0xF980, 0x02C8 ); - rtl8168_mac_ocp_write( tp, 0xF982, 0xC406 ); - rtl8168_mac_ocp_write( tp, 0xF984, 0x7580 ); - rtl8168_mac_ocp_write( tp, 0xF986, 0x4850 ); - rtl8168_mac_ocp_write( tp, 0xF988, 0x8D80 ); - rtl8168_mac_ocp_write( tp, 0xF98A, 0xC403 ); - rtl8168_mac_ocp_write( tp, 0xF98C, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF98E, 0xD3E0 ); - rtl8168_mac_ocp_write( tp, 0xF990, 0x0298 ); + rtl8168_mac_ocp_write(tp, 0xF800, 0xE008); + rtl8168_mac_ocp_write(tp, 0xF802, 0xE01B); + rtl8168_mac_ocp_write(tp, 0xF804, 0xE022); + rtl8168_mac_ocp_write(tp, 0xF806, 0xE094); + rtl8168_mac_ocp_write(tp, 0xF808, 0xE097); + rtl8168_mac_ocp_write(tp, 0xF80A, 0xE09A); + rtl8168_mac_ocp_write(tp, 0xF80C, 0xE0B3); + rtl8168_mac_ocp_write(tp, 0xF80E, 0xE0BA); + rtl8168_mac_ocp_write(tp, 0xF810, 0x49D2); + rtl8168_mac_ocp_write(tp, 0xF812, 0xF10D); + rtl8168_mac_ocp_write(tp, 0xF814, 0x766C); + rtl8168_mac_ocp_write(tp, 0xF816, 0x49E2); + rtl8168_mac_ocp_write(tp, 0xF818, 0xF00A); + rtl8168_mac_ocp_write(tp, 0xF81A, 0x1EC0); + rtl8168_mac_ocp_write(tp, 0xF81C, 0x8EE1); + rtl8168_mac_ocp_write(tp, 0xF81E, 0xC60A); + rtl8168_mac_ocp_write(tp, 0xF820, 0x77C0); + rtl8168_mac_ocp_write(tp, 0xF822, 0x4870); + rtl8168_mac_ocp_write(tp, 0xF824, 0x9FC0); + rtl8168_mac_ocp_write(tp, 0xF826, 0x1EA0); + rtl8168_mac_ocp_write(tp, 0xF828, 0xC707); + rtl8168_mac_ocp_write(tp, 0xF82A, 0x8EE1); + rtl8168_mac_ocp_write(tp, 0xF82C, 0x9D6C); + rtl8168_mac_ocp_write(tp, 0xF82E, 0xC603); + rtl8168_mac_ocp_write(tp, 0xF830, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF832, 0xB416); + rtl8168_mac_ocp_write(tp, 0xF834, 0x0076); + rtl8168_mac_ocp_write(tp, 0xF836, 0xE86C); + rtl8168_mac_ocp_write(tp, 0xF838, 0xC406); + rtl8168_mac_ocp_write(tp, 0xF83A, 0x7580); + rtl8168_mac_ocp_write(tp, 0xF83C, 0x4852); + rtl8168_mac_ocp_write(tp, 0xF83E, 0x8D80); + rtl8168_mac_ocp_write(tp, 0xF840, 0xC403); + rtl8168_mac_ocp_write(tp, 0xF842, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF844, 0xD3E0); + rtl8168_mac_ocp_write(tp, 0xF846, 0x02C8); + rtl8168_mac_ocp_write(tp, 0xF848, 0x8918); + rtl8168_mac_ocp_write(tp, 0xF84A, 0xE815); + rtl8168_mac_ocp_write(tp, 0xF84C, 0x1100); + rtl8168_mac_ocp_write(tp, 0xF84E, 0xF011); + rtl8168_mac_ocp_write(tp, 0xF850, 0xE812); + rtl8168_mac_ocp_write(tp, 0xF852, 0x4990); + rtl8168_mac_ocp_write(tp, 0xF854, 0xF002); + rtl8168_mac_ocp_write(tp, 0xF856, 0xE817); + rtl8168_mac_ocp_write(tp, 0xF858, 0xE80E); + rtl8168_mac_ocp_write(tp, 0xF85A, 0x4992); + rtl8168_mac_ocp_write(tp, 0xF85C, 0xF002); + rtl8168_mac_ocp_write(tp, 0xF85E, 0xE80E); + rtl8168_mac_ocp_write(tp, 0xF860, 0xE80A); + rtl8168_mac_ocp_write(tp, 0xF862, 0x4993); + rtl8168_mac_ocp_write(tp, 0xF864, 0xF002); + rtl8168_mac_ocp_write(tp, 0xF866, 0xE818); + rtl8168_mac_ocp_write(tp, 0xF868, 0xE806); + rtl8168_mac_ocp_write(tp, 0xF86A, 0x4991); + rtl8168_mac_ocp_write(tp, 0xF86C, 0xF002); + rtl8168_mac_ocp_write(tp, 0xF86E, 0xE838); + rtl8168_mac_ocp_write(tp, 0xF870, 0xC25E); + rtl8168_mac_ocp_write(tp, 0xF872, 0xBA00); + rtl8168_mac_ocp_write(tp, 0xF874, 0xC056); + rtl8168_mac_ocp_write(tp, 0xF876, 0x7100); + rtl8168_mac_ocp_write(tp, 0xF878, 0xFF80); + rtl8168_mac_ocp_write(tp, 0xF87A, 0x7100); + rtl8168_mac_ocp_write(tp, 0xF87C, 0x4892); + rtl8168_mac_ocp_write(tp, 0xF87E, 0x4813); + rtl8168_mac_ocp_write(tp, 0xF880, 0x8900); + rtl8168_mac_ocp_write(tp, 0xF882, 0xE00A); + rtl8168_mac_ocp_write(tp, 0xF884, 0x7100); + rtl8168_mac_ocp_write(tp, 0xF886, 0x4890); + rtl8168_mac_ocp_write(tp, 0xF888, 0x4813); + rtl8168_mac_ocp_write(tp, 0xF88A, 0x8900); + rtl8168_mac_ocp_write(tp, 0xF88C, 0xC74B); + rtl8168_mac_ocp_write(tp, 0xF88E, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF890, 0x48C2); + rtl8168_mac_ocp_write(tp, 0xF892, 0x4841); + rtl8168_mac_ocp_write(tp, 0xF894, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF896, 0xC746); + rtl8168_mac_ocp_write(tp, 0xF898, 0x74FC); + rtl8168_mac_ocp_write(tp, 0xF89A, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF89C, 0xF120); + rtl8168_mac_ocp_write(tp, 0xF89E, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF8A0, 0xF11E); + rtl8168_mac_ocp_write(tp, 0xF8A2, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF8A4, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF8A6, 0xF01B); + rtl8168_mac_ocp_write(tp, 0xF8A8, 0x49C6); + rtl8168_mac_ocp_write(tp, 0xF8AA, 0xF119); + rtl8168_mac_ocp_write(tp, 0xF8AC, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF8AE, 0x49C4); + rtl8168_mac_ocp_write(tp, 0xF8B0, 0xF013); + rtl8168_mac_ocp_write(tp, 0xF8B2, 0xC536); + rtl8168_mac_ocp_write(tp, 0xF8B4, 0x74B0); + rtl8168_mac_ocp_write(tp, 0xF8B6, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF8B8, 0xF1FD); + rtl8168_mac_ocp_write(tp, 0xF8BA, 0xC537); + rtl8168_mac_ocp_write(tp, 0xF8BC, 0xC434); + rtl8168_mac_ocp_write(tp, 0xF8BE, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF8C0, 0xC435); + rtl8168_mac_ocp_write(tp, 0xF8C2, 0x1C13); + rtl8168_mac_ocp_write(tp, 0xF8C4, 0x484F); + rtl8168_mac_ocp_write(tp, 0xF8C6, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xF8C8, 0xC52B); + rtl8168_mac_ocp_write(tp, 0xF8CA, 0x74B0); + rtl8168_mac_ocp_write(tp, 0xF8CC, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF8CE, 0xF1FD); + rtl8168_mac_ocp_write(tp, 0xF8D0, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF8D2, 0x48C4); + rtl8168_mac_ocp_write(tp, 0xF8D4, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF8D6, 0x7100); + rtl8168_mac_ocp_write(tp, 0xF8D8, 0x4893); + rtl8168_mac_ocp_write(tp, 0xF8DA, 0x8900); + rtl8168_mac_ocp_write(tp, 0xF8DC, 0xFF80); + rtl8168_mac_ocp_write(tp, 0xF8DE, 0xC520); + rtl8168_mac_ocp_write(tp, 0xF8E0, 0x74B0); + rtl8168_mac_ocp_write(tp, 0xF8E2, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF8E4, 0xF11C); + rtl8168_mac_ocp_write(tp, 0xF8E6, 0xC71E); + rtl8168_mac_ocp_write(tp, 0xF8E8, 0x74FC); + rtl8168_mac_ocp_write(tp, 0xF8EA, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF8EC, 0xF118); + rtl8168_mac_ocp_write(tp, 0xF8EE, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF8F0, 0xF116); + rtl8168_mac_ocp_write(tp, 0xF8F2, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF8F4, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF8F6, 0xF013); + rtl8168_mac_ocp_write(tp, 0xF8F8, 0x48C3); + rtl8168_mac_ocp_write(tp, 0xF8FA, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF8FC, 0xC516); + rtl8168_mac_ocp_write(tp, 0xF8FE, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xF900, 0x49CE); + rtl8168_mac_ocp_write(tp, 0xF902, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xF904, 0xC411); + rtl8168_mac_ocp_write(tp, 0xF906, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF908, 0xC411); + rtl8168_mac_ocp_write(tp, 0xF90A, 0x1C13); + rtl8168_mac_ocp_write(tp, 0xF90C, 0x484F); + rtl8168_mac_ocp_write(tp, 0xF90E, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xF910, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xF912, 0x49CF); + rtl8168_mac_ocp_write(tp, 0xF914, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xF916, 0x7100); + rtl8168_mac_ocp_write(tp, 0xF918, 0x4891); + rtl8168_mac_ocp_write(tp, 0xF91A, 0x8900); + rtl8168_mac_ocp_write(tp, 0xF91C, 0xFF80); + rtl8168_mac_ocp_write(tp, 0xF91E, 0xE400); + rtl8168_mac_ocp_write(tp, 0xF920, 0xD3E0); + rtl8168_mac_ocp_write(tp, 0xF922, 0xE000); + rtl8168_mac_ocp_write(tp, 0xF924, 0x0481); + rtl8168_mac_ocp_write(tp, 0xF926, 0x0C81); + rtl8168_mac_ocp_write(tp, 0xF928, 0xDE20); + rtl8168_mac_ocp_write(tp, 0xF92A, 0x0000); + rtl8168_mac_ocp_write(tp, 0xF92C, 0x0992); + rtl8168_mac_ocp_write(tp, 0xF92E, 0x1B76); + rtl8168_mac_ocp_write(tp, 0xF930, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF932, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF934, 0x059C); + rtl8168_mac_ocp_write(tp, 0xF936, 0x1B76); + rtl8168_mac_ocp_write(tp, 0xF938, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF93A, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF93C, 0x065A); + rtl8168_mac_ocp_write(tp, 0xF93E, 0xB400); + rtl8168_mac_ocp_write(tp, 0xF940, 0x18DE); + rtl8168_mac_ocp_write(tp, 0xF942, 0x2008); + rtl8168_mac_ocp_write(tp, 0xF944, 0x4001); + rtl8168_mac_ocp_write(tp, 0xF946, 0xF10F); + rtl8168_mac_ocp_write(tp, 0xF948, 0x7342); + rtl8168_mac_ocp_write(tp, 0xF94A, 0x1880); + rtl8168_mac_ocp_write(tp, 0xF94C, 0x2008); + rtl8168_mac_ocp_write(tp, 0xF94E, 0x0009); + rtl8168_mac_ocp_write(tp, 0xF950, 0x4018); + rtl8168_mac_ocp_write(tp, 0xF952, 0xF109); + rtl8168_mac_ocp_write(tp, 0xF954, 0x7340); + rtl8168_mac_ocp_write(tp, 0xF956, 0x25BC); + rtl8168_mac_ocp_write(tp, 0xF958, 0x130F); + rtl8168_mac_ocp_write(tp, 0xF95A, 0xF105); + rtl8168_mac_ocp_write(tp, 0xF95C, 0xC00A); + rtl8168_mac_ocp_write(tp, 0xF95E, 0x7300); + rtl8168_mac_ocp_write(tp, 0xF960, 0x4831); + rtl8168_mac_ocp_write(tp, 0xF962, 0x9B00); + rtl8168_mac_ocp_write(tp, 0xF964, 0xB000); + rtl8168_mac_ocp_write(tp, 0xF966, 0x7340); + rtl8168_mac_ocp_write(tp, 0xF968, 0x8320); + rtl8168_mac_ocp_write(tp, 0xF96A, 0xC302); + rtl8168_mac_ocp_write(tp, 0xF96C, 0xBB00); + rtl8168_mac_ocp_write(tp, 0xF96E, 0x0C12); + rtl8168_mac_ocp_write(tp, 0xF970, 0xE860); + rtl8168_mac_ocp_write(tp, 0xF972, 0xC406); + rtl8168_mac_ocp_write(tp, 0xF974, 0x7580); + rtl8168_mac_ocp_write(tp, 0xF976, 0x4851); + rtl8168_mac_ocp_write(tp, 0xF978, 0x8D80); + rtl8168_mac_ocp_write(tp, 0xF97A, 0xC403); + rtl8168_mac_ocp_write(tp, 0xF97C, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF97E, 0xD3E0); + rtl8168_mac_ocp_write(tp, 0xF980, 0x02C8); + rtl8168_mac_ocp_write(tp, 0xF982, 0xC406); + rtl8168_mac_ocp_write(tp, 0xF984, 0x7580); + rtl8168_mac_ocp_write(tp, 0xF986, 0x4850); + rtl8168_mac_ocp_write(tp, 0xF988, 0x8D80); + rtl8168_mac_ocp_write(tp, 0xF98A, 0xC403); + rtl8168_mac_ocp_write(tp, 0xF98C, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF98E, 0xD3E0); + rtl8168_mac_ocp_write(tp, 0xF990, 0x0298); - rtl8168_mac_ocp_write( tp, 0xDE30, 0x0080 ); + rtl8168_mac_ocp_write(tp, 0xDE30, 0x0080); - rtl8168_mac_ocp_write( tp, 0xFC26, 0x8000 ); + rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); - rtl8168_mac_ocp_write( tp, 0xFC28, 0x0075 ); - rtl8168_mac_ocp_write( tp, 0xFC2A, 0x02B1 ); - rtl8168_mac_ocp_write( tp, 0xFC2C, 0x0991 ); - rtl8168_mac_ocp_write( tp, 0xFC2E, 0x059B ); - rtl8168_mac_ocp_write( tp, 0xFC30, 0x0659 ); - rtl8168_mac_ocp_write( tp, 0xFC32, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFC34, 0x02C7 ); - rtl8168_mac_ocp_write( tp, 0xFC36, 0x0279 ); + rtl8168_mac_ocp_write(tp, 0xFC28, 0x0075); + rtl8168_mac_ocp_write(tp, 0xFC2A, 0x02B1); + rtl8168_mac_ocp_write(tp, 0xFC2C, 0x0991); + rtl8168_mac_ocp_write(tp, 0xFC2E, 0x059B); + rtl8168_mac_ocp_write(tp, 0xFC30, 0x0659); + rtl8168_mac_ocp_write(tp, 0xFC32, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFC34, 0x02C7); + rtl8168_mac_ocp_write(tp, 0xFC36, 0x0279); } static void @@ -8209,127 +9266,127 @@ rtl8168_set_mac_mcu_8168gu_1(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - rtl8168_mac_ocp_write( tp, 0xF800, 0xE008 ); - rtl8168_mac_ocp_write( tp, 0xF802, 0xE011 ); - rtl8168_mac_ocp_write( tp, 0xF804, 0xE015 ); - rtl8168_mac_ocp_write( tp, 0xF806, 0xE018 ); - rtl8168_mac_ocp_write( tp, 0xF808, 0xE01B ); - rtl8168_mac_ocp_write( tp, 0xF80A, 0xE027 ); - rtl8168_mac_ocp_write( tp, 0xF80C, 0xE043 ); - rtl8168_mac_ocp_write( tp, 0xF80E, 0xE065 ); - rtl8168_mac_ocp_write( tp, 0xF810, 0x49E2 ); - rtl8168_mac_ocp_write( tp, 0xF812, 0xF005 ); - rtl8168_mac_ocp_write( tp, 0xF814, 0x49EA ); - rtl8168_mac_ocp_write( tp, 0xF816, 0xF003 ); - rtl8168_mac_ocp_write( tp, 0xF818, 0xC404 ); - rtl8168_mac_ocp_write( tp, 0xF81A, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF81C, 0xC403 ); - rtl8168_mac_ocp_write( tp, 0xF81E, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF820, 0x0496 ); - rtl8168_mac_ocp_write( tp, 0xF822, 0x051A ); - rtl8168_mac_ocp_write( tp, 0xF824, 0x1D01 ); - rtl8168_mac_ocp_write( tp, 0xF826, 0x8DE8 ); - rtl8168_mac_ocp_write( tp, 0xF828, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF82A, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF82C, 0x0206 ); - rtl8168_mac_ocp_write( tp, 0xF82E, 0x1B76 ); - rtl8168_mac_ocp_write( tp, 0xF830, 0xC202 ); - rtl8168_mac_ocp_write( tp, 0xF832, 0xBA00 ); - rtl8168_mac_ocp_write( tp, 0xF834, 0x058A ); - rtl8168_mac_ocp_write( tp, 0xF836, 0x1B76 ); - rtl8168_mac_ocp_write( tp, 0xF838, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF83A, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF83C, 0x0648 ); - rtl8168_mac_ocp_write( tp, 0xF83E, 0x74E6 ); - rtl8168_mac_ocp_write( tp, 0xF840, 0x1B78 ); - rtl8168_mac_ocp_write( tp, 0xF842, 0x46DC ); - rtl8168_mac_ocp_write( tp, 0xF844, 0x1300 ); - rtl8168_mac_ocp_write( tp, 0xF846, 0xF005 ); - rtl8168_mac_ocp_write( tp, 0xF848, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF84A, 0x48C3 ); - rtl8168_mac_ocp_write( tp, 0xF84C, 0x48C4 ); - rtl8168_mac_ocp_write( tp, 0xF84E, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF850, 0x64E7 ); - rtl8168_mac_ocp_write( tp, 0xF852, 0xC302 ); - rtl8168_mac_ocp_write( tp, 0xF854, 0xBB00 ); - rtl8168_mac_ocp_write( tp, 0xF856, 0x068E ); - rtl8168_mac_ocp_write( tp, 0xF858, 0x74E4 ); - rtl8168_mac_ocp_write( tp, 0xF85A, 0x49C5 ); - rtl8168_mac_ocp_write( tp, 0xF85C, 0xF106 ); - rtl8168_mac_ocp_write( tp, 0xF85E, 0x49C6 ); - rtl8168_mac_ocp_write( tp, 0xF860, 0xF107 ); - rtl8168_mac_ocp_write( tp, 0xF862, 0x48C8 ); - rtl8168_mac_ocp_write( tp, 0xF864, 0x48C9 ); - rtl8168_mac_ocp_write( tp, 0xF866, 0xE011 ); - rtl8168_mac_ocp_write( tp, 0xF868, 0x48C9 ); - rtl8168_mac_ocp_write( tp, 0xF86A, 0x4848 ); - rtl8168_mac_ocp_write( tp, 0xF86C, 0xE00E ); - rtl8168_mac_ocp_write( tp, 0xF86E, 0x4848 ); - rtl8168_mac_ocp_write( tp, 0xF870, 0x49C7 ); - rtl8168_mac_ocp_write( tp, 0xF872, 0xF00A ); - rtl8168_mac_ocp_write( tp, 0xF874, 0x48C9 ); - rtl8168_mac_ocp_write( tp, 0xF876, 0xC60D ); - rtl8168_mac_ocp_write( tp, 0xF878, 0x1D1F ); - rtl8168_mac_ocp_write( tp, 0xF87A, 0x8DC2 ); - rtl8168_mac_ocp_write( tp, 0xF87C, 0x1D00 ); - rtl8168_mac_ocp_write( tp, 0xF87E, 0x8DC3 ); - rtl8168_mac_ocp_write( tp, 0xF880, 0x1D11 ); - rtl8168_mac_ocp_write( tp, 0xF882, 0x8DC0 ); - rtl8168_mac_ocp_write( tp, 0xF884, 0xE002 ); - rtl8168_mac_ocp_write( tp, 0xF886, 0x4849 ); - rtl8168_mac_ocp_write( tp, 0xF888, 0x94E5 ); - rtl8168_mac_ocp_write( tp, 0xF88A, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF88C, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF88E, 0x0238 ); - rtl8168_mac_ocp_write( tp, 0xF890, 0xE434 ); - rtl8168_mac_ocp_write( tp, 0xF892, 0x49D9 ); - rtl8168_mac_ocp_write( tp, 0xF894, 0xF01B ); - rtl8168_mac_ocp_write( tp, 0xF896, 0xC31E ); - rtl8168_mac_ocp_write( tp, 0xF898, 0x7464 ); - rtl8168_mac_ocp_write( tp, 0xF89A, 0x49C4 ); - rtl8168_mac_ocp_write( tp, 0xF89C, 0xF114 ); - rtl8168_mac_ocp_write( tp, 0xF89E, 0xC31B ); - rtl8168_mac_ocp_write( tp, 0xF8A0, 0x6460 ); - rtl8168_mac_ocp_write( tp, 0xF8A2, 0x14FA ); - rtl8168_mac_ocp_write( tp, 0xF8A4, 0xFA02 ); - rtl8168_mac_ocp_write( tp, 0xF8A6, 0xE00F ); - rtl8168_mac_ocp_write( tp, 0xF8A8, 0xC317 ); - rtl8168_mac_ocp_write( tp, 0xF8AA, 0x7460 ); - rtl8168_mac_ocp_write( tp, 0xF8AC, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF8AE, 0xF10B ); - rtl8168_mac_ocp_write( tp, 0xF8B0, 0xC311 ); - rtl8168_mac_ocp_write( tp, 0xF8B2, 0x7462 ); - rtl8168_mac_ocp_write( tp, 0xF8B4, 0x48C1 ); - rtl8168_mac_ocp_write( tp, 0xF8B6, 0x9C62 ); - rtl8168_mac_ocp_write( tp, 0xF8B8, 0x4841 ); - rtl8168_mac_ocp_write( tp, 0xF8BA, 0x9C62 ); - rtl8168_mac_ocp_write( tp, 0xF8BC, 0xC30A ); - rtl8168_mac_ocp_write( tp, 0xF8BE, 0x1C04 ); - rtl8168_mac_ocp_write( tp, 0xF8C0, 0x8C60 ); - rtl8168_mac_ocp_write( tp, 0xF8C2, 0xE004 ); - rtl8168_mac_ocp_write( tp, 0xF8C4, 0x1C15 ); - rtl8168_mac_ocp_write( tp, 0xF8C6, 0xC305 ); - rtl8168_mac_ocp_write( tp, 0xF8C8, 0x8C60 ); - rtl8168_mac_ocp_write( tp, 0xF8CA, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF8CC, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF8CE, 0x0374 ); - rtl8168_mac_ocp_write( tp, 0xF8D0, 0xE434 ); - rtl8168_mac_ocp_write( tp, 0xF8D2, 0xE030 ); - rtl8168_mac_ocp_write( tp, 0xF8D4, 0xE61C ); - rtl8168_mac_ocp_write( tp, 0xF8D6, 0xE906 ); - rtl8168_mac_ocp_write( tp, 0xF8D8, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF8DA, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF8DC, 0x0000 ); + rtl8168_mac_ocp_write(tp, 0xF800, 0xE008); + rtl8168_mac_ocp_write(tp, 0xF802, 0xE011); + rtl8168_mac_ocp_write(tp, 0xF804, 0xE015); + rtl8168_mac_ocp_write(tp, 0xF806, 0xE018); + rtl8168_mac_ocp_write(tp, 0xF808, 0xE01B); + rtl8168_mac_ocp_write(tp, 0xF80A, 0xE027); + rtl8168_mac_ocp_write(tp, 0xF80C, 0xE043); + rtl8168_mac_ocp_write(tp, 0xF80E, 0xE065); + rtl8168_mac_ocp_write(tp, 0xF810, 0x49E2); + rtl8168_mac_ocp_write(tp, 0xF812, 0xF005); + rtl8168_mac_ocp_write(tp, 0xF814, 0x49EA); + rtl8168_mac_ocp_write(tp, 0xF816, 0xF003); + rtl8168_mac_ocp_write(tp, 0xF818, 0xC404); + rtl8168_mac_ocp_write(tp, 0xF81A, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF81C, 0xC403); + rtl8168_mac_ocp_write(tp, 0xF81E, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF820, 0x0496); + rtl8168_mac_ocp_write(tp, 0xF822, 0x051A); + rtl8168_mac_ocp_write(tp, 0xF824, 0x1D01); + rtl8168_mac_ocp_write(tp, 0xF826, 0x8DE8); + rtl8168_mac_ocp_write(tp, 0xF828, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF82A, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF82C, 0x0206); + rtl8168_mac_ocp_write(tp, 0xF82E, 0x1B76); + rtl8168_mac_ocp_write(tp, 0xF830, 0xC202); + rtl8168_mac_ocp_write(tp, 0xF832, 0xBA00); + rtl8168_mac_ocp_write(tp, 0xF834, 0x058A); + rtl8168_mac_ocp_write(tp, 0xF836, 0x1B76); + rtl8168_mac_ocp_write(tp, 0xF838, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF83A, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF83C, 0x0648); + rtl8168_mac_ocp_write(tp, 0xF83E, 0x74E6); + rtl8168_mac_ocp_write(tp, 0xF840, 0x1B78); + rtl8168_mac_ocp_write(tp, 0xF842, 0x46DC); + rtl8168_mac_ocp_write(tp, 0xF844, 0x1300); + rtl8168_mac_ocp_write(tp, 0xF846, 0xF005); + rtl8168_mac_ocp_write(tp, 0xF848, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF84A, 0x48C3); + rtl8168_mac_ocp_write(tp, 0xF84C, 0x48C4); + rtl8168_mac_ocp_write(tp, 0xF84E, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF850, 0x64E7); + rtl8168_mac_ocp_write(tp, 0xF852, 0xC302); + rtl8168_mac_ocp_write(tp, 0xF854, 0xBB00); + rtl8168_mac_ocp_write(tp, 0xF856, 0x068E); + rtl8168_mac_ocp_write(tp, 0xF858, 0x74E4); + rtl8168_mac_ocp_write(tp, 0xF85A, 0x49C5); + rtl8168_mac_ocp_write(tp, 0xF85C, 0xF106); + rtl8168_mac_ocp_write(tp, 0xF85E, 0x49C6); + rtl8168_mac_ocp_write(tp, 0xF860, 0xF107); + rtl8168_mac_ocp_write(tp, 0xF862, 0x48C8); + rtl8168_mac_ocp_write(tp, 0xF864, 0x48C9); + rtl8168_mac_ocp_write(tp, 0xF866, 0xE011); + rtl8168_mac_ocp_write(tp, 0xF868, 0x48C9); + rtl8168_mac_ocp_write(tp, 0xF86A, 0x4848); + rtl8168_mac_ocp_write(tp, 0xF86C, 0xE00E); + rtl8168_mac_ocp_write(tp, 0xF86E, 0x4848); + rtl8168_mac_ocp_write(tp, 0xF870, 0x49C7); + rtl8168_mac_ocp_write(tp, 0xF872, 0xF00A); + rtl8168_mac_ocp_write(tp, 0xF874, 0x48C9); + rtl8168_mac_ocp_write(tp, 0xF876, 0xC60D); + rtl8168_mac_ocp_write(tp, 0xF878, 0x1D1F); + rtl8168_mac_ocp_write(tp, 0xF87A, 0x8DC2); + rtl8168_mac_ocp_write(tp, 0xF87C, 0x1D00); + rtl8168_mac_ocp_write(tp, 0xF87E, 0x8DC3); + rtl8168_mac_ocp_write(tp, 0xF880, 0x1D11); + rtl8168_mac_ocp_write(tp, 0xF882, 0x8DC0); + rtl8168_mac_ocp_write(tp, 0xF884, 0xE002); + rtl8168_mac_ocp_write(tp, 0xF886, 0x4849); + rtl8168_mac_ocp_write(tp, 0xF888, 0x94E5); + rtl8168_mac_ocp_write(tp, 0xF88A, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF88C, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF88E, 0x0238); + rtl8168_mac_ocp_write(tp, 0xF890, 0xE434); + rtl8168_mac_ocp_write(tp, 0xF892, 0x49D9); + rtl8168_mac_ocp_write(tp, 0xF894, 0xF01B); + rtl8168_mac_ocp_write(tp, 0xF896, 0xC31E); + rtl8168_mac_ocp_write(tp, 0xF898, 0x7464); + rtl8168_mac_ocp_write(tp, 0xF89A, 0x49C4); + rtl8168_mac_ocp_write(tp, 0xF89C, 0xF114); + rtl8168_mac_ocp_write(tp, 0xF89E, 0xC31B); + rtl8168_mac_ocp_write(tp, 0xF8A0, 0x6460); + rtl8168_mac_ocp_write(tp, 0xF8A2, 0x14FA); + rtl8168_mac_ocp_write(tp, 0xF8A4, 0xFA02); + rtl8168_mac_ocp_write(tp, 0xF8A6, 0xE00F); + rtl8168_mac_ocp_write(tp, 0xF8A8, 0xC317); + rtl8168_mac_ocp_write(tp, 0xF8AA, 0x7460); + rtl8168_mac_ocp_write(tp, 0xF8AC, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF8AE, 0xF10B); + rtl8168_mac_ocp_write(tp, 0xF8B0, 0xC311); + rtl8168_mac_ocp_write(tp, 0xF8B2, 0x7462); + rtl8168_mac_ocp_write(tp, 0xF8B4, 0x48C1); + rtl8168_mac_ocp_write(tp, 0xF8B6, 0x9C62); + rtl8168_mac_ocp_write(tp, 0xF8B8, 0x4841); + rtl8168_mac_ocp_write(tp, 0xF8BA, 0x9C62); + rtl8168_mac_ocp_write(tp, 0xF8BC, 0xC30A); + rtl8168_mac_ocp_write(tp, 0xF8BE, 0x1C04); + rtl8168_mac_ocp_write(tp, 0xF8C0, 0x8C60); + rtl8168_mac_ocp_write(tp, 0xF8C2, 0xE004); + rtl8168_mac_ocp_write(tp, 0xF8C4, 0x1C15); + rtl8168_mac_ocp_write(tp, 0xF8C6, 0xC305); + rtl8168_mac_ocp_write(tp, 0xF8C8, 0x8C60); + rtl8168_mac_ocp_write(tp, 0xF8CA, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF8CC, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF8CE, 0x0374); + rtl8168_mac_ocp_write(tp, 0xF8D0, 0xE434); + rtl8168_mac_ocp_write(tp, 0xF8D2, 0xE030); + rtl8168_mac_ocp_write(tp, 0xF8D4, 0xE61C); + rtl8168_mac_ocp_write(tp, 0xF8D6, 0xE906); + rtl8168_mac_ocp_write(tp, 0xF8D8, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF8DA, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF8DC, 0x0000); - rtl8168_mac_ocp_write( tp, 0xFC26, 0x8000 ); + rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); - rtl8168_mac_ocp_write( tp, 0xFC28, 0x0493 ); - rtl8168_mac_ocp_write( tp, 0xFC2A, 0x0205 ); - rtl8168_mac_ocp_write( tp, 0xFC2C, 0x0589 ); - rtl8168_mac_ocp_write( tp, 0xFC2E, 0x0647 ); - rtl8168_mac_ocp_write( tp, 0xFC30, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFC32, 0x0215 ); - rtl8168_mac_ocp_write( tp, 0xFC34, 0x0285 ); + rtl8168_mac_ocp_write(tp, 0xFC28, 0x0493); + rtl8168_mac_ocp_write(tp, 0xFC2A, 0x0205); + rtl8168_mac_ocp_write(tp, 0xFC2C, 0x0589); + rtl8168_mac_ocp_write(tp, 0xFC2E, 0x0647); + rtl8168_mac_ocp_write(tp, 0xFC30, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFC32, 0x0215); + rtl8168_mac_ocp_write(tp, 0xFC34, 0x0285); } static void @@ -8339,426 +9396,426 @@ rtl8168_set_mac_mcu_8168gu_2(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - rtl8168_mac_ocp_write( tp, 0xF800, 0xE008 ); - rtl8168_mac_ocp_write( tp, 0xF802, 0xE00A ); - rtl8168_mac_ocp_write( tp, 0xF804, 0xE00D ); - rtl8168_mac_ocp_write( tp, 0xF806, 0xE02F ); - rtl8168_mac_ocp_write( tp, 0xF808, 0xE031 ); - rtl8168_mac_ocp_write( tp, 0xF80A, 0xE038 ); - rtl8168_mac_ocp_write( tp, 0xF80C, 0xE03A ); - rtl8168_mac_ocp_write( tp, 0xF80E, 0xE051 ); - rtl8168_mac_ocp_write( tp, 0xF810, 0xC202 ); - rtl8168_mac_ocp_write( tp, 0xF812, 0xBA00 ); - rtl8168_mac_ocp_write( tp, 0xF814, 0x0DFC ); - rtl8168_mac_ocp_write( tp, 0xF816, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xF818, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF81A, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF81C, 0x0A30 ); - rtl8168_mac_ocp_write( tp, 0xF81E, 0x49D9 ); - rtl8168_mac_ocp_write( tp, 0xF820, 0xF019 ); - rtl8168_mac_ocp_write( tp, 0xF822, 0xC520 ); - rtl8168_mac_ocp_write( tp, 0xF824, 0x64A5 ); - rtl8168_mac_ocp_write( tp, 0xF826, 0x1400 ); - rtl8168_mac_ocp_write( tp, 0xF828, 0xF007 ); - rtl8168_mac_ocp_write( tp, 0xF82A, 0x0C01 ); - rtl8168_mac_ocp_write( tp, 0xF82C, 0x8CA5 ); - rtl8168_mac_ocp_write( tp, 0xF82E, 0x1C15 ); - rtl8168_mac_ocp_write( tp, 0xF830, 0xC515 ); - rtl8168_mac_ocp_write( tp, 0xF832, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF834, 0xE00F ); - rtl8168_mac_ocp_write( tp, 0xF836, 0xC513 ); - rtl8168_mac_ocp_write( tp, 0xF838, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF83A, 0x48C8 ); - rtl8168_mac_ocp_write( tp, 0xF83C, 0x48CA ); - rtl8168_mac_ocp_write( tp, 0xF83E, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF840, 0xC510 ); - rtl8168_mac_ocp_write( tp, 0xF842, 0x1B00 ); - rtl8168_mac_ocp_write( tp, 0xF844, 0x9BA0 ); - rtl8168_mac_ocp_write( tp, 0xF846, 0x1B1C ); - rtl8168_mac_ocp_write( tp, 0xF848, 0x483F ); - rtl8168_mac_ocp_write( tp, 0xF84A, 0x9BA2 ); - rtl8168_mac_ocp_write( tp, 0xF84C, 0x1B04 ); - rtl8168_mac_ocp_write( tp, 0xF84E, 0xC506 ); - rtl8168_mac_ocp_write( tp, 0xF850, 0x9BA0 ); - rtl8168_mac_ocp_write( tp, 0xF852, 0xC603 ); - rtl8168_mac_ocp_write( tp, 0xF854, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF856, 0x0298 ); - rtl8168_mac_ocp_write( tp, 0xF858, 0x03DE ); - rtl8168_mac_ocp_write( tp, 0xF85A, 0xE434 ); - rtl8168_mac_ocp_write( tp, 0xF85C, 0xE096 ); - rtl8168_mac_ocp_write( tp, 0xF85E, 0xE860 ); - rtl8168_mac_ocp_write( tp, 0xF860, 0xDE20 ); - rtl8168_mac_ocp_write( tp, 0xF862, 0xD3C0 ); - rtl8168_mac_ocp_write( tp, 0xF864, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF866, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF868, 0x0A64 ); - rtl8168_mac_ocp_write( tp, 0xF86A, 0xC707 ); - rtl8168_mac_ocp_write( tp, 0xF86C, 0x1D00 ); - rtl8168_mac_ocp_write( tp, 0xF86E, 0x8DE2 ); - rtl8168_mac_ocp_write( tp, 0xF870, 0x48C1 ); - rtl8168_mac_ocp_write( tp, 0xF872, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF874, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF876, 0x00AA ); - rtl8168_mac_ocp_write( tp, 0xF878, 0xE0C0 ); - rtl8168_mac_ocp_write( tp, 0xF87A, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF87C, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF87E, 0x0132 ); - rtl8168_mac_ocp_write( tp, 0xF880, 0xC50C ); - rtl8168_mac_ocp_write( tp, 0xF882, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xF884, 0x49CE ); - rtl8168_mac_ocp_write( tp, 0xF886, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xF888, 0x1C00 ); - rtl8168_mac_ocp_write( tp, 0xF88A, 0x9EA0 ); - rtl8168_mac_ocp_write( tp, 0xF88C, 0x1C1C ); - rtl8168_mac_ocp_write( tp, 0xF88E, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xF890, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xF892, 0xC402 ); - rtl8168_mac_ocp_write( tp, 0xF894, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF896, 0x0AFA ); - rtl8168_mac_ocp_write( tp, 0xF898, 0xDE20 ); - rtl8168_mac_ocp_write( tp, 0xF89A, 0xE000 ); - rtl8168_mac_ocp_write( tp, 0xF89C, 0xE092 ); - rtl8168_mac_ocp_write( tp, 0xF89E, 0xE430 ); - rtl8168_mac_ocp_write( tp, 0xF8A0, 0xDE20 ); - rtl8168_mac_ocp_write( tp, 0xF8A2, 0xE0C0 ); - rtl8168_mac_ocp_write( tp, 0xF8A4, 0xE860 ); - rtl8168_mac_ocp_write( tp, 0xF8A6, 0xE84C ); - rtl8168_mac_ocp_write( tp, 0xF8A8, 0xB400 ); - rtl8168_mac_ocp_write( tp, 0xF8AA, 0xB430 ); - rtl8168_mac_ocp_write( tp, 0xF8AC, 0xE410 ); - rtl8168_mac_ocp_write( tp, 0xF8AE, 0xC0AE ); - rtl8168_mac_ocp_write( tp, 0xF8B0, 0xB407 ); - rtl8168_mac_ocp_write( tp, 0xF8B2, 0xB406 ); - rtl8168_mac_ocp_write( tp, 0xF8B4, 0xB405 ); - rtl8168_mac_ocp_write( tp, 0xF8B6, 0xB404 ); - rtl8168_mac_ocp_write( tp, 0xF8B8, 0xB403 ); - rtl8168_mac_ocp_write( tp, 0xF8BA, 0xB402 ); - rtl8168_mac_ocp_write( tp, 0xF8BC, 0xB401 ); - rtl8168_mac_ocp_write( tp, 0xF8BE, 0xC7EE ); - rtl8168_mac_ocp_write( tp, 0xF8C0, 0x76F4 ); - rtl8168_mac_ocp_write( tp, 0xF8C2, 0xC2ED ); - rtl8168_mac_ocp_write( tp, 0xF8C4, 0xC3ED ); - rtl8168_mac_ocp_write( tp, 0xF8C6, 0xC1EF ); - rtl8168_mac_ocp_write( tp, 0xF8C8, 0xC5F3 ); - rtl8168_mac_ocp_write( tp, 0xF8CA, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF8CC, 0x49CD ); - rtl8168_mac_ocp_write( tp, 0xF8CE, 0xF001 ); - rtl8168_mac_ocp_write( tp, 0xF8D0, 0xC5EE ); - rtl8168_mac_ocp_write( tp, 0xF8D2, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF8D4, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF8D6, 0xF105 ); - rtl8168_mac_ocp_write( tp, 0xF8D8, 0xC5E4 ); - rtl8168_mac_ocp_write( tp, 0xF8DA, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xF8DC, 0x49CE ); - rtl8168_mac_ocp_write( tp, 0xF8DE, 0xF00B ); - rtl8168_mac_ocp_write( tp, 0xF8E0, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xF8E2, 0x484B ); - rtl8168_mac_ocp_write( tp, 0xF8E4, 0x9C44 ); - rtl8168_mac_ocp_write( tp, 0xF8E6, 0x1C10 ); - rtl8168_mac_ocp_write( tp, 0xF8E8, 0x9C62 ); - rtl8168_mac_ocp_write( tp, 0xF8EA, 0x1C11 ); - rtl8168_mac_ocp_write( tp, 0xF8EC, 0x8C60 ); - rtl8168_mac_ocp_write( tp, 0xF8EE, 0x1C00 ); - rtl8168_mac_ocp_write( tp, 0xF8F0, 0x9CF6 ); - rtl8168_mac_ocp_write( tp, 0xF8F2, 0xE0EC ); - rtl8168_mac_ocp_write( tp, 0xF8F4, 0x49E7 ); - rtl8168_mac_ocp_write( tp, 0xF8F6, 0xF016 ); - rtl8168_mac_ocp_write( tp, 0xF8F8, 0x1D80 ); - rtl8168_mac_ocp_write( tp, 0xF8FA, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xF8FC, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF8FE, 0x4843 ); - rtl8168_mac_ocp_write( tp, 0xF900, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF902, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF904, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF906, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xF908, 0x48C8 ); - rtl8168_mac_ocp_write( tp, 0xF90A, 0x48C9 ); - rtl8168_mac_ocp_write( tp, 0xF90C, 0x48CA ); - rtl8168_mac_ocp_write( tp, 0xF90E, 0x9C44 ); - rtl8168_mac_ocp_write( tp, 0xF910, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF912, 0x4844 ); - rtl8168_mac_ocp_write( tp, 0xF914, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF916, 0x1E01 ); - rtl8168_mac_ocp_write( tp, 0xF918, 0xE8DB ); - rtl8168_mac_ocp_write( tp, 0xF91A, 0x7420 ); - rtl8168_mac_ocp_write( tp, 0xF91C, 0x48C1 ); - rtl8168_mac_ocp_write( tp, 0xF91E, 0x9C20 ); - rtl8168_mac_ocp_write( tp, 0xF920, 0xE0D5 ); - rtl8168_mac_ocp_write( tp, 0xF922, 0x49E6 ); - rtl8168_mac_ocp_write( tp, 0xF924, 0xF02A ); - rtl8168_mac_ocp_write( tp, 0xF926, 0x1D40 ); - rtl8168_mac_ocp_write( tp, 0xF928, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xF92A, 0x74FC ); - rtl8168_mac_ocp_write( tp, 0xF92C, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF92E, 0xF124 ); - rtl8168_mac_ocp_write( tp, 0xF930, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF932, 0xF122 ); - rtl8168_mac_ocp_write( tp, 0xF934, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF936, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF938, 0xF01F ); - rtl8168_mac_ocp_write( tp, 0xF93A, 0xE8D3 ); - rtl8168_mac_ocp_write( tp, 0xF93C, 0x48C4 ); - rtl8168_mac_ocp_write( tp, 0xF93E, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF940, 0x1E00 ); - rtl8168_mac_ocp_write( tp, 0xF942, 0xE8C6 ); - rtl8168_mac_ocp_write( tp, 0xF944, 0xC5B1 ); - rtl8168_mac_ocp_write( tp, 0xF946, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF948, 0x49C3 ); - rtl8168_mac_ocp_write( tp, 0xF94A, 0xF016 ); - rtl8168_mac_ocp_write( tp, 0xF94C, 0xC5AF ); - rtl8168_mac_ocp_write( tp, 0xF94E, 0x74A4 ); - rtl8168_mac_ocp_write( tp, 0xF950, 0x49C2 ); - rtl8168_mac_ocp_write( tp, 0xF952, 0xF005 ); - rtl8168_mac_ocp_write( tp, 0xF954, 0xC5AA ); - rtl8168_mac_ocp_write( tp, 0xF956, 0x74B2 ); - rtl8168_mac_ocp_write( tp, 0xF958, 0x49C9 ); - rtl8168_mac_ocp_write( tp, 0xF95A, 0xF10E ); - rtl8168_mac_ocp_write( tp, 0xF95C, 0xC5A6 ); - rtl8168_mac_ocp_write( tp, 0xF95E, 0x74A8 ); - rtl8168_mac_ocp_write( tp, 0xF960, 0x4845 ); - rtl8168_mac_ocp_write( tp, 0xF962, 0x4846 ); - rtl8168_mac_ocp_write( tp, 0xF964, 0x4847 ); - rtl8168_mac_ocp_write( tp, 0xF966, 0x4848 ); - rtl8168_mac_ocp_write( tp, 0xF968, 0x9CA8 ); - rtl8168_mac_ocp_write( tp, 0xF96A, 0x74B2 ); - rtl8168_mac_ocp_write( tp, 0xF96C, 0x4849 ); - rtl8168_mac_ocp_write( tp, 0xF96E, 0x9CB2 ); - rtl8168_mac_ocp_write( tp, 0xF970, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF972, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xF974, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF976, 0xE0AA ); - rtl8168_mac_ocp_write( tp, 0xF978, 0x49E4 ); - rtl8168_mac_ocp_write( tp, 0xF97A, 0xF018 ); - rtl8168_mac_ocp_write( tp, 0xF97C, 0x1D10 ); - rtl8168_mac_ocp_write( tp, 0xF97E, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xF980, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF982, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF984, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF986, 0x4843 ); - rtl8168_mac_ocp_write( tp, 0xF988, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF98A, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF98C, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF98E, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF990, 0x4844 ); - rtl8168_mac_ocp_write( tp, 0xF992, 0x4842 ); - rtl8168_mac_ocp_write( tp, 0xF994, 0x4841 ); - rtl8168_mac_ocp_write( tp, 0xF996, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF998, 0x1E01 ); - rtl8168_mac_ocp_write( tp, 0xF99A, 0xE89A ); - rtl8168_mac_ocp_write( tp, 0xF99C, 0x7420 ); - rtl8168_mac_ocp_write( tp, 0xF99E, 0x4841 ); - rtl8168_mac_ocp_write( tp, 0xF9A0, 0x9C20 ); - rtl8168_mac_ocp_write( tp, 0xF9A2, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xF9A4, 0x4848 ); - rtl8168_mac_ocp_write( tp, 0xF9A6, 0x9C44 ); - rtl8168_mac_ocp_write( tp, 0xF9A8, 0xE091 ); - rtl8168_mac_ocp_write( tp, 0xF9AA, 0x49E5 ); - rtl8168_mac_ocp_write( tp, 0xF9AC, 0xF03E ); - rtl8168_mac_ocp_write( tp, 0xF9AE, 0x1D20 ); - rtl8168_mac_ocp_write( tp, 0xF9B0, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xF9B2, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF9B4, 0x48C2 ); - rtl8168_mac_ocp_write( tp, 0xF9B6, 0x4841 ); - rtl8168_mac_ocp_write( tp, 0xF9B8, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF9BA, 0x1E01 ); - rtl8168_mac_ocp_write( tp, 0xF9BC, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xF9BE, 0x49CA ); - rtl8168_mac_ocp_write( tp, 0xF9C0, 0xF103 ); - rtl8168_mac_ocp_write( tp, 0xF9C2, 0x49C2 ); - rtl8168_mac_ocp_write( tp, 0xF9C4, 0xF00C ); - rtl8168_mac_ocp_write( tp, 0xF9C6, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF9C8, 0xF004 ); - rtl8168_mac_ocp_write( tp, 0xF9CA, 0x6447 ); - rtl8168_mac_ocp_write( tp, 0xF9CC, 0x2244 ); - rtl8168_mac_ocp_write( tp, 0xF9CE, 0xE002 ); - rtl8168_mac_ocp_write( tp, 0xF9D0, 0x1C01 ); - rtl8168_mac_ocp_write( tp, 0xF9D2, 0x9C62 ); - rtl8168_mac_ocp_write( tp, 0xF9D4, 0x1C11 ); - rtl8168_mac_ocp_write( tp, 0xF9D6, 0x8C60 ); - rtl8168_mac_ocp_write( tp, 0xF9D8, 0x1C00 ); - rtl8168_mac_ocp_write( tp, 0xF9DA, 0x9CF6 ); - rtl8168_mac_ocp_write( tp, 0xF9DC, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xF9DE, 0x49C8 ); - rtl8168_mac_ocp_write( tp, 0xF9E0, 0xF01D ); - rtl8168_mac_ocp_write( tp, 0xF9E2, 0x74FC ); - rtl8168_mac_ocp_write( tp, 0xF9E4, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF9E6, 0xF11A ); - rtl8168_mac_ocp_write( tp, 0xF9E8, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xF9EA, 0xF118 ); - rtl8168_mac_ocp_write( tp, 0xF9EC, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF9EE, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF9F0, 0xF015 ); - rtl8168_mac_ocp_write( tp, 0xF9F2, 0x49C6 ); - rtl8168_mac_ocp_write( tp, 0xF9F4, 0xF113 ); - rtl8168_mac_ocp_write( tp, 0xF9F6, 0xE875 ); - rtl8168_mac_ocp_write( tp, 0xF9F8, 0x48C4 ); - rtl8168_mac_ocp_write( tp, 0xF9FA, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF9FC, 0x7420 ); - rtl8168_mac_ocp_write( tp, 0xF9FE, 0x48C1 ); - rtl8168_mac_ocp_write( tp, 0xFA00, 0x9C20 ); - rtl8168_mac_ocp_write( tp, 0xFA02, 0xC50A ); - rtl8168_mac_ocp_write( tp, 0xFA04, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFA06, 0x8CA5 ); - rtl8168_mac_ocp_write( tp, 0xFA08, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xFA0A, 0xC505 ); - rtl8168_mac_ocp_write( tp, 0xFA0C, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xFA0E, 0x1C11 ); - rtl8168_mac_ocp_write( tp, 0xFA10, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xFA12, 0xE00A ); - rtl8168_mac_ocp_write( tp, 0xFA14, 0xE434 ); - rtl8168_mac_ocp_write( tp, 0xFA16, 0xD3C0 ); - rtl8168_mac_ocp_write( tp, 0xFA18, 0xDC00 ); - rtl8168_mac_ocp_write( tp, 0xFA1A, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xFA1C, 0x49CA ); - rtl8168_mac_ocp_write( tp, 0xFA1E, 0xF004 ); - rtl8168_mac_ocp_write( tp, 0xFA20, 0x48CA ); - rtl8168_mac_ocp_write( tp, 0xFA22, 0x9C44 ); - rtl8168_mac_ocp_write( tp, 0xFA24, 0xE855 ); - rtl8168_mac_ocp_write( tp, 0xFA26, 0xE052 ); - rtl8168_mac_ocp_write( tp, 0xFA28, 0x49E8 ); - rtl8168_mac_ocp_write( tp, 0xFA2A, 0xF024 ); - rtl8168_mac_ocp_write( tp, 0xFA2C, 0x1D01 ); - rtl8168_mac_ocp_write( tp, 0xFA2E, 0x8DF5 ); - rtl8168_mac_ocp_write( tp, 0xFA30, 0x7440 ); - rtl8168_mac_ocp_write( tp, 0xFA32, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xFA34, 0xF11E ); - rtl8168_mac_ocp_write( tp, 0xFA36, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xFA38, 0x49C8 ); - rtl8168_mac_ocp_write( tp, 0xFA3A, 0xF01B ); - rtl8168_mac_ocp_write( tp, 0xFA3C, 0x49CA ); - rtl8168_mac_ocp_write( tp, 0xFA3E, 0xF119 ); - rtl8168_mac_ocp_write( tp, 0xFA40, 0xC5EC ); - rtl8168_mac_ocp_write( tp, 0xFA42, 0x76A4 ); - rtl8168_mac_ocp_write( tp, 0xFA44, 0x49E3 ); - rtl8168_mac_ocp_write( tp, 0xFA46, 0xF015 ); - rtl8168_mac_ocp_write( tp, 0xFA48, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xFA4A, 0xF103 ); - rtl8168_mac_ocp_write( tp, 0xFA4C, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xFA4E, 0xF011 ); - rtl8168_mac_ocp_write( tp, 0xFA50, 0x4849 ); - rtl8168_mac_ocp_write( tp, 0xFA52, 0x9C44 ); - rtl8168_mac_ocp_write( tp, 0xFA54, 0x1C00 ); - rtl8168_mac_ocp_write( tp, 0xFA56, 0x9CF6 ); - rtl8168_mac_ocp_write( tp, 0xFA58, 0x7444 ); - rtl8168_mac_ocp_write( tp, 0xFA5A, 0x49C1 ); - rtl8168_mac_ocp_write( tp, 0xFA5C, 0xF004 ); - rtl8168_mac_ocp_write( tp, 0xFA5E, 0x6446 ); - rtl8168_mac_ocp_write( tp, 0xFA60, 0x1E07 ); - rtl8168_mac_ocp_write( tp, 0xFA62, 0xE003 ); - rtl8168_mac_ocp_write( tp, 0xFA64, 0x1C01 ); - rtl8168_mac_ocp_write( tp, 0xFA66, 0x1E03 ); - rtl8168_mac_ocp_write( tp, 0xFA68, 0x9C62 ); - rtl8168_mac_ocp_write( tp, 0xFA6A, 0x1C11 ); - rtl8168_mac_ocp_write( tp, 0xFA6C, 0x8C60 ); - rtl8168_mac_ocp_write( tp, 0xFA6E, 0xE830 ); - rtl8168_mac_ocp_write( tp, 0xFA70, 0xE02D ); - rtl8168_mac_ocp_write( tp, 0xFA72, 0x49E9 ); - rtl8168_mac_ocp_write( tp, 0xFA74, 0xF004 ); - rtl8168_mac_ocp_write( tp, 0xFA76, 0x1D02 ); - rtl8168_mac_ocp_write( tp, 0xFA78, 0x8DF5 ); - rtl8168_mac_ocp_write( tp, 0xFA7A, 0xE79C ); - rtl8168_mac_ocp_write( tp, 0xFA7C, 0x49E3 ); - rtl8168_mac_ocp_write( tp, 0xFA7E, 0xF006 ); - rtl8168_mac_ocp_write( tp, 0xFA80, 0x1D08 ); - rtl8168_mac_ocp_write( tp, 0xFA82, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xFA84, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xFA86, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xFA88, 0xE73A ); - rtl8168_mac_ocp_write( tp, 0xFA8A, 0x49E1 ); - rtl8168_mac_ocp_write( tp, 0xFA8C, 0xF007 ); - rtl8168_mac_ocp_write( tp, 0xFA8E, 0x1D02 ); - rtl8168_mac_ocp_write( tp, 0xFA90, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xFA92, 0x1E01 ); - rtl8168_mac_ocp_write( tp, 0xFA94, 0xE7A7 ); - rtl8168_mac_ocp_write( tp, 0xFA96, 0xDE20 ); - rtl8168_mac_ocp_write( tp, 0xFA98, 0xE410 ); - rtl8168_mac_ocp_write( tp, 0xFA9A, 0x49E0 ); - rtl8168_mac_ocp_write( tp, 0xFA9C, 0xF017 ); - rtl8168_mac_ocp_write( tp, 0xFA9E, 0x1D01 ); - rtl8168_mac_ocp_write( tp, 0xFAA0, 0x8DF4 ); - rtl8168_mac_ocp_write( tp, 0xFAA2, 0xC5FA ); - rtl8168_mac_ocp_write( tp, 0xFAA4, 0x1C00 ); - rtl8168_mac_ocp_write( tp, 0xFAA6, 0x8CA0 ); - rtl8168_mac_ocp_write( tp, 0xFAA8, 0x1C1B ); - rtl8168_mac_ocp_write( tp, 0xFAAA, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xFAAC, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFAAE, 0x49CF ); - rtl8168_mac_ocp_write( tp, 0xFAB0, 0xF0FE ); - rtl8168_mac_ocp_write( tp, 0xFAB2, 0xC5F3 ); - rtl8168_mac_ocp_write( tp, 0xFAB4, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xFAB6, 0x4849 ); - rtl8168_mac_ocp_write( tp, 0xFAB8, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xFABA, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xFABC, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xFABE, 0xF006 ); - rtl8168_mac_ocp_write( tp, 0xFAC0, 0x48C3 ); - rtl8168_mac_ocp_write( tp, 0xFAC2, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xFAC4, 0xE820 ); - rtl8168_mac_ocp_write( tp, 0xFAC6, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xFAC8, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xFACA, 0xC432 ); - rtl8168_mac_ocp_write( tp, 0xFACC, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xFACE, 0xC5E4 ); - rtl8168_mac_ocp_write( tp, 0xFAD0, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFAD2, 0x49CE ); - rtl8168_mac_ocp_write( tp, 0xFAD4, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xFAD6, 0x9EA0 ); - rtl8168_mac_ocp_write( tp, 0xFAD8, 0x1C1C ); - rtl8168_mac_ocp_write( tp, 0xFADA, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xFADC, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xFADE, 0xFF80 ); - rtl8168_mac_ocp_write( tp, 0xFAE0, 0xB404 ); - rtl8168_mac_ocp_write( tp, 0xFAE2, 0xB405 ); - rtl8168_mac_ocp_write( tp, 0xFAE4, 0xC5D9 ); - rtl8168_mac_ocp_write( tp, 0xFAE6, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFAE8, 0x49CE ); - rtl8168_mac_ocp_write( tp, 0xFAEA, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xFAEC, 0xC41F ); - rtl8168_mac_ocp_write( tp, 0xFAEE, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xFAF0, 0xC41C ); - rtl8168_mac_ocp_write( tp, 0xFAF2, 0x1C13 ); - rtl8168_mac_ocp_write( tp, 0xFAF4, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xFAF6, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xFAF8, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFAFA, 0x49CF ); - rtl8168_mac_ocp_write( tp, 0xFAFC, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xFAFE, 0xB005 ); - rtl8168_mac_ocp_write( tp, 0xFB00, 0xB004 ); - rtl8168_mac_ocp_write( tp, 0xFB02, 0xFF80 ); - rtl8168_mac_ocp_write( tp, 0xFB04, 0xB404 ); - rtl8168_mac_ocp_write( tp, 0xFB06, 0xB405 ); - rtl8168_mac_ocp_write( tp, 0xFB08, 0xC5C7 ); - rtl8168_mac_ocp_write( tp, 0xFB0A, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFB0C, 0x49CE ); - rtl8168_mac_ocp_write( tp, 0xFB0E, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xFB10, 0xC40E ); - rtl8168_mac_ocp_write( tp, 0xFB12, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xFB14, 0xC40A ); - rtl8168_mac_ocp_write( tp, 0xFB16, 0x1C13 ); - rtl8168_mac_ocp_write( tp, 0xFB18, 0x484F ); - rtl8168_mac_ocp_write( tp, 0xFB1A, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xFB1C, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xFB1E, 0x49CF ); - rtl8168_mac_ocp_write( tp, 0xFB20, 0xF1FE ); - rtl8168_mac_ocp_write( tp, 0xFB22, 0xB005 ); - rtl8168_mac_ocp_write( tp, 0xFB24, 0xB004 ); - rtl8168_mac_ocp_write( tp, 0xFB26, 0xFF80 ); - rtl8168_mac_ocp_write( tp, 0xFB28, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFB2A, 0x0481 ); - rtl8168_mac_ocp_write( tp, 0xFB2C, 0x0C81 ); - rtl8168_mac_ocp_write( tp, 0xFB2E, 0x0AE0 ); + rtl8168_mac_ocp_write(tp, 0xF800, 0xE008); + rtl8168_mac_ocp_write(tp, 0xF802, 0xE00A); + rtl8168_mac_ocp_write(tp, 0xF804, 0xE00D); + rtl8168_mac_ocp_write(tp, 0xF806, 0xE02F); + rtl8168_mac_ocp_write(tp, 0xF808, 0xE031); + rtl8168_mac_ocp_write(tp, 0xF80A, 0xE038); + rtl8168_mac_ocp_write(tp, 0xF80C, 0xE03A); + rtl8168_mac_ocp_write(tp, 0xF80E, 0xE051); + rtl8168_mac_ocp_write(tp, 0xF810, 0xC202); + rtl8168_mac_ocp_write(tp, 0xF812, 0xBA00); + rtl8168_mac_ocp_write(tp, 0xF814, 0x0DFC); + rtl8168_mac_ocp_write(tp, 0xF816, 0x7444); + rtl8168_mac_ocp_write(tp, 0xF818, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF81A, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF81C, 0x0A30); + rtl8168_mac_ocp_write(tp, 0xF81E, 0x49D9); + rtl8168_mac_ocp_write(tp, 0xF820, 0xF019); + rtl8168_mac_ocp_write(tp, 0xF822, 0xC520); + rtl8168_mac_ocp_write(tp, 0xF824, 0x64A5); + rtl8168_mac_ocp_write(tp, 0xF826, 0x1400); + rtl8168_mac_ocp_write(tp, 0xF828, 0xF007); + rtl8168_mac_ocp_write(tp, 0xF82A, 0x0C01); + rtl8168_mac_ocp_write(tp, 0xF82C, 0x8CA5); + rtl8168_mac_ocp_write(tp, 0xF82E, 0x1C15); + rtl8168_mac_ocp_write(tp, 0xF830, 0xC515); + rtl8168_mac_ocp_write(tp, 0xF832, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF834, 0xE00F); + rtl8168_mac_ocp_write(tp, 0xF836, 0xC513); + rtl8168_mac_ocp_write(tp, 0xF838, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF83A, 0x48C8); + rtl8168_mac_ocp_write(tp, 0xF83C, 0x48CA); + rtl8168_mac_ocp_write(tp, 0xF83E, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF840, 0xC510); + rtl8168_mac_ocp_write(tp, 0xF842, 0x1B00); + rtl8168_mac_ocp_write(tp, 0xF844, 0x9BA0); + rtl8168_mac_ocp_write(tp, 0xF846, 0x1B1C); + rtl8168_mac_ocp_write(tp, 0xF848, 0x483F); + rtl8168_mac_ocp_write(tp, 0xF84A, 0x9BA2); + rtl8168_mac_ocp_write(tp, 0xF84C, 0x1B04); + rtl8168_mac_ocp_write(tp, 0xF84E, 0xC506); + rtl8168_mac_ocp_write(tp, 0xF850, 0x9BA0); + rtl8168_mac_ocp_write(tp, 0xF852, 0xC603); + rtl8168_mac_ocp_write(tp, 0xF854, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF856, 0x0298); + rtl8168_mac_ocp_write(tp, 0xF858, 0x03DE); + rtl8168_mac_ocp_write(tp, 0xF85A, 0xE434); + rtl8168_mac_ocp_write(tp, 0xF85C, 0xE096); + rtl8168_mac_ocp_write(tp, 0xF85E, 0xE860); + rtl8168_mac_ocp_write(tp, 0xF860, 0xDE20); + rtl8168_mac_ocp_write(tp, 0xF862, 0xD3C0); + rtl8168_mac_ocp_write(tp, 0xF864, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF866, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF868, 0x0A64); + rtl8168_mac_ocp_write(tp, 0xF86A, 0xC707); + rtl8168_mac_ocp_write(tp, 0xF86C, 0x1D00); + rtl8168_mac_ocp_write(tp, 0xF86E, 0x8DE2); + rtl8168_mac_ocp_write(tp, 0xF870, 0x48C1); + rtl8168_mac_ocp_write(tp, 0xF872, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF874, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF876, 0x00AA); + rtl8168_mac_ocp_write(tp, 0xF878, 0xE0C0); + rtl8168_mac_ocp_write(tp, 0xF87A, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF87C, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF87E, 0x0132); + rtl8168_mac_ocp_write(tp, 0xF880, 0xC50C); + rtl8168_mac_ocp_write(tp, 0xF882, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xF884, 0x49CE); + rtl8168_mac_ocp_write(tp, 0xF886, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xF888, 0x1C00); + rtl8168_mac_ocp_write(tp, 0xF88A, 0x9EA0); + rtl8168_mac_ocp_write(tp, 0xF88C, 0x1C1C); + rtl8168_mac_ocp_write(tp, 0xF88E, 0x484F); + rtl8168_mac_ocp_write(tp, 0xF890, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xF892, 0xC402); + rtl8168_mac_ocp_write(tp, 0xF894, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF896, 0x0AFA); + rtl8168_mac_ocp_write(tp, 0xF898, 0xDE20); + rtl8168_mac_ocp_write(tp, 0xF89A, 0xE000); + rtl8168_mac_ocp_write(tp, 0xF89C, 0xE092); + rtl8168_mac_ocp_write(tp, 0xF89E, 0xE430); + rtl8168_mac_ocp_write(tp, 0xF8A0, 0xDE20); + rtl8168_mac_ocp_write(tp, 0xF8A2, 0xE0C0); + rtl8168_mac_ocp_write(tp, 0xF8A4, 0xE860); + rtl8168_mac_ocp_write(tp, 0xF8A6, 0xE84C); + rtl8168_mac_ocp_write(tp, 0xF8A8, 0xB400); + rtl8168_mac_ocp_write(tp, 0xF8AA, 0xB430); + rtl8168_mac_ocp_write(tp, 0xF8AC, 0xE410); + rtl8168_mac_ocp_write(tp, 0xF8AE, 0xC0AE); + rtl8168_mac_ocp_write(tp, 0xF8B0, 0xB407); + rtl8168_mac_ocp_write(tp, 0xF8B2, 0xB406); + rtl8168_mac_ocp_write(tp, 0xF8B4, 0xB405); + rtl8168_mac_ocp_write(tp, 0xF8B6, 0xB404); + rtl8168_mac_ocp_write(tp, 0xF8B8, 0xB403); + rtl8168_mac_ocp_write(tp, 0xF8BA, 0xB402); + rtl8168_mac_ocp_write(tp, 0xF8BC, 0xB401); + rtl8168_mac_ocp_write(tp, 0xF8BE, 0xC7EE); + rtl8168_mac_ocp_write(tp, 0xF8C0, 0x76F4); + rtl8168_mac_ocp_write(tp, 0xF8C2, 0xC2ED); + rtl8168_mac_ocp_write(tp, 0xF8C4, 0xC3ED); + rtl8168_mac_ocp_write(tp, 0xF8C6, 0xC1EF); + rtl8168_mac_ocp_write(tp, 0xF8C8, 0xC5F3); + rtl8168_mac_ocp_write(tp, 0xF8CA, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF8CC, 0x49CD); + rtl8168_mac_ocp_write(tp, 0xF8CE, 0xF001); + rtl8168_mac_ocp_write(tp, 0xF8D0, 0xC5EE); + rtl8168_mac_ocp_write(tp, 0xF8D2, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF8D4, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF8D6, 0xF105); + rtl8168_mac_ocp_write(tp, 0xF8D8, 0xC5E4); + rtl8168_mac_ocp_write(tp, 0xF8DA, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xF8DC, 0x49CE); + rtl8168_mac_ocp_write(tp, 0xF8DE, 0xF00B); + rtl8168_mac_ocp_write(tp, 0xF8E0, 0x7444); + rtl8168_mac_ocp_write(tp, 0xF8E2, 0x484B); + rtl8168_mac_ocp_write(tp, 0xF8E4, 0x9C44); + rtl8168_mac_ocp_write(tp, 0xF8E6, 0x1C10); + rtl8168_mac_ocp_write(tp, 0xF8E8, 0x9C62); + rtl8168_mac_ocp_write(tp, 0xF8EA, 0x1C11); + rtl8168_mac_ocp_write(tp, 0xF8EC, 0x8C60); + rtl8168_mac_ocp_write(tp, 0xF8EE, 0x1C00); + rtl8168_mac_ocp_write(tp, 0xF8F0, 0x9CF6); + rtl8168_mac_ocp_write(tp, 0xF8F2, 0xE0EC); + rtl8168_mac_ocp_write(tp, 0xF8F4, 0x49E7); + rtl8168_mac_ocp_write(tp, 0xF8F6, 0xF016); + rtl8168_mac_ocp_write(tp, 0xF8F8, 0x1D80); + rtl8168_mac_ocp_write(tp, 0xF8FA, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xF8FC, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF8FE, 0x4843); + rtl8168_mac_ocp_write(tp, 0xF900, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF902, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF904, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF906, 0x7444); + rtl8168_mac_ocp_write(tp, 0xF908, 0x48C8); + rtl8168_mac_ocp_write(tp, 0xF90A, 0x48C9); + rtl8168_mac_ocp_write(tp, 0xF90C, 0x48CA); + rtl8168_mac_ocp_write(tp, 0xF90E, 0x9C44); + rtl8168_mac_ocp_write(tp, 0xF910, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF912, 0x4844); + rtl8168_mac_ocp_write(tp, 0xF914, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF916, 0x1E01); + rtl8168_mac_ocp_write(tp, 0xF918, 0xE8DB); + rtl8168_mac_ocp_write(tp, 0xF91A, 0x7420); + rtl8168_mac_ocp_write(tp, 0xF91C, 0x48C1); + rtl8168_mac_ocp_write(tp, 0xF91E, 0x9C20); + rtl8168_mac_ocp_write(tp, 0xF920, 0xE0D5); + rtl8168_mac_ocp_write(tp, 0xF922, 0x49E6); + rtl8168_mac_ocp_write(tp, 0xF924, 0xF02A); + rtl8168_mac_ocp_write(tp, 0xF926, 0x1D40); + rtl8168_mac_ocp_write(tp, 0xF928, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xF92A, 0x74FC); + rtl8168_mac_ocp_write(tp, 0xF92C, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF92E, 0xF124); + rtl8168_mac_ocp_write(tp, 0xF930, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF932, 0xF122); + rtl8168_mac_ocp_write(tp, 0xF934, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF936, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF938, 0xF01F); + rtl8168_mac_ocp_write(tp, 0xF93A, 0xE8D3); + rtl8168_mac_ocp_write(tp, 0xF93C, 0x48C4); + rtl8168_mac_ocp_write(tp, 0xF93E, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF940, 0x1E00); + rtl8168_mac_ocp_write(tp, 0xF942, 0xE8C6); + rtl8168_mac_ocp_write(tp, 0xF944, 0xC5B1); + rtl8168_mac_ocp_write(tp, 0xF946, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF948, 0x49C3); + rtl8168_mac_ocp_write(tp, 0xF94A, 0xF016); + rtl8168_mac_ocp_write(tp, 0xF94C, 0xC5AF); + rtl8168_mac_ocp_write(tp, 0xF94E, 0x74A4); + rtl8168_mac_ocp_write(tp, 0xF950, 0x49C2); + rtl8168_mac_ocp_write(tp, 0xF952, 0xF005); + rtl8168_mac_ocp_write(tp, 0xF954, 0xC5AA); + rtl8168_mac_ocp_write(tp, 0xF956, 0x74B2); + rtl8168_mac_ocp_write(tp, 0xF958, 0x49C9); + rtl8168_mac_ocp_write(tp, 0xF95A, 0xF10E); + rtl8168_mac_ocp_write(tp, 0xF95C, 0xC5A6); + rtl8168_mac_ocp_write(tp, 0xF95E, 0x74A8); + rtl8168_mac_ocp_write(tp, 0xF960, 0x4845); + rtl8168_mac_ocp_write(tp, 0xF962, 0x4846); + rtl8168_mac_ocp_write(tp, 0xF964, 0x4847); + rtl8168_mac_ocp_write(tp, 0xF966, 0x4848); + rtl8168_mac_ocp_write(tp, 0xF968, 0x9CA8); + rtl8168_mac_ocp_write(tp, 0xF96A, 0x74B2); + rtl8168_mac_ocp_write(tp, 0xF96C, 0x4849); + rtl8168_mac_ocp_write(tp, 0xF96E, 0x9CB2); + rtl8168_mac_ocp_write(tp, 0xF970, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF972, 0x484F); + rtl8168_mac_ocp_write(tp, 0xF974, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF976, 0xE0AA); + rtl8168_mac_ocp_write(tp, 0xF978, 0x49E4); + rtl8168_mac_ocp_write(tp, 0xF97A, 0xF018); + rtl8168_mac_ocp_write(tp, 0xF97C, 0x1D10); + rtl8168_mac_ocp_write(tp, 0xF97E, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xF980, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF982, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF984, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF986, 0x4843); + rtl8168_mac_ocp_write(tp, 0xF988, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF98A, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF98C, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF98E, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF990, 0x4844); + rtl8168_mac_ocp_write(tp, 0xF992, 0x4842); + rtl8168_mac_ocp_write(tp, 0xF994, 0x4841); + rtl8168_mac_ocp_write(tp, 0xF996, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF998, 0x1E01); + rtl8168_mac_ocp_write(tp, 0xF99A, 0xE89A); + rtl8168_mac_ocp_write(tp, 0xF99C, 0x7420); + rtl8168_mac_ocp_write(tp, 0xF99E, 0x4841); + rtl8168_mac_ocp_write(tp, 0xF9A0, 0x9C20); + rtl8168_mac_ocp_write(tp, 0xF9A2, 0x7444); + rtl8168_mac_ocp_write(tp, 0xF9A4, 0x4848); + rtl8168_mac_ocp_write(tp, 0xF9A6, 0x9C44); + rtl8168_mac_ocp_write(tp, 0xF9A8, 0xE091); + rtl8168_mac_ocp_write(tp, 0xF9AA, 0x49E5); + rtl8168_mac_ocp_write(tp, 0xF9AC, 0xF03E); + rtl8168_mac_ocp_write(tp, 0xF9AE, 0x1D20); + rtl8168_mac_ocp_write(tp, 0xF9B0, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xF9B2, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF9B4, 0x48C2); + rtl8168_mac_ocp_write(tp, 0xF9B6, 0x4841); + rtl8168_mac_ocp_write(tp, 0xF9B8, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF9BA, 0x1E01); + rtl8168_mac_ocp_write(tp, 0xF9BC, 0x7444); + rtl8168_mac_ocp_write(tp, 0xF9BE, 0x49CA); + rtl8168_mac_ocp_write(tp, 0xF9C0, 0xF103); + rtl8168_mac_ocp_write(tp, 0xF9C2, 0x49C2); + rtl8168_mac_ocp_write(tp, 0xF9C4, 0xF00C); + rtl8168_mac_ocp_write(tp, 0xF9C6, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF9C8, 0xF004); + rtl8168_mac_ocp_write(tp, 0xF9CA, 0x6447); + rtl8168_mac_ocp_write(tp, 0xF9CC, 0x2244); + rtl8168_mac_ocp_write(tp, 0xF9CE, 0xE002); + rtl8168_mac_ocp_write(tp, 0xF9D0, 0x1C01); + rtl8168_mac_ocp_write(tp, 0xF9D2, 0x9C62); + rtl8168_mac_ocp_write(tp, 0xF9D4, 0x1C11); + rtl8168_mac_ocp_write(tp, 0xF9D6, 0x8C60); + rtl8168_mac_ocp_write(tp, 0xF9D8, 0x1C00); + rtl8168_mac_ocp_write(tp, 0xF9DA, 0x9CF6); + rtl8168_mac_ocp_write(tp, 0xF9DC, 0x7444); + rtl8168_mac_ocp_write(tp, 0xF9DE, 0x49C8); + rtl8168_mac_ocp_write(tp, 0xF9E0, 0xF01D); + rtl8168_mac_ocp_write(tp, 0xF9E2, 0x74FC); + rtl8168_mac_ocp_write(tp, 0xF9E4, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF9E6, 0xF11A); + rtl8168_mac_ocp_write(tp, 0xF9E8, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xF9EA, 0xF118); + rtl8168_mac_ocp_write(tp, 0xF9EC, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF9EE, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF9F0, 0xF015); + rtl8168_mac_ocp_write(tp, 0xF9F2, 0x49C6); + rtl8168_mac_ocp_write(tp, 0xF9F4, 0xF113); + rtl8168_mac_ocp_write(tp, 0xF9F6, 0xE875); + rtl8168_mac_ocp_write(tp, 0xF9F8, 0x48C4); + rtl8168_mac_ocp_write(tp, 0xF9FA, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF9FC, 0x7420); + rtl8168_mac_ocp_write(tp, 0xF9FE, 0x48C1); + rtl8168_mac_ocp_write(tp, 0xFA00, 0x9C20); + rtl8168_mac_ocp_write(tp, 0xFA02, 0xC50A); + rtl8168_mac_ocp_write(tp, 0xFA04, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFA06, 0x8CA5); + rtl8168_mac_ocp_write(tp, 0xFA08, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xFA0A, 0xC505); + rtl8168_mac_ocp_write(tp, 0xFA0C, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xFA0E, 0x1C11); + rtl8168_mac_ocp_write(tp, 0xFA10, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xFA12, 0xE00A); + rtl8168_mac_ocp_write(tp, 0xFA14, 0xE434); + rtl8168_mac_ocp_write(tp, 0xFA16, 0xD3C0); + rtl8168_mac_ocp_write(tp, 0xFA18, 0xDC00); + rtl8168_mac_ocp_write(tp, 0xFA1A, 0x7444); + rtl8168_mac_ocp_write(tp, 0xFA1C, 0x49CA); + rtl8168_mac_ocp_write(tp, 0xFA1E, 0xF004); + rtl8168_mac_ocp_write(tp, 0xFA20, 0x48CA); + rtl8168_mac_ocp_write(tp, 0xFA22, 0x9C44); + rtl8168_mac_ocp_write(tp, 0xFA24, 0xE855); + rtl8168_mac_ocp_write(tp, 0xFA26, 0xE052); + rtl8168_mac_ocp_write(tp, 0xFA28, 0x49E8); + rtl8168_mac_ocp_write(tp, 0xFA2A, 0xF024); + rtl8168_mac_ocp_write(tp, 0xFA2C, 0x1D01); + rtl8168_mac_ocp_write(tp, 0xFA2E, 0x8DF5); + rtl8168_mac_ocp_write(tp, 0xFA30, 0x7440); + rtl8168_mac_ocp_write(tp, 0xFA32, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xFA34, 0xF11E); + rtl8168_mac_ocp_write(tp, 0xFA36, 0x7444); + rtl8168_mac_ocp_write(tp, 0xFA38, 0x49C8); + rtl8168_mac_ocp_write(tp, 0xFA3A, 0xF01B); + rtl8168_mac_ocp_write(tp, 0xFA3C, 0x49CA); + rtl8168_mac_ocp_write(tp, 0xFA3E, 0xF119); + rtl8168_mac_ocp_write(tp, 0xFA40, 0xC5EC); + rtl8168_mac_ocp_write(tp, 0xFA42, 0x76A4); + rtl8168_mac_ocp_write(tp, 0xFA44, 0x49E3); + rtl8168_mac_ocp_write(tp, 0xFA46, 0xF015); + rtl8168_mac_ocp_write(tp, 0xFA48, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xFA4A, 0xF103); + rtl8168_mac_ocp_write(tp, 0xFA4C, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xFA4E, 0xF011); + rtl8168_mac_ocp_write(tp, 0xFA50, 0x4849); + rtl8168_mac_ocp_write(tp, 0xFA52, 0x9C44); + rtl8168_mac_ocp_write(tp, 0xFA54, 0x1C00); + rtl8168_mac_ocp_write(tp, 0xFA56, 0x9CF6); + rtl8168_mac_ocp_write(tp, 0xFA58, 0x7444); + rtl8168_mac_ocp_write(tp, 0xFA5A, 0x49C1); + rtl8168_mac_ocp_write(tp, 0xFA5C, 0xF004); + rtl8168_mac_ocp_write(tp, 0xFA5E, 0x6446); + rtl8168_mac_ocp_write(tp, 0xFA60, 0x1E07); + rtl8168_mac_ocp_write(tp, 0xFA62, 0xE003); + rtl8168_mac_ocp_write(tp, 0xFA64, 0x1C01); + rtl8168_mac_ocp_write(tp, 0xFA66, 0x1E03); + rtl8168_mac_ocp_write(tp, 0xFA68, 0x9C62); + rtl8168_mac_ocp_write(tp, 0xFA6A, 0x1C11); + rtl8168_mac_ocp_write(tp, 0xFA6C, 0x8C60); + rtl8168_mac_ocp_write(tp, 0xFA6E, 0xE830); + rtl8168_mac_ocp_write(tp, 0xFA70, 0xE02D); + rtl8168_mac_ocp_write(tp, 0xFA72, 0x49E9); + rtl8168_mac_ocp_write(tp, 0xFA74, 0xF004); + rtl8168_mac_ocp_write(tp, 0xFA76, 0x1D02); + rtl8168_mac_ocp_write(tp, 0xFA78, 0x8DF5); + rtl8168_mac_ocp_write(tp, 0xFA7A, 0xE79C); + rtl8168_mac_ocp_write(tp, 0xFA7C, 0x49E3); + rtl8168_mac_ocp_write(tp, 0xFA7E, 0xF006); + rtl8168_mac_ocp_write(tp, 0xFA80, 0x1D08); + rtl8168_mac_ocp_write(tp, 0xFA82, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xFA84, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xFA86, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xFA88, 0xE73A); + rtl8168_mac_ocp_write(tp, 0xFA8A, 0x49E1); + rtl8168_mac_ocp_write(tp, 0xFA8C, 0xF007); + rtl8168_mac_ocp_write(tp, 0xFA8E, 0x1D02); + rtl8168_mac_ocp_write(tp, 0xFA90, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xFA92, 0x1E01); + rtl8168_mac_ocp_write(tp, 0xFA94, 0xE7A7); + rtl8168_mac_ocp_write(tp, 0xFA96, 0xDE20); + rtl8168_mac_ocp_write(tp, 0xFA98, 0xE410); + rtl8168_mac_ocp_write(tp, 0xFA9A, 0x49E0); + rtl8168_mac_ocp_write(tp, 0xFA9C, 0xF017); + rtl8168_mac_ocp_write(tp, 0xFA9E, 0x1D01); + rtl8168_mac_ocp_write(tp, 0xFAA0, 0x8DF4); + rtl8168_mac_ocp_write(tp, 0xFAA2, 0xC5FA); + rtl8168_mac_ocp_write(tp, 0xFAA4, 0x1C00); + rtl8168_mac_ocp_write(tp, 0xFAA6, 0x8CA0); + rtl8168_mac_ocp_write(tp, 0xFAA8, 0x1C1B); + rtl8168_mac_ocp_write(tp, 0xFAAA, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xFAAC, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFAAE, 0x49CF); + rtl8168_mac_ocp_write(tp, 0xFAB0, 0xF0FE); + rtl8168_mac_ocp_write(tp, 0xFAB2, 0xC5F3); + rtl8168_mac_ocp_write(tp, 0xFAB4, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xFAB6, 0x4849); + rtl8168_mac_ocp_write(tp, 0xFAB8, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xFABA, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xFABC, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xFABE, 0xF006); + rtl8168_mac_ocp_write(tp, 0xFAC0, 0x48C3); + rtl8168_mac_ocp_write(tp, 0xFAC2, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xFAC4, 0xE820); + rtl8168_mac_ocp_write(tp, 0xFAC6, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xFAC8, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xFACA, 0xC432); + rtl8168_mac_ocp_write(tp, 0xFACC, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xFACE, 0xC5E4); + rtl8168_mac_ocp_write(tp, 0xFAD0, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFAD2, 0x49CE); + rtl8168_mac_ocp_write(tp, 0xFAD4, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xFAD6, 0x9EA0); + rtl8168_mac_ocp_write(tp, 0xFAD8, 0x1C1C); + rtl8168_mac_ocp_write(tp, 0xFADA, 0x484F); + rtl8168_mac_ocp_write(tp, 0xFADC, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xFADE, 0xFF80); + rtl8168_mac_ocp_write(tp, 0xFAE0, 0xB404); + rtl8168_mac_ocp_write(tp, 0xFAE2, 0xB405); + rtl8168_mac_ocp_write(tp, 0xFAE4, 0xC5D9); + rtl8168_mac_ocp_write(tp, 0xFAE6, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFAE8, 0x49CE); + rtl8168_mac_ocp_write(tp, 0xFAEA, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xFAEC, 0xC41F); + rtl8168_mac_ocp_write(tp, 0xFAEE, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xFAF0, 0xC41C); + rtl8168_mac_ocp_write(tp, 0xFAF2, 0x1C13); + rtl8168_mac_ocp_write(tp, 0xFAF4, 0x484F); + rtl8168_mac_ocp_write(tp, 0xFAF6, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xFAF8, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFAFA, 0x49CF); + rtl8168_mac_ocp_write(tp, 0xFAFC, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xFAFE, 0xB005); + rtl8168_mac_ocp_write(tp, 0xFB00, 0xB004); + rtl8168_mac_ocp_write(tp, 0xFB02, 0xFF80); + rtl8168_mac_ocp_write(tp, 0xFB04, 0xB404); + rtl8168_mac_ocp_write(tp, 0xFB06, 0xB405); + rtl8168_mac_ocp_write(tp, 0xFB08, 0xC5C7); + rtl8168_mac_ocp_write(tp, 0xFB0A, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFB0C, 0x49CE); + rtl8168_mac_ocp_write(tp, 0xFB0E, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xFB10, 0xC40E); + rtl8168_mac_ocp_write(tp, 0xFB12, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xFB14, 0xC40A); + rtl8168_mac_ocp_write(tp, 0xFB16, 0x1C13); + rtl8168_mac_ocp_write(tp, 0xFB18, 0x484F); + rtl8168_mac_ocp_write(tp, 0xFB1A, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xFB1C, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xFB1E, 0x49CF); + rtl8168_mac_ocp_write(tp, 0xFB20, 0xF1FE); + rtl8168_mac_ocp_write(tp, 0xFB22, 0xB005); + rtl8168_mac_ocp_write(tp, 0xFB24, 0xB004); + rtl8168_mac_ocp_write(tp, 0xFB26, 0xFF80); + rtl8168_mac_ocp_write(tp, 0xFB28, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFB2A, 0x0481); + rtl8168_mac_ocp_write(tp, 0xFB2C, 0x0C81); + rtl8168_mac_ocp_write(tp, 0xFB2E, 0x0AE0); - rtl8168_mac_ocp_write( tp, 0xFC26, 0x8000 ); + rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); - rtl8168_mac_ocp_write( tp, 0xFC28, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFC2A, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFC2C, 0x0297 ); - rtl8168_mac_ocp_write( tp, 0xFC2E, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFC30, 0x00A9 ); - rtl8168_mac_ocp_write( tp, 0xFC32, 0x012D ); - rtl8168_mac_ocp_write( tp, 0xFC34, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xFC36, 0x08DF ); + rtl8168_mac_ocp_write(tp, 0xFC28, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFC2A, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFC2C, 0x0297); + rtl8168_mac_ocp_write(tp, 0xFC2E, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFC30, 0x00A9); + rtl8168_mac_ocp_write(tp, 0xFC32, 0x012D); + rtl8168_mac_ocp_write(tp, 0xFC34, 0x0000); + rtl8168_mac_ocp_write(tp, 0xFC36, 0x08DF); } static void @@ -8768,127 +9825,127 @@ rtl8168_set_mac_mcu_8411b_1(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - rtl8168_mac_ocp_write( tp, 0xF800, 0xE008 ); - rtl8168_mac_ocp_write( tp, 0xF802, 0xE00A ); - rtl8168_mac_ocp_write( tp, 0xF804, 0xE00C ); - rtl8168_mac_ocp_write( tp, 0xF806, 0xE00E ); - rtl8168_mac_ocp_write( tp, 0xF808, 0xE027 ); - rtl8168_mac_ocp_write( tp, 0xF80A, 0xE04F ); - rtl8168_mac_ocp_write( tp, 0xF80C, 0xE05E ); - rtl8168_mac_ocp_write( tp, 0xF80E, 0xE065 ); - rtl8168_mac_ocp_write( tp, 0xF810, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF812, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF814, 0x0000 ); - rtl8168_mac_ocp_write( tp, 0xF816, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF818, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF81A, 0x074C ); - rtl8168_mac_ocp_write( tp, 0xF81C, 0xC302 ); - rtl8168_mac_ocp_write( tp, 0xF81E, 0xBB00 ); - rtl8168_mac_ocp_write( tp, 0xF820, 0x080A ); - rtl8168_mac_ocp_write( tp, 0xF822, 0x6420 ); - rtl8168_mac_ocp_write( tp, 0xF824, 0x48C2 ); - rtl8168_mac_ocp_write( tp, 0xF826, 0x8C20 ); - rtl8168_mac_ocp_write( tp, 0xF828, 0xC516 ); - rtl8168_mac_ocp_write( tp, 0xF82A, 0x64A4 ); - rtl8168_mac_ocp_write( tp, 0xF82C, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF82E, 0xF009 ); - rtl8168_mac_ocp_write( tp, 0xF830, 0x74A2 ); - rtl8168_mac_ocp_write( tp, 0xF832, 0x8CA5 ); - rtl8168_mac_ocp_write( tp, 0xF834, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF836, 0xC50E ); - rtl8168_mac_ocp_write( tp, 0xF838, 0x9CA2 ); - rtl8168_mac_ocp_write( tp, 0xF83A, 0x1C11 ); - rtl8168_mac_ocp_write( tp, 0xF83C, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF83E, 0xE006 ); - rtl8168_mac_ocp_write( tp, 0xF840, 0x74F8 ); - rtl8168_mac_ocp_write( tp, 0xF842, 0x48C4 ); - rtl8168_mac_ocp_write( tp, 0xF844, 0x8CF8 ); - rtl8168_mac_ocp_write( tp, 0xF846, 0xC404 ); - rtl8168_mac_ocp_write( tp, 0xF848, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF84A, 0xC403 ); - rtl8168_mac_ocp_write( tp, 0xF84C, 0xBC00 ); - rtl8168_mac_ocp_write( tp, 0xF84E, 0x0BF2 ); - rtl8168_mac_ocp_write( tp, 0xF850, 0x0C0A ); - rtl8168_mac_ocp_write( tp, 0xF852, 0xE434 ); - rtl8168_mac_ocp_write( tp, 0xF854, 0xD3C0 ); - rtl8168_mac_ocp_write( tp, 0xF856, 0x49D9 ); - rtl8168_mac_ocp_write( tp, 0xF858, 0xF01F ); - rtl8168_mac_ocp_write( tp, 0xF85A, 0xC526 ); - rtl8168_mac_ocp_write( tp, 0xF85C, 0x64A5 ); - rtl8168_mac_ocp_write( tp, 0xF85E, 0x1400 ); - rtl8168_mac_ocp_write( tp, 0xF860, 0xF007 ); - rtl8168_mac_ocp_write( tp, 0xF862, 0x0C01 ); - rtl8168_mac_ocp_write( tp, 0xF864, 0x8CA5 ); - rtl8168_mac_ocp_write( tp, 0xF866, 0x1C15 ); - rtl8168_mac_ocp_write( tp, 0xF868, 0xC51B ); - rtl8168_mac_ocp_write( tp, 0xF86A, 0x9CA0 ); - rtl8168_mac_ocp_write( tp, 0xF86C, 0xE013 ); - rtl8168_mac_ocp_write( tp, 0xF86E, 0xC519 ); - rtl8168_mac_ocp_write( tp, 0xF870, 0x74A0 ); - rtl8168_mac_ocp_write( tp, 0xF872, 0x48C4 ); - rtl8168_mac_ocp_write( tp, 0xF874, 0x8CA0 ); - rtl8168_mac_ocp_write( tp, 0xF876, 0xC516 ); - rtl8168_mac_ocp_write( tp, 0xF878, 0x74A4 ); - rtl8168_mac_ocp_write( tp, 0xF87A, 0x48C8 ); - rtl8168_mac_ocp_write( tp, 0xF87C, 0x48CA ); - rtl8168_mac_ocp_write( tp, 0xF87E, 0x9CA4 ); - rtl8168_mac_ocp_write( tp, 0xF880, 0xC512 ); - rtl8168_mac_ocp_write( tp, 0xF882, 0x1B00 ); - rtl8168_mac_ocp_write( tp, 0xF884, 0x9BA0 ); - rtl8168_mac_ocp_write( tp, 0xF886, 0x1B1C ); - rtl8168_mac_ocp_write( tp, 0xF888, 0x483F ); - rtl8168_mac_ocp_write( tp, 0xF88A, 0x9BA2 ); - rtl8168_mac_ocp_write( tp, 0xF88C, 0x1B04 ); - rtl8168_mac_ocp_write( tp, 0xF88E, 0xC508 ); - rtl8168_mac_ocp_write( tp, 0xF890, 0x9BA0 ); - rtl8168_mac_ocp_write( tp, 0xF892, 0xC505 ); - rtl8168_mac_ocp_write( tp, 0xF894, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF896, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF898, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF89A, 0x0300 ); - rtl8168_mac_ocp_write( tp, 0xF89C, 0x051E ); - rtl8168_mac_ocp_write( tp, 0xF89E, 0xE434 ); - rtl8168_mac_ocp_write( tp, 0xF8A0, 0xE018 ); - rtl8168_mac_ocp_write( tp, 0xF8A2, 0xE092 ); - rtl8168_mac_ocp_write( tp, 0xF8A4, 0xDE20 ); - rtl8168_mac_ocp_write( tp, 0xF8A6, 0xD3C0 ); - rtl8168_mac_ocp_write( tp, 0xF8A8, 0xC50F ); - rtl8168_mac_ocp_write( tp, 0xF8AA, 0x76A4 ); - rtl8168_mac_ocp_write( tp, 0xF8AC, 0x49E3 ); - rtl8168_mac_ocp_write( tp, 0xF8AE, 0xF007 ); - rtl8168_mac_ocp_write( tp, 0xF8B0, 0x49C0 ); - rtl8168_mac_ocp_write( tp, 0xF8B2, 0xF103 ); - rtl8168_mac_ocp_write( tp, 0xF8B4, 0xC607 ); - rtl8168_mac_ocp_write( tp, 0xF8B6, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF8B8, 0xC606 ); - rtl8168_mac_ocp_write( tp, 0xF8BA, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF8BC, 0xC602 ); - rtl8168_mac_ocp_write( tp, 0xF8BE, 0xBE00 ); - rtl8168_mac_ocp_write( tp, 0xF8C0, 0x0C4C ); - rtl8168_mac_ocp_write( tp, 0xF8C2, 0x0C28 ); - rtl8168_mac_ocp_write( tp, 0xF8C4, 0x0C2C ); - rtl8168_mac_ocp_write( tp, 0xF8C6, 0xDC00 ); - rtl8168_mac_ocp_write( tp, 0xF8C8, 0xC707 ); - rtl8168_mac_ocp_write( tp, 0xF8CA, 0x1D00 ); - rtl8168_mac_ocp_write( tp, 0xF8CC, 0x8DE2 ); - rtl8168_mac_ocp_write( tp, 0xF8CE, 0x48C1 ); - rtl8168_mac_ocp_write( tp, 0xF8D0, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF8D2, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF8D4, 0x00AA ); - rtl8168_mac_ocp_write( tp, 0xF8D6, 0xE0C0 ); - rtl8168_mac_ocp_write( tp, 0xF8D8, 0xC502 ); - rtl8168_mac_ocp_write( tp, 0xF8DA, 0xBD00 ); - rtl8168_mac_ocp_write( tp, 0xF8DC, 0x0132 ); + rtl8168_mac_ocp_write(tp, 0xF800, 0xE008); + rtl8168_mac_ocp_write(tp, 0xF802, 0xE00A); + rtl8168_mac_ocp_write(tp, 0xF804, 0xE00C); + rtl8168_mac_ocp_write(tp, 0xF806, 0xE00E); + rtl8168_mac_ocp_write(tp, 0xF808, 0xE027); + rtl8168_mac_ocp_write(tp, 0xF80A, 0xE04F); + rtl8168_mac_ocp_write(tp, 0xF80C, 0xE05E); + rtl8168_mac_ocp_write(tp, 0xF80E, 0xE065); + rtl8168_mac_ocp_write(tp, 0xF810, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF812, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF814, 0x0000); + rtl8168_mac_ocp_write(tp, 0xF816, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF818, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF81A, 0x074C); + rtl8168_mac_ocp_write(tp, 0xF81C, 0xC302); + rtl8168_mac_ocp_write(tp, 0xF81E, 0xBB00); + rtl8168_mac_ocp_write(tp, 0xF820, 0x080A); + rtl8168_mac_ocp_write(tp, 0xF822, 0x6420); + rtl8168_mac_ocp_write(tp, 0xF824, 0x48C2); + rtl8168_mac_ocp_write(tp, 0xF826, 0x8C20); + rtl8168_mac_ocp_write(tp, 0xF828, 0xC516); + rtl8168_mac_ocp_write(tp, 0xF82A, 0x64A4); + rtl8168_mac_ocp_write(tp, 0xF82C, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF82E, 0xF009); + rtl8168_mac_ocp_write(tp, 0xF830, 0x74A2); + rtl8168_mac_ocp_write(tp, 0xF832, 0x8CA5); + rtl8168_mac_ocp_write(tp, 0xF834, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF836, 0xC50E); + rtl8168_mac_ocp_write(tp, 0xF838, 0x9CA2); + rtl8168_mac_ocp_write(tp, 0xF83A, 0x1C11); + rtl8168_mac_ocp_write(tp, 0xF83C, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF83E, 0xE006); + rtl8168_mac_ocp_write(tp, 0xF840, 0x74F8); + rtl8168_mac_ocp_write(tp, 0xF842, 0x48C4); + rtl8168_mac_ocp_write(tp, 0xF844, 0x8CF8); + rtl8168_mac_ocp_write(tp, 0xF846, 0xC404); + rtl8168_mac_ocp_write(tp, 0xF848, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF84A, 0xC403); + rtl8168_mac_ocp_write(tp, 0xF84C, 0xBC00); + rtl8168_mac_ocp_write(tp, 0xF84E, 0x0BF2); + rtl8168_mac_ocp_write(tp, 0xF850, 0x0C0A); + rtl8168_mac_ocp_write(tp, 0xF852, 0xE434); + rtl8168_mac_ocp_write(tp, 0xF854, 0xD3C0); + rtl8168_mac_ocp_write(tp, 0xF856, 0x49D9); + rtl8168_mac_ocp_write(tp, 0xF858, 0xF01F); + rtl8168_mac_ocp_write(tp, 0xF85A, 0xC526); + rtl8168_mac_ocp_write(tp, 0xF85C, 0x64A5); + rtl8168_mac_ocp_write(tp, 0xF85E, 0x1400); + rtl8168_mac_ocp_write(tp, 0xF860, 0xF007); + rtl8168_mac_ocp_write(tp, 0xF862, 0x0C01); + rtl8168_mac_ocp_write(tp, 0xF864, 0x8CA5); + rtl8168_mac_ocp_write(tp, 0xF866, 0x1C15); + rtl8168_mac_ocp_write(tp, 0xF868, 0xC51B); + rtl8168_mac_ocp_write(tp, 0xF86A, 0x9CA0); + rtl8168_mac_ocp_write(tp, 0xF86C, 0xE013); + rtl8168_mac_ocp_write(tp, 0xF86E, 0xC519); + rtl8168_mac_ocp_write(tp, 0xF870, 0x74A0); + rtl8168_mac_ocp_write(tp, 0xF872, 0x48C4); + rtl8168_mac_ocp_write(tp, 0xF874, 0x8CA0); + rtl8168_mac_ocp_write(tp, 0xF876, 0xC516); + rtl8168_mac_ocp_write(tp, 0xF878, 0x74A4); + rtl8168_mac_ocp_write(tp, 0xF87A, 0x48C8); + rtl8168_mac_ocp_write(tp, 0xF87C, 0x48CA); + rtl8168_mac_ocp_write(tp, 0xF87E, 0x9CA4); + rtl8168_mac_ocp_write(tp, 0xF880, 0xC512); + rtl8168_mac_ocp_write(tp, 0xF882, 0x1B00); + rtl8168_mac_ocp_write(tp, 0xF884, 0x9BA0); + rtl8168_mac_ocp_write(tp, 0xF886, 0x1B1C); + rtl8168_mac_ocp_write(tp, 0xF888, 0x483F); + rtl8168_mac_ocp_write(tp, 0xF88A, 0x9BA2); + rtl8168_mac_ocp_write(tp, 0xF88C, 0x1B04); + rtl8168_mac_ocp_write(tp, 0xF88E, 0xC508); + rtl8168_mac_ocp_write(tp, 0xF890, 0x9BA0); + rtl8168_mac_ocp_write(tp, 0xF892, 0xC505); + rtl8168_mac_ocp_write(tp, 0xF894, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF896, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF898, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF89A, 0x0300); + rtl8168_mac_ocp_write(tp, 0xF89C, 0x051E); + rtl8168_mac_ocp_write(tp, 0xF89E, 0xE434); + rtl8168_mac_ocp_write(tp, 0xF8A0, 0xE018); + rtl8168_mac_ocp_write(tp, 0xF8A2, 0xE092); + rtl8168_mac_ocp_write(tp, 0xF8A4, 0xDE20); + rtl8168_mac_ocp_write(tp, 0xF8A6, 0xD3C0); + rtl8168_mac_ocp_write(tp, 0xF8A8, 0xC50F); + rtl8168_mac_ocp_write(tp, 0xF8AA, 0x76A4); + rtl8168_mac_ocp_write(tp, 0xF8AC, 0x49E3); + rtl8168_mac_ocp_write(tp, 0xF8AE, 0xF007); + rtl8168_mac_ocp_write(tp, 0xF8B0, 0x49C0); + rtl8168_mac_ocp_write(tp, 0xF8B2, 0xF103); + rtl8168_mac_ocp_write(tp, 0xF8B4, 0xC607); + rtl8168_mac_ocp_write(tp, 0xF8B6, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF8B8, 0xC606); + rtl8168_mac_ocp_write(tp, 0xF8BA, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF8BC, 0xC602); + rtl8168_mac_ocp_write(tp, 0xF8BE, 0xBE00); + rtl8168_mac_ocp_write(tp, 0xF8C0, 0x0C4C); + rtl8168_mac_ocp_write(tp, 0xF8C2, 0x0C28); + rtl8168_mac_ocp_write(tp, 0xF8C4, 0x0C2C); + rtl8168_mac_ocp_write(tp, 0xF8C6, 0xDC00); + rtl8168_mac_ocp_write(tp, 0xF8C8, 0xC707); + rtl8168_mac_ocp_write(tp, 0xF8CA, 0x1D00); + rtl8168_mac_ocp_write(tp, 0xF8CC, 0x8DE2); + rtl8168_mac_ocp_write(tp, 0xF8CE, 0x48C1); + rtl8168_mac_ocp_write(tp, 0xF8D0, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF8D2, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF8D4, 0x00AA); + rtl8168_mac_ocp_write(tp, 0xF8D6, 0xE0C0); + rtl8168_mac_ocp_write(tp, 0xF8D8, 0xC502); + rtl8168_mac_ocp_write(tp, 0xF8DA, 0xBD00); + rtl8168_mac_ocp_write(tp, 0xF8DC, 0x0132); - rtl8168_mac_ocp_write( tp, 0xFC26, 0x8000 ); + rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); - rtl8168_mac_ocp_write( tp, 0xFC2A, 0x0743 ); - rtl8168_mac_ocp_write( tp, 0xFC2C, 0x0801 ); - rtl8168_mac_ocp_write( tp, 0xFC2E, 0x0BE9 ); - rtl8168_mac_ocp_write( tp, 0xFC30, 0x02FD ); - rtl8168_mac_ocp_write( tp, 0xFC32, 0x0C25 ); - rtl8168_mac_ocp_write( tp, 0xFC34, 0x00A9 ); - rtl8168_mac_ocp_write( tp, 0xFC36, 0x012D ); + rtl8168_mac_ocp_write(tp, 0xFC2A, 0x0743); + rtl8168_mac_ocp_write(tp, 0xFC2C, 0x0801); + rtl8168_mac_ocp_write(tp, 0xFC2E, 0x0BE9); + rtl8168_mac_ocp_write(tp, 0xFC30, 0x02FD); + rtl8168_mac_ocp_write(tp, 0xFC32, 0x0C25); + rtl8168_mac_ocp_write(tp, 0xFC34, 0x00A9); + rtl8168_mac_ocp_write(tp, 0xFC36, 0x012D); } static void @@ -8928,9 +9985,8 @@ rtl8168_set_mac_mcu_8168ep_1(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168ep_1); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168ep_1); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168ep_1[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -8971,9 +10027,8 @@ rtl8168_set_mac_mcu_8168ep_2(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168ep_2); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168ep_2); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168ep_2[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9014,9 +10069,8 @@ rtl8168_set_mac_mcu_8168h_2(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168h_1); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168h_1); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168h_1[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9037,19 +10091,19 @@ rtl8168_set_mac_mcu_8168h_3(struct net_device *dev) 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, @@ -9093,14 +10147,13 @@ rtl8168_set_mac_mcu_8168h_3(struct net_device *dev) 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); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168h_3); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168h_3); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168h_3[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9111,6 +10164,12 @@ rtl8168_set_mac_mcu_8168h_3(struct net_device *dev) rtl8168_mac_ocp_write(tp, 0xFC38, 0x0010); } +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) { @@ -9158,9 +10217,8 @@ rtl8168_set_mac_mcu_8168fp_1(struct net_device *dev) 0x4830, 0x4837, 0xC502, 0xBD00, 0x0A86 }; - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_1_1); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_1_1); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168fp_1_1[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9173,7 +10231,7 @@ rtl8168_set_mac_mcu_8168fp_1(struct net_device *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, @@ -9219,9 +10277,8 @@ rtl8168_set_mac_mcu_8168fp_1(struct net_device *dev) 0x0000 }; - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_1_2); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_1_2); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168fp_1_2[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9239,7 +10296,7 @@ rtl8168_set_mac_mcu_8168fp_1(struct net_device *dev) 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); @@ -9260,9 +10317,8 @@ rtl8168_set_mac_mcu_8168fp_8116as_2(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_8116as_2); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_8116as_2); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168fp_8116as_2[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9296,9 +10352,8 @@ _rtl8168_set_mac_mcu_8168fp_2(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_2); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_2); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168fp_2[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9347,9 +10402,8 @@ rtl8168_set_mac_mcu_8168fp_3(struct net_device *dev) rtl8168_hw_disable_mac_mcu_bps(dev); - for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_3); i++) { + for (i = 0; i < ARRAY_SIZE(mcu_patch_code_8168fp_3); i++) rtl8168_mac_ocp_write(tp, 0xF800 + i * 2, mcu_patch_code_8168fp_3[i]); - } rtl8168_mac_ocp_write(tp, 0xFC26, 0x8000); @@ -9393,6 +10447,7 @@ rtl8168_hw_mac_mcu_config(struct net_device *dev) 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: @@ -9408,6 +10463,9 @@ rtl8168_hw_mac_mcu_config(struct net_device *dev) 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 @@ -9422,7 +10480,7 @@ static void rtl8168_release_firmware(struct rtl8168_private *tp) } } -void rtl8168_apply_firmware(struct rtl8168_private *tp) +static void rtl8168_apply_firmware(struct rtl8168_private *tp) { /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ if (tp->rtl_fw) { @@ -9458,7 +10516,7 @@ rtl8168_hw_init(struct net_device *dev) //Disable UPS if (HW_SUPPORT_UPS_MODE(tp)) - rtl8168_mac_ocp_write(tp, 0xD400, rtl8168_mac_ocp_read( tp, 0xD400) & ~(BIT_0)); + rtl8168_mac_ocp_write(tp, 0xD400, rtl8168_mac_ocp_read(tp, 0xD400) & ~(BIT_0)); //Disable DMA Aggregation switch (tp->mcfg) { @@ -9469,9 +10527,11 @@ rtl8168_hw_init(struct net_device *dev) case CFG_METHOD_33: case CFG_METHOD_34: case CFG_METHOD_35: - 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)); + 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)); rtl8168_mac_ocp_write(tp, 0xC094, 0x0); rtl8168_mac_ocp_write(tp, 0xC09E, 0x0); break; @@ -9495,31 +10555,6 @@ rtl8168_hw_init(struct net_device *dev) 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); @@ -9534,7 +10569,8 @@ rtl8168_hw_init(struct net_device *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) if (!tp->dash_printer_enabled) rtl8168_disable_ocp_phy_power_saving(dev); @@ -9549,7 +10585,7 @@ rtl8168_hw_init(struct net_device *dev) case CFG_METHOD_23: case CFG_METHOD_24: csi_tmp = rtl8168_eri_read(tp, 0x1AB, 1, ERIAR_ExGMAC); - csi_tmp |= ( BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7 ); + csi_tmp |= (BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7); rtl8168_eri_write(tp, 0x1AB, 1, csi_tmp, ERIAR_ExGMAC); break; } @@ -9603,8 +10639,7 @@ rtl8168_hw_ephy_config(struct net_device *dev) ClearAndSetPCIePhyBit(tp, 0x03, BIT_10, - BIT_5 - ); + BIT_5); break; case CFG_METHOD_9: @@ -9615,14 +10650,12 @@ rtl8168_hw_ephy_config(struct net_device *dev) ClearAndSetPCIePhyBit(tp, 0x03, 0xFFB0, - 0x05B0 - ); + 0x05B0); } else { ClearAndSetPCIePhyBit(tp, 0x03, 0xFFF0, - 0x05F0 - ); + 0x05F0); } rtl8168_ephy_write(tp, 0x06, 0xB271); rtl8168_ephy_write(tp, 0x07, 0xCE00); @@ -9635,8 +10668,7 @@ rtl8168_hw_ephy_config(struct net_device *dev) ClearAndSetPCIePhyBit(tp, 0x03, 0xFFF0, - 0x01B0 - ); + 0x01B0); rtl8168_ephy_write(tp, 0x1A, 0x0546); rtl8168_ephy_write(tp, 0x1C, 0x80C4); rtl8168_ephy_write(tp, 0x1D, 0x78E5); @@ -9835,11 +10867,10 @@ rtl8168_hw_ephy_config(struct net_device *dev) break; case CFG_METHOD_26: ClearPCIePhyBit(tp, 0x00, BIT_3); - ClearAndSetPCIePhyBit( tp, - 0x0C, - (BIT_13 | BIT_12 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_4), - (BIT_5 | BIT_11) - ); + ClearAndSetPCIePhyBit(tp, + 0x0C, + (BIT_13 | BIT_12 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_4), + (BIT_5 | BIT_11)); SetPCIePhyBit(tp, 0x1E, BIT_0); ClearPCIePhyBit(tp, 0x19, BIT_15); @@ -9883,12 +10914,12 @@ rtl8168_hw_ephy_config(struct net_device *dev) ClearAndSetPCIePhyBit(tp, 0x0C, BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_8 | BIT_7 | BIT_6 | BIT_5, - BIT_9 | BIT_4 - ); + BIT_9 | BIT_4); break; case CFG_METHOD_29: case CFG_METHOD_30: + case CFG_METHOD_37: ClearPCIePhyBit(tp, 0x1E, BIT_11); SetPCIePhyBit(tp, 0x1E, BIT_0); @@ -9908,13 +10939,11 @@ rtl8168_hw_ephy_config(struct net_device *dev) ClearAndSetPCIePhyBit(tp, 0x19, BIT_6, - (BIT_12| BIT_8) - ); + (BIT_12| BIT_8)); ClearAndSetPCIePhyBit(tp, 0x59, BIT_6, - (BIT_12| BIT_8) - ); + (BIT_12| BIT_8)); ClearPCIePhyBit(tp, 0x0C, BIT_4); ClearPCIePhyBit(tp, 0x4C, BIT_4); @@ -9922,13 +10951,21 @@ rtl8168_hw_ephy_config(struct net_device *dev) 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; } @@ -9942,7 +10979,7 @@ rtl8168_set_phy_mcu_patch_request(struct rtl8168_private *tp) 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); @@ -9972,7 +11009,7 @@ rtl8168_clear_phy_mcu_patch_request(struct rtl8168_private *tp) 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); @@ -10032,6 +11069,8 @@ rtl8168_get_hw_phy_mcu_code_ver(struct rtl8168_private *tp) 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); @@ -10092,7 +11131,7 @@ rtl8168_check_hw_phy_mcu_code_ver(struct net_device *dev) tp->hw_ram_code_ver = rtl8168_get_hw_phy_mcu_code_ver(tp); - if ( tp->hw_ram_code_ver == tp->sw_ram_code_ver) { + if (tp->hw_ram_code_ver == tp->sw_ram_code_ver) { ram_code_ver_match = 1; tp->HwHasWrRamCodeToMicroP = TRUE; } @@ -10140,6 +11179,8 @@ rtl8168_write_hw_phy_mcu_code_ver(struct net_device *dev) 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); @@ -10174,7 +11215,7 @@ rtl8168_phy_ram_code_check(struct net_device *dev) 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); @@ -10195,7 +11236,7 @@ rtl8168_phy_ram_code_check(struct net_device *dev) 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); @@ -10221,7 +11262,7 @@ rtl8168_phy_ram_code_check(struct net_device *dev) 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); @@ -10231,7 +11272,7 @@ rtl8168_phy_ram_code_check(struct net_device *dev) } } - retval = rtl8168_clear_phy_mcu_patch_request(tp); + rtl8168_clear_phy_mcu_patch_request(tp); mdelay(2); break; @@ -21035,7 +22076,7 @@ rtl8168_set_phy_mcu_8168h_1(struct net_device *dev) 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); @@ -21068,23 +22109,45 @@ rtl8168_set_phy_mcu_8168h_2(struct net_device *dev) 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); @@ -21418,15 +22481,57 @@ rtl8168_set_phy_mcu_8168h_3(struct net_device *dev) 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); @@ -22004,11 +23109,14 @@ rtl8168_init_hw_phy_mcu(struct net_device *dev) 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) @@ -23659,11 +24767,6 @@ rtl8168_hw_phy_config(struct net_device *dev) rtl8168_mdio_write(tp, 0x06, rtl8168_mdio_read(tp, 0x06) & ~BIT_8); rtl8168_mdio_write(tp, 0x1f, 0x0000); - rtl8168_mdio_write(tp, 0x1f, 0x0007); //nvidia for 8119i 10M_pll_off - rtl8168_mdio_write(tp, 0x1e, 0x0023); - rtl8168_mdio_write(tp, 0x17, rtl8168_mdio_read(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); @@ -23723,10 +24826,12 @@ rtl8168_hw_phy_config(struct net_device *dev) rtl8168_mdio_write(tp, 0x06, rtl8168_mdio_read(tp, 0x06) & ~BIT_8); rtl8168_mdio_write(tp, 0x1f, 0x0000); - rtl8168_mdio_write(tp, 0x1f, 0x0007); //nvidia for 8119i 10M_pll_off - rtl8168_mdio_write(tp, 0x1e, 0x0023); - rtl8168_mdio_write(tp, 0x17, rtl8168_mdio_read(tp, 0x17) & ~BIT_1); - 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); @@ -23929,8 +25034,7 @@ rtl8168_hw_phy_config(struct net_device *dev) ClearAndSetEthPhyBit(tp, 0x11, BIT_13, - BIT_14 - ); + BIT_14); rtl8168_mdio_write(tp, 0x1F, 0x0000); if (aspm) { @@ -24114,124 +25218,110 @@ rtl8168_hw_phy_config(struct net_device *dev) } else if (tp->mcfg == CFG_METHOD_29) { rtl8168_mdio_write(tp, 0x1F, 0x0A43); rtl8168_mdio_write(tp, 0x13, 0x809b); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xF800 , - 0x8000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xF800 , + 0x8000); rtl8168_mdio_write(tp, 0x13, 0x80A2); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x8000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x8000); rtl8168_mdio_write(tp, 0x13, 0x80A4); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x8500 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x8500); rtl8168_mdio_write(tp, 0x13, 0x809C); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0xbd00 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0xbd00); rtl8168_mdio_write(tp, 0x1F, 0x0000); rtl8168_mdio_write(tp, 0x1F, 0x0A43); rtl8168_mdio_write(tp, 0x13, 0x80AD); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xF800 , - 0x7000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xF800 , + 0x7000); rtl8168_mdio_write(tp, 0x13, 0x80B4); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x5000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x5000); rtl8168_mdio_write(tp, 0x13, 0x80AC); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x4000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x4000); rtl8168_mdio_write(tp, 0x1F, 0x0000); rtl8168_mdio_write(tp, 0x1F, 0x0A43); rtl8168_mdio_write(tp, 0x13, 0x808E); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x1200 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x1200); rtl8168_mdio_write(tp, 0x13, 0x8090); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0xE500 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0xE500); rtl8168_mdio_write(tp, 0x13, 0x8092); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x9F00 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x9F00); rtl8168_mdio_write(tp, 0x1F, 0x0000); if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { u16 dout_tapbin; dout_tapbin = 0x0000; - rtl8168_mdio_write( tp, 0x1F, 0x0A46 ); - gphy_val = rtl8168_mdio_read( tp, 0x13 ); + rtl8168_mdio_write(tp, 0x1F, 0x0A46); + gphy_val = rtl8168_mdio_read(tp, 0x13); gphy_val &= (BIT_1|BIT_0); gphy_val <<= 2; dout_tapbin |= gphy_val; - gphy_val = rtl8168_mdio_read( tp, 0x12 ); + gphy_val = rtl8168_mdio_read(tp, 0x12); gphy_val &= (BIT_15|BIT_14); gphy_val >>= 14; dout_tapbin |= gphy_val; - dout_tapbin = ~( dout_tapbin^BIT_3 ); + dout_tapbin = ~(dout_tapbin^BIT_3); dout_tapbin <<= 12; dout_tapbin &= 0xF000; - rtl8168_mdio_write( tp, 0x1F, 0x0A43 ); + rtl8168_mdio_write(tp, 0x1F, 0x0A43); - rtl8168_mdio_write( tp, 0x13, 0x827A ); - ClearAndSetEthPhyBit( tp, - 0x14, - BIT_15|BIT_14|BIT_13|BIT_12, - dout_tapbin - ); + rtl8168_mdio_write(tp, 0x13, 0x827A); + ClearAndSetEthPhyBit(tp, + 0x14, + BIT_15|BIT_14|BIT_13|BIT_12, + dout_tapbin); - rtl8168_mdio_write( tp, 0x13, 0x827B ); - ClearAndSetEthPhyBit( tp, - 0x14, - BIT_15|BIT_14|BIT_13|BIT_12, - dout_tapbin - ); + rtl8168_mdio_write(tp, 0x13, 0x827B); + ClearAndSetEthPhyBit(tp, + 0x14, + BIT_15|BIT_14|BIT_13|BIT_12, + dout_tapbin); - rtl8168_mdio_write( tp, 0x13, 0x827C ); - ClearAndSetEthPhyBit( tp, - 0x14, - BIT_15|BIT_14|BIT_13|BIT_12, - dout_tapbin - ); + rtl8168_mdio_write(tp, 0x13, 0x827C); + ClearAndSetEthPhyBit(tp, + 0x14, + BIT_15|BIT_14|BIT_13|BIT_12, + dout_tapbin); - rtl8168_mdio_write( tp, 0x13, 0x827D ); - ClearAndSetEthPhyBit( tp, - 0x14, - BIT_15|BIT_14|BIT_13|BIT_12, - dout_tapbin - ); + rtl8168_mdio_write(tp, 0x13, 0x827D); + ClearAndSetEthPhyBit(tp, + 0x14, + BIT_15|BIT_14|BIT_13|BIT_12, + dout_tapbin); rtl8168_mdio_write(tp, 0x1F, 0x0A43); rtl8168_mdio_write(tp, 0x13, 0x8011); @@ -24241,52 +25331,48 @@ rtl8168_hw_phy_config(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1F, 0x0A44); - rtl8168_clear_eth_phy_bit(tp, 0x11, (BIT_11 | BIT_7)); - rtl8168_set_eth_phy_bit(tp, 0x11, (BIT_11)); - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - rtl8168_clear_eth_phy_bit(tp, 0x10, (BIT_0)); + rtl8168_set_eth_phy_bit(tp, 0x11, BIT_11); rtl8168_mdio_write(tp, 0x1F, 0x0000); rtl8168_mdio_write(tp, 0x1F, 0x0BCA); - ClearAndSetEthPhyBit( tp, - 0x17, - (BIT_13 | BIT_12) , - BIT_14 - ); + ClearAndSetEthPhyBit(tp, + 0x17, + (BIT_13 | BIT_12) , + BIT_14); rtl8168_mdio_write(tp, 0x1F, 0x0000); rtl8168_mdio_write(tp, 0x1F, 0x0A43); rtl8168_mdio_write(tp, 0x13, 0x803F); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); rtl8168_mdio_write(tp, 0x13, 0x8047); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); rtl8168_mdio_write(tp, 0x13, 0x804F); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); rtl8168_mdio_write(tp, 0x13, 0x8057); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); rtl8168_mdio_write(tp, 0x13, 0x805F); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); - rtl8168_mdio_write(tp, 0x13, 0x8067 ); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); - rtl8168_mdio_write(tp, 0x13, 0x806F ); - rtl8168_clear_eth_phy_bit( tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_mdio_write(tp, 0x13, 0x8067); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); + rtl8168_mdio_write(tp, 0x13, 0x806F); + rtl8168_clear_eth_phy_bit(tp, 0x14, (BIT_13 | BIT_12)); 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_set_eth_phy_bit(tp, 0x10, BIT_2); 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, - 0x14, - BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0, - 0x0A ); + ClearAndSetEthPhyBit(tp, + 0x14, + BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0, + 0x0A); if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { rtl8168_mdio_write(tp, 0x1F, 0x0A43); @@ -24297,10 +25383,7 @@ rtl8168_hw_phy_config(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1F, 0x0A44); - rtl8168_clear_eth_phy_bit(tp, 0x11, (BIT_11 | BIT_7)); - rtl8168_set_eth_phy_bit(tp, 0x11, (BIT_11)); - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - rtl8168_clear_eth_phy_bit(tp, 0x10, (BIT_0)); + rtl8168_set_eth_phy_bit(tp, 0x11, BIT_11); rtl8168_mdio_write(tp, 0x1F, 0x0000); if (tp->RequireAdcBiasPatch) { @@ -24313,10 +25396,10 @@ rtl8168_hw_phy_config(struct net_device *dev) u16 rlen; rtl8168_mdio_write(tp, 0x1F, 0x0BCD); - gphy_val = rtl8168_mdio_read( tp, 0x16 ); + gphy_val = rtl8168_mdio_read(tp, 0x16); gphy_val &= 0x000F; - if ( gphy_val > 3 ) { + if (gphy_val > 3) { rlen = gphy_val - 3; } else { rlen = 0; @@ -24351,10 +25434,21 @@ rtl8168_hw_phy_config(struct net_device *dev) 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_set_eth_phy_bit( tp, 0x10, BIT_2 ); + rtl8168_set_eth_phy_bit(tp, 0x10, BIT_2); rtl8168_mdio_write(tp, 0x1F, 0x0000); } } @@ -24362,138 +25456,117 @@ rtl8168_hw_phy_config(struct net_device *dev) tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) { rtl8168_mdio_write(tp, 0x1F, 0x0A43); rtl8168_mdio_write(tp, 0x13, 0x808E); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x4800 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x4800); rtl8168_mdio_write(tp, 0x13, 0x8090); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0xCC00 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0xCC00); rtl8168_mdio_write(tp, 0x13, 0x8092); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0xB000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0xB000); rtl8168_mdio_write(tp, 0x13, 0x8088); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x6000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x6000); rtl8168_mdio_write(tp, 0x13, 0x808B); - ClearAndSetEthPhyBit( tp, - 0x14, - 0x3F00 , - 0x0B00 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0x3F00 , + 0x0B00); rtl8168_mdio_write(tp, 0x13, 0x808D); - ClearAndSetEthPhyBit( tp, - 0x14, - 0x1F00 , - 0x0600 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0x1F00 , + 0x0600); rtl8168_mdio_write(tp, 0x13, 0x808C); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0xB000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0xB000); rtl8168_mdio_write(tp, 0x13, 0x80A0); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x2800 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x2800); rtl8168_mdio_write(tp, 0x13, 0x80A2); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x5000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x5000); rtl8168_mdio_write(tp, 0x13, 0x809B); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xF800 , - 0xB000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xF800 , + 0xB000); rtl8168_mdio_write(tp, 0x13, 0x809A); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x4B00 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x4B00); rtl8168_mdio_write(tp, 0x13, 0x809D); - ClearAndSetEthPhyBit( tp, - 0x14, - 0x3F00 , - 0x0800 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0x3F00 , + 0x0800); rtl8168_mdio_write(tp, 0x13, 0x80A1); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x7000 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x7000); rtl8168_mdio_write(tp, 0x13, 0x809F); - ClearAndSetEthPhyBit( tp, - 0x14, - 0x1F00 , - 0x0300 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0x1F00 , + 0x0300); rtl8168_mdio_write(tp, 0x13, 0x809E); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x8800 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x8800); rtl8168_mdio_write(tp, 0x13, 0x80B2); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x2200 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x2200); rtl8168_mdio_write(tp, 0x13, 0x80AD); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xF800 , - 0x9800 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xF800 , + 0x9800); rtl8168_mdio_write(tp, 0x13, 0x80AF); - ClearAndSetEthPhyBit( tp, - 0x14, - 0x3F00 , - 0x0800 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0x3F00 , + 0x0800); rtl8168_mdio_write(tp, 0x13, 0x80B3); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x6F00 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x6F00); rtl8168_mdio_write(tp, 0x13, 0x80B1); - ClearAndSetEthPhyBit( tp, - 0x14, - 0x1F00 , - 0x0300 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0x1F00 , + 0x0300); rtl8168_mdio_write(tp, 0x13, 0x80B0); - ClearAndSetEthPhyBit( tp, - 0x14, - 0xFF00 , - 0x9300 - ); + ClearAndSetEthPhyBit(tp, + 0x14, + 0xFF00 , + 0x9300); rtl8168_mdio_write(tp, 0x1F, 0x0000); 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); @@ -24509,16 +25582,13 @@ rtl8168_hw_phy_config(struct net_device *dev) if (!HW_SUPP_SERDES_PHY(tp) && HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { rtl8168_mdio_write(tp, 0x1F, 0x0A43); - rtl8168_set_eth_phy_bit( tp, 0x10, BIT_2 ); + rtl8168_set_eth_phy_bit(tp, 0x10, BIT_2); rtl8168_mdio_write(tp, 0x1F, 0x0000); } } } else if (tp->mcfg == CFG_METHOD_35) { rtl8168_mdio_write(tp, 0x1F, 0x0A44); - rtl8168_clear_eth_phy_bit(tp, 0x11, (BIT_11 | BIT_7)); - rtl8168_set_eth_phy_bit(tp, 0x11, (BIT_11)); - rtl8168_mdio_write(tp, 0x1F, 0x0A43); - rtl8168_clear_eth_phy_bit(tp, 0x10, (BIT_0)); + rtl8168_set_eth_phy_bit(tp, 0x11, BIT_11); rtl8168_mdio_write(tp, 0x1F, 0x0000); @@ -24635,7 +25705,25 @@ rtl8168_hw_phy_config(struct net_device *dev) 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_set_eth_phy_bit(tp, 0x10, BIT_2); + 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); } } @@ -24664,10 +25752,10 @@ rtl8168_hw_phy_config(struct net_device *dev) } 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 ); + rtl8168_set_eth_phy_bit(tp, 0x11, BIT_7); rtl8168_mdio_write(tp, 0x1F, 0x0000); } @@ -24677,7 +25765,8 @@ rtl8168_hw_phy_config(struct net_device *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) { if (aspm) rtl8168_enable_ocp_phy_power_saving(dev); } @@ -24685,13 +25774,14 @@ rtl8168_hw_phy_config(struct net_device *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); @@ -24726,6 +25816,7 @@ static inline void rtl8168_request_link_timer(struct net_device *dev) #endif mod_timer(timer, jiffies + RTL8168_LINK_TIMEOUT); } +*/ #ifdef CONFIG_NET_POLL_CONTROLLER /* @@ -24737,16 +25828,24 @@ static void 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_tbl[i]; + struct r8168_napi *r8168napi = &tp->r8168napi[i]; - 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) @@ -24781,6 +25880,8 @@ 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; } @@ -24819,11 +25920,31 @@ rtl8168_set_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: RTL_W32(tp, 0x8C, tp->bios_setting); break; } } +static void +rtl8168_setup_mqs_reg(struct rtl8168_private *tp) +{ + //tx + tp->tx_ring[0].tdsar_reg = TxDescStartAddrLow; + tp->tx_ring[1].tdsar_reg = TxHDescStartAddrLow; + + tp->isr_reg[0] = IntrStatus; + tp->isr_reg[1] = IntrStatus1; + tp->isr_reg[2] = IntrStatus2; + tp->isr_reg[3] = IntrStatus3; + + tp->imr_reg[0] = IntrMask; + tp->imr_reg[1] = IntrMask1; + tp->imr_reg[2] = IntrMask2; + tp->imr_reg[3] = IntrMask3; +} + static void rtl8168_init_software_variable(struct net_device *dev) { @@ -24832,8 +25953,12 @@ rtl8168_init_software_variable(struct net_device *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: @@ -24886,6 +26011,8 @@ rtl8168_init_software_variable(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->HwSuppNowIsOobVer = 1; break; } @@ -24906,6 +26033,8 @@ rtl8168_init_software_variable(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->HwSuppPhyOcpVer = 1; break; } @@ -24918,6 +26047,7 @@ rtl8168_init_software_variable(struct net_device *dev) case CFG_METHOD_33: case CFG_METHOD_34: case CFG_METHOD_35: + case CFG_METHOD_36: tp->HwSuppUpsVer = 1; break; } @@ -24960,6 +26090,8 @@ rtl8168_init_software_variable(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->HwSuppAspmClkIntrLock = 1; break; } @@ -24981,8 +26113,20 @@ rtl8168_init_software_variable(struct net_device *dev) 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); @@ -24995,9 +26139,15 @@ rtl8168_init_software_variable(struct net_device *dev) 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; } } @@ -25017,8 +26167,6 @@ rtl8168_init_software_variable(struct net_device *dev) 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: @@ -25040,11 +26188,11 @@ rtl8168_init_software_variable(struct net_device *dev) #ifdef ENABLE_DASH_SUPPORT if (tp->DASH) { if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { - tp->timer_intr_mask |= ( ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); - tp->intr_mask |= ( ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); + tp->timer_intr_mask |= (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); + tp->intr_mask |= (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); } else { - tp->timer_intr_mask |= ( ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK ); - tp->intr_mask |= ( ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK ); + tp->timer_intr_mask |= (ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK); + tp->intr_mask |= (ISRIMR_DP_DASH_OK | ISRIMR_DP_HOST_OK | ISRIMR_DP_REQSYS_OK); } } #endif @@ -25065,6 +26213,8 @@ rtl8168_init_software_variable(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->org_pci_offset_99 = rtl8168_csi_fun0_read_byte(tp, 0x99); tp->org_pci_offset_99 &= ~(BIT_5|BIT_6); break; @@ -25078,6 +26228,8 @@ rtl8168_init_software_variable(struct net_device *dev) 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: @@ -25133,7 +26285,8 @@ rtl8168_init_software_variable(struct net_device *dev) 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) { @@ -25150,22 +26303,23 @@ rtl8168_init_software_variable(struct net_device *dev) } 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; - rtl8168_mac_ocp_write( tp, 0xDD02, 0x807D); - TmpUshort = rtl8168_mac_ocp_read( tp, 0xDD02 ); - ioffset_p3 = ( (TmpUshort & BIT_7) >>7 ); + rtl8168_mac_ocp_write(tp, 0xDD02, 0x807D); + TmpUshort = rtl8168_mac_ocp_read(tp, 0xDD02); + ioffset_p3 = ((TmpUshort & BIT_7) >>7); ioffset_p3 <<= 3; - TmpUshort = rtl8168_mac_ocp_read( tp, 0xDD00 ); + TmpUshort = rtl8168_mac_ocp_read(tp, 0xDD00); ioffset_p3 |= ((TmpUshort & (BIT_15 | BIT_14 | BIT_13))>>13); ioffset_p2 = ((TmpUshort & (BIT_12|BIT_11|BIT_10|BIT_9))>>9); ioffset_p1 = ((TmpUshort & (BIT_8|BIT_7|BIT_6|BIT_5))>>5); - ioffset_p0 = ( (TmpUshort & BIT_4) >>4 ); + ioffset_p0 = ((TmpUshort & BIT_4) >>4); ioffset_p0 <<= 3; ioffset_p0 |= (TmpUshort & (BIT_2| BIT_1 | BIT_0)); @@ -25185,7 +26339,9 @@ rtl8168_init_software_variable(struct net_device *dev) 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); @@ -25252,6 +26408,7 @@ rtl8168_init_software_variable(struct net_device *dev) case CFG_METHOD_19: case CFG_METHOD_20: case CFG_METHOD_30: + case CFG_METHOD_37: tp->RequiredSecLanDonglePatch = TRUE; break; } @@ -25277,6 +26434,8 @@ rtl8168_init_software_variable(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->HwSuppMagicPktVer = WAKEUP_MAGIC_PACKET_V2; break; case CFG_METHOD_DEFAULT: @@ -25331,6 +26490,8 @@ rtl8168_init_software_variable(struct net_device *dev) 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: @@ -25380,6 +26541,7 @@ rtl8168_init_software_variable(struct net_device *dev) 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: @@ -25391,6 +26553,9 @@ rtl8168_init_software_variable(struct net_device *dev) 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) { @@ -25398,6 +26563,83 @@ rtl8168_init_software_variable(struct net_device *dev) 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); @@ -25416,13 +26658,27 @@ rtl8168_init_software_variable(struct net_device *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 @@ -25444,8 +26700,13 @@ rtl8168_release_board(struct pci_dev *pdev, 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); @@ -25491,7 +26752,9 @@ rtl8168_get_mac_address(struct net_device *dev) 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_addr[0] = rtl8168_eri_read(tp, 0xE0, 4, ERIAR_ExGMAC); *(u16*)&mac_addr[4] = rtl8168_eri_read(tp, 0xE4, 2, ERIAR_ExGMAC); } else { @@ -25517,7 +26780,9 @@ rtl8168_get_mac_address(struct net_device *dev) 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); @@ -25545,7 +26810,7 @@ rtl8168_get_mac_address(struct net_device *dev) /* 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; } @@ -25563,19 +26828,14 @@ rtl8168_set_mac_address(struct net_device *dev, { 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; } @@ -26354,7 +27614,6 @@ rtl8168_do_ioctl(struct net_device *dev, struct rtl8168_private *tp = netdev_priv(dev); struct mii_ioctl_data *data = if_mii(ifr); int ret; - unsigned long flags; ret = 0; switch (cmd) { @@ -26363,19 +27622,15 @@ rtl8168_do_ioctl(struct net_device *dev, 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 @@ -26499,7 +27754,7 @@ rtl8168_phy_power_down(struct net_device *dev) case CFG_METHOD_23: case CFG_METHOD_24: csi_tmp = rtl8168_eri_read(tp, 0x1AB, 1, ERIAR_ExGMAC); - csi_tmp &= ~( BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7 ); + csi_tmp &= ~(BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7); rtl8168_eri_write(tp, 0x1AB, 1, csi_tmp, ERIAR_ExGMAC); break; } @@ -26527,6 +27782,8 @@ rtl8168_phy_power_down(struct net_device *dev) 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: @@ -26556,7 +27813,7 @@ rtl8168_init_board(struct pci_dev *pdev, 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)) @@ -26712,24 +27969,10 @@ err_out: } 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; @@ -26746,10 +27989,8 @@ rtl8168_esd_timer(struct timer_list *t) 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; @@ -26762,7 +28003,7 @@ rtl8168_esd_timer(struct timer_list *t) 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; } } @@ -26871,8 +28112,8 @@ rtl8168_esd_timer(struct timer_list *t) 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); @@ -26886,12 +28127,34 @@ rtl8168_esd_timer(struct timer_list *t) 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) @@ -26908,36 +28171,73 @@ rtl8168_link_timer(struct timer_list *t) 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); } +*/ +#ifndef ENABLE_RSS_SUPPORT static int rtl8168_enable_msix(struct rtl8168_private *tp) { - int nvecs = 0; - struct msix_entry msix_ent[1] = {0}; + int i, nvecs = 0; + struct msix_entry msix_ent[R8168_MAX_MSIX_VEC]; + //struct net_device *dev = tp->dev; + //const int len = sizeof(tp->irq_tbl[0].name); + + for (i = 0; i < R8168_MAX_MSIX_VEC; i++) { + msix_ent[i].entry = i; + msix_ent[i].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_ent[0].vector; + for (i = 0; i < nvecs; i++) { + struct r8168_irq *irq = &tp->irq_tbl[i]; + irq->vector = msix_ent[i].vector; + //snprintf(irq->name, len, "%s-%d", dev->name, i); + //irq->handler = rtl8168_interrupt_msix; + } + out: return nvecs; } +#endif /* !ENABLE_RSS_SUPPORT */ /* 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: @@ -26950,40 +28250,55 @@ static unsigned rtl8168_try_msi(struct pci_dev *pdev, struct rtl8168_private *tp 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); -#endif - tp->features &= ~RTL_FEATURE_MSIX; - } - - if (tp->features & RTL_FEATURE_MSI) { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + else if (tp->features & (RTL_FEATURE_MSI)) pci_disable_msi(pdev); #endif - tp->features &= ~RTL_FEATURE_MSI; - } + tp->features &= ~(RTL_FEATURE_MSI | RTL_FEATURE_MSIX); +} + +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 } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) @@ -27020,6 +28335,82 @@ static const struct net_device_ops rtl8168_netdev_ops = { }; #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->r8168napi[i].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->r8168napi[i].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->r8168napi[i])); +#endif +} +#endif //CONFIG_R8168_NAPI + +static void rtl8168_init_napi(struct rtl8168_private *tp) +{ + int i; + + for (i=0; iirq_nvecs; i++) { + struct r8168_napi *r8168napi = &tp->r8168napi[i]; +#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) @@ -27053,7 +28444,13 @@ rtl8168_init_one(struct pci_dev *pdev, 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); @@ -27062,16 +28459,17 @@ rtl8168_init_one(struct pci_dev *pdev, #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) @@ -27095,9 +28493,16 @@ rtl8168_init_one(struct pci_dev *pdev, 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; @@ -27107,10 +28512,10 @@ rtl8168_init_one(struct pci_dev *pdev, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) if ((tp->mcfg == CFG_METHOD_1) || (tp->mcfg == CFG_METHOD_2) || (tp->mcfg == CFG_METHOD_3)) { dev->hw_features &= ~NETIF_F_IPV6_CSUM; -#if defined(NV_NETIF_SET_TSO_MAX_SIZE_PRESENT) /* Linux v5.19 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) netif_set_tso_max_size(dev, LSO_64K); netif_set_tso_max_segs(dev, NIC_MAX_PHYS_BUF_COUNT_LSO2); -#else //NV_NETIF_SET_TSO_MAX_SIZE_PRESENT +#else //LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) netif_set_gso_max_size(dev, LSO_32K); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) dev->gso_max_segs = NIC_MAX_PHYS_BUF_COUNT_LSO_64K; @@ -27118,18 +28523,25 @@ rtl8168_init_one(struct pci_dev *pdev, dev->gso_min_segs = NIC_MIN_PHYS_BUF_COUNT; #endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) -#endif //NV_NETIF_SET_TSO_MAX_SIZE_PRESENT +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) } else { dev->hw_features |= NETIF_F_IPV6_CSUM; 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 defined(NV_NETIF_SET_TSO_MAX_SIZE_PRESENT) /* Linux v5.19 */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) netif_set_tso_max_size(dev, LSO_64K); netif_set_tso_max_segs(dev, NIC_MAX_PHYS_BUF_COUNT_LSO2); -#else //NV_NETIF_SET_TSO_MAX_SIZE_PRESENT +#else //LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) netif_set_gso_max_size(dev, LSO_64K); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) dev->gso_max_segs = NIC_MAX_PHYS_BUF_COUNT_LSO2; @@ -27137,21 +28549,33 @@ rtl8168_init_one(struct pci_dev *pdev, dev->gso_min_segs = NIC_MIN_PHYS_BUF_COUNT; #endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) -#endif //NV_NETIF_SET_TSO_MAX_SIZE_PRESENT +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) } #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) #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); @@ -27161,7 +28585,8 @@ rtl8168_init_one(struct pci_dev *pdev, /* 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; @@ -27204,6 +28629,8 @@ rtl8168_init_one(struct pci_dev *pdev, netif_carrier_off(dev); + rtl8168_sysfs_init(dev); + printk("%s", GPL_CLAIM); out: @@ -27217,9 +28644,11 @@ err_out: 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; @@ -27234,12 +28663,20 @@ rtl8168_remove_one(struct pci_dev *pdev) 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); +#ifdef ENABLE_R8168_SYSFS + rtl8168_sysfs_remove(dev); +#endif //ENABLE_R8168_SYSFS + unregister_netdev(dev); rtl8168_disable_msi(pdev, tp); #ifdef ENABLE_R8168_PROCFS @@ -27259,13 +28696,180 @@ rtl8168_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } +static void rtl8168_free_irq(struct rtl8168_private *tp) +{ + int i; + + for (i=0; iirq_nvecs; i++) { + struct r8168_irq *irq = &tp->irq_tbl[i]; + struct r8168_napi *r8168napi = &tp->r8168napi[i]; + + 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_tbl[0].name); + +#if defined(RTL_USE_NEW_INTR_API) + for (i=0; iirq_nvecs; i++) { + irq = &tp->irq_tbl[i]; + if (tp->features & RTL_FEATURE_MSIX) + irq->handler = rtl8168_interrupt_msix; + else + irq->handler = rtl8168_interrupt; + + r8168napi = &tp->r8168napi[i]; + 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; iirq_nvecs; i++) { + irq = &tp->irq_tbl[i]; + irq->handler = rtl8168_interrupt_msix; + r8168napi = &tp->r8168napi[i]; + 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_tbl[0]; + irq->handler = rtl8168_interrupt; + r8168napi = &tp->r8168napi[0]; + 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_ring[i]; + 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_ring[i]; + 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 @@ -27295,11 +28899,10 @@ static void rtl8168_request_firmware(struct rtl8168_private *tp) } #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; @@ -27312,27 +28915,14 @@ static int rtl8168_open(struct net_device *dev) * 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; @@ -27344,28 +28934,24 @@ static int rtl8168_open(struct net_device *dev) dev->base_addr, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5], tp->irq); + dev->dev_addr[4], dev->dev_addr[5], 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); @@ -27382,35 +28968,24 @@ static int rtl8168_open(struct net_device *dev) rtl8168_dsm(dev, DSM_IF_UP); + clear_bit(R8168_FLAG_DOWN, tp->task_flags); + rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); - spin_unlock_irqrestore(&tp->lock, flags); + if (tp->esd_flag == 0) { + //rtl8168_request_esd_timer(dev); + rtl8168_schedule_esd_work(tp); + } - if (tp->esd_flag == 0) - rtl8168_request_esd_timer(dev); - - 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; } @@ -27420,34 +28995,27 @@ rtl8168_dsm(struct net_device *dev, int dev_state) { struct rtl8168_private *tp = netdev_priv(dev); + if (!(tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) + return; + switch (dev_state) { case DSM_MAC_INIT: - if ((tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) { - if (RTL_R8(tp, MACDBG) & 0x80) - RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) | GPIO_en); - else - RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) & ~GPIO_en); - } - + if (RTL_R8(tp, MACDBG) & 0x80) + RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) | GPIO_en); + else + RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) & ~GPIO_en); break; case DSM_NIC_GOTO_D3: case DSM_IF_DOWN: - if ((tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) { - if (RTL_R8(tp, MACDBG) & 0x80) - RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) & ~GPIO_en); - } + if (RTL_R8(tp, MACDBG) & 0x80) + RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) & ~GPIO_en); break; - case DSM_NIC_RESUME_D3: case DSM_IF_UP: - if ((tp->mcfg == CFG_METHOD_5) || (tp->mcfg == CFG_METHOD_6)) { - if (RTL_R8(tp, MACDBG) & 0x80) - RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) | GPIO_en); - } - + if (RTL_R8(tp, MACDBG) & 0x80) + RTL_W8(tp, GPIO, RTL_R8(tp, GPIO) | GPIO_en); break; } - } static void @@ -27511,9 +29079,8 @@ rtl8168_hw_set_rx_packet_filter(struct net_device *dev) AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys; mc_filter[1] = mc_filter[0] = 0xffffffff; - } else if ((netdev_mc_count(dev) > multicast_filter_limit) - || (dev->flags & IFF_ALLMULTI)) { - /* Too many to filter perfectly -- accept all multicasts. */ + } else if (dev->flags & IFF_ALLMULTI) { + /* accept all multicasts. */ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; mc_filter[1] = mc_filter[0] = 0xffffffff; } else { @@ -27550,6 +29117,18 @@ rtl8168_hw_set_rx_packet_filter(struct net_device *dev) mc_filter[1] = swab32(tmp); tp->rtl8168_rx_config = rtl_chip_info[tp->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_info[tp->chipset].RxConfigMask); RTL_W32(tp, RxConfig, tmp); @@ -27560,17 +29139,10 @@ rtl8168_hw_set_rx_packet_filter(struct net_device *dev) 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); @@ -27586,8 +29158,7 @@ rtl8168_hw_config(struct net_device *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); @@ -27597,6 +29168,8 @@ rtl8168_hw_config(struct net_device *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: @@ -27615,6 +29188,8 @@ rtl8168_hw_config(struct net_device *dev) 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; } @@ -27641,6 +29216,8 @@ rtl8168_hw_config(struct net_device *dev) 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); @@ -28033,15 +29610,21 @@ rtl8168_hw_config(struct net_device *dev) } 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); @@ -28052,7 +29635,7 @@ rtl8168_hw_config(struct net_device *dev) 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) { @@ -28067,7 +29650,8 @@ rtl8168_hw_config(struct net_device *dev) 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); @@ -28119,11 +29703,11 @@ rtl8168_hw_config(struct net_device *dev) 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); @@ -28132,7 +29716,8 @@ rtl8168_hw_config(struct net_device *dev) } 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); @@ -28142,7 +29727,8 @@ rtl8168_hw_config(struct net_device *dev) 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); } @@ -28152,7 +29738,8 @@ rtl8168_hw_config(struct net_device *dev) 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); @@ -28163,9 +29750,11 @@ rtl8168_hw_config(struct net_device *dev) 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); @@ -28325,6 +29914,10 @@ rtl8168_hw_config(struct net_device *dev) 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); @@ -28440,6 +30033,17 @@ rtl8168_hw_config(struct net_device *dev) } } + 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); @@ -28452,6 +30056,8 @@ rtl8168_hw_config(struct net_device *dev) 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: @@ -28478,6 +30084,8 @@ rtl8168_hw_config(struct net_device *dev) 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)) @@ -28498,6 +30106,8 @@ rtl8168_hw_config(struct net_device *dev) 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)) @@ -28524,19 +30134,9 @@ rtl8168_hw_config(struct net_device *dev) 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) @@ -28595,14 +30195,20 @@ rtl8168_hw_config(struct net_device *dev) 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 @@ -28611,7 +30217,6 @@ rtl8168_change_mtu(struct net_device *dev, { 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) @@ -28620,42 +30225,33 @@ rtl8168_change_mtu(struct net_device *dev, 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); + if (tp->link_ok(dev)) + rtl8168_link_on_patch(dev); + else + rtl8168_link_down_patch(dev); - rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); - - spin_unlock_irqrestore(&tp->lock, flags); - - 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); @@ -28674,32 +30270,37 @@ rtl8168_make_unusable_by_asic(struct RxDesc *desc) 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->RxDescPhyAddr[cur_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->RxDescPhyAddr[cur_rx] = mapping; desc->addr = cpu_to_le64(mapping); wmb(); rtl8168_mark_to_asic(desc, rx_buf_sz); @@ -28707,9 +30308,11 @@ rtl8168_map_to_asic(struct RxDesc *desc, 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; @@ -28717,14 +30320,16 @@ rtl8168_alloc_rx_skb(struct rtl8168_private *tp, int ret = 0; if (in_intr) - skb = RTL_ALLOC_SKB_INTR(tp, rx_buf_sz + RTK_RX_ALIGN); + skb = RTL_ALLOC_SKB_INTR(&tp->r8168napi[ring->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); @@ -28735,7 +30340,7 @@ rtl8168_alloc_rx_skb(struct rtl8168_private *tp, } *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; @@ -28748,19 +30353,37 @@ err_out: } 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_skbuff[i]) - rtl8168_free_rx_skb(tp, tp->Rx_skbuff + i, - tp->RxDescArray + i); + if (ring->Rx_skbuff[i]) { + rtl8168_free_rx_skb(tp, + ring, + ring->Rx_skbuff + i, + rtl8168_get_rxdesc(tp, + tp->RxDescArray, + i, + ring->index), + i); + ring->Rx_skbuff[i] = 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_ring[i]); +} + static u32 rtl8168_rx_fill(struct rtl8168_private *tp, + struct rtl8168_rx_ring *ring, struct net_device *dev, u32 start, u32 end, @@ -28771,12 +30394,17 @@ rtl8168_rx_fill(struct rtl8168_private *tp, for (cur = start; end - cur > 0; cur++) { int ret, i = cur % tp->num_rx_desc; - if (tp->Rx_skbuff[i]) + if (ring->Rx_skbuff[i]) 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; @@ -28793,33 +30421,54 @@ rtl8168_mark_as_last_descriptor(struct RxDesc *desc) 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_ring[i]; + 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_ring[0]; + 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_ring[i]; + memset(ring->TxDescArray, 0x0, ring->TxDescAllocSize); - for (i = 0; i < tp->num_tx_desc; i++) { - if (i == (tp->num_tx_desc - 1)) - tp->TxDescArray[i].opts1 = cpu_to_le32(RingEnd); + ring->TxDescArray[ring->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_ring[0]; + struct RxDesc *desc; int ownbit = 0; + int i; if (tp->RxDescArray == NULL) return; @@ -28828,36 +30477,56 @@ rtl8168_rx_desc_offset0_init(struct rtl8168_private *tp, int own) 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->RxDescArray[i].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->RxDescArray[i].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_ring[i]; + 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_ring[i]; + + 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; @@ -28881,8 +30550,11 @@ rtl8168_unmap_tx_skb(struct pci_dev *pdev, 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) @@ -28890,15 +30562,15 @@ static void rtl8168_tx_clear_range(struct rtl8168_private *tp, u32 start, #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); @@ -28908,83 +30580,190 @@ static void rtl8168_tx_clear_range(struct rtl8168_private *tp, u32 start, } } -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_ring[i]; + 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); - - INIT_WORK(&tp->task, task, dev); - schedule_delayed_work(&tp->task, 4); + 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) } -#define rtl8168_cancel_schedule_work(a) - -#else -static void rtl8168_schedule_work(struct net_device *dev, work_func_t task) +static void rtl8168_schedule_esd_work(struct rtl8168_private *tp) { - struct rtl8168_private *tp = netdev_priv(dev); - - INIT_DELAYED_WORK(&tp->task, task); - schedule_delayed_work(&tp->task, 4); +#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) } -static void rtl8168_cancel_schedule_work(struct net_device *dev) +static void rtl8168_schedule_linkchg_work(struct rtl8168_private *tp) { - struct rtl8168_private *tp = netdev_priv(dev); - struct work_struct *work = &tp->task.work; +#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) +} + +void rtl8168_schedule_dash_work(struct rtl8168_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8168_FLAG_TASK_DASH_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->dash_task, RTL8168_DASH_TIMEOUT); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +#define rtl8168_cancel_schedule_reset_work(a) +#define rtl8168_cancel_schedule_esd_work(a) +#define rtl8168_cancel_schedule_linkchg_work(a) +#define rtl8168_cancel_schedule_dash_work(a) + +#else +static void rtl8168_schedule_reset_work(struct rtl8168_private *tp) +{ + 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; if (!work->func) return; - cancel_delayed_work_sync(&tp->task); + cancel_delayed_work_sync(&tp->reset_task); +} + +static void rtl8168_schedule_esd_work(struct rtl8168_private *tp) +{ + set_bit(R8168_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->esd_task, RTL8168_ESD_TIMEOUT); +} + +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->esd_task); +} + +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); +} + +void rtl8168_schedule_dash_work(struct rtl8168_private *tp) +{ + set_bit(R8168_FLAG_TASK_DASH_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->dash_task, RTL8168_DASH_TIMEOUT); +} + +static void rtl8168_cancel_schedule_dash_work(struct rtl8168_private *tp) +{ + struct work_struct *work = &tp->dash_task.work; + + if (!work->func) + return; + + cancel_delayed_work_sync(&tp->dash_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) -#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); + INIT_WORK(&tp->dash_task, rtl8168_dash_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); + INIT_DELAYED_WORK(&tp->dash_task, rtl8168_dash_task); #endif - int ret; +} - if (netif_running(dev)) { - rtl8168_wait_for_quiescence(dev); - rtl8168_close(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); + rtl8168_cancel_schedule_dash_work(tp); +} - ret = rtl8168_open(dev); - if (unlikely(ret < 0)) { - if (unlikely(net_ratelimit())) { - struct rtl8168_private *tp = netdev_priv(dev); - - 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_tbl[i].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 +} #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) static void rtl8168_reset_task(void *_data) @@ -28995,44 +30774,122 @@ 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(); - rtl8168_wait_for_quiescence(dev); + 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; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) - rtl8168_rx_interrupt(dev, tp, &budget); -#else - rtl8168_rx_interrupt(dev, tp, budget); -#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + netdev_err(dev, "Device reseting!\n"); - spin_lock_irqsave(&tp->lock, flags); + netif_carrier_off(dev); + netif_tx_disable(dev); + _rtl8168_wait_for_quiescence(dev); + rtl8168_hw_reset(dev); rtl8168_tx_clear(tp); - if (tp->dirty_rx == tp->cur_rx) { - 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); + rtl8168_init_ring_indexes(tp); - if (netif_msg_intr(tp)) { - printk(PFX KERN_EMERG - "%s: Rx buffers shortage\n", dev->name); - } - } - rtl8168_schedule_work(dev, rtl8168_reset_task); - } + rtl8168_tx_desc_init(tp); + for (i = 0; i < tp->num_rx_desc; i++) + rtl8168_mark_to_asic(tp->RxDescArray + i, tp->rx_buf_sz); + +#ifdef CONFIG_R8168_NAPI + rtl8168_enable_napi(tp); +#endif //CONFIG_R8168_NAPI + + rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + +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(2,6,20) +static void rtl8168_dash_task(void *_data) +{ + struct net_device *dev = _data; + //struct rtl8168_private *tp = netdev_priv(dev); +#else +static void rtl8168_dash_task(struct work_struct *work) +{ + struct rtl8168_private *tp = + container_of(work, struct rtl8168_private, dash_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_DASH_CHECK_PENDING, tp->task_flags)) + goto out_unlock; + +#ifdef ENABLE_DASH_SUPPORT + HandleDashInterrupt(dev); +#endif + +out_unlock: + rtnl_unlock(); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) @@ -29044,27 +30901,22 @@ rtl8168_tx_timeout(struct net_device *dev) #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); + netdev_err(dev, "Transmit timeout reset Device!\n"); /* 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; @@ -29072,6 +30924,7 @@ rtl8168_get_txd_opts1(struct rtl8168_private *tp, static int rtl8168_xmit_frags(struct rtl8168_private *tp, + struct rtl8168_tx_ring *ring, struct sk_buff *skb, const u32 *opts) { @@ -29080,16 +30933,16 @@ rtl8168_xmit_frags(struct rtl8168_private *tp, 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; @@ -29107,15 +30960,13 @@ rtl8168_xmit_frags(struct rtl8168_private *tp, } /* anti gcc 2.95.3 bugware (sic) */ - status = rtl8168_get_txd_opts1(tp, opts[0], len, entry); - if (cur_frag == (nr_frags - 1)) { - tp->tx_skb[entry].skb = skb; + status = rtl8168_get_txd_opts1(ring, opts[0], len, entry); + if (cur_frag == (nr_frags - 1)) status |= LastFrag; - } txd->addr = cpu_to_le64(mapping); - tp->tx_skb[entry].len = len; + ring->tx_skb[entry].len = len; txd->opts2 = cpu_to_le32(opts[1]); wmb(); @@ -29125,7 +30976,7 @@ rtl8168_xmit_frags(struct rtl8168_private *tp, 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; } @@ -29248,45 +31099,6 @@ rtl8168_tx_csum(struct sk_buff *skb, } #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. - */ -static void r8168_csum_workaround(struct rtl8168_private *tp, - struct sk_buff *skb) -{ - if (skb_shinfo(skb)->gso_size) { - netdev_features_t features = tp->dev->features; - struct sk_buff *segs, *nskb; - - features &= ~(NETIF_F_SG | NETIF_F_IPV6_CSUM | NETIF_F_TSO6); - segs = skb_gso_segment(skb, features); - if (IS_ERR(segs) || !segs) - goto drop; - - do { - nskb = segs; - segs = segs->next; - nskb->next = NULL; - rtl8168_start_xmit(nskb, tp->dev); - } while (segs); - - dev_consume_skb_any(skb); - } else if (skb->ip_summed == CHECKSUM_PARTIAL) { - if (skb_checksum_help(skb) < 0) - goto drop; - - rtl8168_start_xmit(skb, tp->dev); - } else { - struct net_device_stats *stats; - -drop: - stats = &tp->dev->stats; - stats->tx_dropped++; - dev_kfree_skb_any(skb); - } -} - /* msdn_giant_send_check() * According to the document of microsoft, the TCP Pseudo Header excludes the * packet length for IPv6 TCP large packets. @@ -29312,12 +31124,13 @@ static int msdn_giant_send_check(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 @@ -29325,18 +31138,27 @@ rtl8168_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(dev); + unsigned int bytecount; + unsigned short gso_segs; + struct ring_info *last; + unsigned int last_entry; unsigned int entry; struct TxDesc *txd; dma_addr_t mapping; u32 len; u32 opts[2]; 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_ring[queue_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", @@ -29345,8 +31167,8 @@ rtl8168_start_xmit(struct sk_buff *skb, 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)) { @@ -29357,6 +31179,9 @@ rtl8168_start_xmit(struct sk_buff *skb, goto err_stop; } + bytecount = skb->len; + gso_segs = 1; + opts[0] = DescOwn; opts[1] = rtl8168_tx_vlan_tag(tp, skb); @@ -29371,6 +31196,23 @@ rtl8168_start_xmit(struct sk_buff *skb, /* TCP Segmentation Offload (or TCP Large Send) */ if (mss) { + union { + struct iphdr *v4; + struct ipv6hdr *v6; + unsigned char *hdr; + } ip; + union { + struct tcphdr *tcp; + struct udphdr *udp; + unsigned char *hdr; + } l4; + u32 l4_offset, hdr_len; + + ip.hdr = skb_network_header(skb); + l4.hdr = skb_checksum_start(skb); + + l4_offset = skb_transport_offset(skb); + assert((l4_offset%2) == 0); if ((tp->mcfg == CFG_METHOD_1) || (tp->mcfg == CFG_METHOD_2) || (tp->mcfg == CFG_METHOD_3)) { @@ -29379,24 +31221,21 @@ rtl8168_start_xmit(struct sk_buff *skb, } else { switch (get_protocol(skb)) { case __constant_htons(ETH_P_IP): - if (skb_transport_offset(skb) <= GTTCPHO_MAX) { + if (l4_offset <= GTTCPHO_MAX) { opts[0] |= GiantSendv4; - opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT; + opts[0] |= l4_offset << GTTCPHO_SHIFT; opts[1] |= min(mss, MSS_MAX) << 18; large_send = 1; } break; 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; - } + if (msdn_giant_send_check(skb)) + goto err_dma_0; #endif - if (skb_transport_offset(skb) <= GTTCPHO_MAX) { + if (l4_offset <= GTTCPHO_MAX) { opts[0] |= GiantSendv6; - opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT; + opts[0] |= l4_offset << GTTCPHO_SHIFT; opts[1] |= min(mss, MSS_MAX) << 18; large_send = 1; } @@ -29410,6 +31249,12 @@ rtl8168_start_xmit(struct sk_buff *skb, if (large_send == 0) goto err_dma_0; + + /* compute length of segmentation header */ + hdr_len = (l4.tcp->doff * 4) + l4_offset; + /* update gso size and bytecount with header size */ + gso_segs = skb_shinfo(skb)->gso_segs; + bytecount += (gso_segs - 1) * hdr_len; } } #endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) @@ -29419,7 +31264,7 @@ rtl8168_start_xmit(struct sk_buff *skb, 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) { @@ -29427,124 +31272,165 @@ rtl8168_start_xmit(struct sk_buff *skb, opts[0] |= FirstFrag; } else { len = skb->len; - - tp->tx_skb[entry].skb = skb; - opts[0] |= FirstFrag | LastFrag; } - opts[0] = rtl8168_get_txd_opts1(tp, opts[0], len, entry); + opts[0] = rtl8168_get_txd_opts1(ring, opts[0], 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_skb[entry].len = len; + /* set first fragment's length */ + ring->tx_skb[entry].len = len; + + /* set skb to last fragment */ + last_entry = (entry + frags) % ring->num_tx_desc; + last = &ring->tx_skb[last_entry]; + last->skb = skb; + last->gso_segs = gso_segs; + last->bytecount = bytecount; + txd->addr = cpu_to_le64(mapping); txd->opts2 = cpu_to_le32(opts[1]); wmb(); txd->opts1 = cpu_to_le32(opts[0]); + netdev_tx_sent_queue(txring_txq(ring), bytecount); + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) dev->trans_start = jiffies; #else 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); - RTL_W8(tp, TxPoll, NPQ); /* 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); + 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); + } + + if (netif_xmit_stopped(txring_txq(ring)) || !netdev_xmit_more()) + rtl8168_doorbell(ring); /* set polling bit */ + + 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_skb[entry].skb = NULL; - rtl8168_tx_clear_range(tp, tp->cur_tx + 1, frags); + 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, int budget) { + unsigned int total_bytes = 0, total_packets = 0; + 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; - u32 len = tx_skb->len; + unsigned int entry = dirty_tx % ring->num_tx_desc; + struct ring_info *tx_skb = ring->tx_skb + entry; u32 status; rmb(); - status = le32_to_cpu(tp->TxDescArray[entry].opts1); + status = le32_to_cpu(ring->TxDescArray[entry].opts1); if (status & DescOwn) break; - RTLDEV->stats.tx_bytes += len; - RTLDEV->stats.tx_packets++; - 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) - dev_consume_skb_any(tx_skb->skb); -#else - dev_kfree_skb_any(tx_skb->skb); -#endif + if (tx_skb->skb != NULL) { + /* update the statistics for this packet */ + total_bytes += tx_skb->bytecount; + total_packets += tx_skb->gso_segs; + + RTL_NAPI_CONSUME_SKB_ANY(tx_skb->skb, budget); tx_skb->skb = NULL; } dirty_tx++; tx_left--; } + if (total_packets) { + netdev_tx_completed_queue(txring_txq(ring), + total_packets, total_bytes); + + RTLDEV->stats.tx_bytes += total_bytes; + RTLDEV->stats.tx_packets += total_packets; + } + 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 budget) +{ + int i; + + for (i = 0; i < rtl8168_tot_tx_rings(tp); i++) + rtl8168_tx_interrupt(&tp->tx_ring[i], budget); +} + static inline int rtl8168_fragmented_frame(u32 status) { @@ -29583,8 +31469,10 @@ rtl8168_rx_csum(struct rtl8168_private *tp, } } +/* 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, @@ -29592,36 +31480,38 @@ rtl8168_try_rx_copy(struct rtl8168_private *tp, { 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->r8168napi[ring->index].napi, + pkt_size + RTK_RX_ALIGN); + if (skb) { + u8 *data; - data = sk_buff[0]->data; - skb_reserve(skb, RTK_RX_ALIGN); + data = sk_buff[0]->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->r8168napi[ring_index].napi, skb); #endif #else netif_rx(skb); @@ -29631,29 +31521,42 @@ rtl8168_rx_skb(struct rtl8168_private *tp, 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 (tp->num_rx_rings == 0 && 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; @@ -29673,94 +31576,81 @@ rtl8168_rx_interrupt(struct net_device *dev, 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; - -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; - } - - skb = tp->Rx_skbuff[entry]; - - 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_skbuff[entry] = 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); - } - - 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 (rtl8168_rx_vlan_skb(tp, desc, skb) < 0) - rtl8168_rx_skb(tp, skb); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) - dev->last_rx = jiffies; -#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) - RTLDEV->stats.rx_bytes += pkt_size; - RTLDEV->stats.rx_packets++; + if (!(dev->features & NETIF_F_RXALL)) + goto release_descriptor; } - cur_rx++; - entry = cur_rx % tp->num_rx_desc; - desc = tp->RxDescArray + entry; + 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++; + goto release_descriptor; + } + + skb = RTL_ALLOC_SKB_INTR(&tp->r8168napi[ring_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->RxDescPhyAddr[entry]; + dma_sync_single_for_cpu(tp_to_dev(tp), + rx_buf_phy_addr, tp->rx_buf_sz, + DMA_FROM_DEVICE); + + rx_buf = ring->Rx_skbuff[entry]->data; + if (!R8168_USE_NAPI_ALLOC_SKB) + skb_reserve(skb, RTK_RX_ALIGN); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) - prefetch(desc); + prefetch(rx_buf); #endif + eth_copy_and_sum(skb, rx_buf, pkt_size, 0); + + dma_sync_single_for_device(tp_to_dev(tp), rx_buf_phy_addr, + tp->rx_buf_sz, DMA_FROM_DEVICE); + +#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 (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; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) + RTLDEV->stats.rx_bytes += pkt_size; + RTLDEV->stats.rx_packets++; + +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; @@ -29776,67 +31666,51 @@ static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance, struct pt_regs 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_reg[0]); +#ifdef ENABLE_RSS_SUPPORT + if (R8168_MULTI_RX_Q(tp)) { + for (i=1; iisr_reg[i]); + } +#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); @@ -29844,51 +31718,31 @@ static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance) 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; iDASH ) { - if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { - u8 DashIntType2Status; - - if (status & ISRIMR_DASH_INTR_CMAC_RESET) - tp->CmacResetIntr = TRUE; - - DashIntType2Status = RTL_CMAC_R8(tp, CMAC_IBISR0); - if (DashIntType2Status & ISRIMR_DASH_TYPE2_ROK) { - tp->RcvFwDashOkEvt = TRUE; - } - if (DashIntType2Status & ISRIMR_DASH_TYPE2_TOK) { - tp->SendFwHostOkEvt = TRUE; - } - if (DashIntType2Status & ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE) { - tp->DashFwDisableRx = TRUE; - } - - RTL_CMAC_W8(tp, CMAC_IBISR0, DashIntType2Status); - } else { - if (status & ISRIMR_DP_REQSYS_OK) { - tp->RcvFwReqSysOkEvt = TRUE; - } - if (status & ISRIMR_DP_DASH_OK) { - tp->RcvFwDashOkEvt = TRUE; - } - if (status & ISRIMR_DP_HOST_OK) { - tp->SendFwHostOkEvt = TRUE; - } - } - } + if (CheckDashInterrupt(dev, status)) + rtl8168_schedule_dash_work(tp); #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->r8168napi[0].napi))) + __RTL_NETIF_RX_SCHEDULE(dev, &tp->r8168napi[0].napi); else if (netif_msg_intr(tp)) printk(KERN_INFO "%s: interrupt %04x in poll\n", dev->name, status); @@ -29897,27 +31751,27 @@ static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance) 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, budget); + 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_ring[i], &budget); #else - rtl8168_rx_interrupt(dev, tp, budget); -#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) - -#ifdef ENABLE_DASH_SUPPORT - if ( tp->DASH ) { - struct net_device *dev = tp->dev; - - HandleDashInterrupt(dev); + rtl8168_rx_interrupt(dev, tp, &tp->rx_ring[i], budget); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) } -#endif rtl8168_switch_to_timer_interrupt(tp); } else { @@ -29931,34 +31785,94 @@ static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance) return IRQ_RETVAL(handled); } -#ifdef CONFIG_R8168_NAPI -static int rtl8168_poll(napi_ptr napi, napi_budget budget) +#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 rtl8168_private *tp = RTL_GET_PRIV(napi, struct rtl8168_private); + 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_tbl[message_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_hw_tot_en_rx_rings) + break; + +#ifdef ENABLE_DASH_SUPPORT + if (message_id == 0 && + CheckDashInterrupt(dev, rtl8168_get_isr_by_vector(tp, 0))) + rtl8168_schedule_dash_work(tp); +#endif + +#ifdef CONFIG_R8168_NAPI + 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 + rtl8168_disable_interrupt_by_vector(tp, message_id); + + rtl8168_self_clear_isr_by_vector(tp, message_id); + + if (message_id == 0) + rtl8168_tx_all_interrupt(tp, budget); + + if (message_id < tp->num_hw_tot_en_rx_rings) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + rtl8168_rx_interrupt(dev, tp, &tp->rx_ring[message_id], &budget); +#else + rtl8168_rx_interrupt(dev, tp, &tp->rx_ring[message_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 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, budget); - work_done = rtl8168_rx_interrupt(dev, tp, budget); + if (all_rx_q) + for (i = 0; i < tp->num_hw_tot_en_rx_rings; i++) + work_done += rtl8168_rx_interrupt(dev, tp, &tp->rx_ring[i], budget); + else + work_done += rtl8168_rx_interrupt(dev, tp, &tp->rx_ring[message_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; - - spin_lock_irqsave(&tp->lock, flags); - HandleDashInterrupt(dev); - spin_unlock_irqrestore(&tp->lock, flags); - } -#endif - #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) return RTL_NAPI_RETURN_VALUE; @@ -29972,8 +31886,55 @@ static int rtl8168_poll(napi_ptr napi, napi_budget budget) * 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_ring[message_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; @@ -30000,91 +31961,65 @@ static void rtl8168_sleep_rx_enable(struct net_device *dev) 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); - -#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 - - spin_lock_irqsave(&tp->lock, flags); + //rtl8168_delete_esd_timer(dev, &tp->esd_timer); + //rtl8168_delete_link_timer(dev, &tp->link_timer); netif_carrier_off(dev); - rtl8168_dsm(dev, DSM_IF_DOWN); + netif_tx_disable(dev); + + _rtl8168_wait_for_quiescence(dev); rtl8168_hw_reset(dev); - spin_unlock_irqrestore(&tp->lock, flags); - - synchronize_irq(tp->irq); - - spin_lock_irqsave(&tp->lock, flags); - rtl8168_tx_clear(tp); rtl8168_rx_clear(tp); - - spin_unlock_irqrestore(&tp->lock, flags); } -static int rtl8168_close(struct net_device *dev) +static int rtl8168_resource_freed(struct rtl8168_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) + if (tp->tx_ring[i].TxDescArray) + return 0; + + if (tp->RxDescArray) + return 0; + + return 1; +} + +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); + rtl8168_free_irq(tp); - free_irq(tp->irq, dev); - - 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); } + rtl8168_dsm(dev, DSM_IF_DOWN); + return 0; } @@ -30094,6 +32029,8 @@ static void rtl8168_shutdown(struct pci_dev *pdev) 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); @@ -30111,6 +32048,8 @@ static void rtl8168_shutdown(struct pci_dev *pdev) 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); @@ -30132,11 +32071,6 @@ net_device_stats *rtl8168_get_stats(struct net_device *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; } @@ -30145,34 +32079,40 @@ net_device_stats *rtl8168_get_stats(struct net_device *dev) #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); @@ -30190,37 +32130,53 @@ rtl8168_suspend(struct pci_dev *pdev, pm_message_t state) 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; - pci_set_power_state(pdev, PCI_D0); + rtnl_lock(); + + 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 @@ -30228,26 +32184,17 @@ rtl8168_resume(struct pci_dev *pdev) #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); + if (HW_DASH_SUPPORT_DASH(tp)) 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); @@ -30262,18 +32209,43 @@ rtl8168_resume(struct pci_dev *pdev) rtl8168_hw_config(dev); - spin_unlock_irqrestore(&tp->lock, flags); + clear_bit(R8168_FLAG_DOWN, tp->task_flags); - rtl8168_schedule_work(dev, rtl8168_reset_task); + rtl8168_schedule_reset_work(tp); + rtl8168_schedule_esd_work(tp); + + 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 = { @@ -30285,9 +32257,13 @@ 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 diff --git a/drivers/net/ethernet/realtek/r8168_realwow.h b/drivers/net/ethernet/realtek/r8168/r8168_realwow.h old mode 100644 new mode 100755 similarity index 98% rename from drivers/net/ethernet/realtek/r8168_realwow.h rename to drivers/net/ethernet/realtek/r8168/r8168_realwow.h index 8e80e641..1c1a970c --- a/drivers/net/ethernet/realtek/r8168_realwow.h +++ b/drivers/net/ethernet/realtek/r8168/r8168_realwow.h @@ -5,7 +5,7 @@ # 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) 2024 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 diff --git a/drivers/net/ethernet/realtek/r8168/r8168_rss.c b/drivers/net/ethernet/realtek/r8168/r8168_rss.c new file mode 100755 index 00000000..3119f1f6 --- /dev/null +++ b/drivers/net/ethernet/realtek/r8168/r8168_rss.c @@ -0,0 +1,500 @@ +// 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) 2024 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 . +# +# Author: +# Realtek NIC software team +# 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 +#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++) + indir[i] = tp->rss_indir_tbl[i]; +} + +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_indir[RTL8168_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 ((indir[i] & 2) && R8168_MULTI_RSS_4Q(tp)) + hw_indir[j + 4] |= bit_on_cnt; + if (indir[i] & 1) + hw_indir[j] |= 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_indir[i]); +} + +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); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) +int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh) +{ + 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; + + rxfh->hfunc = ETH_RSS_HASH_TOP; + + if (rxfh->indir) + rtl8168_get_reta(tp, rxfh->indir); + + if (rxfh->key) + memcpy(rxfh->key, tp->rss_key, RTL8168_RSS_KEY_SIZE); + + return 0; +} + +int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack) +{ + 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 (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + /* Fill out the redirection table */ + if (rxfh->indir) { + int max_queues = tp->num_rx_rings; + + /* Verify user input. */ + for (i = 0; i < reta_entries; i++) + if (rxfh->indir[i] >= max_queues) + return -EINVAL; + + for (i = 0; i < reta_entries; i++) + tp->rss_indir_tbl[i] = rxfh->indir[i]; + } + + /* Fill out the rss hash key */ + if (rxfh->key) + memcpy(tp->rss_key, rxfh->key, RTL8168_RSS_KEY_SIZE); + + rtl8168_store_reta(tp); + + rtl8168_store_rss_key(tp); + + return 0; +} +#else +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; +} + +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 (indir[i] >= max_queues) + return -EINVAL; + + for (i = 0; i < reta_entries; i++) + tp->rss_indir_tbl[i] = indir[i]; + } + + /* 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; +} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,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_tbl[i] = ethtool_rxfh_indir_default(i, tp->num_rx_rings); + + netdev_rss_key_fill(tp->rss_key, RTL8168_RSS_KEY_SIZE); +} diff --git a/drivers/net/ethernet/realtek/r8168/r8168_rss.h b/drivers/net/ethernet/realtek/r8168/r8168_rss.h new file mode 100755 index 00000000..1bef7375 --- /dev/null +++ b/drivers/net/ethernet/realtek/r8168/r8168_rss.h @@ -0,0 +1,72 @@ +/* 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) 2024 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 . +# +# Author: +# Realtek NIC software team +# 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 +#include + +#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); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) +int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh); +int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, + struct netlink_ext_ack *extack); +#else +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); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */ +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 */ diff --git a/drivers/net/ethernet/realtek/rtl_eeprom.c b/drivers/net/ethernet/realtek/r8168/rtl_eeprom.c old mode 100644 new mode 100755 similarity index 96% rename from drivers/net/ethernet/realtek/rtl_eeprom.c rename to drivers/net/ethernet/realtek/r8168/rtl_eeprom.c index 3bd18795..a4b059f8 --- a/drivers/net/ethernet/realtek/rtl_eeprom.c +++ b/drivers/net/ethernet/realtek/r8168/rtl_eeprom.c @@ -5,7 +5,7 @@ # 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) 2024 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 @@ -157,9 +157,8 @@ void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data) int addr_sz = 6; int w_dummy_addr = 4; - if(tp->eeprom_type == EEPROM_TYPE_NONE) { - return ; - } + if(tp->eeprom_type == EEPROM_TYPE_NONE) + return; if (tp->eeprom_type==EEPROM_TYPE_93C46) { addr_sz = 6; @@ -178,17 +177,15 @@ void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data) rtl8168_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3); rtl8168_shift_out_bits(tp, reg, addr_sz); - if (rtl8168_eeprom_cmd_done(tp) < 0) { + if (rtl8168_eeprom_cmd_done(tp) < 0) return; - } rtl8168_stand_by(tp); rtl8168_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3); rtl8168_shift_out_bits(tp, reg, addr_sz); rtl8168_shift_out_bits(tp, data, 16); - if (rtl8168_eeprom_cmd_done(tp) < 0) { + if (rtl8168_eeprom_cmd_done(tp) < 0) return; - } rtl8168_stand_by(tp); rtl8168_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5); diff --git a/drivers/net/ethernet/realtek/rtl_eeprom.h b/drivers/net/ethernet/realtek/r8168/rtl_eeprom.h old mode 100644 new mode 100755 similarity index 97% rename from drivers/net/ethernet/realtek/rtl_eeprom.h rename to drivers/net/ethernet/realtek/r8168/rtl_eeprom.h index 473d8934..ba8e0bc2 --- a/drivers/net/ethernet/realtek/rtl_eeprom.h +++ b/drivers/net/ethernet/realtek/r8168/rtl_eeprom.h @@ -5,7 +5,7 @@ # 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) 2024 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 diff --git a/drivers/net/ethernet/realtek/rtltool.c b/drivers/net/ethernet/realtek/r8168/rtltool.c old mode 100644 new mode 100755 similarity index 82% rename from drivers/net/ethernet/realtek/rtltool.c rename to drivers/net/ethernet/realtek/r8168/rtltool.c index cba91952..a80a6725 --- a/drivers/net/ethernet/realtek/rtltool.c +++ b/drivers/net/ethernet/realtek/r8168/rtltool.c @@ -5,7 +5,7 @@ # 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) 2024 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 @@ -47,7 +47,6 @@ 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))) @@ -72,7 +71,6 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) break; } break; - case RTLTOOL_WRITE_MAC: if (my_cmd.len==1) writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset); @@ -84,51 +82,31 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) 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; @@ -138,20 +116,15 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) 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) @@ -173,7 +146,6 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) break; } break; - case RTLTOOL_WRITE_PCI: if (my_cmd.len==1) pci_write_config_byte(tp->pci_dev, my_cmd.offset, @@ -188,108 +160,69 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) 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; diff --git a/drivers/net/ethernet/realtek/rtltool.h b/drivers/net/ethernet/realtek/r8168/rtltool.h old mode 100644 new mode 100755 similarity index 97% rename from drivers/net/ethernet/realtek/rtltool.h rename to drivers/net/ethernet/realtek/r8168/rtltool.h index b5c6b440..5b755d6b --- a/drivers/net/ethernet/realtek/rtltool.h +++ b/drivers/net/ethernet/realtek/r8168/rtltool.h @@ -5,7 +5,7 @@ # 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) 2024 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