From 3515a9f56b31e807de50e524c0eba133f2b41f70 Mon Sep 17 00:00:00 2001 From: Alex Zhao Date: Thu, 29 May 2025 10:51:01 +0800 Subject: [PATCH 01/16] net: r8168: update r8168 driver to v8.055.00 Signed-off-by: Alex Zhao Change-Id: I70c1788eb070ff4eab9aba51a2e52f95f4ab9d01 --- drivers/net/ethernet/realtek/r8168/Makefile | 28 +- .../ethernet/realtek/r8168/Makefile_linux24x | 2 +- drivers/net/ethernet/realtek/r8168/r8168.h | 906 +- .../net/ethernet/realtek/r8168/r8168_asf.c | 16 +- .../net/ethernet/realtek/r8168/r8168_asf.h | 2 +- .../net/ethernet/realtek/r8168/r8168_dash.h | 7 +- .../net/ethernet/realtek/r8168/r8168_fiber.h | 2 +- .../ethernet/realtek/r8168/r8168_firmware.c | 2 +- .../ethernet/realtek/r8168/r8168_firmware.h | 2 +- drivers/net/ethernet/realtek/r8168/r8168_n.c | 8927 +++++++++++------ .../ethernet/realtek/r8168/r8168_realwow.h | 2 +- .../net/ethernet/realtek/r8168/r8168_rss.c | 482 + .../net/ethernet/realtek/r8168/r8168_rss.h | 72 + .../net/ethernet/realtek/r8168/rtl_eeprom.c | 29 +- .../net/ethernet/realtek/r8168/rtl_eeprom.h | 2 +- drivers/net/ethernet/realtek/r8168/rtltool.c | 79 +- drivers/net/ethernet/realtek/r8168/rtltool.h | 2 +- 17 files changed, 7047 insertions(+), 3515 deletions(-) create mode 100644 drivers/net/ethernet/realtek/r8168/r8168_rss.c create mode 100644 drivers/net/ethernet/realtek/r8168/r8168_rss.h diff --git a/drivers/net/ethernet/realtek/r8168/Makefile b/drivers/net/ethernet/realtek/r8168/Makefile index a1562c15161e..631dbfd2214f 100644 --- a/drivers/net/ethernet/realtek/r8168/Makefile +++ b/drivers/net/ethernet/realtek/r8168/Makefile @@ -4,7 +4,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 @@ -44,6 +44,11 @@ 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 +ENABLE_GIGA_LITE = y ifneq ($(KERNELRELEASE),) obj-$(CONFIG_R8168) := r8168.o @@ -67,7 +72,9 @@ ifneq ($(KERNELRELEASE),) r8168-objs += r8168_dash.o EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT endif - EXTRA_CFLAGS += -DCONFIG_R8168_NAPI + ifneq ($(ENABLE_RSS_SUPPORT), y) + EXTRA_CFLAGS += -DCONFIG_R8168_NAPI + endif EXTRA_CFLAGS += -DCONFIG_R8168_VLAN ifeq ($(CONFIG_DOWN_SPEED_100), y) EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100 @@ -97,6 +104,23 @@ ifneq ($(KERNELRELEASE),) 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 + ifeq ($(ENABLE_GIGA_LITE), y) + EXTRA_CFLAGS += -DENABLE_GIGA_LITE + endif else BASEDIR := /lib/modules/$(shell uname -r) KERNELDIR ?= $(BASEDIR)/build diff --git a/drivers/net/ethernet/realtek/r8168/Makefile_linux24x b/drivers/net/ethernet/realtek/r8168/Makefile_linux24x index a76625bf9792..fb4727a713ef 100644 --- a/drivers/net/ethernet/realtek/r8168/Makefile_linux24x +++ b/drivers/net/ethernet/realtek/r8168/Makefile_linux24x @@ -4,7 +4,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.h b/drivers/net/ethernet/realtek/r8168/r8168.h index 819181d8731a..672900c45d9d 100644 --- a/drivers/net/ethernet/realtek/r8168/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 @@ -33,9 +33,158 @@ ***********************************************************************************/ #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(3,3,0) +#define netif_xmit_stopped netif_tx_queue_stopped +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) +#ifndef MDIO_AN_EEE_ADV_100TX +#define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */ +#endif +#ifndef MDIO_AN_EEE_ADV_1000T +#define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +#define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */ +#define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */ +#define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ +#define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ +#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ +#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */ + +static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) +{ + u32 adv = 0; + + if (eee_adv & MDIO_EEE_100TX) + adv |= ADVERTISED_100baseT_Full; + if (eee_adv & MDIO_EEE_1000T) + adv |= ADVERTISED_1000baseT_Full; + if (eee_adv & MDIO_EEE_10GT) + adv |= ADVERTISED_10000baseT_Full; + if (eee_adv & MDIO_EEE_1000KX) + adv |= ADVERTISED_1000baseKX_Full; + if (eee_adv & MDIO_EEE_10GKX4) + adv |= ADVERTISED_10000baseKX4_Full; + if (eee_adv & MDIO_EEE_10GKR) + adv |= ADVERTISED_10000baseKR_Full; + + return adv; +} + +static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv) +{ + u16 reg = 0; + + if (adv & ADVERTISED_100baseT_Full) + reg |= MDIO_EEE_100TX; + if (adv & ADVERTISED_1000baseT_Full) + reg |= MDIO_EEE_1000T; + if (adv & ADVERTISED_10000baseT_Full) + reg |= MDIO_EEE_10GT; + if (adv & ADVERTISED_1000baseKX_Full) + reg |= MDIO_EEE_1000KX; + if (adv & ADVERTISED_10000baseKX4_Full) + reg |= MDIO_EEE_10GKX4; + if (adv & ADVERTISED_10000baseKR_Full) + reg |= MDIO_EEE_10GKR; + + return reg; +} +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) */ + +#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,8,0) +static inline void fsleep(unsigned long usecs) +{ + if (usecs <= 10) + udelay(usecs); + else if (usecs <= 20000) + usleep_range(usecs, 2 * usecs); + else + msleep(DIV_ROUND_UP(usecs, 1000)); +} +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) */ + +#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; @@ -130,11 +279,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 @@ -160,6 +312,10 @@ do { \ #define ENABLE_R8168_PROCFS #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,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 @@ -267,6 +423,13 @@ do { \ #define MDIO_EEE_1000T 0x0004 #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) +#define ethtool_keee ethtool_eee +#define rtl8168_ethtool_adv_to_mmd_eee_adv_cap1_t ethtool_adv_to_mmd_eee_adv_t +#else +#define rtl8168_ethtool_adv_to_mmd_eee_adv_cap1_t linkmode_to_mii_eee_cap1_t +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) */ + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) #ifdef CONFIG_NET_POLL_CONTROLLER #define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8168_netpoll @@ -319,7 +482,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" @@ -343,20 +506,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" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX +#define RTL8168_VERSION "8.055.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) @@ -428,9 +596,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 */ @@ -438,10 +609,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 @@ -516,12 +694,19 @@ This is free software, and you are welcome to redistribute it under certain cond #define ETH_MIN_MTU 68 #endif +#ifndef WRITE_ONCE +#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val)) +#endif +#ifndef READ_ONCE +#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) +#endif + /*****************************************************************************/ //#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) @@ -566,7 +751,11 @@ typedef int *napi_budget; typedef struct napi_struct *napi_ptr; typedef int napi_budget; -#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function) //dali for kernel6.3.2 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) +#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add_weight(ndev, &priv->napi, function, weight) +#else +#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) #define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget) #define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr) #define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev; @@ -602,6 +791,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__ @@ -636,7 +842,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) { @@ -657,12 +863,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 @@ -693,13 +899,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 */ @@ -1061,10 +1267,17 @@ enum RTL8168_registers { CounterAddrLow = 0x10, CounterAddrHigh = 0x14, CustomLED = 0x18, +#ifdef ENABLE_LIB_SUPPORT + TxDescStartAddrLow = 0x28, + TxDescStartAddrHigh = 0x2c, + TxHDescStartAddrLow = 0x20, + TxHDescStartAddrHigh = 0x24, +#else TxDescStartAddrLow = 0x20, TxDescStartAddrHigh = 0x24, TxHDescStartAddrLow = 0x28, TxHDescStartAddrHigh = 0x2c, +#endif /* ENABLE_LIB_SUPPORT */ FLASH = 0x30, ERSR = 0x36, ChipCmd = 0x37, @@ -1095,13 +1308,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, @@ -1122,6 +1342,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 { @@ -1137,6 +1365,8 @@ enum RTL8168_register_content { TxOK = 0x0004, RxErr = 0x0002, RxOK = 0x0001, + RxDU1 = 0x0002, + RxOK1 = 0x0001, /* RxStatusDesc */ RxRWT = (1 << 22), @@ -1181,6 +1411,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, @@ -1435,6 +1666,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, @@ -1455,9 +1697,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)]; }; @@ -1481,6 +1748,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, @@ -1490,17 +1780,238 @@ 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; +}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +struct ethtool_eee { + __u32 cmd; + __u32 supported; + __u32 advertised; + __u32 lp_advertised; + __u32 eee_active; + __u32 eee_enabled; + __u32 tx_lpi_enabled; + __u32 tx_lpi_timer; + __u32 reserved[2]; +}; +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */ + +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; @@ -1509,23 +2020,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; @@ -1533,7 +2056,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]; @@ -1566,10 +2090,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; @@ -1640,6 +2171,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; @@ -1649,8 +2182,9 @@ struct rtl8168_private { u8 DASH; u8 dash_printer_enabled; u8 HwPkgDet; - void __iomem *mapped_cmac_ioaddr; /* mapped cmac memory map physical address */ + u8 HwSuppOcpChannelVer; 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; @@ -1658,51 +2192,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) @@ -1725,17 +2253,152 @@ struct rtl8168_private { //Realwow-------------- #endif //ENABLE_REALWOW_SUPPORT - u32 eee_adv_t; - u8 eee_enabled; + struct ethtool_keee 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, @@ -1779,6 +2442,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 }; @@ -1817,14 +2482,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 @@ -1862,11 +2530,107 @@ 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_CMAC(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_CMAC(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/r8168_asf.c b/drivers/net/ethernet/realtek/r8168/r8168_asf.c index 29d7f5ae3b2c..ed999d61306e 100644 --- a/drivers/net/ethernet/realtek/r8168/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/r8168_asf.h b/drivers/net/ethernet/realtek/r8168/r8168_asf.h index 4c532ec2f89e..b1fdd94bc1e8 100644 --- a/drivers/net/ethernet/realtek/r8168/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/r8168_dash.h b/drivers/net/ethernet/realtek/r8168/r8168_dash.h index 094775300878..f9703f3d14ac 100644 --- a/drivers/net/ethernet/realtek/r8168/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 @@ -160,6 +160,7 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2; #define OCP_REG_CR (0x36) #define OCP_REG_DMEMSTA (0x38) #define OCP_REG_GPHYAR (0x60) +#define OCP_REG_FIRMWARE_MAJOR_VERSION (0x120) #define OCP_REG_CONFIG0_DASHEN BIT_15 @@ -175,6 +176,9 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2; #define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1) #define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2) #define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3) +#define HW_DASH_SUPPORT_CMAC(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || HW_DASH_SUPPORT_TYPE_3(_M)) +#define HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || \ + HW_DASH_SUPPORT_TYPE_3(_M)) #define RECV_FROM_FW_BUF_SIZE (2048) #define SEND_TO_FW_BUF_SIZE (2048) @@ -247,6 +251,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/r8168_fiber.h b/drivers/net/ethernet/realtek/r8168/r8168_fiber.h index 6a01b39934fc..9e18cbf8d4f7 100644 --- a/drivers/net/ethernet/realtek/r8168/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/r8168_firmware.c b/drivers/net/ethernet/realtek/r8168/r8168_firmware.c index 285498b503e1..f4b331a15ebe 100644 --- a/drivers/net/ethernet/realtek/r8168/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/r8168_firmware.h b/drivers/net/ethernet/realtek/r8168/r8168_firmware.h index 0954333fa73a..8906e63c31da 100644 --- a/drivers/net/ethernet/realtek/r8168/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/r8168_n.c b/drivers/net/ethernet/realtek/r8168/r8168_n.c index bce373d330c0..01128a8093a9 100644 --- a/drivers/net/ethernet/realtek/r8168/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 @@ -81,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 @@ -113,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; @@ -160,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", }, }; @@ -295,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), @@ -406,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; @@ -459,6 +473,16 @@ 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 +#ifdef ENABLE_GIGA_LITE +static int eee_giga_lite = 1; +#else +static int eee_giga_lite = 0; +#endif MODULE_AUTHOR("Realtek and the Linux r8168 crew "); MODULE_DESCRIPTION("RealTek RTL-8168 Gigabit Ethernet driver"); @@ -487,9 +511,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."); @@ -508,6 +529,12 @@ 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."); + +module_param(eee_giga_lite, int, 0); +MODULE_PARM_DESC(eee_giga_lite, "Enable Giga Lite."); + #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)"); @@ -533,6 +560,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 @@ -542,6 +570,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 @@ -552,10 +581,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); @@ -563,10 +590,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); @@ -574,7 +597,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); @@ -586,8 +619,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); @@ -601,9 +632,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) { @@ -755,7 +798,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) @@ -921,21 +964,238 @@ 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; + else { + if (eee_giga_lite) + speed = SPEED_1000; + } + } + + 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 { + fsleep(1000); + 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); @@ -1024,22 +1299,40 @@ 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, "eee_giga_lite\t0x%x\n", eee_giga_lite); 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; @@ -1051,36 +1344,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)); @@ -1097,6 +1373,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; } @@ -1108,12 +1387,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); @@ -1122,7 +1401,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; @@ -1134,12 +1414,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); @@ -1148,7 +1428,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; @@ -1160,12 +1441,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;) { @@ -1176,7 +1457,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; @@ -1188,7 +1470,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: @@ -1202,7 +1483,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); @@ -1211,7 +1493,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; @@ -1223,12 +1506,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); @@ -1245,7 +1528,262 @@ 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(); + +#ifdef ENABLE_LIB_SUPPORT + (void)i; + if (tp->tx_ring[0].TxDescArray) { + struct rtl8168_tx_ring *ring = &tp->tx_ring[0]; + + seq_printf(m, "\ndump rtk tx desc:%d\n", ring->num_tx_desc); + _proc_dump_tx_desc(m, ring->TxDescArray, + ring->TxDescAllocSize, + ring->num_tx_desc); + } + + if (tp->lib_tx_ring[1].desc_addr) { + struct rtl8168_ring *ring = &tp->lib_tx_ring[1]; + + seq_printf(m, "\ndump lib tx desc:%d\n", ring->ring_size); + _proc_dump_tx_desc(m, ring->desc_addr, + ring->desc_size, + ring->ring_size); + } +#else + 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); + } +#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; @@ -1258,13 +1796,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"); @@ -1274,12 +1812,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" @@ -1340,11 +1893,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" + "eee_giga_lite\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" + "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) @@ -1357,11 +1927,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, @@ -1418,23 +2003,40 @@ 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, + eee_giga_lite, 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"); @@ -1450,39 +2052,22 @@ static int proc_get_tally_counter(char *page, char **start, struct rtl8168_private *tp = netdev_priv(dev); struct rtl8168_counters *counters; 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"); @@ -1513,11 +2098,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; } @@ -1531,14 +2117,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", @@ -1551,7 +2137,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"); @@ -1567,14 +2154,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", @@ -1587,7 +2174,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"); @@ -1603,14 +2191,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); @@ -1626,7 +2214,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"); @@ -1642,7 +2231,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) { @@ -1660,7 +2248,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", @@ -1673,7 +2262,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: @@ -1689,14 +2279,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", @@ -1722,14 +2312,330 @@ 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; + 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(); + +#ifdef ENABLE_LIB_SUPPORT + (void)i; + if (tp->tx_ring[0].TxDescArray) { + struct rtl8168_tx_ring *ring = &tp->tx_ring[0]; + + len += snprintf(page + len, count - len, + "\ndump rtk tx desc:%d\n", + ring->num_tx_desc); + _proc_dump_tx_desc(page, &len, &count, + ring->TxDescArray, + ring->TxDescAllocSize, + ring->num_tx_desc); + } + + if (tp->lib_tx_ring[1].desc_addr) { + struct rtl8168_ring *ring = &tp->lib_tx_ring[1]; + + len += snprintf(page + len, count - len, + "\ndump lib tx desc:%d\n", + ring->ring_size); + _proc_dump_tx_desc(page, &len, &count, + ring->desc_addr, + ring->desc_size, + ring->ring_size); + } +#else + 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\n", + i, + ring->num_tx_desc); + _proc_dump_tx_desc(page, &len, &count, + ring->TxDescArray, + ring->TxDescAllocSize, + ring->num_tx_desc); + } +#endif //ENABLE_LIB_SUPPORT + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + + return len; +} + +static int proc_dump_msix_tbl(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + int i, j; + int len = 0; + void __iomem *ioaddr; + struct net_device *dev = data; + 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(); + + 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 @@ -1780,7 +2686,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 @@ -1788,7 +2694,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 }, @@ -1796,58 +2702,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) @@ -1857,33 +2839,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; @@ -1891,7 +2959,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; @@ -1923,7 +2991,7 @@ static void mdio_real_direct_write_phy_ocp(struct rtl8168_private *tp, RTL_W32(tp, PHYOCP, data32); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); if (!(RTL_R32(tp, PHYOCP) & OCPR_Flag)) break; @@ -1975,9 +3043,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 | @@ -1987,7 +3054,7 @@ static void mdio_real_write(struct rtl8168_private *tp, RTL_W32(tp, EPHY_RXER_NUM, 0); for (i = 0; i < 100; i++) { - mdelay(1); + fsleep(1000); if (!(RTL_R32(tp, OCPAR) & OCPAR_Flag)) break; } @@ -2006,11 +3073,11 @@ static void mdio_real_write(struct rtl8168_private *tp, (value & PHYAR_Data_Mask)); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed writing to the specified MII register */ if (!(RTL_R32(tp, PHYAR) & PHYAR_Flag)) { - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); break; } } @@ -2062,7 +3129,7 @@ static u32 mdio_real_direct_read_phy_ocp(struct rtl8168_private *tp, RTL_W32(tp, PHYOCP, data32); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); if (RTL_R32(tp, PHYOCP) & OCPR_Flag) break; @@ -2107,8 +3174,8 @@ static u32 rtl8168_mdio_real_read_phy_ocp(struct rtl8168_private *tp, return mdio_real_direct_read_phy_ocp(tp, ocp_addr); } -u32 mdio_real_read(struct rtl8168_private *tp, - u32 RegAddr) +static u32 mdio_real_read(struct rtl8168_private *tp, + u32 RegAddr) { int i, value = 0; @@ -2119,17 +3186,17 @@ u32 mdio_real_read(struct rtl8168_private *tp, RTL_W32(tp, EPHY_RXER_NUM, 0); for (i = 0; i < 100; i++) { - mdelay(1); + fsleep(1000); if (!(RTL_R32(tp, OCPAR) & OCPAR_Flag)) break; } - mdelay(1); + fsleep(1000); RTL_W32(tp, OCPAR, OCPAR_GPHY_Read); RTL_W32(tp, EPHY_RXER_NUM, 0); for (i = 0; i < 100; i++) { - mdelay(1); + fsleep(1000); if (RTL_R32(tp, OCPAR) & OCPAR_Flag) break; } @@ -2146,12 +3213,12 @@ u32 mdio_real_read(struct rtl8168_private *tp, PHYAR_Read | (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed retrieving data from the specified MII register */ if (RTL_R32(tp, PHYAR) & PHYAR_Flag) { value = RTL_R32(tp, PHYAR) & PHYAR_Data_Mask; - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); break; } } @@ -2201,17 +3268,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) @@ -2291,8 +3356,7 @@ rtl8168_clear_mcu_ocp_bit( rtl8168_clear_and_set_mcu_ocp_bit(tp, addr, mask, - 0 - ); + 0); } static void @@ -2305,8 +3369,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) @@ -2324,7 +3387,7 @@ static u32 real_ocp_read(struct rtl8168_private *tp, u16 addr, u8 len) RTL_W32(tp, OCPAR, (0x0F<<12) | (addr&0xFFF)); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); if (RTL_R32(tp, OCPAR) & OCPAR_Flag) break; } @@ -2346,7 +3409,7 @@ static u32 real_ocp_read(struct rtl8168_private *tp, u16 addr, u8 len) } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return value2; } @@ -2358,16 +3421,21 @@ u32 rtl8168_ocp_read_with_oob_base_address(struct rtl8168_private *tp, u16 addr, u32 rtl8168_ocp_read(struct rtl8168_private *tp, u16 addr, u8 len) { - u32 value = 0; - - if (HW_DASH_SUPPORT_TYPE_2(tp)) - value = rtl8168_ocp_read_with_oob_base_address(tp, addr, len, NO_BASE_ADDRESS); - else if (HW_DASH_SUPPORT_TYPE_3(tp)) - value = rtl8168_ocp_read_with_oob_base_address(tp, addr, len, RTL8168FP_OOBMAC_BASE); - else - value = real_ocp_read(tp, addr, len); - - return value; + switch (tp->HwSuppOcpChannelVer) { + case 1: + return real_ocp_read(tp, addr, len); + case 2: + return rtl8168_ocp_read_with_oob_base_address(tp, addr, len, + NO_BASE_ADDRESS); + case 3: + return rtl8168_ocp_read_with_oob_base_address(tp, addr, len, + RTL8168FP_OOBMAC_BASE); + default: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(1); +#endif + return 0; + } } static int real_ocp_write(struct rtl8168_private *tp, u16 addr, u8 len, u32 value) @@ -2394,7 +3462,7 @@ static int real_ocp_write(struct rtl8168_private *tp, u16 addr, u8 len, u32 valu RTL_W32(tp, OCPAR, OCPAR_Flag | (0x0F<<12) | (addr&0xFFF)); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed ERI write */ if (!(RTL_R32(tp, OCPAR) & OCPAR_Flag)) @@ -2410,7 +3478,7 @@ static int real_ocp_write(struct rtl8168_private *tp, u16 addr, u8 len, u32 valu } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return 0; } @@ -2422,12 +3490,21 @@ u32 rtl8168_ocp_write_with_oob_base_address(struct rtl8168_private *tp, u16 addr void rtl8168_ocp_write(struct rtl8168_private *tp, u16 addr, u8 len, u32 value) { - if (HW_DASH_SUPPORT_TYPE_2(tp)) - rtl8168_ocp_write_with_oob_base_address(tp, addr, len, value, NO_BASE_ADDRESS); - else if (HW_DASH_SUPPORT_TYPE_3(tp)) - rtl8168_ocp_write_with_oob_base_address(tp, addr, len, value, RTL8168FP_OOBMAC_BASE); - else + switch (tp->HwSuppOcpChannelVer) { + case 1: real_ocp_write(tp, addr, len, value); + break; + case 2: + rtl8168_ocp_write_with_oob_base_address(tp, addr, len, value, + NO_BASE_ADDRESS); + break; + case 3: + rtl8168_ocp_write_with_oob_base_address(tp, addr, len, value, + RTL8168FP_OOBMAC_BASE); + break; + default: + break; + } } void rtl8168_oob_mutex_lock(struct rtl8168_private *tp) @@ -2542,7 +3619,20 @@ void rtl8168_oob_notify(struct rtl8168_private *tp, u8 cmd) rtl8168_ocp_write(tp, 0x30, 1, 0x01); } -static int rtl8168_check_dash(struct rtl8168_private *tp) +static u32 rtl8168_get_dash_fw_ver(struct rtl8168_private *tp) +{ + u32 ver = 0xffffffff; + + if (!HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(tp)) + goto exit; + + ver = rtl8168_ocp_read(tp, OCP_REG_FIRMWARE_MAJOR_VERSION, 4); + +exit: + return ver; +} + +static int _rtl8168_check_dash(struct rtl8168_private *tp) { if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { if (rtl8168_ocp_read(tp, 0x128, 1) & BIT_0) @@ -2564,28 +3654,47 @@ static int rtl8168_check_dash(struct rtl8168_private *tp) } } +static int rtl8168_check_dash(struct rtl8168_private *tp) +{ + int dash_enabled; + u32 fw_ver; + + dash_enabled = _rtl8168_check_dash(tp); + if (!dash_enabled) + goto exit; + + if (!HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(tp)) + goto exit; + + fw_ver = rtl8168_get_dash_fw_ver(tp); + if (fw_ver == 0 || fw_ver == 0xffffffff) + dash_enabled = 0; +exit: + return dash_enabled; +} + void rtl8168_dash2_disable_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_CMAC(tp)) { u16 WaitCnt; 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 ); + fsleep(50); WaitCnt++; } while(WaitCnt < 2000); @@ -2599,9 +3708,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_CMAC(tp)) RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) | BIT_0); - } } void rtl8168_dash2_disable_rx(struct rtl8168_private *tp) @@ -2609,9 +3717,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_CMAC(tp)) + RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) & ~(BIT_0)); } void rtl8168_dash2_enable_rx(struct rtl8168_private *tp) @@ -2619,24 +3726,24 @@ 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_CMAC(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) { 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 ); + if (HW_DASH_SUPPORT_CMAC(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, @@ -2659,14 +3766,14 @@ static void _rtl8168_ephy_write(struct rtl8168_private *tp, int addr, int value) (value & EPHYAR_Data_Mask)); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed EPHY write */ if (!(RTL_R32(tp, EPHYAR) & EPHYAR_Flag)) break; } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); } void rtl8168_ephy_write(struct rtl8168_private *tp, int addr, int value) @@ -2683,7 +3790,7 @@ static u16 _rtl8168_ephy_read(struct rtl8168_private *tp, int addr) EPHYAR_Read | (addr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed EPHY read */ if (RTL_R32(tp, EPHYAR) & EPHYAR_Flag) { @@ -2692,7 +3799,7 @@ static u16 _rtl8168_ephy_read(struct rtl8168_private *tp, int addr) } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return value; } @@ -2714,20 +3821,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 @@ -2749,16 +3854,15 @@ 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; RTL_W32(tp, CSIAR, cmd); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed CSI read */ if (RTL_R32(tp, CSIAR) & CSIAR_Flag) { @@ -2767,7 +3871,7 @@ rtl8168_csi_other_fun_read(struct rtl8168_private *tp, } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return value; } @@ -2787,27 +3891,25 @@ 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; RTL_W32(tp, CSIAR, cmd); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed CSI write */ if (!(RTL_R32(tp, CSIAR) & CSIAR_Flag)) break; } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); } static u32 @@ -2871,7 +3973,7 @@ rtl8168_csi_fun0_read_byte(struct rtl8168_private *tp, pci_read_config_byte(pdev, addr, &RetVal); } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return RetVal; } @@ -2893,14 +3995,14 @@ 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; pci_write_config_byte(pdev, addr, value); } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); } static void @@ -3071,7 +4173,7 @@ u32 rtl8168_eri_read_with_oob_base_address(struct rtl8168_private *tp, int addr, RTL_W32(tp, ERIAR, eri_cmd); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed ERI read */ if (RTL_R32(tp, ERIAR) & ERIAR_Flag) @@ -3095,7 +4197,7 @@ u32 rtl8168_eri_read_with_oob_base_address(struct rtl8168_private *tp, int addr, } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return value2; } @@ -3145,7 +4247,7 @@ int rtl8168_eri_write_with_oob_base_address(struct rtl8168_private *tp, int addr RTL_W32(tp, ERIAR, eri_cmd); for (i = 0; i < R8168_CHANNEL_WAIT_COUNT; i++) { - udelay(R8168_CHANNEL_WAIT_TIME); + fsleep(R8168_CHANNEL_WAIT_TIME); /* Check if the RTL8168 has completed ERI write */ if (!(RTL_R32(tp, ERIAR) & ERIAR_Flag)) @@ -3161,7 +4263,7 @@ int rtl8168_eri_write_with_oob_base_address(struct rtl8168_private *tp, int addr } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return 0; } @@ -3192,8 +4294,9 @@ 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; } } @@ -3219,8 +4322,9 @@ 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; } } @@ -3309,23 +4413,69 @@ 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); + fsleep(100); if (RTL_R32(tp, TxConfig) & BIT_11) break; } for (i = 0; i < 10; i++) { - udelay(100); + fsleep(100); if ((RTL_R8(tp, MCUCmd_reg) & (Txfifo_empty | Rxfifo_empty)) == (Txfifo_empty | Rxfifo_empty)) break; } - mdelay(1); + fsleep(2000); break; } } +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++) { + fsleep(10000); + 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++) { + fsleep(10000); + 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. @@ -3345,11 +4495,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); @@ -3357,42 +4503,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); @@ -3402,34 +4528,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: @@ -3446,60 +4554,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 @@ -3508,7 +4672,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) @@ -3522,23 +4686,37 @@ 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)) { + if (HW_DASH_SUPPORT_CMAC(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 @@ -3547,7 +4725,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); @@ -3555,7 +4733,7 @@ rtl8168_nic_reset(struct net_device *dev) case CFG_METHOD_1: case CFG_METHOD_2: case CFG_METHOD_3: - mdelay(10); + fsleep(10000); break; case CFG_METHOD_4: case CFG_METHOD_5: @@ -3567,14 +4745,15 @@ rtl8168_nic_reset(struct net_device *dev) case CFG_METHOD_14: case CFG_METHOD_15: RTL_W8(tp, ChipCmd, StopReq | CmdRxEnb | CmdTxEnb); - udelay(100); + fsleep(100); break; case CFG_METHOD_11: case CFG_METHOD_12: case CFG_METHOD_13: for (i = 0; i < 2000; i++) { - if (!(RTL_R8(tp, TxPoll) & NPQ)) break; - udelay(100); + if (!(RTL_R8(tp, TxPoll) & NPQ)) + break; + fsleep(100); } break; case CFG_METHOD_21: @@ -3592,10 +4771,12 @@ rtl8168_nic_reset(struct net_device *dev) case CFG_METHOD_33: case CFG_METHOD_34: case CFG_METHOD_35: - mdelay(2); + case CFG_METHOD_36: + case CFG_METHOD_37: + fsleep(2000); break; default: - mdelay(10); + fsleep(10000); break; } @@ -3606,7 +4787,7 @@ rtl8168_nic_reset(struct net_device *dev) /* Check that the chip has finished the reset. */ for (i = 100; i > 0; i--) { - udelay(100); + fsleep(100); if ((RTL_R8(tp, ChipCmd) & CmdReset) == 0) break; } @@ -3620,17 +4801,20 @@ rtl8168_nic_reset(struct net_device *dev) rtl8168_oob_notify(tp, OOB_CMD_RESET); for (i = 0; i < 10; i++) { - mdelay(10); + fsleep(10000); if (rtl8168_ocp_read(tp, 0x010, 2)&0x00004000) break; } 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 @@ -3675,6 +4859,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); @@ -3682,11 +4868,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); @@ -3695,8 +4883,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; @@ -3715,9 +4915,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 { @@ -3747,16 +4947,16 @@ 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); + fsleep(200); rx_cmd = le32_to_cpu(rxd->opts1); if ((rx_cmd & DescOwn) == 0) 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; @@ -3778,15 +4978,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 @@ -3805,11 +5005,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 @@ -3822,7 +5024,7 @@ rtl8168_wait_phy_reset_complete(struct rtl8168_private *tp) if (!val) return 0; - mdelay(1); + fsleep(1000); } return -1; @@ -3868,10 +5070,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 @@ -3904,6 +5138,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); @@ -3942,7 +5178,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); @@ -3969,7 +5205,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); @@ -3991,7 +5227,7 @@ rtl8168_hw_aspm_clkreq_enable(struct rtl8168_private *tp, bool enable) RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~ASPM_en); } - udelay(10); + fsleep(10); } #ifdef ENABLE_DASH_SUPPORT @@ -4002,16 +5238,164 @@ NICChkTypeEnableDashInterrupt(struct rtl8168_private *tp) // // even disconnected, enable 3 dash interrupt mask bits for in-band/out-band communication // - if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + if (HW_DASH_SUPPORT_CMAC(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) { @@ -4029,96 +5413,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); @@ -4126,52 +5421,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); } } @@ -4251,7 +5501,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); @@ -4273,7 +5524,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); @@ -4291,7 +5543,7 @@ rtl8168_wait_ll_share_fifo_ready(struct net_device *dev) int i; for (i = 0; i < 10; i++) { - udelay(100); + fsleep(100); if (RTL_R16(tp, 0xD2) & BIT_9) break; } @@ -4318,6 +5570,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); @@ -4335,6 +5589,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; } @@ -4356,6 +5612,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; } @@ -4376,6 +5634,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)) @@ -4418,9 +5678,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; @@ -4451,8 +5713,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; } @@ -4479,6 +5743,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); @@ -4507,6 +5773,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; @@ -4533,6 +5801,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); @@ -4580,6 +5850,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; @@ -4600,6 +5871,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); @@ -4622,7 +5895,7 @@ rtl8168_init_pci_offset_180(struct rtl8168_private *tp) } static void -rtl8168_set_pci_99_180_exit_driver_para(struct net_device *dev) +rtl8168_set_pci_99_exit_driver_para(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(dev); @@ -4641,27 +5914,49 @@ 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); break; } +} - 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: - 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); } } @@ -4670,7 +5965,14 @@ 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); @@ -4684,6 +5986,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); @@ -4713,7 +6016,7 @@ rtl8168_hw_d3_para(struct net_device *dev) gphy_val = rtl8168_mdio_read(tp, 0x06); gphy_val &= ~BIT_7; rtl8168_mdio_write(tp, 0x06, gphy_val); - mdelay(1); + fsleep(1000); rtl8168_mdio_write(tp, 0x1F, 0x0007); rtl8168_mdio_write(tp, 0x1E, 0x002C); gphy_val = rtl8168_mdio_read(tp, 0x16); @@ -4723,12 +6026,13 @@ rtl8168_hw_d3_para(struct net_device *dev) } } - rtl8168_set_pci_99_180_exit_driver_para(dev); + rtl8168_set_pci_99_exit_driver_para(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; @@ -4740,7 +6044,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); @@ -4794,15 +6099,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) @@ -4828,10 +6132,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 @@ -4937,6 +6239,37 @@ rtl8168_set_pci_pme(struct rtl8168_private *tp, int set) pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, pmc); } +static void +rtl8168_enable_giga_lite(struct rtl8168_private *tp, u32 adv) +{ + switch (tp->mcfg) { + case CFG_METHOD_29 ... CFG_METHOD_36: + rtl8168_mdio_write(tp, 0x1F, 0x0A42); + if (adv & ADVERTISED_1000baseT_Full) + rtl8168_set_eth_phy_bit(tp, 0x14, BIT_9); + else + rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_9); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + break; + default: + break; + } +} + +static void +rtl8168_disable_giga_lite(struct rtl8168_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_29 ... CFG_METHOD_36: + rtl8168_mdio_write(tp, 0x1F, 0x0A42); + rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_9); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + break; + default: + break; + } +} + static void rtl8168_set_wol_link_speed(struct net_device *dev) { @@ -5020,6 +6353,8 @@ skip_check_lpa: rtl8168_mdio_write(tp, MII_ADVERTISE, auto_nego); rtl8168_mdio_write(tp, MII_CTRL1000, giga_ctrl); + rtl8168_disable_giga_lite(tp); + rtl8168_phy_restart_nway(dev); exit: @@ -5031,6 +6366,10 @@ rtl8168_powerdown_pll(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(dev); + /* Reboot not set wol link speed */ + if (system_state == SYSTEM_RESTART) + return; + if (tp->wol_enabled == WOL_ENABLED || tp->DASH || tp->EnableKCPOffload) { rtl8168_set_hw_wol(dev, tp->wol_opts); @@ -5042,7 +6381,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); @@ -5107,6 +6446,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; } @@ -5116,7 +6456,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; @@ -5152,6 +6492,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; } @@ -5166,27 +6507,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 @@ -5194,19 +6527,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; @@ -5219,9 +6547,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)); @@ -5252,10 +6580,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) { - //Disable Giga Lite - rtl8168_mdio_write(tp, 0x1F, 0x0A42); - rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_9); + tp->mcfg == CFG_METHOD_35 || tp->mcfg == CFG_METHOD_36) { if (tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 || tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) rtl8168_clear_eth_phy_bit(tp, 0x14, BIT_7); @@ -5270,6 +6595,11 @@ rtl8168_set_speed_xmii(struct net_device *dev, duplex = DUPLEX_FULL; } + if (eee_giga_lite && (autoneg == AUTONEG_ENABLE)) + rtl8168_enable_giga_lite(tp, adv); + else + rtl8168_disable_giga_lite(tp); + giga_ctrl = rtl8168_mdio_read(tp, MII_CTRL1000); giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); @@ -5294,8 +6624,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; @@ -5304,7 +6642,6 @@ rtl8168_set_speed_xmii(struct net_device *dev, rtl8168_mdio_write(tp, MII_ADVERTISE, auto_nego); rtl8168_mdio_write(tp, MII_CTRL1000, giga_ctrl); rtl8168_phy_restart_nway(dev); - mdelay(20); } else { /*true force*/ if (speed == SPEED_10 || speed == SPEED_100) @@ -5351,9 +6688,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; @@ -5378,9 +6713,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; } @@ -5389,17 +6722,13 @@ rtl8168_set_settings(struct net_device *dev, static u32 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; } @@ -5409,11 +6738,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; } @@ -5423,13 +6749,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; @@ -5445,8 +6768,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; } @@ -5455,13 +6776,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 @@ -5469,8 +6787,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) @@ -5505,9 +6821,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; @@ -5515,7 +6829,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 @@ -5526,16 +6839,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) @@ -5589,17 +6899,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; } @@ -5623,7 +6928,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; @@ -5637,21 +6942,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 @@ -5666,7 +6992,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 | @@ -5680,14 +7005,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; @@ -5751,6 +7074,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); @@ -5762,6 +7086,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 } @@ -5789,14 +7114,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; @@ -5827,7 +7150,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) @@ -5923,26 +7245,14 @@ 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) @@ -5961,7 +7271,7 @@ static void rtl8168_get_ringparam(struct net_device *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 LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) @@ -5988,7 +7298,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; } @@ -5998,8 +7308,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); @@ -6017,9 +7326,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(); @@ -6028,21 +7334,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); @@ -6129,7 +7421,7 @@ static int rtl_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, pci_write_config_word(tp->pci_dev, VPD_addr, (u16)i*4); ret = -EFAULT; for (j = 0; j < 10; j++) { - udelay(400); + fsleep(400); pci_read_config_word(tp->pci_dev, VPD_addr, &tmp); if (tmp&0x8000) { ret = 0; @@ -6191,11 +7483,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_keee *eee = &tp->eee; + u16 eee_adv_cap1_t = rtl8168_ethtool_adv_to_mmd_eee_adv_cap1_t(eee->advertised); ret = 0; switch (tp->mcfg) { @@ -6290,6 +7742,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); @@ -6297,7 +7750,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_cap1_t); rtl8168_mdio_write(tp, 0x1F, 0x0000); break; @@ -6315,6 +7768,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); @@ -6324,156 +7778,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; @@ -6573,12 +7883,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); @@ -6594,6 +7908,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); @@ -6603,108 +7918,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; } @@ -6712,15 +7926,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); @@ -6734,102 +7943,283 @@ 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 int -rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *eee) +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; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0) +static void +rtl8168_adv_to_linkmode(unsigned long *mode, u64 adv) +{ + linkmode_zero(mode); + + if (adv & ADVERTISED_10baseT_Half) + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mode); + if (adv & ADVERTISED_10baseT_Full) + linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, mode); + if (adv & ADVERTISED_100baseT_Half) + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mode); + if (adv & ADVERTISED_100baseT_Full) + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mode); + if (adv & ADVERTISED_1000baseT_Half) + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, mode); + if (adv & ADVERTISED_1000baseT_Full) + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mode); + if (adv & ADVERTISED_2500baseX_Full) + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, mode); +} + +static int +rtl_ethtool_get_eee(struct net_device *net, struct ethtool_keee *edata) +{ + __ETHTOOL_DECLARE_LINK_MODE_MASK(common); struct rtl8168_private *tp = netdev_priv(net); - u32 lp, adv, supported = 0; - unsigned long flags; + struct ethtool_keee *eee = &tp->eee; + u32 tx_lpi_timer; u16 val; - switch (tp->mcfg) { - case CFG_METHOD_21 ... CFG_METHOD_35: - break; - default: + if (!rtl8168_support_eee(tp)) return -EOPNOTSUPP; - } - spin_lock_irqsave(&tp->lock, flags); - - if (unlikely(tp->rtk_enable_diag)) { - spin_unlock_irqrestore(&tp->lock, flags); + if (unlikely(tp->rtk_enable_diag)) return -EBUSY; - } - - rtl8168_mdio_write(tp, 0x1F, 0x0A5C); - val = rtl8168_mdio_read(tp, 0x12); - supported = mmd_eee_cap_to_ethtool_sup_t(val); + /* Get LP advertisement EEE */ rtl8168_mdio_write(tp, 0x1F, 0x0A5D); - val = rtl8168_mdio_read(tp, 0x10); - adv = mmd_eee_adv_to_ethtool_adv_t(val); - val = rtl8168_mdio_read(tp, 0x11); - lp = mmd_eee_adv_to_ethtool_adv_t(val); + mii_eee_cap1_mod_linkmode_t(edata->lp_advertised, val);; + + /* Get EEE Tx LPI timer*/ + tx_lpi_timer = rtl8168_device_lpi_t_to_ethtool_lpi_t(tp, eee->tx_lpi_timer); val = rtl8168_eri_read(tp, 0x1B0, 2, ERIAR_ExGMAC); val &= BIT_1 | BIT_0; rtl8168_mdio_write(tp, 0x1F, 0x0000); - spin_unlock_irqrestore(&tp->lock, flags); - - eee->eee_enabled = !!val; - eee->eee_active = !!(supported & adv & lp); - eee->supported = supported; - eee->advertised = adv; - eee->lp_advertised = lp; + edata->eee_enabled = !!val; + linkmode_copy(edata->supported, eee->supported); + linkmode_copy(edata->advertised, eee->advertised); + edata->tx_lpi_enabled = edata->eee_enabled; + edata->tx_lpi_timer = tx_lpi_timer; + linkmode_and(common, edata->advertised, edata->lp_advertised); + edata->eee_active = !linkmode_empty(common); return 0; } static int -rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *eee) +rtl_ethtool_set_eee(struct net_device *net, struct ethtool_keee *edata) { + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); + __ETHTOOL_DECLARE_LINK_MODE_MASK(tmp); struct rtl8168_private *tp = netdev_priv(net); - unsigned long flags; + struct ethtool_keee *eee = &tp->eee; + int rc = 0; - switch (tp->mcfg) { - case CFG_METHOD_21 ... CFG_METHOD_35: - break; - default: + if (!rtl8168_support_eee(tp)) return -EOPNOTSUPP; - } if (HW_SUPP_SERDES_PHY(tp) || !HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp) || tp->DASH) return -EOPNOTSUPP; - spin_lock_irqsave(&tp->lock, flags); - if (unlikely(tp->rtk_enable_diag)) { - spin_unlock_irqrestore(&tp->lock, flags); - return -EBUSY; + dev_printk(KERN_WARNING, tp_to_dev(tp), "Diag Enabled\n"); + rc = -EBUSY; + goto out; } - tp->eee_enabled = eee->eee_enabled; - tp->eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); + if (tp->autoneg != AUTONEG_ENABLE) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE requires autoneg\n"); + rc = -EINVAL; + goto out; + } - if (tp->eee_enabled) - rtl8168_enable_EEE(tp); + rtl8168_adv_to_linkmode(advertising, tp->advertising); + if (linkmode_empty(edata->advertised)) { + linkmode_and(edata->advertised, advertising, eee->supported); + } else if (linkmode_andnot(tmp, edata->advertised, advertising)) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised must be a subset of autoneg advertised speeds\n"); + rc = -EINVAL; + goto out; + } + + if (linkmode_andnot(tmp, edata->advertised, eee->supported)) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised must be a subset of support \n"); + rc = -EINVAL; + goto out; + } + + linkmode_copy(eee->advertised, edata->advertised); + eee->tx_lpi_enabled = edata->tx_lpi_enabled; + eee->tx_lpi_timer = edata->tx_lpi_timer; + 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); +out: + return rc; +} +#else +static int +rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) +{ + struct rtl8168_private *tp = netdev_priv(net); + struct ethtool_eee *eee = &tp->eee; + u32 lp, adv, tx_lpi_timer, supported = 0; + u16 val; + + if (!rtl8168_support_eee(tp)) + return -EOPNOTSUPP; + + if (unlikely(tp->rtk_enable_diag)) + return -EBUSY; + + /* 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, 0x11); + lp = mmd_eee_adv_to_ethtool_adv_t(val); + + /* Get EEE Tx LPI timer*/ + tx_lpi_timer = rtl8168_device_lpi_t_to_ethtool_lpi_t(tp, eee->tx_lpi_timer); + + val = rtl8168_eri_read(tp, 0x1B0, 2, ERIAR_ExGMAC); + val &= BIT_1 | BIT_0; + + rtl8168_mdio_write(tp, 0x1F, 0x0000); + + edata->eee_enabled = !!val; + edata->eee_active = !!(supported & adv & lp); + edata->supported = supported; + edata->advertised = adv; + edata->lp_advertised = lp; + edata->tx_lpi_enabled = edata->eee_enabled; + edata->tx_lpi_timer = tx_lpi_timer; + return 0; } + +static int +rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) +{ + struct rtl8168_private *tp = netdev_priv(net); + struct ethtool_eee *eee = &tp->eee; + u32 advertising; + int rc = 0; + + 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; + + if (unlikely(tp->rtk_enable_diag)) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "Diag Enabled\n"); + rc = -EBUSY; + goto out; + } + + if (tp->autoneg != AUTONEG_ENABLE) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE requires autoneg\n"); + rc = -EINVAL; + goto out; + } + + 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); + + rtl_nway_reset(net); + +out: + return rc; +} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,9,0) */ #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, @@ -6881,6 +8271,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) @@ -6888,175 +8286,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; @@ -7229,9 +8465,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; @@ -7298,10 +8549,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) { @@ -7337,7 +8587,7 @@ static u8 rtl8168_efuse_read(struct rtl8168_private *tp, u16 reg) cnt = 0; do { - udelay(100); + fsleep(100); temp = RTL_R32(tp, EFUSEAR); cnt++; } while (!(temp & EFUSE_READ_OK) && (cnt < EFUSE_Check_Cnt)); @@ -7354,7 +8604,7 @@ static u8 rtl8168_efuse_read(struct rtl8168_private *tp, u16 reg) cnt = 0; do { - udelay(100); + fsleep(100); temp = RTL_R32(tp, EFUSEAR); cnt++; } while (!(temp & EFUSE_READ_OK) && (cnt < EFUSE_Check_Cnt)); @@ -7380,7 +8630,7 @@ static u8 rtl8168_efuse_read(struct rtl8168_private *tp, u16 reg) cnt = 0; do { - udelay(100); + fsleep(100); temp = RTL_R32(tp, EFUSEAR); cnt++; } while ((temp & BIT_31) && (cnt < EFUSE_Check_Cnt)); @@ -7400,7 +8650,7 @@ static u8 rtl8168_efuse_read(struct rtl8168_private *tp, u16 reg) } } - udelay(R8168_CHANNEL_EXIT_DELAY_TIME); + fsleep(R8168_CHANNEL_EXIT_DELAY_TIME); return efuse_data; } @@ -7419,7 +8669,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) @@ -7469,7 +8719,7 @@ rtl8168_wait_phy_state_ready(struct rtl8168_private *tp, do { TmpPhyState = rtl8168_get_phy_state(tp); - mdelay(1); + fsleep(1000); i++; } while ((i < WaitCount) && (TmpPhyState != PhyState)); @@ -7512,7 +8762,7 @@ rtl8168_test_phy_ocp_v2(struct rtl8168_private *tp) rtl8168_mdio_write(tp, 0x1F, 0x0C41); rtl8168_set_eth_phy_bit(tp, 0x14, BIT_0); rtl8168_mdio_write(tp, 0x1F, 0x0000); - mdelay(24); //24ms + fsleep(24000); //24ms rtl8168_mdio_write(tp, 0x1F, 0x0C40); PhyRegValue = rtl8168_mdio_read(tp, 0x12); @@ -7522,7 +8772,7 @@ rtl8168_test_phy_ocp_v2(struct rtl8168_private *tp) rtl8168_mdio_write(tp, 0x1F, 0x0C40); rtl8168_set_eth_phy_bit(tp, 0x11, (BIT_15 | BIT_14)); rtl8168_clear_eth_phy_bit(tp, 0x11, (BIT_15 | BIT_14)); - mdelay(100); + fsleep(100000); rtl8168_mdio_write(tp, 0x1F, 0x0C40); PhyRegValue = rtl8168_mdio_read(tp, 0x12); WaitCnt++; @@ -7597,7 +8847,7 @@ rtl8168_test_phy_ocp_v3(struct rtl8168_private *tp) rtl8168_mdio_write(tp, 0x1F, 0x0C41); rtl8168_set_eth_phy_bit(tp, 0x14, BIT_0); rtl8168_mdio_write(tp, 0x1F, 0x0000); - mdelay(24000); //24ms + fsleep(24000); //24ms rtl8168_mdio_write(tp, 0x1F, 0x0C40); PhyRegValue = rtl8168_mdio_read(tp, 0x12); @@ -7607,7 +8857,7 @@ rtl8168_test_phy_ocp_v3(struct rtl8168_private *tp) rtl8168_mdio_write(tp, 0x1F, 0x0C40); rtl8168_set_eth_phy_bit(tp, 0x11, (BIT_15 | BIT_14)); rtl8168_clear_eth_phy_bit(tp, 0x11, (BIT_15 | BIT_14)); - mdelay(100000); + fsleep(100000); rtl8168_mdio_write(tp, 0x1F, 0x0C40); PhyRegValue = rtl8168_mdio_read(tp, 0x12); WaitCnt++; @@ -7633,7 +8883,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; @@ -7708,7 +8957,7 @@ rtl8168_wait_phy_ups_resume(struct net_device *dev, u16 PhyState) do { TmpPhyState = rtl8168_mdio_read_phy_ocp(tp, 0x0A42, 0x10); TmpPhyState &= 0x7; - mdelay(1); + fsleep(100); i++; } while ((i < 100) && (TmpPhyState != PhyState)); @@ -7720,17 +8969,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 @@ -7755,13 +9002,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); @@ -7819,7 +9064,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); @@ -7857,6 +9104,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; @@ -7888,6 +9137,30 @@ rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(dev); + 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_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: + case CFG_METHOD_37: + /* support mac mcu */ + break; + default: + return; + } + if (tp->HwSuppAspmClkIntrLock) { rtl8168_enable_cfg9346_write(tp); rtl8168_hw_aspm_clkreq_enable(tp, false); @@ -7902,6 +9175,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; } @@ -7922,6 +9197,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); @@ -7930,7 +9207,7 @@ rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev) rtl8168_mac_ocp_write(tp, 0xFC32, 0x0000); rtl8168_mac_ocp_write(tp, 0xFC34, 0x0000); rtl8168_mac_ocp_write(tp, 0xFC36, 0x0000); - mdelay(3); + fsleep(3000); rtl8168_mac_ocp_write(tp, 0xFC26, 0x0000); break; } @@ -7948,222 +9225,220 @@ rtl8168_set_mac_mcu_8168g_1(struct net_device *dev) rtl8168_mac_ocp_write(tp, 0xE434, 0x0004); rtl8168_mac_ocp_write(tp, 0xE43C, 0x0004); - 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 @@ -8171,129 +9446,127 @@ rtl8168_set_mac_mcu_8168gu_1(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(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 @@ -8301,428 +9574,426 @@ rtl8168_set_mac_mcu_8168gu_2(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(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 @@ -8730,129 +10001,127 @@ rtl8168_set_mac_mcu_8411b_1(struct net_device *dev) { struct rtl8168_private *tp = netdev_priv(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 @@ -8890,11 +10159,8 @@ rtl8168_set_mac_mcu_8168ep_1(struct net_device *dev) 0x0000 }; - 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); @@ -8933,11 +10199,8 @@ rtl8168_set_mac_mcu_8168ep_2(struct net_device *dev) 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000 }; - 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); @@ -8947,12 +10210,6 @@ rtl8168_set_mac_mcu_8168ep_2(struct net_device *dev) //rtl8168_mac_ocp_write(tp, 0xFC2C, 0x0485); } -static void -rtl8168_set_mac_mcu_8168h_1(struct net_device *dev) -{ - rtl8168_hw_disable_mac_mcu_bps(dev); -} - static void rtl8168_set_mac_mcu_8168h_2(struct net_device *dev) { @@ -8976,11 +10233,8 @@ rtl8168_set_mac_mcu_8168h_2(struct net_device *dev) 0xC402, 0xBC00, 0x0578, 0xC602, 0xBE00, 0x0000 }; - 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); @@ -9001,19 +10255,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, @@ -9057,14 +10311,11 @@ 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); @@ -9082,8 +10333,6 @@ rtl8168_set_mac_mcu_8168fp_1(struct net_device *dev) u16 i; u16 breakPointEnabled = 0; - rtl8168_hw_disable_mac_mcu_bps(dev); - if(tp->HwPkgDet == 0x00 || tp->HwPkgDet == 0x0F) { static const u16 mcu_patch_code_8168fp_1_1[] = { 0xE00A, 0xE0C1, 0xE104, 0xE108, 0xE10D, 0xE112, 0xE11C, 0xE121, 0xE000, @@ -9122,9 +10371,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); @@ -9137,7 +10385,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, @@ -9183,9 +10431,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); @@ -9203,7 +10450,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); @@ -9222,11 +10469,8 @@ rtl8168_set_mac_mcu_8168fp_8116as_2(struct net_device *dev) 0xBE00, 0x0000 }; - 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); @@ -9258,11 +10502,8 @@ _rtl8168_set_mac_mcu_8168fp_2(struct net_device *dev) 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000 }; - 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); @@ -9309,11 +10550,8 @@ rtl8168_set_mac_mcu_8168fp_3(struct net_device *dev) 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000 }; - 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); @@ -9334,6 +10572,8 @@ rtl8168_hw_mac_mcu_config(struct net_device *dev) if (tp->NotWrMcuPatchCode == TRUE) return; + rtl8168_hw_disable_mac_mcu_bps(dev); + switch (tp->mcfg) { case CFG_METHOD_21: rtl8168_set_mac_mcu_8168g_1(dev); @@ -9353,10 +10593,8 @@ rtl8168_hw_mac_mcu_config(struct net_device *dev) case CFG_METHOD_28: rtl8168_set_mac_mcu_8168ep_2(dev); break; - case CFG_METHOD_29: - 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: @@ -9372,6 +10610,12 @@ rtl8168_hw_mac_mcu_config(struct net_device *dev) case CFG_METHOD_35: rtl8168_set_mac_mcu_8168h_3(dev); break; + case CFG_METHOD_29: + case CFG_METHOD_36: + /* no mac mcu patch code */ + break; + default: + break; } } #endif @@ -9386,7 +10630,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) { @@ -9422,7 +10666,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) { @@ -9433,9 +10677,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; @@ -9459,31 +10705,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); @@ -9498,7 +10719,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); @@ -9513,7 +10735,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; } @@ -9567,8 +10789,7 @@ rtl8168_hw_ephy_config(struct net_device *dev) ClearAndSetPCIePhyBit(tp, 0x03, BIT_10, - BIT_5 - ); + BIT_5); break; case CFG_METHOD_9: @@ -9579,14 +10800,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); @@ -9599,8 +10818,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); @@ -9799,11 +11017,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); @@ -9847,12 +11064,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); @@ -9872,13 +11089,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); @@ -9886,13 +11101,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; } @@ -9906,7 +11129,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); @@ -9914,7 +11137,7 @@ rtl8168_set_phy_mcu_patch_request(struct rtl8168_private *tp) WaitCnt = 0; do { PhyRegValue = rtl8168_mdio_read(tp, 0x10); - udelay(100); + fsleep(100); WaitCnt++; } while (!(PhyRegValue & BIT_6) && (WaitCnt < 1000)); @@ -9936,7 +11159,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); @@ -9944,7 +11167,7 @@ rtl8168_clear_phy_mcu_patch_request(struct rtl8168_private *tp) WaitCnt = 0; do { PhyRegValue = rtl8168_mdio_read(tp, 0x10); - udelay(100); + fsleep(100); WaitCnt++; } while ((PhyRegValue & BIT_6) && (WaitCnt < 1000)); @@ -9996,6 +11219,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); @@ -10043,7 +11268,7 @@ rtl8168_disable_phy_disable_mode(struct net_device *dev) break; } - mdelay(1); + fsleep(1000); dprintk("disable phy disable mode.\n"); } @@ -10056,7 +11281,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; } @@ -10104,6 +11329,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); @@ -10138,7 +11365,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); @@ -10159,7 +11386,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); @@ -10185,7 +11412,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); @@ -10195,9 +11422,9 @@ 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); + fsleep(2000); break; default: break; @@ -10240,7 +11467,7 @@ rtl8168_set_phy_mcu_8168e_1(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp, 0x16, 0x4104); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1E); gphy_val &= 0x03FF; if (gphy_val == 0x000C) @@ -10248,7 +11475,7 @@ rtl8168_set_phy_mcu_8168e_1(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x07); if ((gphy_val & BIT_5) == 0) break; @@ -11585,7 +12812,7 @@ rtl8168_set_phy_mcu_8168e_1(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -11625,7 +12852,7 @@ rtl8168_set_phy_mcu_8168e_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp, 0x16, 0x4104); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1E); gphy_val &= 0x03FF; if (gphy_val==0x000C) @@ -11633,7 +12860,7 @@ rtl8168_set_phy_mcu_8168e_2(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x07); if ((gphy_val & BIT_5) == 0) break; @@ -13011,7 +14238,7 @@ rtl8168_set_phy_mcu_8168e_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -13052,7 +14279,7 @@ rtl8168_set_phy_mcu_8168e_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp, 0x16, 0x4104); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1E); gphy_val &= 0x03FF; if (gphy_val==0x000C) @@ -13060,7 +14287,7 @@ rtl8168_set_phy_mcu_8168e_2(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x07); if ((gphy_val & BIT_5) == 0) break; @@ -14394,7 +15621,7 @@ rtl8168_set_phy_mcu_8168e_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -14421,7 +15648,7 @@ rtl8168_set_phy_mcu_8168evl_1(struct net_device *dev) gphy_val = rtl8168_mdio_read(tp, 0x15); gphy_val &= ~(BIT_12); rtl8168_mdio_write(tp, 0x15, gphy_val); - mdelay(20); + fsleep(20000); rtl8168_mdio_write(tp, 0x1f, 0x0004); rtl8168_mdio_write(tp, 0x1f, 0x0007); rtl8168_mdio_write(tp, 0x1e, 0x0023); @@ -14430,7 +15657,7 @@ rtl8168_set_phy_mcu_8168evl_1(struct net_device *dev) gphy_val |= BIT_0; rtl8168_mdio_write(tp, 0x17, gphy_val); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x17); if (gphy_val & BIT_11) break; @@ -14448,14 +15675,14 @@ rtl8168_set_phy_mcu_8168evl_1(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0002); rtl8168_mdio_write(tp, 0x1f, 0x0000); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1E); if ((gphy_val & 0x03FF) == 0x0014) break; } rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x07); if ((gphy_val & BIT_5) == 0) break; @@ -16927,7 +18154,7 @@ rtl8168_set_phy_mcu_8168evl_1(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -16959,7 +18186,7 @@ rtl8168_set_phy_mcu_8168evl_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0007); rtl8168_mdio_write(tp, 0x1e, 0x002f); for (i = 0; i < 1000; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1c); if ((gphy_val & 0x0080) == 0x0080) break; @@ -16969,7 +18196,7 @@ rtl8168_set_phy_mcu_8168evl_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0007); rtl8168_mdio_write(tp, 0x1e, 0x0023); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x17); if (!(gphy_val & 0x0001)) break; @@ -17891,7 +19118,7 @@ rtl8168_set_phy_mcu_8168evl_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp, 0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -17927,7 +19154,7 @@ rtl8168_set_phy_mcu_8168f_1(struct net_device *dev) rtl8168_mdio_write(tp,0x1f, 0x0007); rtl8168_mdio_write(tp,0x1e, 0x002f); for (i = 0; i < 1000; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1c); if (gphy_val & 0x0080) break; @@ -17937,7 +19164,7 @@ rtl8168_set_phy_mcu_8168f_1(struct net_device *dev) rtl8168_mdio_write(tp,0x1f, 0x0007); rtl8168_mdio_write(tp,0x1e, 0x0023); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x18); if (!(gphy_val & 0x0001)) break; @@ -18772,7 +19999,7 @@ rtl8168_set_phy_mcu_8168f_1(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp,0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -18812,7 +20039,7 @@ rtl8168_set_phy_mcu_8168f_2(struct net_device *dev) rtl8168_mdio_write(tp,0x1f, 0x0007); rtl8168_mdio_write(tp,0x1e, 0x002f); for (i = 0; i < 1000; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1c); if (gphy_val & 0x0080) break; @@ -18822,7 +20049,7 @@ rtl8168_set_phy_mcu_8168f_2(struct net_device *dev) rtl8168_mdio_write(tp,0x1f, 0x0007); rtl8168_mdio_write(tp,0x1e, 0x0023); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x18); if (!(gphy_val & 0x0001)) break; @@ -19134,7 +20361,7 @@ rtl8168_set_phy_mcu_8168f_2(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp,0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -19166,7 +20393,7 @@ rtl8168_set_phy_mcu_8411_1(struct net_device *dev) rtl8168_mdio_write(tp,0x1f, 0x0007); rtl8168_mdio_write(tp,0x1e, 0x002f); for (i = 0; i < 1000; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x1c); if (gphy_val & 0x0080) break; @@ -19176,7 +20403,7 @@ rtl8168_set_phy_mcu_8411_1(struct net_device *dev) rtl8168_mdio_write(tp,0x1f, 0x0007); rtl8168_mdio_write(tp,0x1e, 0x0023); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x18); if (!(gphy_val & 0x0001)) break; @@ -19698,7 +20925,7 @@ rtl8168_set_phy_mcu_8411_1(struct net_device *dev) rtl8168_mdio_write(tp, 0x1f, 0x0000); rtl8168_mdio_write(tp,0x1f, 0x0005); for (i = 0; i < 200; i++) { - udelay(100); + fsleep(100); gphy_val = rtl8168_mdio_read(tp, 0x00); if (gphy_val & BIT_7) break; @@ -20999,7 +22226,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); @@ -21032,23 +22259,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); @@ -21382,15 +22631,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); @@ -21968,11 +23259,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) @@ -23682,6 +24976,13 @@ 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); + rtl8168_mdio_write(tp, 0x1E, 0x0023); + rtl8168_clear_eth_phy_bit(tp, 0x17, BIT_1); + rtl8168_mdio_write(tp, 0x1F, 0x0000); + + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { rtl8168_mdio_write(tp, 0x1f, 0x0005); rtl8168_mdio_write(tp, 0x05, 0x8b85); @@ -23883,8 +25184,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) { @@ -24068,124 +25368,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); @@ -24195,49 +25481,48 @@ rtl8168_hw_phy_config(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1F, 0x0A44); - rtl8168_set_eth_phy_bit( tp, 0x11, BIT_11 ); + 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); @@ -24248,7 +25533,7 @@ rtl8168_hw_phy_config(struct net_device *dev) } rtl8168_mdio_write(tp, 0x1F, 0x0A44); - rtl8168_set_eth_phy_bit( tp, 0x11, BIT_11 ); + rtl8168_set_eth_phy_bit(tp, 0x11, BIT_11); rtl8168_mdio_write(tp, 0x1F, 0x0000); if (tp->RequireAdcBiasPatch) { @@ -24261,10 +25546,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; @@ -24299,10 +25584,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); } } @@ -24310,138 +25606,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); @@ -24457,7 +25732,7 @@ 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); } } @@ -24580,7 +25855,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); } } @@ -24609,10 +25902,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); } @@ -24622,7 +25915,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); } @@ -24630,13 +25924,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); @@ -24671,6 +25966,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 /* @@ -24682,16 +25978,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) @@ -24726,6 +26030,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; } @@ -24764,11 +26070,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) { @@ -24777,8 +26103,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: @@ -24802,6 +26132,28 @@ rtl8168_init_software_variable(struct net_device *dev) break; } + switch (tp->mcfg) { + case CFG_METHOD_11: + case CFG_METHOD_12: + case CFG_METHOD_13: + tp->HwSuppOcpChannelVer = 1; + break; + case CFG_METHOD_23: + case CFG_METHOD_27: + case CFG_METHOD_28: + tp->HwSuppOcpChannelVer = 2; + break; + case CFG_METHOD_31: + case CFG_METHOD_32: + case CFG_METHOD_33: + case CFG_METHOD_34: + tp->HwSuppOcpChannelVer = 3; + break; + default: + tp->HwSuppOcpChannelVer = 0; + break; + } + switch (tp->mcfg) { case CFG_METHOD_31: case CFG_METHOD_32: @@ -24831,6 +26183,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; } @@ -24851,6 +26205,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; } @@ -24863,6 +26219,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; } @@ -24905,6 +26262,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; } @@ -24926,8 +26285,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); @@ -24940,9 +26311,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; } } @@ -24962,8 +26339,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: @@ -24984,12 +26359,12 @@ 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); + if (HW_DASH_SUPPORT_CMAC(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); } 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 @@ -25010,6 +26385,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; @@ -25023,6 +26400,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: @@ -25078,7 +26457,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) { @@ -25095,22 +26475,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)); @@ -25130,7 +26511,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); @@ -25197,6 +26580,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; } @@ -25222,6 +26606,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: @@ -25276,6 +26662,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: @@ -25325,6 +26713,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: @@ -25336,6 +26725,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) { @@ -25343,6 +26735,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); @@ -25361,13 +26830,34 @@ 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_keee *eee = &tp->eee; + + eee->eee_enabled = eee_enable; +#if LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) + eee->supported = SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full; + eee->advertised = mmd_eee_adv_to_ethtool_adv_t(MDIO_EEE_1000T | MDIO_EEE_100TX); +#else + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, eee->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, eee->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, eee->advertised); + linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, eee->advertised); +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) */ + 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 @@ -25389,8 +26879,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); @@ -25436,7 +26931,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 { @@ -25462,7 +26959,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); @@ -25490,7 +26989,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; } @@ -25508,19 +27007,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; } @@ -26299,7 +27793,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) { @@ -26308,19 +27801,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 @@ -26418,7 +27907,7 @@ rtl8168_phy_power_up(struct net_device *dev) case CFG_METHOD_23: case CFG_METHOD_27: case CFG_METHOD_28: - mdelay(10); + fsleep(10000); break; } @@ -26444,7 +27933,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; } @@ -26472,6 +27961,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: @@ -26501,7 +27992,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)) @@ -26657,24 +28148,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; @@ -26691,10 +28168,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; @@ -26707,7 +28182,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; } } @@ -26816,8 +28291,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); @@ -26831,12 +28306,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) @@ -26853,36 +28350,98 @@ 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) +static int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, + int minvec, int maxvec) +{ + int nvec = maxvec; + int rc; + + if (maxvec < minvec) + return -ERANGE; + + do { + rc = pci_enable_msix(dev, entries, nvec); + if (rc < 0) { + return rc; + } else if (rc > 0) { + if (rc < minvec) + return -ENOSPC; + nvec = rc; + } + } while (rc); + + return nvec; +} +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) */ 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: @@ -26895,40 +28454,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) @@ -26965,6 +28539,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) @@ -26998,7 +28648,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); @@ -27007,16 +28663,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) @@ -27040,9 +28697,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; @@ -27069,7 +28733,14 @@ rtl8168_init_one(struct pci_dev *pdev, dev->features |= NETIF_F_IPV6_CSUM; if ((tp->mcfg != CFG_METHOD_16) && (tp->mcfg != CFG_METHOD_17)) { dev->hw_features |= NETIF_F_TSO6; - //dev->features |= NETIF_F_TSO6; + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_26: + /* nothing to do */ + break; + default: + dev->features |= NETIF_F_TSO6; + break; + }; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,19,0) netif_set_tso_max_size(dev, LSO_64K); @@ -27088,15 +28759,27 @@ rtl8168_init_one(struct pci_dev *pdev, #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); @@ -27106,7 +28789,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; @@ -27149,6 +28833,10 @@ rtl8168_init_one(struct pci_dev *pdev, netif_carrier_off(dev); +#ifdef ENABLE_R8168_SYSFS + rtl8168_sysfs_init(dev); +#endif /* ENABLE_R8168_SYSFS */ + printk("%s", GPL_CLAIM); out: @@ -27162,9 +28850,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; @@ -27179,12 +28869,39 @@ 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); + 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: + case CFG_METHOD_37: + rtl8168_disable_pci_offset_180(tp); + break; + } + +#ifdef ENABLE_R8168_SYSFS + rtl8168_sysfs_remove(dev); +#endif //ENABLE_R8168_SYSFS + unregister_netdev(dev); rtl8168_disable_msi(pdev, tp); #ifdef ENABLE_R8168_PROCFS @@ -27204,13 +28921,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 @@ -27240,11 +29124,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; @@ -27257,27 +29140,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; @@ -27289,28 +29159,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); @@ -27327,35 +29193,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; } @@ -27365,60 +29220,63 @@ 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 -set_offset70F(struct rtl8168_private *tp, u8 setting) +_rtl8168_set_l1_l0s_entry_latency(struct rtl8168_private *tp, u8 setting) { u32 csi_tmp; - u32 temp = (u32)setting; - temp = temp << 24; + u32 temp; + + temp = setting & 0x3f; + temp <<= 24; /*set PCI configuration space offset 0x70F to setting*/ /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/ - csi_tmp = rtl8168_csi_read(tp, 0x70c) & 0x00ffffff; + csi_tmp = rtl8168_csi_read(tp, 0x70c) & 0xc0ffffff; rtl8168_csi_write(tp, 0x70c, csi_tmp | temp); } static void -set_offset79(struct rtl8168_private *tp, u8 setting) +rtl8168_set_l1_l0s_entry_latency(struct rtl8168_private *tp) { - //Set PCI configuration space offset 0x79 to setting + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + /* nothing to do */ + break; + default: + _rtl8168_set_l1_l0s_entry_latency(tp, 0x27); + break; + } +} +static void +_rtl8168_set_mrrs(struct rtl8168_private *tp, u8 setting) +{ struct pci_dev *pdev = tp->pci_dev; u8 device_control; - if (hwoptimize & HW_PATCH_SOC_LAN) - return; - pci_read_config_byte(pdev, 0x79, &device_control); device_control &= ~0x70; device_control |= setting; @@ -27426,7 +29284,29 @@ set_offset79(struct rtl8168_private *tp, u8 setting) } static void -set_offset711(struct rtl8168_private *tp, u8 setting) +rtl8168_set_mrrs(struct rtl8168_private *tp) +{ + if (hwoptimize & HW_PATCH_SOC_LAN) + return; + + switch (tp->mcfg) { + case CFG_METHOD_1 ... CFG_METHOD_3: + /* nothing to do */ + break; + case CFG_METHOD_4 ... CFG_METHOD_10: + if (tp->dev->mtu > ETH_DATA_LEN) + _rtl8168_set_mrrs(tp, 0x20); + else + _rtl8168_set_mrrs(tp, 0x40); + break; + default: + _rtl8168_set_mrrs(tp, 0x40); + break; + } +} + +static void +_rtl8168_set_eios_opt(struct rtl8168_private *tp, u8 setting) { u32 csi_tmp; u32 temp = (u32)setting; @@ -27438,6 +29318,19 @@ set_offset711(struct rtl8168_private *tp, u8 setting) rtl8168_csi_write(tp, 0x710, csi_tmp | temp); } +static void +rtl8168_set_eios_opt(struct rtl8168_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_21: + case CFG_METHOD_22: + _rtl8168_set_eios_opt(tp, 0x04); + break; + default: + break; + } +} + static void rtl8168_hw_set_rx_packet_filter(struct net_device *dev) { @@ -27456,9 +29349,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 { @@ -27495,6 +29387,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); @@ -27505,17 +29409,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); @@ -27531,8 +29428,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); @@ -27542,6 +29438,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: @@ -27560,6 +29458,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; } @@ -27586,6 +29486,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); @@ -27614,9 +29516,13 @@ rtl8168_hw_config(struct net_device *dev) RTL_W32(tp, TxConfig, (TX_DMA_BURST_unlimited << TxDMAShift) | (InterFrameGap << TxInterFrameGapShift)); - if (tp->mcfg == CFG_METHOD_4) { - set_offset70F(tp, 0x27); + rtl8168_set_l1_l0s_entry_latency(tp); + rtl8168_set_mrrs(tp); + + rtl8168_set_eios_opt(tp); + + if (tp->mcfg == CFG_METHOD_4) { RTL_W8(tp, DBG_reg, (0x0E << 4) | Fix_Nak_1 | Fix_Nak_2); RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); @@ -27627,13 +29533,9 @@ rtl8168_hw_config(struct net_device *dev) if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - set_offset79(tp, 0x50); } //rx checksum offload enable @@ -27647,9 +29549,6 @@ rtl8168_hw_config(struct net_device *dev) Force_rxflow_en | Force_txflow_en | Cxpl_dbg_sel | ASF | PktCntrDisable | Macdbgo_sel); } else if (tp->mcfg == CFG_METHOD_5) { - - set_offset70F(tp, 0x27); - RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); //disable clock request. @@ -27658,13 +29557,9 @@ rtl8168_hw_config(struct net_device *dev) if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - set_offset79(tp, 0x50); } //rx checksum offload enable @@ -27674,8 +29569,6 @@ rtl8168_hw_config(struct net_device *dev) dev->features |= NETIF_F_RXCSUM; #endif } else if (tp->mcfg == CFG_METHOD_6) { - set_offset70F(tp, 0x27); - RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); //disable clock request. @@ -27684,13 +29577,9 @@ rtl8168_hw_config(struct net_device *dev) if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - set_offset79(tp, 0x50); } //rx checksum offload enable @@ -27700,8 +29589,6 @@ rtl8168_hw_config(struct net_device *dev) dev->features |= NETIF_F_RXCSUM; #endif } else if (tp->mcfg == CFG_METHOD_7) { - set_offset70F(tp, 0x27); - rtl8168_eri_write(tp, 0x1EC, 1, 0x07, ERIAR_ASF); //disable clock request. @@ -27712,19 +29599,11 @@ rtl8168_hw_config(struct net_device *dev) if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - - set_offset79(tp, 0x50); } } else if (tp->mcfg == CFG_METHOD_8) { - - set_offset70F(tp, 0x27); - rtl8168_eri_write(tp, 0x1EC, 1, 0x07, ERIAR_ASF); //disable clock request. @@ -27737,17 +29616,11 @@ rtl8168_hw_config(struct net_device *dev) if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - set_offset79(tp, 0x50); } } else if (tp->mcfg == CFG_METHOD_9) { - set_offset70F(tp, 0x27); - /* disable clock request. */ pci_write_config_byte(pdev, 0x81, 0x00); @@ -27757,32 +29630,22 @@ rtl8168_hw_config(struct net_device *dev) if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - set_offset79(tp, 0x50); } RTL_W8(tp, TDFNR, 0x8); } else if (tp->mcfg == CFG_METHOD_10) { - set_offset70F(tp, 0x27); - RTL_W8(tp, DBG_reg, RTL_R8(tp, DBG_reg) | BIT_7 | BIT_1); if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1); - - set_offset79(tp, 0x20); } else { RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0); RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1); - - set_offset79(tp, 0x50); } RTL_W8(tp, TDFNR, 0x8); @@ -27792,9 +29655,6 @@ rtl8168_hw_config(struct net_device *dev) /* disable clock request. */ pci_write_config_byte(pdev, 0x81, 0x00); } else if (tp->mcfg == CFG_METHOD_11 || tp->mcfg == CFG_METHOD_13) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - if (dev->mtu > ETH_DATA_LEN) RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); else @@ -27805,9 +29665,6 @@ rtl8168_hw_config(struct net_device *dev) RTL_W8(tp, Config1, RTL_R8(tp, Config1) | 0x10); } else if (tp->mcfg == CFG_METHOD_12) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - if (dev->mtu > ETH_DATA_LEN) RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); else @@ -27818,10 +29675,6 @@ rtl8168_hw_config(struct net_device *dev) RTL_W8(tp, Config1, RTL_R8(tp, Config1) | 0x10); } else if (tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) { - - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - if (dev->mtu > ETH_DATA_LEN) { RTL_W8(tp, MTPS, 0x24); RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0); @@ -27853,9 +29706,6 @@ rtl8168_hw_config(struct net_device *dev) RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10); } else if (tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - rtl8168_eri_write(tp, 0xC0, 2, 0x0000, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xB8, 4, 0x00000000, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xC8, 4, 0x00100002, ERIAR_ExGMAC); @@ -27900,9 +29750,6 @@ rtl8168_hw_config(struct net_device *dev) pci_write_config_byte(pdev, 0x81, 0x00); } else if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - rtl8168_eri_write(tp, 0xC8, 4, 0x00100002, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | BIT_7); @@ -27939,9 +29786,6 @@ rtl8168_hw_config(struct net_device *dev) rtl8168_eri_write(tp, 0xCC, 4, 0x00000050, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xd0, 4, 0x00000060, ERIAR_ExGMAC); } else if (tp->mcfg == CFG_METHOD_20) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - rtl8168_eri_write(tp, 0xC8, 4, 0x00100002, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | BIT_7); @@ -27978,15 +29822,16 @@ 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) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - if (tp->mcfg == CFG_METHOD_21 || tp->mcfg == CFG_METHOD_22) - set_offset711(tp, 0x04); - + tp->mcfg == CFG_METHOD_30 || tp->mcfg == CFG_METHOD_35 || + tp->mcfg == CFG_METHOD_36 || tp->mcfg == CFG_METHOD_37) { rtl8168_eri_write(tp, 0xC8, 4, 0x00080002, ERIAR_ExGMAC); - rtl8168_eri_write(tp, 0xCC, 1, 0x38, ERIAR_ExGMAC); - rtl8168_eri_write(tp, 0xD0, 1, 0x48, ERIAR_ExGMAC); +#ifdef ENABLE_LIB_SUPPORT + rtl8168_eri_write(tp, 0xCC, 2, 0x60, ERIAR_ExGMAC); + rtl8168_eri_write(tp, 0xD0, 2, 0x70, ERIAR_ExGMAC); +#else + rtl8168_eri_write(tp, 0xCC, 2, 0x38, ERIAR_ExGMAC); + rtl8168_eri_write(tp, 0xD0, 2, 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); @@ -27997,7 +29842,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) { @@ -28012,7 +29857,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); @@ -28064,11 +29910,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); @@ -28077,7 +29923,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); @@ -28087,7 +29934,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); } @@ -28097,7 +29945,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); @@ -28108,17 +29957,16 @@ 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); - set_offset79(tp, 0x50); - rtl8168_eri_write(tp, 0xC8, 4, 0x00080002, ERIAR_ExGMAC); - rtl8168_eri_write(tp, 0xCC, 1, 0x2F, ERIAR_ExGMAC); - rtl8168_eri_write(tp, 0xD0, 1, 0x5F, ERIAR_ExGMAC); + rtl8168_eri_write(tp, 0xCC, 2, 0x2F, ERIAR_ExGMAC); + rtl8168_eri_write(tp, 0xD0, 2, 0x5F, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | BIT_7); @@ -28188,12 +30036,9 @@ rtl8168_hw_config(struct net_device *dev) } } else if (tp->mcfg == CFG_METHOD_31 || tp->mcfg == CFG_METHOD_32 || tp->mcfg == CFG_METHOD_33 || tp->mcfg == CFG_METHOD_34) { - set_offset70F(tp, 0x27); - set_offset79(tp, 0x50); - rtl8168_eri_write(tp, 0xC8, 4, 0x00080002, ERIAR_ExGMAC); - rtl8168_eri_write(tp, 0xCC, 1, 0x2F, ERIAR_ExGMAC); - rtl8168_eri_write(tp, 0xD0, 1, 0x5F, ERIAR_ExGMAC); + rtl8168_eri_write(tp, 0xCC, 2, 0x2F, ERIAR_ExGMAC); + rtl8168_eri_write(tp, 0xD0, 2, 0x5F, ERIAR_ExGMAC); rtl8168_eri_write(tp, 0xE8, 4, 0x00100006, ERIAR_ExGMAC); RTL_W32(tp, TxConfig, RTL_R32(tp, TxConfig) | BIT_7); @@ -28270,6 +30115,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); @@ -28385,6 +30234,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); @@ -28397,6 +30257,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: @@ -28423,13 +30285,15 @@ rtl8168_hw_config(struct net_device *dev) case CFG_METHOD_33: case CFG_METHOD_34: case CFG_METHOD_35: - rtl8168_disable_pci_offset_99(tp); - if (aspm) { - if (tp->org_pci_offset_99 & (BIT_2 | BIT_5 | BIT_6)) - rtl8168_init_pci_offset_99(tp); - } + case CFG_METHOD_36: + case CFG_METHOD_37: + if (aspm && (tp->org_pci_offset_99 & (BIT_2 | BIT_5 | BIT_6))) + rtl8168_init_pci_offset_99(tp); + else + rtl8168_disable_pci_offset_99(tp); break; } + switch (tp->mcfg) { case CFG_METHOD_24: case CFG_METHOD_25: @@ -28443,11 +30307,12 @@ rtl8168_hw_config(struct net_device *dev) case CFG_METHOD_33: case CFG_METHOD_34: case CFG_METHOD_35: - rtl8168_disable_pci_offset_180(tp); - if (aspm) { - if (tp->org_pci_offset_180 & (BIT_0|BIT_1)) - rtl8168_init_pci_offset_180(tp); - } + case CFG_METHOD_36: + case CFG_METHOD_37: + if (aspm && (tp->org_pci_offset_180 & (BIT_0|BIT_1))) + rtl8168_init_pci_offset_180(tp); + else + rtl8168_disable_pci_offset_180(tp); break; } @@ -28469,24 +30334,14 @@ 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) break; - mdelay(1); + fsleep(1000); } } break; @@ -28537,17 +30392,23 @@ rtl8168_hw_config(struct net_device *dev) rtl8168_disable_cfg9346_write(tp); - udelay(10); + fsleep(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 @@ -28556,7 +30417,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) @@ -28565,42 +30425,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); @@ -28619,32 +30470,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); @@ -28652,9 +30508,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; @@ -28662,14 +30520,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); @@ -28680,7 +30540,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; @@ -28693,19 +30553,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, @@ -28716,12 +30594,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; @@ -28738,33 +30621,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; @@ -28773,36 +30677,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; @@ -28826,8 +30750,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) @@ -28835,15 +30762,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); @@ -28853,83 +30780,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) @@ -28940,44 +30974,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) @@ -28989,27 +31101,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; @@ -29017,6 +31124,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) { @@ -29025,16 +31133,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; @@ -29052,15 +31160,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(); @@ -29070,7 +31176,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; } @@ -29193,45 +31299,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. @@ -29257,12 +31324,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 @@ -29270,18 +31338,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", @@ -29290,8 +31367,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)) { @@ -29302,6 +31379,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); @@ -29316,6 +31396,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)) { @@ -29324,24 +31421,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; } @@ -29355,6 +31449,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) @@ -29364,7 +31464,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) { @@ -29372,124 +31472,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(READ_ONCE(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 (READ_ONCE(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) { @@ -29528,8 +31669,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, @@ -29537,36 +31680,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); @@ -29576,32 +31721,49 @@ 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--) { - status = le32_to_cpu(desc->opts1); - if (status & DescOwn) - break; + 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(READ_ONCE(desc->opts1)); + if (status & DescOwn) { + RTL_R8(tp, tp->imr_reg[0]); + status = le32_to_cpu(READ_ONCE(desc->opts1)); + if (status & DescOwn) + break; + } rmb(); @@ -29618,94 +31780,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; @@ -29721,119 +31870,83 @@ 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); - udelay(300); + netif_tx_disable(dev); + fsleep(300); rtl8168_hw_reset(dev); rtl8168_tx_clear(tp); rtl8168_rx_clear(tp); rtl8168_init_ring(dev); rtl8168_hw_config(dev); rtl8168_hw_start(dev); - netif_wake_queue(dev); + netif_tx_wake_all_queues(dev); } + tp->rx_fifo_of++; + } + + if (other_q_status) { + for (i=1; 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); @@ -29842,27 +31955,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 { @@ -29876,34 +31989,96 @@ 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 if (message_id < tp->num_rx_rings) + work_done += rtl8168_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); + + work_done = min(work_done, work_to_do); 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; @@ -29917,8 +32092,56 @@ 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; + + if (message_id < tp->num_rx_rings) + 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; @@ -29945,91 +32168,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; } @@ -30039,9 +32236,30 @@ 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); + 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: + case CFG_METHOD_37: + rtl8168_disable_pci_offset_180(tp); + break; + } + rtl8168_set_bios_setting(dev); if (s5_keep_curr_mac == 0 && tp->random_mac == 0) rtl8168_rar_set(tp, tp->org_mac_addr); @@ -30056,6 +32274,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); @@ -30077,11 +32297,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; } @@ -30090,34 +32305,34 @@ 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; + rtnl_lock(); if (!netif_running(dev)) goto out; - rtl8168_cancel_schedule_work(dev); - - rtl8168_delete_esd_timer(dev, &tp->esd_timer); - - rtl8168_delete_link_timer(dev, &tp->link_timer); - - netif_stop_queue(dev); + 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); @@ -30135,37 +32350,53 @@ rtl8168_suspend(struct pci_dev *pdev, pm_message_t state) rtl8168_sleep_rx_enable(dev); - spin_unlock_irqrestore(&tp->lock, flags); - 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); - } + + rtnl_unlock(); + + 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 @@ -30173,26 +32404,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); @@ -30207,18 +32429,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 = { @@ -30230,9 +32477,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/r8168_realwow.h b/drivers/net/ethernet/realtek/r8168/r8168_realwow.h index 8e80e6411b25..1c1a970c7f8b 100644 --- a/drivers/net/ethernet/realtek/r8168/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 100644 index 000000000000..0bfe8c7ec5b4 --- /dev/null +++ b/drivers/net/ethernet/realtek/r8168/r8168_rss.c @@ -0,0 +1,482 @@ +// 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; + + 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; + + /* + * 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; + + 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); + + 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); + + 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); + + 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; + + /* 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); + + 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; + + /* 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) + fsleep(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 100644 index 000000000000..f64e56834d3b --- /dev/null +++ b/drivers/net/ethernet/realtek/r8168/r8168_rss.h @@ -0,0 +1,72 @@ +/* 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. + ***********************************************************************************/ + +#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/r8168/rtl_eeprom.c b/drivers/net/ethernet/realtek/r8168/rtl_eeprom.c index b44544e4fff2..9e840b56c925 100644 --- a/drivers/net/ethernet/realtek/r8168/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 @@ -93,7 +93,7 @@ void rtl8168_eeprom_cleanup(struct rtl8168_private *tp) rtl8168_lower_clock(tp, &x); } -int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp) +static int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp) { u8 x; int i; @@ -104,10 +104,10 @@ int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp) x = RTL_R8(tp, Cfg9346); if (x & Cfg9346_EEDO) { - udelay(RTL_CLOCK_RATE * 2 * 3); + fsleep(RTL_CLOCK_RATE * 2 * 3); return 0; } - udelay(1); + fsleep(1); } return -1; @@ -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); @@ -202,7 +199,7 @@ void rtl8168_raise_clock(struct rtl8168_private *tp, u8 *x) { *x = *x | Cfg9346_EESK; RTL_W8(tp, Cfg9346, *x); - udelay(RTL_CLOCK_RATE); + fsleep(RTL_CLOCK_RATE); } void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x) @@ -210,7 +207,7 @@ void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x) *x = *x & ~Cfg9346_EESK; RTL_W8(tp, Cfg9346, *x); - udelay(RTL_CLOCK_RATE); + fsleep(RTL_CLOCK_RATE); } void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count) @@ -229,7 +226,7 @@ void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count) x &= ~Cfg9346_EEDI; RTL_W8(tp, Cfg9346, x); - udelay(RTL_CLOCK_RATE); + fsleep(RTL_CLOCK_RATE); rtl8168_raise_clock(tp, &x); rtl8168_lower_clock(tp, &x); mask = mask >> 1; @@ -272,7 +269,7 @@ void rtl8168_stand_by(struct rtl8168_private *tp) x = RTL_R8(tp, Cfg9346); x &= ~(Cfg9346_EECS | Cfg9346_EESK); RTL_W8(tp, Cfg9346, x); - udelay(RTL_CLOCK_RATE); + fsleep(RTL_CLOCK_RATE); x |= Cfg9346_EECS; RTL_W8(tp, Cfg9346, x); @@ -283,7 +280,7 @@ void rtl8168_set_eeprom_sel_low(struct rtl8168_private *tp) RTL_W8(tp, Cfg9346, Cfg9346_EEM1); RTL_W8(tp, Cfg9346, Cfg9346_EEM1 | Cfg9346_EESK); - udelay(20); + fsleep(20); RTL_W8(tp, Cfg9346, Cfg9346_EEM1); } diff --git a/drivers/net/ethernet/realtek/r8168/rtl_eeprom.h b/drivers/net/ethernet/realtek/r8168/rtl_eeprom.h index 473d8934f5f0..ba8e0bc26b79 100644 --- a/drivers/net/ethernet/realtek/r8168/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/r8168/rtltool.c b/drivers/net/ethernet/realtek/r8168/rtltool.c index cba919529f1f..6b8b723f35b2 100644 --- a/drivers/net/ethernet/realtek/r8168/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))) @@ -56,6 +55,11 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) ret = 0; switch (my_cmd.cmd) { case RTLTOOL_READ_MAC: + if ((my_cmd.offset + my_cmd.len) > R8168_REGS_SIZE) { + ret = -EINVAL; + break; + } + if (my_cmd.len==1) my_cmd.data = readb(tp->mmio_addr+my_cmd.offset); else if (my_cmd.len==2) @@ -72,8 +76,12 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) break; } break; - case RTLTOOL_WRITE_MAC: + if ((my_cmd.offset + my_cmd.len) > R8168_REGS_SIZE) { + ret = -EINVAL; + break; + } + if (my_cmd.len==1) writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset); else if (my_cmd.len==2) @@ -84,51 +92,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 +126,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 +156,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 +170,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/r8168/rtltool.h b/drivers/net/ethernet/realtek/r8168/rtltool.h index b5c6b440edaa..5b755d6b82f8 100644 --- a/drivers/net/ethernet/realtek/r8168/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 From 8597ef189a379df609e51e07c94a8d892d5c4a0a Mon Sep 17 00:00:00 2001 From: Yu Qiaowei Date: Thu, 29 May 2025 18:02:33 +0800 Subject: [PATCH 02/16] video: rockchip: rga3: adapt to kernel-6.12 Change-Id: I2770caf4f4363cce36cae4f8cfbb0be9d322e82b Signed-off-by: Yu Qiaowei --- .../video/rockchip/rga3/include/rga_common.h | 2 ++ drivers/video/rockchip/rga3/rga_common.c | 24 +++++++++++++ drivers/video/rockchip/rga3/rga_debugger.c | 1 + drivers/video/rockchip/rga3/rga_drv.c | 6 ++++ drivers/video/rockchip/rga3/rga_iommu.c | 20 +++-------- drivers/video/rockchip/rga3/rga_mm.c | 35 ++++++------------- 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/drivers/video/rockchip/rga3/include/rga_common.h b/drivers/video/rockchip/rga3/include/rga_common.h index 6c64f74019c9..4ed75821f89a 100644 --- a/drivers/video/rockchip/rga3/include/rga_common.h +++ b/drivers/video/rockchip/rga3/include/rga_common.h @@ -83,4 +83,6 @@ void rga_dump_memory_parm(struct rga_memory_parm *parm); void rga_dump_external_buffer(struct rga_external_buffer *buffer); void rga_dump_req(struct rga_request *request, struct rga_req *req); +unsigned long rga_get_free_pages(gfp_t gfp_mask, unsigned int *order, unsigned long size); + #endif diff --git a/drivers/video/rockchip/rga3/rga_common.c b/drivers/video/rockchip/rga3/rga_common.c index a8af72430303..1563583ddeb8 100644 --- a/drivers/video/rockchip/rga3/rga_common.c +++ b/drivers/video/rockchip/rga3/rga_common.c @@ -925,3 +925,27 @@ void rga_dump_req(struct rga_request *request, struct rga_req *req) rga_req_log(request, "core_mask = %#x, priority = %d, in_fence = %d(%#x)\n", req->core, req->priority, req->in_fence_fd, req->in_fence_fd); } + +unsigned long rga_get_free_pages(gfp_t gfp_mask, unsigned int *order, unsigned long size) +{ + int cur_order, max_order; + unsigned long pages; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) + max_order = MAX_ORDER; +#else + max_order = MAX_PAGE_ORDER; +#endif + + cur_order = get_order(size); + if (cur_order > max_order) { + rga_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n", + cur_order, max_order); + return 0; + } + + pages = __get_free_pages(gfp_mask, cur_order); + *order = cur_order; + + return pages; +} diff --git a/drivers/video/rockchip/rga3/rga_debugger.c b/drivers/video/rockchip/rga3/rga_debugger.c index 572035977338..95cc8097648b 100644 --- a/drivers/video/rockchip/rga3/rga_debugger.c +++ b/drivers/video/rockchip/rga3/rga_debugger.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "rga.h" #include "rga_debugger.h" diff --git a/drivers/video/rockchip/rga3/rga_drv.c b/drivers/video/rockchip/rga3/rga_drv.c index d0d71fefd685..9ef013bb651c 100644 --- a/drivers/video/rockchip/rga3/rga_drv.c +++ b/drivers/video/rockchip/rga3/rga_drv.c @@ -1497,7 +1497,11 @@ pm_disable: return ret; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) static int rga_drv_remove(struct platform_device *pdev) +#else +static void rga_drv_remove(struct platform_device *pdev) +#endif { struct rga_scheduler_t *scheduler = NULL; @@ -1515,7 +1519,9 @@ static int rga_drv_remove(struct platform_device *pdev) up_write(&rga_drvdata->rwsem); +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 11, 0) return 0; +#endif } static void rga_drv_shutdown(struct platform_device *pdev) diff --git a/drivers/video/rockchip/rga3/rga_iommu.c b/drivers/video/rockchip/rga3/rga_iommu.c index 3ba0d58b2c20..4a3223e835cb 100644 --- a/drivers/video/rockchip/rga3/rga_iommu.c +++ b/drivers/video/rockchip/rga3/rga_iommu.c @@ -167,28 +167,16 @@ struct rga_mmu_base *rga_mmu_base_init(size_t size) * malloc pre scale mid buf mmu table: * size * channel_num * address_size */ - order = get_order(size * 3 * sizeof(*mmu_base->buf_virtual)); - if (order >= MAX_ORDER) { - pr_err("Can not alloc pages with order[%d] for mmu_page_table, max_order = %d\n", - order, MAX_ORDER); - goto err_free_mmu_base; - } - - mmu_base->buf_virtual = (uint32_t *) __get_free_pages(GFP_KERNEL | GFP_DMA32, order); + mmu_base->buf_virtual = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, + &order, size * 3 * sizeof(*mmu_base->buf_virtual)); if (mmu_base->buf_virtual == NULL) { pr_err("Can not alloc pages for mmu_page_table\n"); goto err_free_mmu_base; } mmu_base->buf_order = order; - order = get_order(size * sizeof(*mmu_base->pages)); - if (order >= MAX_ORDER) { - pr_err("Can not alloc pages with order[%d] for mmu_base->pages, max_order = %d\n", - order, MAX_ORDER); - goto err_free_buf_virtual; - } - - mmu_base->pages = (struct page **)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + mmu_base->pages = (struct page **)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, + &order, size * sizeof(*mmu_base->pages)); if (mmu_base->pages == NULL) { pr_err("Can not alloc pages for mmu_base->pages\n"); goto err_free_buf_virtual; diff --git a/drivers/video/rockchip/rga3/rga_mm.c b/drivers/video/rockchip/rga3/rga_mm.c index eb34fde9d769..b130e6e604e8 100644 --- a/drivers/video/rockchip/rga3/rga_mm.c +++ b/drivers/video/rockchip/rga3/rga_mm.c @@ -133,9 +133,12 @@ static int rga_get_user_pages(struct page **pages, unsigned long Memory, result = get_user_pages_remote(current, current_mm, Memory << PAGE_SHIFT, pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL); -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 5, 0) result = get_user_pages_remote(current_mm, Memory << PAGE_SHIFT, pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL, NULL); +#else + result = get_user_pages_remote(current_mm, Memory << PAGE_SHIFT, + pageCount, writeFlag ? FOLL_WRITE : 0, pages, NULL); #endif if (result > 0 && result >= pageCount) { @@ -252,14 +255,8 @@ static int rga_alloc_virt_addr(struct rga_virt_addr **virt_addr_p, } /* alloc pages and page_table */ - order = get_order(count * sizeof(struct page *)); - if (order >= MAX_ORDER) { - rga_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n", - order, MAX_ORDER); - return -ENOMEM; - } - - pages = (struct page **)__get_free_pages(GFP_KERNEL, order); + pages = (struct page **)rga_get_free_pages(GFP_KERNEL, + &order, count * sizeof(struct page *)); if (pages == NULL) { rga_err("%s can not alloc pages for viraddr pages\n", __func__); return -ENOMEM; @@ -1196,14 +1193,8 @@ static int rga_mm_set_mmu_base(struct rga_job *job, } if (job->flags & RGA_JOB_USE_HANDLE) { - order = get_order(page_count * sizeof(uint32_t *)); - if (order >= MAX_ORDER) { - rga_job_err(job, "Can not alloc pages with order[%d] for page_table, max_order = %d\n", - order, MAX_ORDER); - return -ENOMEM; - } - - page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + page_table = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, + &order, page_count * sizeof(uint32_t *)); if (page_table == NULL) { rga_job_err(job, "%s can not alloc pages for page_table, order = %d\n", __func__, order); @@ -1261,14 +1252,8 @@ static int rga_mm_set_mmu_base(struct rga_job *job, } if (job->flags & RGA_JOB_USE_HANDLE) { - order = get_order(page_count * sizeof(uint32_t *)); - if (order >= MAX_ORDER) { - rga_job_err(job, "Can not alloc pages with order[%d] for page_table, max_order = %d\n", - order, MAX_ORDER); - return -ENOMEM; - } - - page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); + page_table = (uint32_t *)rga_get_free_pages(GFP_KERNEL | GFP_DMA32, + &order, page_count * sizeof(uint32_t *)); if (page_table == NULL) { rga_job_err(job, "%s can not alloc pages for page_table, order = %d\n", __func__, order); From f803534f3e2d5dd5eaf6886acc4bea4fa85abf7e Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Wed, 28 May 2025 10:54:22 +0800 Subject: [PATCH 03/16] phy: rockchip-snps-pcie3: RK3588 phy lock determines compatibility with all bifurcation situations Change-Id: I34d720cab1a949bb1f518674d85bcb0d81d40062 Signed-off-by: Jon Lin --- .../phy/rockchip/phy-rockchip-snps-pcie3.c | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c index 0d1c4973a0ed..a370f8feff45 100644 --- a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -174,25 +174,29 @@ static int rockchip_p3phy_rk3588_init(struct rockchip_p3phy_priv *priv) static int rockchip_p3phy_rk3588_calibrate(struct rockchip_p3phy_priv *priv) { - int ret = 0; - u32 reg; + u32 phy0_status, phy1_status; + int i, sleep_us = 100; + bool check_both = (priv->pcie30_phymode == PHY_MODE_PCIE_AGGREGATION); - ret = regmap_read_poll_timeout(priv->phy_grf, - RK3588_PCIE3PHY_GRF_PHY0_STATUS1, - reg, RK3588_SRAM_INIT_DONE(reg), - 100, RK_PCIE_SRAM_INIT_TIMEOUT); - if (priv->pcie30_phymode == PHY_MODE_PCIE_AGGREGATION) { - ret |= regmap_read_poll_timeout(priv->phy_grf, - RK3588_PCIE3PHY_GRF_PHY1_STATUS1, - reg, RK3588_SRAM_INIT_DONE(reg), - 100, RK_PCIE_SRAM_INIT_TIMEOUT); + for (i = 0; i < RK_PCIE_SRAM_INIT_TIMEOUT; i += sleep_us) { + regmap_read(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_STATUS1, &phy0_status); + regmap_read(priv->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_STATUS1, &phy1_status); + + if (check_both) { + if (RK3588_SRAM_INIT_DONE(phy0_status) && RK3588_SRAM_INIT_DONE(phy1_status)) + return 0; + } else { + if (RK3588_SRAM_INIT_DONE(phy0_status) || RK3588_SRAM_INIT_DONE(phy1_status)) + return 0; + } + + usleep_range(sleep_us, sleep_us + 10); } - if (ret) - dev_err(&priv->phy->dev, "%s: lock failed 0x%x, check input refclk and power supply\n", - __func__, reg); + pr_err("%s: lock failed p0=0x%x p1=0x%x, check input refclk and power supply\n", + __func__, phy0_status, phy1_status); - return ret; + return -ETIMEDOUT; } static const struct rockchip_p3phy_ops rk3588_ops = { From 3791b78401e2d04fd657f11443f51bb7719d6c0c Mon Sep 17 00:00:00 2001 From: Jon Lin Date: Mon, 2 Jun 2025 23:26:22 +0800 Subject: [PATCH 04/16] misc: rockchip: pcie-rkep: Fix mutex lock not released in pcie_rkep_release Change-Id: I4be295e6efb7509fc5b0d1610f2f6b2c480bbf5d Signed-off-by: Jon Lin --- drivers/misc/rockchip/pcie-rkep.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/misc/rockchip/pcie-rkep.c b/drivers/misc/rockchip/pcie-rkep.c index 4dbe0653f006..89fcabb86c96 100644 --- a/drivers/misc/rockchip/pcie-rkep.c +++ b/drivers/misc/rockchip/pcie-rkep.c @@ -351,8 +351,10 @@ static int pcie_rkep_release(struct inode *inode, struct file *file) mutex_lock(&pcie_file->file_lock_mutex); index = find_first_bit(pcie_file->child_vid_bitmap, RKEP_EP_VIRTUAL_ID_MAX); - if (index >= RKEP_EP_VIRTUAL_ID_MAX) + if (index >= RKEP_EP_VIRTUAL_ID_MAX) { + mutex_unlock(&pcie_file->file_lock_mutex); break; + } __clear_bit(index, pcie_file->child_vid_bitmap); mutex_unlock(&pcie_file->file_lock_mutex); From 994be34daffdb245e7e5c16d4b88969437f556ef Mon Sep 17 00:00:00 2001 From: Johnson Ding Date: Sat, 31 May 2025 18:36:52 +0800 Subject: [PATCH 05/16] video: rockchip: mpp: rkvdec2: Fix reg reading Signed-off-by: Johnson Ding Change-Id: I9dbc24bc1f577f72535dbd42c6d05ca24b0d2e63 --- drivers/video/rockchip/mpp/mpp_rkvdec2_link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 20d55f9f9635..5c51737cd482 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -537,7 +537,7 @@ static int rkvdec2_link_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); struct rkvdec_link_dev *link_dec = dec->link_dec; - struct mpp_dma_buffer *table = link_dec->table; + struct mpp_dma_buffer *table = task->table; struct rkvdec_link_info *info = link_dec->info; struct rkvdec_link_part *part = info->part_r; u32 *tb_reg = (u32 *)table->vaddr; From 907fb7fa62427af37f0f332f03098006138d397c Mon Sep 17 00:00:00 2001 From: Wei Dun Date: Sat, 31 May 2025 10:21:02 +0800 Subject: [PATCH 06/16] media: rockchip: vpss: reduce rockit buf vmap Signed-off-by: Wei Dun Change-Id: I271c2a056fccb6b16f08bfa1f56a1c668cc3b87d --- drivers/media/platform/rockchip/vpss/common.h | 1 + drivers/media/platform/rockchip/vpss/dev.c | 4 ++++ drivers/media/platform/rockchip/vpss/vpss_rockit.c | 9 +++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/rockchip/vpss/common.h b/drivers/media/platform/rockchip/vpss/common.h index 24243c0922db..a313a4362171 100644 --- a/drivers/media/platform/rockchip/vpss/common.h +++ b/drivers/media/platform/rockchip/vpss/common.h @@ -112,6 +112,7 @@ static inline int vpss_outchn_max(int version) } extern int rkvpss_debug; +extern int rkvpss_buf_dbg; extern struct platform_driver rkvpss_plat_drv; extern int rkvpss_cfginfo_num; diff --git a/drivers/media/platform/rockchip/vpss/dev.c b/drivers/media/platform/rockchip/vpss/dev.c index 3748a19909e8..3b7bfddd1004 100644 --- a/drivers/media/platform/rockchip/vpss/dev.c +++ b/drivers/media/platform/rockchip/vpss/dev.c @@ -18,6 +18,10 @@ int rkvpss_debug; module_param_named(debug, rkvpss_debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-6)"); +int rkvpss_buf_dbg; +module_param_named(buf_dbg, rkvpss_buf_dbg, int, 0644); +MODULE_PARM_DESC(buf_dbg, "rkvpss buf dbg"); + static bool rkvpss_clk_dbg; module_param_named(clk_dbg, rkvpss_clk_dbg, bool, 0644); MODULE_PARM_DESC(clk_dbg, "rkvpss clk set by user"); diff --git a/drivers/media/platform/rockchip/vpss/vpss_rockit.c b/drivers/media/platform/rockchip/vpss/vpss_rockit.c index 6e5d7a8a1aa0..60e705815322 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_rockit.c +++ b/drivers/media/platform/rockchip/vpss/vpss_rockit.c @@ -216,8 +216,13 @@ int rkvpss_rockit_buf_queue(struct rockit_rkvpss_cfg *input_cfg) } vpssrk_buf->vaddr = NULL; - if (dma_buf_vmap(input_cfg->buf, &map) == 0) - vpssrk_buf->vaddr = map.vaddr; + /* default vmap two to get image, rkvpss_buf_dbg > 0 to vmap all */ + if (i < 2 || rkvpss_buf_dbg > 0) { + v4l2_dbg(3, rkvpss_debug, &vpss_dev->v4l2_dev, + "stream:%d rockit vmap buf:%p\n", stream->id, input_cfg->buf); + if (dma_buf_vmap(input_cfg->buf, &map) == 0) + vpssrk_buf->vaddr = map.vaddr; + } vpssrk_buf->buff_addr = sg_dma_address(sgt->sgl); get_dma_buf(input_cfg->buf); From 46bdb508e2009e626a09852a5d2da035140b1184 Mon Sep 17 00:00:00 2001 From: Wei Dun Date: Sat, 31 May 2025 15:56:18 +0800 Subject: [PATCH 07/16] media: rockchip: vpss: fix ch5 output issue Signed-off-by: Wei Dun Change-Id: Iacd285be0f36d9360eaba776e21b4efe6bc633c9 --- drivers/media/platform/rockchip/vpss/stream_v20.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/media/platform/rockchip/vpss/stream_v20.c b/drivers/media/platform/rockchip/vpss/stream_v20.c index 420e292c43ef..a294a1d0e0cd 100644 --- a/drivers/media/platform/rockchip/vpss/stream_v20.c +++ b/drivers/media/platform/rockchip/vpss/stream_v20.c @@ -746,9 +746,9 @@ static struct stream_config scl5_config = { .uv_offs_cnt = RKVPSS2X_MI_CHN5_WR_CB_OFFS_CNT, .y_pic_width = RKVPSS2X_MI_CHN5_WR_Y_PIC_WIDTH, .y_pic_size = RKVPSS2X_MI_CHN5_WR_Y_PIC_SIZE, - .ctrl_shd = RKVPSS2X_MI_CHN4_WR_CTRL_SHD, - .y_shd = RKVPSS2X_MI_CHN4_WR_Y_BASE_SHD, - .uv_shd = RKVPSS2X_MI_CHN4_WR_CB_BASE_SHD, + .ctrl_shd = RKVPSS2X_MI_CHN5_WR_CTRL_SHD, + .y_shd = RKVPSS2X_MI_CHN5_WR_Y_BASE_SHD, + .uv_shd = RKVPSS2X_MI_CHN5_WR_CB_BASE_SHD, }, }; @@ -887,7 +887,7 @@ static void scl_force_update(struct rkvpss_stream *stream) val = RKVPSS2X_MI_CHN4_FORCE_UPD; break; case RKVPSS_OUTPUT_CH5: - val = RKVPSS2X_MI_CHN4_FORCE_UPD; + val = RKVPSS2X_MI_CHN5_FORCE_UPD; break; default: return; @@ -1129,7 +1129,7 @@ static void scl_disable_mi(struct rkvpss_stream *stream) val = RKVPSS2X_ISP2VPSS_CHN4_SEL(3); break; case RKVPSS_OUTPUT_CH5: - val = RKVPSS2X_ISP2VPSS_CHN4_SEL(3); + val = RKVPSS2X_ISP2VPSS_CHN5_SEL(3); break; default: return; From 21ccc2dfe7e66661fc3d5eebf044b9f8a718f2f1 Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Tue, 3 Jun 2025 14:30:20 +0800 Subject: [PATCH 08/16] arm64: dts: rockchip: rk3588-evb: Use the hdmi phy pll dynamic allocation mode If the vp dclk clock source corresponding to hdmi is not the corresponding hdmi phy pll, that resulting in abnormal display of some resolutions. Furthermore, the use of hdmi phy pll can support more non-standard resolutions. Change-Id: I7a39ab2d73e912c596d8e1720d251e89c30b1f3b Signed-off-by: Algea Cao --- arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi index b36dd1f3c58f..925445f42981 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-evb.dtsi @@ -280,6 +280,11 @@ mem-supply = <&vdd_cpu_big1_mem_s0>; }; +&display_subsystem { + clocks = <&hdptxphy_hdmi0>, <&hdptxphy_hdmi1>; + clock-names = "hdmi0_phy_pll", "hdmi1_phy_pll"; +}; + &dsi0 { status = "disabled"; //rockchip,lane-rate = <1000>; From 9adbfafceb70ee02960fb847187d9ab8109355ad Mon Sep 17 00:00:00 2001 From: Wei Dun Date: Fri, 18 Apr 2025 15:37:28 +0800 Subject: [PATCH 09/16] media: rockchip: vpss: reset sw_vi2enc_sel on dvbm deinit Signed-off-by: Wei Dun Change-Id: Ia74755db4cba45f74d2108240f8054856ed29d38 --- drivers/media/platform/rockchip/vpss/common.h | 6 ++++++ drivers/media/platform/rockchip/vpss/hw.h | 2 ++ drivers/media/platform/rockchip/vpss/stream_v20.c | 12 +++++++++++- drivers/media/platform/rockchip/vpss/vpss_dvbm.c | 13 +++++++++++++ .../platform/rockchip/vpss/vpss_offline_dvbm.c | 14 ++++++++++++-- .../platform/rockchip/vpss/vpss_offline_dvbm.h | 7 +++++-- .../platform/rockchip/vpss/vpss_offline_v20.c | 2 +- 7 files changed, 50 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/rockchip/vpss/common.h b/drivers/media/platform/rockchip/vpss/common.h index a313a4362171..98ae5bd21593 100644 --- a/drivers/media/platform/rockchip/vpss/common.h +++ b/drivers/media/platform/rockchip/vpss/common.h @@ -51,6 +51,12 @@ enum { ROCKIT_DVBM_START, }; +enum { + DVBM_DEINIT = 0, + DVBM_ONLINE = 1, + DVBM_OFFLINE = 2, +}; + enum rkvpss_fmt_pix_type { FMT_YUV, FMT_RGB, diff --git a/drivers/media/platform/rockchip/vpss/hw.h b/drivers/media/platform/rockchip/vpss/hw.h index fc15d667aba3..e1fd4f76b7d9 100644 --- a/drivers/media/platform/rockchip/vpss/hw.h +++ b/drivers/media/platform/rockchip/vpss/hw.h @@ -70,6 +70,8 @@ struct rkvpss_hw_dev { bool is_suspend; bool is_first; bool is_probe_end; + int dvbm_refcnt; + int dvbm_flag; }; #ifdef CONFIG_VIDEO_ROCKCHIP_VPSS_V10 diff --git a/drivers/media/platform/rockchip/vpss/stream_v20.c b/drivers/media/platform/rockchip/vpss/stream_v20.c index a294a1d0e0cd..aa01566bcc93 100644 --- a/drivers/media/platform/rockchip/vpss/stream_v20.c +++ b/drivers/media/platform/rockchip/vpss/stream_v20.c @@ -1992,6 +1992,13 @@ static void rkvpss_stop_streaming(struct vb2_queue *queue) destroy_buf_queue(stream, VB2_BUF_STATE_ERROR); rkvpss_pipeline_close(dev); tasklet_disable(&stream->buf_done_tasklet); + + if (hw->dvbm_refcnt <= 0 && hw->dvbm_flag != DVBM_OFFLINE) { + v4l2_dbg(2, rkvpss_debug, &dev->v4l2_dev, "%s: clear vpss2enc_sel\n", __func__); + rkvpss_hw_clear_bits(hw, RKVPSS_VPSS_CTRL, RKVPSS_VPSS2ENC_SEL); + hw->dvbm_refcnt = 0; + } + v4l2_dbg(1, rkvpss_debug, &dev->v4l2_dev, "%s %s id:%d exit\n", __func__, node->vdev.name, stream->id); @@ -2103,7 +2110,10 @@ static int rkvpss_start_streaming(struct vb2_queue *queue, unsigned int count) goto pipe_close; } if (dev->stream_vdev.wrap_line && stream->id == RKVPSS_OUTPUT_CH0) - rkvpss_dvbm_init(stream); + if (rkvpss_dvbm_init(stream) != 0) { + v4l2_err(&dev->v4l2_dev, "dvbm init failed\n"); + goto stop_stream; + } ret = rkvpss_pipeline_stream(dev, true); if (ret < 0) goto stop_stream; diff --git a/drivers/media/platform/rockchip/vpss/vpss_dvbm.c b/drivers/media/platform/rockchip/vpss/vpss_dvbm.c index 8e0dc0f14bc6..bc39e9263f2c 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_dvbm.c +++ b/drivers/media/platform/rockchip/vpss/vpss_dvbm.c @@ -50,6 +50,14 @@ int rkvpss_dvbm_init(struct rkvpss_stream *stream) if (!g_dvbm) return -EINVAL; + if (vpss_dev->hw_dev->dvbm_flag == DVBM_OFFLINE) { + v4l2_err(&vpss_dev->v4l2_dev, + "offline dvbm already set, online dvbm set fail.\n"); + return -EINVAL; + } + + vpss_dev->hw_dev->dvbm_refcnt++; + vpss_dev->hw_dev->dvbm_flag = DVBM_ONLINE; width = stream->out_fmt.plane_fmt[0].bytesperline; height = stream->out_fmt.height; @@ -76,6 +84,11 @@ void rkvpss_dvbm_deinit(struct rkvpss_device *vpss_dev) pr_err("g_dvbm %p or vpss_dev %p is NULL\n", g_dvbm, vpss_dev); return; } + + vpss_dev->hw_dev->dvbm_refcnt--; + if (vpss_dev->hw_dev->dvbm_refcnt <= 0) + vpss_dev->hw_dev->dvbm_flag = DVBM_DEINIT; + rk_dvbm_unlink(g_dvbm, vpss_dev->dev_id); } diff --git a/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.c b/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.c index dcc8050766e2..aa160d29d156 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.c +++ b/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.c @@ -38,13 +38,20 @@ int rkvpss_ofl_dvbm_get(struct rkvpss_offline_dev *ofl) return ret; } -int rkvpss_ofl_dvbm_init(struct dma_buf *dbuf, u32 dma_addr, u32 wrap_line, - int width, int height, int id) +int rkvpss_ofl_dvbm_init(struct rkvpss_offline_dev *ofl, struct dma_buf *dbuf, u32 dma_addr, + u32 wrap_line, int width, int height, int id) { struct dvbm_isp_cfg_t dvbm_cfg; if (!g_ofl_dvbm) return -EINVAL; + if (ofl->hw->dvbm_flag == DVBM_ONLINE) { + v4l2_err(&ofl->v4l2_dev, + "online dvbm already set, offline dvbm set fail.\n"); + return -EINVAL; + } + + ofl->hw->dvbm_flag = DVBM_OFFLINE; dvbm_cfg.dma_addr = dma_addr; dvbm_cfg.buf = dbuf; @@ -70,7 +77,10 @@ void rkvpss_ofl_dvbm_deinit(struct rkvpss_offline_dev *ofl, int id) pr_err("g_dvbm %p or vpss_dev %p is NULL\n", g_ofl_dvbm, ofl); return; } + ofl->hw->dvbm_flag = DVBM_DEINIT; rk_dvbm_unlink(g_ofl_dvbm, id); + v4l2_dbg(2, rkvpss_debug, &ofl->v4l2_dev, "%s: clear vpss2enc_sel\n", __func__); + rkvpss_hw_clear_bits(ofl->hw, RKVPSS_VPSS_CTRL, RKVPSS_VPSS2ENC_SEL); } int rkvpss_ofl_dvbm_event(u32 event, u32 seq) diff --git a/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.h b/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.h index 90b22bd72b4c..888221f8557a 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.h +++ b/drivers/media/platform/rockchip/vpss/vpss_offline_dvbm.h @@ -12,12 +12,15 @@ #if IS_ENABLED(CONFIG_ROCKCHIP_DVBM) int rkvpss_ofl_dvbm_get(struct rkvpss_offline_dev *ofl); -int rkvpss_ofl_dvbm_init(struct dma_buf *dbuf, u32 dma_addr, u32 wrap_line, int width, int height, int id); +int rkvpss_ofl_dvbm_init(struct rkvpss_offline_dev *ofl, struct dma_buf *dbuf, + u32 dma_addr, u32 wrap_line, int width, int height, int id); void rkvpss_ofl_dvbm_deinit(struct rkvpss_offline_dev *ofl, int id); int rkvpss_ofl_dvbm_event(u32 event, u32 seq); #else static inline int rkvpss_ofl_dvbm_get(struct rkvpss_offline_dev *ofl) {return -EINVAL; } -static inline int rkvpss_ofl_dvbm_init(struct dma_buf *dbuf, u32 dma_addr, u32 wrap_line, int width, int height, int id) {return -EINVAL; } +static inline int rkvpss_ofl_dvbm_init(struct rkvpss_offline_dev *ofl, struct dma_buf *dbuf, + u32 dma_addr, u32 wrap_line, int width, int height, + int id) {return -EINVAL; } static inline void rkvpss_ofl_dvbm_deinit(struct rkvpss_offline_dev *ofl, int id) {} static inline int rkvpss_ofl_dvbm_event(u32 event, u32 seq) {return -EINVAL; } #endif diff --git a/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c b/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c index e75883ad57b3..a1f927c017f1 100644 --- a/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c +++ b/drivers/media/platform/rockchip/vpss/vpss_offline_v20.c @@ -2438,7 +2438,7 @@ static long rkvpss_ofl_wrap_dvbm_init(struct rkvpss_offline_dev *ofl, wrap_line = cfg->output[i].wrap.wrap_line; - rkvpss_ofl_dvbm_init(dbuf, dma_addr, wrap_line, width, height, cfg->dev_id); + rkvpss_ofl_dvbm_init(ofl, dbuf, dma_addr, wrap_line, width, height, cfg->dev_id); v4l2_dbg(4, rkvpss_debug, &ofl->v4l2_dev, "%s file_id:%d dev_id:%d wrap_chn:%d\n", __func__, file_id, cfg->dev_id, i); From 1de9a23c5483b473928ac72092d2a33cfe09c03f Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Mon, 12 May 2025 17:14:57 +0800 Subject: [PATCH 10/16] drm/rockchip: vop2: Fix the abnormal brightness when post-csc is enabled If all planes are in rgb format and are in yuv overlay, r2y conversion is all carried out in bt601. In this scenario, the input colorspace of post-csc needs to be selected as bt601. Fixes: 2e4cd35f0687 ("drm/rockchip: vop2: update color-encoding selection policy for post-csc") Change-Id: I2311fe8b0edb3ad44fe98231e723e895df1a3d69 Signed-off-by: Algea Cao --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 64 +++++++++++++------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 89d8efce59be..96fccea8e2ca 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -12888,7 +12888,7 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state); struct vop2 *vop2 = vp->vop2; struct drm_plane *plane; - struct drm_plane_state *pstate, *pstate_max = NULL; + struct drm_plane_state *pstate, *max_yuv_pstate = NULL; struct vop2_plane_state *vpstate; struct post_csc_coef csc_coef = {}; struct post_csc_convert_mode convert_mode = {}; @@ -12896,6 +12896,7 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st bool acm_enable; bool post_r2y_en = false; bool post_csc_en = false; + bool rgb_limited_plane = false; int range_type; u64 max_yuv_plane = 0, plane_area; enum drm_color_encoding max_yuv_plane_color_encoding = DRM_COLOR_YCBCR_BT601; @@ -12907,13 +12908,17 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st vpstate = to_vop2_plane_state(pstate); dest = &vpstate->dest; + if (!pstate->fb->format->is_yuv && + pstate->color_range != DRM_COLOR_YCBCR_FULL_RANGE) + rgb_limited_plane = true; + if (pstate->fb->format->is_yuv) { plane_area = drm_rect_width(dest) * drm_rect_height(dest); /* find yuv plane with largest area */ if (max_yuv_plane < plane_area) { max_yuv_plane = plane_area; max_yuv_plane_color_encoding = pstate->color_encoding; - pstate_max = pstate; + max_yuv_pstate = pstate; } } } @@ -12948,36 +12953,49 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st if (is_yuv_output(vcstate->bus_format)) convert_mode.is_output_yuv = true; - if (!vcstate->yuv_overlay || vp->has_dci_enabled_win) + if (vp->has_dci_enabled_win) { convert_mode.is_input_full_range = true; - else if (vcstate->yuv_overlay) + } else if (!vcstate->yuv_overlay) { + /* if there are yuv planes, choose max plane's range */ + if (max_yuv_pstate) { + /* Todo RGB limit range plane */ + convert_mode.is_input_full_range = true; + } else { + if (rgb_limited_plane) + convert_mode.is_input_full_range = false; + else + convert_mode.is_input_full_range = true; + } + } else { + /* yuv overlay range is limited */ convert_mode.is_input_full_range = false; - else if (pstate_max) - convert_mode.is_input_full_range = - pstate_max->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0; - else - convert_mode.is_input_full_range = - vcstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0; + } convert_mode.is_output_full_range = vcstate->color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0; vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_13BIT_DEPTH); - if (post_csc_en) { - convert_mode.output_color_encoding = vcstate->color_encoding; - /* - * When all layers are rgb, the post-csc input color encoding - * is fixed to rgb full, and the value of input_color_encoding - * has no actual utility. - * If there are any yuv planes, value of post-csc input_color_encoding - * selects the value of the yuv plane with the largest area. - */ - if (!pstate_max && !vcstate->yuv_overlay) - convert_mode.intput_color_encoding = vcstate->color_encoding; - else - convert_mode.intput_color_encoding = max_yuv_plane_color_encoding; + convert_mode.output_color_encoding = vcstate->color_encoding; + /* + * When all layers are rgb, the value of input_color_encoding + * has no actual utility, however, the plane csc only supports + * limited range under bt709. Therefore, in this scene, the colorspace + * of plane csc is selected as bt601. The intput_color_encoding + * is consistent with colorspace of plane csc, which is DRM_COLOR_YCBCR_BT601. + * If there are any yuv planes, value of post-csc input_color_encoding + * selects the value of the yuv plane with the largest area. + */ + if (!max_yuv_pstate) + convert_mode.intput_color_encoding = DRM_COLOR_YCBCR_BT601; + else + convert_mode.intput_color_encoding = max_yuv_plane_color_encoding; + if (convert_mode.intput_color_encoding != convert_mode.output_color_encoding || + convert_mode.is_input_full_range != convert_mode.is_output_full_range) + post_csc_en = true; + + if (post_csc_en) { rockchip_calc_post_csc(csc, &csc_coef, &convert_mode); VOP_MODULE_SET(vop2, vp, csc_coe00, csc_coef.csc_coef00); From 58b5fd106b0f3f40f9dda0c7a63b8a5b8c172687 Mon Sep 17 00:00:00 2001 From: Cai YiWei Date: Fri, 6 Jun 2025 09:14:58 +0800 Subject: [PATCH 11/16] media: rockchip: isp: fix sequence error correction Change-Id: I35ea43335f3475a8ddb2dafb25201a7523d9457e Signed-off-by: Cai YiWei --- drivers/media/platform/rockchip/isp/rkisp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/rockchip/isp/rkisp.c b/drivers/media/platform/rockchip/isp/rkisp.c index 49f8c25621ad..05cce6ab4776 100644 --- a/drivers/media/platform/rockchip/isp/rkisp.c +++ b/drivers/media/platform/rockchip/isp/rkisp.c @@ -4242,7 +4242,7 @@ static int rkisp_vicap_sof(struct rkisp_device *dev, struct rkisp_vicap_sof *sof v4l2_dbg(3, rkisp_debug, &dev->v4l2_dev, "vicap sof %d, isp sof %d\n", sof->sequence, dev->dmarx_dev.cur_frame.id); - dev->dmarx_dev.cur_frame.id = sof->sequence; + dev->dmarx_dev.cur_frame.id = sof->sequence - 1; } spin_unlock_irqrestore(&dev->rdbk_lock, flag); return 0; From 04054a0ea76f67b269d43f62dab55df029383756 Mon Sep 17 00:00:00 2001 From: Jkand Huang Date: Thu, 29 May 2025 10:37:34 +0800 Subject: [PATCH 12/16] arm64: dts: rockchip: rv1126b-evb2-v10: sc485sl enable hw_standby Signed-off-by: Jkand Huang Change-Id: Ie12fe2c2abacafcd54ead55a0b543fa028e08fa2 --- arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts index 77b9f3cd1b9d..d1ceaa6832c6 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb2-v10.dts @@ -588,6 +588,7 @@ &sc850sl { reset-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>; + rockchip,camera-module-stb = <1>; }; &sdmmc0 { From 7cd68dc9116ac0dc5e1b67f0aa5f82a96a2a53f8 Mon Sep 17 00:00:00 2001 From: Leo Sun Date: Wed, 4 Jun 2025 14:01:37 +0800 Subject: [PATCH 13/16] media: rockchip: sc850sl: Support for 40 frame rates Change-Id: Idbaef7b7b9a1286b08733dc20e3200ae9266265f Signed-off-by: Leo Sun --- drivers/media/i2c/sc850sl.c | 240 +++++++++++++++++++++++++++++++++++- 1 file changed, 234 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/sc850sl.c b/drivers/media/i2c/sc850sl.c index 4404866b6c91..2abad1b2d37b 100644 --- a/drivers/media/i2c/sc850sl.c +++ b/drivers/media/i2c/sc850sl.c @@ -41,8 +41,10 @@ #endif #define MIPI_FREQ_540M 540000000 +#define MIPI_FREQ_972M 486000000 +#define SC850AI_MAX_LINK_FREQ MIPI_FREQ_540M -#define SC850SL_MAX_PIXEL_RATE (MIPI_FREQ_540M / 10 * 2 * SC850SL_4LANES) +#define SC850SL_MAX_PIXEL_RATE (SC850AI_MAX_LINK_FREQ / 10 * 2 * SC850SL_4LANES) #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode" #define SC850SL_XVCLK_FREQ_24M 24000000 @@ -144,6 +146,7 @@ struct sc850sl_mode { u32 vts_def; u32 exp_def; u32 mipi_freq_idx; + u32 xvclk_freq; u32 bpp; const struct regval *reg_list; u32 hdr_mode; @@ -195,7 +198,7 @@ struct sc850sl { #define to_sc850sl(sd) container_of(sd, struct sc850sl, subdev) //cleaned_0x20_SC850SL_MIPI_24Minput_1C4D_1080Mbps_10bit_3840x2160_30fps_one_expo.ini -static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] = { +static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_30fps_regs[] = { {0x0103, 0x01}, {0x0100, 0x00}, {0x36e9, 0x80}, @@ -394,6 +397,208 @@ static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] = {REG_NULL, 0x00}, }; +static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_40fps_regs[] = { + {0x0103, 0x01}, + {0x0100, 0x00}, + {0x36e9, 0x80}, + {0x36f9, 0x80}, + {0x36ea, 0x09}, + {0x36eb, 0x0c}, + {0x36ec, 0x4b}, + {0x36ed, 0x34}, + {0x36fa, 0xcb}, + {0x36fb, 0x13}, + {0x36fc, 0x00}, + {0x36fd, 0x07}, + {0x36e9, 0x53}, + {0x36f9, 0x53}, + {0x3000, 0x01}, + {0x3018, 0x7a}, + {0x3019, 0xf0}, + {0x301a, 0x30}, + {0x301e, 0x3c}, + {0x301f, 0x0d}, + {0x302a, 0x00}, + {0x3031, 0x0a}, + {0x3032, 0x20}, + {0x3033, 0x22}, + {0x3037, 0x60}, + {0x303e, 0xb4}, + {0x3201, 0x98}, + {0x3203, 0x0c}, + {0x3205, 0xa7}, + {0x3207, 0x83}, + {0x320c, 0x03}, + {0x320d, 0x39}, + {0x3211, 0x08}, + {0x3213, 0x2c}, + {0x3223, 0xc0}, + {0x3226, 0x00}, + {0x3227, 0x03}, + {0x3230, 0x11}, + {0x3231, 0x93}, + {0x3250, 0x40}, + {0x3253, 0x08}, + {0x327e, 0x00}, + {0x3280, 0x00}, + {0x3281, 0x00}, + {0x3301, 0x24}, + {0x3304, 0x30}, + {0x3306, 0x54}, + {0x3308, 0x10}, + {0x3309, 0x60}, + {0x330a, 0x00}, + {0x330b, 0xa0}, + {0x330d, 0x10}, + {0x3314, 0x92}, + {0x331e, 0x29}, + {0x331f, 0x59}, + {0x3333, 0x10}, + {0x3347, 0x05}, + {0x3348, 0xd0}, + {0x3352, 0x01}, + {0x3356, 0x38}, + {0x335d, 0x60}, + {0x3362, 0x70}, + {0x338f, 0x80}, + {0x33af, 0x48}, + {0x33fe, 0x00}, + {0x3400, 0x12}, + {0x3406, 0x04}, + {0x3410, 0x12}, + {0x3416, 0x06}, + {0x3433, 0x01}, + {0x3440, 0x12}, + {0x3446, 0x08}, + {0x3478, 0x01}, + {0x3479, 0x01}, + {0x347a, 0x02}, + {0x347b, 0x01}, + {0x347c, 0x04}, + {0x347d, 0x01}, + {0x3616, 0x0c}, + {0x3620, 0x94}, + {0x3622, 0x74}, + {0x3629, 0x74}, + {0x362a, 0xf0}, + {0x362b, 0x0f}, + {0x362d, 0x00}, + {0x3630, 0x68}, + {0x3633, 0x24}, + {0x3634, 0x22}, + {0x3635, 0x20}, + {0x3637, 0x18}, + {0x3638, 0x26}, + {0x363b, 0x06}, + {0x363c, 0x07}, + {0x363d, 0x05}, + {0x363e, 0x8f}, + {0x3648, 0xe0}, + {0x3649, 0x0a}, + {0x364a, 0x06}, + {0x364c, 0x6a}, + {0x3650, 0x3d}, + {0x3654, 0x70}, + {0x3656, 0x68}, + {0x3657, 0x0f}, + {0x3658, 0x3d}, + {0x365c, 0x40}, + {0x365e, 0x68}, + {0x3901, 0x04}, + {0x3902, 0xf1}, + {0x3904, 0x20}, + {0x3905, 0x91}, + {0x391e, 0x03}, + {0x3928, 0x04}, + {0x3933, 0xa0}, + {0x3934, 0x0a}, + {0x3935, 0x68}, + {0x3936, 0x00}, + {0x3937, 0x20}, + {0x3938, 0x0a}, + {0x3946, 0x20}, + {0x3961, 0x40}, + {0x3962, 0x40}, + {0x3963, 0xc8}, + {0x3964, 0xc8}, + {0x3965, 0x40}, + {0x3966, 0x40}, + {0x3967, 0x00}, + {0x39cd, 0xc8}, + {0x39ce, 0xc8}, + {0x3e01, 0x82}, + {0x3e02, 0x00}, + {0x3e0e, 0x02}, + {0x3e0f, 0x00}, + {0x3e1c, 0x0f}, + {0x3e23, 0x00}, + {0x3e24, 0x00}, + {0x3e53, 0x00}, + {0x3e54, 0x00}, + {0x3e68, 0x00}, + {0x3e69, 0x80}, + {0x3e73, 0x00}, + {0x3e74, 0x00}, + {0x3e86, 0x03}, + {0x3e87, 0x40}, + {0x3f02, 0x24}, + {0x4424, 0x02}, + {0x4501, 0xb4}, + {0x4503, 0x20}, + {0x4509, 0x20}, + {0x4561, 0x12}, + {0x4800, 0x24}, + {0x4837, 0x20}, + {0x4900, 0x24}, + {0x4937, 0x16}, + {0x5000, 0x0e}, + {0x500f, 0x35}, + {0x5020, 0x00}, + {0x5787, 0x10}, + {0x5788, 0x06}, + {0x5789, 0x00}, + {0x578a, 0x18}, + {0x578b, 0x0c}, + {0x578c, 0x00}, + {0x5790, 0x10}, + {0x5791, 0x06}, + {0x5792, 0x01}, + {0x5793, 0x18}, + {0x5794, 0x0c}, + {0x5795, 0x01}, + {0x5799, 0x06}, + {0x57a2, 0x60}, + {0x59e0, 0xfe}, + {0x59e1, 0x40}, + {0x59e2, 0x38}, + {0x59e3, 0x30}, + {0x59e4, 0x20}, + {0x59e5, 0x38}, + {0x59e6, 0x30}, + {0x59e7, 0x20}, + {0x59e8, 0x3f}, + {0x59e9, 0x38}, + {0x59ea, 0x30}, + {0x59eb, 0x3f}, + {0x59ec, 0x38}, + {0x59ed, 0x30}, + {0x59ee, 0xfe}, + {0x59ef, 0x40}, + {0x59f4, 0x38}, + {0x59f5, 0x30}, + {0x59f6, 0x20}, + {0x59f7, 0x38}, + {0x59f8, 0x30}, + {0x59f9, 0x20}, + {0x59fa, 0x3f}, + {0x59fb, 0x38}, + {0x59fc, 0x30}, + {0x59fd, 0x3f}, + {0x59fe, 0x38}, + {0x59ff, 0x30}, + {REG_NULL, 0x00}, +}; + /* * The width and height must be configured to be * the same as the current output resolution of the sensor. @@ -407,6 +612,26 @@ static __maybe_unused const struct regval sc850sl_linear10bit_3840x2160_regs[] = * } */ static const struct sc850sl_mode supported_modes[] = { +#if defined CONFIG_VIDEO_CAM_SLEEP_WAKEUP + { + .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, + .width = 3840, + .height = 2160, + .max_fps = { + .numerator = 10000, + .denominator = 400000, + }, + .exp_def = 0x08c0, + .hts_def = 0x10e0, + .vts_def = 0x08ca, + .reg_list = sc850sl_linear10bit_3840x2160_40fps_regs, + .hdr_mode = NO_HDR, + .xvclk_freq = 24000000, + .mipi_freq_idx = 1, + .bpp = 10, + .vc[PAD0] = 0, + }, +#endif { .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, .width = 3840, @@ -419,8 +644,9 @@ static const struct sc850sl_mode supported_modes[] = { .hts_def = 0x0226 * 5 - 0x180, .vts_def = 0x08ca, .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10, - .reg_list = sc850sl_linear10bit_3840x2160_regs, + .reg_list = sc850sl_linear10bit_3840x2160_30fps_regs, .hdr_mode = NO_HDR, + .xvclk_freq = 24000000, .mipi_freq_idx = 0, .bpp = 10, .vc[PAD0] = 0, @@ -441,6 +667,7 @@ static const char *const sc850sl_test_pattern_menu[] = { static const s64 link_freq_items[] = { MIPI_FREQ_540M, + MIPI_FREQ_972M, }; /* Write registers up to 4 at a time */ @@ -1025,6 +1252,7 @@ static long sc850sl_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) case RKMODULE_SET_QUICK_STREAM: stream = *((u32 *)arg); + dev_info(&sc850sl->client->dev, "stream: %d\n", stream); if (stream) { ret |= sc850sl_write_reg(sc850sl->client, 0x3019, @@ -1354,10 +1582,10 @@ static int __sc850sl_power_on(struct sc850sl *sc850sl) if (ret < 0) dev_err(dev, "could not set pins\n"); } - ret = clk_set_rate(sc850sl->xvclk, SC850SL_XVCLK_FREQ_24M); + ret = clk_set_rate(sc850sl->xvclk, sc850sl->cur_mode->xvclk_freq); if (ret < 0) dev_warn(dev, "Failed to set xvclk rate 24MHz\n"); - if (clk_get_rate(sc850sl->xvclk) != SC850SL_XVCLK_FREQ_24M) + if (clk_get_rate(sc850sl->xvclk) != sc850sl->cur_mode->xvclk_freq) dev_warn(dev, "xvclk mismatched\n"); ret = clk_prepare_enable(sc850sl->xvclk); if (ret < 0) { @@ -1973,7 +2201,7 @@ static int sc850sl_probe(struct i2c_client *client, #endif if (!sc850sl->cam_sw_info) { sc850sl->cam_sw_info = cam_sw_init(); - cam_sw_clk_init(sc850sl->cam_sw_info, sc850sl->xvclk, SC850SL_XVCLK_FREQ_24M); + cam_sw_clk_init(sc850sl->cam_sw_info, sc850sl->xvclk, sc850sl->cur_mode->xvclk_freq); cam_sw_reset_pin_init(sc850sl->cam_sw_info, sc850sl->reset_gpio, 0); cam_sw_pwdn_pin_init(sc850sl->cam_sw_info, sc850sl->pwdn_gpio, 1); } From 9d3d119972064580269ce77703ad490ff2c72488 Mon Sep 17 00:00:00 2001 From: Ziyuan Xu Date: Tue, 27 May 2025 10:19:25 +0800 Subject: [PATCH 14/16] arm64: dts: rockchip: Add rv1126b-thunder-boot for SPI Nor/eMMC rv1126b thunderboot reserved memory layout: H _______________________ | | | ramdisk_c | |_______________________| | | | ramdisk_r | 0x48c40000 |_______________________| | | | mcu_log | 0x48c3c000 |_______________________| | | | mcu | 0x48c00000 |_______________________| | | | [TEEOS+TA+SHM] | 0x48400000 |_______________________| | | | mmc_escd | 0x48000000 |_______________________| | | | mmc_idmac | 0x47fffe00 |_______________________| | | | isp[0..1]_tb_rmem | |_______________________| | | | meta | 0x41240000 |_______________________| | | | fdt | 0x41200000 |_______________________| | | | kernel_r | 0x40208000 |_______________________| | | | bl31 | L |_______________________| Signed-off-by: Ziyuan Xu Change-Id: I69f4dcbf94d6a646794e993ad7dac0e94028ed47 --- .../rockchip/rv1126b-thunder-boot-emmc.dtsi | 33 +++++++ .../rv1126b-thunder-boot-spi-nor.dtsi | 15 +++ .../dts/rockchip/rv1126b-thunder-boot.dtsi | 95 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-emmc.dtsi create mode 100644 arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-spi-nor.dtsi create mode 100644 arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot.dtsi diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-emmc.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-emmc.dtsi new file mode 100644 index 000000000000..1d5b33308f53 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-emmc.dtsi @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "rv1126b-thunder-boot.dtsi" + +/ { + thunder_boot_mmc: thunder-boot-mmc { + compatible = "rockchip,thunder-boot-mmc"; + reg = <0x21470000 0x4000>; + clocks = <&cru HCLK_EMMC>, <&cru CCLK_EMMC>; + clock-names = "biu", "ciu"; + memory-region-src = <&ramdisk_c>; + memory-region-dst = <&ramdisk_r>; + memory-region-idmac = <&mmc_idmac>; + }; +}; + +&emmc { + memory-region-ecsd = <&mmc_ecsd>; + post-power-on-delay-ms = <0>; +}; + +&reserved_memory { + mmc_ecsd: mmc@47fffe00 { + reg = <0x47fffe00 0x00001000>; + }; + + mmc_idmac: mmc@48000000 { + reg = <0x48000000 0x00400000>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-spi-nor.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-spi-nor.dtsi new file mode 100644 index 000000000000..92dfbebff64f --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot-spi-nor.dtsi @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +#include "rv1126b-thunder-boot.dtsi" + +/ { + thunder_boot_spi_nor: thunder-boot-spi-nor { + compatible = "rockchip,thunder-boot-sfc"; + reg = <0x21460000 0x4000>; + memory-region-src = <&ramdisk_c>; + memory-region-dst = <&ramdisk_r>; + }; +}; diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot.dtsi new file mode 100644 index 000000000000..890f84f832d1 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rv1126b-thunder-boot.dtsi @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. + */ + +/ { + ramdisk: ramdisk { + compatible = "rockchip,ramdisk"; + memory-region = <&ramdisk_r>; + }; +}; + +&reserved_memory { + /* + * reserved memory layout + * + * H _______________________ + * | | + * | ramdisk_c | + * |_______________________| + * | | + * | ramdisk_r | + * 0x48c40000 |_______________________| + * | | + * | mcu_log | + * 0x48c3c000 |_______________________| + * | | + * | mcu | + * 0x48c00000 |_______________________| + * | | + * | [TEEOS+TA+SHM] | + * 0x48400000 |_______________________| + * | | + * | isp[0..1]_tb_rmem | + * |_______________________| + * | | + * | meta | + * 0x41240000 |_______________________| + * | | + * | fdt | + * 0x41200000 |_______________________| + * | | + * | kernel_r | + * 0x40208000 |_______________________| + * | | + * | bl31 | + * L |_______________________| + * + */ + + meta: meta@41240000 { + /* reg's offset MUST match with RTOS */ + reg = <0x41240000 0x000c0000>; + }; + + rkisp_thunderboot: rkisp@41300000 { + /* reg's offset MUST match with RTOS */ + /* + * vicap, capture raw10, ceil(w*10/8/256)*256*h *4(buf num) + * e.g. 1920x1080: 0xa8c000 + */ + reg = <0x41300000 0xa8c000>; + }; + + rkisp1_thunderboot: rkisp1_thunderboot { + /* vicap capture for a second camera */ + }; + + /* Should enable this node if the security feature is enabled, like TA. */ + tee: tee@48400000 { + reg = <0x48400000 0x00800000>; + status = "disabled"; + }; + + rtos: rtos@48c00000 { + reg = <0x48c00000 0x0003a000>; + }; + + mcu_log: mcu_log@48c3c000 { + reg = <0x48c3c000 0x4000>; + }; + + ramdisk_r: ramdisk_r { + reg = <0x48c40000 (10 * 0x00100000)>; + }; + + ramdisk_c: ramdisk_c { + reg = <0x49640000 (5 * 0x00100000)>; + }; +}; + +&hw_decompress { + memory-region = <&ramdisk_c>; + status = "okay"; +}; From 4153da4ba0f87dd4c6ceaa170e371ca7686e8d52 Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Fri, 6 Jun 2025 17:43:19 +0800 Subject: [PATCH 15/16] arm64: dts: rockchip: rv1126b: rockchip_suspend: sleep-debug-en = 0 Signed-off-by: XiaoDong Huang Change-Id: Ifa0c6165272c10771bb25db588354802ead26308 --- arch/arm64/boot/dts/rockchip/rv1126b.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi index d3c0d1dfb338..59c2eaeb0998 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b.dtsi +++ b/arch/arm64/boot/dts/rockchip/rv1126b.dtsi @@ -879,7 +879,7 @@ rockchip_suspend: rockchip-suspend { compatible = "rockchip,pm-config"; status = "disabled"; - + rockchip,sleep-debug-en = <0>; rockchip,sleep-mode-config = < (0 | RKPM_SLP_ARMOFF_PMUOFF From 1337cd6a19dc8f7fe0d355334d43b0ef1ba87d0f Mon Sep 17 00:00:00 2001 From: XiaoDong Huang Date: Fri, 6 Jun 2025 18:31:36 +0800 Subject: [PATCH 16/16] arm64: dts: rockchip: rv1126b-evb1-v10: rockchip_suspend: sleep-debug-en = 1 Signed-off-by: XiaoDong Huang Change-Id: I57d48102e35a9b693c19c13121625cd7777183ae --- arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts index 9ab0043261cb..6ab9eb32912f 100644 --- a/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rv1126b-evb1-v10.dts @@ -17,6 +17,8 @@ &rockchip_suspend { status = "okay"; + rockchip,sleep-debug-en = <1>; + rockchip,sleep-mode-config = < (0 | RKPM_SLP_ARMOFF_LOGOFF