├── README.md ├── rtl_eeprom.h ├── r8168_firmware.h ├── rtltool.h ├── r8168_fiber.h ├── r8168_rss.h ├── r8168_realwow.h ├── Makefile ├── r8168_dash.h ├── rtl_eeprom.c ├── r8168_firmware.c ├── r8168_asf.h ├── rtltool.c ├── r8168_rss.c ├── r8168_asf.c └── r8168.h /README.md: -------------------------------------------------------------------------------- 1 | # Realtek RTL8168/RTL8111 1GbE PCIe 2 | 3 | This repository contains the source code provided by Realtek for the RTL8168/RTL8111 1GbE PCIe controllers. 4 | 5 | The source code is provided by Realtek as-is, without any kind of changelog. Git is only used for tracking down the changes introduced between versions. 6 | 7 | ## Original sources 8 | 9 | You can find the original files provided by Realtek [here](https://www.realtek.com/Download/List?cate_id=584). 10 | 11 | The same files from Realtek are provided as [release assets](https://github.com/openwrt/rtl8168/releases). 12 | 13 | ## Disclaimer 14 | 15 | Bug reports or issues should be reported directly to [Realtek](https://www.realtek.com). 16 | 17 | This repository is used for OpenWrt development because the files provided by Realtek are protected with CAPTCHAs and can't be used for creating OpenWrt packages. 18 | -------------------------------------------------------------------------------- /rtl_eeprom.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | //EEPROM opcodes 36 | #define RTL_EEPROM_READ_OPCODE 06 37 | #define RTL_EEPROM_WRITE_OPCODE 05 38 | #define RTL_EEPROM_ERASE_OPCODE 07 39 | #define RTL_EEPROM_EWEN_OPCODE 19 40 | #define RTL_EEPROM_EWDS_OPCODE 16 41 | 42 | #define RTL_CLOCK_RATE 3 43 | 44 | void rtl8168_eeprom_type(struct rtl8168_private *tp); 45 | void rtl8168_eeprom_cleanup(struct rtl8168_private *tp); 46 | u16 rtl8168_eeprom_read_sc(struct rtl8168_private *tp, u16 reg); 47 | void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data); 48 | void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count); 49 | u16 rtl8168_shift_in_bits(struct rtl8168_private *tp); 50 | void rtl8168_raise_clock(struct rtl8168_private *tp, u8 *x); 51 | void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x); 52 | void rtl8168_stand_by(struct rtl8168_private *tp); 53 | void rtl8168_set_eeprom_sel_low(struct rtl8168_private *tp); 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /r8168_firmware.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek 2.5Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #ifndef _LINUX_RTL8168_FIRMWARE_H 36 | #define _LINUX_RTL8168_FIRMWARE_H 37 | 38 | #include 39 | #include 40 | 41 | struct rtl8168_private; 42 | typedef void (*rtl8168_fw_write_t)(struct rtl8168_private *tp, u16 reg, u16 val); 43 | typedef u32 (*rtl8168_fw_read_t)(struct rtl8168_private *tp, u16 reg); 44 | 45 | #define RTL8168_VER_SIZE 32 46 | 47 | struct rtl8168_fw { 48 | rtl8168_fw_write_t phy_write; 49 | rtl8168_fw_read_t phy_read; 50 | rtl8168_fw_write_t mac_mcu_write; 51 | rtl8168_fw_read_t mac_mcu_read; 52 | const struct firmware *fw; 53 | const char *fw_name; 54 | struct device *dev; 55 | 56 | char version[RTL8168_VER_SIZE]; 57 | 58 | struct rtl8168_fw_phy_action { 59 | __le32 *code; 60 | size_t size; 61 | } phy_action; 62 | }; 63 | 64 | int rtl8168_fw_request_firmware(struct rtl8168_fw *rtl_fw); 65 | void rtl8168_fw_release_firmware(struct rtl8168_fw *rtl_fw); 66 | void rtl8168_fw_write_firmware(struct rtl8168_private *tp, struct rtl8168_fw *rtl_fw); 67 | 68 | #endif /* _LINUX_RTL8168_FIRMWARE_H */ 69 | -------------------------------------------------------------------------------- /rtltool.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #ifndef _LINUX_RTLTOOL_H 36 | #define _LINUX_RTLTOOL_H 37 | 38 | #define SIOCRTLTOOL SIOCDEVPRIVATE+1 39 | 40 | enum rtl_cmd { 41 | RTLTOOL_READ_MAC=0, 42 | RTLTOOL_WRITE_MAC, 43 | RTLTOOL_READ_PHY, 44 | RTLTOOL_WRITE_PHY, 45 | RTLTOOL_READ_EPHY, 46 | RTLTOOL_WRITE_EPHY, 47 | RTLTOOL_READ_ERI, 48 | RTLTOOL_WRITE_ERI, 49 | RTLTOOL_READ_PCI, 50 | RTLTOOL_WRITE_PCI, 51 | RTLTOOL_READ_EEPROM, 52 | RTLTOOL_WRITE_EEPROM, 53 | 54 | RTL_READ_OOB_MAC, 55 | RTL_WRITE_OOB_MAC, 56 | 57 | RTL_ENABLE_PCI_DIAG, 58 | RTL_DISABLE_PCI_DIAG, 59 | 60 | RTL_READ_MAC_OCP, 61 | RTL_WRITE_MAC_OCP, 62 | 63 | RTL_DIRECT_READ_PHY_OCP, 64 | RTL_DIRECT_WRITE_PHY_OCP, 65 | 66 | RTLTOOL_INVALID 67 | }; 68 | 69 | struct rtltool_cmd { 70 | __u32 cmd; 71 | __u32 offset; 72 | __u32 len; 73 | __u32 data; 74 | }; 75 | 76 | enum mode_access { 77 | MODE_NONE=0, 78 | MODE_READ, 79 | MODE_WRITE 80 | }; 81 | 82 | #ifdef __KERNEL__ 83 | int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr); 84 | #endif 85 | 86 | #endif /* _LINUX_RTLTOOL_H */ 87 | -------------------------------------------------------------------------------- /r8168_fiber.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #ifndef _LINUX_R8168_FIBER_H 36 | #define _LINUX_R8168_FIBER_H 37 | 38 | enum { 39 | FIBER_MODE_NIC_ONLY = 0, 40 | FIBER_MODE_RTL8168H_RTL8211FS, 41 | FIBER_MODE_RTL8168H_MDI_SWITCH_RTL8211FS, 42 | FIBER_MODE_MAX 43 | }; 44 | 45 | enum { 46 | FIBER_STAT_NOT_CHECKED = 0, 47 | FIBER_STAT_CONNECT_EEPROM, 48 | FIBER_STAT_DISCONNECT, 49 | FIBER_STAT_CONNECT_GPO, 50 | FIBER_STAT_MAX 51 | }; 52 | 53 | enum { 54 | FIBER_LED_MODE_DEFAULT = 0, 55 | FIBER_LED_MODE_1, 56 | FIBER_LED_MODE_MAX 57 | }; 58 | 59 | #define HW_FIBER_MODE_ENABLED(_M) ((_M)->HwFiberModeVer > 0) 60 | #define HW_FIBER_STATUS_CONNECTED(_M) (((_M)->HwFiberStat == FIBER_STAT_CONNECT_EEPROM) || ((_M)->HwFiberStat == FIBER_STAT_CONNECT_GPO)) 61 | #define HW_FIBER_STATUS_DISCONNECTED(_M) ((_M)->HwFiberStat == FIBER_STAT_DISCONNECT) 62 | 63 | struct rtl8168_private; 64 | 65 | void rtl8168_hw_init_fiber_nic(struct rtl8168_private *tp); 66 | void rtl8168_hw_fiber_nic_d3_para(struct rtl8168_private *tp); 67 | void rtl8168_hw_fiber_phy_config(struct rtl8168_private *tp); 68 | void rtl8168_hw_switch_mdi_to_fiber(struct rtl8168_private *tp); 69 | void rtl8168_hw_switch_mdi_to_nic(struct rtl8168_private *tp); 70 | unsigned int rtl8168_hw_fiber_link_ok(struct rtl8168_private *tp); 71 | void rtl8168_check_fiber_link_status(struct rtl8168_private *tp); 72 | void rtl8168_check_hw_fiber_mode_support(struct rtl8168_private *tp); 73 | void rtl8168_set_fiber_mode_software_variable(struct rtl8168_private *tp); 74 | 75 | #endif /* _LINUX_R8168_FIBER_H */ 76 | -------------------------------------------------------------------------------- /r8168_rss.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #ifndef _LINUX_RTL8168_RSS_H 36 | #define _LINUX_RTL8168_RSS_H 37 | 38 | #include 39 | #include 40 | 41 | #define RTL8168_RSS_INDIR_TBL_SIZE 8 42 | #define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ 43 | #define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128 44 | 45 | struct rtl8168_private; 46 | struct RxDescV2; 47 | 48 | int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, 49 | u32 *rule_locs); 50 | int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd); 51 | u32 rtl8168_get_rxfh_key_size(struct net_device *netdev); 52 | u32 rtl8168_rss_indir_size(struct net_device *netdev); 53 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) 54 | int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh); 55 | int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, 56 | struct netlink_ext_ack *extack); 57 | #else 58 | int rtl8168_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, 59 | u8 *hfunc); 60 | int rtl8168_set_rxfh(struct net_device *netdev, const u32 *indir, 61 | const u8 *key, const u8 hfunc); 62 | #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */ 63 | void rtl8168_rx_hash(struct rtl8168_private *tp, 64 | struct RxDescV2 *desc, 65 | struct sk_buff *skb); 66 | void _rtl8168_config_rss(struct rtl8168_private *tp); 67 | void rtl8168_config_rss(struct rtl8168_private *tp); 68 | void rtl8168_init_rss(struct rtl8168_private *tp); 69 | u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp); 70 | void rtl8168_disable_rss(struct rtl8168_private *tp); 71 | 72 | #endif /* _LINUX_RTL8168_RSS_H */ 73 | -------------------------------------------------------------------------------- /r8168_realwow.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #ifndef _LINUX_R8168_REALWOW_H 36 | #define _LINUX_R8168_REALWOW_H 37 | 38 | #define SIOCDEVPRIVATE_RTLREALWOW SIOCDEVPRIVATE+3 39 | 40 | #define MAX_RealWoW_KCP_SIZE (100) 41 | #define MAX_RealWoW_Payload (64) 42 | 43 | #define KA_TX_PACKET_SIZE (100) 44 | #define KA_WAKEUP_PATTERN_SIZE (120) 45 | 46 | //HwSuppKeepAliveOffloadVer 47 | #define HW_SUPPORT_KCP_OFFLOAD(_M) ((_M)->HwSuppKCPOffloadVer > 0) 48 | 49 | enum rtl_realwow_cmd { 50 | 51 | RTL_REALWOW_SET_KCP_DISABLE=0, 52 | RTL_REALWOW_SET_KCP_INFO, 53 | RTL_REALWOW_SET_KCP_CONTENT, 54 | 55 | RTL_REALWOW_SET_KCP_ACKPKTINFO, 56 | RTL_REALWOW_SET_KCP_WPINFO, 57 | RTL_REALWOW_SET_KCPDHCP_TIMEOUT, 58 | 59 | RTLT_REALWOW_COMMAND_INVALID 60 | }; 61 | 62 | struct rtl_realwow_ioctl_struct { 63 | __u32 cmd; 64 | __u32 offset; 65 | __u32 len; 66 | union { 67 | __u32 data; 68 | void *data_buffer; 69 | }; 70 | }; 71 | 72 | typedef struct _MP_KCPInfo { 73 | u8 DIPv4[4]; 74 | u8 MacID[6]; 75 | u16 UdpPort[2]; 76 | u8 PKTLEN[2]; 77 | 78 | u16 ackLostCnt; 79 | u8 KCP_WakePattern[MAX_RealWoW_Payload]; 80 | u8 KCP_AckPacket[MAX_RealWoW_Payload]; 81 | u32 KCP_interval; 82 | u8 KCP_WakePattern_Len; 83 | u8 KCP_AckPacket_Len; 84 | u8 KCP_TxPacket[2][KA_TX_PACKET_SIZE]; 85 | } MP_KCP_INFO, *PMP_KCP_INFO; 86 | 87 | typedef struct _KCPInfo { 88 | u32 nId; // = id 89 | u8 DIPv4[4]; 90 | u8 MacID[6]; 91 | u16 UdpPort; 92 | u16 PKTLEN; 93 | } KCPInfo, *PKCPInfo; 94 | 95 | typedef struct _KCPContent { 96 | u32 id; // = id 97 | u32 mSec; // = msec 98 | u32 size; // =size 99 | u8 bPacket[MAX_RealWoW_KCP_SIZE]; // put packet here 100 | } KCPContent, *PKCPContent; 101 | 102 | typedef struct _RealWoWAckPktInfo { 103 | u16 ackLostCnt; 104 | u16 patterntSize; 105 | u8 pattern[MAX_RealWoW_Payload]; 106 | } RealWoWAckPktInfo,*PRealWoWAckPktInfo; 107 | 108 | typedef struct _RealWoWWPInfo { 109 | u16 patterntSize; 110 | u8 pattern[MAX_RealWoW_Payload]; 111 | } RealWoWWPInfo,*PRealWoWWPInfo; 112 | 113 | int rtl8168_realwow_ioctl(struct net_device *dev, struct ifreq *ifr); 114 | void rtl8168_realwow_hw_init(struct net_device *dev); 115 | void rtl8168_get_realwow_hw_version(struct net_device *dev); 116 | void rtl8168_set_realwow_d3_para(struct net_device *dev); 117 | 118 | #endif /* _LINUX_R8168_REALWOW_H */ 119 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only 2 | ################################################################################ 3 | # 4 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 5 | # controllers with PCI-Express interface. 6 | # 7 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 8 | # 9 | # This program is free software; you can redistribute it and/or modify it 10 | # under the terms of the GNU General Public License as published by the Free 11 | # Software Foundation; either version 2 of the License, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, but WITHOUT 15 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 | # more details. 18 | # 19 | # You should have received a copy of the GNU General Public License along with 20 | # this program; if not, see . 21 | # 22 | # Author: 23 | # Realtek NIC software team 24 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 25 | # 26 | ################################################################################ 27 | 28 | ################################################################################ 29 | # This product is covered by one or more of the following patents: 30 | # US6,570,884, US6,115,776, and US6,327,625. 31 | ################################################################################ 32 | 33 | CONFIG_SOC_LAN = y 34 | ENABLE_FIBER_SUPPORT = n 35 | ENABLE_REALWOW_SUPPORT = n 36 | ENABLE_DASH_SUPPORT = n 37 | ENABLE_DASH_PRINTER_SUPPORT = n 38 | CONFIG_DOWN_SPEED_100 = n 39 | CONFIG_ASPM = y 40 | ENABLE_S5WOL = y 41 | ENABLE_S5_KEEP_CURR_MAC = n 42 | ENABLE_EEE = y 43 | ENABLE_S0_MAGIC_PACKET = n 44 | CONFIG_DYNAMIC_ASPM = y 45 | ENABLE_USE_FIRMWARE_FILE = n 46 | CONFIG_CTAP_SHORT_OFF = n 47 | ENABLE_MULTIPLE_TX_QUEUE = n 48 | ENABLE_RSS_SUPPORT = n 49 | ENABLE_LIB_SUPPORT = n 50 | DISABLE_WOL_SUPPORT = n 51 | ENABLE_GIGA_LITE = y 52 | 53 | ifneq ($(KERNELRELEASE),) 54 | obj-m := r8168.o 55 | r8168-objs := r8168_n.o r8168_asf.o rtl_eeprom.o rtltool.o 56 | ifeq ($(CONFIG_SOC_LAN), y) 57 | EXTRA_CFLAGS += -DCONFIG_SOC_LAN 58 | endif 59 | ifeq ($(ENABLE_FIBER_SUPPORT), y) 60 | r8168-objs += r8168_fiber.o 61 | EXTRA_CFLAGS += -DENABLE_FIBER_SUPPORT 62 | endif 63 | ifeq ($(ENABLE_REALWOW_SUPPORT), y) 64 | r8168-objs += r8168_realwow.o 65 | EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT 66 | endif 67 | ifeq ($(ENABLE_DASH_SUPPORT), y) 68 | r8168-objs += r8168_dash.o 69 | EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT 70 | endif 71 | ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y) 72 | r8168-objs += r8168_dash.o 73 | EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT 74 | endif 75 | ifneq ($(ENABLE_RSS_SUPPORT), y) 76 | EXTRA_CFLAGS += -DCONFIG_R8168_NAPI 77 | endif 78 | EXTRA_CFLAGS += -DCONFIG_R8168_VLAN 79 | ifeq ($(CONFIG_DOWN_SPEED_100), y) 80 | EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100 81 | endif 82 | ifeq ($(CONFIG_ASPM), y) 83 | EXTRA_CFLAGS += -DCONFIG_ASPM 84 | endif 85 | ifeq ($(ENABLE_S5WOL), y) 86 | EXTRA_CFLAGS += -DENABLE_S5WOL 87 | endif 88 | ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y) 89 | EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC 90 | endif 91 | ifeq ($(ENABLE_EEE), y) 92 | EXTRA_CFLAGS += -DENABLE_EEE 93 | endif 94 | ifeq ($(ENABLE_S0_MAGIC_PACKET), y) 95 | EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET 96 | endif 97 | ifeq ($(CONFIG_DYNAMIC_ASPM), y) 98 | EXTRA_CFLAGS += -DCONFIG_DYNAMIC_ASPM 99 | endif 100 | ifeq ($(ENABLE_USE_FIRMWARE_FILE), y) 101 | r8168-objs += r8168_firmware.o 102 | EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE 103 | endif 104 | ifeq ($(CONFIG_CTAP_SHORT_OFF), y) 105 | EXTRA_CFLAGS += -DCONFIG_CTAP_SHORT_OFF 106 | endif 107 | ifeq ($(ENABLE_MULTIPLE_TX_QUEUE), y) 108 | EXTRA_CFLAGS += -DENABLE_MULTIPLE_TX_QUEUE 109 | endif 110 | ifeq ($(ENABLE_RSS_SUPPORT), y) 111 | r8168-objs += r8168_rss.o 112 | EXTRA_CFLAGS += -DENABLE_RSS_SUPPORT 113 | endif 114 | ifeq ($(ENABLE_LIB_SUPPORT), y) 115 | r8168-objs += r8168_lib.o 116 | EXTRA_CFLAGS += -DENABLE_LIB_SUPPORT 117 | endif 118 | ifeq ($(DISABLE_WOL_SUPPORT), y) 119 | EXTRA_CFLAGS += -DDISABLE_WOL_SUPPORT 120 | endif 121 | ifeq ($(ENABLE_GIGA_LITE), y) 122 | EXTRA_CFLAGS += -DENABLE_GIGA_LITE 123 | endif 124 | else 125 | BASEDIR := /lib/modules/$(shell uname -r) 126 | KERNELDIR ?= $(BASEDIR)/build 127 | PWD :=$(shell pwd) 128 | DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net/ethernet -name realtek -type d) 129 | ifeq ($(DRIVERDIR),) 130 | DRIVERDIR := $(shell find $(BASEDIR)/kernel/drivers/net -name realtek -type d) 131 | endif 132 | ifeq ($(DRIVERDIR),) 133 | DRIVERDIR := $(BASEDIR)/kernel/drivers/net 134 | endif 135 | RTKDIR := $(subst $(BASEDIR)/,,$(DRIVERDIR)) 136 | 137 | KERNEL_GCC_VERSION := $(shell cat /proc/version | sed -n 's/.*gcc version \([[:digit:]]\.[[:digit:]]\.[[:digit:]]\).*/\1/p') 138 | CCVERSION = $(shell $(CC) -dumpversion) 139 | 140 | KVER = $(shell uname -r) 141 | KMAJ = $(shell echo $(KVER) | \ 142 | sed -e 's/^\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*.*/\1/') 143 | KMIN = $(shell echo $(KVER) | \ 144 | sed -e 's/^[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*.*/\1/') 145 | KREV = $(shell echo $(KVER) | \ 146 | sed -e 's/^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*/\1/') 147 | 148 | kver_ge = $(shell \ 149 | echo test | awk '{if($(KMAJ) < $(1)) {print 0} else { \ 150 | if($(KMAJ) > $(1)) {print 1} else { \ 151 | if($(KMIN) < $(2)) {print 0} else { \ 152 | if($(KMIN) > $(2)) {print 1} else { \ 153 | if($(KREV) < $(3)) {print 0} else { print 1 } \ 154 | }}}}}' \ 155 | ) 156 | 157 | .PHONY: all 158 | all: print_vars clean modules install 159 | 160 | print_vars: 161 | @echo 162 | @echo "CC: " $(CC) 163 | @echo "CCVERSION: " $(CCVERSION) 164 | @echo "KERNEL_GCC_VERSION: " $(KERNEL_GCC_VERSION) 165 | @echo "KVER: " $(KVER) 166 | @echo "KMAJ: " $(KMAJ) 167 | @echo "KMIN: " $(KMIN) 168 | @echo "KREV: " $(KREV) 169 | @echo "BASEDIR: " $(BASEDIR) 170 | @echo "DRIVERDIR: " $(DRIVERDIR) 171 | @echo "PWD: " $(PWD) 172 | @echo "RTKDIR: " $(RTKDIR) 173 | @echo 174 | 175 | .PHONY:modules 176 | modules: 177 | #ifeq ($(call kver_ge,5,0,0),1) 178 | $(MAKE) -C $(KERNELDIR) M=$(PWD) modules 179 | #else 180 | # $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules 181 | #endif 182 | 183 | .PHONY:clean 184 | clean: 185 | #ifeq ($(call kver_ge,5,0,0),1) 186 | $(MAKE) -C $(KERNELDIR) M=$(PWD) clean 187 | #else 188 | # $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) clean 189 | #endif 190 | 191 | .PHONY:install 192 | install: 193 | #ifeq ($(call kver_ge,5,0,0),1) 194 | $(MAKE) -C $(KERNELDIR) M=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install 195 | #else 196 | # $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) INSTALL_MOD_DIR=$(RTKDIR) modules_install 197 | #endif 198 | 199 | endif 200 | -------------------------------------------------------------------------------- /r8168_dash.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #ifndef _LINUX_R8168_DASH_H 36 | #define _LINUX_R8168_DASH_H 37 | 38 | #define SIOCDEVPRIVATE_RTLDASH SIOCDEVPRIVATE+2 39 | 40 | enum rtl_dash_cmd { 41 | RTL_DASH_ARP_NS_OFFLOAD = 0, 42 | RTL_DASH_SET_OOB_IPMAC, 43 | RTL_DASH_NOTIFY_OOB, 44 | 45 | RTL_DASH_SEND_BUFFER_DATA_TO_DASH_FW, 46 | RTL_DASH_CHECK_SEND_BUFFER_TO_DASH_FW_COMPLETE, 47 | RTL_DASH_GET_RCV_FROM_FW_BUFFER_DATA, 48 | RTL_DASH_OOB_REQ, 49 | RTL_DASH_OOB_ACK, 50 | RTL_DASH_DETACH_OOB_REQ, 51 | RTL_DASH_DETACH_OOB_ACK, 52 | 53 | RTL_FW_SET_IPV4 = 0x10, 54 | RTL_FW_GET_IPV4, 55 | RTL_FW_SET_IPV6, 56 | RTL_FW_GET_IPV6, 57 | RTL_FW_SET_EXT_SNMP, 58 | RTL_FW_GET_EXT_SNMP, 59 | RTL_FW_SET_WAKEUP_PATTERN, 60 | RTL_FW_GET_WAKEUP_PATTERN, 61 | RTL_FW_DEL_WAKEUP_PATTERN, 62 | 63 | RTLT_DASH_COMMAND_INVALID, 64 | }; 65 | 66 | struct rtl_dash_ip_mac { 67 | struct sockaddr ifru_addr; 68 | struct sockaddr ifru_netmask; 69 | struct sockaddr ifru_hwaddr; 70 | }; 71 | 72 | struct rtl_dash_ioctl_struct { 73 | __u32 cmd; 74 | __u32 offset; 75 | __u32 len; 76 | union { 77 | __u32 data; 78 | void *data_buffer; 79 | }; 80 | }; 81 | 82 | struct settings_ipv4 { 83 | __u32 IPv4addr; 84 | __u32 IPv4mask; 85 | __u32 IPv4Gateway; 86 | }; 87 | 88 | struct settings_ipv6 { 89 | __u32 reserved; 90 | __u32 prefixLen; 91 | __u16 IPv6addr[8]; 92 | __u16 IPv6Gateway[8]; 93 | }; 94 | 95 | struct settings_ext_snmp { 96 | __u16 index; 97 | __u16 oid_get_len; 98 | __u8 oid_for_get[24]; 99 | __u8 reserved0[26]; 100 | __u16 value_len; 101 | __u8 value[256]; 102 | __u8 supported; 103 | __u8 reserved1[27]; 104 | }; 105 | 106 | struct wakeup_pattern { 107 | __u8 index; 108 | __u8 valid; 109 | __u8 start; 110 | __u8 length; 111 | __u8 name[36]; 112 | __u8 mask[16]; 113 | __u8 pattern[128]; 114 | __u32 reserved[2]; 115 | }; 116 | 117 | typedef struct _RX_DASH_FROM_FW_DESC { 118 | __le16 length; 119 | __le16 status; 120 | __le32 resv; 121 | __le64 BufferAddress; 122 | } 123 | RX_DASH_FROM_FW_DESC, *PRX_DASH_FROM_FW_DESC; 124 | 125 | typedef struct _TX_DASH_SEND_FW_DESC { 126 | __le16 length; 127 | __le16 status; 128 | __le32 resv; 129 | __le64 BufferAddress; 130 | } 131 | TX_DASH_SEND_FW_DESC, *PTX_DASH_SEND_FW_DESC; 132 | 133 | typedef struct _OSOOBHdr { 134 | __le32 len; 135 | u8 type; 136 | u8 flag; 137 | u8 hostReqV; 138 | u8 res; 139 | } 140 | OSOOBHdr, *POSOOBHdr; 141 | 142 | typedef struct _RX_DASH_BUFFER_TYPE_2 { 143 | OSOOBHdr oobhdr; 144 | u8 RxDataBuffer[0]; 145 | } 146 | RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2; 147 | 148 | #define ALIGN_8 (0x7) 149 | #define ALIGN_16 (0xf) 150 | #define ALIGN_32 (0x1f) 151 | #define ALIGN_64 (0x3f) 152 | #define ALIGN_256 (0xff) 153 | #define ALIGN_4096 (0xfff) 154 | 155 | #define OCP_REG_CONFIG0 (0x10) 156 | #define OCP_REG_CONFIG0_REV_F (0xB8) 157 | #define OCP_REG_DASH_POLL (0x30) 158 | #define OCP_REG_HOST_REQ (0x34) 159 | #define OCP_REG_DASH_REQ (0x35) 160 | #define OCP_REG_CR (0x36) 161 | #define OCP_REG_DMEMSTA (0x38) 162 | #define OCP_REG_GPHYAR (0x60) 163 | #define OCP_REG_FIRMWARE_MAJOR_VERSION (0x120) 164 | 165 | 166 | #define OCP_REG_CONFIG0_DASHEN BIT_15 167 | #define OCP_REG_CONFIG0_OOBRESET BIT_14 168 | #define OCP_REG_CONFIG0_APRDY BIT_13 169 | #define OCP_REG_CONFIG0_FIRMWARERDY BIT_12 170 | #define OCP_REG_CONFIG0_DRIVERRDY BIT_11 171 | #define OCP_REG_CONFIG0_OOB_WDT BIT_9 172 | #define OCP_REG_CONFIG0_DRV_WAIT_OOB BIT_8 173 | #define OCP_REG_CONFIG0_TLSEN BIT_7 174 | 175 | #define HW_DASH_SUPPORT_DASH(_M) ((_M)->HwSuppDashVer > 0) 176 | #define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1) 177 | #define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2) 178 | #define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3) 179 | #define HW_DASH_SUPPORT_CMAC(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || HW_DASH_SUPPORT_TYPE_3(_M)) 180 | #define HW_DASH_SUPPORT_GET_FIRMWARE_VERSION(_M) (HW_DASH_SUPPORT_TYPE_2(_M) || \ 181 | HW_DASH_SUPPORT_TYPE_3(_M)) 182 | 183 | #define RECV_FROM_FW_BUF_SIZE (2048) 184 | #define SEND_TO_FW_BUF_SIZE (2048) 185 | 186 | #define RX_DASH_FROM_FW_OWN BIT_15 187 | #define TX_DASH_SEND_FW_OWN BIT_15 188 | 189 | #define TXS_CC3_0 (BIT_0|BIT_1|BIT_2|BIT_3) 190 | #define TXS_EXC BIT_4 191 | #define TXS_LNKF BIT_5 192 | #define TXS_OWC BIT_6 193 | #define TXS_TES BIT_7 194 | #define TXS_UNF BIT_9 195 | #define TXS_LGSEN BIT_11 196 | #define TXS_LS BIT_12 197 | #define TXS_FS BIT_13 198 | #define TXS_EOR BIT_14 199 | #define TXS_OWN BIT_15 200 | 201 | #define TPPool_HRDY 0x20 202 | 203 | #define HostReqReg (0xC0) 204 | #define SystemMasterDescStartAddrLow (0xF0) 205 | #define SystemMasterDescStartAddrHigh (0xF4) 206 | #define SystemSlaveDescStartAddrLow (0xF8) 207 | #define SystemSlaveDescStartAddrHigh (0xFC) 208 | 209 | //DASH Request Type 210 | #define WSMANREG 0x01 211 | #define OSPUSHDATA 0x02 212 | 213 | #define RXS_OWN BIT_15 214 | #define RXS_EOR BIT_14 215 | #define RXS_FS BIT_13 216 | #define RXS_LS BIT_12 217 | 218 | #define ISRIMR_DP_DASH_OK BIT_15 219 | #define ISRIMR_DP_HOST_OK BIT_13 220 | #define ISRIMR_DP_REQSYS_OK BIT_11 221 | 222 | #define ISRIMR_DASH_INTR_EN BIT_12 223 | #define ISRIMR_DASH_INTR_CMAC_RESET BIT_15 224 | 225 | #define ISRIMR_DASH_TYPE2_ROK BIT_0 226 | #define ISRIMR_DASH_TYPE2_RDU BIT_1 227 | #define ISRIMR_DASH_TYPE2_TOK BIT_2 228 | #define ISRIMR_DASH_TYPE2_TDU BIT_3 229 | #define ISRIMR_DASH_TYPE2_TX_FIFO_FULL BIT_4 230 | #define ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE BIT_5 231 | #define ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE BIT_6 232 | 233 | #define CMAC_OOB_STOP 0x25 234 | #define CMAC_OOB_INIT 0x26 235 | #define CMAC_OOB_RESET 0x2a 236 | 237 | #define NO_BASE_ADDRESS 0x00000000 238 | #define RTL8168FP_OOBMAC_BASE 0xBAF70000 239 | #define RTL8168FP_CMAC_IOBASE 0xBAF20000 240 | #define RTL8168FP_KVM_BASE 0xBAF80400 241 | #define CMAC_SYNC_REG 0x20 242 | #define CMAC_RXDESC_OFFSET 0x90 //RX: 0x90 - 0x98 243 | #define CMAC_TXDESC_OFFSET 0x98 //TX: 0x98 - 0x9F 244 | 245 | /* cmac write/read MMIO register */ 246 | #define RTL_CMAC_W8(tp, reg, val8) writeb ((val8), tp->cmac_ioaddr + (reg)) 247 | #define RTL_CMAC_W16(tp, reg, val16) writew ((val16), tp->cmac_ioaddr + (reg)) 248 | #define RTL_CMAC_W32(tp, reg, val32) writel ((val32), tp->cmac_ioaddr + (reg)) 249 | #define RTL_CMAC_R8(tp, reg) readb (tp->cmac_ioaddr + (reg)) 250 | #define RTL_CMAC_R16(tp, reg) readw (tp->cmac_ioaddr + (reg)) 251 | #define RTL_CMAC_R32(tp, reg) ((unsigned long) readl (tp->cmac_ioaddr + (reg))) 252 | 253 | int rtl8168_dash_ioctl(struct net_device *dev, struct ifreq *ifr); 254 | bool CheckDashInterrupt(struct net_device *dev, u16 status); 255 | void HandleDashInterrupt(struct net_device *dev); 256 | int AllocateDashShareMemory(struct net_device *dev); 257 | void FreeAllocatedDashShareMemory(struct net_device *dev); 258 | void DashHwInit(struct net_device *dev); 259 | 260 | 261 | #endif /* _LINUX_R8168_DASH_H */ 262 | -------------------------------------------------------------------------------- /rtl_eeprom.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include 43 | 44 | #include "r8168.h" 45 | #include "rtl_eeprom.h" 46 | 47 | //------------------------------------------------------------------- 48 | //rtl8168_eeprom_type(): 49 | // tell the eeprom type 50 | //return value: 51 | // 0: the eeprom type is 93C46 52 | // 1: the eeprom type is 93C56 or 93C66 53 | //------------------------------------------------------------------- 54 | void rtl8168_eeprom_type(struct rtl8168_private *tp) 55 | { 56 | u16 magic = 0; 57 | 58 | if (tp->mcfg == CFG_METHOD_DEFAULT) 59 | goto out_no_eeprom; 60 | 61 | if(RTL_R8(tp, 0xD2)&0x04) { 62 | //not support 63 | //tp->eeprom_type = EEPROM_TWSI; 64 | //tp->eeprom_len = 256; 65 | goto out_no_eeprom; 66 | } else if(RTL_R32(tp, RxConfig) & RxCfg_9356SEL) { 67 | tp->eeprom_type = EEPROM_TYPE_93C56; 68 | tp->eeprom_len = 256; 69 | } else { 70 | tp->eeprom_type = EEPROM_TYPE_93C46; 71 | tp->eeprom_len = 128; 72 | } 73 | 74 | magic = rtl8168_eeprom_read_sc(tp, 0); 75 | 76 | out_no_eeprom: 77 | if ((magic != 0x8129) && (magic != 0x8128)) { 78 | tp->eeprom_type = EEPROM_TYPE_NONE; 79 | tp->eeprom_len = 0; 80 | } 81 | } 82 | 83 | void rtl8168_eeprom_cleanup(struct rtl8168_private *tp) 84 | { 85 | u8 x; 86 | 87 | x = RTL_R8(tp, Cfg9346); 88 | x &= ~(Cfg9346_EEDI | Cfg9346_EECS); 89 | 90 | RTL_W8(tp, Cfg9346, x); 91 | 92 | rtl8168_raise_clock(tp, &x); 93 | rtl8168_lower_clock(tp, &x); 94 | } 95 | 96 | static int rtl8168_eeprom_cmd_done(struct rtl8168_private *tp) 97 | { 98 | u8 x; 99 | int i; 100 | 101 | rtl8168_stand_by(tp); 102 | 103 | for (i = 0; i < 50000; i++) { 104 | x = RTL_R8(tp, Cfg9346); 105 | 106 | if (x & Cfg9346_EEDO) { 107 | fsleep(RTL_CLOCK_RATE * 2 * 3); 108 | return 0; 109 | } 110 | fsleep(1); 111 | } 112 | 113 | return -1; 114 | } 115 | 116 | //------------------------------------------------------------------- 117 | //rtl8168_eeprom_read_sc(): 118 | // read one word from eeprom 119 | //------------------------------------------------------------------- 120 | u16 rtl8168_eeprom_read_sc(struct rtl8168_private *tp, u16 reg) 121 | { 122 | int addr_sz = 6; 123 | u8 x; 124 | u16 data; 125 | 126 | if(tp->eeprom_type == EEPROM_TYPE_NONE) { 127 | return -1; 128 | } 129 | 130 | if (tp->eeprom_type==EEPROM_TYPE_93C46) 131 | addr_sz = 6; 132 | else if (tp->eeprom_type==EEPROM_TYPE_93C56) 133 | addr_sz = 8; 134 | 135 | x = Cfg9346_EEM1 | Cfg9346_EECS; 136 | RTL_W8(tp, Cfg9346, x); 137 | 138 | rtl8168_shift_out_bits(tp, RTL_EEPROM_READ_OPCODE, 3); 139 | rtl8168_shift_out_bits(tp, reg, addr_sz); 140 | 141 | data = rtl8168_shift_in_bits(tp); 142 | 143 | rtl8168_eeprom_cleanup(tp); 144 | 145 | RTL_W8(tp, Cfg9346, 0); 146 | 147 | return data; 148 | } 149 | 150 | //------------------------------------------------------------------- 151 | //rtl8168_eeprom_write_sc(): 152 | // write one word to a specific address in the eeprom 153 | //------------------------------------------------------------------- 154 | void rtl8168_eeprom_write_sc(struct rtl8168_private *tp, u16 reg, u16 data) 155 | { 156 | u8 x; 157 | int addr_sz = 6; 158 | int w_dummy_addr = 4; 159 | 160 | if(tp->eeprom_type == EEPROM_TYPE_NONE) 161 | return; 162 | 163 | if (tp->eeprom_type==EEPROM_TYPE_93C46) { 164 | addr_sz = 6; 165 | w_dummy_addr = 4; 166 | } else if (tp->eeprom_type==EEPROM_TYPE_93C56) { 167 | addr_sz = 8; 168 | w_dummy_addr = 6; 169 | } 170 | 171 | x = Cfg9346_EEM1 | Cfg9346_EECS; 172 | RTL_W8(tp, Cfg9346, x); 173 | 174 | rtl8168_shift_out_bits(tp, RTL_EEPROM_EWEN_OPCODE, 5); 175 | rtl8168_shift_out_bits(tp, reg, w_dummy_addr); 176 | rtl8168_stand_by(tp); 177 | 178 | rtl8168_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3); 179 | rtl8168_shift_out_bits(tp, reg, addr_sz); 180 | if (rtl8168_eeprom_cmd_done(tp) < 0) 181 | return; 182 | rtl8168_stand_by(tp); 183 | 184 | rtl8168_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3); 185 | rtl8168_shift_out_bits(tp, reg, addr_sz); 186 | rtl8168_shift_out_bits(tp, data, 16); 187 | if (rtl8168_eeprom_cmd_done(tp) < 0) 188 | return; 189 | rtl8168_stand_by(tp); 190 | 191 | rtl8168_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5); 192 | rtl8168_shift_out_bits(tp, reg, w_dummy_addr); 193 | 194 | rtl8168_eeprom_cleanup(tp); 195 | RTL_W8(tp, Cfg9346, 0); 196 | } 197 | 198 | void rtl8168_raise_clock(struct rtl8168_private *tp, u8 *x) 199 | { 200 | *x = *x | Cfg9346_EESK; 201 | RTL_W8(tp, Cfg9346, *x); 202 | fsleep(RTL_CLOCK_RATE); 203 | } 204 | 205 | void rtl8168_lower_clock(struct rtl8168_private *tp, u8 *x) 206 | { 207 | 208 | *x = *x & ~Cfg9346_EESK; 209 | RTL_W8(tp, Cfg9346, *x); 210 | fsleep(RTL_CLOCK_RATE); 211 | } 212 | 213 | void rtl8168_shift_out_bits(struct rtl8168_private *tp, int data, int count) 214 | { 215 | u8 x; 216 | int mask; 217 | 218 | mask = 0x01 << (count - 1); 219 | x = RTL_R8(tp, Cfg9346); 220 | x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); 221 | 222 | do { 223 | if (data & mask) 224 | x |= Cfg9346_EEDI; 225 | else 226 | x &= ~Cfg9346_EEDI; 227 | 228 | RTL_W8(tp, Cfg9346, x); 229 | fsleep(RTL_CLOCK_RATE); 230 | rtl8168_raise_clock(tp, &x); 231 | rtl8168_lower_clock(tp, &x); 232 | mask = mask >> 1; 233 | } while(mask); 234 | 235 | x &= ~Cfg9346_EEDI; 236 | RTL_W8(tp, Cfg9346, x); 237 | } 238 | 239 | u16 rtl8168_shift_in_bits(struct rtl8168_private *tp) 240 | { 241 | u8 x; 242 | u16 d, i; 243 | 244 | x = RTL_R8(tp, Cfg9346); 245 | x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); 246 | 247 | d = 0; 248 | 249 | for (i = 0; i < 16; i++) { 250 | d = d << 1; 251 | rtl8168_raise_clock(tp, &x); 252 | 253 | x = RTL_R8(tp, Cfg9346); 254 | x &= ~Cfg9346_EEDI; 255 | 256 | if (x & Cfg9346_EEDO) 257 | d |= 1; 258 | 259 | rtl8168_lower_clock(tp, &x); 260 | } 261 | 262 | return d; 263 | } 264 | 265 | void rtl8168_stand_by(struct rtl8168_private *tp) 266 | { 267 | u8 x; 268 | 269 | x = RTL_R8(tp, Cfg9346); 270 | x &= ~(Cfg9346_EECS | Cfg9346_EESK); 271 | RTL_W8(tp, Cfg9346, x); 272 | fsleep(RTL_CLOCK_RATE); 273 | 274 | x |= Cfg9346_EECS; 275 | RTL_W8(tp, Cfg9346, x); 276 | } 277 | 278 | void rtl8168_set_eeprom_sel_low(struct rtl8168_private *tp) 279 | { 280 | RTL_W8(tp, Cfg9346, Cfg9346_EEM1); 281 | RTL_W8(tp, Cfg9346, Cfg9346_EEM1 | Cfg9346_EESK); 282 | 283 | fsleep(20); 284 | 285 | RTL_W8(tp, Cfg9346, Cfg9346_EEM1); 286 | } 287 | -------------------------------------------------------------------------------- /r8168_firmware.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #include "r8168_firmware.h" 40 | 41 | enum rtl_fw_opcode { 42 | PHY_READ = 0x0, 43 | PHY_DATA_OR = 0x1, 44 | PHY_DATA_AND = 0x2, 45 | PHY_BJMPN = 0x3, 46 | PHY_MDIO_CHG = 0x4, 47 | PHY_CLEAR_READCOUNT = 0x7, 48 | PHY_WRITE = 0x8, 49 | PHY_READCOUNT_EQ_SKIP = 0x9, 50 | PHY_COMP_EQ_SKIPN = 0xa, 51 | PHY_COMP_NEQ_SKIPN = 0xb, 52 | PHY_WRITE_PREVIOUS = 0xc, 53 | PHY_SKIPN = 0xd, 54 | PHY_DELAY_MS = 0xe, 55 | }; 56 | 57 | struct fw_info { 58 | u32 magic; 59 | char version[RTL8168_VER_SIZE]; 60 | __le32 fw_start; 61 | __le32 fw_len; 62 | u8 chksum; 63 | } __packed; 64 | 65 | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0) 66 | #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) 67 | #endif 68 | #define FW_OPCODE_SIZE sizeof_field(struct rtl8168_fw_phy_action, code[0]) 69 | 70 | static bool rtl8168_fw_format_ok(struct rtl8168_fw *rtl_fw) 71 | { 72 | const struct firmware *fw = rtl_fw->fw; 73 | struct fw_info *fw_info = (struct fw_info *)fw->data; 74 | struct rtl8168_fw_phy_action *pa = &rtl_fw->phy_action; 75 | 76 | if (fw->size < FW_OPCODE_SIZE) 77 | return false; 78 | 79 | if (!fw_info->magic) { 80 | size_t i, size, start; 81 | u8 checksum = 0; 82 | 83 | if (fw->size < sizeof(*fw_info)) 84 | return false; 85 | 86 | for (i = 0; i < fw->size; i++) 87 | checksum += fw->data[i]; 88 | if (checksum != 0) 89 | return false; 90 | 91 | start = le32_to_cpu(fw_info->fw_start); 92 | if (start > fw->size) 93 | return false; 94 | 95 | size = le32_to_cpu(fw_info->fw_len); 96 | if (size > (fw->size - start) / FW_OPCODE_SIZE) 97 | return false; 98 | 99 | strscpy(rtl_fw->version, fw_info->version, RTL8168_VER_SIZE); 100 | 101 | pa->code = (__le32 *)(fw->data + start); 102 | pa->size = size; 103 | } else { 104 | if (fw->size % FW_OPCODE_SIZE) 105 | return false; 106 | 107 | strscpy(rtl_fw->version, rtl_fw->fw_name, RTL8168_VER_SIZE); 108 | 109 | pa->code = (__le32 *)fw->data; 110 | pa->size = fw->size / FW_OPCODE_SIZE; 111 | } 112 | 113 | return true; 114 | } 115 | 116 | static bool rtl8168_fw_data_ok(struct rtl8168_fw *rtl_fw) 117 | { 118 | struct rtl8168_fw_phy_action *pa = &rtl_fw->phy_action; 119 | size_t index; 120 | 121 | for (index = 0; index < pa->size; index++) { 122 | u32 action = le32_to_cpu(pa->code[index]); 123 | u32 val = action & 0x0000ffff; 124 | u32 regno = (action & 0x0fff0000) >> 16; 125 | 126 | switch (action >> 28) { 127 | case PHY_READ: 128 | case PHY_DATA_OR: 129 | case PHY_DATA_AND: 130 | case PHY_CLEAR_READCOUNT: 131 | case PHY_WRITE: 132 | case PHY_WRITE_PREVIOUS: 133 | case PHY_DELAY_MS: 134 | break; 135 | 136 | case PHY_MDIO_CHG: 137 | if (val > 1) 138 | goto out; 139 | break; 140 | 141 | case PHY_BJMPN: 142 | if (regno > index) 143 | goto out; 144 | break; 145 | case PHY_READCOUNT_EQ_SKIP: 146 | if (index + 2 >= pa->size) 147 | goto out; 148 | break; 149 | case PHY_COMP_EQ_SKIPN: 150 | case PHY_COMP_NEQ_SKIPN: 151 | case PHY_SKIPN: 152 | if (index + 1 + regno >= pa->size) 153 | goto out; 154 | break; 155 | 156 | default: 157 | dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action); 158 | return false; 159 | } 160 | } 161 | 162 | return true; 163 | out: 164 | dev_err(rtl_fw->dev, "Out of range of firmware\n"); 165 | return false; 166 | } 167 | 168 | void rtl8168_fw_write_firmware(struct rtl8168_private *tp, struct rtl8168_fw *rtl_fw) 169 | { 170 | struct rtl8168_fw_phy_action *pa = &rtl_fw->phy_action; 171 | rtl8168_fw_write_t fw_write = rtl_fw->phy_write; 172 | rtl8168_fw_read_t fw_read = rtl_fw->phy_read; 173 | int predata = 0, count = 0; 174 | size_t index; 175 | 176 | for (index = 0; index < pa->size; index++) { 177 | u32 action = le32_to_cpu(pa->code[index]); 178 | u32 data = action & 0x0000ffff; 179 | u32 regno = (action & 0x0fff0000) >> 16; 180 | enum rtl_fw_opcode opcode = action >> 28; 181 | 182 | if (!action) 183 | break; 184 | 185 | switch (opcode) { 186 | case PHY_READ: 187 | predata = fw_read(tp, regno); 188 | count++; 189 | break; 190 | case PHY_DATA_OR: 191 | predata |= data; 192 | break; 193 | case PHY_DATA_AND: 194 | predata &= data; 195 | break; 196 | case PHY_BJMPN: 197 | index -= (regno + 1); 198 | break; 199 | case PHY_MDIO_CHG: 200 | if (data) { 201 | fw_write = rtl_fw->mac_mcu_write; 202 | fw_read = rtl_fw->mac_mcu_read; 203 | } else { 204 | fw_write = rtl_fw->phy_write; 205 | fw_read = rtl_fw->phy_read; 206 | } 207 | 208 | break; 209 | case PHY_CLEAR_READCOUNT: 210 | count = 0; 211 | break; 212 | case PHY_WRITE: 213 | fw_write(tp, regno, data); 214 | break; 215 | case PHY_READCOUNT_EQ_SKIP: 216 | if (count == data) 217 | index++; 218 | break; 219 | case PHY_COMP_EQ_SKIPN: 220 | if (predata == data) 221 | index += regno; 222 | break; 223 | case PHY_COMP_NEQ_SKIPN: 224 | if (predata != data) 225 | index += regno; 226 | break; 227 | case PHY_WRITE_PREVIOUS: 228 | fw_write(tp, regno, predata); 229 | break; 230 | case PHY_SKIPN: 231 | index += regno; 232 | break; 233 | case PHY_DELAY_MS: 234 | mdelay(data); 235 | break; 236 | } 237 | } 238 | } 239 | 240 | void rtl8168_fw_release_firmware(struct rtl8168_fw *rtl_fw) 241 | { 242 | release_firmware(rtl_fw->fw); 243 | } 244 | 245 | int rtl8168_fw_request_firmware(struct rtl8168_fw *rtl_fw) 246 | { 247 | int rc; 248 | 249 | rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); 250 | if (rc < 0) 251 | goto out; 252 | 253 | if (!rtl8168_fw_format_ok(rtl_fw) || !rtl8168_fw_data_ok(rtl_fw)) { 254 | release_firmware(rtl_fw->fw); 255 | rc = -EINVAL; 256 | goto out; 257 | } 258 | 259 | return 0; 260 | out: 261 | dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n", 262 | rtl_fw->fw_name, rc); 263 | return rc; 264 | } 265 | -------------------------------------------------------------------------------- /r8168_asf.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #define SIOCDEVPRIVATE_RTLASF SIOCDEVPRIVATE 36 | 37 | #define FUNCTION_ENABLE 1 38 | #define FUNCTION_DISABLE 0 39 | 40 | #define ASFCONFIG 0 41 | #define ASFCAPABILITY 1 42 | #define ASFCOMMULEN 0 43 | #define ASFHBPERIOD 0 44 | #define ASFWD16RST 0 45 | #define ASFCAPMASK 0 46 | #define ASFALERTRESND 0 47 | #define ASFLSNRPOLLCYC 0 48 | #define ASFSNRPOLLCYC 0 49 | #define ASFWD8RESET 0 50 | #define ASFRWHEXNUM 0 51 | 52 | #define FMW_CAP_MASK 0x0000F867 53 | #define SPC_CMD_MASK 0x1F00 54 | #define SYS_CAP_MASK 0xFF 55 | #define DISABLE_MASK 0x00 56 | 57 | #define MAX_DATA_LEN 200 58 | #define MAX_STR_LEN 200 59 | 60 | #define COMMU_STR_MAX_LEN 23 61 | 62 | #define KEY_LEN 20 63 | #define UUID_LEN 16 64 | #define SYSID_LEN 2 65 | 66 | #define RW_ONE_BYTE 1 67 | #define RW_TWO_BYTES 2 68 | #define RW_FOUR_BYTES 4 69 | 70 | enum asf_registers { 71 | HBPeriod = 0x0000, 72 | WD8Rst = 0x0002, 73 | WD8Timer = 0x0003, 74 | WD16Rst = 0x0004, 75 | LSnsrPollCycle = 0x0006, 76 | ASFSnsrPollPrd = 0x0007, 77 | AlertReSendCnt = 0x0008, 78 | AlertReSendItvl = 0x0009, 79 | SMBAddr = 0x000A, 80 | SMBCap = 0x000B, 81 | ASFConfigR0 = 0x000C, 82 | ASFConfigR1 = 0x000D, 83 | WD16Timer = 0x000E, 84 | ConsoleMA = 0x0010, 85 | ConsoleIP = 0x0016, 86 | IPAddr = 0x001A, 87 | 88 | UUID = 0x0020, 89 | IANA = 0x0030, 90 | SysID = 0x0034, 91 | Community = 0x0036, 92 | StringLength = 0x004D, 93 | LC = 0x004E, 94 | EntityInst = 0x004F, 95 | FmCapMsk = 0x0050, 96 | SpCMDMsk = 0x0054, 97 | SysCapMsk = 0x0056, 98 | WDSysSt = 0x0057, 99 | RxMsgType = 0x0058, 100 | RxSpCMD = 0x0059, 101 | RxSpCMDPa = 0x005A, 102 | RxBtOpMsk = 0x005C, 103 | RmtRstAddr = 0x005E, 104 | RmtRstCmd = 0x005F, 105 | RmtRstData = 0x0060, 106 | RmtPwrOffAddr = 0x0061, 107 | RmtPwrOffCmd = 0x0062, 108 | RmtPwrOffData = 0x0063, 109 | RmtPwrOnAddr = 0x0064, 110 | RmtPwrOnCmd = 0x0065, 111 | RmtPwrOnData = 0x0066, 112 | RmtPCRAddr = 0x0067, 113 | RmtPCRCmd = 0x0068, 114 | RmtPCRData = 0x0069, 115 | RMCP_IANA = 0x006A, 116 | RMCP_OEM = 0x006E, 117 | ASFSnsr0Addr = 0x0070, 118 | 119 | ASFSnsrEvSt = 0x0073, 120 | ASFSnsrEvAlert = 0x0081, 121 | 122 | LSnsrNo = 0x00AD, 123 | AssrtEvntMsk = 0x00AE, 124 | DeAssrtEvntMsk = 0x00AF, 125 | 126 | LSnsrAddr0 = 0x00B0, 127 | LAlertCMD0 = 0x00B1, 128 | LAlertDataMsk0 = 0x00B2, 129 | LAlertCmp0 = 0x00B3, 130 | LAlertESnsrT0 = 0x00B4, 131 | LAlertET0 = 0x00B5, 132 | LAlertEOffset0 = 0x00B6, 133 | LAlertES0 = 0x00B7, 134 | LAlertSN0 = 0x00B8, 135 | LAlertEntity0 = 0x00B9, 136 | LAlertEI0 = 0x00BA, 137 | LSnsrState0 = 0x00BB, 138 | 139 | LSnsrAddr1 = 0x00BD, 140 | LAlertCMD1 = 0x00BE, 141 | LAlertDataMsk1 = 0x00BF, 142 | LAlertCmp1 = 0x00C0, 143 | LAlertESnsrT1 = 0x00C1, 144 | LAlertET1 = 0x00C2, 145 | LAlertEOffset1 = 0x00C3, 146 | LAlertES1 = 0x00C4, 147 | LAlertSN1 = 0x00C5, 148 | LAlertEntity1 = 0x00C6, 149 | LAlertEI1 = 0x00C7, 150 | LSnsrState1 = 0x00C8, 151 | 152 | LSnsrAddr2 = 0x00CA, 153 | LAlertCMD2 = 0x00CB, 154 | LAlertDataMsk2 = 0x00CC, 155 | LAlertCmp2 = 0x00CD, 156 | LAlertESnsrT2 = 0x00CE, 157 | LAlertET2 = 0x00CF, 158 | LAlertEOffset2 = 0x00D0, 159 | LAlertES2 = 0x00D1, 160 | LAlertSN2 = 0x00D2, 161 | LAlertEntity2 = 0x00D3, 162 | LAlertEI2 = 0x00D4, 163 | LSnsrState2 = 0x00D5, 164 | 165 | LSnsrAddr3 = 0x00D7, 166 | LAlertCMD3 = 0x00D8, 167 | LAlertDataMsk3 = 0x00D9, 168 | LAlertCmp3 = 0x00DA, 169 | LAlertESnsrT3 = 0x00DB, 170 | LAlertET3 = 0x00DC, 171 | LAlertEOffset3 = 0x00DD, 172 | LAlertES3 = 0x00DE, 173 | LAlertSN3 = 0x00DF, 174 | LAlertEntity3 = 0x00E0, 175 | LAlertEI3 = 0x00E1, 176 | LSnsrState3 = 0x00E2, 177 | 178 | LSnsrAddr4 = 0x00E4, 179 | LAlertCMD4 = 0x00E5, 180 | LAlertDataMsk4 = 0x00E6, 181 | LAlertCmp4 = 0x00E7, 182 | LAlertESnsrT4 = 0x00E8, 183 | LAlertET4 = 0x00E9, 184 | LAlertEOffset4 = 0x00EA, 185 | LAlertES4 = 0x00EB, 186 | LAlertSN4 = 0x00EC, 187 | LAlertEntity4 = 0x00ED, 188 | LAlertEI4 = 0x00EE, 189 | LSnsrState4 = 0x00EF, 190 | 191 | LSnsrAddr5 = 0x00F1, 192 | LAlertCMD5 = 0x00F2, 193 | LAlertDataMsk5 = 0x00F3, 194 | LAlertCmp5 = 0x00F4, 195 | LAlertESnsrT5 = 0x00F5, 196 | LAlertET5 = 0x00F6, 197 | LAlertEOffset5 = 0x00F7, 198 | LAlertES5 = 0x00F8, 199 | LAlertSN5 = 0x00F9, 200 | LAlertEntity5 = 0x00FA, 201 | LAlertEI5 = 0x00FB, 202 | LSnsrState5 = 0x00FC, 203 | 204 | LSnsrAddr6 = 0x00FE, 205 | LAlertCMD6 = 0x00FF, 206 | LAlertDataMsk6 = 0x0100, 207 | LAlertCmp6 = 0x0101, 208 | LAlertESnsrT6 = 0x0102, 209 | LAlertET6 = 0x0103, 210 | LAlertEOffset6 = 0x0104, 211 | LAlertES6 = 0x0105, 212 | LAlertSN6 = 0x0106, 213 | LAlertEntity6 = 0x0107, 214 | LAlertEI6 = 0x0108, 215 | LSnsrState6 = 0x0109, 216 | 217 | LSnsrAddr7 = 0x010B, 218 | LAlertCMD7 = 0x010C, 219 | LAlertDataMsk7 = 0x010D, 220 | LAlertCmp7 = 0x010E, 221 | LAlertESnsrT7 = 0x010F, 222 | LAlertET7 = 0x0110, 223 | LAlertEOffset7 = 0x0111, 224 | LAlertES7 = 0x0112, 225 | LAlertSN7 = 0x0113, 226 | LAlertEntity7 = 0x0114, 227 | LAlertEI7 = 0x0115, 228 | LSnsrState7 = 0x0116, 229 | LAssert = 0x0117, 230 | LDAssert = 0x0118, 231 | IPServiceType = 0x0119, 232 | IPIdfr = 0x011A, 233 | FlagFOffset = 0x011C, 234 | TTL = 0x011E, 235 | HbtEI = 0x011F, 236 | MgtConSID1 = 0x0120, 237 | MgtConSID2 = 0x0124, 238 | MgdCltSID = 0x0128, 239 | StCd = 0x012C, 240 | MgtConUR = 0x012D, 241 | MgtConUNL = 0x012E, 242 | 243 | AuthPd = 0x0130, 244 | IntyPd = 0x0138, 245 | MgtConRN = 0x0140, 246 | MgdCtlRN = 0x0150, 247 | MgtConUN = 0x0160, 248 | Rakp2IntCk = 0x0170, 249 | KO = 0x017C, 250 | KA = 0x0190, 251 | KG = 0x01A4, 252 | KR = 0x01B8, 253 | CP = 0x01CC, 254 | CQ = 0x01D0, 255 | KC = 0x01D4, 256 | ConsoleSid = 0x01E8, 257 | 258 | SIK1 = 0x01FC, 259 | SIK2 = 0x0210, 260 | Udpsrc_port = 0x0224, 261 | Udpdes_port = 0x0226, 262 | Asf_debug_mux = 0x0228 263 | }; 264 | 265 | enum asf_cmdln_opt { 266 | ASF_GET, 267 | ASF_SET, 268 | ASF_HELP 269 | }; 270 | 271 | struct asf_ioctl_struct { 272 | unsigned int arg; 273 | unsigned int offset; 274 | union { 275 | unsigned int data[MAX_DATA_LEN]; 276 | char string[MAX_STR_LEN]; 277 | } u; 278 | }; 279 | 280 | int rtl8168_asf_ioctl(struct net_device *dev, struct ifreq *ifr); 281 | void rtl8168_asf_hbperiod(struct rtl8168_private *tp, int arg, unsigned int *data); 282 | void rtl8168_asf_wd16rst(struct rtl8168_private *tp, int arg, unsigned int *data); 283 | void rtl8168_asf_console_mac(struct rtl8168_private *, int arg, unsigned int *data); 284 | void rtl8168_asf_ip_address(struct rtl8168_private *, int arg, int offset, unsigned int *data); 285 | void rtl8168_asf_config_regs(struct rtl8168_private *tp, int arg, int offset, unsigned int *data); 286 | void rtl8168_asf_capability_masks(struct rtl8168_private *tp, int arg, int offset, unsigned int *data); 287 | void rtl8168_asf_community_string(struct rtl8168_private *tp, int arg, char *string); 288 | void rtl8168_asf_community_string_len(struct rtl8168_private *tp, int arg, unsigned int *data); 289 | void rtl8168_asf_alert_resend_interval(struct rtl8168_private *tp, int arg, unsigned int *data); 290 | void rtl8168_asf_time_period(struct rtl8168_private *tp, int arg, int offset, unsigned int *data); 291 | void rtl8168_asf_key_access(struct rtl8168_private *, int arg, int offset, unsigned int *data); 292 | void rtl8168_asf_rw_hexadecimal(struct rtl8168_private *tp, int arg, int offset, int len, unsigned int *data); 293 | void rtl8168_asf_rw_iana(struct rtl8168_private *tp, int arg, unsigned int *data); 294 | void rtl8168_asf_rw_uuid(struct rtl8168_private *tp, int arg, unsigned int *data); 295 | void rtl8168_asf_rw_systemid(struct rtl8168_private *tp, int arg, unsigned int *data); 296 | -------------------------------------------------------------------------------- /rtltool.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include "r8168.h" 44 | #include "rtl_eeprom.h" 45 | #include "rtltool.h" 46 | 47 | int rtl8168_tool_ioctl(struct rtl8168_private *tp, struct ifreq *ifr) 48 | { 49 | struct rtltool_cmd my_cmd; 50 | int ret; 51 | 52 | if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd))) 53 | return -EFAULT; 54 | 55 | ret = 0; 56 | switch (my_cmd.cmd) { 57 | case RTLTOOL_READ_MAC: 58 | if ((my_cmd.offset + my_cmd.len) > R8168_REGS_SIZE) { 59 | ret = -EINVAL; 60 | break; 61 | } 62 | 63 | if (my_cmd.len==1) 64 | my_cmd.data = readb(tp->mmio_addr+my_cmd.offset); 65 | else if (my_cmd.len==2) 66 | my_cmd.data = readw(tp->mmio_addr+(my_cmd.offset&~1)); 67 | else if (my_cmd.len==4) 68 | my_cmd.data = readl(tp->mmio_addr+(my_cmd.offset&~3)); 69 | else { 70 | ret = -EOPNOTSUPP; 71 | break; 72 | } 73 | 74 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 75 | ret = -EFAULT; 76 | break; 77 | } 78 | break; 79 | case RTLTOOL_WRITE_MAC: 80 | if ((my_cmd.offset + my_cmd.len) > R8168_REGS_SIZE) { 81 | ret = -EINVAL; 82 | break; 83 | } 84 | 85 | if (my_cmd.len==1) 86 | writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset); 87 | else if (my_cmd.len==2) 88 | writew(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~1)); 89 | else if (my_cmd.len==4) 90 | writel(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~3)); 91 | else { 92 | ret = -EOPNOTSUPP; 93 | break; 94 | } 95 | break; 96 | case RTLTOOL_READ_PHY: 97 | my_cmd.data = rtl8168_mdio_prot_read(tp, my_cmd.offset); 98 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 99 | ret = -EFAULT; 100 | break; 101 | } 102 | break; 103 | case RTLTOOL_WRITE_PHY: 104 | rtl8168_mdio_prot_write(tp, my_cmd.offset, my_cmd.data); 105 | break; 106 | case RTLTOOL_READ_EPHY: 107 | my_cmd.data = rtl8168_ephy_read(tp, my_cmd.offset); 108 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 109 | ret = -EFAULT; 110 | break; 111 | } 112 | break; 113 | case RTLTOOL_WRITE_EPHY: 114 | rtl8168_ephy_write(tp, my_cmd.offset, my_cmd.data); 115 | break; 116 | case RTLTOOL_READ_ERI: 117 | my_cmd.data = 0; 118 | if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) { 119 | my_cmd.data = rtl8168_eri_read(tp, my_cmd.offset, my_cmd.len, ERIAR_ExGMAC); 120 | } else { 121 | ret = -EOPNOTSUPP; 122 | break; 123 | } 124 | 125 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 126 | ret = -EFAULT; 127 | break; 128 | } 129 | break; 130 | case RTLTOOL_WRITE_ERI: 131 | if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) { 132 | rtl8168_eri_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data, ERIAR_ExGMAC); 133 | } else { 134 | ret = -EOPNOTSUPP; 135 | break; 136 | } 137 | break; 138 | case RTLTOOL_READ_PCI: 139 | my_cmd.data = 0; 140 | if (my_cmd.len==1) 141 | pci_read_config_byte(tp->pci_dev, my_cmd.offset, 142 | (u8 *)&my_cmd.data); 143 | else if (my_cmd.len==2) 144 | pci_read_config_word(tp->pci_dev, my_cmd.offset, 145 | (u16 *)&my_cmd.data); 146 | else if (my_cmd.len==4) 147 | pci_read_config_dword(tp->pci_dev, my_cmd.offset, 148 | &my_cmd.data); 149 | else { 150 | ret = -EOPNOTSUPP; 151 | break; 152 | } 153 | 154 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 155 | ret = -EFAULT; 156 | break; 157 | } 158 | break; 159 | case RTLTOOL_WRITE_PCI: 160 | if (my_cmd.len==1) 161 | pci_write_config_byte(tp->pci_dev, my_cmd.offset, 162 | my_cmd.data); 163 | else if (my_cmd.len==2) 164 | pci_write_config_word(tp->pci_dev, my_cmd.offset, 165 | my_cmd.data); 166 | else if (my_cmd.len==4) 167 | pci_write_config_dword(tp->pci_dev, my_cmd.offset, 168 | my_cmd.data); 169 | else { 170 | ret = -EOPNOTSUPP; 171 | break; 172 | } 173 | break; 174 | case RTLTOOL_READ_EEPROM: 175 | my_cmd.data = rtl8168_eeprom_read_sc(tp, my_cmd.offset); 176 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 177 | ret = -EFAULT; 178 | break; 179 | } 180 | break; 181 | case RTLTOOL_WRITE_EEPROM: 182 | rtl8168_eeprom_write_sc(tp, my_cmd.offset, my_cmd.data); 183 | break; 184 | case RTL_READ_OOB_MAC: 185 | rtl8168_oob_mutex_lock(tp); 186 | my_cmd.data = rtl8168_ocp_read(tp, my_cmd.offset, 4); 187 | rtl8168_oob_mutex_unlock(tp); 188 | 189 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 190 | ret = -EFAULT; 191 | break; 192 | } 193 | break; 194 | case RTL_WRITE_OOB_MAC: 195 | if (my_cmd.len == 0 || my_cmd.len > 4) 196 | return -EOPNOTSUPP; 197 | 198 | rtl8168_oob_mutex_lock(tp); 199 | rtl8168_ocp_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data); 200 | rtl8168_oob_mutex_unlock(tp); 201 | break; 202 | case RTL_ENABLE_PCI_DIAG: 203 | tp->rtk_enable_diag = 1; 204 | dprintk("enable rtk diag\n"); 205 | break; 206 | case RTL_DISABLE_PCI_DIAG: 207 | tp->rtk_enable_diag = 0; 208 | dprintk("disable rtk diag\n"); 209 | break; 210 | case RTL_READ_MAC_OCP: 211 | if (my_cmd.offset % 2) 212 | return -EOPNOTSUPP; 213 | 214 | my_cmd.data = rtl8168_mac_ocp_read(tp, my_cmd.offset); 215 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 216 | ret = -EFAULT; 217 | break; 218 | } 219 | break; 220 | case RTL_WRITE_MAC_OCP: 221 | if ((my_cmd.offset % 2) || (my_cmd.len != 2)) 222 | return -EOPNOTSUPP; 223 | 224 | rtl8168_mac_ocp_write(tp, my_cmd.offset, (u16)my_cmd.data); 225 | break; 226 | case RTL_DIRECT_READ_PHY_OCP: 227 | my_cmd.data = rtl8168_mdio_prot_direct_read_phy_ocp(tp, my_cmd.offset); 228 | if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { 229 | ret = -EFAULT; 230 | break; 231 | } 232 | break; 233 | case RTL_DIRECT_WRITE_PHY_OCP: 234 | rtl8168_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data); 235 | break; 236 | default: 237 | ret = -EOPNOTSUPP; 238 | break; 239 | } 240 | 241 | return ret; 242 | } 243 | -------------------------------------------------------------------------------- /r8168_rss.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #include 36 | #include "r8168.h" 37 | 38 | enum rtl8168_rss_register_content { 39 | /* RSS */ 40 | RSS_CTRL_TCP_IPV4_SUPP = (1 << 0), 41 | RSS_CTRL_IPV4_SUPP = (1 << 1), 42 | RSS_CTRL_TCP_IPV6_SUPP = (1 << 2), 43 | RSS_CTRL_IPV6_SUPP = (1 << 3), 44 | RSS_CTRL_IPV6_EXT_SUPP = (1 << 4), 45 | RSS_CTRL_TCP_IPV6_EXT_SUPP = (1 << 5), 46 | RSS_HALF_SUPP = (1 << 7), 47 | RSS_QUAD_CPU_EN = (1 << 16), 48 | RSS_HQ_Q_SUP_R = (1 << 31), 49 | }; 50 | 51 | static int rtl8168_get_rss_hash_opts(struct rtl8168_private *tp, 52 | struct ethtool_rxnfc *cmd) 53 | { 54 | cmd->data = 0; 55 | 56 | /* Report default options for RSS */ 57 | switch (cmd->flow_type) { 58 | case TCP_V4_FLOW: 59 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 60 | fallthrough; 61 | case IPV4_FLOW: 62 | cmd->data |= RXH_IP_SRC | RXH_IP_DST; 63 | break; 64 | case TCP_V6_FLOW: 65 | cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 66 | fallthrough; 67 | case IPV6_FLOW: 68 | cmd->data |= RXH_IP_SRC | RXH_IP_DST; 69 | break; 70 | default: 71 | return -EINVAL; 72 | } 73 | 74 | return 0; 75 | } 76 | 77 | int rtl8168_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, 78 | u32 *rule_locs) 79 | { 80 | struct rtl8168_private *tp = netdev_priv(dev); 81 | int ret = -EOPNOTSUPP; 82 | 83 | if (!(dev->features & NETIF_F_RXHASH)) 84 | return ret; 85 | 86 | switch (cmd->cmd) { 87 | case ETHTOOL_GRXRINGS: 88 | cmd->data = rtl8168_tot_rx_rings(tp); 89 | ret = 0; 90 | break; 91 | case ETHTOOL_GRXFH: 92 | ret = rtl8168_get_rss_hash_opts(tp, cmd); 93 | break; 94 | default: 95 | break; 96 | } 97 | 98 | return ret; 99 | } 100 | 101 | u32 rtl8168_rss_indir_tbl_entries(struct rtl8168_private *tp) 102 | { 103 | return tp->HwSuppIndirTblEntries; 104 | } 105 | 106 | #define RSS_MASK_BITS_OFFSET (8) 107 | static int _rtl8168_set_rss_hash_opt(struct rtl8168_private *tp) 108 | { 109 | u32 hash_mask_len; 110 | u32 rss_ctrl; 111 | 112 | /* Perform hash on these packet types */ 113 | rss_ctrl = RSS_CTRL_TCP_IPV4_SUPP 114 | | RSS_CTRL_IPV4_SUPP 115 | | RSS_CTRL_IPV6_SUPP 116 | | RSS_CTRL_IPV6_EXT_SUPP 117 | | RSS_CTRL_TCP_IPV6_SUPP 118 | | RSS_CTRL_TCP_IPV6_EXT_SUPP; 119 | 120 | if (R8168_MULTI_RSS_4Q(tp)) 121 | rss_ctrl |= RSS_QUAD_CPU_EN; 122 | 123 | hash_mask_len = ilog2(rtl8168_rss_indir_tbl_entries(tp)); 124 | hash_mask_len &= (BIT_0 | BIT_1 | BIT_2); 125 | rss_ctrl |= hash_mask_len << RSS_MASK_BITS_OFFSET; 126 | 127 | rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC); 128 | 129 | return 0; 130 | } 131 | 132 | static int rtl8168_set_rss_hash_opt(struct rtl8168_private *tp, 133 | struct ethtool_rxnfc *nfc) 134 | { 135 | u32 rss_flags = tp->rss_flags; 136 | 137 | /* 138 | * RSS does not support anything other than hashing 139 | * to queues on src and dst IPs and ports 140 | */ 141 | if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | 142 | RXH_L4_B_0_1 | RXH_L4_B_2_3)) 143 | return -EINVAL; 144 | 145 | switch (nfc->flow_type) { 146 | case TCP_V4_FLOW: 147 | case TCP_V6_FLOW: 148 | if (!(nfc->data & RXH_IP_SRC) || 149 | !(nfc->data & RXH_IP_DST) || 150 | !(nfc->data & RXH_L4_B_0_1) || 151 | !(nfc->data & RXH_L4_B_2_3)) 152 | return -EINVAL; 153 | break; 154 | case SCTP_V4_FLOW: 155 | case AH_ESP_V4_FLOW: 156 | case AH_V4_FLOW: 157 | case ESP_V4_FLOW: 158 | case SCTP_V6_FLOW: 159 | case AH_ESP_V6_FLOW: 160 | case AH_V6_FLOW: 161 | case ESP_V6_FLOW: 162 | case IP_USER_FLOW: 163 | case ETHER_FLOW: 164 | /* RSS is not supported for these protocols */ 165 | if (nfc->data) { 166 | netif_err(tp, drv, tp->dev, "Command parameters not supported\n"); 167 | return -EINVAL; 168 | } 169 | return 0; 170 | default: 171 | return -EINVAL; 172 | } 173 | 174 | /* if we changed something we need to update flags */ 175 | if (rss_flags != tp->rss_flags) { 176 | u32 rss_ctrl = rtl8168_eri_read(tp, RSS_CTRL_8168, 4, ERIAR_ExGMAC); 177 | 178 | tp->rss_flags = rss_flags; 179 | 180 | /* Perform hash on these packet types */ 181 | rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP 182 | | RSS_CTRL_IPV4_SUPP 183 | | RSS_CTRL_IPV6_SUPP 184 | | RSS_CTRL_IPV6_EXT_SUPP 185 | | RSS_CTRL_TCP_IPV6_SUPP 186 | | RSS_CTRL_TCP_IPV6_EXT_SUPP; 187 | 188 | if (R8168_MULTI_RSS_4Q(tp)) 189 | rss_ctrl |= RSS_QUAD_CPU_EN; 190 | else 191 | rss_ctrl &= ~RSS_QUAD_CPU_EN; 192 | 193 | rtl8168_eri_write(tp, RSS_CTRL_8168, 4, rss_ctrl, ERIAR_ExGMAC); 194 | } 195 | 196 | return 0; 197 | } 198 | 199 | int rtl8168_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) 200 | { 201 | struct rtl8168_private *tp = netdev_priv(dev); 202 | int ret = -EOPNOTSUPP; 203 | 204 | if (!(dev->features & NETIF_F_RXHASH)) 205 | return ret; 206 | 207 | switch (cmd->cmd) { 208 | case ETHTOOL_SRXFH: 209 | ret = rtl8168_set_rss_hash_opt(tp, cmd); 210 | break; 211 | default: 212 | break; 213 | } 214 | 215 | return ret; 216 | } 217 | 218 | static u32 _rtl8168_get_rxfh_key_size(struct rtl8168_private *tp) 219 | { 220 | return sizeof(tp->rss_key); 221 | } 222 | 223 | u32 rtl8168_get_rxfh_key_size(struct net_device *dev) 224 | { 225 | struct rtl8168_private *tp = netdev_priv(dev); 226 | 227 | if (!(dev->features & NETIF_F_RXHASH)) 228 | return 0; 229 | 230 | return _rtl8168_get_rxfh_key_size(tp); 231 | } 232 | 233 | u32 rtl8168_rss_indir_size(struct net_device *dev) 234 | { 235 | struct rtl8168_private *tp = netdev_priv(dev); 236 | 237 | if (!(dev->features & NETIF_F_RXHASH)) 238 | return 0; 239 | 240 | return rtl8168_rss_indir_tbl_entries(tp); 241 | } 242 | 243 | static void rtl8168_get_reta(struct rtl8168_private *tp, u32 *indir) 244 | { 245 | int i, reta_size = rtl8168_rss_indir_tbl_entries(tp); 246 | 247 | for (i = 0; i < reta_size; i++) 248 | indir[i] = tp->rss_indir_tbl[i]; 249 | } 250 | 251 | static u32 rtl8168_rss_key_reg(struct rtl8168_private *tp) 252 | { 253 | return RSS_KEY_8168; 254 | } 255 | 256 | static u32 rtl8168_rss_indir_tbl_reg(struct rtl8168_private *tp) 257 | { 258 | return Rss_indir_tbl; 259 | } 260 | 261 | static void rtl8168_store_reta(struct rtl8168_private *tp) 262 | { 263 | u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp); 264 | u16 indir_tbl_reg = rtl8168_rss_indir_tbl_reg(tp); 265 | u32 hw_indir[RTL8168_RSS_INDIR_TBL_SIZE] = {0}; 266 | u8 *indir = tp->rss_indir_tbl; 267 | u32 bit_on_cnt = 0x00000001; 268 | u32 i, j; 269 | 270 | /* Mapping redirection table to HW */ 271 | for (i = 0, j = 0; i < reta_entries; i++) { 272 | if ((indir[i] & 2) && R8168_MULTI_RSS_4Q(tp)) 273 | hw_indir[j + 4] |= bit_on_cnt; 274 | if (indir[i] & 1) 275 | hw_indir[j] |= bit_on_cnt; 276 | 277 | if (bit_on_cnt == 0x80000000) { 278 | bit_on_cnt = 0x00000001; 279 | j++; 280 | continue; 281 | } 282 | bit_on_cnt <<= 1; 283 | } 284 | 285 | /* Write redirection table to HW */ 286 | for (i = 0; i < RTL8168_RSS_INDIR_TBL_SIZE; i++) 287 | RTL_W32(tp, indir_tbl_reg + i*4, hw_indir[i]); 288 | } 289 | 290 | static void rtl8168_store_rss_key(struct rtl8168_private *tp) 291 | { 292 | const u16 rss_key_reg = rtl8168_rss_key_reg(tp); 293 | u32 i, rss_key_size = _rtl8168_get_rxfh_key_size(tp); 294 | u32 *rss_key = (u32*)tp->rss_key; 295 | 296 | /* Write redirection table to HW */ 297 | for (i = 0; i < rss_key_size; i+=4) 298 | rtl8168_eri_write(tp, rss_key_reg + i, 4, *rss_key++, ERIAR_ExGMAC); 299 | } 300 | 301 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) 302 | int rtl8168_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh) 303 | { 304 | struct rtl8168_private *tp = netdev_priv(dev); 305 | 306 | if (!(dev->features & NETIF_F_RXHASH)) 307 | return -EOPNOTSUPP; 308 | 309 | rxfh->hfunc = ETH_RSS_HASH_TOP; 310 | 311 | if (rxfh->indir) 312 | rtl8168_get_reta(tp, rxfh->indir); 313 | 314 | if (rxfh->key) 315 | memcpy(rxfh->key, tp->rss_key, RTL8168_RSS_KEY_SIZE); 316 | 317 | return 0; 318 | } 319 | 320 | int rtl8168_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh, 321 | struct netlink_ext_ack *extack) 322 | { 323 | struct rtl8168_private *tp = netdev_priv(dev); 324 | u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp); 325 | int i; 326 | 327 | /* We require at least one supported parameter to be changed and no 328 | * change in any of the unsupported parameters 329 | */ 330 | if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && rxfh->hfunc != ETH_RSS_HASH_TOP) 331 | return -EOPNOTSUPP; 332 | 333 | /* Fill out the redirection table */ 334 | if (rxfh->indir) { 335 | int max_queues = tp->num_rx_rings; 336 | 337 | /* Verify user input. */ 338 | for (i = 0; i < reta_entries; i++) 339 | if (rxfh->indir[i] >= max_queues) 340 | return -EINVAL; 341 | 342 | for (i = 0; i < reta_entries; i++) 343 | tp->rss_indir_tbl[i] = rxfh->indir[i]; 344 | } 345 | 346 | /* Fill out the rss hash key */ 347 | if (rxfh->key) 348 | memcpy(tp->rss_key, rxfh->key, RTL8168_RSS_KEY_SIZE); 349 | 350 | rtl8168_store_reta(tp); 351 | 352 | rtl8168_store_rss_key(tp); 353 | 354 | return 0; 355 | } 356 | #else 357 | int rtl8168_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, 358 | u8 *hfunc) 359 | { 360 | struct rtl8168_private *tp = netdev_priv(dev); 361 | 362 | if (!(dev->features & NETIF_F_RXHASH)) 363 | return -EOPNOTSUPP; 364 | 365 | if (hfunc) 366 | *hfunc = ETH_RSS_HASH_TOP; 367 | 368 | if (indir) 369 | rtl8168_get_reta(tp, indir); 370 | 371 | if (key) 372 | memcpy(key, tp->rss_key, RTL8168_RSS_KEY_SIZE); 373 | 374 | return 0; 375 | } 376 | 377 | int rtl8168_set_rxfh(struct net_device *dev, const u32 *indir, 378 | const u8 *key, const u8 hfunc) 379 | { 380 | struct rtl8168_private *tp = netdev_priv(dev); 381 | u32 reta_entries = rtl8168_rss_indir_tbl_entries(tp); 382 | int i; 383 | 384 | /* We require at least one supported parameter to be changed and no 385 | * change in any of the unsupported parameters 386 | */ 387 | if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) 388 | return -EOPNOTSUPP; 389 | 390 | /* Fill out the redirection table */ 391 | if (indir) { 392 | int max_queues = tp->num_rx_rings; 393 | 394 | /* Verify user input. */ 395 | for (i = 0; i < reta_entries; i++) 396 | if (indir[i] >= max_queues) 397 | return -EINVAL; 398 | 399 | for (i = 0; i < reta_entries; i++) 400 | tp->rss_indir_tbl[i] = indir[i]; 401 | } 402 | 403 | /* Fill out the rss hash key */ 404 | if (key) 405 | memcpy(tp->rss_key, key, RTL8168_RSS_KEY_SIZE); 406 | 407 | rtl8168_store_reta(tp); 408 | 409 | rtl8168_store_rss_key(tp); 410 | 411 | return 0; 412 | } 413 | #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6,8,0) */ 414 | 415 | static u32 rtl8168_get_rx_desc_hash(struct rtl8168_private *tp, 416 | struct RxDescV2 *desc) 417 | { 418 | if (!desc->RSSResult) 419 | fsleep(1); 420 | return le32_to_cpu(desc->RSSResult); 421 | } 422 | 423 | #define RXS_8168_RSS_IPV4 BIT(17) 424 | #define RXS_8168_RSS_IPV6 BIT(18) 425 | #define RXS_8168_RSS_TCP BIT(19) 426 | #define RTL8168_RXS_RSS_L3_TYPE_MASK (RXS_8168_RSS_IPV4 | RXS_8168_RSS_IPV6) 427 | #define RTL8168_RXS_RSS_L4_TYPE_MASK (RXS_8168_RSS_TCP) 428 | void rtl8168_rx_hash(struct rtl8168_private *tp, 429 | struct RxDescV2 *desc, 430 | struct sk_buff *skb) 431 | { 432 | u32 rss_header_info; 433 | 434 | if (!(tp->dev->features & NETIF_F_RXHASH)) 435 | return; 436 | 437 | rss_header_info = le32_to_cpu(desc->opts2); 438 | 439 | if (!(rss_header_info & RTL8168_RXS_RSS_L3_TYPE_MASK)) 440 | return; 441 | 442 | skb_set_hash(skb, rtl8168_get_rx_desc_hash(tp, desc), 443 | (RTL8168_RXS_RSS_L4_TYPE_MASK & rss_header_info) ? 444 | PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); 445 | } 446 | 447 | void rtl8168_disable_rss(struct rtl8168_private *tp) 448 | { 449 | rtl8168_eri_write(tp, RSS_CTRL_8168, 4, 0x00000000, ERIAR_ExGMAC); 450 | } 451 | 452 | void _rtl8168_config_rss(struct rtl8168_private *tp) 453 | { 454 | _rtl8168_set_rss_hash_opt(tp); 455 | 456 | rtl8168_store_reta(tp); 457 | 458 | rtl8168_store_rss_key(tp); 459 | } 460 | 461 | void rtl8168_config_rss(struct rtl8168_private *tp) 462 | { 463 | if (!HW_RSS_SUPPORT_RSS(tp)) 464 | return; 465 | 466 | if (!tp->EnableRss) { 467 | rtl8168_disable_rss(tp); 468 | return; 469 | } 470 | 471 | _rtl8168_config_rss(tp); 472 | } 473 | 474 | void rtl8168_init_rss(struct rtl8168_private *tp) 475 | { 476 | int i; 477 | 478 | for (i = 0; i < rtl8168_rss_indir_tbl_entries(tp); i++) 479 | tp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, tp->num_rx_rings); 480 | 481 | netdev_rss_key_fill(tp->rss_key, RTL8168_RSS_KEY_SIZE); 482 | } 483 | -------------------------------------------------------------------------------- /r8168_asf.c: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | 51 | #include 52 | 53 | #include "r8168.h" 54 | #include "r8168_asf.h" 55 | #include "rtl_eeprom.h" 56 | 57 | int rtl8168_asf_ioctl(struct net_device *dev, 58 | struct ifreq *ifr) 59 | { 60 | struct rtl8168_private *tp = netdev_priv(dev); 61 | void *user_data = ifr->ifr_data; 62 | struct asf_ioctl_struct asf_usrdata; 63 | 64 | if (tp->mcfg != CFG_METHOD_7 && tp->mcfg != CFG_METHOD_8) 65 | return -EOPNOTSUPP; 66 | 67 | if (copy_from_user(&asf_usrdata, user_data, sizeof(struct asf_ioctl_struct))) 68 | return -EFAULT; 69 | 70 | switch (asf_usrdata.offset) { 71 | case HBPeriod: 72 | rtl8168_asf_hbperiod(tp, asf_usrdata.arg, asf_usrdata.u.data); 73 | break; 74 | case WD8Timer: 75 | break; 76 | case WD16Rst: 77 | rtl8168_asf_wd16rst(tp, asf_usrdata.arg, asf_usrdata.u.data); 78 | break; 79 | case WD8Rst: 80 | rtl8168_asf_time_period(tp, asf_usrdata.arg, WD8Rst, asf_usrdata.u.data); 81 | break; 82 | case LSnsrPollCycle: 83 | rtl8168_asf_time_period(tp, asf_usrdata.arg, LSnsrPollCycle, asf_usrdata.u.data); 84 | break; 85 | case ASFSnsrPollPrd: 86 | rtl8168_asf_time_period(tp, asf_usrdata.arg, ASFSnsrPollPrd, asf_usrdata.u.data); 87 | break; 88 | case AlertReSendItvl: 89 | rtl8168_asf_time_period(tp, asf_usrdata.arg, AlertReSendItvl, asf_usrdata.u.data); 90 | break; 91 | case SMBAddr: 92 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, SMBAddr, RW_ONE_BYTE, asf_usrdata.u.data); 93 | break; 94 | case ASFConfigR0: 95 | rtl8168_asf_config_regs(tp, asf_usrdata.arg, ASFConfigR0, asf_usrdata.u.data); 96 | break; 97 | case ASFConfigR1: 98 | rtl8168_asf_config_regs(tp, asf_usrdata.arg, ASFConfigR1, asf_usrdata.u.data); 99 | break; 100 | case ConsoleMA: 101 | rtl8168_asf_console_mac(tp, asf_usrdata.arg, asf_usrdata.u.data); 102 | break; 103 | case ConsoleIP: 104 | rtl8168_asf_ip_address(tp, asf_usrdata.arg, ConsoleIP, asf_usrdata.u.data); 105 | break; 106 | case IPAddr: 107 | rtl8168_asf_ip_address(tp, asf_usrdata.arg, IPAddr, asf_usrdata.u.data); 108 | break; 109 | case UUID: 110 | rtl8168_asf_rw_uuid(tp, asf_usrdata.arg, asf_usrdata.u.data); 111 | break; 112 | case IANA: 113 | rtl8168_asf_rw_iana(tp, asf_usrdata.arg, asf_usrdata.u.data); 114 | break; 115 | case SysID: 116 | rtl8168_asf_rw_systemid(tp, asf_usrdata.arg, asf_usrdata.u.data); 117 | break; 118 | case Community: 119 | rtl8168_asf_community_string(tp, asf_usrdata.arg, asf_usrdata.u.string); 120 | break; 121 | case StringLength: 122 | rtl8168_asf_community_string_len(tp, asf_usrdata.arg, asf_usrdata.u.data); 123 | break; 124 | case FmCapMsk: 125 | rtl8168_asf_capability_masks(tp, asf_usrdata.arg, FmCapMsk, asf_usrdata.u.data); 126 | break; 127 | case SpCMDMsk: 128 | rtl8168_asf_capability_masks(tp, asf_usrdata.arg, SpCMDMsk, asf_usrdata.u.data); 129 | break; 130 | case SysCapMsk: 131 | rtl8168_asf_capability_masks(tp, asf_usrdata.arg, SysCapMsk, asf_usrdata.u.data); 132 | break; 133 | case RmtRstAddr: 134 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtRstAddr, RW_ONE_BYTE, asf_usrdata.u.data); 135 | break; 136 | case RmtRstCmd: 137 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtRstCmd, RW_ONE_BYTE, asf_usrdata.u.data); 138 | break; 139 | case RmtRstData: 140 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtRstData, RW_ONE_BYTE, asf_usrdata.u.data); 141 | break; 142 | case RmtPwrOffAddr: 143 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOffAddr, RW_ONE_BYTE, asf_usrdata.u.data); 144 | break; 145 | case RmtPwrOffCmd: 146 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOffCmd, RW_ONE_BYTE, asf_usrdata.u.data); 147 | break; 148 | case RmtPwrOffData: 149 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOffData, RW_ONE_BYTE, asf_usrdata.u.data); 150 | break; 151 | case RmtPwrOnAddr: 152 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOnAddr, RW_ONE_BYTE, asf_usrdata.u.data); 153 | break; 154 | case RmtPwrOnCmd: 155 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOnCmd, RW_ONE_BYTE, asf_usrdata.u.data); 156 | break; 157 | case RmtPwrOnData: 158 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPwrOnData, RW_ONE_BYTE, asf_usrdata.u.data); 159 | break; 160 | case RmtPCRAddr: 161 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPCRAddr, RW_ONE_BYTE, asf_usrdata.u.data); 162 | break; 163 | case RmtPCRCmd: 164 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPCRCmd, RW_ONE_BYTE, asf_usrdata.u.data); 165 | break; 166 | case RmtPCRData: 167 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, RmtPCRData, RW_ONE_BYTE, asf_usrdata.u.data); 168 | break; 169 | case ASFSnsr0Addr: 170 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, ASFSnsr0Addr, RW_ONE_BYTE, asf_usrdata.u.data); 171 | break; 172 | case LSnsrAddr0: 173 | rtl8168_asf_rw_hexadecimal(tp, asf_usrdata.arg, LSnsrAddr0, RW_ONE_BYTE, asf_usrdata.u.data); 174 | break; 175 | case KO: 176 | /* Get/Set Key Operation */ 177 | rtl8168_asf_key_access(tp, asf_usrdata.arg, KO, asf_usrdata.u.data); 178 | break; 179 | case KA: 180 | /* Get/Set Key Administrator */ 181 | rtl8168_asf_key_access(tp, asf_usrdata.arg, KA, asf_usrdata.u.data); 182 | break; 183 | case KG: 184 | /* Get/Set Key Generation */ 185 | rtl8168_asf_key_access(tp, asf_usrdata.arg, KG, asf_usrdata.u.data); 186 | break; 187 | case KR: 188 | /* Get/Set Key Random */ 189 | rtl8168_asf_key_access(tp, asf_usrdata.arg, KR, asf_usrdata.u.data); 190 | break; 191 | default: 192 | return -EOPNOTSUPP; 193 | } 194 | 195 | if (copy_to_user(user_data, &asf_usrdata, sizeof(struct asf_ioctl_struct))) 196 | return -EFAULT; 197 | 198 | return 0; 199 | } 200 | 201 | void rtl8168_asf_hbperiod(struct rtl8168_private *tp, int arg, unsigned int *data) 202 | { 203 | if (arg == ASF_GET) 204 | data[ASFHBPERIOD] = rtl8168_eri_read(tp, HBPeriod, RW_TWO_BYTES, ERIAR_ASF); 205 | else if (arg == ASF_SET) { 206 | rtl8168_eri_write(tp, HBPeriod, RW_TWO_BYTES, data[ASFHBPERIOD], ERIAR_ASF); 207 | rtl8168_eri_write(tp, 0x1EC, RW_ONE_BYTE, 0x07, ERIAR_ASF); 208 | } 209 | } 210 | 211 | void rtl8168_asf_wd16rst(struct rtl8168_private *tp, int arg, unsigned int *data) 212 | { 213 | data[ASFWD16RST] = rtl8168_eri_read(tp, WD16Rst, RW_TWO_BYTES, ERIAR_ASF); 214 | } 215 | 216 | void rtl8168_asf_console_mac(struct rtl8168_private *tp, int arg, unsigned int *data) 217 | { 218 | int i; 219 | 220 | if (arg == ASF_GET) { 221 | for (i = 0; i < 6; i++) 222 | data[i] = rtl8168_eri_read(tp, ConsoleMA + i, RW_ONE_BYTE, ERIAR_ASF); 223 | } else if (arg == ASF_SET) { 224 | for (i = 0; i < 6; i++) 225 | rtl8168_eri_write(tp, ConsoleMA + i, RW_ONE_BYTE, data[i], ERIAR_ASF); 226 | 227 | /* write the new console MAC address to EEPROM */ 228 | rtl8168_eeprom_write_sc(tp, 70, (data[1] << 8) | data[0]); 229 | rtl8168_eeprom_write_sc(tp, 71, (data[3] << 8) | data[2]); 230 | rtl8168_eeprom_write_sc(tp, 72, (data[5] << 8) | data[4]); 231 | } 232 | } 233 | 234 | void rtl8168_asf_ip_address(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) 235 | { 236 | int i; 237 | int eeprom_off = 0; 238 | 239 | if (arg == ASF_GET) { 240 | for (i = 0; i < 4; i++) 241 | data[i] = rtl8168_eri_read(tp, offset + i, RW_ONE_BYTE, ERIAR_ASF); 242 | } else if (arg == ASF_SET) { 243 | for (i = 0; i < 4; i++) 244 | rtl8168_eri_write(tp, offset + i, RW_ONE_BYTE, data[i], ERIAR_ASF); 245 | 246 | if (offset == ConsoleIP) 247 | eeprom_off = 73; 248 | else if (offset == IPAddr) 249 | eeprom_off = 75; 250 | 251 | /* write the new IP address to EEPROM */ 252 | rtl8168_eeprom_write_sc(tp, eeprom_off, (data[1] << 8) | data[0]); 253 | rtl8168_eeprom_write_sc(tp, eeprom_off + 1, (data[3] << 8) | data[2]); 254 | 255 | } 256 | } 257 | 258 | void rtl8168_asf_config_regs(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) 259 | { 260 | unsigned int value; 261 | 262 | if (arg == ASF_GET) { 263 | data[ASFCAPABILITY] = (rtl8168_eri_read(tp, offset, RW_ONE_BYTE, ERIAR_ASF) & data[ASFCONFIG]) ? FUNCTION_ENABLE : FUNCTION_DISABLE; 264 | } else if (arg == ASF_SET) { 265 | value = rtl8168_eri_read(tp, offset, RW_ONE_BYTE, ERIAR_ASF); 266 | 267 | if (data[ASFCAPABILITY] == FUNCTION_ENABLE) 268 | value |= data[ASFCONFIG]; 269 | else if (data[ASFCAPABILITY] == FUNCTION_DISABLE) 270 | value &= ~data[ASFCONFIG]; 271 | 272 | rtl8168_eri_write(tp, offset, RW_ONE_BYTE, value, ERIAR_ASF); 273 | } 274 | } 275 | 276 | void rtl8168_asf_capability_masks(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) 277 | { 278 | unsigned int len, bit_mask; 279 | 280 | bit_mask = DISABLE_MASK; 281 | 282 | if (offset == FmCapMsk) { 283 | /* System firmware capabilities */ 284 | len = RW_FOUR_BYTES; 285 | if (data[ASFCAPMASK] == FUNCTION_ENABLE) 286 | bit_mask = FMW_CAP_MASK; 287 | } else if (offset == SpCMDMsk) { 288 | /* Special commands */ 289 | len = RW_TWO_BYTES; 290 | if (data[ASFCAPMASK] == FUNCTION_ENABLE) 291 | bit_mask = SPC_CMD_MASK; 292 | } else { 293 | /* System capability (offset == SysCapMsk)*/ 294 | len = RW_ONE_BYTE; 295 | if (data[ASFCAPMASK] == FUNCTION_ENABLE) 296 | bit_mask = SYS_CAP_MASK; 297 | } 298 | 299 | if (arg == ASF_GET) 300 | data[ASFCAPMASK] = rtl8168_eri_read(tp, offset, len, ERIAR_ASF) ? FUNCTION_ENABLE : FUNCTION_DISABLE; 301 | else /* arg == ASF_SET */ 302 | rtl8168_eri_write(tp, offset, len, bit_mask, ERIAR_ASF); 303 | } 304 | 305 | void rtl8168_asf_community_string(struct rtl8168_private *tp, int arg, char *string) 306 | { 307 | int i; 308 | 309 | if (arg == ASF_GET) { 310 | for (i = 0; i < COMMU_STR_MAX_LEN; i++) 311 | string[i] = rtl8168_eri_read(tp, Community + i, RW_ONE_BYTE, ERIAR_ASF); 312 | } else { /* arg == ASF_SET */ 313 | for (i = 0; i < COMMU_STR_MAX_LEN; i++) 314 | rtl8168_eri_write(tp, Community + i, RW_ONE_BYTE, string[i], ERIAR_ASF); 315 | } 316 | } 317 | 318 | void rtl8168_asf_community_string_len(struct rtl8168_private *tp, int arg, unsigned int *data) 319 | { 320 | if (arg == ASF_GET) 321 | data[ASFCOMMULEN] = rtl8168_eri_read(tp, StringLength, RW_ONE_BYTE, ERIAR_ASF); 322 | else /* arg == ASF_SET */ 323 | rtl8168_eri_write(tp, StringLength, RW_ONE_BYTE, data[ASFCOMMULEN], ERIAR_ASF); 324 | } 325 | 326 | void rtl8168_asf_time_period(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) 327 | { 328 | int pos = 0; 329 | 330 | if (offset == WD8Rst) 331 | pos = ASFWD8RESET; 332 | else if (offset == LSnsrPollCycle) 333 | pos = ASFLSNRPOLLCYC; 334 | else if (offset == ASFSnsrPollPrd) 335 | pos = ASFSNRPOLLCYC; 336 | else if (offset == AlertReSendItvl) 337 | pos = ASFALERTRESND; 338 | 339 | if (arg == ASF_GET) 340 | data[pos] = rtl8168_eri_read(tp, offset, RW_ONE_BYTE, ERIAR_ASF); 341 | else /* arg == ASF_SET */ 342 | rtl8168_eri_write(tp, offset, RW_ONE_BYTE, data[pos], ERIAR_ASF); 343 | 344 | } 345 | 346 | void rtl8168_asf_key_access(struct rtl8168_private *tp, int arg, int offset, unsigned int *data) 347 | { 348 | int i, j; 349 | int key_off = 0; 350 | 351 | if (arg == ASF_GET) { 352 | for (i = 0; i < KEY_LEN; i++) 353 | data[i] = rtl8168_eri_read(tp, offset + KEY_LEN - (i + 1), RW_ONE_BYTE, ERIAR_ASF); 354 | } else { 355 | if (offset == KO) 356 | key_off = 162; 357 | else if (offset == KA) 358 | key_off = 172; 359 | else if (offset == KG) 360 | key_off = 182; 361 | else if (offset == KR) 362 | key_off = 192; 363 | 364 | /* arg == ASF_SET */ 365 | for (i = 0; i < KEY_LEN; i++) 366 | rtl8168_eri_write(tp, offset + KEY_LEN - (i + 1), RW_ONE_BYTE, data[i], ERIAR_ASF); 367 | 368 | /* write the new key to EEPROM */ 369 | for (i = 0, j = 19; i < 10; i++, j = j - 2) 370 | rtl8168_eeprom_write_sc(tp, key_off + i, (data[j - 1] << 8) | data[j]); 371 | } 372 | } 373 | 374 | void rtl8168_asf_rw_hexadecimal(struct rtl8168_private *tp, int arg, int offset, int len, unsigned int *data) 375 | { 376 | if (arg == ASF_GET) 377 | data[ASFRWHEXNUM] = rtl8168_eri_read(tp, offset, len, ERIAR_ASF); 378 | else /* arg == ASF_SET */ 379 | rtl8168_eri_write(tp, offset, len, data[ASFRWHEXNUM], ERIAR_ASF); 380 | } 381 | 382 | void rtl8168_asf_rw_systemid(struct rtl8168_private *tp, int arg, unsigned int *data) 383 | { 384 | int i; 385 | 386 | if (arg == ASF_GET) 387 | for (i = 0; i < SYSID_LEN; i++) 388 | data[i] = rtl8168_eri_read(tp, SysID + i, RW_ONE_BYTE, ERIAR_ASF); 389 | else /* arg == ASF_SET */ 390 | for (i = 0; i < SYSID_LEN; i++) 391 | rtl8168_eri_write(tp, SysID + i, RW_ONE_BYTE, data[i], ERIAR_ASF); 392 | } 393 | 394 | void rtl8168_asf_rw_iana(struct rtl8168_private *tp, int arg, unsigned int *data) 395 | { 396 | int i; 397 | 398 | if (arg == ASF_GET) 399 | for (i = 0; i < RW_FOUR_BYTES; i++) 400 | data[i] = rtl8168_eri_read(tp, IANA + i, RW_ONE_BYTE, ERIAR_ASF); 401 | else /* arg == ASF_SET */ 402 | for (i = 0; i < RW_FOUR_BYTES; i++) 403 | rtl8168_eri_write(tp, IANA + i, RW_ONE_BYTE, data[i], ERIAR_ASF); 404 | } 405 | 406 | void rtl8168_asf_rw_uuid(struct rtl8168_private *tp, int arg, unsigned int *data) 407 | { 408 | int i, j; 409 | 410 | if (arg == ASF_GET) 411 | for (i = UUID_LEN - 1, j = 0; i >= 0; i--, j++) 412 | data[j] = rtl8168_eri_read(tp, UUID + i, RW_ONE_BYTE, ERIAR_ASF); 413 | else /* arg == ASF_SET */ 414 | for (i = UUID_LEN - 1, j = 0; i >= 0; i--, j++) 415 | rtl8168_eri_write(tp, UUID + i, RW_ONE_BYTE, data[j], ERIAR_ASF); 416 | } 417 | -------------------------------------------------------------------------------- /r8168.h: -------------------------------------------------------------------------------- 1 | /* SPDX-License-Identifier: GPL-2.0-only */ 2 | /* 3 | ################################################################################ 4 | # 5 | # r8168 is the Linux device driver released for Realtek Gigabit Ethernet 6 | # controllers with PCI-Express interface. 7 | # 8 | # Copyright(c) 2024 Realtek Semiconductor Corp. All rights reserved. 9 | # 10 | # This program is free software; you can redistribute it and/or modify it 11 | # under the terms of the GNU General Public License as published by the Free 12 | # Software Foundation; either version 2 of the License, or (at your option) 13 | # any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 | # more details. 19 | # 20 | # You should have received a copy of the GNU General Public License along with 21 | # this program; if not, see . 22 | # 23 | # Author: 24 | # Realtek NIC software team 25 | # No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan 26 | # 27 | ################################################################################ 28 | */ 29 | 30 | /************************************************************************************ 31 | * This product is covered by one or more of the following patents: 32 | * US6,570,884, US6,115,776, and US6,327,625. 33 | ***********************************************************************************/ 34 | 35 | #include 36 | #include 37 | #include 38 | #include "r8168_dash.h" 39 | #include "r8168_realwow.h" 40 | #include "r8168_fiber.h" 41 | #include "r8168_rss.h" 42 | #ifdef ENABLE_LIB_SUPPORT 43 | #include "r8168_lib.h" 44 | #endif 45 | 46 | /* 47 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)&& !defined(ENABLE_LIB_SUPPORT) 48 | #define RTL_USE_NEW_INTR_API 49 | #endif 50 | */ 51 | 52 | #ifndef fallthrough 53 | #define fallthrough 54 | #endif 55 | 56 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) 57 | #define netif_xmit_stopped netif_tx_queue_stopped 58 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) */ 59 | 60 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) 61 | #ifndef MDIO_AN_EEE_ADV_100TX 62 | #define MDIO_AN_EEE_ADV_100TX 0x0002 /* Advertise 100TX EEE cap */ 63 | #endif 64 | #ifndef MDIO_AN_EEE_ADV_1000T 65 | #define MDIO_AN_EEE_ADV_1000T 0x0004 /* Advertise 1000T EEE cap */ 66 | #endif 67 | 68 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) 69 | #define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX /* 100TX EEE cap */ 70 | #define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T /* 1000T EEE cap */ 71 | #define MDIO_EEE_10GT 0x0008 /* 10GT EEE cap */ 72 | #define MDIO_EEE_1000KX 0x0010 /* 1000KX EEE cap */ 73 | #define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */ 74 | #define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */ 75 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */ 76 | 77 | static inline u32 mmd_eee_adv_to_ethtool_adv_t(u16 eee_adv) 78 | { 79 | u32 adv = 0; 80 | 81 | if (eee_adv & MDIO_EEE_100TX) 82 | adv |= ADVERTISED_100baseT_Full; 83 | if (eee_adv & MDIO_EEE_1000T) 84 | adv |= ADVERTISED_1000baseT_Full; 85 | if (eee_adv & MDIO_EEE_10GT) 86 | adv |= ADVERTISED_10000baseT_Full; 87 | if (eee_adv & MDIO_EEE_1000KX) 88 | adv |= ADVERTISED_1000baseKX_Full; 89 | if (eee_adv & MDIO_EEE_10GKX4) 90 | adv |= ADVERTISED_10000baseKX4_Full; 91 | if (eee_adv & MDIO_EEE_10GKR) 92 | adv |= ADVERTISED_10000baseKR_Full; 93 | 94 | return adv; 95 | } 96 | 97 | static inline u16 ethtool_adv_to_mmd_eee_adv_t(u32 adv) 98 | { 99 | u16 reg = 0; 100 | 101 | if (adv & ADVERTISED_100baseT_Full) 102 | reg |= MDIO_EEE_100TX; 103 | if (adv & ADVERTISED_1000baseT_Full) 104 | reg |= MDIO_EEE_1000T; 105 | if (adv & ADVERTISED_10000baseT_Full) 106 | reg |= MDIO_EEE_10GT; 107 | if (adv & ADVERTISED_1000baseKX_Full) 108 | reg |= MDIO_EEE_1000KX; 109 | if (adv & ADVERTISED_10000baseKX4_Full) 110 | reg |= MDIO_EEE_10GKX4; 111 | if (adv & ADVERTISED_10000baseKR_Full) 112 | reg |= MDIO_EEE_10GKR; 113 | 114 | return reg; 115 | } 116 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0) */ 117 | 118 | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) 119 | static inline 120 | ssize_t strscpy(char *dest, const char *src, size_t count) 121 | { 122 | long res = 0; 123 | 124 | if (count == 0) 125 | return -E2BIG; 126 | 127 | while (count) { 128 | char c; 129 | 130 | c = src[res]; 131 | dest[res] = c; 132 | if (!c) 133 | return res; 134 | res++; 135 | count--; 136 | } 137 | 138 | /* Hit buffer length without finding a NUL; force NUL-termination. */ 139 | if (res) 140 | dest[res-1] = '\0'; 141 | 142 | return -E2BIG; 143 | } 144 | #endif 145 | 146 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0)) 147 | static inline unsigned char *skb_checksum_start(const struct sk_buff *skb) 148 | { 149 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)) 150 | return skb->head + skb->csum_start; 151 | #else /* < 2.6.22 */ 152 | return skb_transport_header(skb); 153 | #endif 154 | } 155 | #endif 156 | 157 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) 158 | static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue, 159 | unsigned int bytes) 160 | {} 161 | static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue, 162 | unsigned int pkts, 163 | unsigned int bytes) 164 | {} 165 | static inline void netdev_tx_reset_queue(struct netdev_queue *q) {} 166 | #endif 167 | 168 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) 169 | static inline void fsleep(unsigned long usecs) 170 | { 171 | if (usecs <= 10) 172 | udelay(usecs); 173 | else if (usecs <= 20000) 174 | usleep_range(usecs, 2 * usecs); 175 | else 176 | msleep(DIV_ROUND_UP(usecs, 1000)); 177 | } 178 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) */ 179 | 180 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5,2,0) 181 | #define netdev_xmit_more() (0) 182 | #endif 183 | 184 | #if LINUX_VERSION_CODE < KERNEL_VERSION(5,8,0) 185 | #define netif_testing_on(dev) 186 | #define netif_testing_off(dev) 187 | #endif 188 | 189 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) 190 | typedef int netdev_tx_t; 191 | #endif 192 | 193 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) 194 | #define skb_transport_offset(skb) (skb->h.raw - skb->data) 195 | #endif 196 | 197 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) 198 | #define device_set_wakeup_enable(dev, val) do {} while (0) 199 | #endif 200 | 201 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) 202 | static inline void ether_addr_copy(u8 *dst, const u8 *src) 203 | { 204 | u16 *a = (u16 *)dst; 205 | const u16 *b = (const u16 *)src; 206 | 207 | a[0] = b[0]; 208 | a[1] = b[1]; 209 | a[2] = b[2]; 210 | } 211 | #endif 212 | 213 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) 214 | #define IS_ERR_OR_NULL(ptr) (!ptr) 215 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) 216 | #define reinit_completion(x) ((x)->done = 0) 217 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) 218 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) 219 | #define pm_runtime_mark_last_busy(x) 220 | #define pm_runtime_put_autosuspend(x) pm_runtime_put(x) 221 | #define pm_runtime_put_sync_autosuspend(x) pm_runtime_put_sync(x) 222 | 223 | static inline bool pm_runtime_suspended(struct device *dev) 224 | { 225 | return dev->power.runtime_status == RPM_SUSPENDED 226 | && !dev->power.disable_depth; 227 | } 228 | 229 | static inline bool pm_runtime_active(struct device *dev) 230 | { 231 | return dev->power.runtime_status == RPM_ACTIVE 232 | || dev->power.disable_depth; 233 | } 234 | #endif 235 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) 236 | #define queue_delayed_work(long_wq, work, delay) schedule_delayed_work(work, delay) 237 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) 238 | #define netif_printk(priv, type, level, netdev, fmt, args...) \ 239 | do { \ 240 | if (netif_msg_##type(priv)) \ 241 | printk(level "%s: " fmt,(netdev)->name , ##args); \ 242 | } while (0) 243 | 244 | #define netif_emerg(priv, type, netdev, fmt, args...) \ 245 | netif_printk(priv, type, KERN_EMERG, netdev, fmt, ##args) 246 | #define netif_alert(priv, type, netdev, fmt, args...) \ 247 | netif_printk(priv, type, KERN_ALERT, netdev, fmt, ##args) 248 | #define netif_crit(priv, type, netdev, fmt, args...) \ 249 | netif_printk(priv, type, KERN_CRIT, netdev, fmt, ##args) 250 | #define netif_err(priv, type, netdev, fmt, args...) \ 251 | netif_printk(priv, type, KERN_ERR, netdev, fmt, ##args) 252 | #define netif_warn(priv, type, netdev, fmt, args...) \ 253 | netif_printk(priv, type, KERN_WARNING, netdev, fmt, ##args) 254 | #define netif_notice(priv, type, netdev, fmt, args...) \ 255 | netif_printk(priv, type, KERN_NOTICE, netdev, fmt, ##args) 256 | #define netif_info(priv, type, netdev, fmt, args...) \ 257 | netif_printk(priv, type, KERN_INFO, (netdev), fmt, ##args) 258 | #endif 259 | #endif 260 | #endif 261 | #endif 262 | #endif 263 | 264 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) 265 | #define setup_timer(_timer, _function, _data) \ 266 | do { \ 267 | (_timer)->function = _function; \ 268 | (_timer)->data = _data; \ 269 | init_timer(_timer); \ 270 | } while (0) 271 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) 272 | 273 | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) 274 | #if defined(skb_vlan_tag_present) && !defined(vlan_tx_tag_present) 275 | #define vlan_tx_tag_present skb_vlan_tag_present 276 | #endif 277 | #if defined(skb_vlan_tag_get) && !defined(vlan_tx_tag_get) 278 | #define vlan_tx_tag_get skb_vlan_tag_get 279 | #endif 280 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) 281 | 282 | #define RTL_ALLOC_SKB_INTR(napi, length) dev_alloc_skb(length) 283 | #define R8168_USE_NAPI_ALLOC_SKB 0 284 | #ifdef CONFIG_R8168_NAPI 285 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) 286 | #undef RTL_ALLOC_SKB_INTR 287 | #define RTL_ALLOC_SKB_INTR(napi, length) napi_alloc_skb(napi, length) 288 | #undef R8168_USE_NAPI_ALLOC_SKB 289 | #define R8168_USE_NAPI_ALLOC_SKB 1 290 | #endif 291 | #endif 292 | 293 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) 294 | #define eth_random_addr(addr) random_ether_addr(addr) 295 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) 296 | 297 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) 298 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) 299 | #define netdev_features_t u32 300 | #endif 301 | #endif 302 | 303 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) 304 | #define NETIF_F_ALL_CSUM NETIF_F_CSUM_MASK 305 | #else 306 | #ifndef NETIF_F_ALL_CSUM 307 | #define NETIF_F_ALL_CSUM NETIF_F_CSUM_MASK 308 | #endif 309 | #endif 310 | 311 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) 312 | #define ENABLE_R8168_PROCFS 313 | #endif 314 | 315 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0) 316 | #define ENABLE_R8168_SYSFS 317 | #endif 318 | 319 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) 320 | #define NETIF_F_HW_VLAN_RX NETIF_F_HW_VLAN_CTAG_RX 321 | #define NETIF_F_HW_VLAN_TX NETIF_F_HW_VLAN_CTAG_TX 322 | #endif 323 | 324 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) 325 | #define __devinit 326 | #define __devexit 327 | #define __devexit_p(func) func 328 | #endif 329 | 330 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 331 | #define CHECKSUM_PARTIAL CHECKSUM_HW 332 | #endif 333 | 334 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 335 | #define irqreturn_t void 336 | #define IRQ_HANDLED 1 337 | #define IRQ_NONE 0 338 | #define IRQ_RETVAL(x) 339 | #endif 340 | 341 | #ifndef NETIF_F_RXALL 342 | #define NETIF_F_RXALL 0 343 | #endif 344 | 345 | #ifndef NETIF_F_RXFCS 346 | #define NETIF_F_RXFCS 0 347 | #endif 348 | 349 | #if !defined(HAVE_FREE_NETDEV) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)) 350 | #define free_netdev(x) kfree(x) 351 | #endif 352 | 353 | #ifndef SET_NETDEV_DEV 354 | #define SET_NETDEV_DEV(net, pdev) 355 | #endif 356 | 357 | #ifndef SET_MODULE_OWNER 358 | #define SET_MODULE_OWNER(dev) 359 | #endif 360 | 361 | #ifndef SA_SHIRQ 362 | #define SA_SHIRQ IRQF_SHARED 363 | #endif 364 | 365 | #ifndef NETIF_F_GSO 366 | #define gso_size tso_size 367 | #define gso_segs tso_segs 368 | #endif 369 | 370 | #ifndef PCI_VENDOR_ID_DLINK 371 | #define PCI_VENDOR_ID_DLINK 0x1186 372 | #endif 373 | 374 | #ifndef dma_mapping_error 375 | #define dma_mapping_error(a,b) 0 376 | #endif 377 | 378 | #ifndef netif_err 379 | #define netif_err(a,b,c,d) 380 | #endif 381 | 382 | #ifndef AUTONEG_DISABLE 383 | #define AUTONEG_DISABLE 0x00 384 | #endif 385 | 386 | #ifndef AUTONEG_ENABLE 387 | #define AUTONEG_ENABLE 0x01 388 | #endif 389 | 390 | #ifndef BMCR_SPEED1000 391 | #define BMCR_SPEED1000 0x0040 392 | #endif 393 | 394 | #ifndef BMCR_SPEED100 395 | #define BMCR_SPEED100 0x2000 396 | #endif 397 | 398 | #ifndef BMCR_SPEED10 399 | #define BMCR_SPEED10 0x0000 400 | #endif 401 | 402 | #ifndef SPEED_UNKNOWN 403 | #define SPEED_UNKNOWN -1 404 | #endif 405 | 406 | #ifndef DUPLEX_UNKNOWN 407 | #define DUPLEX_UNKNOWN 0xff 408 | #endif 409 | 410 | #ifndef SUPPORTED_Pause 411 | #define SUPPORTED_Pause (1 << 13) 412 | #endif 413 | 414 | #ifndef SUPPORTED_Asym_Pause 415 | #define SUPPORTED_Asym_Pause (1 << 14) 416 | #endif 417 | 418 | #ifndef MDIO_EEE_100TX 419 | #define MDIO_EEE_100TX 0x0002 420 | #endif 421 | 422 | #ifndef MDIO_EEE_1000T 423 | #define MDIO_EEE_1000T 0x0004 424 | #endif 425 | 426 | #if LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) 427 | #define ethtool_keee ethtool_eee 428 | #define rtl8168_ethtool_adv_to_mmd_eee_adv_cap1_t ethtool_adv_to_mmd_eee_adv_t 429 | #else 430 | #define rtl8168_ethtool_adv_to_mmd_eee_adv_cap1_t linkmode_to_mii_eee_cap1_t 431 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(6,9,0) */ 432 | 433 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) 434 | #ifdef CONFIG_NET_POLL_CONTROLLER 435 | #define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8168_netpoll 436 | #else 437 | #define RTL_NET_POLL_CONTROLLER 438 | #endif 439 | 440 | #ifdef CONFIG_R8168_VLAN 441 | #define RTL_SET_VLAN dev->vlan_rx_register=rtl8168_vlan_rx_register 442 | #else 443 | #define RTL_SET_VLAN 444 | #endif 445 | 446 | #define RTL_NET_DEVICE_OPS(ops) dev->open=rtl8168_open; \ 447 | dev->hard_start_xmit=rtl8168_start_xmit; \ 448 | dev->get_stats=rtl8168_get_stats; \ 449 | dev->stop=rtl8168_close; \ 450 | dev->tx_timeout=rtl8168_tx_timeout; \ 451 | dev->set_multicast_list=rtl8168_set_rx_mode; \ 452 | dev->change_mtu=rtl8168_change_mtu; \ 453 | dev->set_mac_address=rtl8168_set_mac_address; \ 454 | dev->do_ioctl=rtl8168_do_ioctl; \ 455 | RTL_NET_POLL_CONTROLLER; \ 456 | RTL_SET_VLAN; 457 | #else 458 | #define RTL_NET_DEVICE_OPS(ops) dev->netdev_ops=&ops 459 | #endif 460 | 461 | #ifndef FALSE 462 | #define FALSE 0 463 | #endif 464 | 465 | #ifndef TRUE 466 | #define TRUE 1 467 | #endif 468 | 469 | #ifndef false 470 | #define false 0 471 | #endif 472 | 473 | #ifndef true 474 | #define true 1 475 | #endif 476 | 477 | //Hardware will continue interrupt 10 times after interrupt finished. 478 | #define RTK_KEEP_INTERRUPT_COUNT (10) 479 | 480 | //Due to the hardware design of RTL8111B, the low 32 bit address of receive 481 | //buffer must be 8-byte alignment. 482 | #ifndef NET_IP_ALIGN 483 | #define NET_IP_ALIGN 2 484 | #endif 485 | #define RTK_RX_ALIGN NET_IP_ALIGN 486 | 487 | #ifdef CONFIG_R8168_NAPI 488 | #define NAPI_SUFFIX "-NAPI" 489 | #else 490 | #define NAPI_SUFFIX "" 491 | #endif 492 | #ifdef ENABLE_FIBER_SUPPORT 493 | #define FIBER_SUFFIX "-FIBER" 494 | #else 495 | #define FIBER_SUFFIX "" 496 | #endif 497 | #ifdef ENABLE_REALWOW_SUPPORT 498 | #define REALWOW_SUFFIX "-REALWOW" 499 | #else 500 | #define REALWOW_SUFFIX "" 501 | #endif 502 | #if defined(ENABLE_DASH_PRINTER_SUPPORT) 503 | #define DASH_SUFFIX "-PRINTER" 504 | #elif defined(ENABLE_DASH_SUPPORT) 505 | #define DASH_SUFFIX "-DASH" 506 | #else 507 | #define DASH_SUFFIX "" 508 | #endif 509 | #if defined(ENABLE_RSS_SUPPORT) 510 | #define RSS_SUFFIX "-RSS" 511 | #else 512 | #define RSS_SUFFIX "" 513 | #endif 514 | 515 | #define RTL8168_VERSION "8.055.00" NAPI_SUFFIX FIBER_SUFFIX REALWOW_SUFFIX DASH_SUFFIX RSS_SUFFIX 516 | #define MODULENAME "r8168" 517 | #define PFX MODULENAME ": " 518 | 519 | #define GPL_CLAIM "\ 520 | r8168 Copyright (C) 2024 Realtek NIC software team \n \ 521 | This program comes with ABSOLUTELY NO WARRANTY; for details, please see . \n \ 522 | This is free software, and you are welcome to redistribute it under certain conditions; see . \n" 523 | 524 | #ifdef RTL8168_DEBUG 525 | #define assert(expr) \ 526 | if(!(expr)) { \ 527 | printk("Assertion failed! %s,%s,%s,line=%d\n", \ 528 | #expr,__FILE__,__FUNCTION__,__LINE__); \ 529 | } 530 | #define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) 531 | #else 532 | #define assert(expr) do {} while (0) 533 | #define dprintk(fmt, args...) do {} while (0) 534 | #endif /* RTL8168_DEBUG */ 535 | 536 | #define R8168_MSG_DEFAULT \ 537 | (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) 538 | 539 | #ifdef CONFIG_R8168_NAPI 540 | #define rtl8168_rx_hwaccel_skb vlan_hwaccel_receive_skb 541 | #define rtl8168_rx_quota(count, quota) min(count, quota) 542 | #else 543 | #define rtl8168_rx_hwaccel_skb vlan_hwaccel_rx 544 | #define rtl8168_rx_quota(count, quota) count 545 | #endif 546 | 547 | /* MAC address length */ 548 | #ifndef MAC_ADDR_LEN 549 | #define MAC_ADDR_LEN 6 550 | #endif 551 | 552 | #ifndef MAC_PROTOCOL_LEN 553 | #define MAC_PROTOCOL_LEN 2 554 | #endif 555 | 556 | #ifndef ETH_FCS_LEN 557 | #define ETH_FCS_LEN 4 558 | #endif 559 | 560 | #ifndef NETIF_F_TSO6 561 | #define NETIF_F_TSO6 0 562 | #endif 563 | 564 | #define Reserved2_data 7 565 | #define RX_DMA_BURST 7 /* Maximum PCI burst, '6' is 1024 */ 566 | #define TX_DMA_BURST_unlimited 7 567 | #define TX_DMA_BURST_1024 6 568 | #define TX_DMA_BURST_512 5 569 | #define TX_DMA_BURST_256 4 570 | #define TX_DMA_BURST_128 3 571 | #define TX_DMA_BURST_64 2 572 | #define TX_DMA_BURST_32 1 573 | #define TX_DMA_BURST_16 0 574 | #define Reserved1_data 0x3F 575 | #define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ 576 | #define Jumbo_Frame_1k ETH_DATA_LEN 577 | #define Jumbo_Frame_2k (2*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 578 | #define Jumbo_Frame_3k (3*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 579 | #define Jumbo_Frame_4k (4*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 580 | #define Jumbo_Frame_5k (5*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 581 | #define Jumbo_Frame_6k (6*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 582 | #define Jumbo_Frame_7k (7*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 583 | #define Jumbo_Frame_8k (8*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 584 | #define Jumbo_Frame_9k (9*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) 585 | #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ 586 | #define RxEarly_off_V1 (0x07 << 11) 587 | #define RxEarly_off_V2 (1 << 11) 588 | #define Rx_Single_fetch_V2 (1 << 14) 589 | 590 | #define R8168_REGS_SIZE (256) 591 | #define R8168_MAC_REGS_SIZE (256) 592 | #define R8168_PHY_REGS_SIZE (16*2) 593 | #define R8168_EPHY_REGS_SIZE (31*2) 594 | #define R8168_ERI_REGS_SIZE (0x100) 595 | #define R8168_REGS_DUMP_SIZE (0x400) 596 | #define R8168_PCI_REGS_SIZE (0x100) 597 | #define R8168_NAPI_WEIGHT 64 598 | 599 | #define R8168_MAX_MSIX_VEC 4 600 | 601 | #define RTL8168_TX_TIMEOUT (6 * HZ) 602 | #define RTL8168_LINK_TIMEOUT (1 * HZ) 603 | #define RTL8168_ESD_TIMEOUT (2 * HZ) 604 | #define RTL8168_DASH_TIMEOUT (0) 605 | 606 | #define MAX_NUM_TX_DESC 1024 /* Maximum number of Tx descriptor registers */ 607 | #define MAX_NUM_RX_DESC 1024 /* Maximum number of Rx descriptor registers */ 608 | 609 | #define MIN_NUM_TX_DESC 32 /* Minimum number of Tx descriptor registers */ 610 | #define MIN_NUM_RX_DESC 32 /* Minimum number of Rx descriptor registers */ 611 | 612 | #define NUM_TX_DESC 1024 /* Number of Tx descriptor registers */ 613 | #define NUM_RX_DESC 1024 /* Number of Rx descriptor registers */ 614 | 615 | #define RX_BUF_SIZE 0x05F2 /* 0x05F2 = 1522bye */ 616 | #define R8168_MAX_TX_QUEUES (2) 617 | #define R8168_MAX_RX_QUEUES (4) 618 | #define R8168_MAX_QUEUES R8168_MAX_RX_QUEUES 619 | #define R8168_MULTI_TX_Q(tp) (rtl8168_tot_tx_rings(tp) > 1) 620 | #define R8168_MULTI_RX_Q(tp) (rtl8168_tot_rx_rings(tp) > 1) 621 | #define R8168_MULTI_RX_4Q(tp) (rtl8168_tot_rx_rings(tp) > 3) 622 | #define R8168_MULTI_RSS_4Q(tp) (tp->num_hw_tot_en_rx_rings > 3) 623 | 624 | #define OCP_STD_PHY_BASE 0xa400 625 | 626 | //Channel Wait Count 627 | #define R8168_CHANNEL_WAIT_COUNT (20000) 628 | #define R8168_CHANNEL_WAIT_TIME (1) // 1us 629 | #define R8168_CHANNEL_EXIT_DELAY_TIME (20) //20us 630 | 631 | #define NODE_ADDRESS_SIZE 6 632 | 633 | #define SHORT_PACKET_PADDING_BUF_SIZE 256 634 | 635 | #define RTK_MAGIC_DEBUG_VALUE 0x0badbeef 636 | 637 | /* write/read MMIO register */ 638 | #define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg)) 639 | #define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg)) 640 | #define RTL_W32(tp, reg, val32) writel((val32), tp->mmio_addr + (reg)) 641 | #define RTL_R8(tp, reg) readb(tp->mmio_addr + (reg)) 642 | #define RTL_R16(tp, reg) readw(tp->mmio_addr + (reg)) 643 | #define RTL_R32(tp, reg) ((unsigned long) readl(tp->mmio_addr + (reg))) 644 | 645 | #ifndef DMA_64BIT_MASK 646 | #define DMA_64BIT_MASK 0xffffffffffffffffULL 647 | #endif 648 | 649 | #ifndef DMA_32BIT_MASK 650 | #define DMA_32BIT_MASK 0x00000000ffffffffULL 651 | #endif 652 | 653 | #ifndef NETDEV_TX_OK 654 | #define NETDEV_TX_OK 0 /* driver took care of packet */ 655 | #endif 656 | 657 | #ifndef NETDEV_TX_BUSY 658 | #define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ 659 | #endif 660 | 661 | #ifndef NETDEV_TX_LOCKED 662 | #define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */ 663 | #endif 664 | 665 | #ifndef ADVERTISED_Pause 666 | #define ADVERTISED_Pause (1 << 13) 667 | #endif 668 | 669 | #ifndef ADVERTISED_Asym_Pause 670 | #define ADVERTISED_Asym_Pause (1 << 14) 671 | #endif 672 | 673 | #ifndef ADVERTISE_PAUSE_CAP 674 | #define ADVERTISE_PAUSE_CAP 0x400 675 | #endif 676 | 677 | #ifndef ADVERTISE_PAUSE_ASYM 678 | #define ADVERTISE_PAUSE_ASYM 0x800 679 | #endif 680 | 681 | #ifndef MII_CTRL1000 682 | #define MII_CTRL1000 0x09 683 | #endif 684 | 685 | #ifndef ADVERTISE_1000FULL 686 | #define ADVERTISE_1000FULL 0x200 687 | #endif 688 | 689 | #ifndef ADVERTISE_1000HALF 690 | #define ADVERTISE_1000HALF 0x100 691 | #endif 692 | 693 | #ifndef ETH_MIN_MTU 694 | #define ETH_MIN_MTU 68 695 | #endif 696 | 697 | #ifndef WRITE_ONCE 698 | #define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val)) 699 | #endif 700 | #ifndef READ_ONCE 701 | #define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) 702 | #endif 703 | 704 | /*****************************************************************************/ 705 | 706 | //#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) 707 | #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27)) || \ 708 | ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && \ 709 | (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3)))) 710 | /* copied from linux kernel 2.6.20 include/linux/netdev.h */ 711 | #define NETDEV_ALIGN 32 712 | #define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) 713 | 714 | static inline void *netdev_priv(struct net_device *dev) 715 | { 716 | return (char *)dev + ((sizeof(struct net_device) 717 | + NETDEV_ALIGN_CONST) 718 | & ~NETDEV_ALIGN_CONST); 719 | } 720 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) 721 | 722 | /*****************************************************************************/ 723 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) 724 | #define RTLDEV tp 725 | #else 726 | #define RTLDEV dev 727 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) 728 | /*****************************************************************************/ 729 | 730 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 731 | typedef struct net_device *napi_ptr; 732 | typedef int *napi_budget; 733 | 734 | #define napi dev 735 | #define RTL_NAPI_CONFIG(ndev, priv, function, weig) ndev->poll=function; \ 736 | ndev->weight=weig; 737 | #define RTL_NAPI_QUOTA(budget, ndev) min(*budget, ndev->quota) 738 | #define RTL_GET_PRIV(stuct_ptr, priv_struct) netdev_priv(stuct_ptr) 739 | #define RTL_GET_NETDEV(priv_ptr) 740 | #define RTL_RX_QUOTA(budget) *budget 741 | #define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) *budget -= work_done; \ 742 | ndev->quota -= work_done; 743 | #define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(dev) 744 | #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev) 745 | #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev) 746 | #define RTL_NAPI_RETURN_VALUE work_done >= work_to_do 747 | #define RTL_NAPI_ENABLE(dev, napi) netif_poll_enable(dev) 748 | #define RTL_NAPI_DISABLE(dev, napi) netif_poll_disable(dev) 749 | #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) 750 | #else 751 | typedef struct napi_struct *napi_ptr; 752 | typedef int napi_budget; 753 | 754 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 755 | #define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add_weight(ndev, &priv->napi, function, weight) 756 | #else 757 | #define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight) 758 | #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0) 759 | #define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget) 760 | #define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr) 761 | #define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev; 762 | #define RTL_RX_QUOTA(budget) budget 763 | #define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) 764 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) 765 | #define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(dev, napi) 766 | #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev, napi) 767 | #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev, napi) 768 | #endif 769 | #if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29) 770 | #define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(napi) 771 | #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(napi) 772 | #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(napi) 773 | #endif 774 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) 775 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) 776 | #define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) napi_complete_done(napi, work_done) 777 | #else 778 | #define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) napi_complete(napi) 779 | #endif 780 | #define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) napi_schedule_prep(napi) 781 | #define __RTL_NETIF_RX_SCHEDULE(dev, napi) __napi_schedule(napi) 782 | #endif 783 | #define RTL_NAPI_RETURN_VALUE work_done 784 | #define RTL_NAPI_ENABLE(dev, napi) napi_enable(napi) 785 | #define RTL_NAPI_DISABLE(dev, napi) napi_disable(napi) 786 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) 787 | 788 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 789 | #define RTL_NAPI_DEL(priv) 790 | #else 791 | #define RTL_NAPI_DEL(priv) netif_napi_del(&priv->napi) 792 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) 793 | 794 | /*****************************************************************************/ 795 | #ifdef CONFIG_R8168_NAPI 796 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) 797 | #define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) napi_consume_skb(skb, budget) 798 | #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) 799 | #define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); 800 | #else 801 | #define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); 802 | #endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) 803 | #else //CONFIG_R8168_NAPI 804 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) 805 | #define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); 806 | #else 807 | #define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); 808 | #endif 809 | #endif //CONFIG_R8168_NAPI 810 | 811 | /*****************************************************************************/ 812 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) 813 | #ifdef __CHECKER__ 814 | #define __iomem __attribute__((noderef, address_space(2))) 815 | extern void __chk_io_ptr(void __iomem *); 816 | #define __bitwise __attribute__((bitwise)) 817 | #else 818 | #define __iomem 819 | #define __chk_io_ptr(x) (void)0 820 | #define __bitwise 821 | #endif 822 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) 823 | 824 | /*****************************************************************************/ 825 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) 826 | #ifdef __CHECKER__ 827 | #define __force __attribute__((force)) 828 | #else 829 | #define __force 830 | #endif 831 | #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) 832 | 833 | #ifndef module_param 834 | #define module_param(v,t,p) MODULE_PARM(v, "i"); 835 | #endif 836 | 837 | #ifndef PCI_DEVICE 838 | #define PCI_DEVICE(vend,dev) \ 839 | .vendor = (vend), .device = (dev), \ 840 | .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID 841 | #endif 842 | 843 | /*****************************************************************************/ 844 | /* 2.5.28 => 2.4.23 */ 845 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28)) 846 | 847 | static inline void _kc_synchronize_irq(void) 848 | { 849 | synchronize_irq(); 850 | } 851 | #undef synchronize_irq 852 | #define synchronize_irq(X) _kc_synchronize_irq() 853 | 854 | #include 855 | #define work_struct tq_struct 856 | #undef INIT_WORK 857 | #define INIT_WORK(a,b,c) INIT_TQUEUE(a,(void (*)(void *))b,c) 858 | #undef container_of 859 | #define container_of list_entry 860 | #define schedule_work schedule_task 861 | #define flush_scheduled_work flush_scheduled_tasks 862 | #endif /* 2.5.28 => 2.4.17 */ 863 | 864 | /*****************************************************************************/ 865 | /* 2.6.4 => 2.6.0 */ 866 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)) 867 | #define MODULE_VERSION(_version) MODULE_INFO(version, _version) 868 | #endif /* 2.6.4 => 2.6.0 */ 869 | /*****************************************************************************/ 870 | /* 2.6.0 => 2.5.28 */ 871 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) 872 | #define MODULE_INFO(version, _version) 873 | #ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT 874 | #define CONFIG_E1000_DISABLE_PACKET_SPLIT 1 875 | #endif 876 | 877 | #define pci_set_consistent_dma_mask(dev,mask) 1 878 | 879 | #undef dev_put 880 | #define dev_put(dev) __dev_put(dev) 881 | 882 | #ifndef skb_fill_page_desc 883 | #define skb_fill_page_desc _kc_skb_fill_page_desc 884 | extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size); 885 | #endif 886 | 887 | #ifndef pci_dma_mapping_error 888 | #define pci_dma_mapping_error _kc_pci_dma_mapping_error 889 | static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr) 890 | { 891 | return dma_addr == 0; 892 | } 893 | #endif 894 | 895 | #undef ALIGN 896 | #define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) 897 | 898 | #endif /* 2.6.0 => 2.5.28 */ 899 | 900 | /*****************************************************************************/ 901 | /* 2.4.22 => 2.4.17 */ 902 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)) 903 | #define pci_name(x) ((x)->slot_name) 904 | #endif /* 2.4.22 => 2.4.17 */ 905 | 906 | /*****************************************************************************/ 907 | /* 2.6.5 => 2.6.0 */ 908 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5)) 909 | #define pci_dma_sync_single_for_cpu pci_dma_sync_single 910 | #define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu 911 | #endif /* 2.6.5 => 2.6.0 */ 912 | 913 | /*****************************************************************************/ 914 | 915 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 916 | /* 917 | * initialize a work-struct's func and data pointers: 918 | */ 919 | #define PREPARE_WORK(_work, _func, _data) \ 920 | do { \ 921 | (_work)->func = _func; \ 922 | (_work)->data = _data; \ 923 | } while (0) 924 | 925 | #endif 926 | /*****************************************************************************/ 927 | /* 2.6.4 => 2.6.0 */ 928 | #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) && \ 929 | LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)) || \ 930 | (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ 931 | LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4))) 932 | #define ETHTOOL_OPS_COMPAT 933 | #endif /* 2.6.4 => 2.6.0 */ 934 | 935 | /*****************************************************************************/ 936 | /* Installations with ethtool version without eeprom, adapter id, or statistics 937 | * support */ 938 | 939 | #ifndef ETH_GSTRING_LEN 940 | #define ETH_GSTRING_LEN 32 941 | #endif 942 | 943 | #ifndef ETHTOOL_GSTATS 944 | #define ETHTOOL_GSTATS 0x1d 945 | #undef ethtool_drvinfo 946 | #define ethtool_drvinfo k_ethtool_drvinfo 947 | struct k_ethtool_drvinfo { 948 | u32 cmd; 949 | char driver[32]; 950 | char version[32]; 951 | char fw_version[32]; 952 | char bus_info[32]; 953 | char reserved1[32]; 954 | char reserved2[16]; 955 | u32 n_stats; 956 | u32 testinfo_len; 957 | u32 eedump_len; 958 | u32 regdump_len; 959 | }; 960 | 961 | struct ethtool_stats { 962 | u32 cmd; 963 | u32 n_stats; 964 | u64 data[0]; 965 | }; 966 | #endif /* ETHTOOL_GSTATS */ 967 | 968 | #ifndef ETHTOOL_PHYS_ID 969 | #define ETHTOOL_PHYS_ID 0x1c 970 | #endif /* ETHTOOL_PHYS_ID */ 971 | 972 | #ifndef ETHTOOL_GSTRINGS 973 | #define ETHTOOL_GSTRINGS 0x1b 974 | enum ethtool_stringset { 975 | ETH_SS_TEST = 0, 976 | ETH_SS_STATS, 977 | }; 978 | struct ethtool_gstrings { 979 | u32 cmd; /* ETHTOOL_GSTRINGS */ 980 | u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ 981 | u32 len; /* number of strings in the string set */ 982 | u8 data[0]; 983 | }; 984 | #endif /* ETHTOOL_GSTRINGS */ 985 | 986 | #ifndef ETHTOOL_TEST 987 | #define ETHTOOL_TEST 0x1a 988 | enum ethtool_test_flags { 989 | ETH_TEST_FL_OFFLINE = (1 << 0), 990 | ETH_TEST_FL_FAILED = (1 << 1), 991 | }; 992 | struct ethtool_test { 993 | u32 cmd; 994 | u32 flags; 995 | u32 reserved; 996 | u32 len; 997 | u64 data[0]; 998 | }; 999 | #endif /* ETHTOOL_TEST */ 1000 | 1001 | #ifndef ETHTOOL_GEEPROM 1002 | #define ETHTOOL_GEEPROM 0xb 1003 | #undef ETHTOOL_GREGS 1004 | struct ethtool_eeprom { 1005 | u32 cmd; 1006 | u32 magic; 1007 | u32 offset; 1008 | u32 len; 1009 | u8 data[0]; 1010 | }; 1011 | 1012 | struct ethtool_value { 1013 | u32 cmd; 1014 | u32 data; 1015 | }; 1016 | #endif /* ETHTOOL_GEEPROM */ 1017 | 1018 | #ifndef ETHTOOL_GLINK 1019 | #define ETHTOOL_GLINK 0xa 1020 | #endif /* ETHTOOL_GLINK */ 1021 | 1022 | #ifndef ETHTOOL_GREGS 1023 | #define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */ 1024 | #define ethtool_regs _kc_ethtool_regs 1025 | /* for passing big chunks of data */ 1026 | struct _kc_ethtool_regs { 1027 | u32 cmd; 1028 | u32 version; /* driver-specific, indicates different chips/revs */ 1029 | u32 len; /* bytes */ 1030 | u8 data[0]; 1031 | }; 1032 | #endif /* ETHTOOL_GREGS */ 1033 | 1034 | #ifndef ETHTOOL_GMSGLVL 1035 | #define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ 1036 | #endif 1037 | #ifndef ETHTOOL_SMSGLVL 1038 | #define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */ 1039 | #endif 1040 | #ifndef ETHTOOL_NWAY_RST 1041 | #define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */ 1042 | #endif 1043 | #ifndef ETHTOOL_GLINK 1044 | #define ETHTOOL_GLINK 0x0000000a /* Get link status */ 1045 | #endif 1046 | #ifndef ETHTOOL_GEEPROM 1047 | #define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ 1048 | #endif 1049 | #ifndef ETHTOOL_SEEPROM 1050 | #define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */ 1051 | #endif 1052 | #ifndef ETHTOOL_GCOALESCE 1053 | #define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ 1054 | /* for configuring coalescing parameters of chip */ 1055 | #define ethtool_coalesce _kc_ethtool_coalesce 1056 | struct _kc_ethtool_coalesce { 1057 | u32 cmd; /* ETHTOOL_{G,S}COALESCE */ 1058 | 1059 | /* How many usecs to delay an RX interrupt after 1060 | * a packet arrives. If 0, only rx_max_coalesced_frames 1061 | * is used. 1062 | */ 1063 | u32 rx_coalesce_usecs; 1064 | 1065 | /* How many packets to delay an RX interrupt after 1066 | * a packet arrives. If 0, only rx_coalesce_usecs is 1067 | * used. It is illegal to set both usecs and max frames 1068 | * to zero as this would cause RX interrupts to never be 1069 | * generated. 1070 | */ 1071 | u32 rx_max_coalesced_frames; 1072 | 1073 | /* Same as above two parameters, except that these values 1074 | * apply while an IRQ is being serviced by the host. Not 1075 | * all cards support this feature and the values are ignored 1076 | * in that case. 1077 | */ 1078 | u32 rx_coalesce_usecs_irq; 1079 | u32 rx_max_coalesced_frames_irq; 1080 | 1081 | /* How many usecs to delay a TX interrupt after 1082 | * a packet is sent. If 0, only tx_max_coalesced_frames 1083 | * is used. 1084 | */ 1085 | u32 tx_coalesce_usecs; 1086 | 1087 | /* How many packets to delay a TX interrupt after 1088 | * a packet is sent. If 0, only tx_coalesce_usecs is 1089 | * used. It is illegal to set both usecs and max frames 1090 | * to zero as this would cause TX interrupts to never be 1091 | * generated. 1092 | */ 1093 | u32 tx_max_coalesced_frames; 1094 | 1095 | /* Same as above two parameters, except that these values 1096 | * apply while an IRQ is being serviced by the host. Not 1097 | * all cards support this feature and the values are ignored 1098 | * in that case. 1099 | */ 1100 | u32 tx_coalesce_usecs_irq; 1101 | u32 tx_max_coalesced_frames_irq; 1102 | 1103 | /* How many usecs to delay in-memory statistics 1104 | * block updates. Some drivers do not have an in-memory 1105 | * statistic block, and in such cases this value is ignored. 1106 | * This value must not be zero. 1107 | */ 1108 | u32 stats_block_coalesce_usecs; 1109 | 1110 | /* Adaptive RX/TX coalescing is an algorithm implemented by 1111 | * some drivers to improve latency under low packet rates and 1112 | * improve throughput under high packet rates. Some drivers 1113 | * only implement one of RX or TX adaptive coalescing. Anything 1114 | * not implemented by the driver causes these values to be 1115 | * silently ignored. 1116 | */ 1117 | u32 use_adaptive_rx_coalesce; 1118 | u32 use_adaptive_tx_coalesce; 1119 | 1120 | /* When the packet rate (measured in packets per second) 1121 | * is below pkt_rate_low, the {rx,tx}_*_low parameters are 1122 | * used. 1123 | */ 1124 | u32 pkt_rate_low; 1125 | u32 rx_coalesce_usecs_low; 1126 | u32 rx_max_coalesced_frames_low; 1127 | u32 tx_coalesce_usecs_low; 1128 | u32 tx_max_coalesced_frames_low; 1129 | 1130 | /* When the packet rate is below pkt_rate_high but above 1131 | * pkt_rate_low (both measured in packets per second) the 1132 | * normal {rx,tx}_* coalescing parameters are used. 1133 | */ 1134 | 1135 | /* When the packet rate is (measured in packets per second) 1136 | * is above pkt_rate_high, the {rx,tx}_*_high parameters are 1137 | * used. 1138 | */ 1139 | u32 pkt_rate_high; 1140 | u32 rx_coalesce_usecs_high; 1141 | u32 rx_max_coalesced_frames_high; 1142 | u32 tx_coalesce_usecs_high; 1143 | u32 tx_max_coalesced_frames_high; 1144 | 1145 | /* How often to do adaptive coalescing packet rate sampling, 1146 | * measured in seconds. Must not be zero. 1147 | */ 1148 | u32 rate_sample_interval; 1149 | }; 1150 | #endif /* ETHTOOL_GCOALESCE */ 1151 | 1152 | #ifndef ETHTOOL_SCOALESCE 1153 | #define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */ 1154 | #endif 1155 | #ifndef ETHTOOL_GRINGPARAM 1156 | #define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ 1157 | /* for configuring RX/TX ring parameters */ 1158 | #define ethtool_ringparam _kc_ethtool_ringparam 1159 | struct _kc_ethtool_ringparam { 1160 | u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */ 1161 | 1162 | /* Read only attributes. These indicate the maximum number 1163 | * of pending RX/TX ring entries the driver will allow the 1164 | * user to set. 1165 | */ 1166 | u32 rx_max_pending; 1167 | u32 rx_mini_max_pending; 1168 | u32 rx_jumbo_max_pending; 1169 | u32 tx_max_pending; 1170 | 1171 | /* Values changeable by the user. The valid values are 1172 | * in the range 1 to the "*_max_pending" counterpart above. 1173 | */ 1174 | u32 rx_pending; 1175 | u32 rx_mini_pending; 1176 | u32 rx_jumbo_pending; 1177 | u32 tx_pending; 1178 | }; 1179 | #endif /* ETHTOOL_GRINGPARAM */ 1180 | 1181 | #ifndef ETHTOOL_SRINGPARAM 1182 | #define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ 1183 | #endif 1184 | #ifndef ETHTOOL_GPAUSEPARAM 1185 | #define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ 1186 | /* for configuring link flow control parameters */ 1187 | #define ethtool_pauseparam _kc_ethtool_pauseparam 1188 | struct _kc_ethtool_pauseparam { 1189 | u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ 1190 | 1191 | /* If the link is being auto-negotiated (via ethtool_cmd.autoneg 1192 | * being true) the user may set 'autonet' here non-zero to have the 1193 | * pause parameters be auto-negotiated too. In such a case, the 1194 | * {rx,tx}_pause values below determine what capabilities are 1195 | * advertised. 1196 | * 1197 | * If 'autoneg' is zero or the link is not being auto-negotiated, 1198 | * then {rx,tx}_pause force the driver to use/not-use pause 1199 | * flow control. 1200 | */ 1201 | u32 autoneg; 1202 | u32 rx_pause; 1203 | u32 tx_pause; 1204 | }; 1205 | #endif /* ETHTOOL_GPAUSEPARAM */ 1206 | 1207 | #ifndef ETHTOOL_SPAUSEPARAM 1208 | #define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */ 1209 | #endif 1210 | #ifndef ETHTOOL_GRXCSUM 1211 | #define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ 1212 | #endif 1213 | #ifndef ETHTOOL_SRXCSUM 1214 | #define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ 1215 | #endif 1216 | #ifndef ETHTOOL_GTXCSUM 1217 | #define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ 1218 | #endif 1219 | #ifndef ETHTOOL_STXCSUM 1220 | #define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */ 1221 | #endif 1222 | #ifndef ETHTOOL_GSG 1223 | #define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable 1224 | * (ethtool_value) */ 1225 | #endif 1226 | #ifndef ETHTOOL_SSG 1227 | #define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable 1228 | * (ethtool_value). */ 1229 | #endif 1230 | #ifndef ETHTOOL_TEST 1231 | #define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */ 1232 | #endif 1233 | #ifndef ETHTOOL_GSTRINGS 1234 | #define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ 1235 | #endif 1236 | #ifndef ETHTOOL_PHYS_ID 1237 | #define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ 1238 | #endif 1239 | #ifndef ETHTOOL_GSTATS 1240 | #define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ 1241 | #endif 1242 | #ifndef ETHTOOL_GTSO 1243 | #define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ 1244 | #endif 1245 | #ifndef ETHTOOL_STSO 1246 | #define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ 1247 | #endif 1248 | 1249 | #ifndef ETHTOOL_BUSINFO_LEN 1250 | #define ETHTOOL_BUSINFO_LEN 32 1251 | #endif 1252 | 1253 | /*****************************************************************************/ 1254 | 1255 | enum RTL8168_DSM_STATE { 1256 | DSM_MAC_INIT = 1, 1257 | DSM_NIC_GOTO_D3 = 2, 1258 | DSM_IF_DOWN = 3, 1259 | DSM_NIC_RESUME_D3 = 4, 1260 | DSM_IF_UP = 5, 1261 | }; 1262 | 1263 | enum RTL8168_registers { 1264 | MAC0 = 0x00, /* Ethernet hardware address. */ 1265 | MAC4 = 0x04, 1266 | MAR0 = 0x08, /* Multicast filter. */ 1267 | CounterAddrLow = 0x10, 1268 | CounterAddrHigh = 0x14, 1269 | CustomLED = 0x18, 1270 | #ifdef ENABLE_LIB_SUPPORT 1271 | TxDescStartAddrLow = 0x28, 1272 | TxDescStartAddrHigh = 0x2c, 1273 | TxHDescStartAddrLow = 0x20, 1274 | TxHDescStartAddrHigh = 0x24, 1275 | #else 1276 | TxDescStartAddrLow = 0x20, 1277 | TxDescStartAddrHigh = 0x24, 1278 | TxHDescStartAddrLow = 0x28, 1279 | TxHDescStartAddrHigh = 0x2c, 1280 | #endif /* ENABLE_LIB_SUPPORT */ 1281 | FLASH = 0x30, 1282 | ERSR = 0x36, 1283 | ChipCmd = 0x37, 1284 | TxPoll = 0x38, 1285 | IntrMask = 0x3C, 1286 | IntrStatus = 0x3E, 1287 | TxConfig = 0x40, 1288 | RxConfig = 0x44, 1289 | TCTR = 0x48, 1290 | Cfg9346 = 0x50, 1291 | Config0 = 0x51, 1292 | Config1 = 0x52, 1293 | Config2 = 0x53, 1294 | Config3 = 0x54, 1295 | Config4 = 0x55, 1296 | Config5 = 0x56, 1297 | TDFNR = 0x57, 1298 | TimeInt0 = 0x58, 1299 | TimeInt1 = 0x5C, 1300 | PHYAR = 0x60, 1301 | CSIDR = 0x64, 1302 | CSIAR = 0x68, 1303 | PHYstatus = 0x6C, 1304 | MACDBG = 0x6D, 1305 | GPIO = 0x6E, 1306 | PMCH = 0x6F, 1307 | ERIDR = 0x70, 1308 | ERIAR = 0x74, 1309 | EPHY_RXER_NUM = 0x7C, 1310 | EPHYAR = 0x80, 1311 | IntrMask1 = 0x84, 1312 | IntrMask2 = 0x85, 1313 | IntrStatus1 = 0x86, 1314 | IntrStatus2 = 0x87, 1315 | TimeInt2 = 0x8C, 1316 | Rss_indir_tbl = 0x90, 1317 | OCPDR = 0xB0, 1318 | MACOCP = 0xB0, 1319 | OCPAR = 0xB4, 1320 | SecMAC0 = 0xB4, 1321 | SecMAC4 = 0xB8, 1322 | PHYOCP = 0xB8, 1323 | IntrMask3 = 0xC0, 1324 | IntrStatus3 = 0xC1, 1325 | DBG_reg = 0xD1, 1326 | TwiCmdReg = 0xD2, 1327 | MCUCmd_reg = 0xD3, 1328 | RxMaxSize = 0xDA, 1329 | EFUSEAR = 0xDC, 1330 | CPlusCmd = 0xE0, 1331 | IntrMitigate = 0xE2, 1332 | RxDescAddrLow = 0xE4, 1333 | RxDescAddrHigh = 0xE8, 1334 | MTPS = 0xEC, 1335 | FuncEvent = 0xF0, 1336 | PPSW = 0xF2, 1337 | FuncEventMask = 0xF4, 1338 | TimeInt3 = 0xF4, 1339 | FuncPresetState = 0xF8, 1340 | CMAC_IBCR0 = 0xF8, 1341 | CMAC_IBCR2 = 0xF9, 1342 | CMAC_IBIMR0 = 0xFA, 1343 | CMAC_IBISR0 = 0xFB, 1344 | FuncForceEvent = 0xFC, 1345 | 1346 | /* ERI */ 1347 | RSS_KEY_8168 = 0x90, 1348 | RSS_CTRL_8168 = 0xB8, 1349 | Q_NUM_CTRL_8168 = 0xC0, 1350 | 1351 | /* MAC OCP */ 1352 | EEE_TXIDLE_TIMER_8168 = 0xe048, 1353 | }; 1354 | 1355 | enum RTL8168_register_content { 1356 | /* InterruptStatusBits */ 1357 | SYSErr = 0x8000, 1358 | PCSTimeout = 0x4000, 1359 | SWInt = 0x0100, 1360 | TxDescUnavail = 0x0080, 1361 | RxFIFOOver = 0x0040, 1362 | LinkChg = 0x0020, 1363 | RxDescUnavail = 0x0010, 1364 | TxErr = 0x0008, 1365 | TxOK = 0x0004, 1366 | RxErr = 0x0002, 1367 | RxOK = 0x0001, 1368 | RxDU1 = 0x0002, 1369 | RxOK1 = 0x0001, 1370 | 1371 | /* RxStatusDesc */ 1372 | RxRWT = (1 << 22), 1373 | RxRES = (1 << 21), 1374 | RxRUNT = (1 << 20), 1375 | RxCRC = (1 << 19), 1376 | 1377 | /* ChipCmdBits */ 1378 | StopReq = 0x80, 1379 | CmdReset = 0x10, 1380 | CmdRxEnb = 0x08, 1381 | CmdTxEnb = 0x04, 1382 | RxBufEmpty = 0x01, 1383 | 1384 | /* Cfg9346Bits */ 1385 | Cfg9346_Lock = 0x00, 1386 | Cfg9346_Unlock = 0xC0, 1387 | Cfg9346_EEDO = (1 << 0), 1388 | Cfg9346_EEDI = (1 << 1), 1389 | Cfg9346_EESK = (1 << 2), 1390 | Cfg9346_EECS = (1 << 3), 1391 | Cfg9346_EEM0 = (1 << 6), 1392 | Cfg9346_EEM1 = (1 << 7), 1393 | 1394 | /* rx_mode_bits */ 1395 | AcceptErr = 0x20, 1396 | AcceptRunt = 0x10, 1397 | AcceptBroadcast = 0x08, 1398 | AcceptMulticast = 0x04, 1399 | AcceptMyPhys = 0x02, 1400 | AcceptAllPhys = 0x01, 1401 | 1402 | /* Transmit Priority Polling*/ 1403 | HPQ = 0x80, 1404 | NPQ = 0x40, 1405 | FSWInt = 0x01, 1406 | 1407 | /* RxConfigBits */ 1408 | Reserved2_shift = 13, 1409 | RxCfgDMAShift = 8, 1410 | RxCfg_128_int_en = (1 << 15), 1411 | RxCfg_fet_multi_en = (1 << 14), 1412 | RxCfg_half_refetch = (1 << 13), 1413 | RxCfg_9356SEL = (1 << 6), 1414 | RxCfg_rx_desc_v2_en = (1 << 24), 1415 | 1416 | /* TxConfigBits */ 1417 | TxInterFrameGapShift = 24, 1418 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 1419 | TxMACLoopBack = (1 << 17), /* MAC loopback */ 1420 | 1421 | /* Config1 register */ 1422 | LEDS1 = (1 << 7), 1423 | LEDS0 = (1 << 6), 1424 | Speed_down = (1 << 4), 1425 | MEMMAP = (1 << 3), 1426 | IOMAP = (1 << 2), 1427 | VPD = (1 << 1), 1428 | PMEnable = (1 << 0), /* Power Management Enable */ 1429 | 1430 | /* Config2 register */ 1431 | ClkReqEn = (1 << 7), /* Clock Request Enable */ 1432 | PMSTS_En = (1 << 5), 1433 | 1434 | /* Config3 register */ 1435 | Isolate_en = (1 << 12), /* Isolate enable */ 1436 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ 1437 | LinkUp = (1 << 4), /* This bit is reserved in RTL8168B.*/ 1438 | /* Wake up when the cable connection is re-established */ 1439 | ECRCEN = (1 << 3), /* This bit is reserved in RTL8168B*/ 1440 | Jumbo_En0 = (1 << 2), /* This bit is reserved in RTL8168B*/ 1441 | RDY_TO_L23 = (1 << 1), /* This bit is reserved in RTL8168B*/ 1442 | Beacon_en = (1 << 0), /* This bit is reserved in RTL8168B*/ 1443 | 1444 | /* Config4 register */ 1445 | Jumbo_En1 = (1 << 1), /* This bit is reserved in RTL8168B*/ 1446 | 1447 | /* Config5 register */ 1448 | BWF = (1 << 6), /* Accept Broadcast wakeup frame */ 1449 | MWF = (1 << 5), /* Accept Multicast wakeup frame */ 1450 | UWF = (1 << 4), /* Accept Unicast wakeup frame */ 1451 | LanWake = (1 << 1), /* LanWake enable/disable */ 1452 | PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ 1453 | ASPM_en = (1 << 0), /* ASPM enable */ 1454 | 1455 | /* CPlusCmd */ 1456 | EnableBist = (1 << 15), 1457 | Macdbgo_oe = (1 << 14), 1458 | Normal_mode = (1 << 13), 1459 | Force_halfdup = (1 << 12), 1460 | Force_rxflow_en = (1 << 11), 1461 | Force_txflow_en = (1 << 10), 1462 | Cxpl_dbg_sel = (1 << 9),//This bit is reserved in RTL8168B 1463 | ASF = (1 << 8),//This bit is reserved in RTL8168C 1464 | PktCntrDisable = (1 << 7), 1465 | RxVlan = (1 << 6), 1466 | RxChkSum = (1 << 5), 1467 | Macdbgo_sel = 0x001C, 1468 | INTT_0 = 0x0000, 1469 | INTT_1 = 0x0001, 1470 | INTT_2 = 0x0002, 1471 | INTT_3 = 0x0003, 1472 | 1473 | /* rtl8168_PHYstatus */ 1474 | PowerSaveStatus = 0x80, 1475 | TxFlowCtrl = 0x40, 1476 | RxFlowCtrl = 0x20, 1477 | _1000bpsF = 0x10, 1478 | _100bps = 0x08, 1479 | _10bps = 0x04, 1480 | LinkStatus = 0x02, 1481 | FullDup = 0x01, 1482 | 1483 | /* DBG_reg */ 1484 | Fix_Nak_1 = (1 << 4), 1485 | Fix_Nak_2 = (1 << 3), 1486 | DBGPIN_E2 = (1 << 0), 1487 | 1488 | /* ResetCounterCommand */ 1489 | CounterReset = 0x1, 1490 | /* DumpCounterCommand */ 1491 | CounterDump = 0x8, 1492 | 1493 | /* PHY access */ 1494 | PHYAR_Flag = 0x80000000, 1495 | PHYAR_Write = 0x80000000, 1496 | PHYAR_Read = 0x00000000, 1497 | PHYAR_Reg_Mask = 0x1f, 1498 | PHYAR_Reg_shift = 16, 1499 | PHYAR_Data_Mask = 0xffff, 1500 | 1501 | /* EPHY access */ 1502 | EPHYAR_Flag = 0x80000000, 1503 | EPHYAR_Write = 0x80000000, 1504 | EPHYAR_Read = 0x00000000, 1505 | EPHYAR_Reg_Mask = 0x3f, 1506 | EPHYAR_Reg_shift = 16, 1507 | EPHYAR_Data_Mask = 0xffff, 1508 | 1509 | /* CSI access */ 1510 | CSIAR_Flag = 0x80000000, 1511 | CSIAR_Write = 0x80000000, 1512 | CSIAR_Read = 0x00000000, 1513 | CSIAR_ByteEn = 0x0f, 1514 | CSIAR_ByteEn_shift = 12, 1515 | CSIAR_Addr_Mask = 0x0fff, 1516 | 1517 | /* ERI access */ 1518 | ERIAR_Flag = 0x80000000, 1519 | ERIAR_Write = 0x80000000, 1520 | ERIAR_Read = 0x00000000, 1521 | ERIAR_Addr_Align = 4, /* ERI access register address must be 4 byte alignment */ 1522 | ERIAR_ExGMAC = 0, 1523 | ERIAR_MSIX = 1, 1524 | ERIAR_ASF = 2, 1525 | ERIAR_OOB = 2, 1526 | ERIAR_Type_shift = 16, 1527 | ERIAR_ByteEn = 0x0f, 1528 | ERIAR_ByteEn_shift = 12, 1529 | 1530 | /* OCP GPHY access */ 1531 | OCPDR_Write = 0x80000000, 1532 | OCPDR_Read = 0x00000000, 1533 | OCPDR_Reg_Mask = 0xFF, 1534 | OCPDR_Data_Mask = 0xFFFF, 1535 | OCPDR_GPHY_Reg_shift = 16, 1536 | OCPAR_Flag = 0x80000000, 1537 | OCPAR_GPHY_Write = 0x8000F060, 1538 | OCPAR_GPHY_Read = 0x0000F060, 1539 | OCPR_Write = 0x80000000, 1540 | OCPR_Read = 0x00000000, 1541 | OCPR_Addr_Reg_shift = 16, 1542 | OCPR_Flag = 0x80000000, 1543 | OCP_STD_PHY_BASE_PAGE = 0x0A40, 1544 | 1545 | /* MCU Command */ 1546 | Now_is_oob = (1 << 7), 1547 | Txfifo_empty = (1 << 5), 1548 | Rxfifo_empty = (1 << 4), 1549 | 1550 | /* E-FUSE access */ 1551 | EFUSE_WRITE = 0x80000000, 1552 | EFUSE_WRITE_OK = 0x00000000, 1553 | EFUSE_READ = 0x00000000, 1554 | EFUSE_READ_OK = 0x80000000, 1555 | EFUSE_WRITE_V3 = 0x40000000, 1556 | EFUSE_WRITE_OK_V3 = 0x00000000, 1557 | EFUSE_READ_V3 = 0x80000000, 1558 | EFUSE_READ_OK_V3 = 0x00000000, 1559 | EFUSE_Reg_Mask = 0x03FF, 1560 | EFUSE_Reg_Shift = 8, 1561 | EFUSE_Check_Cnt = 300, 1562 | EFUSE_READ_FAIL = 0xFF, 1563 | EFUSE_Data_Mask = 0x000000FF, 1564 | 1565 | /* GPIO */ 1566 | GPIO_en = (1 << 0), 1567 | 1568 | }; 1569 | 1570 | enum _DescStatusBit { 1571 | DescOwn = (1 << 31), /* Descriptor is owned by NIC */ 1572 | RingEnd = (1 << 30), /* End of descriptor ring */ 1573 | FirstFrag = (1 << 29), /* First segment of a packet */ 1574 | LastFrag = (1 << 28), /* Final segment of a packet */ 1575 | 1576 | /* Tx private */ 1577 | /*------ offset 0 of tx descriptor ------*/ 1578 | LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ 1579 | GiantSendv4 = (1 << 26), /* TCP Giant Send Offload V4 (GSOv4) */ 1580 | GiantSendv6 = (1 << 25), /* TCP Giant Send Offload V6 (GSOv6) */ 1581 | LargeSend_DP = (1 << 16), /* TCP Large Send Offload (TSO) */ 1582 | MSSShift = 16, /* MSS value position */ 1583 | MSSMask = 0x7FFU, /* MSS value 11 bits */ 1584 | TxIPCS = (1 << 18), /* Calculate IP checksum */ 1585 | TxUDPCS = (1 << 17), /* Calculate UDP/IP checksum */ 1586 | TxTCPCS = (1 << 16), /* Calculate TCP/IP checksum */ 1587 | TxVlanTag = (1 << 17), /* Add VLAN tag */ 1588 | 1589 | /*@@@@@@ offset 4 of tx descriptor => bits for RTL8168C/CP only begin @@@@@@*/ 1590 | TxUDPCS_C = (1 << 31), /* Calculate UDP/IP checksum */ 1591 | TxTCPCS_C = (1 << 30), /* Calculate TCP/IP checksum */ 1592 | TxIPCS_C = (1 << 29), /* Calculate IP checksum */ 1593 | TxIPV6F_C = (1 << 28), /* Indicate it is an IPv6 packet */ 1594 | /*@@@@@@ offset 4 of tx descriptor => bits for RTL8168C/CP only end @@@@@@*/ 1595 | 1596 | 1597 | /* Rx private */ 1598 | /*------ offset 0 of rx descriptor ------*/ 1599 | PID1 = (1 << 18), /* Protocol ID bit 1/2 */ 1600 | PID0 = (1 << 17), /* Protocol ID bit 2/2 */ 1601 | 1602 | #define RxProtoUDP (PID1) 1603 | #define RxProtoTCP (PID0) 1604 | #define RxProtoIP (PID1 | PID0) 1605 | #define RxProtoMask RxProtoIP 1606 | 1607 | RxIPF = (1 << 16), /* IP checksum failed */ 1608 | RxUDPF = (1 << 15), /* UDP/IP checksum failed */ 1609 | RxTCPF = (1 << 14), /* TCP/IP checksum failed */ 1610 | RxVlanTag = (1 << 16), /* VLAN tag available */ 1611 | 1612 | /*@@@@@@ offset 0 of rx descriptor => bits for RTL8168C/CP only begin @@@@@@*/ 1613 | RxUDPT = (1 << 18), 1614 | RxTCPT = (1 << 17), 1615 | /*@@@@@@ offset 0 of rx descriptor => bits for RTL8168C/CP only end @@@@@@*/ 1616 | 1617 | /*@@@@@@ offset 4 of rx descriptor => bits for RTL8168C/CP only begin @@@@@@*/ 1618 | RxV6F = (1 << 31), 1619 | RxV4F = (1 << 30), 1620 | /*@@@@@@ offset 4 of rx descriptor => bits for RTL8168C/CP only end @@@@@@*/ 1621 | }; 1622 | 1623 | enum features { 1624 | // RTL_FEATURE_WOL = (1 << 0), 1625 | RTL_FEATURE_MSI = (1 << 1), 1626 | RTL_FEATURE_MSIX = (1 << 2), 1627 | }; 1628 | 1629 | enum wol_capability { 1630 | WOL_DISABLED = 0, 1631 | WOL_ENABLED = 1 1632 | }; 1633 | 1634 | enum bits { 1635 | BIT_0 = (1 << 0), 1636 | BIT_1 = (1 << 1), 1637 | BIT_2 = (1 << 2), 1638 | BIT_3 = (1 << 3), 1639 | BIT_4 = (1 << 4), 1640 | BIT_5 = (1 << 5), 1641 | BIT_6 = (1 << 6), 1642 | BIT_7 = (1 << 7), 1643 | BIT_8 = (1 << 8), 1644 | BIT_9 = (1 << 9), 1645 | BIT_10 = (1 << 10), 1646 | BIT_11 = (1 << 11), 1647 | BIT_12 = (1 << 12), 1648 | BIT_13 = (1 << 13), 1649 | BIT_14 = (1 << 14), 1650 | BIT_15 = (1 << 15), 1651 | BIT_16 = (1 << 16), 1652 | BIT_17 = (1 << 17), 1653 | BIT_18 = (1 << 18), 1654 | BIT_19 = (1 << 19), 1655 | BIT_20 = (1 << 20), 1656 | BIT_21 = (1 << 21), 1657 | BIT_22 = (1 << 22), 1658 | BIT_23 = (1 << 23), 1659 | BIT_24 = (1 << 24), 1660 | BIT_25 = (1 << 25), 1661 | BIT_26 = (1 << 26), 1662 | BIT_27 = (1 << 27), 1663 | BIT_28 = (1 << 28), 1664 | BIT_29 = (1 << 29), 1665 | BIT_30 = (1 << 30), 1666 | BIT_31 = (1 << 31) 1667 | }; 1668 | 1669 | #define RTL8168_CP_NUM 4 1670 | #define RTL8168_MAX_SUPPORT_CP_LEN 110 1671 | 1672 | enum rtl8168_cp_status { 1673 | rtl8168_cp_normal = 0, 1674 | rtl8168_cp_short, 1675 | rtl8168_cp_open, 1676 | rtl8168_cp_mismatch, 1677 | rtl8168_cp_unknown 1678 | }; 1679 | 1680 | enum effuse { 1681 | EFUSE_NOT_SUPPORT = 0, 1682 | EFUSE_SUPPORT_V1, 1683 | EFUSE_SUPPORT_V2, 1684 | EFUSE_SUPPORT_V3, 1685 | }; 1686 | #define RsvdMask 0x3fffc000 1687 | 1688 | struct TxDesc { 1689 | u32 opts1; 1690 | u32 opts2; 1691 | u64 addr; 1692 | }; 1693 | 1694 | struct RxDesc { 1695 | u32 opts1; 1696 | u32 opts2; 1697 | u64 addr; 1698 | }; 1699 | 1700 | struct RxDescV2 { 1701 | u32 opts1; 1702 | u32 opts2; 1703 | u64 addr; 1704 | u32 rsvd1; 1705 | u32 RSSResult; 1706 | u64 rsvd2; 1707 | }; 1708 | 1709 | //Rx Desc Type 1710 | enum rx_desc_ring_type { 1711 | RX_DESC_RING_TYPE_UNKNOWN=0, 1712 | RX_DESC_RING_TYPE_1, 1713 | RX_DESC_RING_TYPE_2, 1714 | RX_DESC_RING_TYPE_3, 1715 | RX_DESC_RING_TYPE_MAX 1716 | }; 1717 | 1718 | enum rx_desc_len { 1719 | RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)), 1720 | RX_DESC_LEN_TYPE_2 = (sizeof(struct RxDescV2)) 1721 | }; 1722 | 1723 | struct ring_info { 1724 | struct sk_buff *skb; 1725 | u32 len; 1726 | unsigned int bytecount; 1727 | unsigned short gso_segs; 1728 | u8 __pad[sizeof(void *) - sizeof(u32)]; 1729 | }; 1730 | 1731 | struct pci_resource { 1732 | u8 cmd; 1733 | u8 cls; 1734 | u16 io_base_h; 1735 | u16 io_base_l; 1736 | u16 mem_base_h; 1737 | u16 mem_base_l; 1738 | u8 ilr; 1739 | u16 resv_0x1c_h; 1740 | u16 resv_0x1c_l; 1741 | u16 resv_0x20_h; 1742 | u16 resv_0x20_l; 1743 | u16 resv_0x24_h; 1744 | u16 resv_0x24_l; 1745 | u16 resv_0x2c_h; 1746 | u16 resv_0x2c_l; 1747 | u32 pci_sn_l; 1748 | u32 pci_sn_h; 1749 | }; 1750 | 1751 | enum r8168_dash_req_flag { 1752 | R8168_RCV_REQ_SYS_OK = 0, 1753 | R8168_RCV_REQ_DASH_OK, 1754 | R8168_SEND_REQ_HOST_OK, 1755 | R8168_CMAC_RESET, 1756 | R8168_CMAC_DISALE_RX_FLAG_MAX, 1757 | R8168_DASH_REQ_FLAG_MAX 1758 | }; 1759 | 1760 | enum r8168_flag { 1761 | R8168_FLAG_DOWN = 0, 1762 | R8168_FLAG_TASK_RESET_PENDING, 1763 | R8168_FLAG_TASK_ESD_CHECK_PENDING, 1764 | R8168_FLAG_TASK_LINKCHG_CHECK_PENDING, 1765 | R8168_FLAG_TASK_DASH_CHECK_PENDING, 1766 | R8168_FLAG_MAX 1767 | }; 1768 | 1769 | enum r8168_sysfs_flag { 1770 | R8168_SYSFS_RTL_ADV = 0, 1771 | R8168_SYSFS_FLAG_MAX 1772 | }; 1773 | 1774 | /* Flow Control Settings */ 1775 | enum rtl8168_fc_mode { 1776 | rtl8168_fc_none = 0, 1777 | rtl8168_fc_rx_pause, 1778 | rtl8168_fc_tx_pause, 1779 | rtl8168_fc_full, 1780 | rtl8168_fc_default 1781 | }; 1782 | 1783 | struct rtl8168_tx_ring { 1784 | void* priv; 1785 | struct net_device *netdev; 1786 | u32 index; 1787 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ 1788 | u32 dirty_tx; 1789 | u32 num_tx_desc; /* Number of Tx descriptor registers */ 1790 | u32 tdu; /* Tx descriptor unavailable count */ 1791 | struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ 1792 | dma_addr_t TxPhyAddr; 1793 | u32 TxDescAllocSize; 1794 | struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ 1795 | 1796 | u16 tdsar_reg; /* Transmit Descriptor Start Address */ 1797 | }; 1798 | 1799 | struct rtl8168_rx_ring { 1800 | void* priv; 1801 | struct net_device *netdev; 1802 | u32 index; 1803 | u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ 1804 | u32 dirty_rx; 1805 | u32 rdu; /* Rx descriptor unavailable count */ 1806 | //struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ 1807 | //u32 RxDescAllocSize; 1808 | u64 RxDescPhyAddr[MAX_NUM_RX_DESC]; /* Rx desc physical address*/ 1809 | //dma_addr_t RxPhyAddr; 1810 | struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ 1811 | 1812 | //u16 rdsar_reg; /* Receive Descriptor Start Address */ 1813 | }; 1814 | 1815 | struct r8168_napi { 1816 | #ifdef CONFIG_R8168_NAPI 1817 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) 1818 | struct napi_struct napi; 1819 | #endif 1820 | #endif 1821 | void* priv; 1822 | int index; 1823 | }; 1824 | 1825 | struct r8168_irq { 1826 | irq_handler_t handler; 1827 | unsigned int vector; 1828 | u8 requested; 1829 | char name[IFNAMSIZ + 10]; 1830 | }; 1831 | 1832 | #pragma pack(1) 1833 | struct rtl8168_regs { 1834 | //00 1835 | u8 mac_id[6]; 1836 | u16 reg_06; 1837 | u8 mar[8]; 1838 | //10 1839 | u64 dtccr; 1840 | u16 ledsel0; 1841 | u16 legreg; 1842 | u32 tctr3; 1843 | //20 1844 | u32 txq0_dsc_st_addr_0; 1845 | u32 txq0_dsc_st_addr_2; 1846 | u64 reg_28; 1847 | //30 1848 | u16 rit; 1849 | u16 ritc; 1850 | u16 reg_34; 1851 | u8 reg_36; 1852 | u8 command; 1853 | u32 imr0; 1854 | u32 isr0; 1855 | //40 1856 | u32 tcr; 1857 | u32 rcr; 1858 | u32 tctr0; 1859 | u32 tctr1; 1860 | //50 1861 | u8 cr93c46; 1862 | u8 config0; 1863 | u8 config1; 1864 | u8 config2; 1865 | u8 config3; 1866 | u8 config4; 1867 | u8 config5; 1868 | u8 tdfnr; 1869 | u32 timer_int0; 1870 | u32 timer_int1; 1871 | //60 1872 | u32 gphy_mdcmdio; 1873 | u32 csidr; 1874 | u32 csiar; 1875 | u16 phy_status; 1876 | u8 config6; 1877 | u8 pmch; 1878 | //70 1879 | u32 eridr; 1880 | u32 eriar; 1881 | u16 config7; 1882 | u16 reg_7a; 1883 | u32 ephy_rxerr_cnt; 1884 | //80 1885 | u32 ephy_mdcmdio; 1886 | u16 ledsel2; 1887 | u16 ledsel1; 1888 | u32 tctr2; 1889 | u32 timer_int2; 1890 | //90 1891 | u8 tppoll0; 1892 | u8 reg_91; 1893 | u16 reg_92; 1894 | u16 led_feature; 1895 | u16 ledsel3; 1896 | u16 eee_led_config; 1897 | u16 reg_9a; 1898 | u32 reg_9c; 1899 | //a0 1900 | u32 reg_a0; 1901 | u32 reg_a4; 1902 | u32 reg_a8; 1903 | u32 reg_ac; 1904 | //b0 1905 | u32 patch_dbg; 1906 | u32 reg_b4; 1907 | u32 gphy_ocp; 1908 | u32 reg_bc; 1909 | //c0 1910 | u32 reg_c0; 1911 | u32 reg_c4; 1912 | u32 reg_c8; 1913 | u16 otp_cmd; 1914 | u16 otp_pg_config; 1915 | //d0 1916 | u16 phy_pwr; 1917 | u8 twsi_ctrl; 1918 | u8 oob_ctrl; 1919 | u16 mac_dbgo; 1920 | u16 mac_dbg; 1921 | u16 reg_d8; 1922 | u16 rms; 1923 | u32 efuse_data; 1924 | //e0 1925 | u16 cplus_cmd; 1926 | u16 reg_e2; 1927 | u32 rxq0_dsc_st_addr_0; 1928 | u32 rxq0_dsc_st_addr_2; 1929 | u16 reg_ec; 1930 | u16 tx10midle_cnt; 1931 | //f0 1932 | u16 misc0; 1933 | u16 misc1; 1934 | u32 timer_int3; 1935 | u32 cmac_ib; 1936 | u16 reg_fc; 1937 | u16 sw_rst; 1938 | }; 1939 | #pragma pack() 1940 | 1941 | struct rtl8168_regs_save { 1942 | union { 1943 | u8 mac_io[R8168_MAC_REGS_SIZE]; 1944 | 1945 | struct rtl8168_regs mac_reg; 1946 | }; 1947 | u16 pcie_phy[R8168_EPHY_REGS_SIZE/2]; 1948 | u16 eth_phy[R8168_PHY_REGS_SIZE/2]; 1949 | u32 eri_reg[R8168_ERI_REGS_SIZE/4]; 1950 | u32 pci_reg[R8168_PCI_REGS_SIZE/4]; 1951 | 1952 | //ktime_t begin_ktime; 1953 | //ktime_t end_ktime; 1954 | //u64 duration_ns; 1955 | 1956 | 1957 | u16 int_miti_rxq0; 1958 | 1959 | u8 int_config; 1960 | u32 imr_new; 1961 | u32 isr_new; 1962 | 1963 | u8 tdu_status; 1964 | u16 rdu_status; 1965 | 1966 | u32 rss_ctrl; 1967 | u8 rss_key[RTL8168_RSS_KEY_SIZE]; 1968 | u8 rss_i_table[RTL8168_MAX_INDIRECTION_TABLE_ENTRIES]; 1969 | u16 rss_queue_num_sel_r; 1970 | }; 1971 | 1972 | struct rtl8168_counters { 1973 | /* legacy */ 1974 | u64 tx_packets; 1975 | u64 rx_packets; 1976 | u64 tx_errors; 1977 | u32 rx_errors; 1978 | u16 rx_missed; 1979 | u16 align_errors; 1980 | u32 tx_one_collision; 1981 | u32 tx_multi_collision; 1982 | u64 rx_unicast; 1983 | u64 rx_broadcast; 1984 | u32 rx_multicast; 1985 | u16 tx_aborted; 1986 | u16 tx_underrun; 1987 | }; 1988 | 1989 | #if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) 1990 | struct ethtool_eee { 1991 | __u32 cmd; 1992 | __u32 supported; 1993 | __u32 advertised; 1994 | __u32 lp_advertised; 1995 | __u32 eee_active; 1996 | __u32 eee_enabled; 1997 | __u32 tx_lpi_enabled; 1998 | __u32 tx_lpi_timer; 1999 | __u32 reserved[2]; 2000 | }; 2001 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) */ 2002 | 2003 | struct rtl8168_private { 2004 | void __iomem *mmio_addr; /* memory map physical address */ 2005 | struct pci_dev *pci_dev; /* Index of PCI device */ 2006 | struct pci_dev *pdev_cmac; /* Index of PCI device */ 2007 | struct net_device *dev; 2008 | struct r8168_napi r8168napi[R8168_MAX_MSIX_VEC]; 2009 | struct r8168_irq irq_tbl[R8168_MAX_MSIX_VEC]; 2010 | unsigned int irq_nvecs; 2011 | unsigned int max_irq_nvecs; 2012 | unsigned int min_irq_nvecs; 2013 | unsigned int hw_supp_irq_nvecs; 2014 | struct net_device_stats stats; /* statistics of net device */ 2015 | u32 msg_enable; 2016 | u32 tx_tcp_csum_cmd; 2017 | u32 tx_udp_csum_cmd; 2018 | u32 tx_ip_csum_cmd; 2019 | u32 tx_ipv6_csum_cmd; 2020 | int max_jumbo_frame_size; 2021 | int chipset; 2022 | u32 mcfg; 2023 | //u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ 2024 | // u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ 2025 | //u32 dirty_rx; 2026 | //u32 dirty_tx; 2027 | u32 num_rx_desc; /* Number of Rx descriptor registers */ 2028 | //u32 num_tx_desc; /* Number of Tx descriptor registers */ 2029 | //struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ 2030 | struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ 2031 | //dma_addr_t TxPhyAddr; 2032 | dma_addr_t RxPhyAddr; 2033 | //u32 TxDescAllocSize; 2034 | u32 RxDescAllocSize; 2035 | //struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ 2036 | //struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */ 2037 | unsigned rx_buf_sz; 2038 | u16 HwSuppNumTxQueues; // Number of tx ring that hardware can support 2039 | u16 HwSuppNumRxQueues; // Number of rx ring that hardware can support 2040 | unsigned int num_tx_rings; // Number of tx ring that non-ring-lib driver used 2041 | unsigned int num_rx_rings; // Number of rx ring that non-ring-lib driver used 2042 | struct rtl8168_tx_ring tx_ring[R8168_MAX_TX_QUEUES]; // non-ring-lib tx ring 2043 | struct rtl8168_rx_ring rx_ring[R8168_MAX_RX_QUEUES]; // non-ring-lib rx ring 2044 | #ifdef ENABLE_LIB_SUPPORT 2045 | struct blocking_notifier_head lib_nh; 2046 | struct rtl8168_ring lib_tx_ring[R8168_MAX_TX_QUEUES]; // ring-lib tx ring 2047 | struct rtl8168_ring lib_rx_ring[R8168_MAX_RX_QUEUES]; // ring-lib rx ring 2048 | #endif 2049 | u16 num_hw_tot_en_rx_rings; // Number of rx ring that hardware enabled 2050 | //struct timer_list esd_timer; 2051 | //struct timer_list link_timer; 2052 | struct pci_resource pci_cfg_space; 2053 | unsigned int esd_flag; 2054 | unsigned int pci_cfg_is_read; 2055 | unsigned int rtl8168_rx_config; 2056 | u16 cp_cmd; 2057 | u16 intr_mask; 2058 | u16 timer_intr_mask; 2059 | u16 isr_reg[R8168_MAX_MSIX_VEC]; 2060 | u16 imr_reg[R8168_MAX_MSIX_VEC]; 2061 | int phy_auto_nego_reg; 2062 | int phy_1000_ctrl_reg; 2063 | u8 org_mac_addr[NODE_ADDRESS_SIZE]; 2064 | struct rtl8168_counters *tally_vaddr; 2065 | dma_addr_t tally_paddr; 2066 | 2067 | #ifdef CONFIG_R8168_VLAN 2068 | struct vlan_group *vlgrp; 2069 | #endif 2070 | u8 wol_enabled; 2071 | u32 wol_opts; 2072 | u8 efuse_ver; 2073 | u8 eeprom_type; 2074 | u8 autoneg; 2075 | u8 duplex; 2076 | u32 speed; 2077 | u32 advertising; 2078 | enum rtl8168_fc_mode fcpause; 2079 | u16 eeprom_len; 2080 | u16 cur_page; 2081 | u32 bios_setting; 2082 | 2083 | int (*set_speed)(struct net_device *, u8 autoneg, u32 speed, u8 duplex, u32 adv); 2084 | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) 2085 | void (*get_settings)(struct net_device *, struct ethtool_cmd *); 2086 | #else 2087 | void (*get_settings)(struct net_device *, struct ethtool_link_ksettings *); 2088 | #endif 2089 | void (*phy_reset_enable)(struct net_device *); 2090 | unsigned int (*phy_reset_pending)(struct net_device *); 2091 | unsigned int (*link_ok)(struct net_device *); 2092 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) 2093 | struct work_struct reset_task; 2094 | struct work_struct esd_task; 2095 | struct work_struct linkchg_task; 2096 | struct work_struct dash_task; 2097 | #else 2098 | struct delayed_work reset_task; 2099 | struct delayed_work esd_task; 2100 | struct delayed_work linkchg_task; 2101 | struct delayed_work dash_task; 2102 | #endif 2103 | DECLARE_BITMAP(task_flags, R8168_FLAG_MAX); 2104 | unsigned features; 2105 | 2106 | u8 org_pci_offset_99; 2107 | u8 org_pci_offset_180; 2108 | u8 issue_offset_99_event; 2109 | 2110 | u8 org_pci_offset_80; 2111 | u8 org_pci_offset_81; 2112 | u8 use_timer_interrrupt; 2113 | 2114 | u32 keep_intr_cnt; 2115 | 2116 | u8 HwIcVerUnknown; 2117 | u8 NotWrRamCodeToMicroP; 2118 | u8 NotWrMcuPatchCode; 2119 | u8 HwHasWrRamCodeToMicroP; 2120 | 2121 | u16 sw_ram_code_ver; 2122 | u16 hw_ram_code_ver; 2123 | 2124 | u8 rtk_enable_diag; 2125 | 2126 | u8 ShortPacketSwChecksum; 2127 | 2128 | u8 UseSwPaddingShortPkt; 2129 | 2130 | u8 RequireAdcBiasPatch; 2131 | u16 AdcBiasPatchIoffset; 2132 | 2133 | u8 RequireAdjustUpsTxLinkPulseTiming; 2134 | u16 SwrCnt1msIni; 2135 | 2136 | u8 HwSuppNowIsOobVer; 2137 | 2138 | u8 RequiredSecLanDonglePatch; 2139 | 2140 | u32 HwFiberModeVer; 2141 | u32 HwFiberStat; 2142 | u8 HwFiberLedMode; 2143 | u8 HwSwitchMdiToFiber; 2144 | 2145 | u8 HwSuppSerDesPhyVer; 2146 | 2147 | u8 HwSuppPhyOcpVer; 2148 | 2149 | u8 HwSuppAspmClkIntrLock; 2150 | 2151 | u16 NicCustLedValue; 2152 | 2153 | u8 HwSuppUpsVer; 2154 | 2155 | u8 HwSuppMagicPktVer; 2156 | 2157 | u8 HwSuppCheckPhyDisableModeVer; 2158 | 2159 | u8 random_mac; 2160 | 2161 | u16 phy_reg_aner; 2162 | u16 phy_reg_anlpar; 2163 | u16 phy_reg_gbsr; 2164 | 2165 | u32 HwPcieSNOffset; 2166 | 2167 | u8 HwSuppEsdVer; 2168 | u8 TestPhyOcpReg; 2169 | u16 BackupPhyFuseDout_15_0; 2170 | u16 BackupPhyFuseDout_31_16; 2171 | u16 BackupPhyFuseDout_47_32; 2172 | u16 BackupPhyFuseDout_63_48; 2173 | 2174 | u8 ring_lib_enabled; 2175 | 2176 | const char *fw_name; 2177 | struct rtl8168_fw *rtl_fw; 2178 | u32 ocp_base; 2179 | 2180 | //Dash+++++++++++++++++ 2181 | u8 HwSuppDashVer; 2182 | u8 DASH; 2183 | u8 dash_printer_enabled; 2184 | u8 HwPkgDet; 2185 | u8 HwSuppOcpChannelVer; 2186 | void __iomem *cmac_ioaddr; /* cmac memory map physical address */ 2187 | DECLARE_BITMAP(dash_req_flags, R8168_DASH_REQ_FLAG_MAX); 2188 | 2189 | #ifdef ENABLE_DASH_SUPPORT 2190 | u16 AfterRecvFromFwBufLen; 2191 | u8 AfterRecvFromFwBuf[RECV_FROM_FW_BUF_SIZE]; 2192 | u16 AfterSendToFwBufLen; 2193 | u8 AfterSendToFwBuf[SEND_TO_FW_BUF_SIZE]; 2194 | u16 SendToFwBufferLen; 2195 | u32 SizeOfSendToFwBuffer; 2196 | u32 SizeOfSendToFwBufferMemAlloc; 2197 | u32 NumOfSendToFwBuffer; 2198 | 2199 | u8 OobReq; 2200 | u8 OobAck; 2201 | u32 OobReqComplete; 2202 | u32 OobAckComplete; 2203 | 2204 | void *SendToFwBuffer; 2205 | dma_addr_t SendToFwBufferPhy; 2206 | u8 SendingToFw; 2207 | PTX_DASH_SEND_FW_DESC TxDashSendFwDesc; 2208 | dma_addr_t TxDashSendFwDescPhy; 2209 | u32 SizeOfTxDashSendFwDescMemAlloc; 2210 | u32 SizeOfTxDashSendFwDesc; 2211 | u32 NumTxDashSendFwDesc; 2212 | u32 CurrNumTxDashSendFwDesc; 2213 | u32 LastSendNumTxDashSendFwDesc; 2214 | 2215 | u32 NumRecvFromFwBuffer; 2216 | u32 SizeOfRecvFromFwBuffer; 2217 | u32 SizeOfRecvFromFwBufferMemAlloc; 2218 | void *RecvFromFwBuffer; 2219 | dma_addr_t RecvFromFwBufferPhy; 2220 | 2221 | PRX_DASH_FROM_FW_DESC RxDashRecvFwDesc; 2222 | dma_addr_t RxDashRecvFwDescPhy; 2223 | u32 SizeOfRxDashRecvFwDescMemAlloc; 2224 | u32 SizeOfRxDashRecvFwDesc; 2225 | u32 NumRxDashRecvFwDesc; 2226 | u32 CurrNumRxDashRecvFwDesc; 2227 | u8 DashReqRegValue; 2228 | u16 HostReqValue; 2229 | 2230 | u32 CmacResetIsrCounter; 2231 | u8 CmacResetIntr; 2232 | u8 CmacResetting; 2233 | u8 CmacOobIssueCmacReset; 2234 | u32 CmacResetbyFwCnt; 2235 | 2236 | #if defined(ENABLE_DASH_PRINTER_SUPPORT) 2237 | struct completion fw_ack; 2238 | struct completion fw_req; 2239 | struct completion fw_host_ok; 2240 | #endif 2241 | //Dash----------------- 2242 | #endif //ENABLE_DASH_SUPPORT 2243 | 2244 | //Realwow++++++++++++++ 2245 | u8 HwSuppKCPOffloadVer; 2246 | 2247 | u8 EnableDhcpTimeoutWake; 2248 | u8 EnableTeredoOffload; 2249 | u8 EnableKCPOffload; 2250 | #ifdef ENABLE_REALWOW_SUPPORT 2251 | u32 DhcpTimeout; 2252 | MP_KCP_INFO MpKCPInfo; 2253 | //Realwow-------------- 2254 | #endif //ENABLE_REALWOW_SUPPORT 2255 | 2256 | struct ethtool_keee eee; 2257 | 2258 | u32 dynamic_aspm_packet_count; 2259 | 2260 | #ifdef ENABLE_R8168_PROCFS 2261 | //Procfs support 2262 | struct proc_dir_entry *proc_dir; 2263 | struct proc_dir_entry *proc_dir_debug; 2264 | struct proc_dir_entry *proc_dir_test; 2265 | #endif 2266 | #ifdef ENABLE_R8168_SYSFS 2267 | //sysfs support 2268 | DECLARE_BITMAP(sysfs_flag, R8168_SYSFS_FLAG_MAX); 2269 | u32 testmode; 2270 | #endif 2271 | u8 HwSuppRxDescType; 2272 | u8 InitRxDescType; 2273 | u16 RxDescLength; //V1 16 Byte V2 32 Bytes 2274 | 2275 | u8 HwSuppRssVer; 2276 | u8 EnableRss; 2277 | u16 HwSuppIndirTblEntries; 2278 | #ifdef ENABLE_RSS_SUPPORT 2279 | u32 rss_flags; 2280 | /* Receive Side Scaling settings */ 2281 | #define RTL8168_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ 2282 | u8 rss_key[RTL8168_RSS_KEY_SIZE]; 2283 | #define RTL8168_MAX_INDIRECTION_TABLE_ENTRIES 128 2284 | u8 rss_indir_tbl[RTL8168_MAX_INDIRECTION_TABLE_ENTRIES]; 2285 | u32 rss_options; 2286 | #endif 2287 | u32 rx_fifo_of; /* Rx fifo overflow count */ 2288 | }; 2289 | 2290 | #ifdef ENABLE_LIB_SUPPORT 2291 | static inline unsigned int 2292 | rtl8168_num_lib_tx_rings(struct rtl8168_private *tp) 2293 | { 2294 | int count, i; 2295 | 2296 | for (count = 0, i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++) 2297 | if(tp->lib_tx_ring[i].enabled) 2298 | count++; 2299 | 2300 | return count; 2301 | } 2302 | 2303 | static inline unsigned int 2304 | rtl8168_num_lib_rx_rings(struct rtl8168_private *tp) 2305 | { 2306 | int count, i; 2307 | 2308 | for (count = 0, i = 1; i < tp->HwSuppNumRxQueues; i++) 2309 | if(tp->lib_rx_ring[i].enabled) 2310 | count++; 2311 | 2312 | return count; 2313 | } 2314 | 2315 | static inline bool 2316 | rtl8168_lib_tx_ring_released(struct rtl8168_private *tp) 2317 | { 2318 | int i; 2319 | bool released = 0; 2320 | 2321 | for (i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++) { 2322 | struct rtl8168_ring *ring = &tp->lib_tx_ring[i]; 2323 | if (ring->allocated) 2324 | goto exit; 2325 | } 2326 | 2327 | released = 1; 2328 | 2329 | exit: 2330 | return released; 2331 | } 2332 | 2333 | static inline bool 2334 | rtl8168_lib_rx_ring_released(struct rtl8168_private *tp) 2335 | { 2336 | int i; 2337 | bool released = 0; 2338 | 2339 | for (i = 1; i < tp->HwSuppNumRxQueues; i++) { 2340 | struct rtl8168_ring *ring = &tp->lib_rx_ring[i]; 2341 | if (ring->allocated) 2342 | goto exit; 2343 | } 2344 | 2345 | released = 1; 2346 | 2347 | exit: 2348 | return released; 2349 | } 2350 | 2351 | #else 2352 | 2353 | static inline unsigned int 2354 | rtl8168_num_lib_tx_rings(struct rtl8168_private *tp) 2355 | { 2356 | return 0; 2357 | } 2358 | 2359 | static inline unsigned int 2360 | rtl8168_num_lib_rx_rings(struct rtl8168_private *tp) 2361 | { 2362 | return 0; 2363 | } 2364 | 2365 | static inline bool 2366 | rtl8168_lib_tx_ring_released(struct rtl8168_private *tp) 2367 | { 2368 | return 1; 2369 | } 2370 | 2371 | static inline bool 2372 | rtl8168_lib_rx_ring_released(struct rtl8168_private *tp) 2373 | { 2374 | return 1; 2375 | } 2376 | #endif 2377 | 2378 | static inline unsigned int 2379 | rtl8168_tot_tx_rings(struct rtl8168_private *tp) 2380 | { 2381 | return tp->num_tx_rings + rtl8168_num_lib_tx_rings(tp); 2382 | } 2383 | 2384 | static inline unsigned int 2385 | rtl8168_tot_rx_rings(struct rtl8168_private *tp) 2386 | { 2387 | return tp->num_rx_rings + rtl8168_num_lib_rx_rings(tp); 2388 | } 2389 | 2390 | static inline struct netdev_queue *txring_txq(const struct rtl8168_tx_ring *ring) 2391 | { 2392 | return netdev_get_tx_queue(ring->netdev, ring->index); 2393 | } 2394 | 2395 | static inline bool 2396 | rtl8168_lib_all_ring_released(struct rtl8168_private *tp) 2397 | { 2398 | return (rtl8168_lib_tx_ring_released(tp) && 2399 | rtl8168_lib_rx_ring_released(tp)); 2400 | } 2401 | 2402 | enum eetype { 2403 | EEPROM_TYPE_NONE=0, 2404 | EEPROM_TYPE_93C46, 2405 | EEPROM_TYPE_93C56, 2406 | EEPROM_TWSI 2407 | }; 2408 | 2409 | enum mcfg { 2410 | CFG_METHOD_1=0, 2411 | CFG_METHOD_2, 2412 | CFG_METHOD_3, 2413 | CFG_METHOD_4, 2414 | CFG_METHOD_5, 2415 | CFG_METHOD_6, 2416 | CFG_METHOD_7, 2417 | CFG_METHOD_8, 2418 | CFG_METHOD_9 , 2419 | CFG_METHOD_10, 2420 | CFG_METHOD_11, 2421 | CFG_METHOD_12, 2422 | CFG_METHOD_13, 2423 | CFG_METHOD_14, 2424 | CFG_METHOD_15, 2425 | CFG_METHOD_16, 2426 | CFG_METHOD_17, 2427 | CFG_METHOD_18, 2428 | CFG_METHOD_19, 2429 | CFG_METHOD_20, 2430 | CFG_METHOD_21, 2431 | CFG_METHOD_22, 2432 | CFG_METHOD_23, 2433 | CFG_METHOD_24, 2434 | CFG_METHOD_25, 2435 | CFG_METHOD_26, 2436 | CFG_METHOD_27, 2437 | CFG_METHOD_28, 2438 | CFG_METHOD_29, 2439 | CFG_METHOD_30, 2440 | CFG_METHOD_31, 2441 | CFG_METHOD_32, 2442 | CFG_METHOD_33, 2443 | CFG_METHOD_34, 2444 | CFG_METHOD_35, 2445 | CFG_METHOD_36, 2446 | CFG_METHOD_37, 2447 | CFG_METHOD_MAX, 2448 | CFG_METHOD_DEFAULT = 0xFF 2449 | }; 2450 | 2451 | #define LSO_32K 32000 2452 | #define LSO_64K 64000 2453 | 2454 | #define NIC_MIN_PHYS_BUF_COUNT (2) 2455 | #define NIC_MAX_PHYS_BUF_COUNT_LSO_64K (24) 2456 | #define NIC_MAX_PHYS_BUF_COUNT_LSO2 (16*4) 2457 | 2458 | #define GTTCPHO_SHIFT 18 2459 | #define GTTCPHO_MAX 0x70U 2460 | #define GTPKTSIZE_MAX 0x3ffffU 2461 | #define TCPHO_SHIFT 18 2462 | #define TCPHO_MAX 0x3ffU 2463 | #define LSOPKTSIZE_MAX 0xffffU 2464 | #define MSS_MAX 0x07ffu /* MSS value */ 2465 | 2466 | #define OOB_CMD_RESET 0x00 2467 | #define OOB_CMD_DRIVER_START 0x05 2468 | #define OOB_CMD_DRIVER_STOP 0x06 2469 | #define OOB_CMD_SET_IPMAC 0x41 2470 | 2471 | #define WAKEUP_MAGIC_PACKET_NOT_SUPPORT (0) 2472 | #define WAKEUP_MAGIC_PACKET_V1 (1) 2473 | #define WAKEUP_MAGIC_PACKET_V2 (2) 2474 | 2475 | //Ram Code Version 2476 | #define NIC_RAMCODE_VERSION_CFG_METHOD_14 (0x0057) 2477 | #define NIC_RAMCODE_VERSION_CFG_METHOD_16 (0x0055) 2478 | #define NIC_RAMCODE_VERSION_CFG_METHOD_18 (0x0052) 2479 | #define NIC_RAMCODE_VERSION_CFG_METHOD_20 (0x0044) 2480 | #define NIC_RAMCODE_VERSION_CFG_METHOD_21 (0x0042) 2481 | #define NIC_RAMCODE_VERSION_CFG_METHOD_24 (0x0001) 2482 | #define NIC_RAMCODE_VERSION_CFG_METHOD_23 (0x0015) 2483 | #define NIC_RAMCODE_VERSION_CFG_METHOD_26 (0x0012) 2484 | #define NIC_RAMCODE_VERSION_CFG_METHOD_28 (0x0019) 2485 | #define NIC_RAMCODE_VERSION_CFG_METHOD_29 (0x0083) 2486 | #define NIC_RAMCODE_VERSION_CFG_METHOD_31 (0x0003) 2487 | #define NIC_RAMCODE_VERSION_CFG_METHOD_35 (0x0027) 2488 | #define NIC_RAMCODE_VERSION_CFG_METHOD_36 (0x0000) 2489 | 2490 | //hwoptimize 2491 | #define HW_PATCH_SOC_LAN (BIT_0) 2492 | #define HW_PATCH_SAMSUNG_LAN_DONGLE (BIT_2) 2493 | 2494 | static const u8 other_q_intr_mask = (RxOK1 | RxDU1); 2495 | 2496 | #define HW_PHY_STATUS_INI 1 2497 | #define HW_PHY_STATUS_EXT_INI 2 2498 | #define HW_PHY_STATUS_LAN_ON 3 2499 | 2500 | void rtl8168_mdio_write(struct rtl8168_private *tp, u16 RegAddr, u16 value); 2501 | void rtl8168_mdio_prot_write(struct rtl8168_private *tp, u32 RegAddr, u32 value); 2502 | void rtl8168_mdio_prot_direct_write_phy_ocp(struct rtl8168_private *tp, u32 RegAddr, u32 value); 2503 | u32 rtl8168_mdio_read(struct rtl8168_private *tp, u16 RegAddr); 2504 | u32 rtl8168_mdio_prot_read(struct rtl8168_private *tp, u32 RegAddr); 2505 | u32 rtl8168_mdio_prot_direct_read_phy_ocp(struct rtl8168_private *tp, u32 RegAddr); 2506 | void rtl8168_ephy_write(struct rtl8168_private *tp, int RegAddr, int value); 2507 | void rtl8168_mac_ocp_write(struct rtl8168_private *tp, u16 reg_addr, u16 value); 2508 | u16 rtl8168_mac_ocp_read(struct rtl8168_private *tp, u16 reg_addr); 2509 | void rtl8168_clear_eth_phy_bit(struct rtl8168_private *tp, u8 addr, u16 mask); 2510 | void rtl8168_set_eth_phy_bit(struct rtl8168_private *tp, u8 addr, u16 mask); 2511 | void rtl8168_ocp_write(struct rtl8168_private *tp, u16 addr, u8 len, u32 data); 2512 | void rtl8168_oob_notify(struct rtl8168_private *tp, u8 cmd); 2513 | void rtl8168_init_ring_indexes(struct rtl8168_private *tp); 2514 | int rtl8168_eri_write(struct rtl8168_private *tp, int addr, int len, u32 value, int type); 2515 | void rtl8168_oob_mutex_lock(struct rtl8168_private *tp); 2516 | u32 rtl8168_ocp_read(struct rtl8168_private *tp, u16 addr, u8 len); 2517 | u32 rtl8168_ocp_read_with_oob_base_address(struct rtl8168_private *tp, u16 addr, u8 len, u32 base_address); 2518 | u32 rtl8168_ocp_write_with_oob_base_address(struct rtl8168_private *tp, u16 addr, u8 len, u32 value, u32 base_address); 2519 | u32 rtl8168_eri_read(struct rtl8168_private *tp, int addr, int len, int type); 2520 | u32 rtl8168_eri_read_with_oob_base_address(struct rtl8168_private *tp, int addr, int len, int type, u32 base_address); 2521 | int rtl8168_eri_write_with_oob_base_address(struct rtl8168_private *tp, int addr, int len, u32 value, int type, u32 base_address); 2522 | u16 rtl8168_ephy_read(struct rtl8168_private *tp, int RegAddr); 2523 | void rtl8168_wait_txrx_fifo_empty(struct net_device *dev); 2524 | void rtl8168_wait_ll_share_fifo_ready(struct net_device *dev); 2525 | void rtl8168_enable_now_is_oob(struct rtl8168_private *tp); 2526 | void rtl8168_disable_now_is_oob(struct rtl8168_private *tp); 2527 | void rtl8168_oob_mutex_unlock(struct rtl8168_private *tp); 2528 | void rtl8168_dash2_disable_tx(struct rtl8168_private *tp); 2529 | void rtl8168_dash2_enable_tx(struct rtl8168_private *tp); 2530 | void rtl8168_dash2_disable_rx(struct rtl8168_private *tp); 2531 | void rtl8168_dash2_enable_rx(struct rtl8168_private *tp); 2532 | void rtl8168_hw_disable_mac_mcu_bps(struct net_device *dev); 2533 | void rtl8168_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz); 2534 | 2535 | static inline struct RxDesc* 2536 | rtl8168_get_rxdesc(struct rtl8168_private *tp, struct RxDesc *RxDescBase, u32 const cur_rx, u32 const q_num) 2537 | { 2538 | u8 *desc = (u8*)RxDescBase; 2539 | u32 offset; 2540 | 2541 | WARN_ON_ONCE(q_num >= tp->num_hw_tot_en_rx_rings); 2542 | 2543 | if (tp->InitRxDescType == RX_DESC_RING_TYPE_2) 2544 | offset = (cur_rx * tp->num_hw_tot_en_rx_rings) + q_num; 2545 | else 2546 | offset = cur_rx; 2547 | 2548 | offset *= tp->RxDescLength; 2549 | desc += offset; 2550 | 2551 | return (struct RxDesc*)desc; 2552 | } 2553 | 2554 | #ifdef ENABLE_DASH_SUPPORT 2555 | 2556 | static inline void 2557 | rtl8168_enable_dash2_interrupt(struct rtl8168_private *tp) 2558 | { 2559 | if (!tp->DASH) 2560 | return; 2561 | 2562 | if (HW_DASH_SUPPORT_CMAC(tp)) 2563 | 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)); 2564 | } 2565 | 2566 | static inline void 2567 | rtl8168_disable_dash2_interrupt(struct rtl8168_private *tp) 2568 | { 2569 | if (!tp->DASH) 2570 | return; 2571 | 2572 | if (HW_DASH_SUPPORT_CMAC(tp)) 2573 | RTL_CMAC_W8(tp, CMAC_IBIMR0, 0); 2574 | } 2575 | #endif 2576 | 2577 | static inline void 2578 | rtl8168_disable_interrupt_by_vector(struct rtl8168_private *tp, 2579 | u32 message_id) 2580 | { 2581 | if (message_id >= R8168_MAX_MSIX_VEC) 2582 | return; 2583 | 2584 | if (message_id == 0) { 2585 | RTL_W16(tp, tp->imr_reg[0], 0x0000); 2586 | #ifdef ENABLE_DASH_SUPPORT 2587 | if (tp->DASH) 2588 | rtl8168_disable_dash2_interrupt(tp); 2589 | #endif 2590 | } else 2591 | RTL_W8(tp, tp->imr_reg[message_id], 0x00); 2592 | } 2593 | 2594 | static inline void 2595 | rtl8168_enable_interrupt_by_vector(struct rtl8168_private *tp, 2596 | u32 message_id) 2597 | { 2598 | if (message_id >= R8168_MAX_MSIX_VEC) 2599 | return; 2600 | 2601 | if (message_id == 0) { 2602 | RTL_W16(tp, tp->imr_reg[0], tp->intr_mask); 2603 | #ifdef ENABLE_DASH_SUPPORT 2604 | if (tp->DASH) 2605 | rtl8168_enable_dash2_interrupt(tp); 2606 | #endif 2607 | } else { 2608 | RTL_W8(tp, tp->imr_reg[message_id], other_q_intr_mask); 2609 | } 2610 | } 2611 | 2612 | int rtl8168_open(struct net_device *dev); 2613 | int rtl8168_close(struct net_device *dev); 2614 | void rtl8168_hw_config(struct net_device *dev); 2615 | void rtl8168_hw_start(struct net_device *dev); 2616 | void rtl8168_hw_reset(struct net_device *dev); 2617 | void rtl8168_tx_clear(struct rtl8168_private *tp); 2618 | void rtl8168_rx_clear(struct rtl8168_private *tp); 2619 | int rtl8168_init_ring(struct net_device *dev); 2620 | int rtl8168_dump_tally_counter(struct rtl8168_private *tp, dma_addr_t paddr); 2621 | void rtl8168_enable_napi(struct rtl8168_private *tp); 2622 | void _rtl8168_wait_for_quiescence(struct net_device *dev); 2623 | 2624 | #ifndef ENABLE_LIB_SUPPORT 2625 | static inline void rtl8168_lib_reset_prepare(struct rtl8168_private *tp) { } 2626 | static inline void rtl8168_lib_reset_complete(struct rtl8168_private *tp) { } 2627 | #endif 2628 | 2629 | #define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0) 2630 | #define HW_SUPP_SERDES_PHY(_M) ((_M)->HwSuppSerDesPhyVer > 0) 2631 | #define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0) 2632 | #define HW_SUPPORT_UPS_MODE(_M) ((_M)->HwSuppUpsVer > 0) 2633 | #define HW_RSS_SUPPORT_RSS(_M) ((_M)->HwSuppRssVer > 0) 2634 | 2635 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) 2636 | #define netdev_mc_count(dev) ((dev)->mc_count) 2637 | #define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) 2638 | #define netdev_for_each_mc_addr(mclist, dev) \ 2639 | for (mclist = dev->mc_list; mclist; mclist = mclist->next) 2640 | #endif 2641 | --------------------------------------------------------------------------------