r8168: update driver to 8.053.00

- Update realtek r8168 driver version to 8.053.00
- This update adds support till K6.8

Bug 4471899

Change-Id: I77734753b8ad9ca108afccda609d29ea73c848f5
Signed-off-by: Revanth Kumar Uppala <ruppala@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3123343
Reviewed-by: Brad Griffis <bgriffis@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Revanth Kumar Uppala
2024-04-24 16:32:27 +05:30
committed by mobile promotions
parent e66ec778b0
commit 7086a36e68
17 changed files with 6618 additions and 3395 deletions

View File

@@ -1,100 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
################################################################################
#
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>.
#
# Author:
# Realtek NIC software team <nicfae@realtek.com>
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
#
################################################################################
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
################################################################################
# This product is covered by one or more of the following patents:
# US6,570,884, US6,115,776, and US6,327,625.
################################################################################
CONFIG_SOC_LAN = n
ENABLE_FIBER_SUPPORT = n
ENABLE_REALWOW_SUPPORT = n
ENABLE_DASH_SUPPORT = n
ENABLE_DASH_PRINTER_SUPPORT = n
CONFIG_DOWN_SPEED_100 = n
CONFIG_ASPM = y
ENABLE_S5WOL = y
ENABLE_S5_KEEP_CURR_MAC = n
ENABLE_EEE = y
ENABLE_S0_MAGIC_PACKET = n
CONFIG_DYNAMIC_ASPM = y
ENABLE_USE_FIRMWARE_FILE = n
CONFIG_CTAP_SHORT_OFF = n
obj-m += r8168.o
r8168-objs += r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o
ifeq ($(CONFIG_SOC_LAN), y)
EXTRA_CFLAGS += -DCONFIG_SOC_LAN
endif
ifeq ($(ENABLE_FIBER_SUPPORT), y)
r8168-objs += r8168_fiber.o
EXTRA_CFLAGS += -DENABLE_FIBER_SUPPORT
endif
ifeq ($(ENABLE_REALWOW_SUPPORT), y)
r8168-objs += r8168_realwow.o
EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT
endif
ifeq ($(ENABLE_DASH_SUPPORT), y)
r8168-objs += r8168_dash.o
EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT
endif
ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y)
r8168-objs += r8168_dash.o
EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT
endif
EXTRA_CFLAGS += -DCONFIG_R8168_NAPI
EXTRA_CFLAGS += -DCONFIG_R8168_VLAN
ifeq ($(CONFIG_DOWN_SPEED_100), y)
EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100
endif
ifeq ($(CONFIG_ASPM), y)
EXTRA_CFLAGS += -DCONFIG_ASPM
endif
ifeq ($(ENABLE_S5WOL), y)
EXTRA_CFLAGS += -DENABLE_S5WOL
endif
ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y)
EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC
endif
ifeq ($(ENABLE_EEE), y)
EXTRA_CFLAGS += -DENABLE_EEE
endif
ifeq ($(ENABLE_S0_MAGIC_PACKET), y)
EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET
endif
ifeq ($(CONFIG_DYNAMIC_ASPM), y)
EXTRA_CFLAGS += -DCONFIG_DYNAMIC_ASPM
endif
ifeq ($(ENABLE_USE_FIRMWARE_FILE), y)
r8168-objs += r8168_firmware.o
EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE
endif
ifeq ($(CONFIG_CTAP_SHORT_OFF), y)
EXTRA_CFLAGS += -DCONFIG_CTAP_SHORT_OFF
ifeq ($(shell expr \( $(VERSION) \) \* 10000 + \( $(PATCHLEVEL) \) \* 100 + \( $(SUBLEVEL) \) \<= 60804), 1)
obj-m += r8168/
endif

View File

@@ -0,0 +1,195 @@
# SPDX-License-Identifier: GPL-2.0-only
################################################################################
#
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>.
#
# Author:
# Realtek NIC software team <nicfae@realtek.com>
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
#
################################################################################
################################################################################
# This product is covered by one or more of the following patents:
# US6,570,884, US6,115,776, and US6,327,625.
################################################################################
CONFIG_SOC_LAN = n
ENABLE_FIBER_SUPPORT = n
ENABLE_REALWOW_SUPPORT = n
ENABLE_DASH_SUPPORT = n
ENABLE_DASH_PRINTER_SUPPORT = n
CONFIG_DOWN_SPEED_100 = n
CONFIG_ASPM = y
ENABLE_S5WOL = y
ENABLE_S5_KEEP_CURR_MAC = n
ENABLE_EEE = y
ENABLE_S0_MAGIC_PACKET = n
CONFIG_DYNAMIC_ASPM = y
ENABLE_USE_FIRMWARE_FILE = n
CONFIG_CTAP_SHORT_OFF = n
ENABLE_MULTIPLE_TX_QUEUE = n
ENABLE_RSS_SUPPORT = n
ENABLE_LIB_SUPPORT = n
DISABLE_WOL_SUPPORT = n
ifneq ($(KERNELRELEASE),)
obj-m := r8168.o
r8168-objs := r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o
ifeq ($(CONFIG_SOC_LAN), y)
EXTRA_CFLAGS += -DCONFIG_SOC_LAN
endif
ifeq ($(ENABLE_FIBER_SUPPORT), y)
r8168-objs += r8168_fiber.o
EXTRA_CFLAGS += -DENABLE_FIBER_SUPPORT
endif
ifeq ($(ENABLE_REALWOW_SUPPORT), y)
r8168-objs += r8168_realwow.o
EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT
endif
ifeq ($(ENABLE_DASH_SUPPORT), y)
r8168-objs += r8168_dash.o
EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT
endif
ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y)
r8168-objs += r8168_dash.o
EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT
endif
ifneq ($(ENABLE_RSS_SUPPORT), y)
EXTRA_CFLAGS += -DCONFIG_R8168_NAPI
endif
EXTRA_CFLAGS += -DCONFIG_R8168_VLAN
ifeq ($(CONFIG_DOWN_SPEED_100), y)
EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100
endif
ifeq ($(CONFIG_ASPM), y)
EXTRA_CFLAGS += -DCONFIG_ASPM
endif
ifeq ($(ENABLE_S5WOL), y)
EXTRA_CFLAGS += -DENABLE_S5WOL
endif
ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y)
EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC
endif
ifeq ($(ENABLE_EEE), y)
EXTRA_CFLAGS += -DENABLE_EEE
endif
ifeq ($(ENABLE_S0_MAGIC_PACKET), y)
EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET
endif
ifeq ($(CONFIG_DYNAMIC_ASPM), y)
EXTRA_CFLAGS += -DCONFIG_DYNAMIC_ASPM
endif
ifeq ($(ENABLE_USE_FIRMWARE_FILE), y)
r8168-objs += r8168_firmware.o
EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE
endif
ifeq ($(CONFIG_CTAP_SHORT_OFF), y)
EXTRA_CFLAGS += -DCONFIG_CTAP_SHORT_OFF
endif
ifeq ($(ENABLE_MULTIPLE_TX_QUEUE), y)
EXTRA_CFLAGS += -DENABLE_MULTIPLE_TX_QUEUE
endif
ifeq ($(ENABLE_RSS_SUPPORT), y)
r8168-objs += r8168_rss.o
EXTRA_CFLAGS += -DENABLE_RSS_SUPPORT
endif
ifeq ($(ENABLE_LIB_SUPPORT), y)
r8168-objs += r8168_lib.o
EXTRA_CFLAGS += -DENABLE_LIB_SUPPORT
endif
ifeq ($(DISABLE_WOL_SUPPORT), y)
EXTRA_CFLAGS += -DDISABLE_WOL_SUPPORT
endif
else
BASEDIR := /lib/modules/$(shell uname -r)
KERNELDIR ?= $(BASEDIR)/build
PWD :=$(shell pwd)
DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net/ethernet -name realtek -type d)
ifeq ($(DRIVERDIR),)
DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net -name realtek -type d)
endif
ifeq ($(DRIVERDIR),)
DRIVERDIR := $(BASEDIR)/kernel/drivers/net
endif
RTKDIR := $(subst $(BASEDIR)/,,$(DRIVERDIR))
KERNEL_GCC_VERSION := $(shell cat /proc/version | sed -n 's/.*gcc version \([[:digit:]]\.[[:digit:]]\.[[:digit:]]\).*/\1/p')
CCVERSION = $(shell $(CC) -dumpversion)
KVER = $(shell uname -r)
KMAJ = $(shell echo $(KVER) | \
sed -e 's/^\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*.*/\1/')
KMIN = $(shell echo $(KVER) | \
sed -e 's/^[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*.*/\1/')
KREV = $(shell echo $(KVER) | \
sed -e 's/^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/')
kver_ge = $(shell \
echo test | awk '{if($(KMAJ) < $(1)) {print 0} else { \
if($(KMAJ) > $(1)) {print 1} else { \
if($(KMIN) < $(2)) {print 0} else { \
if($(KMIN) > $(2)) {print 1} else { \
if($(KREV) < $(3)) {print 0} else { print 1 } \
}}}}}' \
)
.PHONY: all
all: print_vars clean modules install
print_vars:
@echo
@echo "CC: " $(CC)
@echo "CCVERSION: " $(CCVERSION)
@echo "KERNEL_GCC_VERSION: " $(KERNEL_GCC_VERSION)
@echo "KVER: " $(KVER)
@echo "KMAJ: " $(KMAJ)
@echo "KMIN: " $(KMIN)
@echo "KREV: " $(KREV)
@echo "BASEDIR: " $(BASEDIR)
@echo "DRIVERDIR: " $(DRIVERDIR)
@echo "PWD: " $(PWD)
@echo "RTKDIR: " $(RTKDIR)
@echo
.PHONY:modules
modules:
#ifeq ($(call kver_ge,5,0,0),1)
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
#else
# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
#endif
.PHONY:clean
clean:
#ifeq ($(call kver_ge,5,0,0),1)
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
#else
# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean
#endif
.PHONY:install
install:
#ifeq ($(call kver_ge,5,0,0),1)
$(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install
#else
# $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install
#endif
endif

View File

@@ -5,7 +5,7 @@
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@@ -32,12 +32,85 @@
* US6,570,884, US6,115,776, and US6,327,625.
***********************************************************************************/
#include <nvidia/conftest.h>
#include <linux/ethtool.h>
#include <linux/interrupt.h>
#include <linux/version.h>
#include "r8168_dash.h"
#include "r8168_realwow.h"
#include "r8168_fiber.h"
#include "r8168_rss.h"
#ifdef ENABLE_LIB_SUPPORT
#include "r8168_lib.h"
#endif
/*
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)&& !defined(ENABLE_LIB_SUPPORT)
#define RTL_USE_NEW_INTR_API
#endif
*/
#ifndef fallthrough
#define fallthrough
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0)
static inline
ssize_t strscpy(char *dest, const char *src, size_t count)
{
long res = 0;
if (count == 0)
return -E2BIG;
while (count) {
char c;
c = src[res];
dest[res] = c;
if (!c)
return res;
res++;
count--;
}
/* Hit buffer length without finding a NUL; force NUL-termination. */
if (res)
dest[res-1] = '\0';
return -E2BIG;
}
#endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0))
static inline unsigned char *skb_checksum_start(const struct sk_buff *skb)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
return skb->head + skb->csum_start;
#else /* < 2.6.22 */
return skb_transport_header(skb);
#endif
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue,
unsigned int bytes)
{}
static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue,
unsigned int pkts,
unsigned int bytes)
{}
static inline void netdev_tx_reset_queue(struct netdev_queue *q) {}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0)
#define netdev_xmit_more() (0)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0)
#define netif_testing_on(dev)
#define netif_testing_off(dev)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
typedef int netdev_tx_t;
@@ -132,11 +205,14 @@ do { \
#endif
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0)
#define RTL_ALLOC_SKB_INTR(tp, length) dev_alloc_skb(length)
#define RTL_ALLOC_SKB_INTR(napi, length) dev_alloc_skb(length)
#define R8168_USE_NAPI_ALLOC_SKB 0
#ifdef CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0)
#undef RTL_ALLOC_SKB_INTR
#define RTL_ALLOC_SKB_INTR(tp, length) napi_alloc_skb(&tp->napi, length)
#define RTL_ALLOC_SKB_INTR(napi, length) napi_alloc_skb(napi, length)
#undef R8168_USE_NAPI_ALLOC_SKB
#define R8168_USE_NAPI_ALLOC_SKB 1
#endif
#endif
@@ -162,6 +238,10 @@ do { \
#define ENABLE_R8168_PROCFS
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
#define ENABLE_R8168_SYSFS
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
#define NETIF_F_HW_VLAN_RX NETIF_F_HW_VLAN_CTAG_RX
#define NETIF_F_HW_VLAN_TX NETIF_F_HW_VLAN_CTAG_TX
@@ -321,7 +401,7 @@ do { \
#ifndef NET_IP_ALIGN
#define NET_IP_ALIGN 2
#endif
#define RTK_RX_ALIGN 8
#define RTK_RX_ALIGN NET_IP_ALIGN
#ifdef CONFIG_R8168_NAPI
#define NAPI_SUFFIX "-NAPI"
@@ -345,13 +425,18 @@ do { \
#else
#define DASH_SUFFIX ""
#endif
#if defined(ENABLE_RSS_SUPPORT)
#define RSS_SUFFIX "-RSS"
#else
#define RSS_SUFFIX ""
#endif
#define RTL8168_VERSION "8.051.02.10m_pll" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX
#define RTL8168_VERSION "8.053.00" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX RSS_SUFFIX
#define MODULENAME "r8168"
#define PFX MODULENAME ": "
#define GPL_CLAIM "\
r8168 Copyright (C) 2022 Realtek NIC software team <nicfae@realtek.com> \n \
r8168 Copyright (C) 2024 Realtek NIC software team <nicfae@realtek.com> \n \
This program comes with ABSOLUTELY NO WARRANTY; for details, please see <http://www.gnu.org/licenses/>. \n \
This is free software, and you are welcome to redistribute it under certain conditions; see <http://www.gnu.org/licenses/>. \n"
@@ -430,9 +515,12 @@ This is free software, and you are welcome to redistribute it under certain cond
#define R8168_PCI_REGS_SIZE (0x100)
#define R8168_NAPI_WEIGHT 64
#define R8168_MAX_MSIX_VEC 4
#define RTL8168_TX_TIMEOUT (6 * HZ)
#define RTL8168_LINK_TIMEOUT (1 * HZ)
#define RTL8168_ESD_TIMEOUT (2 * HZ)
#define RTL8168_DASH_TIMEOUT (0)
#define MAX_NUM_TX_DESC 1024 /* Maximum number of Tx descriptor registers */
#define MAX_NUM_RX_DESC 1024 /* Maximum number of Rx descriptor registers */
@@ -440,10 +528,17 @@ This is free software, and you are welcome to redistribute it under certain cond
#define MIN_NUM_TX_DESC 32 /* Minimum number of Tx descriptor registers */
#define MIN_NUM_RX_DESC 32 /* Minimum number of Rx descriptor registers */
#define NUM_TX_DESC 256 /* Number of Tx descriptor registers */
#define NUM_RX_DESC 256 /* Number of Rx descriptor registers */
#define NUM_TX_DESC 1024 /* Number of Tx descriptor registers */
#define NUM_RX_DESC 1024 /* Number of Rx descriptor registers */
#define RX_BUF_SIZE 0x05F3 /* 0x05F3 = 1522bye + 1 */
#define RX_BUF_SIZE 0x05F2 /* 0x05F2 = 1522bye */
#define R8168_MAX_TX_QUEUES (2)
#define R8168_MAX_RX_QUEUES (4)
#define R8168_MAX_QUEUES R8168_MAX_RX_QUEUES
#define R8168_MULTI_TX_Q(tp) (rtl8168_tot_tx_rings(tp) > 1)
#define R8168_MULTI_RX_Q(tp) (rtl8168_tot_rx_rings(tp) > 1)
#define R8168_MULTI_RX_4Q(tp) (rtl8168_tot_rx_rings(tp) > 3)
#define R8168_MULTI_RSS_4Q(tp) (tp->num_hw_tot_en_rx_rings > 3)
#define OCP_STD_PHY_BASE 0xa400
@@ -568,13 +663,11 @@ typedef int *napi_budget;
typedef struct napi_struct *napi_ptr;
typedef int napi_budget;
#if defined(NV_NETIF_NAPI_ADD_WEIGHT_PRESENT) /* Linux v6.1 */
#define RTL_NAPI_CONFIG(ndev, priv, function, weight) \
netif_napi_add_weight(ndev, &priv->napi, function, weight)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add_weight(ndev, &priv->napi, function, weight)
#else
#define RTL_NAPI_CONFIG(ndev, priv, function, weight) \
netif_napi_add(ndev, &priv->napi, function, weight)
#endif
#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight)
#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0)
#define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget)
#define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr)
#define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev;
@@ -610,6 +703,23 @@ typedef int napi_budget;
#define RTL_NAPI_DEL(priv) netif_napi_del(&priv->napi)
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
/*****************************************************************************/
#ifdef CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) napi_consume_skb(skb, budget)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb);
#else
#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb);
#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
#else //CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb);
#else
#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb);
#endif
#endif //CONFIG_R8168_NAPI
/*****************************************************************************/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
#ifdef __CHECKER__
@@ -1103,13 +1213,20 @@ enum RTL8168_registers {
ERIAR = 0x74,
EPHY_RXER_NUM = 0x7C,
EPHYAR = 0x80,
IntrMask1 = 0x84,
IntrMask2 = 0x85,
IntrStatus1 = 0x86,
IntrStatus2 = 0x87,
TimeInt2 = 0x8C,
Rss_indir_tbl = 0x90,
OCPDR = 0xB0,
MACOCP = 0xB0,
OCPAR = 0xB4,
SecMAC0 = 0xB4,
SecMAC4 = 0xB8,
PHYOCP = 0xB8,
IntrMask3 = 0xC0,
IntrStatus3 = 0xC1,
DBG_reg = 0xD1,
TwiCmdReg = 0xD2,
MCUCmd_reg = 0xD3,
@@ -1130,6 +1247,14 @@ enum RTL8168_registers {
CMAC_IBIMR0 = 0xFA,
CMAC_IBISR0 = 0xFB,
FuncForceEvent = 0xFC,
/* ERI */
RSS_KEY_8168 = 0x90,
RSS_CTRL_8168 = 0xB8,
Q_NUM_CTRL_8168 = 0xC0,
/* MAC OCP */
EEE_TXIDLE_TIMER_8168 = 0xe048,
};
enum RTL8168_register_content {
@@ -1145,6 +1270,8 @@ enum RTL8168_register_content {
TxOK = 0x0004,
RxErr = 0x0002,
RxOK = 0x0001,
RxDU1 = 0x0002,
RxOK1 = 0x0001,
/* RxStatusDesc */
RxRWT = (1 << 22),
@@ -1189,6 +1316,7 @@ enum RTL8168_register_content {
RxCfg_fet_multi_en = (1 << 14),
RxCfg_half_refetch = (1 << 13),
RxCfg_9356SEL = (1 << 6),
RxCfg_rx_desc_v2_en = (1 << 24),
/* TxConfigBits */
TxInterFrameGapShift = 24,
@@ -1443,6 +1571,17 @@ enum bits {
BIT_31 = (1 << 31)
};
#define RTL8168_CP_NUM 4
#define RTL8168_MAX_SUPPORT_CP_LEN 110
enum rtl8168_cp_status {
rtl8168_cp_normal = 0,
rtl8168_cp_short,
rtl8168_cp_open,
rtl8168_cp_mismatch,
rtl8168_cp_unknown
};
enum effuse {
EFUSE_NOT_SUPPORT = 0,
EFUSE_SUPPORT_V1,
@@ -1463,9 +1602,34 @@ struct RxDesc {
u64 addr;
};
struct RxDescV2 {
u32 opts1;
u32 opts2;
u64 addr;
u32 rsvd1;
u32 RSSResult;
u64 rsvd2;
};
//Rx Desc Type
enum rx_desc_ring_type {
RX_DESC_RING_TYPE_UNKNOWN=0,
RX_DESC_RING_TYPE_1,
RX_DESC_RING_TYPE_2,
RX_DESC_RING_TYPE_3,
RX_DESC_RING_TYPE_MAX
};
enum rx_desc_len {
RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)),
RX_DESC_LEN_TYPE_2 = (sizeof(struct RxDescV2))
};
struct ring_info {
struct sk_buff *skb;
u32 len;
unsigned int bytecount;
unsigned short gso_segs;
u8 __pad[sizeof(void *) - sizeof(u32)];
};
@@ -1489,6 +1653,29 @@ struct pci_resource {
u32 pci_sn_h;
};
enum r8168_dash_req_flag {
R8168_RCV_REQ_SYS_OK = 0,
R8168_RCV_REQ_DASH_OK,
R8168_SEND_REQ_HOST_OK,
R8168_CMAC_RESET,
R8168_CMAC_DISALE_RX_FLAG_MAX,
R8168_DASH_REQ_FLAG_MAX
};
enum r8168_flag {
R8168_FLAG_DOWN = 0,
R8168_FLAG_TASK_RESET_PENDING,
R8168_FLAG_TASK_ESD_CHECK_PENDING,
R8168_FLAG_TASK_LINKCHG_CHECK_PENDING,
R8168_FLAG_TASK_DASH_CHECK_PENDING,
R8168_FLAG_MAX
};
enum r8168_sysfs_flag {
R8168_SYSFS_RTL_ADV = 0,
R8168_SYSFS_FLAG_MAX
};
/* Flow Control Settings */
enum rtl8168_fc_mode {
rtl8168_fc_none = 0,
@@ -1498,17 +1685,224 @@ enum rtl8168_fc_mode {
rtl8168_fc_default
};
struct rtl8168_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
struct net_device *dev;
struct rtl8168_tx_ring {
void* priv;
struct net_device *netdev;
u32 index;
u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
u32 dirty_tx;
u32 num_tx_desc; /* Number of Tx descriptor registers */
u32 tdu; /* Tx descriptor unavailable count */
struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
dma_addr_t TxPhyAddr;
u32 TxDescAllocSize;
struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */
u16 tdsar_reg; /* Transmit Descriptor Start Address */
};
struct rtl8168_rx_ring {
void* priv;
struct net_device *netdev;
u32 index;
u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
u32 dirty_rx;
u32 rdu; /* Rx descriptor unavailable count */
//struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */
//u32 RxDescAllocSize;
u64 RxDescPhyAddr[MAX_NUM_RX_DESC]; /* Rx desc physical address*/
//dma_addr_t RxPhyAddr;
struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */
//u16 rdsar_reg; /* Receive Descriptor Start Address */
};
struct r8168_napi {
#ifdef CONFIG_R8168_NAPI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
struct napi_struct napi;
#endif
#endif
void* priv;
int index;
};
struct r8168_irq {
irq_handler_t handler;
unsigned int vector;
u8 requested;
char name[IFNAMSIZ + 10];
};
#pragma pack(1)
struct rtl8168_regs {
//00
u8 mac_id[6];
u16 reg_06;
u8 mar[8];
//10
u64 dtccr;
u16 ledsel0;
u16 legreg;
u32 tctr3;
//20
u32 txq0_dsc_st_addr_0;
u32 txq0_dsc_st_addr_2;
u64 reg_28;
//30
u16 rit;
u16 ritc;
u16 reg_34;
u8 reg_36;
u8 command;
u32 imr0;
u32 isr0;
//40
u32 tcr;
u32 rcr;
u32 tctr0;
u32 tctr1;
//50
u8 cr93c46;
u8 config0;
u8 config1;
u8 config2;
u8 config3;
u8 config4;
u8 config5;
u8 tdfnr;
u32 timer_int0;
u32 timer_int1;
//60
u32 gphy_mdcmdio;
u32 csidr;
u32 csiar;
u16 phy_status;
u8 config6;
u8 pmch;
//70
u32 eridr;
u32 eriar;
u16 config7;
u16 reg_7a;
u32 ephy_rxerr_cnt;
//80
u32 ephy_mdcmdio;
u16 ledsel2;
u16 ledsel1;
u32 tctr2;
u32 timer_int2;
//90
u8 tppoll0;
u8 reg_91;
u16 reg_92;
u16 led_feature;
u16 ledsel3;
u16 eee_led_config;
u16 reg_9a;
u32 reg_9c;
//a0
u32 reg_a0;
u32 reg_a4;
u32 reg_a8;
u32 reg_ac;
//b0
u32 patch_dbg;
u32 reg_b4;
u32 gphy_ocp;
u32 reg_bc;
//c0
u32 reg_c0;
u32 reg_c4;
u32 reg_c8;
u16 otp_cmd;
u16 otp_pg_config;
//d0
u16 phy_pwr;
u8 twsi_ctrl;
u8 oob_ctrl;
u16 mac_dbgo;
u16 mac_dbg;
u16 reg_d8;
u16 rms;
u32 efuse_data;
//e0
u16 cplus_cmd;
u16 reg_e2;
u32 rxq0_dsc_st_addr_0;
u32 rxq0_dsc_st_addr_2;
u16 reg_ec;
u16 tx10midle_cnt;
//f0
u16 misc0;
u16 misc1;
u32 timer_int3;
u32 cmac_ib;
u16 reg_fc;
u16 sw_rst;
};
#pragma pack()
struct rtl8168_regs_save {
union {
u8 mac_io[R8168_MAC_REGS_SIZE];
struct rtl8168_regs mac_reg;
};
u16 pcie_phy[R8168_EPHY_REGS_SIZE/2];
u16 eth_phy[R8168_PHY_REGS_SIZE/2];
u32 eri_reg[R8168_ERI_REGS_SIZE/4];
u32 pci_reg[R8168_PCI_REGS_SIZE/4];
//ktime_t begin_ktime;
//ktime_t end_ktime;
//u64 duration_ns;
u16 int_miti_rxq0;
u8 int_config;
u32 imr_new;
u32 isr_new;
u8 tdu_status;
u16 rdu_status;
u32 rss_ctrl;
u8 rss_key[RTL8168_RSS_KEY_SIZE];
u8 rss_i_table[RTL8168_MAX_INDIRECTION_TABLE_ENTRIES];
u16 rss_queue_num_sel_r;
};
struct rtl8168_counters {
/* legacy */
u64 tx_packets;
u64 rx_packets;
u64 tx_errors;
u32 rx_errors;
u16 rx_missed;
u16 align_errors;
u32 tx_one_collision;
u32 tx_multi_collision;
u64 rx_unicast;
u64 rx_broadcast;
u32 rx_multicast;
u16 tx_aborted;
u16 tx_underrun;
};
struct rtl8168_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
struct pci_dev *pdev_cmac; /* Index of PCI device */
struct net_device *dev;
struct r8168_napi r8168napi[R8168_MAX_MSIX_VEC];
struct r8168_irq irq_tbl[R8168_MAX_MSIX_VEC];
unsigned int irq_nvecs;
unsigned int max_irq_nvecs;
unsigned int min_irq_nvecs;
unsigned int hw_supp_irq_nvecs;
struct net_device_stats stats; /* statistics of net device */
spinlock_t lock; /* spin lock flag */
u32 msg_enable;
u32 tx_tcp_csum_cmd;
u32 tx_udp_csum_cmd;
@@ -1517,23 +1911,35 @@ struct rtl8168_private {
int max_jumbo_frame_size;
int chipset;
u32 mcfg;
u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
u32 dirty_rx;
u32 dirty_tx;
//u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
// u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
//u32 dirty_rx;
//u32 dirty_tx;
u32 num_rx_desc; /* Number of Rx descriptor registers */
u32 num_tx_desc; /* Number of Tx descriptor registers */
struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
//u32 num_tx_desc; /* Number of Tx descriptor registers */
//struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */
struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */
dma_addr_t TxPhyAddr;
//dma_addr_t TxPhyAddr;
dma_addr_t RxPhyAddr;
u32 TxDescAllocSize;
//u32 TxDescAllocSize;
u32 RxDescAllocSize;
struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */
struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */
//struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */
//struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */
unsigned rx_buf_sz;
struct timer_list esd_timer;
struct timer_list link_timer;
u16 HwSuppNumTxQueues; // Number of tx ring that hardware can support
u16 HwSuppNumRxQueues; // Number of rx ring that hardware can support
unsigned int num_tx_rings; // Number of tx ring that non-ring-lib driver used
unsigned int num_rx_rings; // Number of rx ring that non-ring-lib driver used
struct rtl8168_tx_ring tx_ring[R8168_MAX_TX_QUEUES]; // non-ring-lib tx ring
struct rtl8168_rx_ring rx_ring[R8168_MAX_RX_QUEUES]; // non-ring-lib rx ring
#ifdef ENABLE_LIB_SUPPORT
struct blocking_notifier_head lib_nh;
struct rtl8168_ring lib_tx_ring[R8168_MAX_TX_QUEUES]; // ring-lib tx ring
struct rtl8168_ring lib_rx_ring[R8168_MAX_RX_QUEUES]; // ring-lib rx ring
#endif
u16 num_hw_tot_en_rx_rings; // Number of rx ring that hardware enabled
//struct timer_list esd_timer;
//struct timer_list link_timer;
struct pci_resource pci_cfg_space;
unsigned int esd_flag;
unsigned int pci_cfg_is_read;
@@ -1541,7 +1947,8 @@ struct rtl8168_private {
u16 cp_cmd;
u16 intr_mask;
u16 timer_intr_mask;
int irq;
u16 isr_reg[R8168_MAX_MSIX_VEC];
u16 imr_reg[R8168_MAX_MSIX_VEC];
int phy_auto_nego_reg;
int phy_1000_ctrl_reg;
u8 org_mac_addr[NODE_ADDRESS_SIZE];
@@ -1574,10 +1981,17 @@ struct rtl8168_private {
unsigned int (*phy_reset_pending)(struct net_device *);
unsigned int (*link_ok)(struct net_device *);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
struct work_struct task;
struct work_struct reset_task;
struct work_struct esd_task;
struct work_struct linkchg_task;
struct work_struct dash_task;
#else
struct delayed_work task;
struct delayed_work reset_task;
struct delayed_work esd_task;
struct delayed_work linkchg_task;
struct delayed_work dash_task;
#endif
DECLARE_BITMAP(task_flags, R8168_FLAG_MAX);
unsigned features;
u8 org_pci_offset_99;
@@ -1648,6 +2062,8 @@ struct rtl8168_private {
u16 BackupPhyFuseDout_47_32;
u16 BackupPhyFuseDout_63_48;
u8 ring_lib_enabled;
const char *fw_name;
struct rtl8168_fw *rtl_fw;
u32 ocp_base;
@@ -1657,8 +2073,8 @@ struct rtl8168_private {
u8 DASH;
u8 dash_printer_enabled;
u8 HwPkgDet;
void __iomem *mapped_cmac_ioaddr; /* mapped cmac memory map physical address */
void __iomem *cmac_ioaddr; /* cmac memory map physical address */
DECLARE_BITMAP(dash_req_flags, R8168_DASH_REQ_FLAG_MAX);
#ifdef ENABLE_DASH_SUPPORT
u16 AfterRecvFromFwBufLen;
@@ -1675,12 +2091,6 @@ struct rtl8168_private {
u32 OobReqComplete;
u32 OobAckComplete;
u8 RcvFwReqSysOkEvt;
u8 RcvFwDashOkEvt;
u8 SendFwHostOkEvt;
u8 DashFwDisableRx;
void *SendToFwBuffer;
dma_addr_t SendToFwBufferPhy;
u8 SendingToFw;
@@ -1733,17 +2143,152 @@ struct rtl8168_private {
//Realwow--------------
#endif //ENABLE_REALWOW_SUPPORT
u32 eee_adv_t;
u8 eee_enabled;
struct ethtool_eee eee;
u32 dynamic_aspm_packet_count;
#ifdef ENABLE_R8168_PROCFS
//Procfs support
struct proc_dir_entry *proc_dir;
struct proc_dir_entry *proc_dir_debug;
struct proc_dir_entry *proc_dir_test;
#endif
#ifdef ENABLE_R8168_SYSFS
//sysfs support
DECLARE_BITMAP(sysfs_flag, R8168_SYSFS_FLAG_MAX);
u32 testmode;
#endif
u8 HwSuppRxDescType;
u8 InitRxDescType;
u16 RxDescLength; //V1 16 Byte V2 32 Bytes
u8 HwSuppRssVer;
u8 EnableRss;
u16 HwSuppIndirTblEntries;
#ifdef ENABLE_RSS_SUPPORT
u32 rss_flags;
/* Receive Side Scaling settings */
#define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
u8 rss_key[RTL8168_RSS_KEY_SIZE];
#define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128
u8 rss_indir_tbl[RTL8168_MAX_INDIRECTION_TABLE_ENTRIES];
u32 rss_options;
#endif
u32 rx_fifo_of; /* Rx fifo overflow count */
};
#ifdef ENABLE_LIB_SUPPORT
static inline unsigned int
rtl8168_num_lib_tx_rings(struct rtl8168_private *tp)
{
int count, i;
for (count = 0, i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++)
if(tp->lib_tx_ring[i].enabled)
count++;
return count;
}
static inline unsigned int
rtl8168_num_lib_rx_rings(struct rtl8168_private *tp)
{
int count, i;
for (count = 0, i = 1; i < tp->HwSuppNumRxQueues; i++)
if(tp->lib_rx_ring[i].enabled)
count++;
return count;
}
static inline bool
rtl8168_lib_tx_ring_released(struct rtl8168_private *tp)
{
int i;
bool released = 0;
for (i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++) {
struct rtl8168_ring *ring = &tp->lib_tx_ring[i];
if (ring->allocated)
goto exit;
}
released = 1;
exit:
return released;
}
static inline bool
rtl8168_lib_rx_ring_released(struct rtl8168_private *tp)
{
int i;
bool released = 0;
for (i = 1; i < tp->HwSuppNumRxQueues; i++) {
struct rtl8168_ring *ring = &tp->lib_rx_ring[i];
if (ring->allocated)
goto exit;
}
released = 1;
exit:
return released;
}
#else
static inline unsigned int
rtl8168_num_lib_tx_rings(struct rtl8168_private *tp)
{
return 0;
}
static inline unsigned int
rtl8168_num_lib_rx_rings(struct rtl8168_private *tp)
{
return 0;
}
static inline bool
rtl8168_lib_tx_ring_released(struct rtl8168_private *tp)
{
return 1;
}
static inline bool
rtl8168_lib_rx_ring_released(struct rtl8168_private *tp)
{
return 1;
}
#endif
static inline unsigned int
rtl8168_tot_tx_rings(struct rtl8168_private *tp)
{
return tp->num_tx_rings + rtl8168_num_lib_tx_rings(tp);
}
static inline unsigned int
rtl8168_tot_rx_rings(struct rtl8168_private *tp)
{
return tp->num_rx_rings + rtl8168_num_lib_rx_rings(tp);
}
static inline struct netdev_queue *txring_txq(const struct rtl8168_tx_ring *ring)
{
return netdev_get_tx_queue(ring->netdev, ring->index);
}
static inline bool
rtl8168_lib_all_ring_released(struct rtl8168_private *tp)
{
return (rtl8168_lib_tx_ring_released(tp) &&
rtl8168_lib_rx_ring_released(tp));
}
enum eetype {
EEPROM_TYPE_NONE=0,
EEPROM_TYPE_93C46,
@@ -1787,6 +2332,8 @@ enum mcfg {
CFG_METHOD_33,
CFG_METHOD_34,
CFG_METHOD_35,
CFG_METHOD_36,
CFG_METHOD_37,
CFG_METHOD_MAX,
CFG_METHOD_DEFAULT = 0xFF
};
@@ -1825,14 +2372,17 @@ enum mcfg {
#define NIC_RAMCODE_VERSION_CFG_METHOD_23 (0x0015)
#define NIC_RAMCODE_VERSION_CFG_METHOD_26 (0x0012)
#define NIC_RAMCODE_VERSION_CFG_METHOD_28 (0x0019)
#define NIC_RAMCODE_VERSION_CFG_METHOD_29 (0x0055)
#define NIC_RAMCODE_VERSION_CFG_METHOD_29 (0x0083)
#define NIC_RAMCODE_VERSION_CFG_METHOD_31 (0x0003)
#define NIC_RAMCODE_VERSION_CFG_METHOD_35 (0x0019)
#define NIC_RAMCODE_VERSION_CFG_METHOD_35 (0x0027)
#define NIC_RAMCODE_VERSION_CFG_METHOD_36 (0x0000)
//hwoptimize
#define HW_PATCH_SOC_LAN (BIT_0)
#define HW_PATCH_SAMSUNG_LAN_DONGLE (BIT_2)
static const u8 other_q_intr_mask = (RxOK1 | RxDU1);
#define HW_PHY_STATUS_INI 1
#define HW_PHY_STATUS_EXT_INI 2
#define HW_PHY_STATUS_LAN_ON 3
@@ -1870,11 +2420,109 @@ void rtl8168_dash2_enable_tx(struct rtl8168_private *tp);
void rtl8168_dash2_disable_rx(struct rtl8168_private *tp);
void rtl8168_dash2_enable_rx(struct rtl8168_private *tp);
void rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev);
void rtl8168_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz);
static inline struct RxDesc*
rtl8168_get_rxdesc(struct rtl8168_private *tp, struct RxDesc *RxDescBase, u32 const cur_rx, u32 const q_num)
{
u8 *desc = (u8*)RxDescBase;
u32 offset;
WARN_ON_ONCE(q_num >= tp->num_hw_tot_en_rx_rings);
if (tp->InitRxDescType == RX_DESC_RING_TYPE_2)
offset = (cur_rx * tp->num_hw_tot_en_rx_rings) + q_num;
else
offset = cur_rx;
offset *= tp->RxDescLength;
desc += offset;
return (struct RxDesc*)desc;
}
#ifdef ENABLE_DASH_SUPPORT
static inline void
rtl8168_enable_dash2_interrupt(struct rtl8168_private *tp)
{
if (!tp->DASH)
return;
if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
RTL_CMAC_W8(tp, CMAC_IBIMR0, (ISRIMR_DASH_TYPE2_ROK | ISRIMR_DASH_TYPE2_TOK | ISRIMR_DASH_TYPE2_TDU | ISRIMR_DASH_TYPE2_RDU | ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE));
}
}
static inline void
rtl8168_disable_dash2_interrupt(struct rtl8168_private *tp)
{
if (!tp->DASH)
return;
if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) {
RTL_CMAC_W8(tp, CMAC_IBIMR0, 0);
}
}
#endif
static inline void
rtl8168_disable_interrupt_by_vector(struct rtl8168_private *tp,
u32 message_id)
{
if (message_id >= R8168_MAX_MSIX_VEC)
return;
if (message_id == 0) {
RTL_W16(tp, tp->imr_reg[0], 0x0000);
#ifdef ENABLE_DASH_SUPPORT
if (tp->DASH)
rtl8168_disable_dash2_interrupt(tp);
#endif
} else
RTL_W8(tp, tp->imr_reg[message_id], 0x00);
}
static inline void
rtl8168_enable_interrupt_by_vector(struct rtl8168_private *tp,
u32 message_id)
{
if (message_id >= R8168_MAX_MSIX_VEC)
return;
if (message_id == 0) {
RTL_W16(tp, tp->imr_reg[0], tp->intr_mask);
#ifdef ENABLE_DASH_SUPPORT
if (tp->DASH)
rtl8168_enable_dash2_interrupt(tp);
#endif
} else {
RTL_W8(tp, tp->imr_reg[message_id], other_q_intr_mask);
}
}
int rtl8168_open(struct net_device *dev);
int rtl8168_close(struct net_device *dev);
void rtl8168_hw_config(struct net_device *dev);
void rtl8168_hw_start(struct net_device *dev);
void rtl8168_hw_reset(struct net_device *dev);
void rtl8168_tx_clear(struct rtl8168_private *tp);
void rtl8168_rx_clear(struct rtl8168_private *tp);
int rtl8168_init_ring(struct net_device *dev);
int rtl8168_dump_tally_counter(struct rtl8168_private *tp, dma_addr_t paddr);
void rtl8168_enable_napi(struct rtl8168_private *tp);
void _rtl8168_wait_for_quiescence(struct net_device *dev);
#ifndef ENABLE_LIB_SUPPORT
static inline void rtl8168_lib_reset_prepare(struct rtl8168_private *tp) { }
static inline void rtl8168_lib_reset_complete(struct rtl8168_private *tp) { }
#endif
#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0)
#define HW_SUPP_SERDES_PHY(_M) ((_M)->HwSuppSerDesPhyVer > 0)
#define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0)
#define HW_SUPPORT_UPS_MODE(_M) ((_M)->HwSuppUpsVer > 0)
#define HW_RSS_SUPPORT_RSS(_M) ((_M)->HwSuppRssVer > 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
#define netdev_mc_count(dev) ((dev)->mc_count)

View File

@@ -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;

View File

@@ -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

View File

@@ -5,7 +5,7 @@
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@@ -247,6 +247,7 @@ RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2;
#define RTL_CMAC_R32(tp, reg) ((unsigned long) readl (tp->cmac_ioaddr + (reg)))
int rtl8168_dash_ioctl(struct net_device *dev, struct ifreq *ifr);
bool CheckDashInterrupt(struct net_device *dev, u16 status);
void HandleDashInterrupt(struct net_device *dev);
int AllocateDashShareMemory(struct net_device *dev);
void FreeAllocatedDashShareMemory(struct net_device *dev);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -0,0 +1,500 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
################################################################################
#
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>.
#
# Author:
# Realtek NIC software team <nicfae@realtek.com>
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
#
################################################################################
*/
/************************************************************************************
* This product is covered by one or more of the following patents:
* US6,570,884, US6,115,776, and US6,327,625.
***********************************************************************************/
#include <linux/version.h>
#include "r8168.h"
enum rtl8168_rss_register_content {
/* RSS */
RSS_CTRL_TCP_IPV4_SUPP = (1 << 0),
RSS_CTRL_IPV4_SUPP = (1 << 1),
RSS_CTRL_TCP_IPV6_SUPP = (1 << 2),
RSS_CTRL_IPV6_SUPP = (1 << 3),
RSS_CTRL_IPV6_EXT_SUPP = (1 << 4),
RSS_CTRL_TCP_IPV6_EXT_SUPP = (1 << 5),
RSS_HALF_SUPP = (1 << 7),
RSS_QUAD_CPU_EN = (1 << 16),
RSS_HQ_Q_SUP_R = (1 << 31),
};
static int rtl8168_get_rss_hash_opts(struct rtl8168_private *tp,
struct ethtool_rxnfc *cmd)
{
cmd->data = 0;
/* Report default options for RSS */
switch (cmd->flow_type) {
case TCP_V4_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
fallthrough;
case IPV4_FLOW:
cmd->data |= RXH_IP_SRC | RXH_IP_DST;
break;
case TCP_V6_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
fallthrough;
case IPV6_FLOW:
cmd->data |= RXH_IP_SRC | RXH_IP_DST;
break;
default:
return -EINVAL;
}
return 0;
}
int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
u32 *rule_locs)
{
struct rtl8168_private *tp = netdev_priv(dev);
int ret = -EOPNOTSUPP;
netif_info(tp, drv, tp->dev, "rss get rxnfc\n");
if (!(dev->features & NETIF_F_RXHASH))
return ret;
switch (cmd->cmd) {
case ETHTOOL_GRXRINGS:
cmd->data = rtl8168_tot_rx_rings(tp);
ret = 0;
break;
case ETHTOOL_GRXFH:
ret = rtl8168_get_rss_hash_opts(tp, cmd);
break;
default:
break;
}
return ret;
}
u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp)
{
return tp->HwSuppIndirTblEntries;
}
#define RSS_MASK_BITS_OFFSET (8)
static int _rtl8168_set_rss_hash_opt(struct rtl8168_private *tp)
{
u32 hash_mask_len;
u32 rss_ctrl;
/* Perform hash on these packet types */
rss_ctrl = RSS_CTRL_TCP_IPV4_SUPP
| RSS_CTRL_IPV4_SUPP
| RSS_CTRL_IPV6_SUPP
| RSS_CTRL_IPV6_EXT_SUPP
| RSS_CTRL_TCP_IPV6_SUPP
| RSS_CTRL_TCP_IPV6_EXT_SUPP;
if (R8168_MULTI_RSS_4Q(tp))
rss_ctrl |= RSS_QUAD_CPU_EN;
hash_mask_len = ilog2(rtl8168_rss_indir_tbl_entries(tp));
hash_mask_len &= (BIT_0 | BIT_1 | BIT_2);
rss_ctrl |= hash_mask_len << RSS_MASK_BITS_OFFSET;
rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC);
return 0;
}
static int rtl8168_set_rss_hash_opt(struct rtl8168_private *tp,
struct ethtool_rxnfc *nfc)
{
u32 rss_flags = tp->rss_flags;
netif_info(tp, drv, tp->dev, "rss set hash\n");
/*
* RSS does not support anything other than hashing
* to queues on src and dst IPs and ports
*/
if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
RXH_L4_B_0_1 | RXH_L4_B_2_3))
return -EINVAL;
switch (nfc->flow_type) {
case TCP_V4_FLOW:
case TCP_V6_FLOW:
if (!(nfc->data & RXH_IP_SRC) ||
!(nfc->data & RXH_IP_DST) ||
!(nfc->data & RXH_L4_B_0_1) ||
!(nfc->data & RXH_L4_B_2_3))
return -EINVAL;
break;
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
case AH_V4_FLOW:
case ESP_V4_FLOW:
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
case AH_V6_FLOW:
case ESP_V6_FLOW:
case IP_USER_FLOW:
case ETHER_FLOW:
/* RSS is not supported for these protocols */
if (nfc->data) {
netif_err(tp, drv, tp->dev, "Command parameters not supported\n");
return -EINVAL;
}
return 0;
default:
return -EINVAL;
}
/* if we changed something we need to update flags */
if (rss_flags != tp->rss_flags) {
u32 rss_ctrl = rtl8168_eri_read(tp, RSS_CTRL_8168, 4, ERIAR_ExGMAC);
tp->rss_flags = rss_flags;
/* Perform hash on these packet types */
rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP
| RSS_CTRL_IPV4_SUPP
| RSS_CTRL_IPV6_SUPP
| RSS_CTRL_IPV6_EXT_SUPP
| RSS_CTRL_TCP_IPV6_SUPP
| RSS_CTRL_TCP_IPV6_EXT_SUPP;
if (R8168_MULTI_RSS_4Q(tp))
rss_ctrl |= RSS_QUAD_CPU_EN;
else
rss_ctrl &= ~RSS_QUAD_CPU_EN;
rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC);
}
return 0;
}
int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
{
struct rtl8168_private *tp = netdev_priv(dev);
int ret = -EOPNOTSUPP;
netif_info(tp, drv, tp->dev, "rss set rxnfc\n");
if (!(dev->features & NETIF_F_RXHASH))
return ret;
switch (cmd->cmd) {
case ETHTOOL_SRXFH:
ret = rtl8168_set_rss_hash_opt(tp, cmd);
break;
default:
break;
}
return ret;
}
static u32 _rtl8168_get_rxfh_key_size(struct rtl8168_private *tp)
{
return sizeof(tp->rss_key);
}
u32 rtl8168_get_rxfh_key_size(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
netif_info(tp, drv, tp->dev, "rss get key size\n");
if (!(dev->features & NETIF_F_RXHASH))
return 0;
return _rtl8168_get_rxfh_key_size(tp);
}
u32 rtl8168_rss_indir_size(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
netif_info(tp, drv, tp->dev, "rss get indir tbl size\n");
if (!(dev->features & NETIF_F_RXHASH))
return 0;
return rtl8168_rss_indir_tbl_entries(tp);
}
static void rtl8168_get_reta(struct rtl8168_private *tp, u32 *indir)
{
int i, reta_size = rtl8168_rss_indir_tbl_entries(tp);
for (i = 0; i < reta_size; i++)
indir[i] = tp->rss_indir_tbl[i];
}
static u32 rtl8168_rss_key_reg(struct rtl8168_private *tp)
{
return RSS_KEY_8168;
}
static u32 rtl8168_rss_indir_tbl_reg(struct rtl8168_private *tp)
{
return Rss_indir_tbl;
}
static void rtl8168_store_reta(struct rtl8168_private *tp)
{
u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
u16 indir_tbl_reg = rtl8168_rss_indir_tbl_reg(tp);
u32 hw_indir[RTL8168_RSS_INDIR_TBL_SIZE] = {0};
u8 *indir = tp->rss_indir_tbl;
u32 bit_on_cnt = 0x00000001;
u32 i, j;
/* Mapping redirection table to HW */
for (i = 0, j = 0; i < reta_entries; i++) {
if ((indir[i] & 2) && R8168_MULTI_RSS_4Q(tp))
hw_indir[j + 4] |= bit_on_cnt;
if (indir[i] & 1)
hw_indir[j] |= bit_on_cnt;
if (bit_on_cnt == 0x80000000) {
bit_on_cnt = 0x00000001;
j++;
continue;
}
bit_on_cnt <<= 1;
}
/* Write redirection table to HW */
for (i = 0; i < RTL8168_RSS_INDIR_TBL_SIZE; i++)
RTL_W32(tp, indir_tbl_reg + i*4, hw_indir[i]);
}
static void rtl8168_store_rss_key(struct rtl8168_private *tp)
{
const u16 rss_key_reg = rtl8168_rss_key_reg(tp);
u32 i, rss_key_size = _rtl8168_get_rxfh_key_size(tp);
u32 *rss_key = (u32*)tp->rss_key;
/* Write redirection table to HW */
for (i = 0; i < rss_key_size; i+=4)
rtl8168_eri_write(tp, rss_key_reg + i, 4, *rss_key++, ERIAR_ExGMAC);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0)
int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh)
{
struct rtl8168_private *tp = netdev_priv(dev);
netif_info(tp, drv, tp->dev, "rss get rxfh\n");
if (!(dev->features & NETIF_F_RXHASH))
return -EOPNOTSUPP;
rxfh->hfunc = ETH_RSS_HASH_TOP;
if (rxfh->indir)
rtl8168_get_reta(tp, rxfh->indir);
if (rxfh->key)
memcpy(rxfh->key, tp->rss_key, RTL8168_RSS_KEY_SIZE);
return 0;
}
int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct rtl8168_private *tp = netdev_priv(dev);
u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
int i;
netif_info(tp, drv, tp->dev, "rss set rxfh\n");
/* We require at least one supported parameter to be changed and no
* change in any of the unsupported parameters
*/
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
/* Fill out the redirection table */
if (rxfh->indir) {
int max_queues = tp->num_rx_rings;
/* Verify user input. */
for (i = 0; i < reta_entries; i++)
if (rxfh->indir[i] >= max_queues)
return -EINVAL;
for (i = 0; i < reta_entries; i++)
tp->rss_indir_tbl[i] = rxfh->indir[i];
}
/* Fill out the rss hash key */
if (rxfh->key)
memcpy(tp->rss_key, rxfh->key, RTL8168_RSS_KEY_SIZE);
rtl8168_store_reta(tp);
rtl8168_store_rss_key(tp);
return 0;
}
#else
int rtl8168_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
u8 *hfunc)
{
struct rtl8168_private *tp = netdev_priv(dev);
netif_info(tp, drv, tp->dev, "rss get rxfh\n");
if (!(dev->features & NETIF_F_RXHASH))
return -EOPNOTSUPP;
if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
if (indir)
rtl8168_get_reta(tp, indir);
if (key)
memcpy(key, tp->rss_key, RTL8168_RSS_KEY_SIZE);
return 0;
}
int rtl8168_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc)
{
struct rtl8168_private *tp = netdev_priv(dev);
u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp);
int i;
netif_info(tp, drv, tp->dev, "rss set rxfh\n");
/* We require at least one supported parameter to be changed and no
* change in any of the unsupported parameters
*/
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
/* Fill out the redirection table */
if (indir) {
int max_queues = tp->num_rx_rings;
/* Verify user input. */
for (i = 0; i < reta_entries; i++)
if (indir[i] >= max_queues)
return -EINVAL;
for (i = 0; i < reta_entries; i++)
tp->rss_indir_tbl[i] = indir[i];
}
/* Fill out the rss hash key */
if (key)
memcpy(tp->rss_key, key, RTL8168_RSS_KEY_SIZE);
rtl8168_store_reta(tp);
rtl8168_store_rss_key(tp);
return 0;
}
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */
static u32 rtl8168_get_rx_desc_hash(struct rtl8168_private *tp,
struct RxDescV2 *desc)
{
if (!desc->RSSResult)
udelay(1);
return le32_to_cpu(desc->RSSResult);
}
#define RXS_8168_RSS_IPV4 BIT(17)
#define RXS_8168_RSS_IPV6 BIT(18)
#define RXS_8168_RSS_TCP BIT(19)
#define RTL8168_RXS_RSS_L3_TYPE_MASK (RXS_8168_RSS_IPV4 | RXS_8168_RSS_IPV6)
#define RTL8168_RXS_RSS_L4_TYPE_MASK (RXS_8168_RSS_TCP)
void rtl8168_rx_hash(struct rtl8168_private *tp,
struct RxDescV2 *desc,
struct sk_buff *skb)
{
u32 rss_header_info;
if (!(tp->dev->features & NETIF_F_RXHASH))
return;
rss_header_info = le32_to_cpu(desc->opts2);
if (!(rss_header_info & RTL8168_RXS_RSS_L3_TYPE_MASK))
return;
skb_set_hash(skb, rtl8168_get_rx_desc_hash(tp, desc),
(RTL8168_RXS_RSS_L4_TYPE_MASK & rss_header_info) ?
PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3);
}
void rtl8168_disable_rss(struct rtl8168_private *tp)
{
rtl8168_eri_write(tp, RSS_CTRL_8168, 4, 0x00000000, ERIAR_ExGMAC);
}
void _rtl8168_config_rss(struct rtl8168_private *tp)
{
_rtl8168_set_rss_hash_opt(tp);
rtl8168_store_reta(tp);
rtl8168_store_rss_key(tp);
}
void rtl8168_config_rss(struct rtl8168_private *tp)
{
if (!HW_RSS_SUPPORT_RSS(tp))
return;
if (!tp->EnableRss) {
rtl8168_disable_rss(tp);
return;
}
_rtl8168_config_rss(tp);
}
void rtl8168_init_rss(struct rtl8168_private *tp)
{
int i;
for (i = 0; i < rtl8168_rss_indir_tbl_entries(tp); i++)
tp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, tp->num_rx_rings);
netdev_rss_key_fill(tp->rss_key, RTL8168_RSS_KEY_SIZE);
}

View File

@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
################################################################################
#
# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>.
#
# Author:
# Realtek NIC software team <nicfae@realtek.com>
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
#
################################################################################
*/
/************************************************************************************
* This product is covered by one or more of the following patents:
* US6,570,884, US6,115,776, and US6,327,625.
***********************************************************************************/
#ifndef _LINUX_RTL8168_RSS_H
#define _LINUX_RTL8168_RSS_H
#include <linux/netdevice.h>
#include <linux/types.h>
#define RTL8168_RSS_INDIR_TBL_SIZE 8
#define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
#define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128
struct rtl8168_private;
struct RxDescV2;
int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
u32 *rule_locs);
int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd);
u32 rtl8168_get_rxfh_key_size(struct net_device *netdev);
u32 rtl8168_rss_indir_size(struct net_device *netdev);
#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 */

View File

@@ -5,7 +5,7 @@
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@@ -157,9 +157,8 @@ void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data)
int addr_sz = 6;
int w_dummy_addr = 4;
if(tp->eeprom_type == EEPROM_TYPE_NONE) {
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);

View File

@@ -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

View File

@@ -5,7 +5,7 @@
# r8168 is the Linux device driver released for Realtek Gigabit Ethernet
# controllers with PCI-Express interface.
#
# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved.
# Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
@@ -47,7 +47,6 @@
int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
{
struct rtltool_cmd my_cmd;
unsigned long flags;
int ret;
if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd)))
@@ -72,7 +71,6 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
break;
}
break;
case RTLTOOL_WRITE_MAC:
if (my_cmd.len==1)
writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset);
@@ -84,51 +82,31 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
ret = -EOPNOTSUPP;
break;
}
break;
case RTLTOOL_READ_PHY:
spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_mdio_prot_read(tp, my_cmd.offset);
spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
case RTLTOOL_WRITE_PHY:
spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_prot_write(tp, my_cmd.offset, my_cmd.data);
spin_unlock_irqrestore(&tp->lock, flags);
break;
case RTLTOOL_READ_EPHY:
spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_ephy_read(tp, my_cmd.offset);
spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
case RTLTOOL_WRITE_EPHY:
spin_lock_irqsave(&tp->lock, flags);
rtl8168_ephy_write(tp, my_cmd.offset, my_cmd.data);
spin_unlock_irqrestore(&tp->lock, flags);
break;
case RTLTOOL_READ_ERI:
my_cmd.data = 0;
if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) {
spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_eri_read(tp, my_cmd.offset, my_cmd.len, ERIAR_ExGMAC);
spin_unlock_irqrestore(&tp->lock, flags);
} else {
ret = -EOPNOTSUPP;
break;
@@ -138,20 +116,15 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
ret = -EFAULT;
break;
}
break;
case RTLTOOL_WRITE_ERI:
if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) {
spin_lock_irqsave(&tp->lock, flags);
rtl8168_eri_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data, ERIAR_ExGMAC);
spin_unlock_irqrestore(&tp->lock, flags);
} else {
ret = -EOPNOTSUPP;
break;
}
break;
case RTLTOOL_READ_PCI:
my_cmd.data = 0;
if (my_cmd.len==1)
@@ -173,7 +146,6 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
break;
}
break;
case RTLTOOL_WRITE_PCI:
if (my_cmd.len==1)
pci_write_config_byte(tp->pci_dev, my_cmd.offset,
@@ -188,108 +160,69 @@ int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr)
ret = -EOPNOTSUPP;
break;
}
break;
case RTLTOOL_READ_EEPROM:
spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_eeprom_read_sc(tp, my_cmd.offset);
spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
case RTLTOOL_WRITE_EEPROM:
spin_lock_irqsave(&tp->lock, flags);
rtl8168_eeprom_write_sc(tp, my_cmd.offset, my_cmd.data);
spin_unlock_irqrestore(&tp->lock, flags);
break;
case RTL_READ_OOB_MAC:
spin_lock_irqsave(&tp->lock, flags);
rtl8168_oob_mutex_lock(tp);
my_cmd.data = rtl8168_ocp_read(tp, my_cmd.offset, 4);
rtl8168_oob_mutex_unlock(tp);
spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
case RTL_WRITE_OOB_MAC:
if (my_cmd.len == 0 || my_cmd.len > 4)
return -EOPNOTSUPP;
spin_lock_irqsave(&tp->lock, flags);
rtl8168_oob_mutex_lock(tp);
rtl8168_ocp_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data);
rtl8168_oob_mutex_unlock(tp);
spin_unlock_irqrestore(&tp->lock, flags);
break;
case RTL_ENABLE_PCI_DIAG:
spin_lock_irqsave(&tp->lock, flags);
tp->rtk_enable_diag = 1;
spin_unlock_irqrestore(&tp->lock, flags);
dprintk("enable rtk diag\n");
break;
case RTL_DISABLE_PCI_DIAG:
spin_lock_irqsave(&tp->lock, flags);
tp->rtk_enable_diag = 0;
spin_unlock_irqrestore(&tp->lock, flags);
dprintk("disable rtk diag\n");
break;
case RTL_READ_MAC_OCP:
if (my_cmd.offset % 2)
return -EOPNOTSUPP;
spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_mac_ocp_read(tp, my_cmd.offset);
spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
case RTL_WRITE_MAC_OCP:
if ((my_cmd.offset % 2) || (my_cmd.len != 2))
return -EOPNOTSUPP;
spin_lock_irqsave(&tp->lock, flags);
rtl8168_mac_ocp_write(tp, my_cmd.offset, (u16)my_cmd.data);
spin_unlock_irqrestore(&tp->lock, flags);
break;
case RTL_DIRECT_READ_PHY_OCP:
spin_lock_irqsave(&tp->lock, flags);
my_cmd.data = rtl8168_mdio_prot_direct_read_phy_ocp(tp, my_cmd.offset);
spin_unlock_irqrestore(&tp->lock, flags);
if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) {
ret = -EFAULT;
break;
}
break;
case RTL_DIRECT_WRITE_PHY_OCP:
spin_lock_irqsave(&tp->lock, flags);
rtl8168_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data);
spin_unlock_irqrestore(&tp->lock, flags);
break;
default:
ret = -EOPNOTSUPP;
break;

View File

@@ -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