// 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) 2021 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.
***********************************************************************************/
/*
* This driver is modified from r8169.c in Linux kernel 2.6.18
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/ip.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
#endif
#include <linux/tcp.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/completion.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
#include <linux/pci-aspm.h>
#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37)
#include <linux/prefetch.h>
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#define dev_printk(A,B,fmt,args...) printk(A fmt,##args)
#else
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
#include <linux/mdio.h>
#endif
#include <asm/io.h>
#include <asm/irq.h>
#include "r8125.h"
#include "rtl_eeprom.h"
#include "rtltool.h"
#include "r8125_firmware.h"
#ifdef ENABLE_R8125_PROCFS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#endif
#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw"
#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.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;
} rtl_chip_fw_infos[] = {
/* PCI-E devices. */
[CFG_METHOD_2] = {"RTL8125A" },
[CFG_METHOD_3] = {"RTL8125A", FIRMWARE_8125A_3},
[CFG_METHOD_4] = {"RTL8125B", },
[CFG_METHOD_5] = {"RTL8125B", FIRMWARE_8125B_2},
[CFG_METHOD_6] = {"RTL8168KB", FIRMWARE_8125A_3},
[CFG_METHOD_7] = {"RTL8168KB", FIRMWARE_8125B_2},
[CFG_METHOD_DEFAULT] = {"Unknown", },
};
#define _R(NAME,MAC,RCR,MASK,JumFrameSz) \
{ .name = NAME, .mcfg = MAC, .RCR_Cfg = RCR, .RxConfigMask = MASK, .jumbo_frame_sz = JumFrameSz }
static const struct {
const char *name;
u8 mcfg;
u32 RCR_Cfg;
u32 RxConfigMask; /* Clears the bits supported by this chip */
u32 jumbo_frame_sz;
} rtl_chip_info[] = {
_R("RTL8125A",
CFG_METHOD_2,
BIT_30 | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8125A",
CFG_METHOD_3,
BIT_30 | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8125B",
CFG_METHOD_4,
BIT_30 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8125B",
CFG_METHOD_5,
BIT_30 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168KB",
CFG_METHOD_6,
BIT_30 | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("RTL8168KB",
CFG_METHOD_7,
BIT_30 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_9k),
_R("Unknown",
CFG_METHOD_DEFAULT,
(RX_DMA_BURST << RxCfgDMAShift),
0xff7e5880,
Jumbo_Frame_1k)
};
#undef _R
#ifndef PCI_VENDOR_ID_DLINK
#define PCI_VENDOR_ID_DLINK 0x1186
#endif
static struct pci_device_id rtl8125_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125), },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8162), },
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x3000), },
{0,},
};
MODULE_DEVICE_TABLE(pci, rtl8125_pci_tbl);
static int rx_copybreak = 0;
static int use_dac = 1;
static int timer_count = 0x2600;
static int timer_count_v2 = (0x2600 / 0x100);
static struct {
u32 msg_enable;
} debug = { -1 };
static unsigned int speed_mode = SPEED_2500;
static unsigned int duplex_mode = DUPLEX_FULL;
static unsigned int autoneg_mode = AUTONEG_ENABLE;
static unsigned int advertising_mode = ADVERTISED_10baseT_Half |
ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half |
ADVERTISED_100baseT_Full |
ADVERTISED_1000baseT_Half |
ADVERTISED_1000baseT_Full |
ADVERTISED_2500baseX_Full;
#ifdef CONFIG_ASPM
static int aspm = 1;
#else
static int aspm = 0;
#endif
#ifdef ENABLE_S5WOL
static int s5wol = 1;
#else
static int s5wol = 0;
#endif
#ifdef ENABLE_S5_KEEP_CURR_MAC
static int s5_keep_curr_mac = 1;
#else
static int s5_keep_curr_mac = 0;
#endif
#ifdef ENABLE_EEE
static int eee_enable = 1;
#else
static int eee_enable = 0;
#endif
#ifdef CONFIG_SOC_LAN
static ulong hwoptimize = HW_PATCH_SOC_LAN;
#else
static ulong hwoptimize = 0;
#endif
#ifdef ENABLE_S0_MAGIC_PACKET
static int s0_magic_packet = 1;
#else
static int s0_magic_packet = 0;
#endif
#ifdef ENABLE_TX_NO_CLOSE
static int tx_no_close_enable = 1;
#else
static int tx_no_close_enable = 0;
#endif
#ifdef ENABLE_PTP_MASTER_MODE
static int enable_ptp_master_mode = 1;
#else
static int enable_ptp_master_mode = 0;
#endif
#ifdef DISABLE_PM_SUPPORT
static int disable_pm_support = 1;
#else
static int disable_pm_support = 0;
#endif
MODULE_AUTHOR("Realtek and the Linux r8125 crew <netdev@vger.kernel.org>");
MODULE_DESCRIPTION("Realtek RTL8125 2.5Gigabit Ethernet driver");
module_param(speed_mode, uint, 0);
MODULE_PARM_DESC(speed_mode, "force phy operation. Deprecated by ethtool (8).");
module_param(duplex_mode, uint, 0);
MODULE_PARM_DESC(duplex_mode, "force phy operation. Deprecated by ethtool (8).");
module_param(autoneg_mode, uint, 0);
MODULE_PARM_DESC(autoneg_mode, "force phy operation. Deprecated by ethtool (8).");
module_param(advertising_mode, uint, 0);
MODULE_PARM_DESC(advertising_mode, "force phy operation. Deprecated by ethtool (8).");
module_param(aspm, int, 0);
MODULE_PARM_DESC(aspm, "Enable ASPM.");
module_param
评论1
最新资源