From 971f0c6e7085963588ca3b030c562c122c6c0026 Mon Sep 17 00:00:00 2001 From: Fabio Belavenuto Date: Fri, 1 Jul 2022 18:52:57 -0300 Subject: [PATCH] Added r8125 addon --- addons/r8125/install.sh | 4 + addons/r8125/manifest.yml | 25 + addons/r8125/src/4.4.180/Makefile | 88 + addons/r8125/src/4.4.180/r8125.h | 2536 +++ addons/r8125/src/4.4.180/r8125_dash.h | 261 + addons/r8125/src/4.4.180/r8125_firmware.c | 264 + addons/r8125/src/4.4.180/r8125_firmware.h | 68 + addons/r8125/src/4.4.180/r8125_n.c | 15803 ++++++++++++++++ addons/r8125/src/4.4.180/r8125_ptp.c | 594 + addons/r8125/src/4.4.180/r8125_ptp.h | 81 + addons/r8125/src/4.4.180/r8125_realwow.h | 118 + addons/r8125/src/4.4.180/r8125_rss.c | 481 + addons/r8125/src/4.4.180/r8125_rss.h | 69 + addons/r8125/src/4.4.180/rtl_eeprom.c | 289 + addons/r8125/src/4.4.180/rtl_eeprom.h | 53 + addons/r8125/src/4.4.180/rtltool.c | 260 + addons/r8125/src/4.4.180/rtltool.h | 86 + .../opt/arpl/model-configs/DS1621+.yml | 2 + .../opt/arpl/model-configs/DS3622xs+.yml | 4 +- .../p3/addons/r8125/apollolake-4.4.180.tgz | Bin 0 -> 67101 bytes .../p3/addons/r8125/broadwell-4.4.180.tgz | Bin 0 -> 66406 bytes .../p3/addons/r8125/broadwellnk-4.4.180.tgz | Bin 0 -> 66405 bytes .../p3/addons/r8125/denverton-4.4.180.tgz | Bin 0 -> 67002 bytes .../p3/addons/r8125/geminilake-4.4.180.tgz | Bin 0 -> 66402 bytes files/board/arpl/p3/addons/r8125/manifest.yml | 25 + .../arpl/p3/addons/r8125/purley-4.4.180.tgz | Bin 0 -> 66406 bytes .../arpl/p3/addons/r8125/v1000-4.4.180.tgz | Bin 0 -> 66400 bytes 27 files changed, 21109 insertions(+), 2 deletions(-) create mode 100644 addons/r8125/install.sh create mode 100644 addons/r8125/manifest.yml create mode 100755 addons/r8125/src/4.4.180/Makefile create mode 100755 addons/r8125/src/4.4.180/r8125.h create mode 100755 addons/r8125/src/4.4.180/r8125_dash.h create mode 100755 addons/r8125/src/4.4.180/r8125_firmware.c create mode 100755 addons/r8125/src/4.4.180/r8125_firmware.h create mode 100755 addons/r8125/src/4.4.180/r8125_n.c create mode 100755 addons/r8125/src/4.4.180/r8125_ptp.c create mode 100755 addons/r8125/src/4.4.180/r8125_ptp.h create mode 100755 addons/r8125/src/4.4.180/r8125_realwow.h create mode 100755 addons/r8125/src/4.4.180/r8125_rss.c create mode 100755 addons/r8125/src/4.4.180/r8125_rss.h create mode 100755 addons/r8125/src/4.4.180/rtl_eeprom.c create mode 100755 addons/r8125/src/4.4.180/rtl_eeprom.h create mode 100755 addons/r8125/src/4.4.180/rtltool.c create mode 100755 addons/r8125/src/4.4.180/rtltool.h create mode 100644 files/board/arpl/p3/addons/r8125/apollolake-4.4.180.tgz create mode 100644 files/board/arpl/p3/addons/r8125/broadwell-4.4.180.tgz create mode 100644 files/board/arpl/p3/addons/r8125/broadwellnk-4.4.180.tgz create mode 100644 files/board/arpl/p3/addons/r8125/denverton-4.4.180.tgz create mode 100644 files/board/arpl/p3/addons/r8125/geminilake-4.4.180.tgz create mode 100644 files/board/arpl/p3/addons/r8125/manifest.yml create mode 100644 files/board/arpl/p3/addons/r8125/purley-4.4.180.tgz create mode 100644 files/board/arpl/p3/addons/r8125/v1000-4.4.180.tgz diff --git a/addons/r8125/install.sh b/addons/r8125/install.sh new file mode 100644 index 00000000..98bfddff --- /dev/null +++ b/addons/r8125/install.sh @@ -0,0 +1,4 @@ +if [ "${1}" = "rd" ]; then + echo "Installing module for RealTek RTL8125 2.5Gigabit PCI-e Ethernet adapter" + ${INSMOD} "/modules/r8125.ko" ${PARAMS} +fi diff --git a/addons/r8125/manifest.yml b/addons/r8125/manifest.yml new file mode 100644 index 00000000..9a7074c3 --- /dev/null +++ b/addons/r8125/manifest.yml @@ -0,0 +1,25 @@ +version: 1 +name: r8125 +description: "Driver for RealTek RTL8125 2.5Gigabit PCI-e Ethernet adapter" +available-for: + apollolake-4.4.180: + install-script: &script "install.sh" + modules: true + broadwell-4.4.180: + install-script: *script + modules: true + broadwellnk-4.4.180: + install-script: *script + modules: true + denverton-4.4.180: + install-script: *script + modules: true + geminilake-4.4.180: + install-script: *script + modules: true + v1000-4.4.180: + install-script: *script + modules: true + purley-4.4.180: + install-script: *script + modules: true diff --git a/addons/r8125/src/4.4.180/Makefile b/addons/r8125/src/4.4.180/Makefile new file mode 100755 index 00000000..d8c99bff --- /dev/null +++ b/addons/r8125/src/4.4.180/Makefile @@ -0,0 +1,88 @@ +CONFIG_SOC_LAN = n +ENABLE_REALWOW_SUPPORT = n +ENABLE_DASH_SUPPORT = n +ENABLE_DASH_PRINTER_SUPPORT = n +CONFIG_DOWN_SPEED_100 = n +CONFIG_ASPM = y +ENABLE_S5WOL = y +ENABLE_S5_KEEP_CURR_MAC = n +ENABLE_EEE = y +ENABLE_S0_MAGIC_PACKET = n +ENABLE_TX_NO_CLOSE = y +ENABLE_MULTIPLE_TX_QUEUE = n +ENABLE_PTP_SUPPORT = n +ENABLE_PTP_MASTER_MODE = n +ENABLE_RSS_SUPPORT = n +ENABLE_LIB_SUPPORT = n +ENABLE_USE_FIRMWARE_FILE = n +DISABLE_PM_SUPPORT = n +DISABLE_MULTI_MSIX_VECTOR = n + +obj-m := r8125.o +r8125-objs := r8125_n.o rtl_eeprom.o rtltool.o +ifeq ($(CONFIG_SOC_LAN), y) + EXTRA_CFLAGS += -DCONFIG_SOC_LAN +endif +ifeq ($(ENABLE_REALWOW_SUPPORT), y) + r8125-objs += r8125_realwow.o + EXTRA_CFLAGS += -DENABLE_REALWOW_SUPPORT +endif +ifeq ($(ENABLE_DASH_SUPPORT), y) + r8125-objs += r8125_dash.o + EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT +endif +ifeq ($(ENABLE_DASH_PRINTER_SUPPORT), y) + r8125-objs += r8125_dash.o + EXTRA_CFLAGS += -DENABLE_DASH_SUPPORT -DENABLE_DASH_PRINTER_SUPPORT +endif +EXTRA_CFLAGS += -DCONFIG_R8125_NAPI +EXTRA_CFLAGS += -DCONFIG_R8125_VLAN +ifeq ($(CONFIG_DOWN_SPEED_100), y) + EXTRA_CFLAGS += -DCONFIG_DOWN_SPEED_100 +endif +ifeq ($(CONFIG_ASPM), y) + EXTRA_CFLAGS += -DCONFIG_ASPM +endif +ifeq ($(ENABLE_S5WOL), y) + EXTRA_CFLAGS += -DENABLE_S5WOL +endif +ifeq ($(ENABLE_S5_KEEP_CURR_MAC), y) + EXTRA_CFLAGS += -DENABLE_S5_KEEP_CURR_MAC +endif +ifeq ($(ENABLE_EEE), y) + EXTRA_CFLAGS += -DENABLE_EEE +endif +ifeq ($(ENABLE_S0_MAGIC_PACKET), y) + EXTRA_CFLAGS += -DENABLE_S0_MAGIC_PACKET +endif +ifeq ($(ENABLE_TX_NO_CLOSE), y) + EXTRA_CFLAGS += -DENABLE_TX_NO_CLOSE +endif +ifeq ($(ENABLE_MULTIPLE_TX_QUEUE), y) + EXTRA_CFLAGS += -DENABLE_MULTIPLE_TX_QUEUE +endif +ifeq ($(ENABLE_PTP_SUPPORT), y) + r8125-objs += r8125_ptp.o + EXTRA_CFLAGS += -DENABLE_PTP_SUPPORT +endif +ifeq ($(ENABLE_PTP_MASTER_MODE), y) + EXTRA_CFLAGS += -DENABLE_PTP_MASTER_MODE +endif +ifeq ($(ENABLE_RSS_SUPPORT), y) + r8125-objs += r8125_rss.o + EXTRA_CFLAGS += -DENABLE_RSS_SUPPORT +endif +ifeq ($(ENABLE_LIB_SUPPORT), y) + r8125-objs += r8125_lib.o + EXTRA_CFLAGS += -DENABLE_LIB_SUPPORT +endif +ifeq ($(ENABLE_USE_FIRMWARE_FILE), y) + r8125-objs += r8125_firmware.o + EXTRA_CFLAGS += -DENABLE_USE_FIRMWARE_FILE +endif +ifeq ($(DISABLE_PM_SUPPORT), y) + EXTRA_CFLAGS += -DDISABLE_PM_SUPPORT +endif +ifeq ($(DISABLE_MULTI_MSIX_VECTOR), y) + EXTRA_CFLAGS += -DDISABLE_MULTI_MSIX_VECTOR +endif diff --git a/addons/r8125/src/4.4.180/r8125.h b/addons/r8125/src/4.4.180/r8125.h new file mode 100755 index 00000000..d48ab769 --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125.h @@ -0,0 +1,2536 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef __R8125_H +#define __R8125_H + +//#include +#include +#include +#include +#include "r8125_dash.h" +#include "r8125_realwow.h" +#include "r8125_ptp.h" +#include "r8125_rss.h" +#ifdef ENABLE_LIB_SUPPORT +#include "r8125_lib.h" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) +typedef int netdev_tx_t; +#endif + +/* +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)&& !defined(ENABLE_LIB_SUPPORT) +#define RTL_USE_NEW_INTR_API +#endif +*/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define skb_transport_offset(skb) (skb->h.raw - skb->data) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) +#define device_set_wakeup_enable(dev, val) do {} while (0) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) +static inline void ether_addr_copy(u8 *dst, const u8 *src) +{ + u16 *a = (u16 *)dst; + const u16 *b = (const u16 *)src; + + a[0] = b[0]; + a[1] = b[1]; + a[2] = b[2]; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0) +#define IS_ERR_OR_NULL(ptr) (!ptr) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) +#define reinit_completion(x) ((x)->done = 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#define pm_runtime_mark_last_busy(x) +#define pm_runtime_put_autosuspend(x) pm_runtime_put(x) +#define pm_runtime_put_sync_autosuspend(x) pm_runtime_put_sync(x) + +static inline bool pm_runtime_suspended(struct device *dev) +{ + return dev->power.runtime_status == RPM_SUSPENDED + && !dev->power.disable_depth; +} + +static inline bool pm_runtime_active(struct device *dev) +{ + return dev->power.runtime_status == RPM_ACTIVE + || dev->power.disable_depth; +} +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) +#define queue_delayed_work(long_wq, work, delay) schedule_delayed_work(work, delay) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#define netif_printk(priv, type, level, netdev, fmt, args...) \ + do { \ + if (netif_msg_##type(priv)) \ + printk(level "%s: " fmt,(netdev)->name , ##args); \ + } while (0) + +#define netif_emerg(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_EMERG, netdev, fmt, ##args) +#define netif_alert(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_ALERT, netdev, fmt, ##args) +#define netif_crit(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_CRIT, netdev, fmt, ##args) +#define netif_err(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_ERR, netdev, fmt, ##args) +#define netif_warn(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_WARNING, netdev, fmt, ##args) +#define netif_notice(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_NOTICE, netdev, fmt, ##args) +#define netif_info(priv, type, netdev, fmt, args...) \ + netif_printk(priv, type, KERN_INFO, (netdev), fmt, ##args) +#endif +#endif +#endif +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +#define setup_timer(_timer, _function, _data) \ +do { \ + (_timer)->function = _function; \ + (_timer)->data = _data; \ + init_timer(_timer); \ +} while (0) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) +#if defined(skb_vlan_tag_present) && !defined(vlan_tx_tag_present) +#define vlan_tx_tag_present skb_vlan_tag_present +#endif +#if defined(skb_vlan_tag_get) && !defined(vlan_tx_tag_get) +#define vlan_tx_tag_get skb_vlan_tag_get +#endif +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) + +#define RTL_ALLOC_SKB_INTR(napi, length) dev_alloc_skb(length) +#ifdef CONFIG_R8125_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) +#undef RTL_ALLOC_SKB_INTR +#define RTL_ALLOC_SKB_INTR(napi, length) napi_alloc_skb(napi, length) +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) +#define eth_random_addr(addr) random_ether_addr(addr) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) +#define netdev_features_t u32 +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) +#define NETIF_F_ALL_CSUM NETIF_F_CSUM_MASK +#else +#ifndef NETIF_F_ALL_CSUM +#define NETIF_F_ALL_CSUM NETIF_F_CSUM_MASK +#endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) +#define ENABLE_R8125_PROCFS +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +#define NETIF_F_HW_VLAN_RX NETIF_F_HW_VLAN_CTAG_RX +#define NETIF_F_HW_VLAN_TX NETIF_F_HW_VLAN_CTAG_TX +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) +#define __devinit +#define __devexit +#define __devexit_p(func) func +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#define CHECKSUM_PARTIAL CHECKSUM_HW +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#define irqreturn_t void +#define IRQ_HANDLED 1 +#define IRQ_NONE 0 +#define IRQ_RETVAL(x) +#endif + +#ifndef NETIF_F_RXALL +#define NETIF_F_RXALL 0 +#endif + +#ifndef NETIF_F_RXFCS +#define NETIF_F_RXFCS 0 +#endif + +#ifndef HAVE_FREE_NETDEV +#define free_netdev(x) kfree(x) +#endif + +#ifndef SET_NETDEV_DEV +#define SET_NETDEV_DEV(net, pdev) +#endif + +#ifndef SET_MODULE_OWNER +#define SET_MODULE_OWNER(dev) +#endif + +#ifndef SA_SHIRQ +#define SA_SHIRQ IRQF_SHARED +#endif + +#ifndef NETIF_F_GSO +#define gso_size tso_size +#define gso_segs tso_segs +#endif + +#ifndef PCI_VENDOR_ID_DLINK +#define PCI_VENDOR_ID_DLINK 0x1186 +#endif + +#ifndef dma_mapping_error +#define dma_mapping_error(a,b) 0 +#endif + +#ifndef netif_err +#define netif_err(a,b,c,d) +#endif + +#ifndef AUTONEG_DISABLE +#define AUTONEG_DISABLE 0x00 +#endif + +#ifndef AUTONEG_ENABLE +#define AUTONEG_ENABLE 0x01 +#endif + +#ifndef BMCR_SPEED1000 +#define BMCR_SPEED1000 0x0040 +#endif + +#ifndef BMCR_SPEED100 +#define BMCR_SPEED100 0x2000 +#endif + +#ifndef BMCR_SPEED10 +#define BMCR_SPEED10 0x0000 +#endif + +#ifndef SPEED_UNKNOWN +#define SPEED_UNKNOWN -1 +#endif + +#ifndef DUPLEX_UNKNOWN +#define DUPLEX_UNKNOWN 0xff +#endif + +#ifndef SUPPORTED_Pause +#define SUPPORTED_Pause (1 << 13) +#endif + +#ifndef SUPPORTED_Asym_Pause +#define SUPPORTED_Asym_Pause (1 << 14) +#endif + +#ifndef MDIO_EEE_100TX +#define MDIO_EEE_100TX 0x0002 +#endif + +#ifndef MDIO_EEE_1000T +#define MDIO_EEE_1000T 0x0004 +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +#ifdef CONFIG_NET_POLL_CONTROLLER +#define RTL_NET_POLL_CONTROLLER dev->poll_controller=rtl8125_netpoll +#else +#define RTL_NET_POLL_CONTROLLER +#endif + +#ifdef CONFIG_R8125_VLAN +#define RTL_SET_VLAN dev->vlan_rx_register=rtl8125_vlan_rx_register +#else +#define RTL_SET_VLAN +#endif + +#define RTL_NET_DEVICE_OPS(ops) dev->open=rtl8125_open; \ + dev->hard_start_xmit=rtl8125_start_xmit; \ + dev->get_stats=rtl8125_get_stats; \ + dev->stop=rtl8125_close; \ + dev->tx_timeout=rtl8125_tx_timeout; \ + dev->set_multicast_list=rtl8125_set_rx_mode; \ + dev->change_mtu=rtl8125_change_mtu; \ + dev->set_mac_address=rtl8125_set_mac_address; \ + dev->do_ioctl=rtl8125_do_ioctl; \ + RTL_NET_POLL_CONTROLLER; \ + RTL_SET_VLAN; +#else +#define RTL_NET_DEVICE_OPS(ops) dev->netdev_ops=&ops +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef false +#define false 0 +#endif + +#ifndef true +#define true 1 +#endif + +//Hardware will continue interrupt 10 times after interrupt finished. +#define RTK_KEEP_INTERRUPT_COUNT (10) + +//the low 32 bit address of receive buffer must be 8-byte alignment. +#ifndef NET_IP_ALIGN +#define NET_IP_ALIGN 2 +#endif +#define RTK_RX_ALIGN 8 + +#ifdef CONFIG_R8125_NAPI +#define NAPI_SUFFIX "-NAPI" +#else +#define NAPI_SUFFIX "" +#endif +#if defined(ENABLE_DASH_PRINTER_SUPPORT) +#define DASH_SUFFIX "-PRINTER" +#elif defined(ENABLE_DASH_SUPPORT) +#define DASH_SUFFIX "-DASH" +#else +#define DASH_SUFFIX "" +#endif + +#if defined(ENABLE_REALWOW_SUPPORT) +#define REALWOW_SUFFIX "-REALWOW" +#else +#define REALWOW_SUFFIX "" +#endif + +#if defined(ENABLE_PTP_SUPPORT) +#define PTP_SUFFIX "-PTP" +#else +#define PTP_SUFFIX "" +#endif + +#if defined(ENABLE_RSS_SUPPORT) +#define RSS_SUFFIX "-RSS" +#else +#define RSS_SUFFIX "" +#endif + +#define RTL8125_VERSION "9.009.01" NAPI_SUFFIX DASH_SUFFIX REALWOW_SUFFIX PTP_SUFFIX RSS_SUFFIX +#define MODULENAME "r8125" +#define PFX MODULENAME ": " + +#define GPL_CLAIM "\ +r8125 Copyright (C) 2022 Realtek NIC software team \n \ +This program comes with ABSOLUTELY NO WARRANTY; for details, please see . \n \ +This is free software, and you are welcome to redistribute it under certain conditions; see . \n" + +#ifdef RTL8125_DEBUG +#define assert(expr) \ + if(!(expr)) { \ + printk( "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr,__FILE__,__FUNCTION__,__LINE__); \ + } +#define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) +#else +#define assert(expr) do {} while (0) +#define dprintk(fmt, args...) do {} while (0) +#endif /* RTL8125_DEBUG */ + +#define R8125_MSG_DEFAULT \ + (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN) + +#ifdef CONFIG_R8125_NAPI +#define rtl8125_rx_hwaccel_skb vlan_hwaccel_receive_skb +#define rtl8125_rx_quota(count, quota) min(count, quota) +#else +#define rtl8125_rx_hwaccel_skb vlan_hwaccel_rx +#define rtl8125_rx_quota(count, quota) count +#endif + +/* MAC address length */ +#ifndef MAC_ADDR_LEN +#define MAC_ADDR_LEN 6 +#endif + +#ifndef MAC_PROTOCOL_LEN +#define MAC_PROTOCOL_LEN 2 +#endif + +#ifndef ETH_FCS_LEN +#define ETH_FCS_LEN 4 +#endif + +#ifndef NETIF_F_TSO6 +#define NETIF_F_TSO6 0 +#endif + +#define Reserved2_data 7 +#define RX_DMA_BURST 7 /* Maximum PCI burst, '7' is unlimited */ +#define TX_DMA_BURST_unlimited 7 +#define TX_DMA_BURST_1024 6 +#define TX_DMA_BURST_512 5 +#define TX_DMA_BURST_256 4 +#define TX_DMA_BURST_128 3 +#define TX_DMA_BURST_64 2 +#define TX_DMA_BURST_32 1 +#define TX_DMA_BURST_16 0 +#define Reserved1_data 0x3F +#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ +#define Jumbo_Frame_1k ETH_DATA_LEN +#define Jumbo_Frame_2k (2*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_3k (3*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_4k (4*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_5k (5*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_6k (6*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_7k (7*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_8k (8*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define Jumbo_Frame_9k (9*1024 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) +#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ +#define RxEarly_off_V1 (0x07 << 11) +#define RxEarly_off_V2 (1 << 11) +#define Rx_Single_fetch_V2 (1 << 14) + +#define R8125_REGS_SIZE (256) +#define R8125_MAC_REGS_SIZE (256) +#define R8125_PHY_REGS_SIZE (16*2) +#define R8125_EPHY_REGS_SIZE (31*2) +#define R8125_ERI_REGS_SIZE (0x100) +#define R8125_REGS_DUMP_SIZE (0x400) +#define R8125_PCI_REGS_SIZE (0x100) +#define R8125_NAPI_WEIGHT 64 + +#define R8125_MAX_MSIX_VEC_8125B 32 +#define R8125_MIN_MSIX_VEC_8125B 17 +#define R8125_MAX_MSIX_VEC 32 +#define R8125_MAX_RX_QUEUES_VEC_V3 (16) + +#define RTL8125_TX_TIMEOUT (6 * HZ) +#define RTL8125_LINK_TIMEOUT (1 * HZ) +#define RTL8125_ESD_TIMEOUT (2 * HZ) + +#define MAX_NUM_TX_DESC 1024 /* Maximum number of Tx descriptor registers */ +#define MAX_NUM_RX_DESC 1024 /* Maximum number of Rx descriptor registers */ + +#define MIN_NUM_TX_DESC 256 /* Minimum number of Tx descriptor registers */ +#define MIN_NUM_RX_DESC 256 /* Minimum number of Rx descriptor registers */ + +#define NUM_TX_DESC MAX_NUM_TX_DESC /* Number of Tx descriptor registers */ +#define NUM_RX_DESC MAX_NUM_RX_DESC /* Number of Rx descriptor registers */ + +#define RX_BUF_SIZE 0x05F3 /* 0x05F3 = 1522bye + 1 */ + +#define R8125_MAX_TX_QUEUES (2) +#define R8125_MAX_RX_QUEUES (4) +#define R8125_MAX_QUEUES R8125_MAX_RX_QUEUES + +#define OCP_STD_PHY_BASE 0xa400 + +#ifdef ENABLE_LIB_SUPPORT +#define R8125_MULTI_RX_Q(tp) 0 +#else +#define R8125_MULTI_RX_Q(tp) (tp->num_rx_rings > 1) +#endif + +#define NODE_ADDRESS_SIZE 6 + +#define SHORT_PACKET_PADDING_BUF_SIZE 256 + +#define RTK_MAGIC_DEBUG_VALUE 0x0badbeef + +/* write/read MMIO register */ +#define RTL_W8(tp, reg, val8) writeb((val8), tp->mmio_addr + (reg)) +#define RTL_W16(tp, reg, val16) writew((val16), tp->mmio_addr + (reg)) +#define RTL_W32(tp, reg, val32) writel((val32), tp->mmio_addr + (reg)) +#define RTL_R8(tp, reg) readb(tp->mmio_addr + (reg)) +#define RTL_R16(tp, reg) readw(tp->mmio_addr + (reg)) +#define RTL_R32(tp, reg) ((unsigned long) readl(tp->mmio_addr + (reg))) + +#ifndef DMA_64BIT_MASK +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#endif + +#ifndef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef NETDEV_TX_OK +#define NETDEV_TX_OK 0 /* driver took care of packet */ +#endif + +#ifndef NETDEV_TX_BUSY +#define NETDEV_TX_BUSY 1 /* driver tx path was busy*/ +#endif + +#ifndef NETDEV_TX_LOCKED +#define NETDEV_TX_LOCKED -1t /* driver tx lock was already taken */ +#endif + +#ifndef ADVERTISED_Pause +#define ADVERTISED_Pause (1 << 13) +#endif + +#ifndef ADVERTISED_Asym_Pause +#define ADVERTISED_Asym_Pause (1 << 14) +#endif + +#ifndef ADVERTISE_PAUSE_CAP +#define ADVERTISE_PAUSE_CAP 0x400 +#endif + +#ifndef ADVERTISE_PAUSE_ASYM +#define ADVERTISE_PAUSE_ASYM 0x800 +#endif + +#ifndef MII_CTRL1000 +#define MII_CTRL1000 0x09 +#endif + +#ifndef ADVERTISE_1000FULL +#define ADVERTISE_1000FULL 0x200 +#endif + +#ifndef ADVERTISE_1000HALF +#define ADVERTISE_1000HALF 0x100 +#endif + +#ifndef ADVERTISED_2500baseX_Full +#define ADVERTISED_2500baseX_Full 0x8000 +#endif + +#define RTK_ADVERTISE_2500FULL 0x80 +#define RTK_LPA_ADVERTISE_2500FULL 0x20 +#define RTK_LPA_ADVERTISE_5000FULL 0x40 +#define RTK_LPA_ADVERTISE_10000FULL 0x800 + +#define RTK_EEE_ADVERTISE_2500FULL 0x01 +#define RTK_LPA_EEE_ADVERTISE_2500FULL 0x01 + +/* Tx NO CLOSE */ +#define MAX_TX_NO_CLOSE_DESC_PTR_V2 0x10000 +#define TX_NO_CLOSE_SW_PTR_MASK_V2 0x1FFFF + +#ifndef ETH_MIN_MTU +#define ETH_MIN_MTU 68 +#endif + +#define D0_SPEED_UP_SPEED_DISABLE 0 +#define D0_SPEED_UP_SPEED_1000 1 +#define D0_SPEED_UP_SPEED_2500 2 + +#define RTL8125_MAC_MCU_PAGE_SIZE 256 //256 words + +#ifndef WRITE_ONCE +#define WRITE_ONCE(var, val) (*((volatile typeof(val) *)(&(var))) = (val)) +#endif +#ifndef READ_ONCE +#define READ_ONCE(var) (*((volatile typeof(var) *)(&(var)))) +#endif + +/*****************************************************************************/ + +//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) +#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \ + (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \ + ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) ))) +/* copied from linux kernel 2.6.20 include/linux/netdev.h */ +#define NETDEV_ALIGN 32 +#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) + +static inline void *netdev_priv(struct net_device *dev) +{ + return (char *)dev + ((sizeof(struct net_device) + + NETDEV_ALIGN_CONST) + & ~NETDEV_ALIGN_CONST); +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) + +/*****************************************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define RTLDEV tp +#else +#define RTLDEV dev +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +/*****************************************************************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +typedef struct net_device *napi_ptr; +typedef int *napi_budget; + +#define napi dev +#define RTL_NAPI_CONFIG(ndev, priv, function, weig) ndev->poll=function; \ + ndev->weight=weig; +#define RTL_NAPI_QUOTA(budget, ndev) min(*budget, ndev->quota) +#define RTL_GET_PRIV(stuct_ptr, priv_struct) netdev_priv(stuct_ptr) +#define RTL_GET_NETDEV(priv_ptr) +#define RTL_RX_QUOTA(budget) *budget +#define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) *budget -= work_done; \ + ndev->quota -= work_done; +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(dev) +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev) +#define RTL_NAPI_RETURN_VALUE work_done >= work_to_do +#define RTL_NAPI_ENABLE(dev, napi) netif_poll_enable(dev) +#define RTL_NAPI_DISABLE(dev, napi) netif_poll_disable(dev) +#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) +#else +typedef struct napi_struct *napi_ptr; +typedef int napi_budget; + +#define RTL_NAPI_CONFIG(ndev, priv, function, weight) netif_napi_add(ndev, &priv->napi, function, weight) +#define RTL_NAPI_QUOTA(budget, ndev) min(budget, budget) +#define RTL_GET_PRIV(stuct_ptr, priv_struct) container_of(stuct_ptr, priv_struct, stuct_ptr) +#define RTL_GET_NETDEV(priv_ptr) struct net_device *dev = priv_ptr->dev; +#define RTL_RX_QUOTA(budget) budget +#define RTL_NAPI_QUOTA_UPDATE(ndev, work_done, budget) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(dev, napi) +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(dev, napi) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(dev, napi) +#endif +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,29) +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) netif_rx_complete(napi) +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) netif_rx_schedule_prep(napi) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __netif_rx_schedule(napi) +#endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0) +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) napi_complete_done(napi, work_done) +#else +#define RTL_NETIF_RX_COMPLETE(dev, napi, work_done) napi_complete(napi) +#endif +#define RTL_NETIF_RX_SCHEDULE_PREP(dev, napi) napi_schedule_prep(napi) +#define __RTL_NETIF_RX_SCHEDULE(dev, napi) __napi_schedule(napi) +#endif +#define RTL_NAPI_RETURN_VALUE work_done +#define RTL_NAPI_ENABLE(dev, napi) napi_enable(napi) +#define RTL_NAPI_DISABLE(dev, napi) napi_disable(napi) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) +#define RTL_NAPI_DEL(priv) +#else +#define RTL_NAPI_DEL(priv) netif_napi_del(&priv->napi) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) + +/*****************************************************************************/ +#ifdef CONFIG_R8125_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) napi_consume_skb(skb, budget) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); +#else +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) +#else //CONFIG_R8125_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_consume_skb_any(skb); +#else +#define RTL_NAPI_CONSUME_SKB_ANY(skb, budget) dev_kfree_skb_any(skb); +#endif +#endif //CONFIG_R8125_NAPI + +/*****************************************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) +#ifdef __CHECKER__ +#define __iomem __attribute__((noderef, address_space(2))) +extern void __chk_io_ptr(void __iomem *); +#define __bitwise __attribute__((bitwise)) +#else +#define __iomem +#define __chk_io_ptr(x) (void)0 +#define __bitwise +#endif +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) + +/*****************************************************************************/ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#else +#define __force +#endif +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) + +#ifndef module_param +#define module_param(v,t,p) MODULE_PARM(v, "i"); +#endif + +#ifndef PCI_DEVICE +#define PCI_DEVICE(vend,dev) \ + .vendor = (vend), .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID +#endif + +/*****************************************************************************/ +/* 2.5.28 => 2.4.23 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) + +static inline void _kc_synchronize_irq(void) +{ + synchronize_irq(); +} +#undef synchronize_irq +#define synchronize_irq(X) _kc_synchronize_irq() + +#include +#define work_struct tq_struct +#undef INIT_WORK +#define INIT_WORK(a,b,c) INIT_TQUEUE(a,(void (*)(void *))b,c) +#undef container_of +#define container_of list_entry +#define schedule_work schedule_task +#define flush_scheduled_work flush_scheduled_tasks +#endif /* 2.5.28 => 2.4.17 */ + +/*****************************************************************************/ +/* 2.6.4 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) +#define MODULE_VERSION(_version) MODULE_INFO(version, _version) +#endif /* 2.6.4 => 2.6.0 */ +/*****************************************************************************/ +/* 2.6.0 => 2.5.28 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) ) +#define MODULE_INFO(version, _version) +#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT +#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1 +#endif + +#define pci_set_consistent_dma_mask(dev,mask) 1 + +#undef dev_put +#define dev_put(dev) __dev_put(dev) + +#ifndef skb_fill_page_desc +#define skb_fill_page_desc _kc_skb_fill_page_desc +extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size); +#endif + +#ifndef pci_dma_mapping_error +#define pci_dma_mapping_error _kc_pci_dma_mapping_error +static inline int _kc_pci_dma_mapping_error(dma_addr_t dma_addr) +{ + return dma_addr == 0; +} +#endif + +#undef ALIGN +#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) + +#endif /* 2.6.0 => 2.5.28 */ + +/*****************************************************************************/ +/* 2.4.22 => 2.4.17 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) +#define pci_name(x) ((x)->slot_name) +#endif /* 2.4.22 => 2.4.17 */ + +/*****************************************************************************/ +/* 2.6.5 => 2.6.0 */ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) +#define pci_dma_sync_single_for_cpu pci_dma_sync_single +#define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu +#endif /* 2.6.5 => 2.6.0 */ + +/*****************************************************************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +/* + * initialize a work-struct's func and data pointers: + */ +#define PREPARE_WORK(_work, _func, _data) \ + do { \ + (_work)->func = _func; \ + (_work)->data = _data; \ + } while (0) + +#endif +/*****************************************************************************/ +/* 2.6.4 => 2.6.0 */ +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) && \ + LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)) || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4))) +#define ETHTOOL_OPS_COMPAT +#endif /* 2.6.4 => 2.6.0 */ + +/*****************************************************************************/ +/* Installations with ethtool version without eeprom, adapter id, or statistics + * support */ + +#ifndef ETH_GSTRING_LEN +#define ETH_GSTRING_LEN 32 +#endif + +#ifndef ETHTOOL_GSTATS +#define ETHTOOL_GSTATS 0x1d +#undef ethtool_drvinfo +#define ethtool_drvinfo k_ethtool_drvinfo +struct k_ethtool_drvinfo { + u32 cmd; + char driver[32]; + char version[32]; + char fw_version[32]; + char bus_info[32]; + char reserved1[32]; + char reserved2[16]; + u32 n_stats; + u32 testinfo_len; + u32 eedump_len; + u32 regdump_len; +}; + +struct ethtool_stats { + u32 cmd; + u32 n_stats; + u64 data[0]; +}; +#endif /* ETHTOOL_GSTATS */ + +#ifndef ETHTOOL_PHYS_ID +#define ETHTOOL_PHYS_ID 0x1c +#endif /* ETHTOOL_PHYS_ID */ + +#ifndef ETHTOOL_GSTRINGS +#define ETHTOOL_GSTRINGS 0x1b +enum ethtool_stringset { + ETH_SS_TEST = 0, + ETH_SS_STATS, +}; +struct ethtool_gstrings { + u32 cmd; /* ETHTOOL_GSTRINGS */ + u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/ + u32 len; /* number of strings in the string set */ + u8 data[0]; +}; +#endif /* ETHTOOL_GSTRINGS */ + +#ifndef ETHTOOL_TEST +#define ETHTOOL_TEST 0x1a +enum ethtool_test_flags { + ETH_TEST_FL_OFFLINE = (1 << 0), + ETH_TEST_FL_FAILED = (1 << 1), +}; +struct ethtool_test { + u32 cmd; + u32 flags; + u32 reserved; + u32 len; + u64 data[0]; +}; +#endif /* ETHTOOL_TEST */ + +#ifndef ETHTOOL_GEEPROM +#define ETHTOOL_GEEPROM 0xb +#undef ETHTOOL_GREGS +struct ethtool_eeprom { + u32 cmd; + u32 magic; + u32 offset; + u32 len; + u8 data[0]; +}; + +struct ethtool_value { + u32 cmd; + u32 data; +}; +#endif /* ETHTOOL_GEEPROM */ + +#ifndef ETHTOOL_GLINK +#define ETHTOOL_GLINK 0xa +#endif /* ETHTOOL_GLINK */ + +#ifndef ETHTOOL_GREGS +#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */ +#define ethtool_regs _kc_ethtool_regs +/* for passing big chunks of data */ +struct _kc_ethtool_regs { + u32 cmd; + u32 version; /* driver-specific, indicates different chips/revs */ + u32 len; /* bytes */ + u8 data[0]; +}; +#endif /* ETHTOOL_GREGS */ + +#ifndef ETHTOOL_GMSGLVL +#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */ +#endif +#ifndef ETHTOOL_SMSGLVL +#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */ +#endif +#ifndef ETHTOOL_NWAY_RST +#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */ +#endif +#ifndef ETHTOOL_GLINK +#define ETHTOOL_GLINK 0x0000000a /* Get link status */ +#endif +#ifndef ETHTOOL_GEEPROM +#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */ +#endif +#ifndef ETHTOOL_SEEPROM +#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */ +#endif +#ifndef ETHTOOL_GCOALESCE +#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */ +/* for configuring coalescing parameters of chip */ +#define ethtool_coalesce _kc_ethtool_coalesce +struct _kc_ethtool_coalesce { + u32 cmd; /* ETHTOOL_{G,S}COALESCE */ + + /* How many usecs to delay an RX interrupt after + * a packet arrives. If 0, only rx_max_coalesced_frames + * is used. + */ + u32 rx_coalesce_usecs; + + /* How many packets to delay an RX interrupt after + * a packet arrives. If 0, only rx_coalesce_usecs is + * used. It is illegal to set both usecs and max frames + * to zero as this would cause RX interrupts to never be + * generated. + */ + u32 rx_max_coalesced_frames; + + /* Same as above two parameters, except that these values + * apply while an IRQ is being serviced by the host. Not + * all cards support this feature and the values are ignored + * in that case. + */ + u32 rx_coalesce_usecs_irq; + u32 rx_max_coalesced_frames_irq; + + /* How many usecs to delay a TX interrupt after + * a packet is sent. If 0, only tx_max_coalesced_frames + * is used. + */ + u32 tx_coalesce_usecs; + + /* How many packets to delay a TX interrupt after + * a packet is sent. If 0, only tx_coalesce_usecs is + * used. It is illegal to set both usecs and max frames + * to zero as this would cause TX interrupts to never be + * generated. + */ + u32 tx_max_coalesced_frames; + + /* Same as above two parameters, except that these values + * apply while an IRQ is being serviced by the host. Not + * all cards support this feature and the values are ignored + * in that case. + */ + u32 tx_coalesce_usecs_irq; + u32 tx_max_coalesced_frames_irq; + + /* How many usecs to delay in-memory statistics + * block updates. Some drivers do not have an in-memory + * statistic block, and in such cases this value is ignored. + * This value must not be zero. + */ + u32 stats_block_coalesce_usecs; + + /* Adaptive RX/TX coalescing is an algorithm implemented by + * some drivers to improve latency under low packet rates and + * improve throughput under high packet rates. Some drivers + * only implement one of RX or TX adaptive coalescing. Anything + * not implemented by the driver causes these values to be + * silently ignored. + */ + u32 use_adaptive_rx_coalesce; + u32 use_adaptive_tx_coalesce; + + /* When the packet rate (measured in packets per second) + * is below pkt_rate_low, the {rx,tx}_*_low parameters are + * used. + */ + u32 pkt_rate_low; + u32 rx_coalesce_usecs_low; + u32 rx_max_coalesced_frames_low; + u32 tx_coalesce_usecs_low; + u32 tx_max_coalesced_frames_low; + + /* When the packet rate is below pkt_rate_high but above + * pkt_rate_low (both measured in packets per second) the + * normal {rx,tx}_* coalescing parameters are used. + */ + + /* When the packet rate is (measured in packets per second) + * is above pkt_rate_high, the {rx,tx}_*_high parameters are + * used. + */ + u32 pkt_rate_high; + u32 rx_coalesce_usecs_high; + u32 rx_max_coalesced_frames_high; + u32 tx_coalesce_usecs_high; + u32 tx_max_coalesced_frames_high; + + /* How often to do adaptive coalescing packet rate sampling, + * measured in seconds. Must not be zero. + */ + u32 rate_sample_interval; +}; +#endif /* ETHTOOL_GCOALESCE */ + +#ifndef ETHTOOL_SCOALESCE +#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */ +#endif +#ifndef ETHTOOL_GRINGPARAM +#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */ +/* for configuring RX/TX ring parameters */ +#define ethtool_ringparam _kc_ethtool_ringparam +struct _kc_ethtool_ringparam { + u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */ + + /* Read only attributes. These indicate the maximum number + * of pending RX/TX ring entries the driver will allow the + * user to set. + */ + u32 rx_max_pending; + u32 rx_mini_max_pending; + u32 rx_jumbo_max_pending; + u32 tx_max_pending; + + /* Values changeable by the user. The valid values are + * in the range 1 to the "*_max_pending" counterpart above. + */ + u32 rx_pending; + u32 rx_mini_pending; + u32 rx_jumbo_pending; + u32 tx_pending; +}; +#endif /* ETHTOOL_GRINGPARAM */ + +#ifndef ETHTOOL_SRINGPARAM +#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */ +#endif +#ifndef ETHTOOL_GPAUSEPARAM +#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */ +/* for configuring link flow control parameters */ +#define ethtool_pauseparam _kc_ethtool_pauseparam +struct _kc_ethtool_pauseparam { + u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */ + + /* If the link is being auto-negotiated (via ethtool_cmd.autoneg + * being true) the user may set 'autonet' here non-zero to have the + * pause parameters be auto-negotiated too. In such a case, the + * {rx,tx}_pause values below determine what capabilities are + * advertised. + * + * If 'autoneg' is zero or the link is not being auto-negotiated, + * then {rx,tx}_pause force the driver to use/not-use pause + * flow control. + */ + u32 autoneg; + u32 rx_pause; + u32 tx_pause; +}; +#endif /* ETHTOOL_GPAUSEPARAM */ + +#ifndef ETHTOOL_SPAUSEPARAM +#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */ +#endif +#ifndef ETHTOOL_GRXCSUM +#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_SRXCSUM +#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_GTXCSUM +#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_STXCSUM +#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_GSG +#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable +* (ethtool_value) */ +#endif +#ifndef ETHTOOL_SSG +#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable +* (ethtool_value). */ +#endif +#ifndef ETHTOOL_TEST +#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */ +#endif +#ifndef ETHTOOL_GSTRINGS +#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ +#endif +#ifndef ETHTOOL_PHYS_ID +#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ +#endif +#ifndef ETHTOOL_GSTATS +#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ +#endif +#ifndef ETHTOOL_GTSO +#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ +#endif +#ifndef ETHTOOL_STSO +#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ +#endif + +#ifndef ETHTOOL_BUSINFO_LEN +#define ETHTOOL_BUSINFO_LEN 32 +#endif + +/*****************************************************************************/ + +enum RTL8125_registers { + MAC0 = 0x00, /* Ethernet hardware address. */ + MAC4 = 0x04, + MAR0 = 0x08, /* Multicast filter. */ + CounterAddrLow = 0x10, + CounterAddrHigh = 0x14, + CustomLED = 0x18, + TxDescStartAddrLow = 0x20, + TxDescStartAddrHigh = 0x24, + TxHDescStartAddrLow = 0x28, + TxHDescStartAddrHigh = 0x2c, + FLASH = 0x30, + INT_CFG0_8125 = 0x34, + ERSR = 0x36, + ChipCmd = 0x37, + TxPoll = 0x38, + IntrMask = 0x3C, + IntrStatus = 0x3E, + TxConfig = 0x40, + RxConfig = 0x44, + TCTR = 0x48, + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + Config2 = 0x53, + Config3 = 0x54, + Config4 = 0x55, + Config5 = 0x56, + TDFNR = 0x57, + TimeInt0 = 0x58, + TimeInt1 = 0x5C, + PHYAR = 0x60, + CSIDR = 0x64, + CSIAR = 0x68, + PHYstatus = 0x6C, + MACDBG = 0x6D, + GPIO = 0x6E, + PMCH = 0x6F, + ERIDR = 0x70, + ERIAR = 0x74, + INT_CFG1_8125 = 0x7A, + EPHY_RXER_NUM = 0x7C, + EPHYAR = 0x80, + TimeInt2 = 0x8C, + OCPDR = 0xB0, + MACOCP = 0xB0, + OCPAR = 0xB4, + SecMAC0 = 0xB4, + SecMAC4 = 0xB8, + PHYOCP = 0xB8, + DBG_reg = 0xD1, + TwiCmdReg = 0xD2, + MCUCmd_reg = 0xD3, + RxMaxSize = 0xDA, + EFUSEAR = 0xDC, + CPlusCmd = 0xE0, + IntrMitigate = 0xE2, + RxDescAddrLow = 0xE4, + RxDescAddrHigh = 0xE8, + MTPS = 0xEC, + FuncEvent = 0xF0, + PPSW = 0xF2, + FuncEventMask = 0xF4, + TimeInt3 = 0xF4, + FuncPresetState = 0xF8, + CMAC_IBCR0 = 0xF8, + CMAC_IBCR2 = 0xF9, + CMAC_IBIMR0 = 0xFA, + CMAC_IBISR0 = 0xFB, + FuncForceEvent = 0xFC, + //8125 + IMR0_8125 = 0x38, + ISR0_8125 = 0x3C, + TPPOLL_8125 = 0x90, + IMR1_8125 = 0x800, + ISR1_8125 = 0x802, + IMR2_8125 = 0x804, + ISR2_8125 = 0x806, + IMR3_8125 = 0x808, + ISR3_8125 = 0x80A, + BACKUP_ADDR0_8125 = 0x19E0, + BACKUP_ADDR1_8125 = 0X19E4, + TCTR0_8125 = 0x0048, + TCTR1_8125 = 0x004C, + TCTR2_8125 = 0x0088, + TCTR3_8125 = 0x001C, + TIMER_INT0_8125 = 0x0058, + TIMER_INT1_8125 = 0x005C, + TIMER_INT2_8125 = 0x008C, + TIMER_INT3_8125 = 0x00F4, + INT_MITI_V2_0_RX = 0x0A00, + INT_MITI_V2_0_TX = 0x0A02, + INT_MITI_V2_1_RX = 0x0A08, + INT_MITI_V2_1_TX = 0x0A0A, + IMR_V2_CLEAR_REG_8125 = 0x0D00, + ISR_V2_8125 = 0x0D04, + IMR_V2_SET_REG_8125 = 0x0D0C, + TDU_STA_8125 = 0x0D08, + RDU_STA_8125 = 0x0D0A, + TX_NEW_CTRL = 0x203E, + TNPDS_Q1_LOW_8125 = 0x2100, + PLA_TXQ0_IDLE_CREDIT = 0x2500, + PLA_TXQ1_IDLE_CREDIT = 0x2504, + SW_TAIL_PTR0_8125 = 0x2800, + HW_CLO_PTR0_8125 = 0x2802, + RDSAR_Q1_LOW_8125 = 0x4000, + RSS_CTRL_8125 = 0x4500, + Q_NUM_CTRL_8125 = 0x4800, + RSS_KEY_8125 = 0x4600, + RSS_INDIRECTION_TBL_8125_V2 = 0x4700, + EEE_TXIDLE_TIMER_8125 = 0x6048, + PTP_CTRL_8125 = 0x6800, + PTP_STATUS_8125 = 0x6802, + PTP_ISR_8125 = 0x6804, + PTP_IMR_8125 = 0x6805, + PTP_TIME_CORRECT_CMD_8125 = 0x6806, + PTP_SOFT_CONFIG_Time_NS_8125 = 0x6808, + PTP_SOFT_CONFIG_Time_S_8125 = 0x680C, + PTP_LOCAL_Time_SUB_NS_8125 = 0x6814, + PTP_LOCAL_Time_NS_8125 = 0x6818, + PTP_LOCAL_Time_S_8125 = 0x681C, + PTP_Time_SHIFTER_S_8125 = 0x6856, + PPS_RISE_TIME_NS_8125 = 0x68A0, + PPS_RISE_TIME_S_8125 = 0x68A4, +}; + +enum RTL8125_register_content { + /* InterruptStatusBits */ + SYSErr = 0x8000, + PCSTimeout = 0x4000, + SWInt = 0x0100, + TxDescUnavail = 0x0080, + RxFIFOOver = 0x0040, + LinkChg = 0x0020, + RxDescUnavail = 0x0010, + TxErr = 0x0008, + TxOK = 0x0004, + RxErr = 0x0002, + RxOK = 0x0001, + RxDU1 = 0x0002, + RxOK1 = 0x0001, + + /* RxStatusDesc */ + RxRWT = (1 << 22), + RxRES = (1 << 21), + RxRUNT = (1 << 20), + RxCRC = (1 << 19), + + RxRWT_V3 = (1 << 18), + RxRES_V3 = (1 << 20), + RxRUNT_V3 = (1 << 19), + RxCRC_V3 = (1 << 17), + + /* ChipCmdBits */ + StopReq = 0x80, + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, + + /* Cfg9346Bits */ + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xC0, + Cfg9346_EEDO = (1 << 0), + Cfg9346_EEDI = (1 << 1), + Cfg9346_EESK = (1 << 2), + Cfg9346_EECS = (1 << 3), + Cfg9346_EEM0 = (1 << 6), + Cfg9346_EEM1 = (1 << 7), + + /* rx_mode_bits */ + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, + + /* Transmit Priority Polling*/ + HPQ = 0x80, + NPQ = 0x40, + FSWInt = 0x01, + + /* RxConfigBits */ + Reserved2_shift = 13, + RxCfgDMAShift = 8, + EnableRxDescV3 = (1 << 24), + EnableOuterVlan = (1 << 23), + EnableInnerVlan = (1 << 22), + RxCfg_128_int_en = (1 << 15), + RxCfg_fet_multi_en = (1 << 14), + RxCfg_half_refetch = (1 << 13), + RxCfg_pause_slot_en = (1 << 11), + RxCfg_9356SEL = (1 << 6), + + /* TxConfigBits */ + TxInterFrameGapShift = 24, + TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ + TxMACLoopBack = (1 << 17), /* MAC loopback */ + + /* Config1 register */ + LEDS1 = (1 << 7), + LEDS0 = (1 << 6), + Speed_down = (1 << 4), + MEMMAP = (1 << 3), + IOMAP = (1 << 2), + VPD = (1 << 1), + PMEnable = (1 << 0), /* Power Management Enable */ + + /* Config2 register */ + PMSTS_En = (1 << 5), + + /* Config3 register */ + Isolate_en = (1 << 12), /* Isolate enable */ + MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ + LinkUp = (1 << 4), /* This bit is reserved in RTL8125B.*/ + /* Wake up when the cable connection is re-established */ + ECRCEN = (1 << 3), /* This bit is reserved in RTL8125B*/ + Jumbo_En0 = (1 << 2), /* This bit is reserved in RTL8125B*/ + RDY_TO_L23 = (1 << 1), /* This bit is reserved in RTL8125B*/ + Beacon_en = (1 << 0), /* This bit is reserved in RTL8125B*/ + + /* Config4 register */ + Jumbo_En1 = (1 << 1), /* This bit is reserved in RTL8125B*/ + + /* Config5 register */ + BWF = (1 << 6), /* Accept Broadcast wakeup frame */ + MWF = (1 << 5), /* Accept Multicast wakeup frame */ + UWF = (1 << 4), /* Accept Unicast wakeup frame */ + LanWake = (1 << 1), /* LanWake enable/disable */ + PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ + + /* CPlusCmd */ + EnableBist = (1 << 15), + Macdbgo_oe = (1 << 14), + Normal_mode = (1 << 13), + Force_halfdup = (1 << 12), + Force_rxflow_en = (1 << 11), + Force_txflow_en = (1 << 10), + Cxpl_dbg_sel = (1 << 9),//This bit is reserved in RTL8125B + ASF = (1 << 8),//This bit is reserved in RTL8125C + PktCntrDisable = (1 << 7), + RxVlan = (1 << 6), + RxChkSum = (1 << 5), + Macdbgo_sel = 0x001C, + INTT_0 = 0x0000, + INTT_1 = 0x0001, + INTT_2 = 0x0002, + INTT_3 = 0x0003, + + /* rtl8125_PHYstatus */ + PowerSaveStatus = 0x80, + _2500bpsF = 0x400, + TxFlowCtrl = 0x40, + RxFlowCtrl = 0x20, + _1000bpsF = 0x10, + _100bps = 0x08, + _10bps = 0x04, + LinkStatus = 0x02, + FullDup = 0x01, + + /* DBG_reg */ + Fix_Nak_1 = (1 << 4), + Fix_Nak_2 = (1 << 3), + DBGPIN_E2 = (1 << 0), + + /* ResetCounterCommand */ + CounterReset = 0x1, + /* DumpCounterCommand */ + CounterDump = 0x8, + + /* PHY access */ + PHYAR_Flag = 0x80000000, + PHYAR_Write = 0x80000000, + PHYAR_Read = 0x00000000, + PHYAR_Reg_Mask = 0x1f, + PHYAR_Reg_shift = 16, + PHYAR_Data_Mask = 0xffff, + + /* EPHY access */ + EPHYAR_Flag = 0x80000000, + EPHYAR_Write = 0x80000000, + EPHYAR_Read = 0x00000000, + EPHYAR_Reg_Mask = 0x3f, + EPHYAR_Reg_Mask_v2 = 0x7f, + EPHYAR_Reg_shift = 16, + EPHYAR_Data_Mask = 0xffff, + + /* CSI access */ + CSIAR_Flag = 0x80000000, + CSIAR_Write = 0x80000000, + CSIAR_Read = 0x00000000, + CSIAR_ByteEn = 0x0f, + CSIAR_ByteEn_shift = 12, + CSIAR_Addr_Mask = 0x0fff, + + /* ERI access */ + ERIAR_Flag = 0x80000000, + ERIAR_Write = 0x80000000, + ERIAR_Read = 0x00000000, + ERIAR_Addr_Align = 4, /* ERI access register address must be 4 byte alignment */ + ERIAR_ExGMAC = 0, + ERIAR_MSIX = 1, + ERIAR_ASF = 2, + ERIAR_OOB = 2, + ERIAR_Type_shift = 16, + ERIAR_ByteEn = 0x0f, + ERIAR_ByteEn_shift = 12, + + /* OCP GPHY access */ + OCPDR_Write = 0x80000000, + OCPDR_Read = 0x00000000, + OCPDR_Reg_Mask = 0xFF, + OCPDR_Data_Mask = 0xFFFF, + OCPDR_GPHY_Reg_shift = 16, + OCPAR_Flag = 0x80000000, + OCPAR_GPHY_Write = 0x8000F060, + OCPAR_GPHY_Read = 0x0000F060, + OCPR_Write = 0x80000000, + OCPR_Read = 0x00000000, + OCPR_Addr_Reg_shift = 16, + OCPR_Flag = 0x80000000, + OCP_STD_PHY_BASE_PAGE = 0x0A40, + + /* MCU Command */ + Now_is_oob = (1 << 7), + Txfifo_empty = (1 << 5), + Rxfifo_empty = (1 << 4), + + /* E-FUSE access */ + EFUSE_WRITE = 0x80000000, + EFUSE_WRITE_OK = 0x00000000, + EFUSE_READ = 0x00000000, + EFUSE_READ_OK = 0x80000000, + EFUSE_WRITE_V3 = 0x40000000, + EFUSE_WRITE_OK_V3 = 0x00000000, + EFUSE_READ_V3 = 0x80000000, + EFUSE_READ_OK_V3 = 0x00000000, + EFUSE_Reg_Mask = 0x03FF, + EFUSE_Reg_Shift = 8, + EFUSE_Check_Cnt = 300, + EFUSE_READ_FAIL = 0xFF, + EFUSE_Data_Mask = 0x000000FF, + + /* GPIO */ + GPIO_en = (1 << 0), + + /* PTP */ + PTP_ISR_TOK = (1 << 1), + PTP_ISR_TER = (1 << 2), + PTP_EXEC_CMD = (1 << 7), + PTP_ADJUST_TIME_NS_NEGATIVE = (1 << 30), + PTP_ADJUST_TIME_S_NEGATIVE = (1ULL << 48), + + /* New Interrupt Bits */ + INT_CFG0_ENABLE_8125 = (1 << 0), + INT_CFG0_TIMEOUT0_BYPASS_8125 = (1 << 1), + INT_CFG0_MITIGATION_BYPASS_8125 = (1 << 2), + ISRIMR_V2_ROK_Q0 = (1 << 0), + ISRIMR_TOK_Q0 = (1 << 16), + ISRIMR_TOK_Q1 = (1 << 18), + ISRIMR_V2_LINKCHG = (1 << 21), + + /* Magic Number */ + RTL8125_MAGIC_NUMBER = 0x0badbadbadbadbadull, +}; + +enum _DescStatusBit { + DescOwn = (1 << 31), /* Descriptor is owned by NIC */ + RingEnd = (1 << 30), /* End of descriptor ring */ + FirstFrag = (1 << 29), /* First segment of a packet */ + LastFrag = (1 << 28), /* Final segment of a packet */ + + DescOwn_V3 = (DescOwn), /* Descriptor is owned by NIC */ + RingEnd_V3 = (RingEnd), /* End of descriptor ring */ + FirstFrag_V3 = (1 << 25), /* First segment of a packet */ + LastFrag_V3 = (1 << 24), /* Final segment of a packet */ + + /* Tx private */ + /*------ offset 0 of tx descriptor ------*/ + LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */ + GiantSendv4 = (1 << 26), /* TCP Giant Send Offload V4 (GSOv4) */ + GiantSendv6 = (1 << 25), /* TCP Giant Send Offload V6 (GSOv6) */ + LargeSend_DP = (1 << 16), /* TCP Large Send Offload (TSO) */ + MSSShift = 16, /* MSS value position */ + MSSMask = 0x7FFU, /* MSS value 11 bits */ + TxIPCS = (1 << 18), /* Calculate IP checksum */ + TxUDPCS = (1 << 17), /* Calculate UDP/IP checksum */ + TxTCPCS = (1 << 16), /* Calculate TCP/IP checksum */ + TxVlanTag = (1 << 17), /* Add VLAN tag */ + + /*@@@@@@ offset 4 of tx descriptor => bits for RTL8125 only begin @@@@@@*/ + TxUDPCS_C = (1 << 31), /* Calculate UDP/IP checksum */ + TxTCPCS_C = (1 << 30), /* Calculate TCP/IP checksum */ + TxIPCS_C = (1 << 29), /* Calculate IP checksum */ + TxIPV6F_C = (1 << 28), /* Indicate it is an IPv6 packet */ + /*@@@@@@ offset 4 of tx descriptor => bits for RTL8125 only end @@@@@@*/ + + + /* Rx private */ + /*------ offset 0 of rx descriptor ------*/ + PID1 = (1 << 18), /* Protocol ID bit 1/2 */ + PID0 = (1 << 17), /* Protocol ID bit 2/2 */ + +#define RxProtoUDP (PID1) +#define RxProtoTCP (PID0) +#define RxProtoIP (PID1 | PID0) +#define RxProtoMask RxProtoIP + + RxIPF = (1 << 16), /* IP checksum failed */ + RxUDPF = (1 << 15), /* UDP/IP checksum failed */ + RxTCPF = (1 << 14), /* TCP/IP checksum failed */ + RxVlanTag = (1 << 16), /* VLAN tag available */ + + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxUDPT = (1 << 18), + RxTCPT = (1 << 17), + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only end @@@@@@*/ + + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxV6F = (1 << 31), + RxV4F = (1 << 30), + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/ + + + PID1_v3 = (1 << 29), /* Protocol ID bit 1/2 */ + PID0_v3 = (1 << 28), /* Protocol ID bit 2/2 */ + +#define RxProtoUDP_v3 (PID1_v3) +#define RxProtoTCP_v3 (PID0_v3) +#define RxProtoIP_v3 (PID1_v3 | PID0_v3) +#define RxProtoMask_v3 RxProtoIP_v3 + + RxIPF_v3 = (1 << 26), /* IP checksum failed */ + RxUDPF_v3 = (1 << 25), /* UDP/IP checksum failed */ + RxTCPF_v3 = (1 << 24), /* TCP/IP checksum failed */ + RxSCTPF_v3 = (1 << 23), /* TCP/IP checksum failed */ + RxVlanTag_v3 = (RxVlanTag), /* VLAN tag available */ + + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxUDPT_v3 = (1 << 29), + RxTCPT_v3 = (1 << 28), + RxSCTP_v3 = (1 << 27), + /*@@@@@@ offset 0 of rx descriptor => bits for RTL8125 only end @@@@@@*/ + + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only begin @@@@@@*/ + RxV6F_v3 = (RxV6F), + RxV4F_v3 = (RxV4F), + /*@@@@@@ offset 4 of rx descriptor => bits for RTL8125 only end @@@@@@*/ +}; + +enum features { +// RTL_FEATURE_WOL = (1 << 0), + RTL_FEATURE_MSI = (1 << 1), + RTL_FEATURE_MSIX = (1 << 2), +}; + +enum wol_capability { + WOL_DISABLED = 0, + WOL_ENABLED = 1 +}; + +enum bits { + BIT_0 = (1 << 0), + BIT_1 = (1 << 1), + BIT_2 = (1 << 2), + BIT_3 = (1 << 3), + BIT_4 = (1 << 4), + BIT_5 = (1 << 5), + BIT_6 = (1 << 6), + BIT_7 = (1 << 7), + BIT_8 = (1 << 8), + BIT_9 = (1 << 9), + BIT_10 = (1 << 10), + BIT_11 = (1 << 11), + BIT_12 = (1 << 12), + BIT_13 = (1 << 13), + BIT_14 = (1 << 14), + BIT_15 = (1 << 15), + BIT_16 = (1 << 16), + BIT_17 = (1 << 17), + BIT_18 = (1 << 18), + BIT_19 = (1 << 19), + BIT_20 = (1 << 20), + BIT_21 = (1 << 21), + BIT_22 = (1 << 22), + BIT_23 = (1 << 23), + BIT_24 = (1 << 24), + BIT_25 = (1 << 25), + BIT_26 = (1 << 26), + BIT_27 = (1 << 27), + BIT_28 = (1 << 28), + BIT_29 = (1 << 29), + BIT_30 = (1 << 30), + BIT_31 = (1 << 31) +}; + +enum effuse { + EFUSE_NOT_SUPPORT = 0, + EFUSE_SUPPORT_V1, + EFUSE_SUPPORT_V2, + EFUSE_SUPPORT_V3, + EFUSE_SUPPORT_V4, +}; +#define RsvdMask 0x3fffc000 +#define RsvdMaskV3 0x3fff8000 + +struct TxDesc { + u32 opts1; + u32 opts2; + u64 addr; + u32 reserved0; + u32 reserved1; + u32 reserved2; + u32 reserved3; +}; + +struct RxDesc { + u32 opts1; + u32 opts2; + u64 addr; +}; + +struct RxDescV3 { + union { + struct { + u32 rsv1; + u32 rsv2; + } RxDescDDWord1; + }; + + union { + struct { + u32 RSSResult; + u16 HeaderBufferLen; + u16 HeaderInfo; + } RxDescNormalDDWord2; + + struct { + u32 rsv5; + u32 rsv6; + } RxDescDDWord2; + }; + + union { + u64 addr; + + struct { + u32 TimeStampLow; + u32 TimeStampHigh; + } RxDescTimeStamp; + + struct { + u32 rsv8; + u32 rsv9; + } RxDescDDWord3; + }; + + union { + struct { + u32 opts2; + u32 opts1; + } RxDescNormalDDWord4; + + struct { + u16 TimeStampHHigh; + u16 rsv11; + u32 opts1; + } RxDescPTPDDWord4; + }; +}; + +enum rxdesc_type { + RXDESC_TYPE_NORMAL=0, + RXDESC_TYPE_NEXT, + RXDESC_TYPE_PTP, + RXDESC_TYPE_MAX +}; + +//Rx Desc Type +enum rx_desc_ring_type { + RX_DESC_RING_TYPE_UNKNOWN=0, + RX_DESC_RING_TYPE_1, + RX_DESC_RING_TYPE_2, + RX_DESC_RING_TYPE_3, + RX_DESC_RING_TYPE_MAX +}; + +enum rx_desc_len { + RX_DESC_LEN_TYPE_1 = (sizeof(struct RxDesc)), + RX_DESC_LEN_TYPE_3 = (sizeof(struct RxDescV3)) +}; + +struct ring_info { + struct sk_buff *skb; + u32 len; + u8 __pad[sizeof(void *) - sizeof(u32)]; +}; + +struct pci_resource { + u8 cmd; + u8 cls; + u16 io_base_h; + u16 io_base_l; + u16 mem_base_h; + u16 mem_base_l; + u8 ilr; + u16 resv_0x1c_h; + u16 resv_0x1c_l; + u16 resv_0x20_h; + u16 resv_0x20_l; + u16 resv_0x24_h; + u16 resv_0x24_l; + u16 resv_0x2c_h; + u16 resv_0x2c_l; + u32 pci_sn_l; + u32 pci_sn_h; +}; + +enum r8125_flag { + R8125_FLAG_DOWN = 0, + R8125_FLAG_TASK_RESET_PENDING, + R8125_FLAG_TASK_ESD_CHECK_PENDING, + R8125_FLAG_TASK_LINKCHG_CHECK_PENDING, + R8125_FLAG_MAX +}; + +struct rtl8125_tx_ring { + void* priv; + u32 index; + u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + u32 dirty_tx; + u32 num_tx_desc; /* Number of Tx descriptor registers */ + struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ + dma_addr_t TxPhyAddr; + struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */ + + u32 NextHwDesCloPtr; + u32 BeginHwDesCloPtr; + + u16 hw_clo_ptr_reg; + u16 sw_tail_ptr_reg; + + u16 tdsar_reg; /* Transmit Descriptor Start Address */ +}; + +struct rtl8125_rx_ring { + void* priv; + u32 index; + u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + u32 dirty_rx; + u32 num_rx_desc; /* Number of Rx descriptor registers */ + struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ + u64 RxDescPhyAddr[MAX_NUM_RX_DESC]; /* Rx desc physical address*/ + dma_addr_t RxPhyAddr; + struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ + + u16 rdsar_reg; /* Receive Descriptor Start Address */ +}; + +struct r8125_napi { +#ifdef CONFIG_R8125_NAPI +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) + struct napi_struct napi; +#endif +#endif + void* priv; + int index; +}; + +struct r8125_irq { + irq_handler_t handler; + unsigned int vector; + u8 requested; + char name[IFNAMSIZ + 10]; +}; + +#pragma pack(1) +struct rtl8125_regs { + //00 + u8 mac_id[6]; + u16 reg_06; + u8 mar[8]; + //10 + u64 dtccr; + u16 ledsel0; + u16 legreg; + u32 tctr3; + //20 + u32 txq0_dsc_st_addr_0; + u32 txq0_dsc_st_addr_2; + u64 reg_28; + //30 + u16 rit; + u16 ritc; + u16 reg_34; + u8 reg_36; + u8 command; + u32 imr0; + u32 isr0; + //40 + u32 tcr; + u32 rcr; + u32 tctr0; + u32 tctr1; + //50 + u8 cr93c46; + u8 config0; + u8 config1; + u8 config2; + u8 config3; + u8 config4; + u8 config5; + u8 tdfnr; + u32 timer_int0; + u32 timer_int1; + //60 + u32 gphy_mdcmdio; + u32 csidr; + u32 csiar; + u16 phy_status; + u8 config6; + u8 pmch; + //70 + u32 eridr; + u32 eriar; + u16 config7; + u16 reg_7a; + u32 ephy_rxerr_cnt; + //80 + u32 ephy_mdcmdio; + u16 ledsel2; + u16 ledsel1; + u32 tctr2; + u32 timer_int2; + //90 + u8 tppoll0; + u8 reg_91; + u16 reg_92; + u16 led_feature; + u16 ledsel3; + u16 eee_led_config; + u16 reg_9a; + u32 reg_9c; + //a0 + u32 reg_a0; + u32 reg_a4; + u32 reg_a8; + u32 reg_ac; + //b0 + u32 patch_dbg; + u32 reg_b4; + u32 gphy_ocp; + u32 reg_bc; + //c0 + u32 reg_c0; + u32 reg_c4; + u32 reg_c8; + u16 otp_cmd; + u16 otp_pg_config; + //d0 + u16 phy_pwr; + u8 twsi_ctrl; + u8 oob_ctrl; + u16 mac_dbgo; + u16 mac_dbg; + u16 reg_d8; + u16 rms; + u32 efuse_data; + //e0 + u16 cplus_cmd; + u16 reg_e2; + u32 rxq0_dsc_st_addr_0; + u32 rxq0_dsc_st_addr_2; + u16 reg_ec; + u16 tx10midle_cnt; + //f0 + u16 misc0; + u16 misc1; + u32 timer_int3; + u32 cmac_ib; + u16 reg_fc; + u16 sw_rst; +}; +#pragma pack() + +struct rtl8125_regs_save { + union { + u8 mac_io[R8125_MAC_REGS_SIZE]; + + struct rtl8125_regs mac_reg; + }; + u16 pcie_phy[R8125_EPHY_REGS_SIZE/2]; + u16 eth_phy[R8125_PHY_REGS_SIZE/2]; + u32 eri_reg[R8125_ERI_REGS_SIZE/4]; + u32 pci_reg[R8125_PCI_REGS_SIZE/4]; + u16 sw_tail_ptr_reg[R8125_MAX_TX_QUEUES]; + u16 hw_clo_ptr_reg[R8125_MAX_TX_QUEUES]; + + //ktime_t begin_ktime; + //ktime_t end_ktime; + //u64 duration_ns; + + u16 sw0_tail_ptr; + u16 next_hwq0_clo_ptr; + u16 sw1_tail_ptr; + u16 next_hwq1_clo_ptr; + + u16 int_miti_rxq0; + u16 int_miti_txq0; + u16 int_miti_rxq1; + u16 int_miti_txq1; + u8 int_config; + u32 imr_new; + u32 isr_new; + + u8 tdu_status; + u16 rdu_status; + + u16 tc_mode; + + u32 txq1_dsc_st_addr_0; + u32 txq1_dsc_st_addr_2; + + u32 pla_tx_q0_idle_credit; + u32 pla_tx_q1_idle_credit; + + u32 rxq1_dsc_st_addr_0; + u32 rxq1_dsc_st_addr_2; + + u32 rss_ctrl; + u8 rss_key[RTL8125_RSS_KEY_SIZE]; + u8 rss_i_table[RTL8125_MAX_INDIRECTION_TABLE_ENTRIES]; + u16 rss_queue_num_sel_r; +}; + +struct rtl8125_counters { + /* legacy */ + u64 tx_packets; + u64 rx_packets; + u64 tx_errors; + u32 rx_errors; + u16 rx_missed; + u16 align_errors; + u32 tx_one_collision; + u32 tx_multi_collision; + u64 rx_unicast; + u64 rx_broadcast; + u32 rx_multicast; + u16 tx_aborted; + u16 tx_underrun; + + /* extended */ + u64 tx_octets; + u64 rx_octets; + u64 rx_multicast64; + u64 tx_unicast64; + u64 tx_broadcast64; + u64 tx_multicast64; + u32 tx_pause_on; + u32 tx_pause_off; + u32 tx_pause_all; + u32 tx_deferred; + u32 tx_late_collision; + u32 tx_all_collision; + u32 tx_aborted32; + u32 align_errors32; + u32 rx_frame_too_long; + u32 rx_runt; + u32 rx_pause_on; + u32 rx_pause_off; + u32 rx_pause_all; + u32 rx_unknown_opcode; + u32 rx_mac_error; + u32 tx_underrun32; + u32 rx_mac_missed; + u32 rx_tcam_dropped; + u32 tdu; + u32 rdu; +}; + +/* Flow Control Settings */ +enum rtl8125_fc_mode { + rtl8125_fc_none = 0, + rtl8125_fc_rx_pause, + rtl8125_fc_tx_pause, + rtl8125_fc_full, + rtl8125_fc_default +}; + +struct rtl8125_private { + void __iomem *mmio_addr; /* memory map physical address */ + struct pci_dev *pci_dev; /* Index of PCI device */ + struct net_device *dev; + struct r8125_napi r8125napi[R8125_MAX_MSIX_VEC]; + struct r8125_irq irq_tbl[R8125_MAX_MSIX_VEC]; + unsigned int irq_nvecs; + unsigned int max_irq_nvecs; + unsigned int min_irq_nvecs; + //struct msix_entry msix_entries[R8125_MAX_MSIX_VEC]; + struct net_device_stats stats; /* statistics of net device */ +#ifdef ENABLE_PTP_SUPPORT + spinlock_t lock; /* spin lock flag */ +#endif + u32 msg_enable; + u32 tx_tcp_csum_cmd; + u32 tx_udp_csum_cmd; + u32 tx_ip_csum_cmd; + u32 tx_ipv6_csum_cmd; + int max_jumbo_frame_size; + int chipset; + u32 mcfg; + //u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ + //u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ + //u32 dirty_rx; + //u32 dirty_tx; + //struct TxDesc *TxDescArray; /* 256-aligned Tx descriptor ring */ + //struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ + //dma_addr_t TxPhyAddr; + //dma_addr_t RxPhyAddr; + //struct sk_buff *Rx_skbuff[MAX_NUM_RX_DESC]; /* Rx data buffers */ + //struct ring_info tx_skb[MAX_NUM_TX_DESC]; /* Tx data buffers */ + unsigned rx_buf_sz; + u16 HwSuppNumTxQueues; + u16 HwSuppNumRxQueues; + unsigned int num_tx_rings; + unsigned int num_rx_rings; + struct rtl8125_tx_ring tx_ring[R8125_MAX_TX_QUEUES]; + struct rtl8125_rx_ring rx_ring[R8125_MAX_RX_QUEUES]; +#ifdef ENABLE_LIB_SUPPORT + struct atomic_notifier_head lib_nh; + struct rtl8125_ring lib_tx_ring[R8125_MAX_TX_QUEUES]; + struct rtl8125_ring lib_rx_ring[R8125_MAX_RX_QUEUES]; +#endif + //struct timer_list esd_timer; + //struct timer_list link_timer; + struct pci_resource pci_cfg_space; + unsigned int esd_flag; + unsigned int pci_cfg_is_read; + unsigned int rtl8125_rx_config; + u16 cp_cmd; + u32 intr_mask; + u32 timer_intr_mask; + u16 isr_reg[R8125_MAX_QUEUES]; + u16 imr_reg[R8125_MAX_QUEUES]; + int phy_auto_nego_reg; + int phy_1000_ctrl_reg; + int phy_2500_ctrl_reg; + u8 org_mac_addr[NODE_ADDRESS_SIZE]; + struct rtl8125_counters *tally_vaddr; + dma_addr_t tally_paddr; + +#ifdef CONFIG_R8125_VLAN + struct vlan_group *vlgrp; +#endif + u8 wol_enabled; + u32 wol_opts; + u8 efuse_ver; + u8 eeprom_type; + u8 autoneg; + u8 duplex; + u32 speed; + u32 advertising; + enum rtl8125_fc_mode fcpause; + u16 eeprom_len; + u16 cur_page; + u32 bios_setting; + + int (*set_speed)(struct net_device *, u8 autoneg, u32 speed, u8 duplex, u32 adv); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + void (*get_settings)(struct net_device *, struct ethtool_cmd *); +#else + void (*get_settings)(struct net_device *, struct ethtool_link_ksettings *); +#endif + void (*phy_reset_enable)(struct net_device *); + unsigned int (*phy_reset_pending)(struct net_device *); + unsigned int (*link_ok)(struct net_device *); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + struct work_struct reset_task; + struct work_struct esd_task; + struct work_struct linkchg_task; +#else + struct delayed_work reset_task; + struct delayed_work esd_task; + struct delayed_work linkchg_task; +#endif + DECLARE_BITMAP(task_flags, R8125_FLAG_MAX); + unsigned features; + + u8 org_pci_offset_99; + u8 org_pci_offset_180; + u8 issue_offset_99_event; + + u8 org_pci_offset_80; + u8 org_pci_offset_81; + u8 use_timer_interrrupt; + + u32 keep_intr_cnt; + + u8 HwIcVerUnknown; + u8 NotWrRamCodeToMicroP; + u8 NotWrMcuPatchCode; + u8 HwHasWrRamCodeToMicroP; + + u16 sw_ram_code_ver; + u16 hw_ram_code_ver; + + u8 RequireRduNonStopPatch; + + u8 rtk_enable_diag; + + u8 ShortPacketSwChecksum; + + u8 UseSwPaddingShortPkt; + + void *ShortPacketEmptyBuffer; + dma_addr_t ShortPacketEmptyBufferPhy; + + u8 RequireAdcBiasPatch; + u16 AdcBiasPatchIoffset; + + u8 RequireAdjustUpsTxLinkPulseTiming; + u16 SwrCnt1msIni; + + u8 HwSuppNowIsOobVer; + + u8 RequiredSecLanDonglePatch; + + u8 RequirePhyMdiSwapPatch; + + u8 RequireLSOPatch; + + u32 HwFiberModeVer; + u32 HwFiberStat; + u8 HwSwitchMdiToFiber; + + u16 NicCustLedValue; + + u8 HwSuppMagicPktVer; + + u8 HwSuppLinkChgWakeUpVer; + + u8 HwSuppCheckPhyDisableModeVer; + + u8 random_mac; + + u16 phy_reg_aner; + u16 phy_reg_anlpar; + u16 phy_reg_gbsr; + u16 phy_reg_status_2500; + + u32 HwPcieSNOffset; + + u8 HwSuppTxNoCloseVer; + u8 EnableTxNoClose; + + u8 HwSuppIsrVer; + u8 HwCurrIsrVer; + + u8 HwSuppIntMitiVer; + + u8 HwSuppExtendTallyCounterVer; + + u8 check_keep_link_speed; + u8 resume_not_chg_speed; + + u8 HwSuppD0SpeedUpVer; + u8 D0SpeedUpSpeed; + + u8 ring_lib_enabled; + + const char *fw_name; + struct rtl8125_fw *rtl_fw; + u32 ocp_base; + + //Dash+++++++++++++++++ + u8 HwSuppDashVer; + u8 DASH; + u8 dash_printer_enabled; + u8 HwPkgDet; + void __iomem *mapped_cmac_ioaddr; /* mapped cmac memory map physical address */ + void __iomem *cmac_ioaddr; /* cmac memory map physical address */ + +#ifdef ENABLE_DASH_SUPPORT + u16 AfterRecvFromFwBufLen; + u8 AfterRecvFromFwBuf[RECV_FROM_FW_BUF_SIZE]; + u16 AfterSendToFwBufLen; + u8 AfterSendToFwBuf[SEND_TO_FW_BUF_SIZE]; + u16 SendToFwBufferLen; + u32 SizeOfSendToFwBuffer; + u32 SizeOfSendToFwBufferMemAlloc; + u32 NumOfSendToFwBuffer; + + u8 OobReq; + u8 OobAck; + u32 OobReqComplete; + u32 OobAckComplete; + + u8 RcvFwReqSysOkEvt; + u8 RcvFwDashOkEvt; + u8 SendFwHostOkEvt; + + u8 DashFwDisableRx; + + void *UnalignedSendToFwBufferVa; + void *SendToFwBuffer; + u64 SendToFwBufferPhy; + u8 SendingToFw; + dma_addr_t UnalignedSendToFwBufferPa; + PTX_DASH_SEND_FW_DESC TxDashSendFwDesc; + u64 TxDashSendFwDescPhy; + u8 *UnalignedTxDashSendFwDescVa; + u32 SizeOfTxDashSendFwDescMemAlloc; + u32 SizeOfTxDashSendFwDesc; + u32 NumTxDashSendFwDesc; + u32 CurrNumTxDashSendFwDesc; + u32 LastSendNumTxDashSendFwDesc; + dma_addr_t UnalignedTxDashSendFwDescPa; + + u32 NumRecvFromFwBuffer; + u32 SizeOfRecvFromFwBuffer; + u32 SizeOfRecvFromFwBufferMemAlloc; + void *RecvFromFwBuffer; + u64 RecvFromFwBufferPhy; + + void *UnalignedRecvFromFwBufferVa; + dma_addr_t UnalignedRecvFromFwBufferPa; + PRX_DASH_FROM_FW_DESC RxDashRecvFwDesc; + u64 RxDashRecvFwDescPhy; + u8 *UnalignedRxDashRecvFwDescVa; + u32 SizeOfRxDashRecvFwDescMemAlloc; + u32 SizeOfRxDashRecvFwDesc; + u32 NumRxDashRecvFwDesc; + u32 CurrNumRxDashRecvFwDesc; + dma_addr_t UnalignedRxDashRecvFwDescPa; + u8 DashReqRegValue; + u16 HostReqValue; + + u32 CmacResetIsrCounter; + u8 CmacResetIntr; + u8 CmacResetting; + u8 CmacOobIssueCmacReset; + u32 CmacResetbyFwCnt; + +#if defined(ENABLE_DASH_PRINTER_SUPPORT) + struct completion fw_ack; + struct completion fw_req; + struct completion fw_host_ok; +#endif + //Dash----------------- +#endif //ENABLE_DASH_SUPPORT + + //Realwow++++++++++++++ + u8 HwSuppKCPOffloadVer; + + u8 EnableDhcpTimeoutWake; + u8 EnableTeredoOffload; + u8 EnableKCPOffload; +#ifdef ENABLE_REALWOW_SUPPORT + u32 DhcpTimeout; + MP_KCP_INFO MpKCPInfo; + //Realwow-------------- +#endif //ENABLE_REALWOW_SUPPORT + + struct ethtool_eee eee; + +#ifdef ENABLE_R8125_PROCFS + //Procfs support + struct proc_dir_entry *proc_dir; +#endif + u8 InitRxDescType; + u16 RxDescLength; //V1 16 Byte V2 32 Bytes + + u8 HwSuppPtpVer; + u8 EnablePtp; + u8 ptp_master_mode; + s64 ptp_adjust; +#ifdef ENABLE_PTP_SUPPORT + u32 tx_hwtstamp_timeouts; + u32 tx_hwtstamp_skipped; + struct work_struct ptp_tx_work; + struct sk_buff *ptp_tx_skb; + struct hwtstamp_config hwtstamp_config; + unsigned long ptp_tx_start; + struct ptp_clock_info ptp_clock_info; + struct ptp_clock *ptp_clock; +#endif + + u8 HwSuppRssVer; + u8 EnableRss; + u16 HwSuppIndirTblEntries; +#ifdef ENABLE_RSS_SUPPORT + u32 rss_flags; + /* Receive Side Scaling settings */ + u8 rss_key[RTL8125_RSS_KEY_SIZE]; + u8 rss_indir_tbl[RTL8125_MAX_INDIRECTION_TABLE_ENTRIES]; + u32 rss_options; +#endif + + u8 HwSuppMacMcuVer; + u16 MacMcuPageSize; +}; + +#ifdef ENABLE_LIB_SUPPORT +static inline unsigned int +rtl8125_num_lib_tx_rings(struct rtl8125_private *tp) +{ + int count, i; + + for (count = 0, i = tp->num_tx_rings; i < tp->HwSuppNumTxQueues; i++) + if(tp->lib_tx_ring[i].enabled) + count++; + + return count; +} + +static inline unsigned int +rtl8125_num_lib_rx_rings(struct rtl8125_private *tp) +{ + int count, i; + + for (count = 0, i = tp->num_rx_rings; i < tp->HwSuppNumRxQueues; i++) + if(tp->lib_rx_ring[i].enabled) + count++; + + return count; +} + +#else +static inline unsigned int +rtl8125_num_lib_tx_rings(struct rtl8125_private *tp) +{ + return 0; +} + +static inline unsigned int +rtl8125_num_lib_rx_rings(struct rtl8125_private *tp) +{ + return 0; +} +#endif + +static inline unsigned int +rtl8125_tot_tx_rings(struct rtl8125_private *tp) +{ + return tp->num_tx_rings + rtl8125_num_lib_tx_rings(tp); +} + +static inline unsigned int +rtl8125_tot_rx_rings(struct rtl8125_private *tp) +{ + return tp->num_rx_rings + rtl8125_num_lib_rx_rings(tp); +} + +enum eetype { + EEPROM_TYPE_NONE=0, + EEPROM_TYPE_93C46, + EEPROM_TYPE_93C56, + EEPROM_TWSI +}; + +enum mcfg { + CFG_METHOD_2=2, + CFG_METHOD_3, + CFG_METHOD_4, + CFG_METHOD_5, + CFG_METHOD_6, + CFG_METHOD_7, + CFG_METHOD_DEFAULT, + CFG_METHOD_MAX +}; + +#define LSO_32K 32000 +#define LSO_64K 64000 + +#define NIC_MIN_PHYS_BUF_COUNT (2) +#define NIC_MAX_PHYS_BUF_COUNT_LSO_64K (24) +#define NIC_MAX_PHYS_BUF_COUNT_LSO2 (16*4) + +#define GTTCPHO_SHIFT 18 +#define GTTCPHO_MAX 0x70U +#define GTPKTSIZE_MAX 0x3ffffU +#define TCPHO_SHIFT 18 +#define TCPHO_MAX 0x3ffU +#define LSOPKTSIZE_MAX 0xffffU +#define MSS_MAX 0x07ffu /* MSS value */ + +#define OOB_CMD_RESET 0x00 +#define OOB_CMD_DRIVER_START 0x05 +#define OOB_CMD_DRIVER_STOP 0x06 +#define OOB_CMD_SET_IPMAC 0x41 + +#define WAKEUP_MAGIC_PACKET_NOT_SUPPORT (0) +#define WAKEUP_MAGIC_PACKET_V1 (1) +#define WAKEUP_MAGIC_PACKET_V2 (2) +#define WAKEUP_MAGIC_PACKET_V3 (3) + +//Ram Code Version +#define NIC_RAMCODE_VERSION_CFG_METHOD_2 (0x0b11) +#define NIC_RAMCODE_VERSION_CFG_METHOD_3 (0x0b33) +#define NIC_RAMCODE_VERSION_CFG_METHOD_4 (0x0b17) +#define NIC_RAMCODE_VERSION_CFG_METHOD_5 (0x0b74) + +//hwoptimize +#define HW_PATCH_SOC_LAN (BIT_0) +#define HW_PATCH_SAMSUNG_LAN_DONGLE (BIT_2) + +static const u16 other_q_intr_mask = (RxOK1 | RxDU1); + +void rtl8125_mdio_write(struct rtl8125_private *tp, u16 RegAddr, u16 value); +void rtl8125_mdio_prot_write(struct rtl8125_private *tp, u32 RegAddr, u32 value); +void rtl8125_mdio_prot_direct_write_phy_ocp(struct rtl8125_private *tp, u32 RegAddr, u32 value); +u32 rtl8125_mdio_read(struct rtl8125_private *tp, u16 RegAddr); +u32 rtl8125_mdio_prot_read(struct rtl8125_private *tp, u32 RegAddr); +u32 rtl8125_mdio_prot_direct_read_phy_ocp(struct rtl8125_private *tp, u32 RegAddr); +void rtl8125_ephy_write(struct rtl8125_private *tp, int RegAddr, int value); +void rtl8125_mac_ocp_write(struct rtl8125_private *tp, u16 reg_addr, u16 value); +u32 rtl8125_mac_ocp_read(struct rtl8125_private *tp, u16 reg_addr); +void rtl8125_clear_eth_phy_bit(struct rtl8125_private *tp, u8 addr, u16 mask); +void rtl8125_set_eth_phy_bit(struct rtl8125_private *tp, u8 addr, u16 mask); +void rtl8125_ocp_write(struct rtl8125_private *tp, u16 addr, u8 len, u32 data); +void rtl8125_oob_notify(struct rtl8125_private *tp, u8 cmd); +void rtl8125_init_ring_indexes(struct rtl8125_private *tp); +int rtl8125_eri_write(struct rtl8125_private *tp, int addr, int len, u32 value, int type); +void rtl8125_oob_mutex_lock(struct rtl8125_private *tp); +u32 rtl8125_ocp_read(struct rtl8125_private *tp, u16 addr, u8 len); +u32 rtl8125_ocp_read_with_oob_base_address(struct rtl8125_private *tp, u16 addr, u8 len, u32 base_address); +u32 rtl8125_ocp_write_with_oob_base_address(struct rtl8125_private *tp, u16 addr, u8 len, u32 value, u32 base_address); +u32 rtl8125_eri_read(struct rtl8125_private *tp, int addr, int len, int type); +u32 rtl8125_eri_read_with_oob_base_address(struct rtl8125_private *tp, int addr, int len, int type, u32 base_address); +int rtl8125_eri_write(struct rtl8125_private *tp, int addr, int len, u32 value, int type); +int rtl8125_eri_write_with_oob_base_address(struct rtl8125_private *tp, int addr, int len, u32 value, int type, u32 base_address); +u16 rtl8125_ephy_read(struct rtl8125_private *tp, int RegAddr); +void rtl8125_wait_txrx_fifo_empty(struct net_device *dev); +void rtl8125_enable_now_is_oob(struct rtl8125_private *tp); +void rtl8125_disable_now_is_oob(struct rtl8125_private *tp); +void rtl8125_oob_mutex_unlock(struct rtl8125_private *tp); +void rtl8125_dash2_disable_tx(struct rtl8125_private *tp); +void rtl8125_dash2_enable_tx(struct rtl8125_private *tp); +void rtl8125_dash2_disable_rx(struct rtl8125_private *tp); +void rtl8125_dash2_enable_rx(struct rtl8125_private *tp); +void rtl8125_hw_disable_mac_mcu_bps(struct net_device *dev); +void rtl8125_mark_to_asic(struct rtl8125_private *tp, struct RxDesc *desc, u32 rx_buf_sz); + +static inline void +rtl8125_make_unusable_by_asic(struct rtl8125_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) { + ((struct RxDescV3 *)desc)->addr = RTL8125_MAGIC_NUMBER; + ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts1 &= ~cpu_to_le32(DescOwn | RsvdMaskV3); + } else { + desc->addr = RTL8125_MAGIC_NUMBER; + desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); + } +} + +static inline struct RxDesc* +rtl8125_get_rxdesc(struct rtl8125_private *tp, struct RxDesc *RxDescBase, u32 const cur_rx) +{ + return (struct RxDesc*)((u8*)RxDescBase + (cur_rx * tp->RxDescLength)); +} + +static inline void +rtl8125_disable_hw_interrupt_v2(struct rtl8125_private *tp, + u32 message_id) +{ + RTL_W32(tp, IMR_V2_CLEAR_REG_8125, BIT(message_id)); +} + +static inline void +rtl8125_enable_hw_interrupt_v2(struct rtl8125_private *tp, u32 message_id) +{ + RTL_W32(tp, IMR_V2_SET_REG_8125, BIT(message_id)); +} + +int rtl8125_open(struct net_device *dev); +int rtl8125_close(struct net_device *dev); +void rtl8125_hw_config(struct net_device *dev); +void rtl8125_hw_set_timer_int_8125(struct rtl8125_private *tp, u32 message_id, u8 timer_intmiti_val); +void rtl8125_set_rx_q_num(struct rtl8125_private *tp, unsigned int num_rx_queues); +void rtl8125_set_tx_q_num(struct rtl8125_private *tp, unsigned int num_tx_queues); +void rtl8125_hw_start(struct net_device *dev); +void rtl8125_hw_reset(struct net_device *dev); +void rtl8125_tx_clear(struct rtl8125_private *tp); +void rtl8125_rx_clear(struct rtl8125_private *tp); +int rtl8125_init_ring(struct net_device *dev); +void rtl8125_hw_set_rx_packet_filter(struct net_device *dev); +void rtl8125_enable_hw_linkchg_interrupt(struct rtl8125_private *tp); +int rtl8125_dump_tally_counter(struct rtl8125_private *tp, dma_addr_t paddr); + +#ifndef ENABLE_LIB_SUPPORT +static inline void rtl8125_lib_reset_prepare(struct rtl8125_private *tp) { } +static inline void rtl8125_lib_reset_complete(struct rtl8125_private *tp) { } +#endif + +#define HW_SUPPORT_CHECK_PHY_DISABLE_MODE(_M) ((_M)->HwSuppCheckPhyDisableModeVer > 0 ) +#define HW_HAS_WRITE_PHY_MCU_RAM_CODE(_M) (((_M)->HwHasWrRamCodeToMicroP == TRUE) ? 1 : 0) +#define HW_SUPPORT_D0_SPEED_UP(_M) ((_M)->HwSuppD0SpeedUpVer > 0) +#define HW_SUPPORT_MAC_MCU(_M) ((_M)->HwSuppMacMcuVer > 0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34) +#define netdev_mc_count(dev) ((dev)->mc_count) +#define netdev_mc_empty(dev) (netdev_mc_count(dev) == 0) +#define netdev_for_each_mc_addr(mclist, dev) \ + for (mclist = dev->mc_list; mclist; mclist = mclist->next) +#endif + +#endif /* __R8125_H */ diff --git a/addons/r8125/src/4.4.180/r8125_dash.h b/addons/r8125/src/4.4.180/r8125_dash.h new file mode 100755 index 00000000..6819370d --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_dash.h @@ -0,0 +1,261 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8125_DASH_H +#define _LINUX_R8125_DASH_H + +#include + +#define SIOCDEVPRIVATE_RTLDASH SIOCDEVPRIVATE+2 + +enum rtl_dash_cmd { + RTL_DASH_ARP_NS_OFFLOAD = 0, + RTL_DASH_SET_OOB_IPMAC, + RTL_DASH_NOTIFY_OOB, + + RTL_DASH_SEND_BUFFER_DATA_TO_DASH_FW, + RTL_DASH_CHECK_SEND_BUFFER_TO_DASH_FW_COMPLETE, + RTL_DASH_GET_RCV_FROM_FW_BUFFER_DATA, + RTL_DASH_OOB_REQ, + RTL_DASH_OOB_ACK, + RTL_DASH_DETACH_OOB_REQ, + RTL_DASH_DETACH_OOB_ACK, + + RTL_FW_SET_IPV4 = 0x10, + RTL_FW_GET_IPV4, + RTL_FW_SET_IPV6, + RTL_FW_GET_IPV6, + RTL_FW_SET_EXT_SNMP, + RTL_FW_GET_EXT_SNMP, + RTL_FW_SET_WAKEUP_PATTERN, + RTL_FW_GET_WAKEUP_PATTERN, + RTL_FW_DEL_WAKEUP_PATTERN, + + RTLT_DASH_COMMAND_INVALID, +}; + +struct rtl_dash_ip_mac { + struct sockaddr ifru_addr; + struct sockaddr ifru_netmask; + struct sockaddr ifru_hwaddr; +}; + +struct rtl_dash_ioctl_struct { + __u32 cmd; + __u32 offset; + __u32 len; + union { + __u32 data; + void *data_buffer; + }; +}; + +struct settings_ipv4 { + __u32 IPv4addr; + __u32 IPv4mask; + __u32 IPv4Gateway; +}; + +struct settings_ipv6 { + __u32 reserved; + __u32 prefixLen; + __u16 IPv6addr[8]; + __u16 IPv6Gateway[8]; +}; + +struct settings_ext_snmp { + __u16 index; + __u16 oid_get_len; + __u8 oid_for_get[24]; + __u8 reserved0[26]; + __u16 value_len; + __u8 value[256]; + __u8 supported; + __u8 reserved1[27]; +}; + +struct wakeup_pattern { + __u8 index; + __u8 valid; + __u8 start; + __u8 length; + __u8 name[36]; + __u8 mask[16]; + __u8 pattern[128]; + __u32 reserved[2]; +}; + +typedef struct _RX_DASH_FROM_FW_DESC { + u16 length; + u8 statusLowByte; + u8 statusHighByte; + u32 resv; + u64 BufferAddress; +} +RX_DASH_FROM_FW_DESC, *PRX_DASH_FROM_FW_DESC; + +typedef struct _TX_DASH_SEND_FW_DESC { + u16 length; + u8 statusLowByte; + u8 statusHighByte; + u32 resv; + u64 BufferAddress; +} +TX_DASH_SEND_FW_DESC, *PTX_DASH_SEND_FW_DESC; + +typedef struct _OSOOBHdr { + u32 len; + u8 type; + u8 flag; + u8 hostReqV; + u8 res; +} +OSOOBHdr, *POSOOBHdr; + +typedef struct _RX_DASH_BUFFER_TYPE_2 { + OSOOBHdr oobhdr; + u8 RxDataBuffer[0]; +} +RX_DASH_BUFFER_TYPE_2, *PRX_DASH_BUFFER_TYPE_2; + +#define ALIGN_8 (0x7) +#define ALIGN_16 (0xf) +#define ALIGN_32 (0x1f) +#define ALIGN_64 (0x3f) +#define ALIGN_256 (0xff) +#define ALIGN_4096 (0xfff) + +#define OCP_REG_CONFIG0 (0x10) +#define OCP_REG_CONFIG0_REV_F (0xB8) +#define OCP_REG_DASH_POLL (0x30) +#define OCP_REG_HOST_REQ (0x34) +#define OCP_REG_DASH_REQ (0x35) +#define OCP_REG_CR (0x36) +#define OCP_REG_DMEMSTA (0x38) +#define OCP_REG_GPHYAR (0x60) + + +#define OCP_REG_CONFIG0_DASHEN BIT_15 +#define OCP_REG_CONFIG0_OOBRESET BIT_14 +#define OCP_REG_CONFIG0_APRDY BIT_13 +#define OCP_REG_CONFIG0_FIRMWARERDY BIT_12 +#define OCP_REG_CONFIG0_DRIVERRDY BIT_11 +#define OCP_REG_CONFIG0_OOB_WDT BIT_9 +#define OCP_REG_CONFIG0_DRV_WAIT_OOB BIT_8 +#define OCP_REG_CONFIG0_TLSEN BIT_7 + +#define HW_DASH_SUPPORT_DASH(_M) ((_M)->HwSuppDashVer > 0 ) +#define HW_DASH_SUPPORT_TYPE_1(_M) ((_M)->HwSuppDashVer == 1 ) +#define HW_DASH_SUPPORT_TYPE_2(_M) ((_M)->HwSuppDashVer == 2 ) +#define HW_DASH_SUPPORT_TYPE_3(_M) ((_M)->HwSuppDashVer == 3 ) + +#define RECV_FROM_FW_BUF_SIZE (1520) +#define SEND_TO_FW_BUF_SIZE (1520) + +#define RX_DASH_FROM_FW_OWN BIT_15 +#define TX_DASH_SEND_FW_OWN BIT_15 +#define TX_DASH_SEND_FW_OWN_HIGHBYTE BIT_7 + +#define TXS_CC3_0 (BIT_0|BIT_1|BIT_2|BIT_3) +#define TXS_EXC BIT_4 +#define TXS_LNKF BIT_5 +#define TXS_OWC BIT_6 +#define TXS_TES BIT_7 +#define TXS_UNF BIT_9 +#define TXS_LGSEN BIT_11 +#define TXS_LS BIT_12 +#define TXS_FS BIT_13 +#define TXS_EOR BIT_14 +#define TXS_OWN BIT_15 + +#define TPPool_HRDY 0x20 + +#define HostReqReg (0xC0) +#define SystemMasterDescStartAddrLow (0xF0) +#define SystemMasterDescStartAddrHigh (0xF4) +#define SystemSlaveDescStartAddrLow (0xF8) +#define SystemSlaveDescStartAddrHigh (0xFC) + +//DASH Request Type +#define WSMANREG 0x01 +#define OSPUSHDATA 0x02 + +#define RXS_OWN BIT_15 +#define RXS_EOR BIT_14 +#define RXS_FS BIT_13 +#define RXS_LS BIT_12 + +#define ISRIMR_DP_DASH_OK BIT_15 +#define ISRIMR_DP_HOST_OK BIT_13 +#define ISRIMR_DP_REQSYS_OK BIT_11 + +#define ISRIMR_DASH_INTR_EN BIT_12 +#define ISRIMR_DASH_INTR_CMAC_RESET BIT_15 + +#define ISRIMR_DASH_TYPE2_ROK BIT_0 +#define ISRIMR_DASH_TYPE2_RDU BIT_1 +#define ISRIMR_DASH_TYPE2_TOK BIT_2 +#define ISRIMR_DASH_TYPE2_TDU BIT_3 +#define ISRIMR_DASH_TYPE2_TX_FIFO_FULL BIT_4 +#define ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE BIT_5 +#define ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE BIT_6 + +#define CMAC_OOB_STOP 0x25 +#define CMAC_OOB_INIT 0x26 +#define CMAC_OOB_RESET 0x2a + +#define NO_BASE_ADDRESS 0x00000000 +#define RTL8168FP_OOBMAC_BASE 0xBAF70000 +#define RTL8168FP_CMAC_IOBASE 0xBAF20000 +#define RTL8168FP_KVM_BASE 0xBAF80400 +#define CMAC_SYNC_REG 0x20 +#define CMAC_RXDESC_OFFSET 0x90 //RX: 0x90 - 0x98 +#define CMAC_TXDESC_OFFSET 0x98 //TX: 0x98 - 0x9F + +/* cmac write/read MMIO register */ +#define RTL_CMAC_W8(tp, reg, val8) writeb ((val8), tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_W16(tp, reg, val16) writew ((val16), tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_W32(tp, reg, val32) writel ((val32), tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_R8(tp, reg) readb (tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_R16(tp, reg) readw (tp->cmac_ioaddr + (reg)) +#define RTL_CMAC_R32(tp, reg) ((unsigned long) readl (tp->cmac_ioaddr + (reg))) + +int rtl8125_dash_ioctl(struct net_device *dev, struct ifreq *ifr); +void HandleDashInterrupt(struct net_device *dev); +int AllocateDashShareMemory(struct net_device *dev); +void FreeAllocatedDashShareMemory(struct net_device *dev); +void DashHwInit(struct net_device *dev); + + +#endif /* _LINUX_R8125_DASH_H */ diff --git a/addons/r8125/src/4.4.180/r8125_firmware.c b/addons/r8125/src/4.4.180/r8125_firmware.c new file mode 100755 index 00000000..61b92d11 --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_firmware.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8168 is the Linux device driver released for Realtek Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include + +#include "r8125_firmware.h" + +enum rtl_fw_opcode { + PHY_READ = 0x0, + PHY_DATA_OR = 0x1, + PHY_DATA_AND = 0x2, + PHY_BJMPN = 0x3, + PHY_MDIO_CHG = 0x4, + PHY_CLEAR_READCOUNT = 0x7, + PHY_WRITE = 0x8, + PHY_READCOUNT_EQ_SKIP = 0x9, + PHY_COMP_EQ_SKIPN = 0xa, + PHY_COMP_NEQ_SKIPN = 0xb, + PHY_WRITE_PREVIOUS = 0xc, + PHY_SKIPN = 0xd, + PHY_DELAY_MS = 0xe, +}; + +struct fw_info { + u32 magic; + char version[RTL8125_VER_SIZE]; + __le32 fw_start; + __le32 fw_len; + u8 chksum; +} __packed; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0) +#define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) +#endif +#define FW_OPCODE_SIZE sizeof_field(struct rtl8125_fw_phy_action, code[0]) + +static bool rtl8125_fw_format_ok(struct rtl8125_fw *rtl_fw) +{ + const struct firmware *fw = rtl_fw->fw; + struct fw_info *fw_info = (struct fw_info *)fw->data; + struct rtl8125_fw_phy_action *pa = &rtl_fw->phy_action; + + if (fw->size < FW_OPCODE_SIZE) + return false; + + if (!fw_info->magic) { + size_t i, size, start; + u8 checksum = 0; + + if (fw->size < sizeof(*fw_info)) + return false; + + for (i = 0; i < fw->size; i++) + checksum += fw->data[i]; + if (checksum != 0) + return false; + + start = le32_to_cpu(fw_info->fw_start); + if (start > fw->size) + return false; + + size = le32_to_cpu(fw_info->fw_len); + if (size > (fw->size - start) / FW_OPCODE_SIZE) + return false; + + strscpy(rtl_fw->version, fw_info->version, RTL8125_VER_SIZE); + + pa->code = (__le32 *)(fw->data + start); + pa->size = size; + } else { + if (fw->size % FW_OPCODE_SIZE) + return false; + + strscpy(rtl_fw->version, rtl_fw->fw_name, RTL8125_VER_SIZE); + + pa->code = (__le32 *)fw->data; + pa->size = fw->size / FW_OPCODE_SIZE; + } + + return true; +} + +static bool rtl8125_fw_data_ok(struct rtl8125_fw *rtl_fw) +{ + struct rtl8125_fw_phy_action *pa = &rtl_fw->phy_action; + size_t index; + + for (index = 0; index < pa->size; index++) { + u32 action = le32_to_cpu(pa->code[index]); + u32 val = action & 0x0000ffff; + u32 regno = (action & 0x0fff0000) >> 16; + + switch (action >> 28) { + case PHY_READ: + case PHY_DATA_OR: + case PHY_DATA_AND: + case PHY_CLEAR_READCOUNT: + case PHY_WRITE: + case PHY_WRITE_PREVIOUS: + case PHY_DELAY_MS: + break; + + case PHY_MDIO_CHG: + if (val > 1) + goto out; + break; + + case PHY_BJMPN: + if (regno > index) + goto out; + break; + case PHY_READCOUNT_EQ_SKIP: + if (index + 2 >= pa->size) + goto out; + break; + case PHY_COMP_EQ_SKIPN: + case PHY_COMP_NEQ_SKIPN: + case PHY_SKIPN: + if (index + 1 + regno >= pa->size) + goto out; + break; + + default: + dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action); + return false; + } + } + + return true; +out: + dev_err(rtl_fw->dev, "Out of range of firmware\n"); + return false; +} + +void rtl8125_fw_write_firmware(struct rtl8125_private *tp, struct rtl8125_fw *rtl_fw) +{ + struct rtl8125_fw_phy_action *pa = &rtl_fw->phy_action; + rtl8125_fw_write_t fw_write = rtl_fw->phy_write; + rtl8125_fw_read_t fw_read = rtl_fw->phy_read; + int predata = 0, count = 0; + size_t index; + + for (index = 0; index < pa->size; index++) { + u32 action = le32_to_cpu(pa->code[index]); + u32 data = action & 0x0000ffff; + u32 regno = (action & 0x0fff0000) >> 16; + enum rtl_fw_opcode opcode = action >> 28; + + if (!action) + break; + + switch (opcode) { + case PHY_READ: + predata = fw_read(tp, regno); + count++; + break; + case PHY_DATA_OR: + predata |= data; + break; + case PHY_DATA_AND: + predata &= data; + break; + case PHY_BJMPN: + index -= (regno + 1); + break; + case PHY_MDIO_CHG: + if (data) { + fw_write = rtl_fw->mac_mcu_write; + fw_read = rtl_fw->mac_mcu_read; + } else { + fw_write = rtl_fw->phy_write; + fw_read = rtl_fw->phy_read; + } + + break; + case PHY_CLEAR_READCOUNT: + count = 0; + break; + case PHY_WRITE: + fw_write(tp, regno, data); + break; + case PHY_READCOUNT_EQ_SKIP: + if (count == data) + index++; + break; + case PHY_COMP_EQ_SKIPN: + if (predata == data) + index += regno; + break; + case PHY_COMP_NEQ_SKIPN: + if (predata != data) + index += regno; + break; + case PHY_WRITE_PREVIOUS: + fw_write(tp, regno, predata); + break; + case PHY_SKIPN: + index += regno; + break; + case PHY_DELAY_MS: + mdelay(data); + break; + } + } +} + +void rtl8125_fw_release_firmware(struct rtl8125_fw *rtl_fw) +{ + release_firmware(rtl_fw->fw); +} + +int rtl8125_fw_request_firmware(struct rtl8125_fw *rtl_fw) +{ + int rc; + + rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); + if (rc < 0) + goto out; + + if (!rtl8125_fw_format_ok(rtl_fw) || !rtl8125_fw_data_ok(rtl_fw)) { + release_firmware(rtl_fw->fw); + rc = -EINVAL; + goto out; + } + + return 0; +out: + dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n", + rtl_fw->fw_name, rc); + return rc; +} diff --git a/addons/r8125/src/4.4.180/r8125_firmware.h b/addons/r8125/src/4.4.180/r8125_firmware.h new file mode 100755 index 00000000..df97bf9b --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_firmware.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_rtl8125_FIRMWARE_H +#define _LINUX_rtl8125_FIRMWARE_H + +#include +#include + +struct rtl8125_private; +typedef void (*rtl8125_fw_write_t)(struct rtl8125_private *tp, u16 reg, u16 val); +typedef u32 (*rtl8125_fw_read_t)(struct rtl8125_private *tp, u16 reg); + +#define RTL8125_VER_SIZE 32 + +struct rtl8125_fw { + rtl8125_fw_write_t phy_write; + rtl8125_fw_read_t phy_read; + rtl8125_fw_write_t mac_mcu_write; + rtl8125_fw_read_t mac_mcu_read; + const struct firmware *fw; + const char *fw_name; + struct device *dev; + + char version[RTL8125_VER_SIZE]; + + struct rtl8125_fw_phy_action { + __le32 *code; + size_t size; + } phy_action; +}; + +int rtl8125_fw_request_firmware(struct rtl8125_fw *rtl_fw); +void rtl8125_fw_release_firmware(struct rtl8125_fw *rtl_fw); +void rtl8125_fw_write_firmware(struct rtl8125_private *tp, struct rtl8125_fw *rtl_fw); + +#endif /* _LINUX_rtl8125_FIRMWARE_H */ diff --git a/addons/r8125/src/4.4.180/r8125_n.c b/addons/r8125/src/4.4.180/r8125_n.c new file mode 100755 index 00000000..0bc5eec3 --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_n.c @@ -0,0 +1,15803 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +/* + * This driver is modified from r8169.c in Linux kernel 2.6.18 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +#include +#include +#endif +#include +#include +#include +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0) +#include +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#define dev_printk(A,B,fmt,args...) printk(A fmt,##args) +#else +#include +#include +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +#include +#endif + +#include +#include + +#include "r8125.h" +#include "rtl_eeprom.h" +#include "rtltool.h" +#include "r8125_firmware.h" + +#ifdef ENABLE_R8125_PROCFS +#include +#include +#endif + +#define FIRMWARE_8125A_3 "rtl_nic/rtl8125a-3.fw" +#define FIRMWARE_8125B_2 "rtl_nic/rtl8125b-2.fw" + +/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). + The RTL chips use a 64 element hash table based on the Ethernet CRC. */ +static const int multicast_filter_limit = 32; + +static const struct { + const char *name; + const char *fw_name; +} rtl_chip_fw_infos[] = { + /* PCI-E devices. */ + [CFG_METHOD_2] = {"RTL8125A" }, + [CFG_METHOD_3] = {"RTL8125A", FIRMWARE_8125A_3}, + [CFG_METHOD_4] = {"RTL8125B", }, + [CFG_METHOD_5] = {"RTL8125B", FIRMWARE_8125B_2}, + [CFG_METHOD_6] = {"RTL8168KB", FIRMWARE_8125A_3}, + [CFG_METHOD_7] = {"RTL8168KB", FIRMWARE_8125B_2}, + [CFG_METHOD_DEFAULT] = {"Unknown", }, +}; + +#define _R(NAME,MAC,RCR,MASK,JumFrameSz) \ + { .name = NAME, .mcfg = MAC, .RCR_Cfg = RCR, .RxConfigMask = MASK, .jumbo_frame_sz = JumFrameSz } + +static const struct { + const char *name; + u8 mcfg; + u32 RCR_Cfg; + u32 RxConfigMask; /* Clears the bits supported by this chip */ + u32 jumbo_frame_sz; +} rtl_chip_info[] = { + _R("RTL8125A", + CFG_METHOD_2, + BIT_30 | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8125A", + CFG_METHOD_3, + BIT_30 | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8125B", + CFG_METHOD_4, + BIT_30 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8125B", + CFG_METHOD_5, + BIT_30 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8168KB", + CFG_METHOD_6, + BIT_30 | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("RTL8168KB", + CFG_METHOD_7, + BIT_30 | RxCfg_pause_slot_en | EnableInnerVlan | EnableOuterVlan | (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_9k), + + _R("Unknown", + CFG_METHOD_DEFAULT, + (RX_DMA_BURST << RxCfgDMAShift), + 0xff7e5880, + Jumbo_Frame_1k) +}; +#undef _R + + +#ifndef PCI_VENDOR_ID_DLINK +#define PCI_VENDOR_ID_DLINK 0x1186 +#endif + +static struct pci_device_id rtl8125_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8125), }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8162), }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x3000), }, + {0,}, +}; + +MODULE_DEVICE_TABLE(pci, rtl8125_pci_tbl); + +static int rx_copybreak = 0; +static int use_dac = 1; +static int timer_count = 0x2600; +static int timer_count_v2 = (0x2600 / 0x100); + +static struct { + u32 msg_enable; +} debug = { -1 }; + +static unsigned int speed_mode = SPEED_2500; +static unsigned int duplex_mode = DUPLEX_FULL; +static unsigned int autoneg_mode = AUTONEG_ENABLE; +static unsigned int advertising_mode = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_2500baseX_Full; +#ifdef CONFIG_ASPM +static int aspm = 1; +#else +static int aspm = 0; +#endif +#ifdef ENABLE_S5WOL +static int s5wol = 1; +#else +static int s5wol = 0; +#endif +#ifdef ENABLE_S5_KEEP_CURR_MAC +static int s5_keep_curr_mac = 1; +#else +static int s5_keep_curr_mac = 0; +#endif +#ifdef ENABLE_EEE +static int eee_enable = 1; +#else +static int eee_enable = 0; +#endif +#ifdef CONFIG_SOC_LAN +static ulong hwoptimize = HW_PATCH_SOC_LAN; +#else +static ulong hwoptimize = 0; +#endif +#ifdef ENABLE_S0_MAGIC_PACKET +static int s0_magic_packet = 1; +#else +static int s0_magic_packet = 0; +#endif +#ifdef ENABLE_TX_NO_CLOSE +static int tx_no_close_enable = 1; +#else +static int tx_no_close_enable = 0; +#endif +#ifdef ENABLE_PTP_MASTER_MODE +static int enable_ptp_master_mode = 1; +#else +static int enable_ptp_master_mode = 0; +#endif +#ifdef DISABLE_PM_SUPPORT +static int disable_pm_support = 1; +#else +static int disable_pm_support = 0; +#endif + +MODULE_AUTHOR("Realtek and the Linux r8125 crew "); +MODULE_DESCRIPTION("Realtek RTL8125 2.5Gigabit Ethernet driver"); + +module_param(speed_mode, uint, 0); +MODULE_PARM_DESC(speed_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(duplex_mode, uint, 0); +MODULE_PARM_DESC(duplex_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(autoneg_mode, uint, 0); +MODULE_PARM_DESC(autoneg_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(advertising_mode, uint, 0); +MODULE_PARM_DESC(advertising_mode, "force phy operation. Deprecated by ethtool (8)."); + +module_param(aspm, int, 0); +MODULE_PARM_DESC(aspm, "Enable ASPM."); + +module_param(s5wol, int, 0); +MODULE_PARM_DESC(s5wol, "Enable Shutdown Wake On Lan."); + +module_param(s5_keep_curr_mac, int, 0); +MODULE_PARM_DESC(s5_keep_curr_mac, "Enable Shutdown Keep Current MAC Address."); + +module_param(rx_copybreak, int, 0); +MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); + +module_param(use_dac, int, 0); +MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); + +module_param(timer_count, int, 0); +MODULE_PARM_DESC(timer_count, "Timer Interrupt Interval."); + +module_param(eee_enable, int, 0); +MODULE_PARM_DESC(eee_enable, "Enable Energy Efficient Ethernet."); + +module_param(hwoptimize, ulong, 0); +MODULE_PARM_DESC(hwoptimize, "Enable HW optimization function."); + +module_param(s0_magic_packet, int, 0); +MODULE_PARM_DESC(s0_magic_packet, "Enable S0 Magic Packet."); + +module_param(tx_no_close_enable, int, 0); +MODULE_PARM_DESC(tx_no_close_enable, "Enable TX No Close."); + +module_param(enable_ptp_master_mode, int, 0); +MODULE_PARM_DESC(enable_ptp_master_mode, "Enable PTP Master Mode."); + +module_param(disable_pm_support, int, 0); +MODULE_PARM_DESC(disable_pm_support, "Disable PM support."); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +module_param_named(debug, debug.msg_enable, int, 0); +MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 16=all)"); +#endif//LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + +MODULE_LICENSE("GPL"); +#ifdef ENABLE_USE_FIRMWARE_FILE +MODULE_FIRMWARE(FIRMWARE_8125A_3); +MODULE_FIRMWARE(FIRMWARE_8125B_2); +#endif + +MODULE_VERSION(RTL8125_VERSION); + +/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +static void rtl8125_esd_timer(unsigned long __opaque); +#else +static void rtl8125_esd_timer(struct timer_list *t); +#endif +*/ +/* +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +static void rtl8125_link_timer(unsigned long __opaque); +#else +static void rtl8125_link_timer(struct timer_list *t); +#endif +*/ + +static netdev_tx_t rtl8125_start_xmit(struct sk_buff *skb, struct net_device *dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8125_interrupt(int irq, void *dev_instance, struct pt_regs *regs); +#else +static irqreturn_t rtl8125_interrupt(int irq, void *dev_instance); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8125_interrupt_msix(int irq, void *dev_instance, struct pt_regs *regs); +#else +static irqreturn_t rtl8125_interrupt_msix(int irq, void *dev_instance); +#endif +static void rtl8125_set_rx_mode(struct net_device *dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static void rtl8125_tx_timeout(struct net_device *dev, unsigned int txqueue); +#else +static void rtl8125_tx_timeout(struct net_device *dev); +#endif +static struct net_device_stats *rtl8125_get_stats(struct net_device *dev); +static int rtl8125_rx_interrupt(struct net_device *, struct rtl8125_private *, struct rtl8125_rx_ring *, napi_budget); +static int rtl8125_tx_interrupt(struct rtl8125_tx_ring *ring, int budget); +static int rtl8125_tx_interrupt_with_vector(struct rtl8125_private *tp, const int message_id, int budget); +static void rtl8125_wait_for_quiescence(struct net_device *dev); +static int rtl8125_change_mtu(struct net_device *dev, int new_mtu); +static void rtl8125_down(struct net_device *dev); + +static int rtl8125_set_mac_address(struct net_device *dev, void *p); +static void rtl8125_rar_set(struct rtl8125_private *tp, const u8 *addr); +static void rtl8125_desc_addr_fill(struct rtl8125_private *); +static void rtl8125_tx_desc_init(struct rtl8125_private *tp); +static void rtl8125_rx_desc_init(struct rtl8125_private *tp); + +static u32 mdio_direct_read_phy_ocp(struct rtl8125_private *tp, u16 RegAddr); +static u16 rtl8125_get_hw_phy_mcu_code_ver(struct rtl8125_private *tp); +static void rtl8125_phy_power_up(struct net_device *dev); +static void rtl8125_phy_power_down(struct net_device *dev); +static int rtl8125_set_speed(struct net_device *dev, u8 autoneg, u32 speed, u8 duplex, u32 adv); +static bool rtl8125_set_phy_mcu_patch_request(struct rtl8125_private *tp); +static bool rtl8125_clear_phy_mcu_patch_request(struct rtl8125_private *tp); + +#ifdef CONFIG_R8125_NAPI +static int rtl8125_poll(napi_ptr napi, napi_budget budget); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8125_reset_task(void *_data); +static void rtl8125_esd_task(void *_data); +static void rtl8125_linkchg_task(void *_data); +#else +static void rtl8125_reset_task(struct work_struct *work); +static void rtl8125_esd_task(struct work_struct *work); +static void rtl8125_linkchg_task(struct work_struct *work); +#endif +static void rtl8125_schedule_reset_work(struct rtl8125_private *tp); +static void rtl8125_schedule_esd_work(struct rtl8125_private *tp); +static void rtl8125_schedule_linkchg_work(struct rtl8125_private *tp); +static void rtl8125_init_all_schedule_work(struct rtl8125_private *tp); +static void rtl8125_cancel_all_schedule_work(struct rtl8125_private *tp); + +static inline struct device *tp_to_dev(struct rtl8125_private *tp) +{ + return &tp->pci_dev->dev; +} + +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) && \ + LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,00))) +void ethtool_convert_legacy_u32_to_link_mode(unsigned long *dst, + u32 legacy_u32) +{ + bitmap_zero(dst, __ETHTOOL_LINK_MODE_MASK_NBITS); + dst[0] = legacy_u32; +} + +bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, + const unsigned long *src) +{ + bool retval = true; + + /* TODO: following test will soon always be true */ + if (__ETHTOOL_LINK_MODE_MASK_NBITS > 32) { + __ETHTOOL_DECLARE_LINK_MODE_MASK(ext); + + bitmap_zero(ext, __ETHTOOL_LINK_MODE_MASK_NBITS); + bitmap_fill(ext, 32); + bitmap_complement(ext, ext, __ETHTOOL_LINK_MODE_MASK_NBITS); + if (bitmap_intersects(ext, src, + __ETHTOOL_LINK_MODE_MASK_NBITS)) { + /* src mask goes beyond bit 31 */ + retval = false; + } + } + *legacy_u32 = src[0]; + return retval; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + +#ifndef LPA_1000FULL +#define LPA_1000FULL 0x0800 +#endif + +#ifndef LPA_1000HALF +#define LPA_1000HALF 0x0400 +#endif + +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0) +static inline void eth_hw_addr_random(struct net_device *dev) +{ + random_ether_addr(dev->dev_addr); +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#undef ethtool_ops +#define ethtool_ops _kc_ethtool_ops + +struct _kc_ethtool_ops { + int (*get_settings)(struct net_device *, struct ethtool_cmd *); + int (*set_settings)(struct net_device *, struct ethtool_cmd *); + void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); + int (*get_regs_len)(struct net_device *); + void (*get_regs)(struct net_device *, struct ethtool_regs *, void *); + void (*get_wol)(struct net_device *, struct ethtool_wolinfo *); + int (*set_wol)(struct net_device *, struct ethtool_wolinfo *); + u32 (*get_msglevel)(struct net_device *); + void (*set_msglevel)(struct net_device *, u32); + int (*nway_reset)(struct net_device *); + u32 (*get_link)(struct net_device *); + int (*get_eeprom_len)(struct net_device *); + int (*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *); + int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *); + int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *); + void (*get_ringparam)(struct net_device *, struct ethtool_ringparam *); + int (*set_ringparam)(struct net_device *, struct ethtool_ringparam *); + void (*get_pauseparam)(struct net_device *, + struct ethtool_pauseparam*); + int (*set_pauseparam)(struct net_device *, + struct ethtool_pauseparam*); + u32 (*get_rx_csum)(struct net_device *); + int (*set_rx_csum)(struct net_device *, u32); + u32 (*get_tx_csum)(struct net_device *); + int (*set_tx_csum)(struct net_device *, u32); + u32 (*get_sg)(struct net_device *); + int (*set_sg)(struct net_device *, u32); + u32 (*get_tso)(struct net_device *); + int (*set_tso)(struct net_device *, u32); + int (*self_test_count)(struct net_device *); + void (*self_test)(struct net_device *, struct ethtool_test *, u64 *); + void (*get_strings)(struct net_device *, u32 stringset, u8 *); + int (*phys_id)(struct net_device *, u32); + int (*get_stats_count)(struct net_device *); + void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, + u64 *); +} *ethtool_ops = NULL; + +#undef SET_ETHTOOL_OPS +#define SET_ETHTOOL_OPS(netdev, ops) (ethtool_ops = (ops)) + +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) +#ifndef SET_ETHTOOL_OPS +#define SET_ETHTOOL_OPS(netdev,ops) \ + ( (netdev)->ethtool_ops = (ops) ) +#endif //SET_ETHTOOL_OPS +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0) + +//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) +#ifndef netif_msg_init +#define netif_msg_init _kc_netif_msg_init +/* copied from linux kernel 2.6.20 include/linux/netdevice.h */ +static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) +{ + /* use default */ + if (debug_value < 0 || debug_value >= (sizeof(u32) * 8)) + return default_msg_enable_bits; + if (debug_value == 0) /* no output */ + return 0; + /* set low N bits */ + return (1 << debug_value) - 1; +} + +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) +static inline void eth_copy_and_sum (struct sk_buff *dest, + const unsigned char *src, + int len, int base) +{ + memcpy (dest->data, src, len); +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) +/* copied from linux kernel 2.6.20 /include/linux/time.h */ +/* Parameters used to convert the timespec values: */ +#define MSEC_PER_SEC 1000L + +/* copied from linux kernel 2.6.20 /include/linux/jiffies.h */ +/* + * Change timeval to jiffies, trying to avoid the + * most obvious overflows.. + * + * And some not so obvious. + * + * Note that we don't want to return MAX_LONG, because + * for various timeout reasons we often end up having + * to wait "jiffies+1" in order to guarantee that we wait + * at _least_ "jiffies" - so "jiffies+1" had better still + * be positive. + */ +#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1) + +/* + * Convert jiffies to milliseconds and back. + * + * Avoid unnecessary multiplications/divisions in the + * two most common HZ cases: + */ +static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j) +{ +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (MSEC_PER_SEC / HZ) * j; +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); +#else + return (j * MSEC_PER_SEC) / HZ; +#endif +} + +static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m) +{ + if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) + return m * (HZ / MSEC_PER_SEC); +#else + return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; +#endif +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + +/* copied from linux kernel 2.6.12.6 /include/linux/pm.h */ +typedef int __bitwise pci_power_t; + +/* copied from linux kernel 2.6.12.6 /include/linux/pci.h */ +typedef u32 __bitwise pm_message_t; + +#define PCI_D0 ((pci_power_t __force) 0) +#define PCI_D1 ((pci_power_t __force) 1) +#define PCI_D2 ((pci_power_t __force) 2) +#define PCI_D3hot ((pci_power_t __force) 3) +#define PCI_D3cold ((pci_power_t __force) 4) +#define PCI_POWER_ERROR ((pci_power_t __force) -1) + +/* copied from linux kernel 2.6.12.6 /drivers/pci/pci.c */ +/** + * pci_choose_state - Choose the power state of a PCI device + * @dev: PCI device to be suspended + * @state: target sleep state for the whole system. This is the value + * that is passed to suspend() function. + * + * Returns PCI power state suitable for given device and given system + * message. + */ + +pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) +{ + if (!pci_find_capability(dev, PCI_CAP_ID_PM)) + return PCI_D0; + + switch (state) { + case 0: + return PCI_D0; + case 3: + return PCI_D3hot; + default: + printk("They asked me for state %d\n", state); +// BUG(); + } + return PCI_D0; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) +/** + * msleep_interruptible - sleep waiting for waitqueue interruptions + * @msecs: Time in milliseconds to sleep for + */ +#define msleep_interruptible _kc_msleep_interruptible +unsigned long _kc_msleep_interruptible(unsigned int msecs) +{ + unsigned long timeout = _kc_msecs_to_jiffies(msecs); + + while (timeout && !signal_pending(current)) { + set_current_state(TASK_INTERRUPTIBLE); + timeout = schedule_timeout(timeout); + } + return _kc_jiffies_to_msecs(timeout); +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) +/* copied from linux kernel 2.6.20 include/linux/sched.h */ +#ifndef __sched +#define __sched __attribute__((__section__(".sched.text"))) +#endif + +/* copied from linux kernel 2.6.20 kernel/timer.c */ +signed long __sched schedule_timeout_uninterruptible(signed long timeout) +{ + __set_current_state(TASK_UNINTERRUPTIBLE); + return schedule_timeout(timeout); +} + +/* copied from linux kernel 2.6.20 include/linux/mii.h */ +#undef if_mii +#define if_mii _kc_if_mii +static inline struct mii_ioctl_data *if_mii(struct ifreq *rq) +{ + return (struct mii_ioctl_data *) &rq->ifr_ifru; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) + +static u32 rtl8125_read_thermal_sensor(struct rtl8125_private *tp) +{ + u16 ts_digout; + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + ts_digout = mdio_direct_read_phy_ocp(tp, 0xBD84); + ts_digout &= 0x3ff; + break; + default: + ts_digout = 0xffff; + break; + } + + return ts_digout; +} + +int rtl8125_dump_tally_counter(struct rtl8125_private *tp, dma_addr_t paddr) +{ + u32 cmd; + u32 WaitCnt; + int retval = -1; + + RTL_W32(tp, CounterAddrHigh, (u64)paddr >> 32); + cmd = (u64)paddr & DMA_BIT_MASK(32); + RTL_W32(tp, CounterAddrLow, cmd); + RTL_W32(tp, CounterAddrLow, cmd | CounterDump); + + WaitCnt = 0; + while (RTL_R32(tp, CounterAddrLow) & CounterDump) { + udelay(10); + + WaitCnt++; + if (WaitCnt > 20) + break; + } + + if (WaitCnt <= 20) + retval = 0; + + return retval; +} + +#ifdef ENABLE_R8125_PROCFS +/**************************************************************************** +* -----------------------------PROCFS STUFF------------------------- +***************************************************************************** +*/ + +static struct proc_dir_entry *rtl8125_proc; +static int proc_init_num = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +static int proc_get_driver_variable(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8125_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump Driver Variable\n"); + + rtnl_lock(); + + seq_puts(m, "Variable\tValue\n----------\t-----\n"); + seq_printf(m, "MODULENAME\t%s\n", MODULENAME); + seq_printf(m, "driver version\t%s\n", RTL8125_VERSION); + seq_printf(m, "mcfg\t%d\n", tp->mcfg); + seq_printf(m, "chipset\t%d\n", tp->chipset); + seq_printf(m, "chipset_name\t%s\n", rtl_chip_info[tp->chipset].name); + seq_printf(m, "mtu\t%d\n", dev->mtu); + seq_printf(m, "NUM_RX_DESC\t0x%x\n", tp->rx_ring[0].num_rx_desc); + seq_printf(m, "cur_rx0\t0x%x\n", tp->rx_ring[0].cur_rx); + seq_printf(m, "dirty_rx0\t0x%x\n", tp->rx_ring[0].dirty_rx); + seq_printf(m, "cur_rx1\t0x%x\n", tp->rx_ring[1].cur_rx); + seq_printf(m, "dirty_rx1\t0x%x\n", tp->rx_ring[1].dirty_rx); + seq_printf(m, "cur_rx2\t0x%x\n", tp->rx_ring[2].cur_rx); + seq_printf(m, "dirty_rx2\t0x%x\n", tp->rx_ring[2].dirty_rx); + seq_printf(m, "cur_rx3\t0x%x\n", tp->rx_ring[3].cur_rx); + seq_printf(m, "dirty_rx3\t0x%x\n", tp->rx_ring[3].dirty_rx); + seq_printf(m, "NUM_TX_DESC\t0x%x\n", tp->tx_ring[0].num_tx_desc); + seq_printf(m, "cur_tx0\t0x%x\n", tp->tx_ring[0].cur_tx); + seq_printf(m, "dirty_tx0\t0x%x\n", tp->tx_ring[0].dirty_tx); + seq_printf(m, "cur_tx1\t0x%x\n", tp->tx_ring[1].cur_tx); + seq_printf(m, "dirty_tx1\t0x%x\n", tp->tx_ring[1].dirty_tx); + seq_printf(m, "rx_buf_sz\t0x%x\n", tp->rx_buf_sz); + seq_printf(m, "esd_flag\t0x%x\n", tp->esd_flag); + seq_printf(m, "pci_cfg_is_read\t0x%x\n", tp->pci_cfg_is_read); + seq_printf(m, "rtl8125_rx_config\t0x%x\n", tp->rtl8125_rx_config); + seq_printf(m, "cp_cmd\t0x%x\n", tp->cp_cmd); + seq_printf(m, "intr_mask\t0x%x\n", tp->intr_mask); + seq_printf(m, "timer_intr_mask\t0x%x\n", tp->timer_intr_mask); + seq_printf(m, "wol_enabled\t0x%x\n", tp->wol_enabled); + seq_printf(m, "wol_opts\t0x%x\n", tp->wol_opts); + seq_printf(m, "efuse_ver\t0x%x\n", tp->efuse_ver); + seq_printf(m, "eeprom_type\t0x%x\n", tp->eeprom_type); + seq_printf(m, "autoneg\t0x%x\n", tp->autoneg); + seq_printf(m, "duplex\t0x%x\n", tp->duplex); + seq_printf(m, "speed\t%d\n", tp->speed); + seq_printf(m, "advertising\t0x%x\n", tp->advertising); + seq_printf(m, "eeprom_len\t0x%x\n", tp->eeprom_len); + seq_printf(m, "cur_page\t0x%x\n", tp->cur_page); + seq_printf(m, "bios_setting\t0x%x\n", tp->bios_setting); + seq_printf(m, "features\t0x%x\n", tp->features); + seq_printf(m, "org_pci_offset_99\t0x%x\n", tp->org_pci_offset_99); + seq_printf(m, "org_pci_offset_180\t0x%x\n", tp->org_pci_offset_180); + seq_printf(m, "issue_offset_99_event\t0x%x\n", tp->issue_offset_99_event); + seq_printf(m, "org_pci_offset_80\t0x%x\n", tp->org_pci_offset_80); + seq_printf(m, "org_pci_offset_81\t0x%x\n", tp->org_pci_offset_81); + seq_printf(m, "use_timer_interrrupt\t0x%x\n", tp->use_timer_interrrupt); + seq_printf(m, "HwIcVerUnknown\t0x%x\n", tp->HwIcVerUnknown); + seq_printf(m, "NotWrRamCodeToMicroP\t0x%x\n", tp->NotWrRamCodeToMicroP); + seq_printf(m, "NotWrMcuPatchCode\t0x%x\n", tp->NotWrMcuPatchCode); + seq_printf(m, "HwHasWrRamCodeToMicroP\t0x%x\n", tp->HwHasWrRamCodeToMicroP); + seq_printf(m, "sw_ram_code_ver\t0x%x\n", tp->sw_ram_code_ver); + seq_printf(m, "hw_ram_code_ver\t0x%x\n", tp->hw_ram_code_ver); + seq_printf(m, "rtk_enable_diag\t0x%x\n", tp->rtk_enable_diag); + seq_printf(m, "ShortPacketSwChecksum\t0x%x\n", tp->ShortPacketSwChecksum); + seq_printf(m, "UseSwPaddingShortPkt\t0x%x\n", tp->UseSwPaddingShortPkt); + seq_printf(m, "RequireRduNonStopPatch\t0x%x\n", tp->RequireRduNonStopPatch); + seq_printf(m, "RequireAdcBiasPatch\t0x%x\n", tp->RequireAdcBiasPatch); + seq_printf(m, "AdcBiasPatchIoffset\t0x%x\n", tp->AdcBiasPatchIoffset); + seq_printf(m, "RequireAdjustUpsTxLinkPulseTiming\t0x%x\n", tp->RequireAdjustUpsTxLinkPulseTiming); + seq_printf(m, "SwrCnt1msIni\t0x%x\n", tp->SwrCnt1msIni); + seq_printf(m, "HwSuppNowIsOobVer\t0x%x\n", tp->HwSuppNowIsOobVer); + seq_printf(m, "HwFiberModeVer\t0x%x\n", tp->HwFiberModeVer); + seq_printf(m, "HwFiberStat\t0x%x\n", tp->HwFiberStat); + seq_printf(m, "HwSwitchMdiToFiber\t0x%x\n", tp->HwSwitchMdiToFiber); + seq_printf(m, "NicCustLedValue\t0x%x\n", tp->NicCustLedValue); + seq_printf(m, "RequiredSecLanDonglePatch\t0x%x\n", tp->RequiredSecLanDonglePatch); + seq_printf(m, "HwSuppDashVer\t0x%x\n", tp->HwSuppDashVer); + seq_printf(m, "DASH\t0x%x\n", tp->DASH); + seq_printf(m, "dash_printer_enabled\t0x%x\n", tp->dash_printer_enabled); + seq_printf(m, "HwSuppKCPOffloadVer\t0x%x\n", tp->HwSuppKCPOffloadVer); + seq_printf(m, "speed_mode\t0x%x\n", speed_mode); + seq_printf(m, "duplex_mode\t0x%x\n", duplex_mode); + seq_printf(m, "autoneg_mode\t0x%x\n", autoneg_mode); + seq_printf(m, "advertising_mode\t0x%x\n", advertising_mode); + seq_printf(m, "aspm\t0x%x\n", aspm); + seq_printf(m, "s5wol\t0x%x\n", s5wol); + seq_printf(m, "s5_keep_curr_mac\t0x%x\n", s5_keep_curr_mac); + seq_printf(m, "eee_enable\t0x%x\n", tp->eee.eee_enabled); + seq_printf(m, "hwoptimize\t0x%lx\n", hwoptimize); + seq_printf(m, "proc_init_num\t0x%x\n", proc_init_num); + seq_printf(m, "s0_magic_packet\t0x%x\n", s0_magic_packet); + seq_printf(m, "HwSuppMagicPktVer\t0x%x\n", tp->HwSuppMagicPktVer); + seq_printf(m, "HwSuppLinkChgWakeUpVer\t0x%x\n", tp->HwSuppLinkChgWakeUpVer); + seq_printf(m, "HwSuppD0SpeedUpVer\t0x%x\n", tp->HwSuppD0SpeedUpVer); + seq_printf(m, "D0SpeedUpSpeed\t0x%x\n", tp->D0SpeedUpSpeed); + seq_printf(m, "HwSuppCheckPhyDisableModeVer\t0x%x\n", tp->HwSuppCheckPhyDisableModeVer); + seq_printf(m, "HwPkgDet\t0x%x\n", tp->HwPkgDet); + seq_printf(m, "HwSuppTxNoCloseVer\t0x%x\n", tp->HwSuppTxNoCloseVer); + seq_printf(m, "EnableTxNoClose\t0x%x\n", tp->EnableTxNoClose); + seq_printf(m, "NextHwDesCloPtr0\t0x%x\n", tp->tx_ring[0].NextHwDesCloPtr); + seq_printf(m, "BeginHwDesCloPtr0\t0x%x\n", tp->tx_ring[0].BeginHwDesCloPtr); + seq_printf(m, "NextHwDesCloPtr1\t0x%x\n", tp->tx_ring[1].NextHwDesCloPtr); + seq_printf(m, "BeginHwDesCloPtr1\t0x%x\n", tp->tx_ring[1].BeginHwDesCloPtr); + seq_printf(m, "InitRxDescType\t0x%x\n", tp->InitRxDescType); + seq_printf(m, "RxDescLength\t0x%x\n", tp->RxDescLength); + seq_printf(m, "num_rx_rings\t0x%x\n", tp->num_rx_rings); + seq_printf(m, "num_tx_rings\t0x%x\n", tp->num_tx_rings); + seq_printf(m, "tot_rx_rings\t0x%x\n", rtl8125_tot_rx_rings(tp)); + seq_printf(m, "tot_tx_rings\t0x%x\n", rtl8125_tot_tx_rings(tp)); + seq_printf(m, "EnableRss\t0x%x\n", tp->EnableRss); + seq_printf(m, "EnablePtp\t0x%x\n", tp->EnablePtp); + seq_printf(m, "ptp_master_mode\t0x%x\n", tp->ptp_master_mode); + seq_printf(m, "min_irq_nvecs\t0x%x\n", tp->min_irq_nvecs); + seq_printf(m, "irq_nvecs\t0x%x\n", tp->irq_nvecs); + seq_printf(m, "ring_lib_enabled\t0x%x\n", tp->ring_lib_enabled); + seq_printf(m, "HwSuppIsrVer\t0x%x\n", tp->HwSuppIsrVer); + seq_printf(m, "HwCurrIsrVer\t0x%x\n", tp->HwCurrIsrVer); +#ifdef ENABLE_PTP_SUPPORT + seq_printf(m, "tx_hwtstamp_timeouts\t0x%x\n", tp->tx_hwtstamp_timeouts); + seq_printf(m, "tx_hwtstamp_skipped\t0x%x\n", tp->tx_hwtstamp_skipped); +#endif + seq_printf(m, "random_mac\t0x%x\n", tp->random_mac); + seq_printf(m, "org_mac_addr\t%pM\n", tp->org_mac_addr); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + seq_printf(m, "perm_addr\t%pM\n", dev->perm_addr); +#endif + seq_printf(m, "dev_addr\t%pM\n", dev->dev_addr); + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_tally_counter(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8125_private *tp = netdev_priv(dev); + struct rtl8125_counters *counters; + dma_addr_t paddr; + + seq_puts(m, "\nDump Tally Counter\n"); + + rtnl_lock(); + + counters = tp->tally_vaddr; + paddr = tp->tally_paddr; + if (!counters) { + seq_puts(m, "\nDump Tally Counter Fail\n"); + goto out_unlock; + } + + rtl8125_dump_tally_counter(tp, paddr); + + seq_puts(m, "Statistics\tValue\n----------\t-----\n"); + seq_printf(m, "tx_packets\t%lld\n", le64_to_cpu(counters->tx_packets)); + seq_printf(m, "rx_packets\t%lld\n", le64_to_cpu(counters->rx_packets)); + seq_printf(m, "tx_errors\t%lld\n", le64_to_cpu(counters->tx_errors)); + seq_printf(m, "rx_errors\t%d\n", le32_to_cpu(counters->rx_errors)); + seq_printf(m, "rx_missed\t%d\n", le16_to_cpu(counters->rx_missed)); + seq_printf(m, "align_errors\t%d\n", le16_to_cpu(counters->align_errors)); + seq_printf(m, "tx_one_collision\t%d\n", le32_to_cpu(counters->tx_one_collision)); + seq_printf(m, "tx_multi_collision\t%d\n", le32_to_cpu(counters->tx_multi_collision)); + seq_printf(m, "rx_unicast\t%lld\n", le64_to_cpu(counters->rx_unicast)); + seq_printf(m, "rx_broadcast\t%lld\n", le64_to_cpu(counters->rx_broadcast)); + seq_printf(m, "rx_multicast\t%d\n", le32_to_cpu(counters->rx_multicast)); + seq_printf(m, "tx_aborted\t%d\n", le16_to_cpu(counters->tx_aborted)); + seq_printf(m, "tx_underrun\t%d\n", le16_to_cpu(counters->tx_underrun)); + + seq_printf(m, "tx_octets\t%lld\n", le64_to_cpu(counters->tx_octets)); + seq_printf(m, "rx_octets\t%lld\n", le64_to_cpu(counters->rx_octets)); + seq_printf(m, "rx_multicast64\t%lld\n", le64_to_cpu(counters->rx_multicast64)); + seq_printf(m, "tx_unicast64\t%lld\n", le64_to_cpu(counters->tx_unicast64)); + seq_printf(m, "tx_broadcast64\t%lld\n", le64_to_cpu(counters->tx_broadcast64)); + seq_printf(m, "tx_multicast64\t%lld\n", le64_to_cpu(counters->tx_multicast64)); + seq_printf(m, "tx_pause_on\t%d\n", le32_to_cpu(counters->tx_pause_on)); + seq_printf(m, "tx_pause_off\t%d\n", le32_to_cpu(counters->tx_pause_off)); + seq_printf(m, "tx_pause_all\t%d\n", le32_to_cpu(counters->tx_pause_all)); + seq_printf(m, "tx_deferred\t%d\n", le32_to_cpu(counters->tx_deferred)); + seq_printf(m, "tx_late_collision\t%d\n", le32_to_cpu(counters->tx_late_collision)); + seq_printf(m, "tx_all_collision\t%d\n", le32_to_cpu(counters->tx_all_collision)); + seq_printf(m, "tx_aborted32\t%d\n", le32_to_cpu(counters->tx_aborted32)); + seq_printf(m, "align_errors32\t%d\n", le32_to_cpu(counters->align_errors32)); + seq_printf(m, "rx_frame_too_long\t%d\n", le32_to_cpu(counters->rx_frame_too_long)); + seq_printf(m, "rx_runt\t%d\n", le32_to_cpu(counters->rx_runt)); + seq_printf(m, "rx_pause_on\t%d\n", le32_to_cpu(counters->rx_pause_on)); + seq_printf(m, "rx_pause_off\t%d\n", le32_to_cpu(counters->rx_pause_off)); + seq_printf(m, "rx_pause_all\t%d\n", le32_to_cpu(counters->rx_pause_all)); + seq_printf(m, "rx_unknown_opcode\t%d\n", le32_to_cpu(counters->rx_unknown_opcode)); + seq_printf(m, "rx_mac_error\t%d\n", le32_to_cpu(counters->rx_mac_error)); + seq_printf(m, "tx_underrun32\t%d\n", le32_to_cpu(counters->tx_underrun32)); + seq_printf(m, "rx_mac_missed\t%d\n", le32_to_cpu(counters->rx_mac_missed)); + seq_printf(m, "rx_tcam_dropped\t%d\n", le32_to_cpu(counters->rx_tcam_dropped)); + seq_printf(m, "tdu\t%d\n", le32_to_cpu(counters->tdu)); + seq_printf(m, "rdu\t%d\n", le32_to_cpu(counters->rdu)); + + seq_putc(m, '\n'); + +out_unlock: + rtnl_unlock(); + + return 0; +} + +static int proc_get_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8125_MAC_REGS_SIZE; + u8 byte_rd; + struct rtl8125_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + + seq_puts(m, "\nDump MAC Registers\n"); + seq_puts(m, "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + seq_printf(m, "%02x ", byte_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_pcie_phy(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8125_EPHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8125_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump PCIE PHY\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8125_ephy_read(tp, n); + seq_printf(m, "%04x ", word_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_eth_phy(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8125_PHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8125_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump Ethernet PHY\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + seq_puts(m, "\n####################page 0##################\n "); + rtl8125_mdio_write(tp, 0x1f, 0x0000); + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8125_mdio_read(tp, n); + seq_printf(m, "%04x ", word_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_extended_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8125_ERI_REGS_SIZE; + u32 dword_rd; + struct rtl8125_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump Extended Registers\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%02x:\t", n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + dword_rd = rtl8125_eri_read(tp, n, 4, ERIAR_ExGMAC); + seq_printf(m, "%08x ", dword_rd); + } + } + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_pci_registers(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + int i, n, max = R8125_PCI_REGS_SIZE; + u32 dword_rd; + struct rtl8125_private *tp = netdev_priv(dev); + + seq_puts(m, "\nDump PCI Registers\n"); + seq_puts(m, "\nOffset\tValue\n------\t-----\n "); + + rtnl_lock(); + + for (n = 0; n < max;) { + seq_printf(m, "\n0x%03x:\t", n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + seq_printf(m, "%08x ", dword_rd); + } + } + + n = 0x110; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + seq_printf(m, "\n0x%03x:\t%08x ", n, dword_rd); + n = 0x70c; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + seq_printf(m, "\n0x%03x:\t%08x ", n, dword_rd); + + rtnl_unlock(); + + seq_putc(m, '\n'); + return 0; +} + +static int proc_get_temperature(struct seq_file *m, void *v) +{ + struct net_device *dev = m->private; + struct rtl8125_private *tp = netdev_priv(dev); + u16 ts_digout, tj, fah; + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + seq_puts(m, "\nChip Temperature\n"); + break; + default: + seq_puts(m, "\nThis Chip Does Not Support Dump Temperature\n"); + break; + } + + rtnl_lock(); + ts_digout = rtl8125_read_thermal_sensor(tp); + rtnl_unlock(); + + tj = ts_digout / 2; + if (ts_digout <= 512) { + tj = ts_digout / 2; + seq_printf(m, "Cel:%d\n", tj); + fah = tj * (9/5) + 32; + seq_printf(m, "Fah:%d\n", fah); + } else { + tj = (512 - ((ts_digout / 2) - 512)) / 2; + seq_printf(m, "Cel:-%d\n", tj); + fah = tj * (9/5) + 32; + seq_printf(m, "Fah:-%d\n", fah); + } + + seq_putc(m, '\n'); + return 0; +} +#else + +static int proc_get_driver_variable(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct rtl8125_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Driver Driver\n"); + + rtnl_lock(); + + len += snprintf(page + len, count - len, + "Variable\tValue\n----------\t-----\n"); + + len += snprintf(page + len, count - len, + "MODULENAME\t%s\n" + "driver version\t%s\n" + "mcfg\t%d\n" + "chipset\t%d\n" + "chipset_name\t%s\n" + "mtu\t%d\n" + "NUM_RX_DESC\t0x%x\n" + "cur_rx0\t0x%x\n" + "dirty_rx0\t0x%x\n" + "cur_rx1\t0x%x\n" + "dirty_rx1\t0x%x\n" + "cur_rx2\t0x%x\n" + "dirty_rx2\t0x%x\n" + "cur_rx3\t0x%x\n" + "dirty_rx3\t0x%x\n" + "NUM_TX_DESC\t0x%x\n" + "cur_tx0\t0x%x\n" + "dirty_tx0\t0x%x\n" + "cur_tx1\t0x%x\n" + "dirty_tx1\t0x%x\n" + "rx_buf_sz\t0x%x\n" + "esd_flag\t0x%x\n" + "pci_cfg_is_read\t0x%x\n" + "rtl8125_rx_config\t0x%x\n" + "cp_cmd\t0x%x\n" + "intr_mask\t0x%x\n" + "timer_intr_mask\t0x%x\n" + "wol_enabled\t0x%x\n" + "wol_opts\t0x%x\n" + "efuse_ver\t0x%x\n" + "eeprom_type\t0x%x\n" + "autoneg\t0x%x\n" + "duplex\t0x%x\n" + "speed\t%d\n" + "advertising\t0x%x\n" + "eeprom_len\t0x%x\n" + "cur_page\t0x%x\n" + "bios_setting\t0x%x\n" + "features\t0x%x\n" + "org_pci_offset_99\t0x%x\n" + "org_pci_offset_180\t0x%x\n" + "issue_offset_99_event\t0x%x\n" + "org_pci_offset_80\t0x%x\n" + "org_pci_offset_81\t0x%x\n" + "use_timer_interrrupt\t0x%x\n" + "HwIcVerUnknown\t0x%x\n" + "NotWrRamCodeToMicroP\t0x%x\n" + "NotWrMcuPatchCode\t0x%x\n" + "HwHasWrRamCodeToMicroP\t0x%x\n" + "sw_ram_code_ver\t0x%x\n" + "hw_ram_code_ver\t0x%x\n" + "rtk_enable_diag\t0x%x\n" + "ShortPacketSwChecksum\t0x%x\n" + "UseSwPaddingShortPkt\t0x%x\n" + "RequireRduNonStopPatch\t0x%x\n" + "RequireAdcBiasPatch\t0x%x\n" + "AdcBiasPatchIoffset\t0x%x\n" + "RequireAdjustUpsTxLinkPulseTiming\t0x%x\n" + "SwrCnt1msIni\t0x%x\n" + "HwSuppNowIsOobVer\t0x%x\n" + "HwFiberModeVer\t0x%x\n" + "HwFiberStat\t0x%x\n" + "HwSwitchMdiToFiber\t0x%x\n" + "NicCustLedValue\t0x%x\n" + "RequiredSecLanDonglePatch\t0x%x\n" + "HwSuppDashVer\t0x%x\n" + "DASH\t0x%x\n" + "dash_printer_enabled\t0x%x\n" + "HwSuppKCPOffloadVer\t0x%x\n" + "speed_mode\t0x%x\n" + "duplex_mode\t0x%x\n" + "autoneg_mode\t0x%x\n" + "advertising_mode\t0x%x\n" + "aspm\t0x%x\n" + "s5wol\t0x%x\n" + "s5_keep_curr_mac\t0x%x\n" + "eee_enable\t0x%x\n" + "hwoptimize\t0x%lx\n" + "proc_init_num\t0x%x\n" + "s0_magic_packet\t0x%x\n" + "HwSuppMagicPktVer\t0x%x\n" + "HwSuppLinkChgWakeUpVer\t0x%x\n" + "HwSuppD0SpeedUpVer\t0x%x\n" + "D0SpeedUpSpeed\t0x%x\n" + "HwSuppCheckPhyDisableModeVer\t0x%x\n" + "HwPkgDet\t0x%x\n" + "HwSuppTxNoCloseVer\t0x%x\n" + "EnableTxNoClose\t0x%x\n" + "NextHwDesCloPtr0\t0x%x\n" + "BeginHwDesCloPtr0\t0x%x\n" + "NextHwDesCloPtr1\t0x%x\n" + "BeginHwDesCloPtr1\t0x%x\n" + "InitRxDescType\t0x%x\n" + "RxDescLength\t0x%x\n" + "num_rx_rings\t0x%x\n" + "num_tx_rings\t0x%x\n" + "tot_rx_rings\t0x%x\n" + "tot_tx_rings\t0x%x\n" + "EnableRss\t0x%x\n" + "EnablePtp\t0x%x\n" + "ptp_master_mode\t0x%x\n" + "min_irq_nvecs\t0x%x\n" + "irq_nvecs\t0x%x\n" + "ring_lib_enabled\t0x%x\n" + "HwSuppIsrVer\t0x%x\n" + "HwCurrIsrVer\t0x%x\n" +#ifdef ENABLE_PTP_SUPPORT + "tx_hwtstamp_timeouts\t0x%x\n" + "tx_hwtstamp_skipped\t0x%x\n" +#endif + "random_mac\t0x%x\n" + "org_mac_addr\t%pM\n" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + "perm_addr\t%pM\n" +#endif + "dev_addr\t%pM\n", + MODULENAME, + RTL8125_VERSION, + tp->mcfg, + tp->chipset, + rtl_chip_info[tp->chipset].name, + dev->mtu, + tp->rx_ring[0].num_rx_desc, + tp->rx_ring[0].cur_rx, + tp->rx_ring[0].dirty_rx, + tp->rx_ring[1].cur_rx, + tp->rx_ring[1].dirty_rx, + tp->rx_ring[2].cur_rx, + tp->rx_ring[2].dirty_rx, + tp->rx_ring[3].cur_rx, + tp->rx_ring[3].dirty_rx, + tp->tx_ring[0].num_tx_desc, + tp->tx_ring[0].cur_tx, + tp->tx_ring[0].dirty_tx, + tp->tx_ring[1].cur_tx, + tp->tx_ring[1].dirty_tx, + tp->rx_buf_sz, + tp->esd_flag, + tp->pci_cfg_is_read, + tp->rtl8125_rx_config, + tp->cp_cmd, + tp->intr_mask, + tp->timer_intr_mask, + tp->wol_enabled, + tp->wol_opts, + tp->efuse_ver, + tp->eeprom_type, + tp->autoneg, + tp->duplex, + tp->speed, + tp->advertising, + tp->eeprom_len, + tp->cur_page, + tp->bios_setting, + tp->features, + tp->org_pci_offset_99, + tp->org_pci_offset_180, + tp->issue_offset_99_event, + tp->org_pci_offset_80, + tp->org_pci_offset_81, + tp->use_timer_interrrupt, + tp->HwIcVerUnknown, + tp->NotWrRamCodeToMicroP, + tp->NotWrMcuPatchCode, + tp->HwHasWrRamCodeToMicroP, + tp->sw_ram_code_ver, + tp->hw_ram_code_ver, + tp->rtk_enable_diag, + tp->ShortPacketSwChecksum, + tp->UseSwPaddingShortPkt, + tp->RequireRduNonStopPatch, + tp->RequireAdcBiasPatch, + tp->AdcBiasPatchIoffset, + tp->RequireAdjustUpsTxLinkPulseTiming, + tp->SwrCnt1msIni, + tp->HwSuppNowIsOobVer, + tp->HwFiberModeVer, + tp->HwFiberStat, + tp->HwSwitchMdiToFiber, + tp->NicCustLedValue, + tp->RequiredSecLanDonglePatch, + tp->HwSuppDashVer, + tp->DASH, + tp->dash_printer_enabled, + tp->HwSuppKCPOffloadVer, + speed_mode, + duplex_mode, + autoneg_mode, + advertising_mode, + aspm, + s5wol, + s5_keep_curr_mac, + tp->eee.eee_enabled, + hwoptimize, + proc_init_num, + s0_magic_packet, + tp->HwSuppMagicPktVer, + tp->HwSuppLinkChgWakeUpVer, + tp->HwSuppD0SpeedUpVer, + tp->D0SpeedUpSpeed, + tp->HwSuppCheckPhyDisableModeVer, + tp->HwPkgDet, + tp->HwSuppTxNoCloseVer, + tp->EnableTxNoClose, + tp->tx_ring[0].NextHwDesCloPtr, + tp->tx_ring[0].BeginHwDesCloPtr, + tp->tx_ring[1].NextHwDesCloPtr, + tp->tx_ring[1].BeginHwDesCloPtr, + tp->InitRxDescType, + tp->RxDescLength, + tp->num_rx_rings, + tp->num_tx_rings, + tp->tot_rx_rings, + tp->tot_tx_rings, + tp->EnableRss, + tp->EnablePtp, + tp->ptp_master_mode, + tp->min_irq_nvecs, + tp->irq_nvecs, + tp->ring_lib_enabled, + tp->HwSuppIsrVer, + tp->HwCurrIsrVer, +#ifdef ENABLE_PTP_SUPPORT + tp->tx_hwtstamp_timeouts, + tp->tx_hwtstamp_skipped, +#endif + tp->random_mac, + tp->org_mac_addr, +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + dev->perm_addr, +#endif + dev->dev_addr + ); + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_tally_counter(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct rtl8125_private *tp = netdev_priv(dev); + struct rtl8125_counters *counters; + dma_addr_t paddr; + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Tally Counter\n"); + + rtnl_lock(); + + counters = tp->tally_vaddr; + paddr = tp->tally_paddr; + if (!counters) { + len += snprintf(page + len, count - len, + "\nDump Tally Counter Fail\n"); + goto out_unlock; + } + + rtl8125_dump_tally_counter(tp, paddr); + + len += snprintf(page + len, count - len, + "Statistics\tValue\n----------\t-----\n"); + + len += snprintf(page + len, count - len, + "tx_packets\t%lld\n" + "rx_packets\t%lld\n" + "tx_errors\t%lld\n" + "rx_errors\t%d\n" + "rx_missed\t%d\n" + "align_errors\t%d\n" + "tx_one_collision\t%d\n" + "tx_multi_collision\t%d\n" + "rx_unicast\t%lld\n" + "rx_broadcast\t%lld\n" + "rx_multicast\t%d\n" + "tx_aborted\t%d\n" + "tx_underrun\t%d\n", + + "tx_octets\t%lld\n", + "rx_octets\t%lld\n", + "rx_multicast64\t%lld\n", + "tx_unicast64\t%lld\n", + "tx_broadcast64\t%lld\n", + "tx_multicast64\t%lld\n", + "tx_pause_on\t%d\n", + "tx_pause_off\t%d\n", + "tx_pause_all\t%d\n", + "tx_deferred\t%d\n", + "tx_late_collision\t%d\n", + "tx_all_collision\t%d\n", + "tx_aborted32\t%d\n", + "align_errors32\t%d\n", + "rx_frame_too_long\t%d\n", + "rx_runt\t%d\n", + "rx_pause_on\t%d\n", + "rx_pause_off\t%d\n", + "rx_pause_all\t%d\n", + "rx_unknown_opcode\t%d\n", + "rx_mac_error\t%d\n", + "tx_underrun32\t%d\n", + "rx_mac_missed\t%d\n", + "rx_tcam_dropped\t%d\n", + "tdu\t%d\n", + "rdu\t%d\n", + le64_to_cpu(counters->tx_packets), + le64_to_cpu(counters->rx_packets), + le64_to_cpu(counters->tx_errors), + le32_to_cpu(counters->rx_errors), + le16_to_cpu(counters->rx_missed), + le16_to_cpu(counters->align_errors), + le32_to_cpu(counters->tx_one_collision), + le32_to_cpu(counters->tx_multi_collision), + le64_to_cpu(counters->rx_unicast), + le64_to_cpu(counters->rx_broadcast), + le32_to_cpu(counters->rx_multicast), + le16_to_cpu(counters->tx_aborted), + le16_to_cpu(counters->tx_underrun), + + le64_to_cpu(counters->tx_octets), + le64_to_cpu(counters->rx_octets), + le64_to_cpu(counters->rx_multicast64), + le64_to_cpu(counters->tx_unicast64), + le64_to_cpu(counters->tx_broadcast64), + le64_to_cpu(counters->tx_multicast64), + le32_to_cpu(counters->tx_pause_on), + le32_to_cpu(counters->tx_pause_off), + le32_to_cpu(counters->tx_pause_all), + le32_to_cpu(counters->tx_deferred), + le32_to_cpu(counters->tx_late_collision), + le32_to_cpu(counters->tx_all_collision), + le32_to_cpu(counters->tx_aborted32), + le32_to_cpu(counters->align_errors32), + le32_to_cpu(counters->rx_frame_too_long), + le32_to_cpu(counters->rx_runt), + le32_to_cpu(counters->rx_pause_on), + le32_to_cpu(counters->rx_pause_off), + le32_to_cpu(counters->rx_pause_all), + le32_to_cpu(counters->rx_unknown_opcode), + le32_to_cpu(counters->rx_mac_error), + le32_to_cpu(counters->tx_underrun32), + le32_to_cpu(counters->rx_mac_missed), + le32_to_cpu(counters->rx_tcam_dropped), + le32_to_cpu(counters->tdu), + le32_to_cpu(counters->rdu), + ); + + len += snprintf(page + len, count - len, "\n"); +out_unlock: + rtnl_unlock(); + + *eof = 1; + return len; +} + +static int proc_get_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8125_MAC_REGS_SIZE; + u8 byte_rd; + struct rtl8125_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump MAC Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 16 && n < max; i++, n++) { + byte_rd = readb(ioaddr + n); + len += snprintf(page + len, count - len, + "%02x ", + byte_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_pcie_phy(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8125_EPHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8125_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump PCIE PHY\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8125_ephy_read(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_eth_phy(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8125_PHY_REGS_SIZE/2; + u16 word_rd; + struct rtl8125_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Ethernet PHY\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + len += snprintf(page + len, count - len, + "\n####################page 0##################\n"); + rtl8125_mdio_write(tp, 0x1f, 0x0000); + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 8 && n < max; i++, n++) { + word_rd = rtl8125_mdio_read(tp, n); + len += snprintf(page + len, count - len, + "%04x ", + word_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_extended_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8125_ERI_REGS_SIZE; + u32 dword_rd; + struct rtl8125_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump Extended Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%02x:\t", + n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + dword_rd = rtl8125_eri_read(tp, n, 4, ERIAR_ExGMAC); + len += snprintf(page + len, count - len, + "%08x ", + dword_rd); + } + } + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_pci_registers(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + int i, n, max = R8125_PCI_REGS_SIZE; + u32 dword_rd; + struct rtl8125_private *tp = netdev_priv(dev); + int len = 0; + + len += snprintf(page + len, count - len, + "\nDump PCI Registers\n" + "Offset\tValue\n------\t-----\n"); + + rtnl_lock(); + + for (n = 0; n < max;) { + len += snprintf(page + len, count - len, + "\n0x%03x:\t", + n); + + for (i = 0; i < 4 && n < max; i++, n+=4) { + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + len += snprintf(page + len, count - len, + "%08x ", + dword_rd); + } + } + + n = 0x110; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + len += snprintf(page + len, count - len, + "\n0x%03x:\t%08x ", + n, + dword_rd); + n = 0x70c; + pci_read_config_dword(tp->pci_dev, n, &dword_rd); + len += snprintf(page + len, count - len, + "\n0x%03x:\t%08x ", + n, + dword_rd); + + rtnl_unlock(); + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} + +static int proc_get_temperature(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct rtl8125_private *tp = netdev_priv(dev); + u16 ts_digout, tj, fah; + int len = 0; + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + len += snprintf(page + len, count - len, + "\nChip Temperature\n"); + break; + default: + len += snprintf(page + len, count - len, + "\nThis Chip Does Not Support Dump Temperature\n"); + break; + } + + rtnl_lock(); + ts_digout = rtl8125_read_thermal_sensor(tp); + rtnl_unlock(); + + tj = ts_digout / 2; + if (ts_digout <= 512) { + tj = ts_digout / 2; + len += snprintf(page + len, count - len, + "Cel:%d\n", + tj); + fah = tj * (9/5) + 32; + len += snprintf(page + len, count - len, + "Fah:%d\n", + fah); + + } else { + tj = (512 - ((ts_digout / 2) - 512)) / 2; + len += snprintf(page + len, count - len, + "Cel:-%d\n", + tj); + fah = tj * (9/5) + 32; + len += snprintf(page + len, count - len, + "Fah:-%d\n", + fah); + } + + len += snprintf(page + len, count - len, "\n"); + + *eof = 1; + return len; +} +#endif +static void rtl8125_proc_module_init(void) +{ + //create /proc/net/r8125 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + rtl8125_proc = proc_mkdir(MODULENAME, init_net.proc_net); +#else + rtl8125_proc = proc_mkdir(MODULENAME, proc_net); +#endif + if (!rtl8125_proc) + dprintk("cannot create %s proc entry \n", MODULENAME); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) +/* + * seq_file wrappers for procfile show routines. + */ +static int rtl8125_proc_open(struct inode *inode, struct file *file) +{ + struct net_device *dev = proc_get_parent_data(inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) + int (*show)(struct seq_file *, void *) = pde_data(inode); +#else + int (*show)(struct seq_file *, void *) = PDE_DATA(inode); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) + + return single_open(file, show, dev); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static const struct proc_ops rtl8125_proc_fops = { + .proc_open = rtl8125_proc_open, + .proc_read = seq_read, + .proc_lseek = seq_lseek, + .proc_release = single_release, +}; +#else +static const struct file_operations rtl8125_proc_fops = { + .open = rtl8125_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif + +#endif + +/* + * Table of proc files we need to create. + */ +struct rtl8125_proc_file { + char name[12]; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + int (*show)(struct seq_file *, void *); +#else + int (*show)(char *, char **, off_t, int, int *, void *); +#endif +}; + +static const struct rtl8125_proc_file rtl8125_proc_files[] = { + { "driver_var", &proc_get_driver_variable }, + { "tally", &proc_get_tally_counter }, + { "registers", &proc_get_registers }, + { "pcie_phy", &proc_get_pcie_phy }, + { "eth_phy", &proc_get_eth_phy }, + { "ext_regs", &proc_get_extended_registers }, + { "pci_regs", &proc_get_pci_registers }, + { "temp", &proc_get_temperature }, + { "", NULL } +}; + +static void rtl8125_proc_init(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + const struct rtl8125_proc_file *f; + struct proc_dir_entry *dir; + + if (rtl8125_proc && !tp->proc_dir) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + dir = proc_mkdir_data(dev->name, 0, rtl8125_proc, dev); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s\n", + MODULENAME, dev->name); + return; + } + + tp->proc_dir = dir; + proc_init_num++; + + for (f = rtl8125_proc_files; f->name[0]; f++) { + if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, + &rtl8125_proc_fops, f->show)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s\n", + MODULENAME, dev->name, f->name); + return; + } + } +#else + dir = proc_mkdir(dev->name, rtl8125_proc); + if (!dir) { + printk("Unable to initialize /proc/net/%s/%s\n", + MODULENAME, dev->name); + return; + } + + tp->proc_dir = dir; + proc_init_num++; + + for (f = rtl8125_proc_files; f->name[0]; f++) { + if (!create_proc_read_entry(f->name, S_IFREG | S_IRUGO, + dir, f->show, dev)) { + printk("Unable to initialize " + "/proc/net/%s/%s/%s\n", + MODULENAME, dev->name, f->name); + return; + } + } +#endif + } +} + +static void rtl8125_proc_remove(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->proc_dir) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + remove_proc_subtree(dev->name, rtl8125_proc); + proc_init_num--; + +#else + const struct rtl8125_proc_file *f; + struct rtl8125_private *tp = netdev_priv(dev); + + for (f = rtl8125_proc_files; f->name[0]; f++) + remove_proc_entry(f->name, tp->proc_dir); + + remove_proc_entry(dev->name, rtl8125_proc); + proc_init_num--; +#endif + tp->proc_dir = NULL; + } +} + +#endif //ENABLE_R8125_PROCFS + +static inline u16 map_phy_ocp_addr(u16 PageNum, u8 RegNum) +{ + u16 OcpPageNum = 0; + u8 OcpRegNum = 0; + u16 OcpPhyAddress = 0; + + if ( PageNum == 0 ) { + OcpPageNum = OCP_STD_PHY_BASE_PAGE + ( RegNum / 8 ); + OcpRegNum = 0x10 + ( RegNum % 8 ); + } else { + OcpPageNum = PageNum; + OcpRegNum = RegNum; + } + + OcpPageNum <<= 4; + + if ( OcpRegNum < 16 ) { + OcpPhyAddress = 0; + } else { + OcpRegNum -= 16; + OcpRegNum <<= 1; + + OcpPhyAddress = OcpPageNum + OcpRegNum; + } + + + return OcpPhyAddress; +} + +static void mdio_real_direct_write_phy_ocp(struct rtl8125_private *tp, + u16 RegAddr, + u16 value) +{ + u32 data32; + int i; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(RegAddr % 2); +#endif + data32 = RegAddr/2; + data32 <<= OCPR_Addr_Reg_shift; + data32 |= OCPR_Write | value; + + RTL_W32(tp, PHYOCP, data32); + for (i = 0; i < 100; i++) { + udelay(1); + + if (!(RTL_R32(tp, PHYOCP) & OCPR_Flag)) + break; + } +} + +static void mdio_direct_write_phy_ocp(struct rtl8125_private *tp, + u16 RegAddr, + u16 value) +{ + if (tp->rtk_enable_diag) return; + + mdio_real_direct_write_phy_ocp(tp, RegAddr, value); +} + +/* +static void rtl8125_mdio_write_phy_ocp(struct rtl8125_private *tp, + u16 PageNum, + u32 RegAddr, + u32 value) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + mdio_direct_write_phy_ocp(tp, ocp_addr, value); +} +*/ + +static void rtl8125_mdio_real_write_phy_ocp(struct rtl8125_private *tp, + u16 PageNum, + u32 RegAddr, + u32 value) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + mdio_real_direct_write_phy_ocp(tp, ocp_addr, value); +} + +static void mdio_real_write(struct rtl8125_private *tp, + u16 RegAddr, + u16 value) +{ + if (RegAddr == 0x1F) { + tp->cur_page = value; + return; + } + rtl8125_mdio_real_write_phy_ocp(tp, tp->cur_page, RegAddr, value); +} + +void rtl8125_mdio_write(struct rtl8125_private *tp, + u16 RegAddr, + u16 value) +{ + if (tp->rtk_enable_diag) return; + + mdio_real_write(tp, RegAddr, value); +} + +void rtl8125_mdio_prot_write(struct rtl8125_private *tp, + u32 RegAddr, + u32 value) +{ + mdio_real_write(tp, RegAddr, value); +} + +void rtl8125_mdio_prot_direct_write_phy_ocp(struct rtl8125_private *tp, + u32 RegAddr, + u32 value) +{ + mdio_real_direct_write_phy_ocp(tp, RegAddr, value); +} + +static u32 mdio_real_direct_read_phy_ocp(struct rtl8125_private *tp, + u16 RegAddr) +{ + u32 data32; + int i, value = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(RegAddr % 2); +#endif + data32 = RegAddr/2; + data32 <<= OCPR_Addr_Reg_shift; + + RTL_W32(tp, PHYOCP, data32); + for (i = 0; i < 100; i++) { + udelay(1); + + if (RTL_R32(tp, PHYOCP) & OCPR_Flag) + break; + } + value = RTL_R32(tp, PHYOCP) & OCPDR_Data_Mask; + + return value; +} + +static u32 mdio_direct_read_phy_ocp(struct rtl8125_private *tp, + u16 RegAddr) +{ + if (tp->rtk_enable_diag) return 0xffffffff; + + return mdio_real_direct_read_phy_ocp(tp, RegAddr); +} + +/* +static u32 rtl8125_mdio_read_phy_ocp(struct rtl8125_private *tp, + u16 PageNum, + u32 RegAddr) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + return mdio_direct_read_phy_ocp(tp, ocp_addr); +} +*/ + +static u32 rtl8125_mdio_real_read_phy_ocp(struct rtl8125_private *tp, + u16 PageNum, + u32 RegAddr) +{ + u16 ocp_addr; + + ocp_addr = map_phy_ocp_addr(PageNum, RegAddr); + + return mdio_real_direct_read_phy_ocp(tp, ocp_addr); +} + +static u32 mdio_real_read(struct rtl8125_private *tp, + u16 RegAddr) +{ + return rtl8125_mdio_real_read_phy_ocp(tp, tp->cur_page, RegAddr); +} + +u32 rtl8125_mdio_read(struct rtl8125_private *tp, + u16 RegAddr) +{ + if (tp->rtk_enable_diag) return 0xffffffff; + + return mdio_real_read(tp, RegAddr); +} + +u32 rtl8125_mdio_prot_read(struct rtl8125_private *tp, + u32 RegAddr) +{ + return mdio_real_read(tp, RegAddr); +} + +u32 rtl8125_mdio_prot_direct_read_phy_ocp(struct rtl8125_private *tp, + u32 RegAddr) +{ + return mdio_real_direct_read_phy_ocp(tp, RegAddr); +} + +static void ClearAndSetEthPhyBit(struct rtl8125_private *tp, u8 addr, u16 clearmask, u16 setmask) +{ + u16 PhyRegValue; + + PhyRegValue = rtl8125_mdio_read(tp, addr); + PhyRegValue &= ~clearmask; + PhyRegValue |= setmask; + rtl8125_mdio_write(tp, addr, PhyRegValue); +} + +void rtl8125_clear_eth_phy_bit(struct rtl8125_private *tp, u8 addr, u16 mask) +{ + ClearAndSetEthPhyBit(tp, + addr, + mask, + 0 + ); +} + +void rtl8125_set_eth_phy_bit(struct rtl8125_private *tp, u8 addr, u16 mask) +{ + ClearAndSetEthPhyBit(tp, + addr, + 0, + mask + ); +} + +static void ClearAndSetEthPhyOcpBit(struct rtl8125_private *tp, u16 addr, u16 clearmask, u16 setmask) +{ + u16 PhyRegValue; + + PhyRegValue = mdio_direct_read_phy_ocp(tp, addr); + PhyRegValue &= ~clearmask; + PhyRegValue |= setmask; + mdio_direct_write_phy_ocp(tp, addr, PhyRegValue); +} + +void ClearEthPhyOcpBit(struct rtl8125_private *tp, u16 addr, u16 mask) +{ + ClearAndSetEthPhyOcpBit(tp, + addr, + mask, + 0 + ); +} + +void SetEthPhyOcpBit(struct rtl8125_private *tp, u16 addr, u16 mask) +{ + ClearAndSetEthPhyOcpBit(tp, + addr, + 0, + mask + ); +} + +void rtl8125_mac_ocp_write(struct rtl8125_private *tp, u16 reg_addr, u16 value) +{ + u32 data32; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(reg_addr % 2); +#endif + + data32 = reg_addr/2; + data32 <<= OCPR_Addr_Reg_shift; + data32 += value; + data32 |= OCPR_Write; + + RTL_W32(tp, MACOCP, data32); +} + +u32 rtl8125_mac_ocp_read(struct rtl8125_private *tp, u16 reg_addr) +{ + u32 data32; + u16 data16 = 0; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(reg_addr % 2); +#endif + + data32 = reg_addr/2; + data32 <<= OCPR_Addr_Reg_shift; + + RTL_W32(tp, MACOCP, data32); + data16 = (u16)RTL_R32(tp, MACOCP); + + return data16; +} + +#ifdef ENABLE_USE_FIRMWARE_FILE +static void mac_mcu_write(struct rtl8125_private *tp, u16 reg, u16 value) +{ + if (reg == 0x1f) { + tp->ocp_base = value << 4; + return; + } + + rtl8125_mac_ocp_write(tp, tp->ocp_base + reg, value); +} + +static u32 mac_mcu_read(struct rtl8125_private *tp, u16 reg) +{ + return rtl8125_mac_ocp_read(tp, tp->ocp_base + reg); +} +#endif + +static void +ClearAndSetMcuAccessRegBit( + struct rtl8125_private *tp, + u16 addr, + u16 clearmask, + u16 setmask +) +{ + u16 PhyRegValue; + + PhyRegValue = rtl8125_mac_ocp_read(tp, addr); + PhyRegValue &= ~clearmask; + PhyRegValue |= setmask; + rtl8125_mac_ocp_write(tp, addr, PhyRegValue); +} + +static void +ClearMcuAccessRegBit( + struct rtl8125_private *tp, + u16 addr, + u16 mask +) +{ + ClearAndSetMcuAccessRegBit(tp, + addr, + mask, + 0 + ); +} + +static void +SetMcuAccessRegBit( + struct rtl8125_private *tp, + u16 addr, + u16 mask +) +{ + ClearAndSetMcuAccessRegBit(tp, + addr, + 0, + mask + ); +} + +u32 rtl8125_ocp_read_with_oob_base_address(struct rtl8125_private *tp, u16 addr, u8 len, const u32 base_address) +{ + return rtl8125_eri_read_with_oob_base_address(tp, addr, len, ERIAR_OOB, base_address); +} + +u32 rtl8125_ocp_read(struct rtl8125_private *tp, u16 addr, u8 len) +{ + u32 value = 0; + + if (HW_DASH_SUPPORT_TYPE_2(tp)) + value = rtl8125_ocp_read_with_oob_base_address(tp, addr, len, NO_BASE_ADDRESS); + else if (HW_DASH_SUPPORT_TYPE_3(tp)) + value = rtl8125_ocp_read_with_oob_base_address(tp, addr, len, RTL8168FP_OOBMAC_BASE); + + return value; +} + +u32 rtl8125_ocp_write_with_oob_base_address(struct rtl8125_private *tp, u16 addr, u8 len, u32 value, const u32 base_address) +{ + return rtl8125_eri_write_with_oob_base_address(tp, addr, len, value, ERIAR_OOB, base_address); +} + +void rtl8125_ocp_write(struct rtl8125_private *tp, u16 addr, u8 len, u32 value) +{ + if (HW_DASH_SUPPORT_TYPE_2(tp)) + rtl8125_ocp_write_with_oob_base_address(tp, addr, len, value, NO_BASE_ADDRESS); + else if (HW_DASH_SUPPORT_TYPE_3(tp)) + rtl8125_ocp_write_with_oob_base_address(tp, addr, len, value, RTL8168FP_OOBMAC_BASE); +} + +void rtl8125_oob_mutex_lock(struct rtl8125_private *tp) +{ + u8 reg_16, reg_a0; + u32 wait_cnt_0, wait_Cnt_1; + u16 ocp_reg_mutex_ib; + u16 ocp_reg_mutex_oob; + u16 ocp_reg_mutex_prio; + + if (!tp->DASH) return; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + default: + ocp_reg_mutex_oob = 0x110; + ocp_reg_mutex_ib = 0x114; + ocp_reg_mutex_prio = 0x11C; + break; + } + + rtl8125_ocp_write(tp, ocp_reg_mutex_ib, 1, BIT_0); + reg_16 = rtl8125_ocp_read(tp, ocp_reg_mutex_oob, 1); + wait_cnt_0 = 0; + while(reg_16) { + reg_a0 = rtl8125_ocp_read(tp, ocp_reg_mutex_prio, 1); + if (reg_a0) { + rtl8125_ocp_write(tp, ocp_reg_mutex_ib, 1, 0x00); + reg_a0 = rtl8125_ocp_read(tp, ocp_reg_mutex_prio, 1); + wait_Cnt_1 = 0; + while(reg_a0) { + reg_a0 = rtl8125_ocp_read(tp, ocp_reg_mutex_prio, 1); + + wait_Cnt_1++; + + if (wait_Cnt_1 > 2000) + break; + }; + rtl8125_ocp_write(tp, ocp_reg_mutex_ib, 1, BIT_0); + + } + reg_16 = rtl8125_ocp_read(tp, ocp_reg_mutex_oob, 1); + + wait_cnt_0++; + + if (wait_cnt_0 > 2000) + break; + }; +} + +void rtl8125_oob_mutex_unlock(struct rtl8125_private *tp) +{ + u16 ocp_reg_mutex_ib; + u16 ocp_reg_mutex_oob; + u16 ocp_reg_mutex_prio; + + if (!tp->DASH) return; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + default: + ocp_reg_mutex_oob = 0x110; + ocp_reg_mutex_ib = 0x114; + ocp_reg_mutex_prio = 0x11C; + break; + } + + rtl8125_ocp_write(tp, ocp_reg_mutex_prio, 1, BIT_0); + rtl8125_ocp_write(tp, ocp_reg_mutex_ib, 1, 0x00); +} + +void rtl8125_oob_notify(struct rtl8125_private *tp, u8 cmd) +{ + rtl8125_eri_write(tp, 0xE8, 1, cmd, ERIAR_ExGMAC); + + rtl8125_ocp_write(tp, 0x30, 1, 0x01); +} + +static int rtl8125_check_dash(struct rtl8125_private *tp) +{ + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + if (rtl8125_ocp_read(tp, 0x128, 1) & BIT_0) + return 1; + } + + return 0; +} + +void rtl8125_dash2_disable_tx(struct rtl8125_private *tp) +{ + if (!tp->DASH) return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + u16 WaitCnt; + u8 TmpUchar; + + //Disable oob Tx + RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) & ~( BIT_0 )); + WaitCnt = 0; + + //wait oob tx disable + do { + TmpUchar = RTL_CMAC_R8(tp, CMAC_IBISR0); + + if ( TmpUchar & ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE ) { + break; + } + + udelay( 50 ); + WaitCnt++; + } while(WaitCnt < 2000); + + //Clear ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE + RTL_CMAC_W8(tp, CMAC_IBISR0, RTL_CMAC_R8(tp, CMAC_IBISR0) | ISRIMR_DASH_TYPE2_TX_DISABLE_IDLE); + } +} + +void rtl8125_dash2_enable_tx(struct rtl8125_private *tp) +{ + if (!tp->DASH) return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBCR2, RTL_CMAC_R8(tp, CMAC_IBCR2) | BIT_0); + } +} + +void rtl8125_dash2_disable_rx(struct rtl8125_private *tp) +{ + if (!tp->DASH) return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) & ~( BIT_0 )); + } +} + +void rtl8125_dash2_enable_rx(struct rtl8125_private *tp) +{ + if (!tp->DASH) return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBCR0, RTL_CMAC_R8(tp, CMAC_IBCR0) | BIT_0); + } +} + +static void rtl8125_dash2_disable_txrx(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + rtl8125_dash2_disable_tx( tp ); + rtl8125_dash2_disable_rx( tp ); + } +} + +static void rtl8125_driver_start(struct rtl8125_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + int timeout; + u32 tmp_value; + + rtl8125_ocp_write(tp, 0x180, 1, OOB_CMD_DRIVER_START); + tmp_value = rtl8125_ocp_read(tp, 0x30, 1); + tmp_value |= BIT_0; + rtl8125_ocp_write(tp, 0x30, 1, tmp_value); + + for (timeout = 0; timeout < 10; timeout++) { + mdelay(10); + if (rtl8125_ocp_read(tp, 0x124, 1) & BIT_0) + break; + } + } +} + +static void rtl8125_driver_stop(struct rtl8125_private *tp) +{ + if (!tp->DASH) + return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + struct net_device *dev = tp->dev; + int timeout; + u32 tmp_value; + + rtl8125_dash2_disable_txrx(dev); + + rtl8125_ocp_write(tp, 0x180, 1, OOB_CMD_DRIVER_STOP); + tmp_value = rtl8125_ocp_read(tp, 0x30, 1); + tmp_value |= BIT_0; + rtl8125_ocp_write(tp, 0x30, 1, tmp_value); + + for (timeout = 0; timeout < 10; timeout++) { + mdelay(10); + if (!(rtl8125_ocp_read(tp, 0x124, 1) & BIT_0)) + break; + } + } +} + +void rtl8125_ephy_write(struct rtl8125_private *tp, int RegAddr, int value) +{ + int i; + + RTL_W32(tp, EPHYAR, + EPHYAR_Write | + (RegAddr & EPHYAR_Reg_Mask_v2) << EPHYAR_Reg_shift | + (value & EPHYAR_Data_Mask)); + + for (i = 0; i < 10; i++) { + udelay(100); + + /* Check if the RTL8125 has completed EPHY write */ + if (!(RTL_R32(tp, EPHYAR) & EPHYAR_Flag)) + break; + } + + udelay(20); +} + +u16 rtl8125_ephy_read(struct rtl8125_private *tp, int RegAddr) +{ + int i; + u16 value = 0xffff; + + RTL_W32(tp, EPHYAR, + EPHYAR_Read | (RegAddr & EPHYAR_Reg_Mask_v2) << EPHYAR_Reg_shift); + + for (i = 0; i < 10; i++) { + udelay(100); + + /* Check if the RTL8125 has completed EPHY read */ + if (RTL_R32(tp, EPHYAR) & EPHYAR_Flag) { + value = (u16) (RTL_R32(tp, EPHYAR) & EPHYAR_Data_Mask); + break; + } + } + + udelay(20); + + return value; +} + +static void ClearAndSetPCIePhyBit(struct rtl8125_private *tp, u8 addr, u16 clearmask, u16 setmask) +{ + u16 EphyValue; + + EphyValue = rtl8125_ephy_read(tp, addr); + EphyValue &= ~clearmask; + EphyValue |= setmask; + rtl8125_ephy_write(tp, addr, EphyValue); +} + +static void ClearPCIePhyBit(struct rtl8125_private *tp, u8 addr, u16 mask) +{ + ClearAndSetPCIePhyBit( tp, + addr, + mask, + 0 + ); +} + +static void SetPCIePhyBit( struct rtl8125_private *tp, u8 addr, u16 mask) +{ + ClearAndSetPCIePhyBit( tp, + addr, + 0, + mask + ); +} + +static u32 +rtl8125_csi_other_fun_read(struct rtl8125_private *tp, + u8 multi_fun_sel_bit, + u32 addr) +{ + u32 cmd; + int i; + u32 value = 0; + + cmd = CSIAR_Read | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + multi_fun_sel_bit = 0; + + if (multi_fun_sel_bit > 7) + return 0xffffffff; + + cmd |= multi_fun_sel_bit << 16; + + RTL_W32(tp, CSIAR, cmd); + + for (i = 0; i < 10; i++) { + udelay(100); + + /* Check if the RTL8125 has completed CSI read */ + if (RTL_R32(tp, CSIAR) & CSIAR_Flag) { + value = (u32)RTL_R32(tp, CSIDR); + break; + } + } + + udelay(20); + + return value; +} + +static void +rtl8125_csi_other_fun_write(struct rtl8125_private *tp, + u8 multi_fun_sel_bit, + u32 addr, + u32 value) +{ + u32 cmd; + int i; + + RTL_W32(tp, CSIDR, value); + cmd = CSIAR_Write | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask); + if (tp->mcfg == CFG_METHOD_DEFAULT) + multi_fun_sel_bit = 0; + + if ( multi_fun_sel_bit > 7 ) + return; + + cmd |= multi_fun_sel_bit << 16; + + RTL_W32(tp, CSIAR, cmd); + + for (i = 0; i < 10; i++) { + udelay(100); + + /* Check if the RTL8125 has completed CSI write */ + if (!(RTL_R32(tp, CSIAR) & CSIAR_Flag)) + break; + } + + udelay(20); +} + +static u32 +rtl8125_csi_read(struct rtl8125_private *tp, + u32 addr) +{ + u8 multi_fun_sel_bit; + + multi_fun_sel_bit = 0; + + return rtl8125_csi_other_fun_read(tp, multi_fun_sel_bit, addr); +} + +static void +rtl8125_csi_write(struct rtl8125_private *tp, + u32 addr, + u32 value) +{ + u8 multi_fun_sel_bit; + + multi_fun_sel_bit = 0; + + rtl8125_csi_other_fun_write(tp, multi_fun_sel_bit, addr, value); +} + +static u8 +rtl8125_csi_fun0_read_byte(struct rtl8125_private *tp, + u32 addr) +{ + u8 RetVal = 0; + + if (tp->mcfg == CFG_METHOD_DEFAULT) { + struct pci_dev *pdev = tp->pci_dev; + + pci_read_config_byte(pdev, addr, &RetVal); + } else { + u32 TmpUlong; + u16 RegAlignAddr; + u8 ShiftByte; + + RegAlignAddr = addr & ~(0x3); + ShiftByte = addr & (0x3); + TmpUlong = rtl8125_csi_other_fun_read(tp, 0, addr); + TmpUlong >>= (8*ShiftByte); + RetVal = (u8)TmpUlong; + } + + udelay(20); + + return RetVal; +} + +static void +rtl8125_csi_fun0_write_byte(struct rtl8125_private *tp, + u32 addr, + u8 value) +{ + if (tp->mcfg == CFG_METHOD_DEFAULT) { + struct pci_dev *pdev = tp->pci_dev; + + pci_write_config_byte(pdev, addr, value); + } else { + u32 TmpUlong; + u16 RegAlignAddr; + u8 ShiftByte; + + RegAlignAddr = addr & ~(0x3); + ShiftByte = addr & (0x3); + TmpUlong = rtl8125_csi_other_fun_read(tp, 0, RegAlignAddr); + TmpUlong &= ~(0xFF << (8*ShiftByte)); + TmpUlong |= (value << (8*ShiftByte)); + rtl8125_csi_other_fun_write( tp, 0, RegAlignAddr, TmpUlong ); + } + + udelay(20); +} + +u32 rtl8125_eri_read_with_oob_base_address(struct rtl8125_private *tp, int addr, int len, int type, const u32 base_address) +{ + int i, val_shift, shift = 0; + u32 value1 = 0, value2 = 0, mask; + u32 eri_cmd; + const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) | (base_address & 0x000FFF); + + if (len > 4 || len <= 0) + return -1; + + while (len > 0) { + val_shift = addr % ERIAR_Addr_Align; + addr = addr & ~0x3; + + eri_cmd = ERIAR_Read | + transformed_base_address | + type << ERIAR_Type_shift | + ERIAR_ByteEn << ERIAR_ByteEn_shift | + (addr & 0x0FFF); + if (addr & 0xF000) { + u32 tmp; + + tmp = addr & 0xF000; + tmp >>= 12; + eri_cmd |= (tmp << 20) & 0x00F00000; + } + + RTL_W32(tp, ERIAR, eri_cmd); + + for (i = 0; i < 10; i++) { + udelay(100); + + /* Check if the RTL8125 has completed ERI read */ + if (RTL_R32(tp, ERIAR) & ERIAR_Flag) + break; + } + + if (len == 1) mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 2) mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 3) mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + + value1 = RTL_R32(tp, ERIDR) & mask; + value2 |= (value1 >> val_shift * 8) << shift * 8; + + if (len <= 4 - val_shift) { + len = 0; + } else { + len -= (4 - val_shift); + shift = 4 - val_shift; + addr += 4; + } + } + + udelay(20); + + return value2; +} + +u32 rtl8125_eri_read(struct rtl8125_private *tp, int addr, int len, int type) +{ + return rtl8125_eri_read_with_oob_base_address(tp, addr, len, type, 0); +} + +int rtl8125_eri_write_with_oob_base_address(struct rtl8125_private *tp, int addr, int len, u32 value, int type, const u32 base_address) +{ + int i, val_shift, shift = 0; + u32 value1 = 0, mask; + u32 eri_cmd; + const u32 transformed_base_address = ((base_address & 0x00FFF000) << 6) | (base_address & 0x000FFF); + + if (len > 4 || len <= 0) + return -1; + + while (len > 0) { + val_shift = addr % ERIAR_Addr_Align; + addr = addr & ~0x3; + + if (len == 1) mask = (0xFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 2) mask = (0xFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else if (len == 3) mask = (0xFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + else mask = (0xFFFFFFFF << (val_shift * 8)) & 0xFFFFFFFF; + + value1 = rtl8125_eri_read_with_oob_base_address(tp, addr, 4, type, base_address) & ~mask; + value1 |= ((value << val_shift * 8) >> shift * 8); + + RTL_W32(tp, ERIDR, value1); + + eri_cmd = ERIAR_Write | + transformed_base_address | + type << ERIAR_Type_shift | + ERIAR_ByteEn << ERIAR_ByteEn_shift | + (addr & 0x0FFF); + if (addr & 0xF000) { + u32 tmp; + + tmp = addr & 0xF000; + tmp >>= 12; + eri_cmd |= (tmp << 20) & 0x00F00000; + } + + RTL_W32(tp, ERIAR, eri_cmd); + + for (i = 0; i < 10; i++) { + udelay(100); + + /* Check if the RTL8125 has completed ERI write */ + if (!(RTL_R32(tp, ERIAR) & ERIAR_Flag)) + break; + } + + if (len <= 4 - val_shift) { + len = 0; + } else { + len -= (4 - val_shift); + shift = 4 - val_shift; + addr += 4; + } + } + + udelay(20); + + return 0; +} + +int rtl8125_eri_write(struct rtl8125_private *tp, int addr, int len, u32 value, int type) +{ + return rtl8125_eri_write_with_oob_base_address(tp, addr, len, value, type, NO_BASE_ADDRESS); +} + +static void +rtl8125_enable_rxdvgate(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) | BIT_3); + mdelay(2); + break; + } +} + +static void +rtl8125_disable_rxdvgate(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_3); + mdelay(2); + break; + } +} + +static u8 +rtl8125_is_gpio_low(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u8 gpio_low = FALSE; + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + if (!(rtl8125_mac_ocp_read(tp, 0xDC04) & BIT_13)) + gpio_low = TRUE; + break; + } + + if (gpio_low) + dprintk("gpio is low.\n"); + + return gpio_low; +} + +static u8 +rtl8125_is_phy_disable_mode_enabled(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u8 phy_disable_mode_enabled = FALSE; + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + if (RTL_R8(tp, 0xF2) & BIT_5) + phy_disable_mode_enabled = TRUE; + break; + } + + if (phy_disable_mode_enabled) + dprintk("phy disable mode enabled.\n"); + + return phy_disable_mode_enabled; +} + +static u8 +rtl8125_is_in_phy_disable_mode(struct net_device *dev) +{ + u8 in_phy_disable_mode = FALSE; + + if (rtl8125_is_phy_disable_mode_enabled(dev) && rtl8125_is_gpio_low(dev)) + in_phy_disable_mode = TRUE; + + if (in_phy_disable_mode) + dprintk("Hardware is in phy disable mode.\n"); + + return in_phy_disable_mode; +} + +static bool +rtl8125_stop_all_request(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + + RTL_W8(tp, ChipCmd, RTL_R8(tp, ChipCmd) | StopReq); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + for (i = 0; i < 20; i++) { + udelay(10); + if (!(RTL_R8(tp, ChipCmd) & StopReq)) break; + } + + if (i == 20) + return 0; + break; + } + + return 1; +} + +void +rtl8125_wait_txrx_fifo_empty(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + rtl8125_stop_all_request(dev); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + for (i = 0; i < 3000; i++) { + udelay(50); + if ((RTL_R8(tp, MCUCmd_reg) & (Txfifo_empty | Rxfifo_empty)) == (Txfifo_empty | Rxfifo_empty)) + break; + } + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + for (i = 0; i < 3000; i++) { + udelay(50); + if ((RTL_R16(tp, IntrMitigate) & (BIT_0 | BIT_1 | BIT_8)) == (BIT_0 | BIT_1 | BIT_8)) + break; + } + break; + } +} + +#ifdef ENABLE_DASH_SUPPORT + +static inline void +rtl8125_enable_dash2_interrupt(struct rtl8125_private *tp) +{ + if (!tp->DASH) return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBIMR0, ( ISRIMR_DASH_TYPE2_ROK | ISRIMR_DASH_TYPE2_TOK | ISRIMR_DASH_TYPE2_TDU | ISRIMR_DASH_TYPE2_RDU | ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE )); + } +} + +static inline void +rtl8125_disable_dash2_interrupt(struct rtl8125_private *tp) +{ + if (!tp->DASH) return; + + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBIMR0, 0); + } +} +#endif + +void +rtl8125_enable_hw_linkchg_interrupt(struct rtl8125_private *tp) +{ + switch (tp->HwCurrIsrVer) { + case 2: + RTL_W32(tp, IMR_V2_SET_REG_8125, ISRIMR_V2_LINKCHG); + break; + case 1: + RTL_W32(tp, tp->imr_reg[0], LinkChg | RTL_R32(tp, tp->imr_reg[0])); + break; + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8125_enable_dash2_interrupt(tp); +#endif +} + +static inline void +rtl8125_enable_hw_interrupt(struct rtl8125_private *tp) +{ + switch (tp->HwCurrIsrVer) { + case 2: + RTL_W32(tp, IMR_V2_SET_REG_8125, tp->intr_mask); + break; + case 1: + RTL_W32(tp, tp->imr_reg[0], tp->intr_mask); + + if (R8125_MULTI_RX_Q(tp)) { + int i; + for (i=1; inum_rx_rings; i++) + RTL_W16(tp, tp->imr_reg[i], other_q_intr_mask); + } + break; + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8125_enable_dash2_interrupt(tp); +#endif +} + +static inline void rtl8125_clear_hw_isr_v2(struct rtl8125_private *tp, + u32 message_id) +{ + RTL_W32(tp, ISR_V2_8125, BIT(message_id)); +} + +static inline void +rtl8125_disable_hw_interrupt(struct rtl8125_private *tp) +{ + if (tp->HwCurrIsrVer == 2) { + RTL_W32(tp, IMR_V2_CLEAR_REG_8125, 0xFFFFFFFF); + } else { + RTL_W32(tp, tp->imr_reg[0], 0x0000); + + if (R8125_MULTI_RX_Q(tp)) { + int i; + for (i=1; inum_rx_rings; i++) + RTL_W16(tp, tp->imr_reg[i], 0); + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8125_disable_dash2_interrupt(tp); +#endif + } +} + +static inline void +rtl8125_switch_to_hw_interrupt(struct rtl8125_private *tp) +{ + RTL_W32(tp, TIMER_INT0_8125, 0x0000); + + rtl8125_enable_hw_interrupt(tp); +} + +static inline void +rtl8125_switch_to_timer_interrupt(struct rtl8125_private *tp) +{ + if (tp->use_timer_interrrupt) { + RTL_W32(tp, TIMER_INT0_8125, timer_count); + RTL_W32(tp, TCTR0_8125, timer_count); + RTL_W32(tp, tp->imr_reg[0], tp->timer_intr_mask); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + rtl8125_enable_dash2_interrupt(tp); +#endif + } else { + rtl8125_switch_to_hw_interrupt(tp); + } +} + +static void +rtl8125_irq_mask_and_ack(struct rtl8125_private *tp) +{ + rtl8125_disable_hw_interrupt(tp); + + if (tp->HwCurrIsrVer == 2) { + RTL_W32(tp, ISR_V2_8125, 0xFFFFFFFF); + } else { +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + if (tp->dash_printer_enabled) { + RTL_W32(tp, tp->isr_reg[0], RTL_R32(tp, tp->isr_reg[0]) & + ~(ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET)); + } else { + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + RTL_CMAC_W8(tp, CMAC_IBISR0, RTL_CMAC_R8(tp, CMAC_IBISR0)); + } + } + } else { + RTL_W32(tp, tp->isr_reg[0], RTL_R32(tp, tp->isr_reg[0])); + } +#else + RTL_W32(tp, tp->isr_reg[0], RTL_R32(tp, tp->isr_reg[0])); +#endif + if (R8125_MULTI_RX_Q(tp)) { + int i; + for (i=1; inum_rx_rings; i++) + RTL_W16(tp, tp->isr_reg[i], RTL_R16(tp, tp->isr_reg[i])); + } + } +} + +static void +rtl8125_nic_reset(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + + RTL_W32(tp, RxConfig, (RX_DMA_BURST << RxCfgDMAShift)); + + rtl8125_enable_rxdvgate(dev); + + rtl8125_stop_all_request(dev); + + rtl8125_wait_txrx_fifo_empty(dev); + + mdelay(2); + + /* Soft reset the chip. */ + RTL_W8(tp, ChipCmd, CmdReset); + + /* Check that the chip has finished the reset. */ + for (i = 100; i > 0; i--) { + udelay(100); + if ((RTL_R8(tp, ChipCmd) & CmdReset) == 0) + break; + } +} + +static void +rtl8125_hw_set_interrupt_type(struct rtl8125_private *tp, u8 isr_ver) +{ + u8 tmp; + + switch (tp->HwSuppIsrVer) { + case 2: + tmp = RTL_R8(tp, INT_CFG0_8125); + tmp &= ~(INT_CFG0_ENABLE_8125); + if (isr_ver == 2) + tmp |= INT_CFG0_ENABLE_8125; + RTL_W8(tp, INT_CFG0_8125, tmp); + break; + } +} + +static void +rtl8125_hw_clear_timer_int(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W32(tp, TIMER_INT0_8125, 0x0000); + RTL_W32(tp, TIMER_INT1_8125, 0x0000); + RTL_W32(tp, TIMER_INT2_8125, 0x0000); + RTL_W32(tp, TIMER_INT3_8125, 0x0000); + break; + } +} + +static void +rtl8125_hw_clear_int_miti(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + + switch (tp->HwSuppIntMitiVer) { + case 3: + //IntMITI_0-IntMITI_31 + for (i=0xA00; i<0xB00; i+=4) + RTL_W32(tp, i, 0x0000); + break; + case 4: + //IntMITI_0-IntMITI_15 + for (i = 0xA00; i < 0xA80; i += 4) + RTL_W32(tp, i, 0x0000); + + RTL_W8(tp, INT_CFG0_8125, RTL_R8(tp, INT_CFG0_8125) & + ~(INT_CFG0_TIMEOUT0_BYPASS_8125 | INT_CFG0_MITIGATION_BYPASS_8125)); + + RTL_W16(tp, INT_CFG1_8125, 0x0000); + break; + } +} + +void +rtl8125_hw_set_timer_int_8125(struct rtl8125_private *tp, + u32 message_id, + u8 timer_intmiti_val) +{ + switch (tp->HwSuppIntMitiVer) { + case 4: +#ifdef ENABLE_LIB_SUPPORT + if (message_id < R8125_MAX_RX_QUEUES_VEC_V3) + timer_intmiti_val = 0; +#else + if (tp->EnableRss && (message_id < R8125_MAX_RX_QUEUES_VEC_V3)) + timer_intmiti_val = 0; +#endif //ENABLE_LIB_SUPPORT + if (message_id < R8125_MAX_RX_QUEUES_VEC_V3) //ROK + RTL_W8(tp,INT_MITI_V2_0_RX + 8 * message_id, timer_intmiti_val); + else if (message_id == 16) //TOK + RTL_W8(tp,INT_MITI_V2_0_TX, timer_intmiti_val); + else if (message_id == 18) //TOK + RTL_W8(tp,INT_MITI_V2_1_TX, timer_intmiti_val); + break; + } +} + +void +rtl8125_hw_reset(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_lib_reset_prepare(tp); + + /* Disable interrupts */ + rtl8125_irq_mask_and_ack(tp); + + rtl8125_hw_clear_timer_int(dev); + + rtl8125_nic_reset(dev); +} + +static unsigned int +rtl8125_xmii_reset_pending(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + unsigned int retval; + + rtl8125_mdio_write(tp, 0x1f, 0x0000); + retval = rtl8125_mdio_read(tp, MII_BMCR) & BMCR_RESET; + + return retval; +} + +static unsigned int +rtl8125_xmii_link_ok(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + unsigned int retval; + + retval = (RTL_R16(tp, PHYstatus) & LinkStatus) ? 1 : 0; + + return retval; +} + +static int +rtl8125_wait_phy_reset_complete(struct rtl8125_private *tp) +{ + int i, val; + + for (i = 0; i < 2500; i++) { + val = rtl8125_mdio_read(tp, MII_BMCR) & BMCR_RESET; + if (!val) + return 0; + + mdelay(1); + } + + return -1; +} + +static void +rtl8125_xmii_reset_enable(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (rtl8125_is_in_phy_disable_mode(dev)) { + return; + } + + rtl8125_mdio_write(tp, 0x1f, 0x0000); + rtl8125_mdio_write(tp, MII_ADVERTISE, rtl8125_mdio_read(tp, MII_ADVERTISE) & + ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL)); + rtl8125_mdio_write(tp, MII_CTRL1000, rtl8125_mdio_read(tp, MII_CTRL1000) & + ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL)); + mdio_direct_write_phy_ocp(tp, 0xA5D4, mdio_direct_read_phy_ocp(tp, 0xA5D4) & ~(RTK_ADVERTISE_2500FULL)); + rtl8125_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); + + if (rtl8125_wait_phy_reset_complete(tp) == 0) return; + + if (netif_msg_link(tp)) + printk(KERN_ERR "%s: PHY reset failed.\n", dev->name); +} + +void +rtl8125_init_ring_indexes(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8125_tx_ring *ring = &tp->tx_ring[i]; + ring->dirty_tx = ring->cur_tx = 0; + ring->NextHwDesCloPtr = 0; + ring->BeginHwDesCloPtr = 0; + ring->index = i; + ring->priv = tp; + } + + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8125_rx_ring *ring = &tp->rx_ring[i]; + ring->dirty_rx = ring->cur_rx = 0; + ring->index = i; + ring->priv = tp; + } + +#ifdef ENABLE_LIB_SUPPORT + for (i = 0; i < tp->HwSuppNumTxQueues; i++) { + struct rtl8125_ring *ring = &tp->lib_tx_ring[i]; + ring->direction = RTL8125_CH_DIR_TX; + ring->queue_num = i; + ring->private = tp; + } + + for (i = 0; i < tp->HwSuppNumRxQueues; i++) { + struct rtl8125_ring *ring = &tp->lib_rx_ring[i]; + ring->direction = RTL8125_CH_DIR_RX; + ring->queue_num = i; + ring->private = tp; + } +#endif +} + +static void +rtl8125_issue_offset_99_event(struct rtl8125_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xE09A, rtl8125_mac_ocp_read(tp, 0xE09A) | BIT_0); + break; + } +} + +#ifdef ENABLE_DASH_SUPPORT +static void +NICChkTypeEnableDashInterrupt(struct rtl8125_private *tp) +{ + if (tp->DASH) { + // + // even disconnected, enable 3 dash interrupt mask bits for in-band/out-band communication + // + if (HW_DASH_SUPPORT_TYPE_2(tp) || HW_DASH_SUPPORT_TYPE_3(tp)) { + rtl8125_enable_dash2_interrupt(tp); + RTL_W16(tp, IntrMask, (ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET)); + } + } +} +#endif + +static int rtl8125_enable_eee_plus(struct rtl8125_private *tp) +{ + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xE080, rtl8125_mac_ocp_read(tp, 0xE080)|BIT_1); + break; + + default: +// dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support EEEPlus\n"); + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static int rtl8125_disable_eee_plus(struct rtl8125_private *tp) +{ + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xE080, rtl8125_mac_ocp_read(tp, 0xE080)&~BIT_1); + break; + + default: +// dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support EEEPlus\n"); + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static void +rtl8125_link_on_patch(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_hw_config(dev); + + if ((tp->mcfg == CFG_METHOD_2) && + netif_running(dev)) { + if (RTL_R16(tp, PHYstatus)&FullDup) + RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | (BIT_24 | BIT_25)) & ~BIT_19); + else + RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | BIT_25) & ~(BIT_19 | BIT_24)); + } + + if ((tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) && + (RTL_R8(tp, PHYstatus) & _10bps)) + rtl8125_enable_eee_plus(tp); + + rtl8125_hw_start(dev); + + netif_carrier_on(dev); + + netif_tx_wake_all_queues(dev); + + tp->phy_reg_aner = rtl8125_mdio_read(tp, MII_EXPANSION); + tp->phy_reg_anlpar = rtl8125_mdio_read(tp, MII_LPA); + tp->phy_reg_gbsr = rtl8125_mdio_read(tp, MII_STAT1000); + tp->phy_reg_status_2500 = mdio_direct_read_phy_ocp(tp, 0xA5D6); +} + +static void +rtl8125_link_down_patch(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + tp->phy_reg_aner = 0; + tp->phy_reg_anlpar = 0; + tp->phy_reg_gbsr = 0; + tp->phy_reg_status_2500 = 0; + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) + rtl8125_disable_eee_plus(tp); + + netif_tx_stop_all_queues(dev); + + netif_carrier_off(dev); + + rtl8125_hw_reset(dev); + + rtl8125_tx_clear(tp); + + rtl8125_rx_clear(tp); + + rtl8125_init_ring(dev); + + rtl8125_enable_hw_linkchg_interrupt(tp); + + //rtl8125_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + NICChkTypeEnableDashInterrupt(tp); + } +#endif +} + +static void +_rtl8125_check_link_status(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->link_ok(dev)) { + rtl8125_link_on_patch(dev); + + if (netif_msg_ifup(tp)) + printk(KERN_INFO PFX "%s: link up\n", dev->name); + } else { + if (netif_msg_ifdown(tp)) + printk(KERN_INFO PFX "%s: link down\n", dev->name); + + rtl8125_link_down_patch(dev); + } +} + +static void +rtl8125_check_link_status(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + _rtl8125_check_link_status(dev); + + tp->resume_not_chg_speed = 0; +} + +static void +rtl8125_link_option_giga(u8 *aut, + u32 *spd, + u8 *dup, + u32 *adv) +{ + if ((*spd != SPEED_1000) && + (*spd != SPEED_100) && + (*spd != SPEED_10)) + *spd = SPEED_1000; + + if ((*dup != DUPLEX_FULL) && (*dup != DUPLEX_HALF)) + *dup = DUPLEX_FULL; + + if ((*aut != AUTONEG_ENABLE) && (*aut != AUTONEG_DISABLE)) + *aut = AUTONEG_ENABLE; + + *adv &= (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full); + if (*adv == 0) + *adv = (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full); +} + +static void +rtl8125_link_option(u8 *aut, + u32 *spd, + u8 *dup, + u32 *adv) +{ + if ((*spd != SPEED_2500) && (*spd != SPEED_1000) && + (*spd != SPEED_100) && (*spd != SPEED_10)) + *spd = SPEED_2500; + + if ((*dup != DUPLEX_FULL) && (*dup != DUPLEX_HALF)) + *dup = DUPLEX_FULL; + + if ((*aut != AUTONEG_ENABLE) && (*aut != AUTONEG_DISABLE)) + *aut = AUTONEG_ENABLE; + + *adv &= (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_2500baseX_Full); + if (*adv == 0) + *adv = (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full | + ADVERTISED_2500baseX_Full); +} + +/* +static void +rtl8125_enable_ocp_phy_power_saving(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 val; + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + val = mdio_direct_read_phy_ocp(tp, 0xC416); + if (val != 0x0050) { + rtl8125_set_phy_mcu_patch_request(tp); + mdio_direct_write_phy_ocp(tp, 0xC416, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xC416, 0x0050); + rtl8125_clear_phy_mcu_patch_request(tp); + } + } +} +*/ + +static void +rtl8125_disable_ocp_phy_power_saving(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 val; + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + val = mdio_direct_read_phy_ocp(tp, 0xC416); + if (val != 0x0500) { + rtl8125_set_phy_mcu_patch_request(tp); + mdio_direct_write_phy_ocp(tp, 0xC416, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xC416, 0x0500); + rtl8125_clear_phy_mcu_patch_request(tp); + } + } +} + +static void +rtl8125_wait_ll_share_fifo_ready(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + + for (i = 0; i < 10; i++) { + udelay(100); + if (RTL_R16(tp, 0xD2) & BIT_9) + break; + } +} + +static void +rtl8125_disable_pci_offset_99(struct rtl8125_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xE032, rtl8125_mac_ocp_read(tp, 0xE032) & ~(BIT_0 | BIT_1)); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_csi_fun0_write_byte(tp, 0x99, 0x00); + break; + } +} + +static void +rtl8125_enable_pci_offset_99(struct rtl8125_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_csi_fun0_write_byte(tp, 0x99, tp->org_pci_offset_99); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE032); + csi_tmp &= ~(BIT_0 | BIT_1); + if (tp->org_pci_offset_99 & (BIT_5 | BIT_6)) + csi_tmp |= BIT_1; + if (tp->org_pci_offset_99 & BIT_2) + csi_tmp |= BIT_0; + rtl8125_mac_ocp_write(tp, 0xE032, csi_tmp); + break; + } +} + +static void +rtl8125_init_pci_offset_99(struct rtl8125_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xCDD0, 0x9003); + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE034); + csi_tmp |= (BIT_15 | BIT_14); + rtl8125_mac_ocp_write(tp, 0xE034, csi_tmp); + rtl8125_mac_ocp_write(tp, 0xCDD2, 0x889C); + rtl8125_mac_ocp_write(tp, 0xCDD8, 0x9003); + rtl8125_mac_ocp_write(tp, 0xCDD4, 0x8C30); + rtl8125_mac_ocp_write(tp, 0xCDDA, 0x9003); + rtl8125_mac_ocp_write(tp, 0xCDD6, 0x9003); + rtl8125_mac_ocp_write(tp, 0xCDDC, 0x9003); + rtl8125_mac_ocp_write(tp, 0xCDE8, 0x883E); + rtl8125_mac_ocp_write(tp, 0xCDEA, 0x9003); + rtl8125_mac_ocp_write(tp, 0xCDEC, 0x889C); + rtl8125_mac_ocp_write(tp, 0xCDEE, 0x9003); + rtl8125_mac_ocp_write(tp, 0xCDF0, 0x8C09); + rtl8125_mac_ocp_write(tp, 0xCDF2, 0x9003); + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE032); + csi_tmp |= (BIT_14); + rtl8125_mac_ocp_write(tp, 0xE032, csi_tmp); + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE0A2); + csi_tmp |= (BIT_0); + rtl8125_mac_ocp_write(tp, 0xE0A2, csi_tmp); + break; + } + + rtl8125_enable_pci_offset_99(tp); +} + +static void +rtl8125_disable_pci_offset_180(struct rtl8125_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE092); + csi_tmp &= 0xFF00; + rtl8125_mac_ocp_write(tp, 0xE092, csi_tmp); + break; + } +} + +static void +rtl8125_enable_pci_offset_180(struct rtl8125_private *tp) +{ + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE094); + csi_tmp &= 0x00FF; + rtl8125_mac_ocp_write(tp, 0xE094, csi_tmp); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + csi_tmp = rtl8125_mac_ocp_read(tp, 0xE092); + csi_tmp &= 0xFF00; + csi_tmp |= BIT_2; + rtl8125_mac_ocp_write(tp, 0xE092, csi_tmp); + break; + } +} + +static void +rtl8125_init_pci_offset_180(struct rtl8125_private *tp) +{ + if (tp->org_pci_offset_180 & (BIT_0|BIT_1)) + rtl8125_enable_pci_offset_180(tp); + else + rtl8125_disable_pci_offset_180(tp); +} + +static void +rtl8125_set_pci_99_180_exit_driver_para(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + if (tp->org_pci_offset_99 & BIT_2) + rtl8125_issue_offset_99_event(tp); + rtl8125_disable_pci_offset_99(tp); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_disable_pci_offset_180(tp); + break; + } +} + +static void +rtl8125_enable_cfg9346_write(struct rtl8125_private *tp) +{ + RTL_W8(tp, Cfg9346, RTL_R8(tp, Cfg9346) | Cfg9346_Unlock); +} + +static void +rtl8125_disable_cfg9346_write(struct rtl8125_private *tp) +{ + RTL_W8(tp, Cfg9346, RTL_R8(tp, Cfg9346) & ~Cfg9346_Unlock); +} + +static void +rtl8125_enable_exit_l1_mask(struct rtl8125_private *tp) +{ + //(1)ERI(0xD4)(OCP 0xC0AC).bit[7:12]=6'b111111, L1 Mask + SetMcuAccessRegBit(tp, 0xC0AC, (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12)); +} + +static void +rtl8125_disable_exit_l1_mask(struct rtl8125_private *tp) +{ + //(1)ERI(0xD4)(OCP 0xC0AC).bit[7:12]=6'b000000, L1 Mask + ClearMcuAccessRegBit(tp, 0xC0AC, (BIT_7 | BIT_8 | BIT_9 | BIT_10 | BIT_11 | BIT_12)); +} + +static void +rtl8125_enable_extend_tally_couter(struct rtl8125_private *tp) +{ + switch (tp->HwSuppExtendTallyCounterVer) { + case 1: + SetMcuAccessRegBit(tp, 0xEA84, (BIT_1 | BIT_0)); + break; + } +} + +static void +rtl8125_disable_extend_tally_couter(struct rtl8125_private *tp) +{ + switch (tp->HwSuppExtendTallyCounterVer) { + case 1: + ClearMcuAccessRegBit(tp, 0xEA84, (BIT_1 | BIT_0)); + break; + } +} + +static void +rtl8125_hw_d3_para(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + RTL_W16(tp, RxMaxSize, RX_BUF_SIZE); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, 0xF1, RTL_R8(tp, 0xF1) & ~BIT_7); + rtl8125_enable_cfg9346_write(tp); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~BIT_7); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + rtl8125_disable_cfg9346_write(tp); + break; + } + + rtl8125_disable_exit_l1_mask(tp); + +#ifdef ENABLE_REALWOW_SUPPORT + rtl8125_set_realwow_d3_para(dev); +#endif + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xEA18, 0x0064); + break; + } + + rtl8125_set_pci_99_180_exit_driver_para(dev); + + /*disable ocp phy power saving*/ + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) + rtl8125_disable_ocp_phy_power_saving(dev); + + rtl8125_disable_rxdvgate(dev); + + rtl8125_disable_extend_tally_couter(tp); +} + +static void +rtl8125_enable_magic_packet(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + rtl8125_mac_ocp_write(tp, 0xC0B6, rtl8125_mac_ocp_read(tp, 0xC0B6) | BIT_0); + break; + } +} +static void +rtl8125_disable_magic_packet(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + rtl8125_mac_ocp_write(tp, 0xC0B6, rtl8125_mac_ocp_read(tp, 0xC0B6) & ~BIT_0); + break; + } +} + +static void +rtl8125_enable_linkchg_wakeup(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->HwSuppLinkChgWakeUpVer) { + case 3: + RTL_W8(tp, Config3, RTL_R8(tp, Config3) | LinkUp); + ClearAndSetMcuAccessRegBit(tp, 0xE0C6, (BIT_5 | BIT_3 | BIT_2), (BIT_4 | BIT_1 | BIT_0)); + break; + } +} + +static void +rtl8125_disable_linkchg_wakeup(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->HwSuppLinkChgWakeUpVer) { + case 3: + RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~LinkUp); + ClearMcuAccessRegBit(tp, 0xE0C6, (BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0)); + break; + } +} + +#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) + +static u32 +rtl8125_get_hw_wol(struct rtl8125_private *tp) +{ + u8 options; + u32 csi_tmp; + u32 wol_opts = 0; + + if (disable_pm_support) + goto out; + + options = RTL_R8(tp, Config1); + if (!(options & PMEnable)) + goto out; + + options = RTL_R8(tp, Config3); + if (options & LinkUp) + wol_opts |= WAKE_PHY; + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + csi_tmp = rtl8125_mac_ocp_read(tp, 0xC0B6); + if (csi_tmp & BIT_0) + wol_opts |= WAKE_MAGIC; + break; + } + + options = RTL_R8(tp, Config5); + if (options & UWF) + wol_opts |= WAKE_UCAST; + if (options & BWF) + wol_opts |= WAKE_BCAST; + if (options & MWF) + wol_opts |= WAKE_MCAST; + +out: + return wol_opts; +} + +static void +rtl8125_enable_d0_speedup(struct rtl8125_private *tp) +{ + if (FALSE == HW_SUPPORT_D0_SPEED_UP(tp)) return; + if (tp->D0SpeedUpSpeed == D0_SPEED_UP_SPEED_DISABLE) return; + + if (tp->HwSuppD0SpeedUpVer == 1) { + u16 mac_ocp_data; + + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) | BIT_3); + + //speed up speed + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE10A); + mac_ocp_data &= ~(BIT_10 | BIT_9 | BIT_8 | BIT_7); + if (tp->D0SpeedUpSpeed == D0_SPEED_UP_SPEED_2500) { + mac_ocp_data |= BIT_7; + } + rtl8125_mac_ocp_write(tp, 0xE10A, mac_ocp_data); + + //speed up flowcontrol + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE860); + mac_ocp_data |= (BIT_15 | BIT_14); + rtl8125_mac_ocp_write(tp, 0xE860, mac_ocp_data); + } +} + +static void +rtl8125_disable_d0_speedup(struct rtl8125_private *tp) +{ + if (FALSE == HW_SUPPORT_D0_SPEED_UP(tp)) return; + + if (tp->HwSuppD0SpeedUpVer == 1) + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) & ~BIT_7); +} + +static void +rtl8125_set_hw_wol(struct net_device *dev, u32 wolopts) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i,tmp; + static struct { + u32 opt; + u16 reg; + u8 mask; + } cfg[] = { + { WAKE_PHY, Config3, LinkUp }, + { WAKE_UCAST, Config5, UWF }, + { WAKE_BCAST, Config5, BWF }, + { WAKE_MCAST, Config5, MWF }, + { WAKE_ANY, Config5, LanWake }, + { WAKE_MAGIC, Config3, MagicPacket }, + }; + + switch (tp->HwSuppMagicPktVer) { + case WAKEUP_MAGIC_PACKET_V3: + default: + tmp = ARRAY_SIZE(cfg) - 1; + + if (wolopts & WAKE_MAGIC) + rtl8125_enable_magic_packet(dev); + else + rtl8125_disable_magic_packet(dev); + break; + } + + rtl8125_enable_cfg9346_write(tp); + + for (i = 0; i < tmp; i++) { + u8 options = RTL_R8(tp, cfg[i].reg) & ~cfg[i].mask; + if (wolopts & cfg[i].opt) + options |= cfg[i].mask; + RTL_W8(tp, cfg[i].reg, options); + } + + switch (tp->HwSuppLinkChgWakeUpVer) { + case 3: + if (wolopts & WAKE_PHY) + rtl8125_enable_linkchg_wakeup(dev); + else + rtl8125_disable_linkchg_wakeup(dev); + break; + } + + rtl8125_disable_cfg9346_write(tp); +} + +static void +rtl8125_phy_restart_nway(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (rtl8125_is_in_phy_disable_mode(dev)) return; + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + rtl8125_mdio_write(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); +} + +static void +rtl8125_phy_setup_force_mode(struct net_device *dev, u32 speed, u8 duplex) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 bmcr_true_force = 0; + + if (rtl8125_is_in_phy_disable_mode(dev)) return; + + if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) { + bmcr_true_force = BMCR_SPEED10; + } else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) { + bmcr_true_force = BMCR_SPEED10 | BMCR_FULLDPLX; + } else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) { + bmcr_true_force = BMCR_SPEED100; + } else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) { + bmcr_true_force = BMCR_SPEED100 | BMCR_FULLDPLX; + } else { + netif_err(tp, drv, dev, "Failed to set phy force mode!\n"); + return; + } + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + rtl8125_mdio_write(tp, MII_BMCR, bmcr_true_force); +} + +static void +rtl8125_set_pci_pme(struct rtl8125_private *tp, int set) +{ + struct pci_dev *pdev = tp->pci_dev; + u16 pmc; + + if (!pdev->pm_cap) + return; + + pci_read_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, &pmc); + pmc |= PCI_PM_CTRL_PME_STATUS; + if (set) + pmc |= PCI_PM_CTRL_PME_ENABLE; + else + pmc &= ~PCI_PM_CTRL_PME_ENABLE; + pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, pmc); +} + +static void +rtl8125_set_wol_link_speed(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int auto_nego; + int giga_ctrl; + int ctrl_2500; + u32 adv; + u16 anlpar; + u16 gbsr; + u16 status_2500; + u16 aner; + + if (tp->autoneg != AUTONEG_ENABLE) + goto exit; + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + + auto_nego = rtl8125_mdio_read(tp, MII_ADVERTISE); + auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL + | ADVERTISE_100HALF | ADVERTISE_100FULL); + + giga_ctrl = rtl8125_mdio_read(tp, MII_CTRL1000); + giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); + + ctrl_2500 = mdio_direct_read_phy_ocp(tp, 0xA5D4); + ctrl_2500 &= ~(RTK_ADVERTISE_2500FULL); + + aner = anlpar = gbsr = status_2500 = 0; + if (tp->link_ok(dev)) { + aner = rtl8125_mdio_read(tp, MII_EXPANSION); + anlpar = rtl8125_mdio_read(tp, MII_LPA); + gbsr = rtl8125_mdio_read(tp, MII_STAT1000); + status_2500 = mdio_direct_read_phy_ocp(tp, 0xA5D6); + } else { + if (netif_running(dev)) { + aner = tp->phy_reg_aner; + anlpar = tp->phy_reg_anlpar; + gbsr = tp->phy_reg_gbsr; + status_2500 = tp->phy_reg_status_2500; + } + } + + if ((aner | anlpar | gbsr | status_2500) == 0) { + int auto_nego_tmp = 0; + adv = tp->advertising; + if ((adv & ADVERTISED_10baseT_Half) && (anlpar & LPA_10HALF)) + auto_nego_tmp |= ADVERTISE_10HALF; + if ((adv & ADVERTISED_10baseT_Full) && (anlpar & LPA_10FULL)) + auto_nego_tmp |= ADVERTISE_10FULL; + if ((adv & ADVERTISED_100baseT_Half) && (anlpar & LPA_100HALF)) + auto_nego_tmp |= ADVERTISE_100HALF; + if ((adv & ADVERTISED_100baseT_Full) && (anlpar & LPA_100FULL)) + auto_nego_tmp |= ADVERTISE_100FULL; + + if (auto_nego_tmp == 0) goto exit; + + auto_nego |= auto_nego_tmp; + goto skip_check_lpa; + } + if (!(aner & EXPANSION_NWAY)) goto exit; + + adv = tp->advertising; + if ((adv & ADVERTISED_10baseT_Half) && (anlpar & LPA_10HALF)) + auto_nego |= ADVERTISE_10HALF; + else if ((adv & ADVERTISED_10baseT_Full) && (anlpar & LPA_10FULL)) + auto_nego |= ADVERTISE_10FULL; + else if ((adv & ADVERTISED_100baseT_Half) && (anlpar & LPA_100HALF)) + auto_nego |= ADVERTISE_100HALF; + else if ((adv & ADVERTISED_100baseT_Full) && (anlpar & LPA_100FULL)) + auto_nego |= ADVERTISE_100FULL; + else if (adv & ADVERTISED_1000baseT_Half && (gbsr & LPA_1000HALF)) + giga_ctrl |= ADVERTISE_1000HALF; + else if (adv & ADVERTISED_1000baseT_Full && (gbsr & LPA_1000FULL)) + giga_ctrl |= ADVERTISE_1000FULL; + else if (adv & ADVERTISED_2500baseX_Full && (status_2500 & RTK_LPA_ADVERTISE_2500FULL)) + ctrl_2500 |= RTK_ADVERTISE_2500FULL; + else + goto exit; + +skip_check_lpa: + if (tp->DASH) + auto_nego |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10HALF | ADVERTISE_10FULL); + +#ifdef CONFIG_DOWN_SPEED_100 + auto_nego |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10HALF | ADVERTISE_10FULL); +#endif + + rtl8125_mdio_write(tp, MII_ADVERTISE, auto_nego); + rtl8125_mdio_write(tp, MII_CTRL1000, giga_ctrl); + mdio_direct_write_phy_ocp(tp, 0xA5D4, ctrl_2500); + + rtl8125_phy_restart_nway(dev); + +exit: + return; +} + +static bool +rtl8125_keep_wol_link_speed(struct net_device *dev, u8 from_suspend) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if ((from_suspend && !tp->link_ok(dev)) || + (!from_suspend && tp->resume_not_chg_speed)) + return 1; + + return 0; +} +static void +rtl8125_powerdown_pll(struct net_device *dev, u8 from_suspend) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + tp->check_keep_link_speed = 0; + if (tp->wol_enabled == WOL_ENABLED || tp->DASH || tp->EnableKCPOffload) { + rtl8125_set_hw_wol(dev, tp->wol_opts); + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + rtl8125_enable_cfg9346_write(tp); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) | PMSTS_En); + rtl8125_disable_cfg9346_write(tp); + } + + /* Enable the PME and clear the status */ + rtl8125_set_pci_pme(tp, 1); + + if (rtl8125_keep_wol_link_speed(dev, from_suspend)) { + if (tp->wol_opts & WAKE_PHY) + tp->check_keep_link_speed = 1; + } else { + if (HW_SUPPORT_D0_SPEED_UP(tp)) { + rtl8125_enable_d0_speedup(tp); + tp->check_keep_link_speed = 1; + } + + rtl8125_set_wol_link_speed(dev); + } + + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); + + return; + } + + if (tp->DASH) + return; + + rtl8125_phy_power_down(dev); + + if (!tp->HwIcVerUnknown) { + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) & ~BIT_7); + break; + } + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_6); + break; + } +} + +static void rtl8125_powerup_pll(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, PMCH, RTL_R8(tp, PMCH) | BIT_7 | BIT_6); + break; + } + + if (tp->resume_not_chg_speed) return; + + rtl8125_phy_power_up(dev); +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static void +rtl8125_get_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u8 options; + + wol->wolopts = 0; + + if (tp->mcfg == CFG_METHOD_DEFAULT || disable_pm_support) { + wol->supported = 0; + return; + } else { + wol->supported = WAKE_ANY; + } + + options = RTL_R8(tp, Config1); + if (!(options & PMEnable)) + return; + + wol->wolopts = tp->wol_opts; +} + +static int +rtl8125_set_wol(struct net_device *dev, + struct ethtool_wolinfo *wol) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT || disable_pm_support) + return -EOPNOTSUPP; + + tp->wol_opts = wol->wolopts; + + tp->wol_enabled = (tp->wol_opts) ? WOL_ENABLED : WOL_DISABLED; + + device_set_wakeup_enable(tp_to_dev(tp), wol->wolopts); + + return 0; +} + +static void +rtl8125_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct rtl8125_fw *rtl_fw = tp->rtl_fw; + + strcpy(info->driver, MODULENAME); + strcpy(info->version, RTL8125_VERSION); + strcpy(info->bus_info, pci_name(tp->pci_dev)); + info->regdump_len = R8125_REGS_DUMP_SIZE; + info->eedump_len = tp->eeprom_len; + BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version)); + if (rtl_fw) + strlcpy(info->fw_version, rtl_fw->version, + sizeof(info->fw_version)); +} + +static int +rtl8125_get_regs_len(struct net_device *dev) +{ + return R8125_REGS_DUMP_SIZE; +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static void +rtl8125_set_d0_speedup_speed(struct rtl8125_private *tp) +{ + if (FALSE == HW_SUPPORT_D0_SPEED_UP(tp)) return; + + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_DISABLE; + if (tp->autoneg == AUTONEG_ENABLE) { + if (tp->speed == SPEED_2500) + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_2500; + else if(tp->speed == SPEED_1000) + tp->D0SpeedUpSpeed = D0_SPEED_UP_SPEED_1000; + } +} + +static int +rtl8125_set_speed_xmii(struct net_device *dev, + u8 autoneg, + u32 speed, + u8 duplex, + u32 adv) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int auto_nego = 0; + int giga_ctrl = 0; + int ctrl_2500 = 0; + int rc = -EINVAL; + + //Disable Giga Lite + ClearEthPhyOcpBit(tp, 0xA428, BIT_9); + ClearEthPhyOcpBit(tp, 0xA5EA, BIT_0); + + if (speed != SPEED_2500 && + (speed != SPEED_1000) && + (speed != SPEED_100) && + (speed != SPEED_10)) { + speed = SPEED_2500; + duplex = DUPLEX_FULL; + } + + giga_ctrl = rtl8125_mdio_read(tp, MII_CTRL1000); + giga_ctrl &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL); + ctrl_2500 = mdio_direct_read_phy_ocp(tp, 0xA5D4); + ctrl_2500 &= ~(RTK_ADVERTISE_2500FULL); + + if (autoneg == AUTONEG_ENABLE) { + /*n-way force*/ + auto_nego = rtl8125_mdio_read(tp, MII_ADVERTISE); + auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL | + ADVERTISE_100HALF | ADVERTISE_100FULL | + ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); + + if (adv & ADVERTISED_10baseT_Half) + auto_nego |= ADVERTISE_10HALF; + if (adv & ADVERTISED_10baseT_Full) + auto_nego |= ADVERTISE_10FULL; + if (adv & ADVERTISED_100baseT_Half) + auto_nego |= ADVERTISE_100HALF; + if (adv & ADVERTISED_100baseT_Full) + auto_nego |= ADVERTISE_100FULL; + if (adv & ADVERTISED_1000baseT_Half) + giga_ctrl |= ADVERTISE_1000HALF; + if (adv & ADVERTISED_1000baseT_Full) + giga_ctrl |= ADVERTISE_1000FULL; + if (adv & ADVERTISED_2500baseX_Full) + ctrl_2500 |= RTK_ADVERTISE_2500FULL; + + //flow control + if (dev->mtu <= ETH_DATA_LEN && tp->fcpause == rtl8125_fc_full) + auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + + tp->phy_auto_nego_reg = auto_nego; + tp->phy_1000_ctrl_reg = giga_ctrl; + + tp->phy_2500_ctrl_reg = ctrl_2500; + + rtl8125_mdio_write(tp, 0x1f, 0x0000); + rtl8125_mdio_write(tp, MII_ADVERTISE, auto_nego); + rtl8125_mdio_write(tp, MII_CTRL1000, giga_ctrl); + mdio_direct_write_phy_ocp(tp, 0xA5D4, ctrl_2500); + rtl8125_phy_restart_nway(dev); + mdelay(20); + } else { + /*true force*/ + if (speed == SPEED_10 || speed == SPEED_100) + rtl8125_phy_setup_force_mode(dev, speed, duplex); + else + goto out; + } + + tp->autoneg = autoneg; + tp->speed = speed; + tp->duplex = duplex; + tp->advertising = adv; + + rtl8125_set_d0_speedup_speed(tp); + + rc = 0; +out: + return rc; +} + +static int +rtl8125_set_speed(struct net_device *dev, + u8 autoneg, + u32 speed, + u8 duplex, + u32 adv) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ret; + + if (tp->resume_not_chg_speed) return 0; + + ret = tp->set_speed(dev, autoneg, speed, duplex, adv); + + return ret; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static int +rtl8125_set_settings(struct net_device *dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + struct ethtool_cmd *cmd +#else + const struct ethtool_link_ksettings *cmd +#endif + ) +{ + int ret; + u8 autoneg; + u32 speed; + u8 duplex; + u32 supported, advertising; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + autoneg = cmd->autoneg; + speed = cmd->speed; + duplex = cmd->duplex; + supported = cmd->supported; + advertising = cmd->advertising; +#else + const struct ethtool_link_settings *base = &cmd->base; + autoneg = base->autoneg; + speed = base->speed; + duplex = base->duplex; + ethtool_convert_link_mode_to_legacy_u32(&supported, + cmd->link_modes.supported); + ethtool_convert_link_mode_to_legacy_u32(&advertising, + cmd->link_modes.advertising); + if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.supported)) + supported |= ADVERTISED_2500baseX_Full; + if (test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.advertising)) + advertising |= ADVERTISED_2500baseX_Full; +#endif + if (advertising & ~supported) + return -EINVAL; + + ret = rtl8125_set_speed(dev, autoneg, speed, duplex, advertising); + + return ret; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +static u32 +rtl8125_get_tx_csum(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u32 ret; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + ret = ((dev->features & NETIF_F_IP_CSUM) != 0); +#else + ret = ((dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) != 0); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + + return ret; +} + +static u32 +rtl8125_get_rx_csum(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u32 ret; + + ret = tp->cp_cmd & RxChkSum; + + return ret; +} + +static int +rtl8125_set_tx_csum(struct net_device *dev, + u32 data) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + return -EOPNOTSUPP; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + if (data) + dev->features |= NETIF_F_IP_CSUM; + else + dev->features &= ~NETIF_F_IP_CSUM; +#else + if (data) + dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + else + dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + + return 0; +} + +static int +rtl8125_set_rx_csum(struct net_device *dev, + u32 data) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + return -EOPNOTSUPP; + + if (data) + tp->cp_cmd |= RxChkSum; + else + tp->cp_cmd &= ~RxChkSum; + + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + + return 0; +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static u32 +rtl8125_rx_desc_opts1(struct rtl8125_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts1; + else + return desc->opts1; +} + +static u32 +rtl8125_rx_desc_opts2(struct rtl8125_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts2; + else + return desc->opts2; +} + +#ifdef CONFIG_R8125_VLAN + +static void +rtl8125_clear_rx_desc_opts2(struct rtl8125_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + ((struct RxDescV3 *)desc)->RxDescNormalDDWord4.opts2 = 0; + else + desc->opts2 = 0; +} + +static inline u32 +rtl8125_tx_vlan_tag(struct rtl8125_private *tp, + struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + return (tp->vlgrp && vlan_tx_tag_present(skb)) ? + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4,0,0) + return (vlan_tx_tag_present(skb)) ? + TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; +#else + return (skb_vlan_tag_present(skb)) ? + TxVlanTag | swab16(skb_vlan_tag_get(skb)) : 0x00; +#endif + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + +static void +rtl8125_vlan_rx_register(struct net_device *dev, + struct vlan_group *grp) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + tp->vlgrp = grp; + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + if (tp->vlgrp) { + tp->rtl8125_rx_config |= (EnableInnerVlan | EnableOuterVlan); + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) | (EnableInnerVlan | EnableOuterVlan)) + } else { + tp->rtl8125_rx_config &= ~(EnableInnerVlan | EnableOuterVlan); + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~(EnableInnerVlan | EnableOuterVlan)) + } + } +} + +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +static void +rtl8125_vlan_rx_kill_vid(struct net_device *dev, + unsigned short vid) +{ + struct rtl8125_private *tp = netdev_priv(dev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) + if (tp->vlgrp) + tp->vlgrp->vlan_devices[vid] = NULL; +#else + vlan_group_set_device(tp->vlgrp, vid, NULL); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) +} +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + +static int +rtl8125_rx_vlan_skb(struct rtl8125_private *tp, + struct RxDesc *desc, + struct sk_buff *skb) +{ + u32 opts2 = le32_to_cpu(rtl8125_rx_desc_opts2(tp, desc)); + int ret = -1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + if (tp->vlgrp && (opts2 & RxVlanTag)) { + rtl8125_rx_hwaccel_skb(skb, tp->vlgrp, + swab16(opts2 & 0xffff)); + ret = 0; + } +#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) + if (opts2 & RxVlanTag) + __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); +#else + if (opts2 & RxVlanTag) + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), swab16(opts2 & 0xffff)); +#endif + + rtl8125_clear_rx_desc_opts2(tp, desc); + return ret; +} + +#else /* !CONFIG_R8125_VLAN */ + +static inline u32 +rtl8125_tx_vlan_tag(struct rtl8125_private *tp, + struct sk_buff *skb) +{ + return 0; +} + +static int +rtl8125_rx_vlan_skb(struct rtl8125_private *tp, + struct RxDesc *desc, + struct sk_buff *skb) +{ + return -1; +} + +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + +static netdev_features_t rtl8125_fix_features(struct net_device *dev, + netdev_features_t features) +{ + if (dev->mtu > MSS_MAX) + features &= ~NETIF_F_ALL_TSO; + if (dev->mtu > ETH_DATA_LEN) { + features &= ~NETIF_F_ALL_TSO; + features &= ~NETIF_F_ALL_CSUM; + } +#ifndef CONFIG_R8125_VLAN + features &= ~NETIF_F_ALL_CSUM; +#endif + + return features; +} + +static int rtl8125_hw_set_features(struct net_device *dev, + netdev_features_t features) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u32 rx_config; + + rx_config = RTL_R32(tp, RxConfig); + if (features & NETIF_F_RXALL) { + tp->rtl8125_rx_config |= (AcceptErr | AcceptRunt); + rx_config |= (AcceptErr | AcceptRunt); + } else { + tp->rtl8125_rx_config &= ~(AcceptErr | AcceptRunt); + rx_config &= ~(AcceptErr | AcceptRunt); + } + + if (features & NETIF_F_HW_VLAN_RX) { + tp->rtl8125_rx_config |= (EnableInnerVlan | EnableOuterVlan); + rx_config |= (EnableInnerVlan | EnableOuterVlan); + } else { + tp->rtl8125_rx_config &= ~(EnableInnerVlan | EnableOuterVlan); + rx_config &= ~(EnableInnerVlan | EnableOuterVlan); + } + + RTL_W32(tp, RxConfig, rx_config); + + if (features & NETIF_F_RXCSUM) + tp->cp_cmd |= RxChkSum; + else + tp->cp_cmd &= ~RxChkSum; + + RTL_W16(tp, CPlusCmd, tp->cp_cmd); + RTL_R16(tp, CPlusCmd); + + return 0; +} + +static int rtl8125_set_features(struct net_device *dev, + netdev_features_t features) +{ + features &= NETIF_F_RXALL | NETIF_F_RXCSUM | NETIF_F_HW_VLAN_RX; + + rtl8125_hw_set_features(dev, features); + + return 0; +} + +#endif + +static void rtl8125_gset_xmii(struct net_device *dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + struct ethtool_cmd *cmd +#else + struct ethtool_link_ksettings *cmd +#endif + ) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 aner = tp->phy_reg_aner; + u16 anlpar = tp->phy_reg_anlpar; + u16 gbsr = tp->phy_reg_gbsr; + u16 status_2500 = tp->phy_reg_status_2500; + u32 lpa_adv = 0; + u16 status; + u8 autoneg, duplex; + u32 speed = 0; + u16 bmcr; + u32 supported, advertising; + u8 report_lpa = 0; + + supported = SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_Autoneg | + SUPPORTED_TP | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause; + + if (tp->mcfg == CFG_METHOD_6 || tp->mcfg == CFG_METHOD_7) + supported &= ~SUPPORTED_2500baseX_Full; + + advertising = ADVERTISED_TP; + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + bmcr = rtl8125_mdio_read(tp, MII_BMCR); + + if (bmcr & BMCR_ANENABLE) { + advertising |= ADVERTISED_Autoneg; + autoneg = AUTONEG_ENABLE; + + if (tp->phy_auto_nego_reg & ADVERTISE_10HALF) + advertising |= ADVERTISED_10baseT_Half; + if (tp->phy_auto_nego_reg & ADVERTISE_10FULL) + advertising |= ADVERTISED_10baseT_Full; + if (tp->phy_auto_nego_reg & ADVERTISE_100HALF) + advertising |= ADVERTISED_100baseT_Half; + if (tp->phy_auto_nego_reg & ADVERTISE_100FULL) + advertising |= ADVERTISED_100baseT_Full; + if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL) + advertising |= ADVERTISED_1000baseT_Full; + if (tp->phy_2500_ctrl_reg & RTK_ADVERTISE_2500FULL) + advertising |= ADVERTISED_2500baseX_Full; + } else { + autoneg = AUTONEG_DISABLE; + } + + status = RTL_R16(tp, PHYstatus); + if (netif_running(dev) && (status & LinkStatus)) + report_lpa = 1; + + if (report_lpa) { + /*link on*/ + if (status & _2500bpsF) + speed = SPEED_2500; + else if (status & _1000bpsF) + speed = SPEED_1000; + else if (status & _100bps) + speed = SPEED_100; + else if (status & _10bps) + speed = SPEED_10; + + if (status & TxFlowCtrl) + advertising |= ADVERTISED_Asym_Pause; + + if (status & RxFlowCtrl) + advertising |= ADVERTISED_Pause; + + duplex = ((status & (_1000bpsF | _2500bpsF)) || (status & FullDup)) ? + DUPLEX_FULL : DUPLEX_HALF; + + /*link partner*/ + if (aner & EXPANSION_NWAY) + lpa_adv |= ADVERTISED_Autoneg; + if (anlpar & LPA_10HALF) + lpa_adv |= ADVERTISED_10baseT_Half; + if (anlpar & LPA_10FULL) + lpa_adv |= ADVERTISED_10baseT_Full; + if (anlpar & LPA_100HALF) + lpa_adv |= ADVERTISED_100baseT_Half; + if (anlpar & LPA_100FULL) + lpa_adv |= ADVERTISED_100baseT_Full; + if (anlpar & LPA_PAUSE_CAP) + lpa_adv |= ADVERTISED_Pause; + if (anlpar & LPA_PAUSE_ASYM) + lpa_adv |= ADVERTISED_Asym_Pause; + if (gbsr & LPA_1000HALF) + lpa_adv |= ADVERTISED_1000baseT_Half; + if (gbsr & LPA_1000FULL) + lpa_adv |= ADVERTISED_1000baseT_Full; + if (status_2500 & RTK_LPA_ADVERTISE_2500FULL) + lpa_adv |= ADVERTISED_2500baseX_Full; + } else { + /*link down*/ + speed = SPEED_UNKNOWN; + duplex = DUPLEX_UNKNOWN; + lpa_adv = 0; + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + cmd->supported = supported; + cmd->advertising = advertising; + cmd->autoneg = autoneg; + cmd->speed = speed; + cmd->duplex = duplex; + cmd->port = PORT_TP; + cmd->lp_advertising = lpa_adv; +#else + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, + supported); + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, + advertising); + ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, + lpa_adv); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,0,0) + if (supported & SUPPORTED_2500baseX_Full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + cmd->link_modes.supported, 0); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.supported, 1); + } + if (advertising & ADVERTISED_2500baseX_Full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + cmd->link_modes.advertising, 0); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.advertising, 1); + } + if (report_lpa) { + if (lpa_adv & ADVERTISED_2500baseX_Full) { + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, + cmd->link_modes.lp_advertising, 0); + linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, + cmd->link_modes.lp_advertising, 1); + } + if (status_2500 & RTK_LPA_ADVERTISE_5000FULL) + linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, + cmd->link_modes.lp_advertising, 1); + if (status_2500 & RTK_LPA_ADVERTISE_10000FULL) + linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + cmd->link_modes.lp_advertising, 1); + } +#endif + cmd->base.autoneg = autoneg; + cmd->base.speed = speed; + cmd->base.duplex = duplex; + cmd->base.port = PORT_TP; +#endif +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static int +rtl8125_get_settings(struct net_device *dev, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + struct ethtool_cmd *cmd +#else + struct ethtool_link_ksettings *cmd +#endif + ) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + tp->get_settings(dev, cmd); + + return 0; +} + +static void rtl8125_get_regs(struct net_device *dev, struct ethtool_regs *regs, + void *p) +{ + struct rtl8125_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + unsigned int i; + u8 *data = p; + + if (regs->len < R8125_REGS_DUMP_SIZE) + return /* -EINVAL */; + + memset(p, 0, regs->len); + + for (i = 0; i < R8125_MAC_REGS_SIZE; i++) + *data++ = readb(ioaddr + i); + data = (u8*)p + 256; + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + for (i = 0; i < R8125_PHY_REGS_SIZE/2; i++) { + *(u16*)data = rtl8125_mdio_read(tp, i); + data += 2; + } + data = (u8*)p + 256 * 2; + + for (i = 0; i < R8125_EPHY_REGS_SIZE/2; i++) { + *(u16*)data = rtl8125_ephy_read(tp, i); + data += 2; + } + data = (u8*)p + 256 * 3; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + default: + for (i = 0; i < R8125_ERI_REGS_SIZE; i+=4) { + *(u32*)data = rtl8125_eri_read(tp, i , 4, ERIAR_ExGMAC); + data += 4; + } + break; + } +} + +static void rtl8125_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + pause->autoneg = (tp->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); + if (tp->fcpause == rtl8125_fc_rx_pause) + pause->rx_pause = 1; + else if (tp->fcpause == rtl8125_fc_tx_pause) + pause->tx_pause = 1; + else if (tp->fcpause == rtl8125_fc_full) { + pause->rx_pause = 1; + pause->tx_pause = 1; + } +} + +static int rtl8125_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *pause) +{ + struct rtl8125_private *tp = netdev_priv(dev); + enum rtl8125_fc_mode newfc; + + if (pause->tx_pause || pause->rx_pause) + newfc = rtl8125_fc_full; + else + newfc = rtl8125_fc_none; + + if (tp->fcpause != newfc) { + tp->fcpause = newfc; + + rtl8125_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + } + + return 0; + +} + +static u32 +rtl8125_get_msglevel(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + return tp->msg_enable; +} + +static void +rtl8125_set_msglevel(struct net_device *dev, + u32 value) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + tp->msg_enable = value; +} + +static const char rtl8125_gstrings[][ETH_GSTRING_LEN] = { + /* legacy */ + "tx_packets", + "rx_packets", + "tx_errors", + "rx_errors", + "rx_missed", + "align_errors", + "tx_single_collisions", + "tx_multi_collisions", + "unicast", + "broadcast", + "multicast", + "tx_aborted", + "tx_underrun", + + /* extended */ + "tx_octets", + "rx_octets", + "rx_multicast64", + "tx_unicast64", + "tx_broadcast64", + "tx_multicast64", + "tx_pause_on", + "tx_pause_off", + "tx_pause_all", + "tx_deferred", + "tx_late_collision", + "tx_all_collision", + "tx_aborted32", + "align_errors32", + "rx_frame_too_long", + "rx_runt", + "rx_pause_on", + "rx_pause_off", + "rx_pause_all", + "rx_unknown_opcode", + "rx_mac_error", + "tx_underrun32", + "rx_mac_missed", + "rx_tcam_dropped", + "tdu", + "rdu", +}; +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static int rtl8125_get_stats_count(struct net_device *dev) +{ + return ARRAY_SIZE(rtl8125_gstrings); +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +#else +static int rtl8125_get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return ARRAY_SIZE(rtl8125_gstrings); + default: + return -EOPNOTSUPP; + } +} +#endif + +static void +rtl8125_set_ring_size(struct rtl8125_private *tp, u32 rx, u32 tx) +{ + int i; + + for (i = 0; i < tp->num_rx_rings; i++) + tp->rx_ring[i].num_rx_desc = rx; + + for (i = 0; i < tp->num_tx_rings; i++) + tp->tx_ring[i].num_tx_desc = tx; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +static void rtl8125_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) +#else +static void rtl8125_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + ring->rx_max_pending = MAX_NUM_TX_DESC; + ring->tx_max_pending = MAX_NUM_RX_DESC;; + ring->rx_pending = tp->rx_ring[0].num_rx_desc; + ring->tx_pending = tp->tx_ring[0].num_tx_desc; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +static int rtl8125_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring, + struct kernel_ethtool_ringparam *kernel_ring, + struct netlink_ext_ack *extack) +#else +static int rtl8125_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u32 new_rx_count, new_tx_count; + int rc = 0; + + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + + new_tx_count = clamp_t(u32, ring->tx_pending, + MIN_NUM_TX_DESC, MAX_NUM_TX_DESC); + + new_rx_count = clamp_t(u32, ring->rx_pending, + MIN_NUM_RX_DESC, MAX_NUM_RX_DESC); + + if ((new_rx_count == tp->rx_ring[0].num_rx_desc) && + (new_tx_count == tp->tx_ring[0].num_tx_desc)) { + /* nothing to do */ + return 0; + } + + if (netif_running(dev)) { + rtl8125_wait_for_quiescence(dev); + rtl8125_close(dev); + } + + rtl8125_set_ring_size(tp, new_rx_count, new_tx_count); + + if (netif_running(dev)) + rc = rtl8125_open(dev); + + return rc; +} +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static void +rtl8125_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, + u64 *data) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct rtl8125_counters *counters; + dma_addr_t paddr; + + ASSERT_RTNL(); + + counters = tp->tally_vaddr; + paddr = tp->tally_paddr; + if (!counters) + return; + + rtl8125_dump_tally_counter(tp, paddr); + + data[0] = le64_to_cpu(counters->tx_packets); + data[1] = le64_to_cpu(counters->rx_packets); + data[2] = le64_to_cpu(counters->tx_errors); + data[3] = le32_to_cpu(counters->rx_errors); + data[4] = le16_to_cpu(counters->rx_missed); + data[5] = le16_to_cpu(counters->align_errors); + data[6] = le32_to_cpu(counters->tx_one_collision); + data[7] = le32_to_cpu(counters->tx_multi_collision); + data[8] = le64_to_cpu(counters->rx_unicast); + data[9] = le64_to_cpu(counters->rx_broadcast); + data[10] = le32_to_cpu(counters->rx_multicast); + data[11] = le16_to_cpu(counters->tx_aborted); + data[12] = le16_to_cpu(counters->tx_underrun); + + data[13] = le64_to_cpu(counters->tx_octets); + data[14] = le64_to_cpu(counters->rx_octets); + data[15] = le64_to_cpu(counters->rx_multicast64); + data[16] = le64_to_cpu(counters->tx_unicast64); + data[17] = le64_to_cpu(counters->tx_broadcast64); + data[18] = le64_to_cpu(counters->tx_multicast64); + data[19] = le32_to_cpu(counters->tx_pause_on); + data[20] = le32_to_cpu(counters->tx_pause_off); + data[21] = le32_to_cpu(counters->tx_pause_all); + data[22] = le32_to_cpu(counters->tx_deferred); + data[23] = le32_to_cpu(counters->tx_late_collision); + data[24] = le32_to_cpu(counters->tx_all_collision); + data[25] = le32_to_cpu(counters->tx_aborted32); + data[26] = le32_to_cpu(counters->align_errors32); + data[27] = le32_to_cpu(counters->rx_frame_too_long); + data[28] = le32_to_cpu(counters->rx_runt); + data[29] = le32_to_cpu(counters->rx_pause_on); + data[30] = le32_to_cpu(counters->rx_pause_off); + data[31] = le32_to_cpu(counters->rx_pause_all); + data[32] = le32_to_cpu(counters->rx_unknown_opcode); + data[33] = le32_to_cpu(counters->rx_mac_error); + data[34] = le32_to_cpu(counters->tx_underrun32); + data[35] = le32_to_cpu(counters->rx_mac_missed); + data[36] = le32_to_cpu(counters->rx_tcam_dropped); + data[37] = le32_to_cpu(counters->tdu); + data[38] = le32_to_cpu(counters->rdu); +} + +static void +rtl8125_get_strings(struct net_device *dev, + u32 stringset, + u8 *data) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(data, rtl8125_gstrings, sizeof(rtl8125_gstrings)); + break; + } +} +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +static int rtl_get_eeprom_len(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + return tp->eeprom_len; +} + +static int rtl_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 *buf) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i,j,ret; + int start_w, end_w; + int VPD_addr, VPD_data; + u32 *eeprom_buff; + u16 tmp; + + if (tp->eeprom_type == EEPROM_TYPE_NONE) { + dev_printk(KERN_DEBUG, tp_to_dev(tp), "Detect none EEPROM\n"); + return -EOPNOTSUPP; + } else if (eeprom->len == 0 || (eeprom->offset+eeprom->len) > tp->eeprom_len) { + dev_printk(KERN_DEBUG, tp_to_dev(tp), "Invalid parameter\n"); + return -EINVAL; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + default: + VPD_addr = 0xD2; + VPD_data = 0xD4; + break; + } + + start_w = eeprom->offset >> 2; + end_w = (eeprom->offset + eeprom->len - 1) >> 2; + + eeprom_buff = kmalloc(sizeof(u32)*(end_w - start_w + 1), GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + rtl8125_enable_cfg9346_write(tp); + ret = -EFAULT; + for (i=start_w; i<=end_w; i++) { + pci_write_config_word(tp->pci_dev, VPD_addr, (u16)i*4); + ret = -EFAULT; + for (j = 0; j < 10; j++) { + udelay(400); + pci_read_config_word(tp->pci_dev, VPD_addr, &tmp); + if (tmp&0x8000) { + ret = 0; + break; + } + } + + if (ret) + break; + + pci_read_config_dword(tp->pci_dev, VPD_data, &eeprom_buff[i-start_w]); + } + rtl8125_disable_cfg9346_write(tp); + + if (!ret) + memcpy(buf, (u8 *)eeprom_buff + (eeprom->offset & 3), eeprom->len); + + kfree(eeprom_buff); + + return ret; +} + +#undef ethtool_op_get_link +#define ethtool_op_get_link _kc_ethtool_op_get_link +static u32 _kc_ethtool_op_get_link(struct net_device *dev) +{ + return netif_carrier_ok(dev) ? 1 : 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) +#undef ethtool_op_get_sg +#define ethtool_op_get_sg _kc_ethtool_op_get_sg +static u32 _kc_ethtool_op_get_sg(struct net_device *dev) +{ +#ifdef NETIF_F_SG + return (dev->features & NETIF_F_SG) != 0; +#else + return 0; +#endif +} + +#undef ethtool_op_set_sg +#define ethtool_op_set_sg _kc_ethtool_op_set_sg +static int _kc_ethtool_op_set_sg(struct net_device *dev, u32 data) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_DEFAULT) + return -EOPNOTSUPP; + +#ifdef NETIF_F_SG + if (data) + dev->features |= NETIF_F_SG; + else + dev->features &= ~NETIF_F_SG; +#endif + + return 0; +} +#endif + +static int rtl8125_enable_eee(struct rtl8125_private *tp) +{ + struct ethtool_eee *eee = &tp->eee; + u16 eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(eee->advertised); + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + RTL_W16(tp, EEE_TXIDLE_TIMER_8125, eee->tx_lpi_timer); + + SetMcuAccessRegBit(tp, 0xE040, (BIT_1|BIT_0)); + SetMcuAccessRegBit(tp, 0xEB62, (BIT_2|BIT_1)); + + SetEthPhyOcpBit(tp, 0xA432, BIT_4); + ClearAndSetEthPhyOcpBit(tp, + 0xA5D0, + MDIO_EEE_100TX | MDIO_EEE_1000T, + eee_adv_t); + ClearEthPhyOcpBit(tp, 0xA6D4, BIT_0); + + ClearEthPhyOcpBit(tp, 0xA6D8, BIT_4); + ClearEthPhyOcpBit(tp, 0xA428, BIT_7); + ClearEthPhyOcpBit(tp, 0xA4A2, BIT_9); + break; + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + RTL_W16(tp, EEE_TXIDLE_TIMER_8125, eee->tx_lpi_timer); + + SetMcuAccessRegBit(tp, 0xE040, (BIT_1|BIT_0)); + + ClearAndSetEthPhyOcpBit(tp, + 0xA5D0, + MDIO_EEE_100TX | MDIO_EEE_1000T, + eee_adv_t); + if (eee->advertised & SUPPORTED_2500baseX_Full) + SetEthPhyOcpBit(tp, 0xA6D4, BIT_0); + else + ClearEthPhyOcpBit(tp, 0xA6D4, BIT_0); + + ClearEthPhyOcpBit(tp, 0xA6D8, BIT_4); + ClearEthPhyOcpBit(tp, 0xA428, BIT_7); + ClearEthPhyOcpBit(tp, 0xA4A2, BIT_9); + break; + default: +// dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support EEE\n"); + ret = -EOPNOTSUPP; + break; + } + + /*Advanced EEE*/ + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_set_phy_mcu_patch_request(tp); + ClearMcuAccessRegBit(tp, 0xE052, BIT_0); + ClearEthPhyOcpBit(tp, 0xA442, BIT_12 | BIT_13); + ClearEthPhyOcpBit(tp, 0xA430, BIT_15); + rtl8125_clear_phy_mcu_patch_request(tp); + break; + } + + return ret; +} + +static int rtl8125_disable_eee(struct rtl8125_private *tp) +{ + int ret; + + ret = 0; + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + ClearMcuAccessRegBit(tp, 0xE040, (BIT_1|BIT_0)); + ClearMcuAccessRegBit(tp, 0xEB62, (BIT_2|BIT_1)); + + ClearEthPhyOcpBit(tp, 0xA432, BIT_4); + ClearEthPhyOcpBit(tp, 0xA5D0, (BIT_2 | BIT_1)); + ClearEthPhyOcpBit(tp, 0xA6D4, BIT_0); + + ClearEthPhyOcpBit(tp, 0xA6D8, BIT_4); + ClearEthPhyOcpBit(tp, 0xA428, BIT_7); + ClearEthPhyOcpBit(tp, 0xA4A2, BIT_9); + break; + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + ClearMcuAccessRegBit(tp, 0xE040, (BIT_1|BIT_0)); + + ClearEthPhyOcpBit(tp, 0xA5D0, (BIT_2 | BIT_1)); + ClearEthPhyOcpBit(tp, 0xA6D4, BIT_0); + + ClearEthPhyOcpBit(tp, 0xA6D8, BIT_4); + ClearEthPhyOcpBit(tp, 0xA428, BIT_7); + ClearEthPhyOcpBit(tp, 0xA4A2, BIT_9); + break; + default: +// dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support EEE\n"); + ret = -EOPNOTSUPP; + break; + } + + /*Advanced EEE*/ + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_set_phy_mcu_patch_request(tp); + ClearMcuAccessRegBit(tp, 0xE052, BIT_0); + ClearEthPhyOcpBit(tp, 0xA442, BIT_12 | BIT_13); + ClearEthPhyOcpBit(tp, 0xA430, BIT_15); + rtl8125_clear_phy_mcu_patch_request(tp); + break; + } + + return ret; +} + +static int rtl_nway_reset(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ret, bmcr; + + if (unlikely(tp->rtk_enable_diag)) + return -EBUSY; + + /* if autoneg is off, it's an error */ + rtl8125_mdio_write(tp, 0x1F, 0x0000); + bmcr = rtl8125_mdio_read(tp, MII_BMCR); + + if (bmcr & BMCR_ANENABLE) { + bmcr |= BMCR_ANRESTART; + rtl8125_mdio_write(tp, MII_BMCR, bmcr); + ret = 0; + } else { + ret = -EINVAL; + } + + return ret; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) +static u32 +rtl8125_tx_lpi_timer_to_us(struct rtl8125_private *tp , u32 tx_lpi_timer) +{ + u32 to_us; + u16 status; + + //2.5G : tx_lpi_timer * 3.2ns + //Giga: tx_lpi_timer * 8ns + //100M : tx_lpi_timer * 80ns + to_us = tx_lpi_timer * 80; + status = RTL_R16(tp, PHYstatus); + if (status & LinkStatus) { + /*link on*/ + if (status & _2500bpsF) + to_us = (tx_lpi_timer * 32) / 10; + else if (status & _1000bpsF) + to_us = tx_lpi_timer * 8; + } + + //ns to us + to_us /= 1000; + + return to_us; +} + +static int +rtl_ethtool_get_eee(struct net_device *net, struct ethtool_eee *edata) +{ + struct rtl8125_private *tp = netdev_priv(net); + struct ethtool_eee *eee = &tp->eee; + u32 lp, adv, tx_lpi_timer, supported = 0; + u16 val; + + if (unlikely(tp->rtk_enable_diag)) + return -EBUSY; + + /* Get Supported EEE */ + //val = mdio_direct_read_phy_ocp(tp, 0xA5C4); + //supported = mmd_eee_cap_to_ethtool_sup_t(val); + supported = eee->supported; + + /* Get advertisement EEE */ + val = mdio_direct_read_phy_ocp(tp, 0xA5D0); + adv = mmd_eee_adv_to_ethtool_adv_t(val); + val = mdio_direct_read_phy_ocp(tp, 0xA6D4); + if (val & RTK_EEE_ADVERTISE_2500FULL) + adv |= ADVERTISED_2500baseX_Full; + + /* Get LP advertisement EEE */ + val = mdio_direct_read_phy_ocp(tp, 0xA5D2); + lp = mmd_eee_adv_to_ethtool_adv_t(val); + val = mdio_direct_read_phy_ocp(tp, 0xA6D0); + if (val & RTK_LPA_EEE_ADVERTISE_2500FULL) + lp |= ADVERTISED_2500baseX_Full; + + /* Get EEE Tx LPI timer*/ + tx_lpi_timer = RTL_R16(tp, EEE_TXIDLE_TIMER_8125); + + val = rtl8125_mac_ocp_read(tp, 0xE040); + val &= BIT_1 | BIT_0; + + edata->eee_enabled = !!val; + edata->eee_active = !!(supported & adv & lp); + edata->supported = supported; + edata->advertised = adv; + edata->lp_advertised = lp; + edata->tx_lpi_enabled = edata->eee_enabled; + edata->tx_lpi_timer = rtl8125_tx_lpi_timer_to_us(tp, tx_lpi_timer); + + return 0; +} + +static int +rtl_ethtool_set_eee(struct net_device *net, struct ethtool_eee *edata) +{ + struct rtl8125_private *tp = netdev_priv(net); + struct ethtool_eee *eee = &tp->eee; + u32 advertising; + int rc = 0; + + if (!HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp) || + tp->DASH) + return -EOPNOTSUPP; + + if (unlikely(tp->rtk_enable_diag)) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "Diag Enabled\n"); + rc = -EBUSY; + goto out; + } + + if (tp->autoneg != AUTONEG_ENABLE) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE requires autoneg\n"); + rc = -EINVAL; + goto out; + } + + if (edata->tx_lpi_enabled) { + if (edata->tx_lpi_timer > tp->max_jumbo_frame_size || + edata->tx_lpi_timer < ETH_MIN_MTU) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "Valid LPI timer range is %d to %d. \n", + ETH_MIN_MTU, tp->max_jumbo_frame_size); + rc = -EINVAL; + goto out; + } + } + + advertising = tp->advertising; + if (!edata->advertised) { + edata->advertised = advertising & eee->supported; + } else if (edata->advertised & ~advertising) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of autoneg advertised speeds %x\n", + edata->advertised, advertising); + rc = -EINVAL; + goto out; + } + + if (edata->advertised & ~eee->supported) { + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE advertised %x must be a subset of support %x\n", + edata->advertised, eee->supported); + rc = -EINVAL; + goto out; + } + + //tp->eee.eee_enabled = edata->eee_enabled; + //tp->eee_adv_t = ethtool_adv_to_mmd_eee_adv_t(edata->advertised); + + dev_printk(KERN_WARNING, tp_to_dev(tp), "EEE tx_lpi_timer %x must be a subset of support %x\n", + edata->tx_lpi_timer, eee->tx_lpi_timer); + + eee->advertised = edata->advertised; + eee->tx_lpi_enabled = edata->tx_lpi_enabled; + eee->tx_lpi_timer = edata->tx_lpi_timer; + eee->eee_enabled = edata->eee_enabled; + + if (eee->eee_enabled) + rtl8125_enable_eee(tp); + else + rtl8125_disable_eee(tp); + + rtl_nway_reset(net); + + return rc; + +out: + + return rc; +} +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) +static const struct ethtool_ops rtl8125_ethtool_ops = { + .get_drvinfo = rtl8125_get_drvinfo, + .get_regs_len = rtl8125_get_regs_len, + .get_link = ethtool_op_get_link, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .get_ringparam = rtl8125_get_ringparam, + .set_ringparam = rtl8125_set_ringparam, +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) + .get_settings = rtl8125_get_settings, + .set_settings = rtl8125_set_settings, +#else + .get_link_ksettings = rtl8125_get_settings, + .set_link_ksettings = rtl8125_set_settings, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,6,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .get_pauseparam = rtl8125_get_pauseparam, + .set_pauseparam = rtl8125_set_pauseparam, +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + .get_msglevel = rtl8125_get_msglevel, + .set_msglevel = rtl8125_set_msglevel, +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + .get_rx_csum = rtl8125_get_rx_csum, + .set_rx_csum = rtl8125_set_rx_csum, + .get_tx_csum = rtl8125_get_tx_csum, + .set_tx_csum = rtl8125_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, + .set_tso = ethtool_op_set_tso, +#endif //NETIF_F_TSO +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) + .get_regs = rtl8125_get_regs, + .get_wol = rtl8125_get_wol, + .set_wol = rtl8125_set_wol, + .get_strings = rtl8125_get_strings, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + .get_stats_count = rtl8125_get_stats_count, +#else + .get_sset_count = rtl8125_get_sset_count, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) + .get_ethtool_stats = rtl8125_get_ethtool_stats, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +#ifdef ETHTOOL_GPERMADDR + .get_perm_addr = ethtool_op_get_perm_addr, +#endif //ETHTOOL_GPERMADDR +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) + .get_eeprom = rtl_get_eeprom, + .get_eeprom_len = rtl_get_eeprom_len, +#ifdef ENABLE_RSS_SUPPORT + .get_rxnfc = rtl8125_get_rxnfc, + .set_rxnfc = rtl8125_set_rxnfc, + .get_rxfh_indir_size = rtl8125_rss_indir_size, + .get_rxfh_key_size = rtl8125_get_rxfh_key_size, + .get_rxfh = rtl8125_get_rxfh, + .set_rxfh = rtl8125_set_rxfh, +#endif //ENABLE_RSS_SUPPORT +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +#ifdef ENABLE_PTP_SUPPORT + .get_ts_info = rtl8125_get_ts_info, +#else + .get_ts_info = ethtool_op_get_ts_info, +#endif //ENABLE_PTP_SUPPORT +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) + .get_eee = rtl_ethtool_get_eee, + .set_eee = rtl_ethtool_set_eee, +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0) */ + .nway_reset = rtl_nway_reset, + +}; +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + +#if 0 + +static int rtl8125_enable_green_feature(struct rtl8125_private *tp) +{ + u16 gphy_val; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8011); + SetEthPhyOcpBit(tp, 0xA438, BIT_15); + rtl8125_mdio_write(tp, 0x00, 0x9200); + break; + default: + dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support Green Feature\n"); + break; + } + + return 0; +} + +static int rtl8125_disable_green_feature(struct rtl8125_private *tp) +{ + u16 gphy_val; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8011); + ClearEthPhyOcpBit(tp, 0xA438, BIT_15); + rtl8125_mdio_write(tp, 0x00, 0x9200); + break; + default: + dev_printk(KERN_DEBUG, tp_to_dev(tp), "Not Support Green Feature\n"); + break; + } + + return 0; +} + +#endif + +static void rtl8125_get_mac_version(struct rtl8125_private *tp) +{ + u32 reg,val32; + u32 ICVerID; + struct pci_dev *pdev = tp->pci_dev; + + val32 = RTL_R32(tp, TxConfig); + reg = val32 & 0x7c800000; + ICVerID = val32 & 0x00700000; + + switch (reg) { + case 0x60800000: + if (ICVerID == 0x00000000) { + tp->mcfg = CFG_METHOD_2; + } else if (ICVerID == 0x100000) { + tp->mcfg = CFG_METHOD_3; + } else { + tp->mcfg = CFG_METHOD_3; + tp->HwIcVerUnknown = TRUE; + } + + tp->efuse_ver = EFUSE_SUPPORT_V4; + break; + case 0x64000000: + if (ICVerID == 0x00000000) { + tp->mcfg = CFG_METHOD_4; + } else if (ICVerID == 0x100000) { + tp->mcfg = CFG_METHOD_5; + } else { + tp->mcfg = CFG_METHOD_5; + tp->HwIcVerUnknown = TRUE; + } + + tp->efuse_ver = EFUSE_SUPPORT_V4; + break; + default: + printk("unknown chip version (%x)\n",reg); + tp->mcfg = CFG_METHOD_DEFAULT; + tp->HwIcVerUnknown = TRUE; + tp->efuse_ver = EFUSE_NOT_SUPPORT; + break; + } + + if (pdev->subsystem_vendor == 0x8162) { + if (tp->mcfg == CFG_METHOD_3) + tp->mcfg = CFG_METHOD_6; + else if (tp->mcfg == CFG_METHOD_5) + tp->mcfg = CFG_METHOD_7; + } +} + +static void +rtl8125_print_mac_version(struct rtl8125_private *tp) +{ + int i; + for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { + if (tp->mcfg == rtl_chip_info[i].mcfg) { + dprintk("Realtek PCIe 2.5GbE Family Controller mcfg = %04d\n", + rtl_chip_info[i].mcfg); + return; + } + } + + dprintk("mac_version == Unknown\n"); +} + +static void +rtl8125_tally_counter_addr_fill(struct rtl8125_private *tp) +{ + if (!tp->tally_paddr) + return; + + RTL_W32(tp, CounterAddrHigh, (u64)tp->tally_paddr >> 32); + RTL_W32(tp, CounterAddrLow, (u64)tp->tally_paddr & (DMA_BIT_MASK(32))); +} + +static void +rtl8125_tally_counter_clear(struct rtl8125_private *tp) +{ + if (!tp->tally_paddr) + return; + + RTL_W32(tp, CounterAddrHigh, (u64)tp->tally_paddr >> 32); + RTL_W32(tp, CounterAddrLow, ((u64)tp->tally_paddr & (DMA_BIT_MASK(32))) | CounterReset); +} + +static void +rtl8125_clear_phy_ups_reg(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + ClearEthPhyOcpBit(tp, 0xA466, BIT_0); + break; + }; + ClearEthPhyOcpBit(tp, 0xA468, BIT_3 | BIT_1); +} + +static int +rtl8125_is_ups_resume(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) + return (rtl8125_mac_ocp_read(tp, 0xD42C) & BIT_8); + + return 0; +} + +static void +rtl8125_clear_ups_resume_bit(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) + rtl8125_mac_ocp_write(tp, 0xD408, rtl8125_mac_ocp_read(tp, 0xD408) & ~(BIT_8)); +} + +static void +rtl8125_wait_phy_ups_resume(struct net_device *dev, u16 PhyState) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 TmpPhyState; + int i=0; + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + do { + TmpPhyState = mdio_direct_read_phy_ocp(tp, 0xA420); + TmpPhyState &= 0x7; + mdelay(1); + i++; + } while ((i < 100) && (TmpPhyState != PhyState)); + } + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + WARN_ON_ONCE(i == 100); +#endif +} + +void +rtl8125_enable_now_is_oob(struct rtl8125_private *tp) +{ + if ( tp->HwSuppNowIsOobVer == 1 ) { + RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) | Now_is_oob); + } +} + +void +rtl8125_disable_now_is_oob(struct rtl8125_private *tp) +{ + if ( tp->HwSuppNowIsOobVer == 1 ) { + RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) & ~Now_is_oob); + } +} + +static void +rtl8125_exit_oob(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 data16; + + RTL_W32(tp, RxConfig, RTL_R32(tp, RxConfig) & ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast | AcceptMyPhys | AcceptAllPhys)); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + rtl8125_dash2_disable_txrx(dev); + break; + } + + if (tp->DASH) { + rtl8125_driver_stop(tp); + rtl8125_driver_start(tp); +#ifdef ENABLE_DASH_SUPPORT + DashHwInit(dev); +#endif + } + +#ifdef ENABLE_REALWOW_SUPPORT + rtl8125_realwow_hw_init(dev); +#else + //Disable realwow function + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xC0BC, 0x00FF); + break; + } +#endif //ENABLE_REALWOW_SUPPORT + + rtl8125_nic_reset(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_disable_now_is_oob(tp); + + data16 = rtl8125_mac_ocp_read(tp, 0xE8DE) & ~BIT_14; + rtl8125_mac_ocp_write(tp, 0xE8DE, data16); + rtl8125_wait_ll_share_fifo_ready(dev); + + rtl8125_mac_ocp_write(tp, 0xC0AA, 0x07D0); + rtl8125_mac_ocp_write(tp, 0xC0A6, 0x01B5); + rtl8125_mac_ocp_write(tp, 0xC01E, 0x5555); + + rtl8125_wait_ll_share_fifo_ready(dev); + break; + } + + //wait ups resume (phy state 2) + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + if (rtl8125_is_ups_resume(dev)) { + rtl8125_wait_phy_ups_resume(dev, 2); + rtl8125_clear_ups_resume_bit(dev); + rtl8125_clear_phy_ups_reg(dev); + } + break; + }; +} + +void +rtl8125_hw_disable_mac_mcu_bps(struct net_device *dev) +{ + u16 regAddr; + + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_enable_cfg9346_write(tp); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~BIT_7); + rtl8125_disable_cfg9346_write(tp); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xFC48, 0x0000); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + for (regAddr = 0xFC28; regAddr < 0xFC48; regAddr += 2) { + rtl8125_mac_ocp_write(tp, regAddr, 0x0000); + } + + mdelay(3); + + rtl8125_mac_ocp_write(tp, 0xFC26, 0x0000); + break; + } +} + +#ifndef ENABLE_USE_FIRMWARE_FILE +static void +rtl8125_switch_mac_mcu_ram_code_page(struct rtl8125_private *tp, u16 page) +{ + u16 tmpUshort; + + page &= (BIT_1 | BIT_0); + tmpUshort = rtl8125_mac_ocp_read(tp, 0xE446); + tmpUshort &= ~(BIT_1 | BIT_0); + tmpUshort |= page; + rtl8125_mac_ocp_write(tp, 0xE446, tmpUshort); +} + +static void +_rtl8125_write_mac_mcu_ram_code(struct rtl8125_private *tp, const u16 *entry, u16 entry_cnt) +{ + u16 i; + + for (i = 0; i < entry_cnt; i++) { + rtl8125_mac_ocp_write(tp, 0xF800 + i * 2, entry[i]); + } +} + +static void +_rtl8125_write_mac_mcu_ram_code_with_page(struct rtl8125_private *tp, const u16 *entry, u16 entry_cnt, u16 page_size) +{ + u16 i; + u16 offset; + + if (page_size == 0) return; + + for (i = 0; i < entry_cnt; i++) { + offset = i % page_size; + if (offset == 0) { + u16 page = (i / page_size); + rtl8125_switch_mac_mcu_ram_code_page(tp, page); + } + rtl8125_mac_ocp_write(tp, 0xF800 + offset * 2, entry[i]); + } +} + +static void +rtl8125_write_mac_mcu_ram_code(struct rtl8125_private *tp, const u16 *entry, u16 entry_cnt) +{ + if (FALSE == HW_SUPPORT_MAC_MCU(tp)) return; + if (entry == NULL || entry_cnt == 0) return; + + if (tp->MacMcuPageSize > 0) + _rtl8125_write_mac_mcu_ram_code_with_page(tp, entry, entry_cnt, tp->MacMcuPageSize); + else + _rtl8125_write_mac_mcu_ram_code(tp, entry, entry_cnt); +} + +static void +rtl8125_set_mac_mcu_8125a_1(struct net_device *dev) +{ + rtl8125_hw_disable_mac_mcu_bps(dev); +} + +static void +rtl8125_set_mac_mcu_8125a_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + static const u16 mcu_patch_code_8125a_2[] = { + 0xE010, 0xE012, 0xE022, 0xE024, 0xE029, 0xE02B, 0xE094, 0xE09D, 0xE09F, + 0xE0AA, 0xE0B5, 0xE0C6, 0xE0CC, 0xE0D1, 0xE0D6, 0xE0D8, 0xC602, 0xBE00, + 0x0000, 0xC60F, 0x73C4, 0x49B3, 0xF106, 0x73C2, 0xC608, 0xB406, 0xC609, + 0xFF80, 0xC605, 0xB406, 0xC605, 0xFF80, 0x0544, 0x0568, 0xE906, 0xCDE8, + 0xC602, 0xBE00, 0x0000, 0x48C1, 0x48C2, 0x9C46, 0xC402, 0xBC00, 0x0A12, + 0xC602, 0xBE00, 0x0EBA, 0x1501, 0xF02A, 0x1500, 0xF15D, 0xC661, 0x75C8, + 0x49D5, 0xF00A, 0x49D6, 0xF008, 0x49D7, 0xF006, 0x49D8, 0xF004, 0x75D2, + 0x49D9, 0xF150, 0xC553, 0x77A0, 0x75C8, 0x4855, 0x4856, 0x4857, 0x4858, + 0x48DA, 0x48DB, 0x49FE, 0xF002, 0x485A, 0x49FF, 0xF002, 0x485B, 0x9DC8, + 0x75D2, 0x4859, 0x9DD2, 0xC643, 0x75C0, 0x49D4, 0xF033, 0x49D0, 0xF137, + 0xE030, 0xC63A, 0x75C8, 0x49D5, 0xF00E, 0x49D6, 0xF00C, 0x49D7, 0xF00A, + 0x49D8, 0xF008, 0x75D2, 0x49D9, 0xF005, 0xC62E, 0x75C0, 0x49D7, 0xF125, + 0xC528, 0x77A0, 0xC627, 0x75C8, 0x4855, 0x4856, 0x4857, 0x4858, 0x48DA, + 0x48DB, 0x49FE, 0xF002, 0x485A, 0x49FF, 0xF002, 0x485B, 0x9DC8, 0x75D2, + 0x4859, 0x9DD2, 0xC616, 0x75C0, 0x4857, 0x9DC0, 0xC613, 0x75C0, 0x49DA, + 0xF003, 0x49D0, 0xF107, 0xC60B, 0xC50E, 0x48D9, 0x9DC0, 0x4859, 0x9DC0, + 0xC608, 0xC702, 0xBF00, 0x3AE0, 0xE860, 0xB400, 0xB5D4, 0xE908, 0xE86C, + 0x1200, 0xC409, 0x6780, 0x48F1, 0x8F80, 0xC404, 0xC602, 0xBE00, 0x10AA, + 0xC010, 0xEA7C, 0xC602, 0xBE00, 0x0000, 0x740A, 0x4846, 0x4847, 0x9C0A, + 0xC607, 0x74C0, 0x48C6, 0x9CC0, 0xC602, 0xBE00, 0x13FE, 0xE054, 0x72CA, + 0x4826, 0x4827, 0x9ACA, 0xC607, 0x72C0, 0x48A6, 0x9AC0, 0xC602, 0xBE00, + 0x07DC, 0xE054, 0xC60F, 0x74C4, 0x49CC, 0xF109, 0xC60C, 0x74CA, 0x48C7, + 0x9CCA, 0xC609, 0x74C0, 0x4846, 0x9CC0, 0xC602, 0xBE00, 0x2480, 0xE092, + 0xE0C0, 0xE054, 0x7420, 0x48C0, 0x9C20, 0x7444, 0xC602, 0xBE00, 0x12F8, + 0x1BFF, 0x46EB, 0x1BFF, 0xC102, 0xB900, 0x0D5A, 0x1BFF, 0x46EB, 0x1BFF, + 0xC102, 0xB900, 0x0E2A, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6486, + 0x0B15, 0x090E, 0x1139 + }; + + rtl8125_hw_disable_mac_mcu_bps(dev); + + rtl8125_write_mac_mcu_ram_code(tp, mcu_patch_code_8125a_2, ARRAY_SIZE(mcu_patch_code_8125a_2)); + + rtl8125_mac_ocp_write(tp, 0xFC26, 0x8000); + + rtl8125_mac_ocp_write(tp, 0xFC2A, 0x0540); + rtl8125_mac_ocp_write(tp, 0xFC2E, 0x0A06); + rtl8125_mac_ocp_write(tp, 0xFC30, 0x0EB8); + rtl8125_mac_ocp_write(tp, 0xFC32, 0x3A5C); + rtl8125_mac_ocp_write(tp, 0xFC34, 0x10A8); + rtl8125_mac_ocp_write(tp, 0xFC40, 0x0D54); + rtl8125_mac_ocp_write(tp, 0xFC42, 0x0E24); + + rtl8125_mac_ocp_write(tp, 0xFC48, 0x307A); +} + +static void +rtl8125_set_mac_mcu_8125b_1(struct net_device *dev) +{ + rtl8125_hw_disable_mac_mcu_bps(dev); +} + +static void +rtl8125_set_mac_mcu_8125b_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + static const u16 mcu_patch_code_8125b_2[] = { + 0xE010, 0xE01B, 0xE026, 0xE037, 0xE03D, 0xE057, 0xE05B, 0xE060, 0xE062, + 0xE064, 0xE066, 0xE068, 0xE06A, 0xE06C, 0xE06E, 0xE070, 0x740A, 0x4846, + 0x4847, 0x9C0A, 0xC607, 0x74C0, 0x48C6, 0x9CC0, 0xC602, 0xBE00, 0x13F0, + 0xE054, 0x72CA, 0x4826, 0x4827, 0x9ACA, 0xC607, 0x72C0, 0x48A6, 0x9AC0, + 0xC602, 0xBE00, 0x081C, 0xE054, 0xC60F, 0x74C4, 0x49CC, 0xF109, 0xC60C, + 0x74CA, 0x48C7, 0x9CCA, 0xC609, 0x74C0, 0x4846, 0x9CC0, 0xC602, 0xBE00, + 0x2494, 0xE092, 0xE0C0, 0xE054, 0x7420, 0x48C0, 0x9C20, 0x7444, 0xC602, + 0xBE00, 0x12DC, 0x733A, 0x21B5, 0x25BC, 0x1304, 0xF111, 0x1B12, 0x1D2A, + 0x3168, 0x3ADA, 0x31AB, 0x1A00, 0x9AC0, 0x1300, 0xF1FB, 0x7620, 0x236E, + 0x276F, 0x1A3C, 0x22A1, 0x41B5, 0x9EE2, 0x76E4, 0x486F, 0x9EE4, 0xC602, + 0xBE00, 0x4A26, 0x733A, 0x49BB, 0xC602, 0xBE00, 0x47A2, 0x48C1, 0x48C2, + 0x9C46, 0xC402, 0xBC00, 0x0A52, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, + 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, + 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, 0x0000, 0xC602, 0xBE00, + 0x0000, 0xC602, 0xBE00, 0x0000 + }; + + rtl8125_hw_disable_mac_mcu_bps(dev); + + rtl8125_write_mac_mcu_ram_code(tp, mcu_patch_code_8125b_2, ARRAY_SIZE(mcu_patch_code_8125b_2)); + + rtl8125_mac_ocp_write(tp, 0xFC26, 0x8000); + + rtl8125_mac_ocp_write(tp, 0xFC28, 0x13E6); + rtl8125_mac_ocp_write(tp, 0xFC2A, 0x0812); + rtl8125_mac_ocp_write(tp, 0xFC2C, 0x248C); + rtl8125_mac_ocp_write(tp, 0xFC2E, 0x12DA); + rtl8125_mac_ocp_write(tp, 0xFC30, 0x4A20); + rtl8125_mac_ocp_write(tp, 0xFC32, 0x47A0); + //rtl8125_mac_ocp_write(tp, 0xFC34, 0x0A46); + + rtl8125_mac_ocp_write(tp, 0xFC48, 0x003F); +} + +static void +rtl8125_hw_mac_mcu_config(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->NotWrMcuPatchCode == TRUE) return; + + switch (tp->mcfg) { + case CFG_METHOD_2: + rtl8125_set_mac_mcu_8125a_1(dev); + break; + case CFG_METHOD_3: + case CFG_METHOD_6: + rtl8125_set_mac_mcu_8125a_2(dev); + break; + case CFG_METHOD_4: + rtl8125_set_mac_mcu_8125b_1(dev); + break; + case CFG_METHOD_5: + case CFG_METHOD_7: + rtl8125_set_mac_mcu_8125b_2(dev); + break; + } +} +#endif + +#ifdef ENABLE_USE_FIRMWARE_FILE +static void rtl8125_release_firmware(struct rtl8125_private *tp) +{ + if (tp->rtl_fw) { + rtl8125_fw_release_firmware(tp->rtl_fw); + kfree(tp->rtl_fw); + tp->rtl_fw = NULL; + } +} + +void rtl8125_apply_firmware(struct rtl8125_private *tp) +{ + /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ + if (tp->rtl_fw) { + rtl8125_fw_write_firmware(tp, tp->rtl_fw); + /* At least one firmware doesn't reset tp->ocp_base. */ + tp->ocp_base = OCP_STD_PHY_BASE; + + /* PHY soft reset may still be in progress */ + //phy_read_poll_timeout(tp->phydev, MII_BMCR, val, + // !(val & BMCR_RESET), + // 50000, 600000, true); + rtl8125_wait_phy_reset_complete(tp); + + tp->hw_ram_code_ver = rtl8125_get_hw_phy_mcu_code_ver(tp); + tp->sw_ram_code_ver = tp->hw_ram_code_ver; + tp->HwHasWrRamCodeToMicroP = TRUE; + } +} +#endif + +static void +rtl8125_hw_init(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u32 csi_tmp; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_enable_cfg9346_write(tp); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~BIT_7); + rtl8125_disable_cfg9346_write(tp); + RTL_W8(tp, 0xF1, RTL_R8(tp, 0xF1) & ~BIT_7); + break; + } + + //Disable UPS + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xD40A, rtl8125_mac_ocp_read( tp, 0xD40A) & ~(BIT_4)); + break; + } + +#ifndef ENABLE_USE_FIRMWARE_FILE + if (!tp->rtl_fw) + rtl8125_hw_mac_mcu_config(dev); +#endif + + /*disable ocp phy power saving*/ + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) + rtl8125_disable_ocp_phy_power_saving(dev); + + //Set PCIE uncorrectable error status mask pcie 0x108 + csi_tmp = rtl8125_csi_read(tp, 0x108); + csi_tmp |= BIT_20; + rtl8125_csi_write(tp, 0x108, csi_tmp); + + rtl8125_enable_cfg9346_write(tp); + rtl8125_disable_linkchg_wakeup(dev); + rtl8125_disable_cfg9346_write(tp); + rtl8125_disable_magic_packet(dev); + rtl8125_disable_d0_speedup(tp); + rtl8125_set_pci_pme(tp, 0); + if (s0_magic_packet == 1) + rtl8125_enable_magic_packet(dev); + +#ifdef ENABLE_USE_FIRMWARE_FILE + if (tp->rtl_fw && + !tp->resume_not_chg_speed && + !(HW_DASH_SUPPORT_TYPE_3(tp) && + tp->HwPkgDet == 0x06)) + rtl8125_apply_firmware(tp); +#endif +} + +static void +rtl8125_hw_ephy_config(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + rtl8125_ephy_write(tp, 0x01, 0xA812); + rtl8125_ephy_write(tp, 0x09, 0x520C); + rtl8125_ephy_write(tp, 0x04, 0xD000); + rtl8125_ephy_write(tp, 0x0D, 0xF702); + rtl8125_ephy_write(tp, 0x0A, 0x8653); + rtl8125_ephy_write(tp, 0x06, 0x001E); + rtl8125_ephy_write(tp, 0x08, 0x3595); + rtl8125_ephy_write(tp, 0x20, 0x9455); + rtl8125_ephy_write(tp, 0x21, 0x99FF); + rtl8125_ephy_write(tp, 0x02, 0x6046); + rtl8125_ephy_write(tp, 0x29, 0xFE00); + rtl8125_ephy_write(tp, 0x23, 0xAB62); + + rtl8125_ephy_write(tp, 0x41, 0xA80C); + rtl8125_ephy_write(tp, 0x49, 0x520C); + rtl8125_ephy_write(tp, 0x44, 0xD000); + rtl8125_ephy_write(tp, 0x4D, 0xF702); + rtl8125_ephy_write(tp, 0x4A, 0x8653); + rtl8125_ephy_write(tp, 0x46, 0x001E); + rtl8125_ephy_write(tp, 0x48, 0x3595); + rtl8125_ephy_write(tp, 0x60, 0x9455); + rtl8125_ephy_write(tp, 0x61, 0x99FF); + rtl8125_ephy_write(tp, 0x42, 0x6046); + rtl8125_ephy_write(tp, 0x69, 0xFE00); + rtl8125_ephy_write(tp, 0x63, 0xAB62); + break; + case CFG_METHOD_3: + case CFG_METHOD_6: + rtl8125_ephy_write(tp, 0x04, 0xD000); + rtl8125_ephy_write(tp, 0x0A, 0x8653); + rtl8125_ephy_write(tp, 0x23, 0xAB66); + rtl8125_ephy_write(tp, 0x20, 0x9455); + rtl8125_ephy_write(tp, 0x21, 0x99FF); + rtl8125_ephy_write(tp, 0x29, 0xFE04); + + rtl8125_ephy_write(tp, 0x44, 0xD000); + rtl8125_ephy_write(tp, 0x4A, 0x8653); + rtl8125_ephy_write(tp, 0x63, 0xAB66); + rtl8125_ephy_write(tp, 0x60, 0x9455); + rtl8125_ephy_write(tp, 0x61, 0x99FF); + rtl8125_ephy_write(tp, 0x69, 0xFE04); + + ClearAndSetPCIePhyBit(tp, + 0x2A, + (BIT_14 | BIT_13 | BIT_12), + (BIT_13 | BIT_12) + ); + ClearPCIePhyBit(tp, 0x19, BIT_6); + SetPCIePhyBit(tp, 0x1B, (BIT_11 | BIT_10 | BIT_9)); + ClearPCIePhyBit(tp, 0x1B, (BIT_14 | BIT_13 | BIT_12)); + rtl8125_ephy_write(tp, 0x02, 0x6042); + rtl8125_ephy_write(tp, 0x06, 0x0014); + + ClearAndSetPCIePhyBit(tp, + 0x6A, + (BIT_14 | BIT_13 | BIT_12), + (BIT_13 | BIT_12) + ); + ClearPCIePhyBit(tp, 0x59, BIT_6); + SetPCIePhyBit(tp, 0x5B, (BIT_11 | BIT_10 | BIT_9)); + ClearPCIePhyBit(tp, 0x5B, (BIT_14 | BIT_13 | BIT_12)); + rtl8125_ephy_write(tp, 0x42, 0x6042); + rtl8125_ephy_write(tp, 0x46, 0x0014); + break; + case CFG_METHOD_4: + rtl8125_ephy_write(tp, 0x06, 0x001F); + rtl8125_ephy_write(tp, 0x0A, 0xB66B); + rtl8125_ephy_write(tp, 0x01, 0xA852); + rtl8125_ephy_write(tp, 0x24, 0x0008); + rtl8125_ephy_write(tp, 0x2F, 0x6052); + rtl8125_ephy_write(tp, 0x0D, 0xF716); + rtl8125_ephy_write(tp, 0x20, 0xD477); + rtl8125_ephy_write(tp, 0x21, 0x4477); + rtl8125_ephy_write(tp, 0x22, 0x0013); + rtl8125_ephy_write(tp, 0x23, 0xBB66); + rtl8125_ephy_write(tp, 0x0B, 0xA909); + rtl8125_ephy_write(tp, 0x29, 0xFF04); + rtl8125_ephy_write(tp, 0x1B, 0x1EA0); + + rtl8125_ephy_write(tp, 0x46, 0x001F); + rtl8125_ephy_write(tp, 0x4A, 0xB66B); + rtl8125_ephy_write(tp, 0x41, 0xA84A); + rtl8125_ephy_write(tp, 0x64, 0x000C); + rtl8125_ephy_write(tp, 0x6F, 0x604A); + rtl8125_ephy_write(tp, 0x4D, 0xF716); + rtl8125_ephy_write(tp, 0x60, 0xD477); + rtl8125_ephy_write(tp, 0x61, 0x4477); + rtl8125_ephy_write(tp, 0x62, 0x0013); + rtl8125_ephy_write(tp, 0x63, 0xBB66); + rtl8125_ephy_write(tp, 0x4B, 0xA909); + rtl8125_ephy_write(tp, 0x69, 0xFF04); + rtl8125_ephy_write(tp, 0x5B, 0x1EA0); + break; + case CFG_METHOD_5: + case CFG_METHOD_7: + rtl8125_ephy_write(tp, 0x0B, 0xA908); + rtl8125_ephy_write(tp, 0x1E, 0x20EB); + rtl8125_ephy_write(tp, 0x22, 0x0023); + rtl8125_ephy_write(tp, 0x02, 0x60C2); + rtl8125_ephy_write(tp, 0x29, 0xFF00); + + rtl8125_ephy_write(tp, 0x4B, 0xA908); + rtl8125_ephy_write(tp, 0x5E, 0x28EB); + rtl8125_ephy_write(tp, 0x62, 0x0023); + rtl8125_ephy_write(tp, 0x42, 0x60C2); + rtl8125_ephy_write(tp, 0x69, 0xFF00); + break; + } +} + +static u16 +rtl8125_get_hw_phy_mcu_code_ver(struct rtl8125_private *tp) +{ + u16 hw_ram_code_ver = ~0; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + mdio_direct_write_phy_ocp(tp, 0xA436, 0x801E); + hw_ram_code_ver = mdio_direct_read_phy_ocp(tp, 0xA438); + break; + } + + return hw_ram_code_ver; +} + +static int +rtl8125_check_hw_phy_mcu_code_ver(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ram_code_ver_match = 0; + + tp->hw_ram_code_ver = rtl8125_get_hw_phy_mcu_code_ver(tp); + + if (tp->hw_ram_code_ver == tp->sw_ram_code_ver) { + ram_code_ver_match = 1; + tp->HwHasWrRamCodeToMicroP = TRUE; + } + + return ram_code_ver_match; +} + +bool +rtl8125_set_phy_mcu_patch_request(struct rtl8125_private *tp) +{ + u16 gphy_val; + u16 WaitCount; + bool bSuccess = TRUE; + + SetEthPhyOcpBit(tp, 0xB820, BIT_4); + + WaitCount = 0; + do { + gphy_val = mdio_direct_read_phy_ocp(tp, 0xB800); + udelay(100); + WaitCount++; + } while (!(gphy_val & BIT_6) && (WaitCount < 1000)); + + if (!(gphy_val & BIT_6) && (WaitCount == 1000)) bSuccess = FALSE; + + if (!bSuccess) + dprintk("rtl8125_set_phy_mcu_patch_request fail.\n"); + + return bSuccess; +} + +bool +rtl8125_clear_phy_mcu_patch_request(struct rtl8125_private *tp) +{ + u16 gphy_val; + u16 WaitCount; + bool bSuccess = TRUE; + + ClearEthPhyOcpBit(tp, 0xB820, BIT_4); + + WaitCount = 0; + do { + gphy_val = mdio_direct_read_phy_ocp(tp, 0xB800); + udelay(100); + WaitCount++; + } while ((gphy_val & BIT_6) && (WaitCount < 1000)); + + if ((gphy_val & BIT_6) && (WaitCount == 1000)) bSuccess = FALSE; + + if (!bSuccess) + dprintk("rtl8125_clear_phy_mcu_patch_request fail.\n"); + + return bSuccess; +} + +#ifndef ENABLE_USE_FIRMWARE_FILE +static void +rtl8125_write_hw_phy_mcu_code_ver(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + mdio_direct_write_phy_ocp(tp, 0xA436, 0x801E); + mdio_direct_write_phy_ocp(tp, 0xA438, tp->sw_ram_code_ver); + tp->hw_ram_code_ver = tp->sw_ram_code_ver; + break; + } +} + +static void +rtl8125_acquire_phy_mcu_patch_key_lock(struct rtl8125_private *tp) +{ + u16 PatchKey; + + switch (tp->mcfg) { + case CFG_METHOD_2: + PatchKey = 0x8600; + break; + case CFG_METHOD_3: + case CFG_METHOD_6: + PatchKey = 0x8601; + break; + case CFG_METHOD_4: + PatchKey = 0x3700; + break; + case CFG_METHOD_5: + case CFG_METHOD_7: + PatchKey = 0x3701; + break; + default: + return; + } + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8024); + mdio_direct_write_phy_ocp(tp, 0xA438, PatchKey); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xB82E); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0001); +} + +static void +rtl8125_release_phy_mcu_patch_key_lock(struct rtl8125_private *tp) +{ + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + mdio_direct_write_phy_ocp(tp, 0xA436, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + ClearEthPhyOcpBit(tp, 0xB82E, BIT_0); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8024); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + break; + default: + break; + } +} + +static void +rtl8125_set_phy_mcu_ram_code(struct net_device *dev, const u16 *ramcode, u16 codesize) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 i; + u16 addr; + u16 val; + + if (ramcode == NULL || codesize % 2) { + goto out; + } + + for (i = 0; i < codesize; i += 2) { + addr = ramcode[i]; + val = ramcode[i + 1]; + if (addr == 0xFFFF && val == 0xFFFF) { + break; + } + mdio_direct_write_phy_ocp(tp, addr, val); + } + +out: + return; +} + +static void +rtl8125_enable_phy_disable_mode(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) | BIT_5); + break; + } + + dprintk("enable phy disable mode.\n"); +} + +static void +rtl8125_disable_phy_disable_mode(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->HwSuppCheckPhyDisableModeVer) { + case 3: + RTL_W8(tp, 0xF2, RTL_R8(tp, 0xF2) & ~BIT_5); + break; + } + + mdelay(1); + + dprintk("disable phy disable mode.\n"); +} + +static void +rtl8125_set_hw_phy_before_init_phy_mcu(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u16 PhyRegValue; + + switch (tp->mcfg) { + case CFG_METHOD_4: + mdio_direct_write_phy_ocp(tp, 0xBF86, 0x9000); + + SetEthPhyOcpBit(tp, 0xC402, BIT_10); + ClearEthPhyOcpBit(tp, 0xC402, BIT_10); + + PhyRegValue = mdio_direct_read_phy_ocp(tp, 0xBF86); + PhyRegValue &= (BIT_1 | BIT_0); + if (PhyRegValue != 0) + dprintk("PHY watch dog not clear, value = 0x%x \n", PhyRegValue); + + mdio_direct_write_phy_ocp(tp, 0xBD86, 0x1010); + mdio_direct_write_phy_ocp(tp, 0xBD88, 0x1010); + + ClearAndSetEthPhyOcpBit(tp, + 0xBD4E, + BIT_11 | BIT_10, + BIT_11); + ClearAndSetEthPhyOcpBit(tp, + 0xBF46, + BIT_11 | BIT_10 | BIT_9 | BIT_8, + BIT_10 | BIT_9 | BIT_8); + break; + } +} + +static void +rtl8125_real_set_phy_mcu_8125a_1(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_acquire_phy_mcu_patch_key_lock(tp); + + + SetEthPhyOcpBit(tp, 0xB820, BIT_7); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA016); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8013); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8021); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x802f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x803d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8042); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8051); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8051); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa088); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a50); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8008); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd1a3); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x401a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd707); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40c2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60a6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f8b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a6c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8080); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd019); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd1a2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x401a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd707); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40c4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60a6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f8b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a84); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8970); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c07); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0901); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcf09); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd705); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xceff); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf0a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1213); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8401); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8580); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1253); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd064); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd181); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4018); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc50f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd706); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2c59); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x804d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc60f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc605); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x10fd); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA026); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA024); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA022); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x10f4); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA020); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1252); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA006); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1206); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA004); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a78); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a60); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a4f); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA008); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3f00); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA016); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0010); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8066); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x807c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8089); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x808e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80b2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80c2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x62db); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x655c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd73e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60e9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x614a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x61ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0505); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0509); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x653c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd73e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60e9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x614a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x61ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0502); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0506); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x050a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd73e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60e9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x614a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x61ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0505); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0506); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x050c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd73e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60e9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x614a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x61ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0509); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x050a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x050c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0508); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0304); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd73e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60e9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x614a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x61ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0321); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0502); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0321); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0321); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0508); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0321); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0346); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8208); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x609d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa50f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x001a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x001a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x607d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00ab); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60fd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa50f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaa0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x017b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a05); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x017b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60fd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa50f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaa0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x01e0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a05); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x01e0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60fd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa50f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaa0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0231); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0503); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a05); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0231); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA08E); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA08C); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0221); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA08A); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x01ce); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA088); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0169); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA086); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00a6); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA084); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x000d); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA082); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0308); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA080); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x029f); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA090); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x007f); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA016); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0020); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8017); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8029); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8054); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x805a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8064); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80a7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9430); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9480); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb408); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd120); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd057); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x064b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcb80); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9906); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0567); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcb94); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x82a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x800a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8406); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8dff); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa840); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0773); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcb91); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4063); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd139); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd140); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd040); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07dc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa110); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa2a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4045); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa180); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x405d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa720); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0742); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07ec); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f74); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0742); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7fb6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x82a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07dc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x064b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07c0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5fa7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0481); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x94bc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x870c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa00a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa280); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8220); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x078e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcb92); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa840); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4063); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd140); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd150); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd040); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd703); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6121); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x61a2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6223); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf02f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d10); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf00f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d20); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf00a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d30); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf005); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d40); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa008); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4046); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x405d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa720); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0742); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07f7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f74); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0742); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7fb5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x800a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3ad4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0537); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8840); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x064b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8301); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x800a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x82a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa70c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9402); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x890c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8840); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x064b); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA10E); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0642); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA10C); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0686); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA10A); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0788); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA108); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x047b); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA106); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x065c); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA104); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0769); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA102); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0565); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA100); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x06f9); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA110); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00ff); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb87c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8530); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb87e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf85); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3caf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8593); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf85); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9caf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x85a5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5afb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe083); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfb0c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x020d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x021b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x10bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86d7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbe0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x83fc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1b10); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xda02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xdd02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5afb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe083); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfd0c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x020d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x021b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x10bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86dd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86e0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbe0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x83fe); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1b10); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf2f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbd02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2cac); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0286); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x65af); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x212b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x022c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86b6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf21); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cd1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x03bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8710); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x870d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8719); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8716); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x871f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x871c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8728); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8725); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8707); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbad); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x281c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd100); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1302); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2202); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2b02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae1a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd101); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1302); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2202); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2b02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd101); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3402); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3102); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3d02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3a02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4302); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4c02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4902); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd100); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2e02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4602); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf87); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4f02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ab7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf35); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7ff8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfaef); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x69bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86e3); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86fb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86e6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86fe); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86e9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86ec); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfbbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x025a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7bf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86ef); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0262); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7cbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86f2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0262); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7cbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86f5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0262); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7cbf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x86f8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0262); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7cef); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x96fe); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfc04); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf8fa); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xef69); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xef02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6273); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf202); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6273); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf502); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6273); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbf86); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf802); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6273); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xef96); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfefc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0420); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb540); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x53b5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4086); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb540); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb9b5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40c8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb03a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc8b0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbac8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb13a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc8b1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xba77); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbd26); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffbd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2677); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbd28); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffbd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2840); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbd26); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc8bd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2640); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbd28); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc8bd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x28bb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa430); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x98b0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1eba); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb01e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xdcb0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1e98); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb09e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbab0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9edc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb09e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x98b1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1eba); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb11e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xdcb1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1e98); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb19e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbab1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9edc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb19e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x11b0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1e22); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb01e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x33b0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1e11); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb09e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x22b0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9e33); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb09e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x11b1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1e22); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb11e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x33b1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1e11); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb19e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x22b1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9e33); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb19e); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb85e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2f71); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb860); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x20d9); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb862); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2109); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb864); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x34e7); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb878); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x000f); + + + ClearEthPhyOcpBit(tp, 0xB820, BIT_7); + + + rtl8125_release_phy_mcu_patch_key_lock(tp); +} + +static void +rtl8125_set_phy_mcu_8125a_1(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_set_phy_mcu_patch_request(tp); + + rtl8125_real_set_phy_mcu_8125a_1(dev); + + rtl8125_clear_phy_mcu_patch_request(tp); +} + +static void +rtl8125_real_set_phy_mcu_8125a_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_acquire_phy_mcu_patch_key_lock(tp); + + + SetEthPhyOcpBit(tp, 0xB820, BIT_7); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA016); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x808b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x808f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8093); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8097); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x809d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80a1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80aa); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x607b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf00e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x42da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf01e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x615b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1456); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14a4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14bc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f2e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf01c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1456); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14a4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14bc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f2e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf024); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1456); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14a4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14bc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f2e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf02c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1456); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14a4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x14bc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f2e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf034); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd719); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4118); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac11); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa410); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4779); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1444); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf034); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd719); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4118); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac22); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa420); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4559); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1444); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf023); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd719); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4118); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac44); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa440); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4339); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1444); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd719); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4118); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac88); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa480); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xce00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4119); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xac0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1444); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf001); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1456); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd718); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5fac); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc48f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x141b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd504); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x121a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd0b4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd1bb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0898); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd0b4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd1bb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a0e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd064); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd18a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0b7e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x401c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd501); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa804); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8804); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x053b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd500); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa301); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0648); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc520); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa201); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x252d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1646); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd708); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4006); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1646); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0308); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA026); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0307); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA024); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1645); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA022); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0647); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA020); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x053a); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA006); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0b7c); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA004); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0a0c); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0896); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x11a1); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA008); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xff00); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA016); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0010); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8015); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x801a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xad02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x02d7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00ed); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0509); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xc100); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x008f); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA08E); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA08C); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA08A); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA088); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA086); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA084); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA082); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x008d); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA080); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00eb); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA090); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0103); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA016); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0020); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA012); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8014); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8018); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8024); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8051); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8055); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8072); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x80dc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfffd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfffd); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8301); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x800a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x82a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa70c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x9402); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x890c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8840); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa380); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x066e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcb91); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4063); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd139); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd140); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd040); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa110); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa2a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4085); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa180); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8280); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x405d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa720); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0743); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07f0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5f74); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0743); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7fb6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x82a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0c0f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x066e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd158); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd04d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x03d4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x94bc); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x870c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8380); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd10d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd040); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07c4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5fb4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa190); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa00a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa280); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa404); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa220); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd130); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd040); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07c4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5fb4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xbb80); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd1c4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd074); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa301); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x604b); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa90c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0556); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xcb92); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4063); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd116); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd119); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd040); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd703); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x60a0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6241); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x63e2); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6583); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf054); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x611e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d10); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf02f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d50); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf02a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x611e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d20); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf021); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d60); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf01c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x611e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d30); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf013); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d70); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf00e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x611e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x40da); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d40); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf005); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d80); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x405d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa720); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd700); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x5ff4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa008); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd704); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x4046); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0743); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07fb); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd703); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7f6f); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7f4e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7f2d); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7f0c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x800a); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0cf0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0d00); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07e8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8010); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa740); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0743); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7fb5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd701); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3ad4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0556); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8610); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x066e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd1f5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xd049); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x1800); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x01ec); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA10E); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x01ea); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA10C); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x06a9); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA10A); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x078a); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA108); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x03d2); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA106); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x067f); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA104); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0665); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA102); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA100); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xA110); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00fc); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb87c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8530); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb87e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf85); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x3caf); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8545); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf85); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x45af); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8545); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xee82); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf900); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0103); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xaf03); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb7f8); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe0a6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00e1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa601); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xef01); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x58f0); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa080); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x37a1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8402); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae16); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa185); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x02ae); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x11a1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8702); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae0c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xa188); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x02ae); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x07a1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8902); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae02); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xae1c); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe0b4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x62e1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb463); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6901); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe4b4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x62e5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb463); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe0b4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x62e1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb463); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6901); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xe4b4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x62e5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xb463); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xfc04); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb85e); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x03b3); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb860); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb862); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb864); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xffff); + mdio_direct_write_phy_ocp(tp, 0xA436, 0xb878); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0001); + + + ClearEthPhyOcpBit(tp, 0xB820, BIT_7); + + + rtl8125_release_phy_mcu_patch_key_lock(tp); +} + +static void +rtl8125_set_phy_mcu_8125a_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_set_phy_mcu_patch_request(tp); + + rtl8125_real_set_phy_mcu_8125a_2(dev); + + rtl8125_clear_phy_mcu_patch_request(tp); +} + +static const u16 phy_mcu_ram_code_8125b_1[] = { + 0xa436, 0x8024, 0xa438, 0x3700, 0xa436, 0xB82E, 0xa438, 0x0001, + 0xb820, 0x0090, 0xa436, 0xA016, 0xa438, 0x0000, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x8025, 0xa438, 0x1800, 0xa438, 0x803a, + 0xa438, 0x1800, 0xa438, 0x8044, 0xa438, 0x1800, 0xa438, 0x8083, + 0xa438, 0x1800, 0xa438, 0x808d, 0xa438, 0x1800, 0xa438, 0x808d, + 0xa438, 0x1800, 0xa438, 0x808d, 0xa438, 0xd712, 0xa438, 0x4077, + 0xa438, 0xd71e, 0xa438, 0x4159, 0xa438, 0xd71e, 0xa438, 0x6099, + 0xa438, 0x7f44, 0xa438, 0x1800, 0xa438, 0x1a14, 0xa438, 0x9040, + 0xa438, 0x9201, 0xa438, 0x1800, 0xa438, 0x1b1a, 0xa438, 0xd71e, + 0xa438, 0x2425, 0xa438, 0x1a14, 0xa438, 0xd71f, 0xa438, 0x3ce5, + 0xa438, 0x1afb, 0xa438, 0x1800, 0xa438, 0x1b00, 0xa438, 0xd712, + 0xa438, 0x4077, 0xa438, 0xd71e, 0xa438, 0x4159, 0xa438, 0xd71e, + 0xa438, 0x60b9, 0xa438, 0x2421, 0xa438, 0x1c17, 0xa438, 0x1800, + 0xa438, 0x1a14, 0xa438, 0x9040, 0xa438, 0x1800, 0xa438, 0x1c2c, + 0xa438, 0xd71e, 0xa438, 0x2425, 0xa438, 0x1a14, 0xa438, 0xd71f, + 0xa438, 0x3ce5, 0xa438, 0x1c0f, 0xa438, 0x1800, 0xa438, 0x1c13, + 0xa438, 0xd702, 0xa438, 0xd501, 0xa438, 0x6072, 0xa438, 0x8401, + 0xa438, 0xf002, 0xa438, 0xa401, 0xa438, 0x1000, 0xa438, 0x146e, + 0xa438, 0x1800, 0xa438, 0x0b77, 0xa438, 0xd703, 0xa438, 0x665d, + 0xa438, 0x653e, 0xa438, 0x641f, 0xa438, 0xd700, 0xa438, 0x62c4, + 0xa438, 0x6185, 0xa438, 0x6066, 0xa438, 0x1800, 0xa438, 0x165a, + 0xa438, 0xc101, 0xa438, 0xcb00, 0xa438, 0x1000, 0xa438, 0x1945, + 0xa438, 0xd700, 0xa438, 0x7fa6, 0xa438, 0x1800, 0xa438, 0x807d, + 0xa438, 0xc102, 0xa438, 0xcb00, 0xa438, 0x1000, 0xa438, 0x1945, + 0xa438, 0xd700, 0xa438, 0x2569, 0xa438, 0x8058, 0xa438, 0x1800, + 0xa438, 0x807d, 0xa438, 0xc104, 0xa438, 0xcb00, 0xa438, 0x1000, + 0xa438, 0x1945, 0xa438, 0xd700, 0xa438, 0x7fa4, 0xa438, 0x1800, + 0xa438, 0x807d, 0xa438, 0xc120, 0xa438, 0xcb00, 0xa438, 0x1000, + 0xa438, 0x1945, 0xa438, 0xd703, 0xa438, 0x7fbf, 0xa438, 0x1800, + 0xa438, 0x807d, 0xa438, 0xc140, 0xa438, 0xcb00, 0xa438, 0x1000, + 0xa438, 0x1945, 0xa438, 0xd703, 0xa438, 0x7fbe, 0xa438, 0x1800, + 0xa438, 0x807d, 0xa438, 0xc180, 0xa438, 0xcb00, 0xa438, 0x1000, + 0xa438, 0x1945, 0xa438, 0xd703, 0xa438, 0x7fbd, 0xa438, 0xc100, + 0xa438, 0xcb00, 0xa438, 0xd708, 0xa438, 0x6018, 0xa438, 0x1800, + 0xa438, 0x165a, 0xa438, 0x1000, 0xa438, 0x14f6, 0xa438, 0xd014, + 0xa438, 0xd1e3, 0xa438, 0x1000, 0xa438, 0x1356, 0xa438, 0xd705, + 0xa438, 0x5fbe, 0xa438, 0x1800, 0xa438, 0x1559, 0xa436, 0xA026, + 0xa438, 0xffff, 0xa436, 0xA024, 0xa438, 0xffff, 0xa436, 0xA022, + 0xa438, 0xffff, 0xa436, 0xA020, 0xa438, 0x1557, 0xa436, 0xA006, + 0xa438, 0x1677, 0xa436, 0xA004, 0xa438, 0x0b75, 0xa436, 0xA002, + 0xa438, 0x1c17, 0xa436, 0xA000, 0xa438, 0x1b04, 0xa436, 0xA008, + 0xa438, 0x1f00, 0xa436, 0xA016, 0xa438, 0x0020, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x817f, 0xa438, 0x1800, 0xa438, 0x82ab, + 0xa438, 0x1800, 0xa438, 0x83f8, 0xa438, 0x1800, 0xa438, 0x8444, + 0xa438, 0x1800, 0xa438, 0x8454, 0xa438, 0x1800, 0xa438, 0x8459, + 0xa438, 0x1800, 0xa438, 0x8465, 0xa438, 0xcb11, 0xa438, 0xa50c, + 0xa438, 0x8310, 0xa438, 0xd701, 0xa438, 0x4076, 0xa438, 0x0c03, + 0xa438, 0x0903, 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, + 0xa438, 0x0d00, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d00, + 0xa438, 0x1000, 0xa438, 0x0a7d, 0xa438, 0x1000, 0xa438, 0x0a4d, + 0xa438, 0xcb12, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x5f84, 0xa438, 0xd102, 0xa438, 0xd040, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xd701, + 0xa438, 0x60f3, 0xa438, 0xd413, 0xa438, 0x1000, 0xa438, 0x0a37, + 0xa438, 0xd410, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0xcb13, + 0xa438, 0xa108, 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8108, + 0xa438, 0xa00a, 0xa438, 0xa910, 0xa438, 0xa780, 0xa438, 0xd14a, + 0xa438, 0xd048, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd701, + 0xa438, 0x6255, 0xa438, 0xd700, 0xa438, 0x5f74, 0xa438, 0x6326, + 0xa438, 0xd702, 0xa438, 0x5f07, 0xa438, 0x800a, 0xa438, 0xa004, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8004, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8001, 0xa438, 0x0c03, + 0xa438, 0x0902, 0xa438, 0xffe2, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x5fab, 0xa438, 0xba08, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f8b, 0xa438, 0x9a08, + 0xa438, 0x800a, 0xa438, 0xd702, 0xa438, 0x6535, 0xa438, 0xd40d, + 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0xcb14, 0xa438, 0xa004, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8004, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8001, 0xa438, 0xa00a, + 0xa438, 0xa780, 0xa438, 0xd14a, 0xa438, 0xd048, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x6206, + 0xa438, 0xd702, 0xa438, 0x5f47, 0xa438, 0x800a, 0xa438, 0xa004, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8004, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8001, 0xa438, 0x0c03, + 0xa438, 0x0902, 0xa438, 0x1800, 0xa438, 0x8064, 0xa438, 0x800a, + 0xa438, 0xd40e, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x7f8c, 0xa438, 0xd701, 0xa438, 0x6073, 0xa438, 0xd701, + 0xa438, 0x4216, 0xa438, 0xa004, 0xa438, 0x1000, 0xa438, 0x0a42, + 0xa438, 0x8004, 0xa438, 0xa001, 0xa438, 0x1000, 0xa438, 0x0a42, + 0xa438, 0x8001, 0xa438, 0xd120, 0xa438, 0xd040, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0x8504, + 0xa438, 0xcb21, 0xa438, 0xa301, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd700, 0xa438, 0x5f9f, 0xa438, 0x8301, 0xa438, 0xd704, + 0xa438, 0x40e0, 0xa438, 0xd196, 0xa438, 0xd04d, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xcb22, + 0xa438, 0x1000, 0xa438, 0x0a6d, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa640, 0xa438, 0x9503, 0xa438, 0x8910, 0xa438, 0x8720, + 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, 0xa438, 0x0d01, + 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d01, 0xa438, 0x1000, + 0xa438, 0x0a7d, 0xa438, 0x0c1f, 0xa438, 0x0f14, 0xa438, 0xcb23, + 0xa438, 0x8fc0, 0xa438, 0x1000, 0xa438, 0x0a25, 0xa438, 0xaf40, + 0xa438, 0x1000, 0xa438, 0x0a25, 0xa438, 0x0cc0, 0xa438, 0x0f80, + 0xa438, 0x1000, 0xa438, 0x0a25, 0xa438, 0xafc0, 0xa438, 0x1000, + 0xa438, 0x0a25, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd701, + 0xa438, 0x5dee, 0xa438, 0xcb24, 0xa438, 0x8f1f, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd701, 0xa438, 0x7f6e, 0xa438, 0xa111, + 0xa438, 0xa215, 0xa438, 0xa401, 0xa438, 0x8404, 0xa438, 0xa720, + 0xa438, 0xcb25, 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x8640, + 0xa438, 0x9503, 0xa438, 0x1000, 0xa438, 0x0b43, 0xa438, 0x1000, + 0xa438, 0x0b86, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x7f8c, 0xa438, 0xcb26, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x5f82, 0xa438, 0x8111, 0xa438, 0x8205, + 0xa438, 0x8404, 0xa438, 0xcb27, 0xa438, 0xd404, 0xa438, 0x1000, + 0xa438, 0x0a37, 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, + 0xa438, 0x0d02, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d02, + 0xa438, 0x1000, 0xa438, 0x0a7d, 0xa438, 0xa710, 0xa438, 0xa104, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8104, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8001, 0xa438, 0xa120, + 0xa438, 0xaa0f, 0xa438, 0x8110, 0xa438, 0xa284, 0xa438, 0xa404, + 0xa438, 0xa00a, 0xa438, 0xd193, 0xa438, 0xd046, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xcb28, + 0xa438, 0xa110, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fa8, 0xa438, 0x8110, 0xa438, 0x8284, 0xa438, 0xa404, + 0xa438, 0x800a, 0xa438, 0x8710, 0xa438, 0xb804, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f82, 0xa438, 0x9804, + 0xa438, 0xcb29, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x5f85, 0xa438, 0xa710, 0xa438, 0xb820, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f65, 0xa438, 0x9820, + 0xa438, 0xcb2a, 0xa438, 0xa190, 0xa438, 0xa284, 0xa438, 0xa404, + 0xa438, 0xa00a, 0xa438, 0xd13d, 0xa438, 0xd04a, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x3444, 0xa438, 0x8149, + 0xa438, 0xa220, 0xa438, 0xd1a0, 0xa438, 0xd040, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x3444, 0xa438, 0x8151, + 0xa438, 0xd702, 0xa438, 0x5f51, 0xa438, 0xcb2f, 0xa438, 0xa302, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd708, 0xa438, 0x5f63, + 0xa438, 0xd411, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0x8302, + 0xa438, 0xd409, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x7f8c, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x5fa3, 0xa438, 0x8190, 0xa438, 0x82a4, 0xa438, 0x8404, + 0xa438, 0x800a, 0xa438, 0xb808, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x7fa3, 0xa438, 0x9808, 0xa438, 0x1800, + 0xa438, 0x0433, 0xa438, 0xcb15, 0xa438, 0xa508, 0xa438, 0xd700, + 0xa438, 0x6083, 0xa438, 0x0c1f, 0xa438, 0x0d01, 0xa438, 0xf003, + 0xa438, 0x0c1f, 0xa438, 0x0d01, 0xa438, 0x1000, 0xa438, 0x0a7d, + 0xa438, 0x1000, 0xa438, 0x0a4d, 0xa438, 0xa301, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5f9f, 0xa438, 0x8301, + 0xa438, 0xd704, 0xa438, 0x40e0, 0xa438, 0xd115, 0xa438, 0xd04f, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0xd413, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0xcb16, + 0xa438, 0x1000, 0xa438, 0x0a6d, 0xa438, 0x0c03, 0xa438, 0x1502, + 0xa438, 0xa640, 0xa438, 0x9503, 0xa438, 0x8720, 0xa438, 0xd17a, + 0xa438, 0xd04c, 0xa438, 0x0c1f, 0xa438, 0x0f14, 0xa438, 0xcb17, + 0xa438, 0x8fc0, 0xa438, 0x1000, 0xa438, 0x0a25, 0xa438, 0xaf40, + 0xa438, 0x1000, 0xa438, 0x0a25, 0xa438, 0x0cc0, 0xa438, 0x0f80, + 0xa438, 0x1000, 0xa438, 0x0a25, 0xa438, 0xafc0, 0xa438, 0x1000, + 0xa438, 0x0a25, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd701, + 0xa438, 0x61ce, 0xa438, 0xd700, 0xa438, 0x5db4, 0xa438, 0xcb18, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x8640, 0xa438, 0x9503, + 0xa438, 0xa720, 0xa438, 0x1000, 0xa438, 0x0b43, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xffd6, 0xa438, 0x8f1f, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd701, 0xa438, 0x7f8e, 0xa438, 0xa131, + 0xa438, 0xaa0f, 0xa438, 0xa2d5, 0xa438, 0xa407, 0xa438, 0xa720, + 0xa438, 0x8310, 0xa438, 0xa308, 0xa438, 0x8308, 0xa438, 0xcb19, + 0xa438, 0x0c03, 0xa438, 0x1502, 0xa438, 0x8640, 0xa438, 0x9503, + 0xa438, 0x1000, 0xa438, 0x0b43, 0xa438, 0x1000, 0xa438, 0x0b86, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xb920, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, 0xa438, 0x9920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f8c, + 0xa438, 0xcb1a, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x5f82, 0xa438, 0x8111, 0xa438, 0x82c5, 0xa438, 0xa404, + 0xa438, 0x8402, 0xa438, 0xb804, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x7f82, 0xa438, 0x9804, 0xa438, 0xcb1b, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5f85, + 0xa438, 0xa710, 0xa438, 0xb820, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x7f65, 0xa438, 0x9820, 0xa438, 0xcb1c, + 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, 0xa438, 0x0d02, + 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d02, 0xa438, 0x1000, + 0xa438, 0x0a7d, 0xa438, 0xa110, 0xa438, 0xa284, 0xa438, 0xa404, + 0xa438, 0x8402, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fa8, 0xa438, 0xcb1d, 0xa438, 0xa180, 0xa438, 0xa402, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fa8, + 0xa438, 0xa220, 0xa438, 0xd1f5, 0xa438, 0xd049, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x3444, 0xa438, 0x8221, + 0xa438, 0xd702, 0xa438, 0x5f51, 0xa438, 0xb920, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, 0xa438, 0x9920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f8c, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fa3, + 0xa438, 0xa504, 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, + 0xa438, 0x0d00, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d00, + 0xa438, 0x1000, 0xa438, 0x0a7d, 0xa438, 0xa00a, 0xa438, 0x8190, + 0xa438, 0x82a4, 0xa438, 0x8402, 0xa438, 0xa404, 0xa438, 0xb808, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7fa3, + 0xa438, 0x9808, 0xa438, 0xcb2b, 0xa438, 0xcb2c, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5f84, 0xa438, 0xd14a, + 0xa438, 0xd048, 0xa438, 0xa780, 0xa438, 0xcb2d, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5f94, 0xa438, 0x6208, + 0xa438, 0xd702, 0xa438, 0x5f27, 0xa438, 0x800a, 0xa438, 0xa004, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8004, 0xa438, 0xa001, + 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8001, 0xa438, 0x0c03, + 0xa438, 0x0902, 0xa438, 0xa00a, 0xa438, 0xffe9, 0xa438, 0xcb2e, + 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, 0xa438, 0x0d02, + 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d02, 0xa438, 0x1000, + 0xa438, 0x0a7d, 0xa438, 0xa190, 0xa438, 0xa284, 0xa438, 0xa406, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fa8, + 0xa438, 0xa220, 0xa438, 0xd1a0, 0xa438, 0xd040, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x3444, 0xa438, 0x827d, + 0xa438, 0xd702, 0xa438, 0x5f51, 0xa438, 0xcb2f, 0xa438, 0xa302, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd708, 0xa438, 0x5f63, + 0xa438, 0xd411, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0x8302, + 0xa438, 0xd409, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x7f8c, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x5fa3, 0xa438, 0x8190, 0xa438, 0x82a4, 0xa438, 0x8406, + 0xa438, 0x800a, 0xa438, 0xb808, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x7fa3, 0xa438, 0x9808, 0xa438, 0x1800, + 0xa438, 0x0433, 0xa438, 0xcb30, 0xa438, 0x8380, 0xa438, 0xcb31, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5f86, + 0xa438, 0x9308, 0xa438, 0xb204, 0xa438, 0xb301, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd701, 0xa438, 0x5fa2, 0xa438, 0xb302, + 0xa438, 0x9204, 0xa438, 0xcb32, 0xa438, 0xd408, 0xa438, 0x1000, + 0xa438, 0x0a37, 0xa438, 0xd141, 0xa438, 0xd043, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xd704, + 0xa438, 0x4ccc, 0xa438, 0xd700, 0xa438, 0x4c81, 0xa438, 0xd702, + 0xa438, 0x609e, 0xa438, 0xd1e5, 0xa438, 0xd04d, 0xa438, 0xf003, + 0xa438, 0xd1e5, 0xa438, 0xd04d, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xd700, 0xa438, 0x6083, + 0xa438, 0x0c1f, 0xa438, 0x0d01, 0xa438, 0xf003, 0xa438, 0x0c1f, + 0xa438, 0x0d01, 0xa438, 0x1000, 0xa438, 0x0a7d, 0xa438, 0x8710, + 0xa438, 0xa108, 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8108, + 0xa438, 0xa203, 0xa438, 0x8120, 0xa438, 0x8a0f, 0xa438, 0xa111, + 0xa438, 0x8204, 0xa438, 0xa140, 0xa438, 0x1000, 0xa438, 0x0a42, + 0xa438, 0x8140, 0xa438, 0xd17a, 0xa438, 0xd04b, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xa204, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fa7, + 0xa438, 0xb920, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x5fac, 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x7f8c, 0xa438, 0xd404, 0xa438, 0x1000, + 0xa438, 0x0a37, 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, + 0xa438, 0x0d02, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d02, + 0xa438, 0x1000, 0xa438, 0x0a7d, 0xa438, 0xa710, 0xa438, 0x8101, + 0xa438, 0x8201, 0xa438, 0xa104, 0xa438, 0x1000, 0xa438, 0x0a42, + 0xa438, 0x8104, 0xa438, 0xa120, 0xa438, 0xaa0f, 0xa438, 0x8110, + 0xa438, 0xa284, 0xa438, 0xa404, 0xa438, 0xa00a, 0xa438, 0xd193, + 0xa438, 0xd047, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0xa110, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd700, 0xa438, 0x5fa8, 0xa438, 0xa180, 0xa438, 0xd13d, + 0xa438, 0xd04a, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0xf024, 0xa438, 0xa710, 0xa438, 0xa00a, + 0xa438, 0x8190, 0xa438, 0x8204, 0xa438, 0xa280, 0xa438, 0xa404, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fa7, + 0xa438, 0x8710, 0xa438, 0xb920, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x5fac, 0xa438, 0x9920, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f8c, 0xa438, 0x800a, + 0xa438, 0x8190, 0xa438, 0x8284, 0xa438, 0x8406, 0xa438, 0xd700, + 0xa438, 0x4121, 0xa438, 0xd701, 0xa438, 0x60f3, 0xa438, 0xd1e5, + 0xa438, 0xd04d, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x8710, 0xa438, 0xa00a, 0xa438, 0x8190, + 0xa438, 0x8204, 0xa438, 0xa280, 0xa438, 0xa404, 0xa438, 0xb920, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x5fac, + 0xa438, 0x9920, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, + 0xa438, 0x7f8c, 0xa438, 0xcb33, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd71f, 0xa438, 0x5f85, 0xa438, 0xa710, 0xa438, 0xb820, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd71f, 0xa438, 0x7f65, + 0xa438, 0x9820, 0xa438, 0xcb34, 0xa438, 0xa00a, 0xa438, 0xa190, + 0xa438, 0xa284, 0xa438, 0xa404, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd700, 0xa438, 0x5fa9, 0xa438, 0xd701, 0xa438, 0x6853, + 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, 0xa438, 0x0d00, + 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d00, 0xa438, 0x1000, + 0xa438, 0x0a7d, 0xa438, 0x8190, 0xa438, 0x8284, 0xa438, 0xcb35, + 0xa438, 0xd407, 0xa438, 0x1000, 0xa438, 0x0a37, 0xa438, 0x8110, + 0xa438, 0x8204, 0xa438, 0xa280, 0xa438, 0xa00a, 0xa438, 0xd704, + 0xa438, 0x4215, 0xa438, 0xa304, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd700, 0xa438, 0x5fb8, 0xa438, 0xd1c3, 0xa438, 0xd043, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0x8304, 0xa438, 0xd700, 0xa438, 0x4109, 0xa438, 0xf01e, + 0xa438, 0xcb36, 0xa438, 0xd412, 0xa438, 0x1000, 0xa438, 0x0a37, + 0xa438, 0xd700, 0xa438, 0x6309, 0xa438, 0xd702, 0xa438, 0x42c7, + 0xa438, 0x800a, 0xa438, 0x8180, 0xa438, 0x8280, 0xa438, 0x8404, + 0xa438, 0xa004, 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8004, + 0xa438, 0xa001, 0xa438, 0x1000, 0xa438, 0x0a42, 0xa438, 0x8001, + 0xa438, 0x0c03, 0xa438, 0x0902, 0xa438, 0xa00a, 0xa438, 0xd14a, + 0xa438, 0xd048, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0xd700, 0xa438, 0x6083, 0xa438, 0x0c1f, + 0xa438, 0x0d02, 0xa438, 0xf003, 0xa438, 0x0c1f, 0xa438, 0x0d02, + 0xa438, 0x1000, 0xa438, 0x0a7d, 0xa438, 0xcc55, 0xa438, 0xcb37, + 0xa438, 0xa00a, 0xa438, 0xa190, 0xa438, 0xa2a4, 0xa438, 0xa404, + 0xa438, 0xd700, 0xa438, 0x6041, 0xa438, 0xa402, 0xa438, 0xd13d, + 0xa438, 0xd04a, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, + 0xa438, 0x5fa9, 0xa438, 0xd702, 0xa438, 0x5f71, 0xa438, 0xcb38, + 0xa438, 0x8224, 0xa438, 0xa288, 0xa438, 0x8180, 0xa438, 0xa110, + 0xa438, 0xa404, 0xa438, 0x800a, 0xa438, 0xd700, 0xa438, 0x6041, + 0xa438, 0x8402, 0xa438, 0xd415, 0xa438, 0x1000, 0xa438, 0x0a37, + 0xa438, 0xd13d, 0xa438, 0xd04a, 0xa438, 0x1000, 0xa438, 0x0a5e, + 0xa438, 0xd700, 0xa438, 0x5fb4, 0xa438, 0xcb39, 0xa438, 0xa00a, + 0xa438, 0xa190, 0xa438, 0xa2a0, 0xa438, 0xa404, 0xa438, 0xd700, + 0xa438, 0x6041, 0xa438, 0xa402, 0xa438, 0xd17a, 0xa438, 0xd047, + 0xa438, 0x1000, 0xa438, 0x0a5e, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0x1800, 0xa438, 0x0560, 0xa438, 0xa111, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0xd3f5, + 0xa438, 0xd219, 0xa438, 0x1000, 0xa438, 0x0c31, 0xa438, 0xd708, + 0xa438, 0x5fa5, 0xa438, 0xa215, 0xa438, 0xd30e, 0xa438, 0xd21a, + 0xa438, 0x1000, 0xa438, 0x0c31, 0xa438, 0xd708, 0xa438, 0x63e9, + 0xa438, 0xd708, 0xa438, 0x5f65, 0xa438, 0xd708, 0xa438, 0x7f36, + 0xa438, 0xa004, 0xa438, 0x1000, 0xa438, 0x0c35, 0xa438, 0x8004, + 0xa438, 0xa001, 0xa438, 0x1000, 0xa438, 0x0c35, 0xa438, 0x8001, + 0xa438, 0xd708, 0xa438, 0x4098, 0xa438, 0xd102, 0xa438, 0x9401, + 0xa438, 0xf003, 0xa438, 0xd103, 0xa438, 0xb401, 0xa438, 0x1000, + 0xa438, 0x0c27, 0xa438, 0xa108, 0xa438, 0x1000, 0xa438, 0x0c35, + 0xa438, 0x8108, 0xa438, 0x8110, 0xa438, 0x8294, 0xa438, 0xa202, + 0xa438, 0x1800, 0xa438, 0x0bdb, 0xa438, 0xd39c, 0xa438, 0xd210, + 0xa438, 0x1000, 0xa438, 0x0c31, 0xa438, 0xd708, 0xa438, 0x5fa5, + 0xa438, 0xd39c, 0xa438, 0xd210, 0xa438, 0x1000, 0xa438, 0x0c31, + 0xa438, 0xd708, 0xa438, 0x5fa5, 0xa438, 0x1000, 0xa438, 0x0c31, + 0xa438, 0xd708, 0xa438, 0x29b5, 0xa438, 0x840e, 0xa438, 0xd708, + 0xa438, 0x5f4a, 0xa438, 0x0c1f, 0xa438, 0x1014, 0xa438, 0x1000, + 0xa438, 0x0c31, 0xa438, 0xd709, 0xa438, 0x7fa4, 0xa438, 0x901f, + 0xa438, 0x1800, 0xa438, 0x0c23, 0xa438, 0xcb43, 0xa438, 0xa508, + 0xa438, 0xd701, 0xa438, 0x3699, 0xa438, 0x844a, 0xa438, 0xa504, + 0xa438, 0xa190, 0xa438, 0xa2a0, 0xa438, 0xa404, 0xa438, 0xa00a, + 0xa438, 0xd700, 0xa438, 0x2109, 0xa438, 0x05ea, 0xa438, 0xa402, + 0xa438, 0x1800, 0xa438, 0x05ea, 0xa438, 0xcb90, 0xa438, 0x0cf0, + 0xa438, 0x0ca0, 0xa438, 0x1800, 0xa438, 0x06db, 0xa438, 0xd1ff, + 0xa438, 0xd052, 0xa438, 0xa508, 0xa438, 0x8718, 0xa438, 0xa00a, + 0xa438, 0xa190, 0xa438, 0xa2a0, 0xa438, 0xa404, 0xa438, 0x0cf0, + 0xa438, 0x0c50, 0xa438, 0x1800, 0xa438, 0x09ef, 0xa438, 0x1000, + 0xa438, 0x0a5e, 0xa438, 0xd704, 0xa438, 0x2e70, 0xa438, 0x06da, + 0xa438, 0xd700, 0xa438, 0x5f55, 0xa438, 0xa90c, 0xa438, 0x1800, + 0xa438, 0x0645, 0xa436, 0xA10E, 0xa438, 0x0644, 0xa436, 0xA10C, + 0xa438, 0x09e9, 0xa436, 0xA10A, 0xa438, 0x06da, 0xa436, 0xA108, + 0xa438, 0x05e1, 0xa436, 0xA106, 0xa438, 0x0be4, 0xa436, 0xA104, + 0xa438, 0x0435, 0xa436, 0xA102, 0xa438, 0x0141, 0xa436, 0xA100, + 0xa438, 0x026d, 0xa436, 0xA110, 0xa438, 0x00ff, 0xa436, 0xb87c, + 0xa438, 0x85fe, 0xa436, 0xb87e, 0xa438, 0xaf86, 0xa438, 0x16af, + 0xa438, 0x8699, 0xa438, 0xaf86, 0xa438, 0xe5af, 0xa438, 0x86f9, + 0xa438, 0xaf87, 0xa438, 0x7aaf, 0xa438, 0x883a, 0xa438, 0xaf88, + 0xa438, 0x58af, 0xa438, 0x8b6c, 0xa438, 0xd48b, 0xa438, 0x7c02, + 0xa438, 0x8644, 0xa438, 0x2c00, 0xa438, 0x503c, 0xa438, 0xffd6, + 0xa438, 0xac27, 0xa438, 0x18e1, 0xa438, 0x82fe, 0xa438, 0xad28, + 0xa438, 0x0cd4, 0xa438, 0x8b84, 0xa438, 0x0286, 0xa438, 0x442c, + 0xa438, 0x003c, 0xa438, 0xac27, 0xa438, 0x06ee, 0xa438, 0x8299, + 0xa438, 0x01ae, 0xa438, 0x04ee, 0xa438, 0x8299, 0xa438, 0x00af, + 0xa438, 0x23dc, 0xa438, 0xf9fa, 0xa438, 0xcefa, 0xa438, 0xfbef, + 0xa438, 0x79fb, 0xa438, 0xc4bf, 0xa438, 0x8b76, 0xa438, 0x026c, + 0xa438, 0x6dac, 0xa438, 0x2804, 0xa438, 0xd203, 0xa438, 0xae02, + 0xa438, 0xd201, 0xa438, 0xbdd8, 0xa438, 0x19d9, 0xa438, 0xef94, + 0xa438, 0x026c, 0xa438, 0x6d78, 0xa438, 0x03ef, 0xa438, 0x648a, + 0xa438, 0x0002, 0xa438, 0xbdd8, 0xa438, 0x19d9, 0xa438, 0xef94, + 0xa438, 0x026c, 0xa438, 0x6d78, 0xa438, 0x03ef, 0xa438, 0x7402, + 0xa438, 0x72cd, 0xa438, 0xac50, 0xa438, 0x02ef, 0xa438, 0x643a, + 0xa438, 0x019f, 0xa438, 0xe4ef, 0xa438, 0x4678, 0xa438, 0x03ac, + 0xa438, 0x2002, 0xa438, 0xae02, 0xa438, 0xd0ff, 0xa438, 0xffef, + 0xa438, 0x97ff, 0xa438, 0xfec6, 0xa438, 0xfefd, 0xa438, 0x041f, + 0xa438, 0x771f, 0xa438, 0x221c, 0xa438, 0x450d, 0xa438, 0x481f, + 0xa438, 0x00ac, 0xa438, 0x7f04, 0xa438, 0x1a94, 0xa438, 0xae08, + 0xa438, 0x1a94, 0xa438, 0xac7f, 0xa438, 0x03d7, 0xa438, 0x0100, + 0xa438, 0xef46, 0xa438, 0x0d48, 0xa438, 0x1f00, 0xa438, 0x1c45, + 0xa438, 0xef69, 0xa438, 0xef57, 0xa438, 0xef74, 0xa438, 0x0272, + 0xa438, 0xe8a7, 0xa438, 0xffff, 0xa438, 0x0d1a, 0xa438, 0x941b, + 0xa438, 0x979e, 0xa438, 0x072d, 0xa438, 0x0100, 0xa438, 0x1a64, + 0xa438, 0xef76, 0xa438, 0xef97, 0xa438, 0x0d98, 0xa438, 0xd400, + 0xa438, 0xff1d, 0xa438, 0x941a, 0xa438, 0x89cf, 0xa438, 0x1a75, + 0xa438, 0xaf74, 0xa438, 0xf9bf, 0xa438, 0x8b79, 0xa438, 0x026c, + 0xa438, 0x6da1, 0xa438, 0x0005, 0xa438, 0xe180, 0xa438, 0xa0ae, + 0xa438, 0x03e1, 0xa438, 0x80a1, 0xa438, 0xaf26, 0xa438, 0x9aac, + 0xa438, 0x284d, 0xa438, 0xe08f, 0xa438, 0xffef, 0xa438, 0x10c0, + 0xa438, 0xe08f, 0xa438, 0xfe10, 0xa438, 0x1b08, 0xa438, 0xa000, + 0xa438, 0x04c8, 0xa438, 0xaf40, 0xa438, 0x67c8, 0xa438, 0xbf8b, + 0xa438, 0x8c02, 0xa438, 0x6c4e, 0xa438, 0xc4bf, 0xa438, 0x8b8f, + 0xa438, 0x026c, 0xa438, 0x6def, 0xa438, 0x74e0, 0xa438, 0x830c, + 0xa438, 0xad20, 0xa438, 0x0302, 0xa438, 0x74ac, 0xa438, 0xccef, + 0xa438, 0x971b, 0xa438, 0x76ad, 0xa438, 0x5f02, 0xa438, 0xae13, + 0xa438, 0xef69, 0xa438, 0xef30, 0xa438, 0x1b32, 0xa438, 0xc4ef, + 0xa438, 0x46e4, 0xa438, 0x8ffb, 0xa438, 0xe58f, 0xa438, 0xfce7, + 0xa438, 0x8ffd, 0xa438, 0xcc10, 0xa438, 0x11ae, 0xa438, 0xb8d1, + 0xa438, 0x00a1, 0xa438, 0x1f03, 0xa438, 0xaf40, 0xa438, 0x4fbf, + 0xa438, 0x8b8c, 0xa438, 0x026c, 0xa438, 0x4ec4, 0xa438, 0xbf8b, + 0xa438, 0x8f02, 0xa438, 0x6c6d, 0xa438, 0xef74, 0xa438, 0xe083, + 0xa438, 0x0cad, 0xa438, 0x2003, 0xa438, 0x0274, 0xa438, 0xaccc, + 0xa438, 0xef97, 0xa438, 0x1b76, 0xa438, 0xad5f, 0xa438, 0x02ae, + 0xa438, 0x04ef, 0xa438, 0x69ef, 0xa438, 0x3111, 0xa438, 0xaed1, + 0xa438, 0x0287, 0xa438, 0x80af, 0xa438, 0x2293, 0xa438, 0xf8f9, + 0xa438, 0xfafb, 0xa438, 0xef59, 0xa438, 0xe080, 0xa438, 0x13ad, + 0xa438, 0x252f, 0xa438, 0xbf88, 0xa438, 0x2802, 0xa438, 0x6c6d, + 0xa438, 0xef64, 0xa438, 0x1f44, 0xa438, 0xe18f, 0xa438, 0xb91b, + 0xa438, 0x64ad, 0xa438, 0x4f1d, 0xa438, 0xd688, 0xa438, 0x2bd7, + 0xa438, 0x882e, 0xa438, 0x0274, 0xa438, 0x73ad, 0xa438, 0x5008, + 0xa438, 0xbf88, 0xa438, 0x3102, 0xa438, 0x737c, 0xa438, 0xae03, + 0xa438, 0x0287, 0xa438, 0xd0bf, 0xa438, 0x882b, 0xa438, 0x0273, + 0xa438, 0x73e0, 0xa438, 0x824c, 0xa438, 0xf621, 0xa438, 0xe482, + 0xa438, 0x4cbf, 0xa438, 0x8834, 0xa438, 0x0273, 0xa438, 0x7cef, + 0xa438, 0x95ff, 0xa438, 0xfefd, 0xa438, 0xfc04, 0xa438, 0xf8f9, + 0xa438, 0xfafb, 0xa438, 0xef79, 0xa438, 0xbf88, 0xa438, 0x1f02, + 0xa438, 0x737c, 0xa438, 0x1f22, 0xa438, 0xac32, 0xa438, 0x31ef, + 0xa438, 0x12bf, 0xa438, 0x8822, 0xa438, 0x026c, 0xa438, 0x4ed6, + 0xa438, 0x8fba, 0xa438, 0x1f33, 0xa438, 0xac3c, 0xa438, 0x1eef, + 0xa438, 0x13bf, 0xa438, 0x8837, 0xa438, 0x026c, 0xa438, 0x4eef, + 0xa438, 0x96d8, 0xa438, 0x19d9, 0xa438, 0xbf88, 0xa438, 0x2502, + 0xa438, 0x6c4e, 0xa438, 0xbf88, 0xa438, 0x2502, 0xa438, 0x6c4e, + 0xa438, 0x1616, 0xa438, 0x13ae, 0xa438, 0xdf12, 0xa438, 0xaecc, + 0xa438, 0xbf88, 0xa438, 0x1f02, 0xa438, 0x7373, 0xa438, 0xef97, + 0xa438, 0xfffe, 0xa438, 0xfdfc, 0xa438, 0x0466, 0xa438, 0xac88, + 0xa438, 0x54ac, 0xa438, 0x88f0, 0xa438, 0xac8a, 0xa438, 0x92ac, + 0xa438, 0xbadd, 0xa438, 0xac6c, 0xa438, 0xeeac, 0xa438, 0x6cff, + 0xa438, 0xad02, 0xa438, 0x99ac, 0xa438, 0x0030, 0xa438, 0xac88, + 0xa438, 0xd4c3, 0xa438, 0x5000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x0000, + 0xa438, 0x0000, 0xa438, 0x0000, 0xa438, 0x00b4, 0xa438, 0xecee, + 0xa438, 0x8298, 0xa438, 0x00af, 0xa438, 0x1412, 0xa438, 0xf8bf, + 0xa438, 0x8b5d, 0xa438, 0x026c, 0xa438, 0x6d58, 0xa438, 0x03e1, + 0xa438, 0x8fb8, 0xa438, 0x2901, 0xa438, 0xe58f, 0xa438, 0xb8a0, + 0xa438, 0x0049, 0xa438, 0xef47, 0xa438, 0xe483, 0xa438, 0x02e5, + 0xa438, 0x8303, 0xa438, 0xbfc2, 0xa438, 0x5f1a, 0xa438, 0x95f7, + 0xa438, 0x05ee, 0xa438, 0xffd2, 0xa438, 0x00d8, 0xa438, 0xf605, + 0xa438, 0x1f11, 0xa438, 0xef60, 0xa438, 0xbf8b, 0xa438, 0x3002, + 0xa438, 0x6c4e, 0xa438, 0xbf8b, 0xa438, 0x3302, 0xa438, 0x6c6d, + 0xa438, 0xf728, 0xa438, 0xbf8b, 0xa438, 0x3302, 0xa438, 0x6c4e, + 0xa438, 0xf628, 0xa438, 0xbf8b, 0xa438, 0x3302, 0xa438, 0x6c4e, + 0xa438, 0x0c64, 0xa438, 0xef46, 0xa438, 0xbf8b, 0xa438, 0x6002, + 0xa438, 0x6c4e, 0xa438, 0x0289, 0xa438, 0x9902, 0xa438, 0x3920, + 0xa438, 0xaf89, 0xa438, 0x96a0, 0xa438, 0x0149, 0xa438, 0xef47, + 0xa438, 0xe483, 0xa438, 0x04e5, 0xa438, 0x8305, 0xa438, 0xbfc2, + 0xa438, 0x5f1a, 0xa438, 0x95f7, 0xa438, 0x05ee, 0xa438, 0xffd2, + 0xa438, 0x00d8, 0xa438, 0xf605, 0xa438, 0x1f11, 0xa438, 0xef60, + 0xa438, 0xbf8b, 0xa438, 0x3002, 0xa438, 0x6c4e, 0xa438, 0xbf8b, + 0xa438, 0x3302, 0xa438, 0x6c6d, 0xa438, 0xf729, 0xa438, 0xbf8b, + 0xa438, 0x3302, 0xa438, 0x6c4e, 0xa438, 0xf629, 0xa438, 0xbf8b, + 0xa438, 0x3302, 0xa438, 0x6c4e, 0xa438, 0x0c64, 0xa438, 0xef46, + 0xa438, 0xbf8b, 0xa438, 0x6302, 0xa438, 0x6c4e, 0xa438, 0x0289, + 0xa438, 0x9902, 0xa438, 0x3920, 0xa438, 0xaf89, 0xa438, 0x96a0, + 0xa438, 0x0249, 0xa438, 0xef47, 0xa438, 0xe483, 0xa438, 0x06e5, + 0xa438, 0x8307, 0xa438, 0xbfc2, 0xa438, 0x5f1a, 0xa438, 0x95f7, + 0xa438, 0x05ee, 0xa438, 0xffd2, 0xa438, 0x00d8, 0xa438, 0xf605, + 0xa438, 0x1f11, 0xa438, 0xef60, 0xa438, 0xbf8b, 0xa438, 0x3002, + 0xa438, 0x6c4e, 0xa438, 0xbf8b, 0xa438, 0x3302, 0xa438, 0x6c6d, + 0xa438, 0xf72a, 0xa438, 0xbf8b, 0xa438, 0x3302, 0xa438, 0x6c4e, + 0xa438, 0xf62a, 0xa438, 0xbf8b, 0xa438, 0x3302, 0xa438, 0x6c4e, + 0xa438, 0x0c64, 0xa438, 0xef46, 0xa438, 0xbf8b, 0xa438, 0x6602, + 0xa438, 0x6c4e, 0xa438, 0x0289, 0xa438, 0x9902, 0xa438, 0x3920, + 0xa438, 0xaf89, 0xa438, 0x96ef, 0xa438, 0x47e4, 0xa438, 0x8308, + 0xa438, 0xe583, 0xa438, 0x09bf, 0xa438, 0xc25f, 0xa438, 0x1a95, + 0xa438, 0xf705, 0xa438, 0xeeff, 0xa438, 0xd200, 0xa438, 0xd8f6, + 0xa438, 0x051f, 0xa438, 0x11ef, 0xa438, 0x60bf, 0xa438, 0x8b30, + 0xa438, 0x026c, 0xa438, 0x4ebf, 0xa438, 0x8b33, 0xa438, 0x026c, + 0xa438, 0x6df7, 0xa438, 0x2bbf, 0xa438, 0x8b33, 0xa438, 0x026c, + 0xa438, 0x4ef6, 0xa438, 0x2bbf, 0xa438, 0x8b33, 0xa438, 0x026c, + 0xa438, 0x4e0c, 0xa438, 0x64ef, 0xa438, 0x46bf, 0xa438, 0x8b69, + 0xa438, 0x026c, 0xa438, 0x4e02, 0xa438, 0x8999, 0xa438, 0x0239, + 0xa438, 0x20af, 0xa438, 0x8996, 0xa438, 0xaf39, 0xa438, 0x1ef8, + 0xa438, 0xf9fa, 0xa438, 0xe08f, 0xa438, 0xb838, 0xa438, 0x02ad, + 0xa438, 0x2702, 0xa438, 0xae03, 0xa438, 0xaf8b, 0xa438, 0x201f, + 0xa438, 0x66ef, 0xa438, 0x65bf, 0xa438, 0xc21f, 0xa438, 0x1a96, + 0xa438, 0xf705, 0xa438, 0xeeff, 0xa438, 0xd200, 0xa438, 0xdaf6, + 0xa438, 0x05bf, 0xa438, 0xc22f, 0xa438, 0x1a96, 0xa438, 0xf705, + 0xa438, 0xeeff, 0xa438, 0xd200, 0xa438, 0xdbf6, 0xa438, 0x05ef, + 0xa438, 0x021f, 0xa438, 0x110d, 0xa438, 0x42bf, 0xa438, 0x8b3c, + 0xa438, 0x026c, 0xa438, 0x4eef, 0xa438, 0x021b, 0xa438, 0x031f, + 0xa438, 0x110d, 0xa438, 0x42bf, 0xa438, 0x8b36, 0xa438, 0x026c, + 0xa438, 0x4eef, 0xa438, 0x021a, 0xa438, 0x031f, 0xa438, 0x110d, + 0xa438, 0x42bf, 0xa438, 0x8b39, 0xa438, 0x026c, 0xa438, 0x4ebf, + 0xa438, 0xc23f, 0xa438, 0x1a96, 0xa438, 0xf705, 0xa438, 0xeeff, + 0xa438, 0xd200, 0xa438, 0xdaf6, 0xa438, 0x05bf, 0xa438, 0xc24f, + 0xa438, 0x1a96, 0xa438, 0xf705, 0xa438, 0xeeff, 0xa438, 0xd200, + 0xa438, 0xdbf6, 0xa438, 0x05ef, 0xa438, 0x021f, 0xa438, 0x110d, + 0xa438, 0x42bf, 0xa438, 0x8b45, 0xa438, 0x026c, 0xa438, 0x4eef, + 0xa438, 0x021b, 0xa438, 0x031f, 0xa438, 0x110d, 0xa438, 0x42bf, + 0xa438, 0x8b3f, 0xa438, 0x026c, 0xa438, 0x4eef, 0xa438, 0x021a, + 0xa438, 0x031f, 0xa438, 0x110d, 0xa438, 0x42bf, 0xa438, 0x8b42, + 0xa438, 0x026c, 0xa438, 0x4eef, 0xa438, 0x56d0, 0xa438, 0x201f, + 0xa438, 0x11bf, 0xa438, 0x8b4e, 0xa438, 0x026c, 0xa438, 0x4ebf, + 0xa438, 0x8b48, 0xa438, 0x026c, 0xa438, 0x4ebf, 0xa438, 0x8b4b, + 0xa438, 0x026c, 0xa438, 0x4ee1, 0xa438, 0x8578, 0xa438, 0xef03, + 0xa438, 0x480a, 0xa438, 0x2805, 0xa438, 0xef20, 0xa438, 0x1b01, + 0xa438, 0xad27, 0xa438, 0x3f1f, 0xa438, 0x44e0, 0xa438, 0x8560, + 0xa438, 0xe185, 0xa438, 0x61bf, 0xa438, 0x8b51, 0xa438, 0x026c, + 0xa438, 0x4ee0, 0xa438, 0x8566, 0xa438, 0xe185, 0xa438, 0x67bf, + 0xa438, 0x8b54, 0xa438, 0x026c, 0xa438, 0x4ee0, 0xa438, 0x856c, + 0xa438, 0xe185, 0xa438, 0x6dbf, 0xa438, 0x8b57, 0xa438, 0x026c, + 0xa438, 0x4ee0, 0xa438, 0x8572, 0xa438, 0xe185, 0xa438, 0x73bf, + 0xa438, 0x8b5a, 0xa438, 0x026c, 0xa438, 0x4ee1, 0xa438, 0x8fb8, + 0xa438, 0x5900, 0xa438, 0xf728, 0xa438, 0xe58f, 0xa438, 0xb8af, + 0xa438, 0x8b2c, 0xa438, 0xe185, 0xa438, 0x791b, 0xa438, 0x21ad, + 0xa438, 0x373e, 0xa438, 0x1f44, 0xa438, 0xe085, 0xa438, 0x62e1, + 0xa438, 0x8563, 0xa438, 0xbf8b, 0xa438, 0x5102, 0xa438, 0x6c4e, + 0xa438, 0xe085, 0xa438, 0x68e1, 0xa438, 0x8569, 0xa438, 0xbf8b, + 0xa438, 0x5402, 0xa438, 0x6c4e, 0xa438, 0xe085, 0xa438, 0x6ee1, + 0xa438, 0x856f, 0xa438, 0xbf8b, 0xa438, 0x5702, 0xa438, 0x6c4e, + 0xa438, 0xe085, 0xa438, 0x74e1, 0xa438, 0x8575, 0xa438, 0xbf8b, + 0xa438, 0x5a02, 0xa438, 0x6c4e, 0xa438, 0xe18f, 0xa438, 0xb859, + 0xa438, 0x00f7, 0xa438, 0x28e5, 0xa438, 0x8fb8, 0xa438, 0xae4a, + 0xa438, 0x1f44, 0xa438, 0xe085, 0xa438, 0x64e1, 0xa438, 0x8565, + 0xa438, 0xbf8b, 0xa438, 0x5102, 0xa438, 0x6c4e, 0xa438, 0xe085, + 0xa438, 0x6ae1, 0xa438, 0x856b, 0xa438, 0xbf8b, 0xa438, 0x5402, + 0xa438, 0x6c4e, 0xa438, 0xe085, 0xa438, 0x70e1, 0xa438, 0x8571, + 0xa438, 0xbf8b, 0xa438, 0x5702, 0xa438, 0x6c4e, 0xa438, 0xe085, + 0xa438, 0x76e1, 0xa438, 0x8577, 0xa438, 0xbf8b, 0xa438, 0x5a02, + 0xa438, 0x6c4e, 0xa438, 0xe18f, 0xa438, 0xb859, 0xa438, 0x00f7, + 0xa438, 0x28e5, 0xa438, 0x8fb8, 0xa438, 0xae0c, 0xa438, 0xe18f, + 0xa438, 0xb839, 0xa438, 0x04ac, 0xa438, 0x2f04, 0xa438, 0xee8f, + 0xa438, 0xb800, 0xa438, 0xfefd, 0xa438, 0xfc04, 0xa438, 0xf0ac, + 0xa438, 0x8efc, 0xa438, 0xac8c, 0xa438, 0xf0ac, 0xa438, 0xfaf0, + 0xa438, 0xacf8, 0xa438, 0xf0ac, 0xa438, 0xf6f0, 0xa438, 0xad00, + 0xa438, 0xf0ac, 0xa438, 0xfef0, 0xa438, 0xacfc, 0xa438, 0xf0ac, + 0xa438, 0xf4f0, 0xa438, 0xacf2, 0xa438, 0xf0ac, 0xa438, 0xf0f0, + 0xa438, 0xacb0, 0xa438, 0xf0ac, 0xa438, 0xaef0, 0xa438, 0xacac, + 0xa438, 0xf0ac, 0xa438, 0xaaf0, 0xa438, 0xacee, 0xa438, 0xf0b0, + 0xa438, 0x24f0, 0xa438, 0xb0a4, 0xa438, 0xf0b1, 0xa438, 0x24f0, + 0xa438, 0xb1a4, 0xa438, 0xee8f, 0xa438, 0xb800, 0xa438, 0xd400, + 0xa438, 0x00af, 0xa438, 0x3976, 0xa438, 0x66ac, 0xa438, 0xeabb, + 0xa438, 0xa430, 0xa438, 0x6e50, 0xa438, 0x6e53, 0xa438, 0x6e56, + 0xa438, 0x6e59, 0xa438, 0x6e5c, 0xa438, 0x6e5f, 0xa438, 0x6e62, + 0xa438, 0x6e65, 0xa438, 0xd9ac, 0xa438, 0x70f0, 0xa438, 0xac6a, + 0xa436, 0xb85e, 0xa438, 0x23b7, 0xa436, 0xb860, 0xa438, 0x74db, + 0xa436, 0xb862, 0xa438, 0x268c, 0xa436, 0xb864, 0xa438, 0x3FE5, + 0xa436, 0xb886, 0xa438, 0x2250, 0xa436, 0xb888, 0xa438, 0x140e, + 0xa436, 0xb88a, 0xa438, 0x3696, 0xa436, 0xb88c, 0xa438, 0x3973, + 0xa436, 0xb838, 0xa438, 0x00ff, 0xb820, 0x0010, 0xa436, 0x8464, + 0xa438, 0xaf84, 0xa438, 0x7caf, 0xa438, 0x8485, 0xa438, 0xaf85, + 0xa438, 0x13af, 0xa438, 0x851e, 0xa438, 0xaf85, 0xa438, 0xb9af, + 0xa438, 0x8684, 0xa438, 0xaf87, 0xa438, 0x01af, 0xa438, 0x8701, + 0xa438, 0xac38, 0xa438, 0x03af, 0xa438, 0x38bb, 0xa438, 0xaf38, + 0xa438, 0xc302, 0xa438, 0x4618, 0xa438, 0xbf85, 0xa438, 0x0a02, + 0xa438, 0x54b7, 0xa438, 0xbf85, 0xa438, 0x1002, 0xa438, 0x54c0, + 0xa438, 0xd400, 0xa438, 0x0fbf, 0xa438, 0x8507, 0xa438, 0x024f, + 0xa438, 0x48bf, 0xa438, 0x8504, 0xa438, 0x024f, 0xa438, 0x6759, + 0xa438, 0xf0a1, 0xa438, 0x3008, 0xa438, 0xbf85, 0xa438, 0x0d02, + 0xa438, 0x54c0, 0xa438, 0xae06, 0xa438, 0xbf85, 0xa438, 0x0d02, + 0xa438, 0x54b7, 0xa438, 0xbf85, 0xa438, 0x0402, 0xa438, 0x4f67, + 0xa438, 0xa183, 0xa438, 0x02ae, 0xa438, 0x15a1, 0xa438, 0x8502, + 0xa438, 0xae10, 0xa438, 0x59f0, 0xa438, 0xa180, 0xa438, 0x16bf, + 0xa438, 0x8501, 0xa438, 0x024f, 0xa438, 0x67a1, 0xa438, 0x381b, + 0xa438, 0xae0b, 0xa438, 0xe18f, 0xa438, 0xffbf, 0xa438, 0x84fe, + 0xa438, 0x024f, 0xa438, 0x48ae, 0xa438, 0x17bf, 0xa438, 0x84fe, + 0xa438, 0x0254, 0xa438, 0xb7bf, 0xa438, 0x84fb, 0xa438, 0x0254, + 0xa438, 0xb7ae, 0xa438, 0x09a1, 0xa438, 0x5006, 0xa438, 0xbf84, + 0xa438, 0xfb02, 0xa438, 0x54c0, 0xa438, 0xaf04, 0xa438, 0x4700, + 0xa438, 0xad34, 0xa438, 0xfdad, 0xa438, 0x0670, 0xa438, 0xae14, + 0xa438, 0xf0a6, 0xa438, 0x00b8, 0xa438, 0xbd32, 0xa438, 0x30bd, + 0xa438, 0x30aa, 0xa438, 0xbd2c, 0xa438, 0xccbd, 0xa438, 0x2ca1, + 0xa438, 0x0705, 0xa438, 0xec80, 0xa438, 0xaf40, 0xa438, 0xf7af, + 0xa438, 0x40f5, 0xa438, 0xd101, 0xa438, 0xbf85, 0xa438, 0xa402, + 0xa438, 0x4f48, 0xa438, 0xbf85, 0xa438, 0xa702, 0xa438, 0x54c0, + 0xa438, 0xd10f, 0xa438, 0xbf85, 0xa438, 0xaa02, 0xa438, 0x4f48, + 0xa438, 0x024d, 0xa438, 0x6abf, 0xa438, 0x85ad, 0xa438, 0x024f, + 0xa438, 0x67bf, 0xa438, 0x8ff7, 0xa438, 0xddbf, 0xa438, 0x85b0, + 0xa438, 0x024f, 0xa438, 0x67bf, 0xa438, 0x8ff8, 0xa438, 0xddbf, + 0xa438, 0x85b3, 0xa438, 0x024f, 0xa438, 0x67bf, 0xa438, 0x8ff9, + 0xa438, 0xddbf, 0xa438, 0x85b6, 0xa438, 0x024f, 0xa438, 0x67bf, + 0xa438, 0x8ffa, 0xa438, 0xddd1, 0xa438, 0x00bf, 0xa438, 0x85aa, + 0xa438, 0x024f, 0xa438, 0x4802, 0xa438, 0x4d6a, 0xa438, 0xbf85, + 0xa438, 0xad02, 0xa438, 0x4f67, 0xa438, 0xbf8f, 0xa438, 0xfbdd, + 0xa438, 0xbf85, 0xa438, 0xb002, 0xa438, 0x4f67, 0xa438, 0xbf8f, + 0xa438, 0xfcdd, 0xa438, 0xbf85, 0xa438, 0xb302, 0xa438, 0x4f67, + 0xa438, 0xbf8f, 0xa438, 0xfddd, 0xa438, 0xbf85, 0xa438, 0xb602, + 0xa438, 0x4f67, 0xa438, 0xbf8f, 0xa438, 0xfedd, 0xa438, 0xbf85, + 0xa438, 0xa702, 0xa438, 0x54b7, 0xa438, 0xbf85, 0xa438, 0xa102, + 0xa438, 0x54b7, 0xa438, 0xaf3c, 0xa438, 0x2066, 0xa438, 0xb800, + 0xa438, 0xb8bd, 0xa438, 0x30ee, 0xa438, 0xbd2c, 0xa438, 0xb8bd, + 0xa438, 0x7040, 0xa438, 0xbd86, 0xa438, 0xc8bd, 0xa438, 0x8640, + 0xa438, 0xbd88, 0xa438, 0xc8bd, 0xa438, 0x8802, 0xa438, 0x1929, + 0xa438, 0xa202, 0xa438, 0x02ae, 0xa438, 0x03a2, 0xa438, 0x032e, + 0xa438, 0xd10f, 0xa438, 0xbf85, 0xa438, 0xaa02, 0xa438, 0x4f48, + 0xa438, 0xe18f, 0xa438, 0xf7bf, 0xa438, 0x85ad, 0xa438, 0x024f, + 0xa438, 0x48e1, 0xa438, 0x8ff8, 0xa438, 0xbf85, 0xa438, 0xb002, + 0xa438, 0x4f48, 0xa438, 0xe18f, 0xa438, 0xf9bf, 0xa438, 0x85b3, + 0xa438, 0x024f, 0xa438, 0x48e1, 0xa438, 0x8ffa, 0xa438, 0xbf85, + 0xa438, 0xb602, 0xa438, 0x4f48, 0xa438, 0xae2c, 0xa438, 0xd100, + 0xa438, 0xbf85, 0xa438, 0xaa02, 0xa438, 0x4f48, 0xa438, 0xe18f, + 0xa438, 0xfbbf, 0xa438, 0x85ad, 0xa438, 0x024f, 0xa438, 0x48e1, + 0xa438, 0x8ffc, 0xa438, 0xbf85, 0xa438, 0xb002, 0xa438, 0x4f48, + 0xa438, 0xe18f, 0xa438, 0xfdbf, 0xa438, 0x85b3, 0xa438, 0x024f, + 0xa438, 0x48e1, 0xa438, 0x8ffe, 0xa438, 0xbf85, 0xa438, 0xb602, + 0xa438, 0x4f48, 0xa438, 0xbf86, 0xa438, 0x7e02, 0xa438, 0x4f67, + 0xa438, 0xa100, 0xa438, 0x02ae, 0xa438, 0x25a1, 0xa438, 0x041d, + 0xa438, 0xe18f, 0xa438, 0xf1bf, 0xa438, 0x8675, 0xa438, 0x024f, + 0xa438, 0x48e1, 0xa438, 0x8ff2, 0xa438, 0xbf86, 0xa438, 0x7802, + 0xa438, 0x4f48, 0xa438, 0xe18f, 0xa438, 0xf3bf, 0xa438, 0x867b, + 0xa438, 0x024f, 0xa438, 0x48ae, 0xa438, 0x29a1, 0xa438, 0x070b, + 0xa438, 0xae24, 0xa438, 0xbf86, 0xa438, 0x8102, 0xa438, 0x4f67, + 0xa438, 0xad28, 0xa438, 0x1be1, 0xa438, 0x8ff4, 0xa438, 0xbf86, + 0xa438, 0x7502, 0xa438, 0x4f48, 0xa438, 0xe18f, 0xa438, 0xf5bf, + 0xa438, 0x8678, 0xa438, 0x024f, 0xa438, 0x48e1, 0xa438, 0x8ff6, + 0xa438, 0xbf86, 0xa438, 0x7b02, 0xa438, 0x4f48, 0xa438, 0xaf09, + 0xa438, 0x8420, 0xa438, 0xbc32, 0xa438, 0x20bc, 0xa438, 0x3e76, + 0xa438, 0xbc08, 0xa438, 0xfda6, 0xa438, 0x1a00, 0xa438, 0xb64e, + 0xa438, 0xd101, 0xa438, 0xbf85, 0xa438, 0xa402, 0xa438, 0x4f48, + 0xa438, 0xbf85, 0xa438, 0xa702, 0xa438, 0x54c0, 0xa438, 0xd10f, + 0xa438, 0xbf85, 0xa438, 0xaa02, 0xa438, 0x4f48, 0xa438, 0x024d, + 0xa438, 0x6abf, 0xa438, 0x85ad, 0xa438, 0x024f, 0xa438, 0x67bf, + 0xa438, 0x8ff7, 0xa438, 0xddbf, 0xa438, 0x85b0, 0xa438, 0x024f, + 0xa438, 0x67bf, 0xa438, 0x8ff8, 0xa438, 0xddbf, 0xa438, 0x85b3, + 0xa438, 0x024f, 0xa438, 0x67bf, 0xa438, 0x8ff9, 0xa438, 0xddbf, + 0xa438, 0x85b6, 0xa438, 0x024f, 0xa438, 0x67bf, 0xa438, 0x8ffa, + 0xa438, 0xddd1, 0xa438, 0x00bf, 0xa438, 0x85aa, 0xa438, 0x024f, + 0xa438, 0x4802, 0xa438, 0x4d6a, 0xa438, 0xbf85, 0xa438, 0xad02, + 0xa438, 0x4f67, 0xa438, 0xbf8f, 0xa438, 0xfbdd, 0xa438, 0xbf85, + 0xa438, 0xb002, 0xa438, 0x4f67, 0xa438, 0xbf8f, 0xa438, 0xfcdd, + 0xa438, 0xbf85, 0xa438, 0xb302, 0xa438, 0x4f67, 0xa438, 0xbf8f, + 0xa438, 0xfddd, 0xa438, 0xbf85, 0xa438, 0xb602, 0xa438, 0x4f67, + 0xa438, 0xbf8f, 0xa438, 0xfedd, 0xa438, 0xbf85, 0xa438, 0xa702, + 0xa438, 0x54b7, 0xa438, 0xaf00, 0xa438, 0x8800, 0xa436, 0xb818, + 0xa438, 0x38b8, 0xa436, 0xb81a, 0xa438, 0x0444, 0xa436, 0xb81c, + 0xa438, 0x40ee, 0xa436, 0xb81e, 0xa438, 0x3C1A, 0xa436, 0xb850, + 0xa438, 0x0981, 0xa436, 0xb852, 0xa438, 0x0085, 0xa436, 0xb878, + 0xa438, 0xffff, 0xa436, 0xb884, 0xa438, 0xffff, 0xa436, 0xb832, + 0xa438, 0x003f, 0xa436, 0x0000, 0xa438, 0x0000, 0xa436, 0xB82E, + 0xa438, 0x0000, 0xa436, 0x8024, 0xa438, 0x0000, 0xb820, 0x0000, + 0xa436, 0x801E, 0xa438, 0x0021, 0xFFFF, 0xFFFF +}; + +static const u16 phy_mcu_ram_code_8125b_2[] = { + 0xa436, 0x8024, 0xa438, 0x3701, 0xa436, 0xB82E, 0xa438, 0x0001, + 0xb820, 0x0090, 0xa436, 0xA016, 0xa438, 0x0000, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x801a, 0xa438, 0x1800, 0xa438, 0x803f, + 0xa438, 0x1800, 0xa438, 0x8045, 0xa438, 0x1800, 0xa438, 0x8067, + 0xa438, 0x1800, 0xa438, 0x806d, 0xa438, 0x1800, 0xa438, 0x8071, + 0xa438, 0x1800, 0xa438, 0x80b1, 0xa438, 0xd093, 0xa438, 0xd1c4, + 0xa438, 0x1000, 0xa438, 0x135c, 0xa438, 0xd704, 0xa438, 0x5fbc, + 0xa438, 0xd504, 0xa438, 0xc9f1, 0xa438, 0x1800, 0xa438, 0x0fc9, + 0xa438, 0xbb50, 0xa438, 0xd505, 0xa438, 0xa202, 0xa438, 0xd504, + 0xa438, 0x8c0f, 0xa438, 0xd500, 0xa438, 0x1000, 0xa438, 0x1519, + 0xa438, 0x1000, 0xa438, 0x135c, 0xa438, 0xd75e, 0xa438, 0x5fae, + 0xa438, 0x9b50, 0xa438, 0x1000, 0xa438, 0x135c, 0xa438, 0xd75e, + 0xa438, 0x7fae, 0xa438, 0x1000, 0xa438, 0x135c, 0xa438, 0xd707, + 0xa438, 0x40a7, 0xa438, 0xd719, 0xa438, 0x4071, 0xa438, 0x1800, + 0xa438, 0x1557, 0xa438, 0xd719, 0xa438, 0x2f70, 0xa438, 0x803b, + 0xa438, 0x2f73, 0xa438, 0x156a, 0xa438, 0x5e70, 0xa438, 0x1800, + 0xa438, 0x155d, 0xa438, 0xd505, 0xa438, 0xa202, 0xa438, 0xd500, + 0xa438, 0xffed, 0xa438, 0xd709, 0xa438, 0x4054, 0xa438, 0xa788, + 0xa438, 0xd70b, 0xa438, 0x1800, 0xa438, 0x172a, 0xa438, 0xc0c1, + 0xa438, 0xc0c0, 0xa438, 0xd05a, 0xa438, 0xd1ba, 0xa438, 0xd701, + 0xa438, 0x2529, 0xa438, 0x022a, 0xa438, 0xd0a7, 0xa438, 0xd1b9, + 0xa438, 0xa208, 0xa438, 0x1000, 0xa438, 0x080e, 0xa438, 0xd701, + 0xa438, 0x408b, 0xa438, 0x1000, 0xa438, 0x0a65, 0xa438, 0xf003, + 0xa438, 0x1000, 0xa438, 0x0a6b, 0xa438, 0xd701, 0xa438, 0x1000, + 0xa438, 0x0920, 0xa438, 0x1000, 0xa438, 0x0915, 0xa438, 0x1000, + 0xa438, 0x0909, 0xa438, 0x228f, 0xa438, 0x804e, 0xa438, 0x9801, + 0xa438, 0xd71e, 0xa438, 0x5d61, 0xa438, 0xd701, 0xa438, 0x1800, + 0xa438, 0x022a, 0xa438, 0x2005, 0xa438, 0x091a, 0xa438, 0x3bd9, + 0xa438, 0x0919, 0xa438, 0x1800, 0xa438, 0x0916, 0xa438, 0xd090, + 0xa438, 0xd1c9, 0xa438, 0x1800, 0xa438, 0x1064, 0xa438, 0xd096, + 0xa438, 0xd1a9, 0xa438, 0xd503, 0xa438, 0xa104, 0xa438, 0x0c07, + 0xa438, 0x0902, 0xa438, 0xd500, 0xa438, 0xbc10, 0xa438, 0xd501, + 0xa438, 0xce01, 0xa438, 0xa201, 0xa438, 0x8201, 0xa438, 0xce00, + 0xa438, 0xd500, 0xa438, 0xc484, 0xa438, 0xd503, 0xa438, 0xcc02, + 0xa438, 0xcd0d, 0xa438, 0xaf01, 0xa438, 0xd500, 0xa438, 0xd703, + 0xa438, 0x4371, 0xa438, 0xbd08, 0xa438, 0x1000, 0xa438, 0x135c, + 0xa438, 0xd75e, 0xa438, 0x5fb3, 0xa438, 0xd503, 0xa438, 0xd0f5, + 0xa438, 0xd1c6, 0xa438, 0x0cf0, 0xa438, 0x0e50, 0xa438, 0xd704, + 0xa438, 0x401c, 0xa438, 0xd0f5, 0xa438, 0xd1c6, 0xa438, 0x0cf0, + 0xa438, 0x0ea0, 0xa438, 0x401c, 0xa438, 0xd07b, 0xa438, 0xd1c5, + 0xa438, 0x8ef0, 0xa438, 0x401c, 0xa438, 0x9d08, 0xa438, 0x1000, + 0xa438, 0x135c, 0xa438, 0xd75e, 0xa438, 0x7fb3, 0xa438, 0x1000, + 0xa438, 0x135c, 0xa438, 0xd75e, 0xa438, 0x5fad, 0xa438, 0x1000, + 0xa438, 0x14c5, 0xa438, 0xd703, 0xa438, 0x3181, 0xa438, 0x80af, + 0xa438, 0x60ad, 0xa438, 0x1000, 0xa438, 0x135c, 0xa438, 0xd703, + 0xa438, 0x5fba, 0xa438, 0x1800, 0xa438, 0x0cc7, 0xa438, 0xa802, + 0xa438, 0xa301, 0xa438, 0xa801, 0xa438, 0xc004, 0xa438, 0xd710, + 0xa438, 0x4000, 0xa438, 0x1800, 0xa438, 0x1e79, 0xa436, 0xA026, + 0xa438, 0x1e78, 0xa436, 0xA024, 0xa438, 0x0c93, 0xa436, 0xA022, + 0xa438, 0x1062, 0xa436, 0xA020, 0xa438, 0x0915, 0xa436, 0xA006, + 0xa438, 0x020a, 0xa436, 0xA004, 0xa438, 0x1726, 0xa436, 0xA002, + 0xa438, 0x1542, 0xa436, 0xA000, 0xa438, 0x0fc7, 0xa436, 0xA008, + 0xa438, 0xff00, 0xa436, 0xA016, 0xa438, 0x0010, 0xa436, 0xA012, + 0xa438, 0x0000, 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, + 0xa438, 0x1800, 0xa438, 0x801d, 0xa438, 0x1800, 0xa438, 0x802c, + 0xa438, 0x1800, 0xa438, 0x802c, 0xa438, 0x1800, 0xa438, 0x802c, + 0xa438, 0x1800, 0xa438, 0x802c, 0xa438, 0x1800, 0xa438, 0x802c, + 0xa438, 0x1800, 0xa438, 0x802c, 0xa438, 0xd700, 0xa438, 0x6090, + 0xa438, 0x60d1, 0xa438, 0xc95c, 0xa438, 0xf007, 0xa438, 0x60b1, + 0xa438, 0xc95a, 0xa438, 0xf004, 0xa438, 0xc956, 0xa438, 0xf002, + 0xa438, 0xc94e, 0xa438, 0x1800, 0xa438, 0x00cd, 0xa438, 0xd700, + 0xa438, 0x6090, 0xa438, 0x60d1, 0xa438, 0xc95c, 0xa438, 0xf007, + 0xa438, 0x60b1, 0xa438, 0xc95a, 0xa438, 0xf004, 0xa438, 0xc956, + 0xa438, 0xf002, 0xa438, 0xc94e, 0xa438, 0x1000, 0xa438, 0x022a, + 0xa438, 0x1800, 0xa438, 0x0132, 0xa436, 0xA08E, 0xa438, 0xffff, + 0xa436, 0xA08C, 0xa438, 0xffff, 0xa436, 0xA08A, 0xa438, 0xffff, + 0xa436, 0xA088, 0xa438, 0xffff, 0xa436, 0xA086, 0xa438, 0xffff, + 0xa436, 0xA084, 0xa438, 0xffff, 0xa436, 0xA082, 0xa438, 0x012f, + 0xa436, 0xA080, 0xa438, 0x00cc, 0xa436, 0xA090, 0xa438, 0x0103, + 0xa436, 0xA016, 0xa438, 0x0020, 0xa436, 0xA012, 0xa438, 0x0000, + 0xa436, 0xA014, 0xa438, 0x1800, 0xa438, 0x8010, 0xa438, 0x1800, + 0xa438, 0x8020, 0xa438, 0x1800, 0xa438, 0x802a, 0xa438, 0x1800, + 0xa438, 0x8035, 0xa438, 0x1800, 0xa438, 0x803c, 0xa438, 0x1800, + 0xa438, 0x803c, 0xa438, 0x1800, 0xa438, 0x803c, 0xa438, 0x1800, + 0xa438, 0x803c, 0xa438, 0xd107, 0xa438, 0xd042, 0xa438, 0xa404, + 0xa438, 0x1000, 0xa438, 0x09df, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0x8280, 0xa438, 0xd700, 0xa438, 0x6065, 0xa438, 0xd125, + 0xa438, 0xf002, 0xa438, 0xd12b, 0xa438, 0xd040, 0xa438, 0x1800, + 0xa438, 0x077f, 0xa438, 0x0cf0, 0xa438, 0x0c50, 0xa438, 0xd104, + 0xa438, 0xd040, 0xa438, 0x1000, 0xa438, 0x0aa8, 0xa438, 0xd700, + 0xa438, 0x5fb4, 0xa438, 0x1800, 0xa438, 0x0a2e, 0xa438, 0xcb9b, + 0xa438, 0xd110, 0xa438, 0xd040, 0xa438, 0x1000, 0xa438, 0x0b7b, + 0xa438, 0x1000, 0xa438, 0x09df, 0xa438, 0xd700, 0xa438, 0x5fb4, + 0xa438, 0x1800, 0xa438, 0x081b, 0xa438, 0x1000, 0xa438, 0x09df, + 0xa438, 0xd704, 0xa438, 0x7fb8, 0xa438, 0xa718, 0xa438, 0x1800, + 0xa438, 0x074e, 0xa436, 0xA10E, 0xa438, 0xffff, 0xa436, 0xA10C, + 0xa438, 0xffff, 0xa436, 0xA10A, 0xa438, 0xffff, 0xa436, 0xA108, + 0xa438, 0xffff, 0xa436, 0xA106, 0xa438, 0x074d, 0xa436, 0xA104, + 0xa438, 0x0818, 0xa436, 0xA102, 0xa438, 0x0a2c, 0xa436, 0xA100, + 0xa438, 0x077e, 0xa436, 0xA110, 0xa438, 0x000f, 0xa436, 0xb87c, + 0xa438, 0x8625, 0xa436, 0xb87e, 0xa438, 0xaf86, 0xa438, 0x3daf, + 0xa438, 0x8689, 0xa438, 0xaf88, 0xa438, 0x69af, 0xa438, 0x8887, + 0xa438, 0xaf88, 0xa438, 0x9caf, 0xa438, 0x889c, 0xa438, 0xaf88, + 0xa438, 0x9caf, 0xa438, 0x889c, 0xa438, 0xbf86, 0xa438, 0x49d7, + 0xa438, 0x0040, 0xa438, 0x0277, 0xa438, 0x7daf, 0xa438, 0x2727, + 0xa438, 0x0000, 0xa438, 0x7205, 0xa438, 0x0000, 0xa438, 0x7208, + 0xa438, 0x0000, 0xa438, 0x71f3, 0xa438, 0x0000, 0xa438, 0x71f6, + 0xa438, 0x0000, 0xa438, 0x7229, 0xa438, 0x0000, 0xa438, 0x722c, + 0xa438, 0x0000, 0xa438, 0x7217, 0xa438, 0x0000, 0xa438, 0x721a, + 0xa438, 0x0000, 0xa438, 0x721d, 0xa438, 0x0000, 0xa438, 0x7211, + 0xa438, 0x0000, 0xa438, 0x7220, 0xa438, 0x0000, 0xa438, 0x7214, + 0xa438, 0x0000, 0xa438, 0x722f, 0xa438, 0x0000, 0xa438, 0x7223, + 0xa438, 0x0000, 0xa438, 0x7232, 0xa438, 0x0000, 0xa438, 0x7226, + 0xa438, 0xf8f9, 0xa438, 0xfae0, 0xa438, 0x85b3, 0xa438, 0x3802, + 0xa438, 0xad27, 0xa438, 0x02ae, 0xa438, 0x03af, 0xa438, 0x8830, + 0xa438, 0x1f66, 0xa438, 0xef65, 0xa438, 0xbfc2, 0xa438, 0x1f1a, + 0xa438, 0x96f7, 0xa438, 0x05ee, 0xa438, 0xffd2, 0xa438, 0x00da, + 0xa438, 0xf605, 0xa438, 0xbfc2, 0xa438, 0x2f1a, 0xa438, 0x96f7, + 0xa438, 0x05ee, 0xa438, 0xffd2, 0xa438, 0x00db, 0xa438, 0xf605, + 0xa438, 0xef02, 0xa438, 0x1f11, 0xa438, 0x0d42, 0xa438, 0xbf88, + 0xa438, 0x4202, 0xa438, 0x6e7d, 0xa438, 0xef02, 0xa438, 0x1b03, + 0xa438, 0x1f11, 0xa438, 0x0d42, 0xa438, 0xbf88, 0xa438, 0x4502, + 0xa438, 0x6e7d, 0xa438, 0xef02, 0xa438, 0x1a03, 0xa438, 0x1f11, + 0xa438, 0x0d42, 0xa438, 0xbf88, 0xa438, 0x4802, 0xa438, 0x6e7d, + 0xa438, 0xbfc2, 0xa438, 0x3f1a, 0xa438, 0x96f7, 0xa438, 0x05ee, + 0xa438, 0xffd2, 0xa438, 0x00da, 0xa438, 0xf605, 0xa438, 0xbfc2, + 0xa438, 0x4f1a, 0xa438, 0x96f7, 0xa438, 0x05ee, 0xa438, 0xffd2, + 0xa438, 0x00db, 0xa438, 0xf605, 0xa438, 0xef02, 0xa438, 0x1f11, + 0xa438, 0x0d42, 0xa438, 0xbf88, 0xa438, 0x4b02, 0xa438, 0x6e7d, + 0xa438, 0xef02, 0xa438, 0x1b03, 0xa438, 0x1f11, 0xa438, 0x0d42, + 0xa438, 0xbf88, 0xa438, 0x4e02, 0xa438, 0x6e7d, 0xa438, 0xef02, + 0xa438, 0x1a03, 0xa438, 0x1f11, 0xa438, 0x0d42, 0xa438, 0xbf88, + 0xa438, 0x5102, 0xa438, 0x6e7d, 0xa438, 0xef56, 0xa438, 0xd020, + 0xa438, 0x1f11, 0xa438, 0xbf88, 0xa438, 0x5402, 0xa438, 0x6e7d, + 0xa438, 0xbf88, 0xa438, 0x5702, 0xa438, 0x6e7d, 0xa438, 0xbf88, + 0xa438, 0x5a02, 0xa438, 0x6e7d, 0xa438, 0xe185, 0xa438, 0xa0ef, + 0xa438, 0x0348, 0xa438, 0x0a28, 0xa438, 0x05ef, 0xa438, 0x201b, + 0xa438, 0x01ad, 0xa438, 0x2735, 0xa438, 0x1f44, 0xa438, 0xe085, + 0xa438, 0x88e1, 0xa438, 0x8589, 0xa438, 0xbf88, 0xa438, 0x5d02, + 0xa438, 0x6e7d, 0xa438, 0xe085, 0xa438, 0x8ee1, 0xa438, 0x858f, + 0xa438, 0xbf88, 0xa438, 0x6002, 0xa438, 0x6e7d, 0xa438, 0xe085, + 0xa438, 0x94e1, 0xa438, 0x8595, 0xa438, 0xbf88, 0xa438, 0x6302, + 0xa438, 0x6e7d, 0xa438, 0xe085, 0xa438, 0x9ae1, 0xa438, 0x859b, + 0xa438, 0xbf88, 0xa438, 0x6602, 0xa438, 0x6e7d, 0xa438, 0xaf88, + 0xa438, 0x3cbf, 0xa438, 0x883f, 0xa438, 0x026e, 0xa438, 0x9cad, + 0xa438, 0x2835, 0xa438, 0x1f44, 0xa438, 0xe08f, 0xa438, 0xf8e1, + 0xa438, 0x8ff9, 0xa438, 0xbf88, 0xa438, 0x5d02, 0xa438, 0x6e7d, + 0xa438, 0xe08f, 0xa438, 0xfae1, 0xa438, 0x8ffb, 0xa438, 0xbf88, + 0xa438, 0x6002, 0xa438, 0x6e7d, 0xa438, 0xe08f, 0xa438, 0xfce1, + 0xa438, 0x8ffd, 0xa438, 0xbf88, 0xa438, 0x6302, 0xa438, 0x6e7d, + 0xa438, 0xe08f, 0xa438, 0xfee1, 0xa438, 0x8fff, 0xa438, 0xbf88, + 0xa438, 0x6602, 0xa438, 0x6e7d, 0xa438, 0xaf88, 0xa438, 0x3ce1, + 0xa438, 0x85a1, 0xa438, 0x1b21, 0xa438, 0xad37, 0xa438, 0x341f, + 0xa438, 0x44e0, 0xa438, 0x858a, 0xa438, 0xe185, 0xa438, 0x8bbf, + 0xa438, 0x885d, 0xa438, 0x026e, 0xa438, 0x7de0, 0xa438, 0x8590, + 0xa438, 0xe185, 0xa438, 0x91bf, 0xa438, 0x8860, 0xa438, 0x026e, + 0xa438, 0x7de0, 0xa438, 0x8596, 0xa438, 0xe185, 0xa438, 0x97bf, + 0xa438, 0x8863, 0xa438, 0x026e, 0xa438, 0x7de0, 0xa438, 0x859c, + 0xa438, 0xe185, 0xa438, 0x9dbf, 0xa438, 0x8866, 0xa438, 0x026e, + 0xa438, 0x7dae, 0xa438, 0x401f, 0xa438, 0x44e0, 0xa438, 0x858c, + 0xa438, 0xe185, 0xa438, 0x8dbf, 0xa438, 0x885d, 0xa438, 0x026e, + 0xa438, 0x7de0, 0xa438, 0x8592, 0xa438, 0xe185, 0xa438, 0x93bf, + 0xa438, 0x8860, 0xa438, 0x026e, 0xa438, 0x7de0, 0xa438, 0x8598, + 0xa438, 0xe185, 0xa438, 0x99bf, 0xa438, 0x8863, 0xa438, 0x026e, + 0xa438, 0x7de0, 0xa438, 0x859e, 0xa438, 0xe185, 0xa438, 0x9fbf, + 0xa438, 0x8866, 0xa438, 0x026e, 0xa438, 0x7dae, 0xa438, 0x0ce1, + 0xa438, 0x85b3, 0xa438, 0x3904, 0xa438, 0xac2f, 0xa438, 0x04ee, + 0xa438, 0x85b3, 0xa438, 0x00af, 0xa438, 0x39d9, 0xa438, 0x22ac, + 0xa438, 0xeaf0, 0xa438, 0xacf6, 0xa438, 0xf0ac, 0xa438, 0xfaf0, + 0xa438, 0xacf8, 0xa438, 0xf0ac, 0xa438, 0xfcf0, 0xa438, 0xad00, + 0xa438, 0xf0ac, 0xa438, 0xfef0, 0xa438, 0xacf0, 0xa438, 0xf0ac, + 0xa438, 0xf4f0, 0xa438, 0xacf2, 0xa438, 0xf0ac, 0xa438, 0xb0f0, + 0xa438, 0xacae, 0xa438, 0xf0ac, 0xa438, 0xacf0, 0xa438, 0xacaa, + 0xa438, 0xa100, 0xa438, 0x0ce1, 0xa438, 0x8ff7, 0xa438, 0xbf88, + 0xa438, 0x8402, 0xa438, 0x6e7d, 0xa438, 0xaf26, 0xa438, 0xe9e1, + 0xa438, 0x8ff6, 0xa438, 0xbf88, 0xa438, 0x8402, 0xa438, 0x6e7d, + 0xa438, 0xaf26, 0xa438, 0xf520, 0xa438, 0xac86, 0xa438, 0xbf88, + 0xa438, 0x3f02, 0xa438, 0x6e9c, 0xa438, 0xad28, 0xa438, 0x03af, + 0xa438, 0x3324, 0xa438, 0xad38, 0xa438, 0x03af, 0xa438, 0x32e6, + 0xa438, 0xaf32, 0xa438, 0xfb00, 0xa436, 0xb87c, 0xa438, 0x8ff6, + 0xa436, 0xb87e, 0xa438, 0x0705, 0xa436, 0xb87c, 0xa438, 0x8ff8, + 0xa436, 0xb87e, 0xa438, 0x19cc, 0xa436, 0xb87c, 0xa438, 0x8ffa, + 0xa436, 0xb87e, 0xa438, 0x28e3, 0xa436, 0xb87c, 0xa438, 0x8ffc, + 0xa436, 0xb87e, 0xa438, 0x1047, 0xa436, 0xb87c, 0xa438, 0x8ffe, + 0xa436, 0xb87e, 0xa438, 0x0a45, 0xa436, 0xb85e, 0xa438, 0x271E, + 0xa436, 0xb860, 0xa438, 0x3846, 0xa436, 0xb862, 0xa438, 0x26E6, + 0xa436, 0xb864, 0xa438, 0x32E3, 0xa436, 0xb886, 0xa438, 0xffff, + 0xa436, 0xb888, 0xa438, 0xffff, 0xa436, 0xb88a, 0xa438, 0xffff, + 0xa436, 0xb88c, 0xa438, 0xffff, 0xa436, 0xb838, 0xa438, 0x000f, + 0xb820, 0x0010, 0xa436, 0x846e, 0xa438, 0xaf84, 0xa438, 0x86af, + 0xa438, 0x8690, 0xa438, 0xaf86, 0xa438, 0xa4af, 0xa438, 0x86a4, + 0xa438, 0xaf86, 0xa438, 0xa4af, 0xa438, 0x86a4, 0xa438, 0xaf86, + 0xa438, 0xa4af, 0xa438, 0x86a4, 0xa438, 0xee82, 0xa438, 0x5f00, + 0xa438, 0x0284, 0xa438, 0x90af, 0xa438, 0x0441, 0xa438, 0xf8e0, + 0xa438, 0x8ff3, 0xa438, 0xa000, 0xa438, 0x0502, 0xa438, 0x84a4, + 0xa438, 0xae06, 0xa438, 0xa001, 0xa438, 0x0302, 0xa438, 0x84c8, + 0xa438, 0xfc04, 0xa438, 0xf8f9, 0xa438, 0xef59, 0xa438, 0xe080, + 0xa438, 0x15ad, 0xa438, 0x2702, 0xa438, 0xae03, 0xa438, 0xaf84, + 0xa438, 0xc3bf, 0xa438, 0x53ca, 0xa438, 0x0252, 0xa438, 0xc8ad, + 0xa438, 0x2807, 0xa438, 0x0285, 0xa438, 0x2cee, 0xa438, 0x8ff3, + 0xa438, 0x01ef, 0xa438, 0x95fd, 0xa438, 0xfc04, 0xa438, 0xf8f9, + 0xa438, 0xfaef, 0xa438, 0x69bf, 0xa438, 0x53ca, 0xa438, 0x0252, + 0xa438, 0xc8ac, 0xa438, 0x2822, 0xa438, 0xd480, 0xa438, 0x00bf, + 0xa438, 0x8684, 0xa438, 0x0252, 0xa438, 0xa9bf, 0xa438, 0x8687, + 0xa438, 0x0252, 0xa438, 0xa9bf, 0xa438, 0x868a, 0xa438, 0x0252, + 0xa438, 0xa9bf, 0xa438, 0x868d, 0xa438, 0x0252, 0xa438, 0xa9ee, + 0xa438, 0x8ff3, 0xa438, 0x00af, 0xa438, 0x8526, 0xa438, 0xe08f, + 0xa438, 0xf4e1, 0xa438, 0x8ff5, 0xa438, 0xe28f, 0xa438, 0xf6e3, + 0xa438, 0x8ff7, 0xa438, 0x1b45, 0xa438, 0xac27, 0xa438, 0x0eee, + 0xa438, 0x8ff4, 0xa438, 0x00ee, 0xa438, 0x8ff5, 0xa438, 0x0002, + 0xa438, 0x852c, 0xa438, 0xaf85, 0xa438, 0x26e0, 0xa438, 0x8ff4, + 0xa438, 0xe18f, 0xa438, 0xf52c, 0xa438, 0x0001, 0xa438, 0xe48f, + 0xa438, 0xf4e5, 0xa438, 0x8ff5, 0xa438, 0xef96, 0xa438, 0xfefd, + 0xa438, 0xfc04, 0xa438, 0xf8f9, 0xa438, 0xef59, 0xa438, 0xbf53, + 0xa438, 0x2202, 0xa438, 0x52c8, 0xa438, 0xa18b, 0xa438, 0x02ae, + 0xa438, 0x03af, 0xa438, 0x85da, 0xa438, 0xbf57, 0xa438, 0x7202, + 0xa438, 0x52c8, 0xa438, 0xe48f, 0xa438, 0xf8e5, 0xa438, 0x8ff9, + 0xa438, 0xbf57, 0xa438, 0x7502, 0xa438, 0x52c8, 0xa438, 0xe48f, + 0xa438, 0xfae5, 0xa438, 0x8ffb, 0xa438, 0xbf57, 0xa438, 0x7802, + 0xa438, 0x52c8, 0xa438, 0xe48f, 0xa438, 0xfce5, 0xa438, 0x8ffd, + 0xa438, 0xbf57, 0xa438, 0x7b02, 0xa438, 0x52c8, 0xa438, 0xe48f, + 0xa438, 0xfee5, 0xa438, 0x8fff, 0xa438, 0xbf57, 0xa438, 0x6c02, + 0xa438, 0x52c8, 0xa438, 0xa102, 0xa438, 0x13ee, 0xa438, 0x8ffc, + 0xa438, 0x80ee, 0xa438, 0x8ffd, 0xa438, 0x00ee, 0xa438, 0x8ffe, + 0xa438, 0x80ee, 0xa438, 0x8fff, 0xa438, 0x00af, 0xa438, 0x8599, + 0xa438, 0xa101, 0xa438, 0x0cbf, 0xa438, 0x534c, 0xa438, 0x0252, + 0xa438, 0xc8a1, 0xa438, 0x0303, 0xa438, 0xaf85, 0xa438, 0x77bf, + 0xa438, 0x5322, 0xa438, 0x0252, 0xa438, 0xc8a1, 0xa438, 0x8b02, + 0xa438, 0xae03, 0xa438, 0xaf86, 0xa438, 0x64e0, 0xa438, 0x8ff8, + 0xa438, 0xe18f, 0xa438, 0xf9bf, 0xa438, 0x8684, 0xa438, 0x0252, + 0xa438, 0xa9e0, 0xa438, 0x8ffa, 0xa438, 0xe18f, 0xa438, 0xfbbf, + 0xa438, 0x8687, 0xa438, 0x0252, 0xa438, 0xa9e0, 0xa438, 0x8ffc, + 0xa438, 0xe18f, 0xa438, 0xfdbf, 0xa438, 0x868a, 0xa438, 0x0252, + 0xa438, 0xa9e0, 0xa438, 0x8ffe, 0xa438, 0xe18f, 0xa438, 0xffbf, + 0xa438, 0x868d, 0xa438, 0x0252, 0xa438, 0xa9af, 0xa438, 0x867f, + 0xa438, 0xbf53, 0xa438, 0x2202, 0xa438, 0x52c8, 0xa438, 0xa144, + 0xa438, 0x3cbf, 0xa438, 0x547b, 0xa438, 0x0252, 0xa438, 0xc8e4, + 0xa438, 0x8ff8, 0xa438, 0xe58f, 0xa438, 0xf9bf, 0xa438, 0x547e, + 0xa438, 0x0252, 0xa438, 0xc8e4, 0xa438, 0x8ffa, 0xa438, 0xe58f, + 0xa438, 0xfbbf, 0xa438, 0x5481, 0xa438, 0x0252, 0xa438, 0xc8e4, + 0xa438, 0x8ffc, 0xa438, 0xe58f, 0xa438, 0xfdbf, 0xa438, 0x5484, + 0xa438, 0x0252, 0xa438, 0xc8e4, 0xa438, 0x8ffe, 0xa438, 0xe58f, + 0xa438, 0xffbf, 0xa438, 0x5322, 0xa438, 0x0252, 0xa438, 0xc8a1, + 0xa438, 0x4448, 0xa438, 0xaf85, 0xa438, 0xa7bf, 0xa438, 0x5322, + 0xa438, 0x0252, 0xa438, 0xc8a1, 0xa438, 0x313c, 0xa438, 0xbf54, + 0xa438, 0x7b02, 0xa438, 0x52c8, 0xa438, 0xe48f, 0xa438, 0xf8e5, + 0xa438, 0x8ff9, 0xa438, 0xbf54, 0xa438, 0x7e02, 0xa438, 0x52c8, + 0xa438, 0xe48f, 0xa438, 0xfae5, 0xa438, 0x8ffb, 0xa438, 0xbf54, + 0xa438, 0x8102, 0xa438, 0x52c8, 0xa438, 0xe48f, 0xa438, 0xfce5, + 0xa438, 0x8ffd, 0xa438, 0xbf54, 0xa438, 0x8402, 0xa438, 0x52c8, + 0xa438, 0xe48f, 0xa438, 0xfee5, 0xa438, 0x8fff, 0xa438, 0xbf53, + 0xa438, 0x2202, 0xa438, 0x52c8, 0xa438, 0xa131, 0xa438, 0x03af, + 0xa438, 0x85a7, 0xa438, 0xd480, 0xa438, 0x00bf, 0xa438, 0x8684, + 0xa438, 0x0252, 0xa438, 0xa9bf, 0xa438, 0x8687, 0xa438, 0x0252, + 0xa438, 0xa9bf, 0xa438, 0x868a, 0xa438, 0x0252, 0xa438, 0xa9bf, + 0xa438, 0x868d, 0xa438, 0x0252, 0xa438, 0xa9ef, 0xa438, 0x95fd, + 0xa438, 0xfc04, 0xa438, 0xf0d1, 0xa438, 0x2af0, 0xa438, 0xd12c, + 0xa438, 0xf0d1, 0xa438, 0x44f0, 0xa438, 0xd146, 0xa438, 0xbf86, + 0xa438, 0xa102, 0xa438, 0x52c8, 0xa438, 0xbf86, 0xa438, 0xa102, + 0xa438, 0x52c8, 0xa438, 0xd101, 0xa438, 0xaf06, 0xa438, 0xa570, + 0xa438, 0xce42, 0xa436, 0xb818, 0xa438, 0x043d, 0xa436, 0xb81a, + 0xa438, 0x06a3, 0xa436, 0xb81c, 0xa438, 0xffff, 0xa436, 0xb81e, + 0xa438, 0xffff, 0xa436, 0xb850, 0xa438, 0xffff, 0xa436, 0xb852, + 0xa438, 0xffff, 0xa436, 0xb878, 0xa438, 0xffff, 0xa436, 0xb884, + 0xa438, 0xffff, 0xa436, 0xb832, 0xa438, 0x0003, 0xa436, 0x0000, + 0xa438, 0x0000, 0xa436, 0xB82E, 0xa438, 0x0000, 0xa436, 0x8024, + 0xa438, 0x0000, 0xa436, 0x801E, 0xa438, 0x0021, 0xb820, 0x0000, + 0xFFFF, 0xFFFF +}; + +static void +rtl8125_real_set_phy_mcu_8125b_1(struct net_device *dev) +{ + rtl8125_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8125b_1, + ARRAY_SIZE(phy_mcu_ram_code_8125b_1) + ); +} + +static void +rtl8125_set_phy_mcu_8125b_1(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_set_phy_mcu_patch_request(tp); + + rtl8125_real_set_phy_mcu_8125b_1(dev); + + rtl8125_clear_phy_mcu_patch_request(tp); +} + +static void +rtl8125_real_set_phy_mcu_8125b_2(struct net_device *dev) +{ + rtl8125_set_phy_mcu_ram_code(dev, + phy_mcu_ram_code_8125b_2, + ARRAY_SIZE(phy_mcu_ram_code_8125b_2) + ); +} + +static void +rtl8125_set_phy_mcu_8125b_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_set_phy_mcu_patch_request(tp); + + rtl8125_real_set_phy_mcu_8125b_2(dev); + + rtl8125_clear_phy_mcu_patch_request(tp); +} + +static void +rtl8125_init_hw_phy_mcu(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u8 require_disable_phy_disable_mode = FALSE; + + if (tp->NotWrRamCodeToMicroP == TRUE) return; + if (rtl8125_check_hw_phy_mcu_code_ver(dev)) return; + + if (HW_SUPPORT_CHECK_PHY_DISABLE_MODE(tp) && rtl8125_is_in_phy_disable_mode(dev)) + require_disable_phy_disable_mode = TRUE; + + if (require_disable_phy_disable_mode) + rtl8125_disable_phy_disable_mode(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + rtl8125_set_phy_mcu_8125a_1(dev); + break; + case CFG_METHOD_3: + case CFG_METHOD_6: + rtl8125_set_phy_mcu_8125a_2(dev); + break; + case CFG_METHOD_4: + rtl8125_set_phy_mcu_8125b_1(dev); + break; + case CFG_METHOD_5: + case CFG_METHOD_7: + rtl8125_set_phy_mcu_8125b_2(dev); + break; + } + + if (require_disable_phy_disable_mode) + rtl8125_enable_phy_disable_mode(dev); + + rtl8125_write_hw_phy_mcu_code_ver(dev); + + rtl8125_mdio_write(tp,0x1F, 0x0000); + + tp->HwHasWrRamCodeToMicroP = TRUE; +} +#endif + +static void +rtl8125_enable_phy_aldps(struct rtl8125_private *tp) +{ + //enable aldps + //GPHY OCP 0xA430 bit[2] = 0x1 (en_aldps) + SetEthPhyOcpBit(tp, 0xA430, BIT_2); +} + +static void +rtl8125_hw_phy_config_8125a_1(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + ClearAndSetEthPhyOcpBit(tp, + 0xAD40, + 0x03FF, + 0x84 + ); + + SetEthPhyOcpBit(tp, 0xAD4E, BIT_4); + ClearAndSetEthPhyOcpBit(tp, + 0xAD16, + 0x03FF, + 0x0006 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xAD32, + 0x003F, + 0x0006 + ); + ClearEthPhyOcpBit(tp, 0xAC08, BIT_12); + ClearEthPhyOcpBit(tp, 0xAC08, BIT_8); + ClearAndSetEthPhyOcpBit(tp, + 0xAC8A, + BIT_15|BIT_14|BIT_13|BIT_12, + BIT_14|BIT_13|BIT_12 + ); + SetEthPhyOcpBit(tp, 0xAD18, BIT_10); + SetEthPhyOcpBit(tp, 0xAD1A, 0x3FF); + SetEthPhyOcpBit(tp, 0xAD1C, 0x3FF); + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80EA); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0xC400 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80EB); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0x0700, + 0x0300 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80F8); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x1C00 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80F1); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x3000 + ); + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80FE); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0xA500 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8102); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x5000 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8105); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x3300 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8100); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x7000 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8104); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0xF000 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8106); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x6500 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80DC); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0xED00 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80DF); + SetEthPhyOcpBit(tp, 0xA438, BIT_8); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80E1); + ClearEthPhyOcpBit(tp, 0xA438, BIT_8); + + ClearAndSetEthPhyOcpBit(tp, + 0xBF06, + 0x003F, + 0x38 + ); + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x819F); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xD0B6); + + mdio_direct_write_phy_ocp(tp, 0xBC34, 0x5555); + ClearAndSetEthPhyOcpBit(tp, + 0xBF0A, + BIT_11|BIT_10|BIT_9, + BIT_11|BIT_9 + ); + + ClearEthPhyOcpBit(tp, 0xA5C0, BIT_10); + + SetEthPhyOcpBit(tp, 0xA442, BIT_11); + + //enable aldps + //GPHY OCP 0xA430 bit[2] = 0x1 (en_aldps) + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8125_enable_phy_aldps(tp); + } + } +} + +static void +rtl8125_hw_phy_config_8125a_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + SetEthPhyOcpBit(tp, 0xAD4E, BIT_4); + ClearAndSetEthPhyOcpBit(tp, + 0xAD16, + 0x03FF, + 0x03FF + ); + ClearAndSetEthPhyOcpBit(tp, + 0xAD32, + 0x003F, + 0x0006 + ); + ClearEthPhyOcpBit(tp, 0xAC08, BIT_12); + ClearEthPhyOcpBit(tp, 0xAC08, BIT_8); + ClearAndSetEthPhyOcpBit(tp, + 0xACC0, + BIT_1|BIT_0, + BIT_1 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xAD40, + BIT_7|BIT_6|BIT_5, + BIT_6 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xAD40, + BIT_2|BIT_1|BIT_0, + BIT_2 + ); + ClearEthPhyOcpBit(tp, 0xAC14, BIT_7); + ClearEthPhyOcpBit(tp, 0xAC80, BIT_9|BIT_8); + ClearAndSetEthPhyOcpBit(tp, + 0xAC5E, + BIT_2|BIT_1|BIT_0, + BIT_1 + ); + mdio_direct_write_phy_ocp(tp, 0xAD4C, 0x00A8); + mdio_direct_write_phy_ocp(tp, 0xAC5C, 0x01FF); + ClearAndSetEthPhyOcpBit(tp, + 0xAC8A, + BIT_7|BIT_6|BIT_5|BIT_4, + BIT_5|BIT_4 + ); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8157); + ClearAndSetEthPhyOcpBit(tp, + 0xB87E, + 0xFF00, + 0x0500 + ); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8159); + ClearAndSetEthPhyOcpBit(tp, + 0xB87E, + 0xFF00, + 0x0700 + ); + + + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80A2); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0153); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x809C); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0153); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x81B3); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0043); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00A7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00D6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00EC); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00F6); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00FB); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00FD); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00FF); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x00BB); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0058); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0029); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0013); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0009); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0004); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0002); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0000); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8257); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x020F); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80EA); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x7843); + + + rtl8125_set_phy_mcu_patch_request(tp); + + ClearEthPhyOcpBit(tp, 0xB896, BIT_0); + ClearEthPhyOcpBit(tp, 0xB892, 0xFF00); + + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC091); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x6E12); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC092); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1214); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC094); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1516); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC096); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x171B); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC098); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1B1C); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC09A); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1F1F); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC09C); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x2021); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC09E); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x2224); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC0A0); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x2424); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC0A2); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x2424); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC0A4); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x2424); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC018); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0AF2); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC01A); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0D4A); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC01C); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0F26); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC01E); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x118D); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC020); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x14F3); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC022); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x175A); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC024); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x19C0); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC026); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1C26); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC089); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x6050); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC08A); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x5F6E); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC08C); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x6E6E); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC08E); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x6E6E); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC090); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x6E12); + + SetEthPhyOcpBit(tp, 0xB896, BIT_0); + + rtl8125_clear_phy_mcu_patch_request(tp); + + + SetEthPhyOcpBit(tp, 0xD068, BIT_13); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x81A2); + SetEthPhyOcpBit(tp, 0xA438, BIT_8); + ClearAndSetEthPhyOcpBit(tp, + 0xB54C, + 0xFF00, + 0xDB00); + + + ClearEthPhyOcpBit(tp, 0xA454, BIT_0); + + + SetEthPhyOcpBit(tp, 0xA5D4, BIT_5); + ClearEthPhyOcpBit(tp, 0xAD4E, BIT_4); + ClearEthPhyOcpBit(tp, 0xA86A, BIT_0); + + + SetEthPhyOcpBit(tp, 0xA442, BIT_11); + + + if (tp->RequirePhyMdiSwapPatch) { + u16 adccal_offset_p0; + u16 adccal_offset_p1; + u16 adccal_offset_p2; + u16 adccal_offset_p3; + u16 rg_lpf_cap_xg_p0; + u16 rg_lpf_cap_xg_p1; + u16 rg_lpf_cap_xg_p2; + u16 rg_lpf_cap_xg_p3; + u16 rg_lpf_cap_p0; + u16 rg_lpf_cap_p1; + u16 rg_lpf_cap_p2; + u16 rg_lpf_cap_p3; + + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0007, + 0x0001 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0000 + ); + adccal_offset_p0 = mdio_direct_read_phy_ocp(tp, 0xD06A); + adccal_offset_p0 &= 0x07FF; + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0008 + ); + adccal_offset_p1 = mdio_direct_read_phy_ocp(tp, 0xD06A); + adccal_offset_p1 &= 0x07FF; + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0010 + ); + adccal_offset_p2 = mdio_direct_read_phy_ocp(tp, 0xD06A); + adccal_offset_p2 &= 0x07FF; + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0018 + ); + adccal_offset_p3 = mdio_direct_read_phy_ocp(tp, 0xD06A); + adccal_offset_p3 &= 0x07FF; + + + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0000 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD06A, + 0x07FF, + adccal_offset_p3 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0008 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD06A, + 0x07FF, + adccal_offset_p2 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0010 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD06A, + 0x07FF, + adccal_offset_p1 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD068, + 0x0018, + 0x0018 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xD06A, + 0x07FF, + adccal_offset_p0 + ); + + + rg_lpf_cap_xg_p0 = mdio_direct_read_phy_ocp(tp, 0xBD5A); + rg_lpf_cap_xg_p0 &= 0x001F; + rg_lpf_cap_xg_p1 = mdio_direct_read_phy_ocp(tp, 0xBD5A); + rg_lpf_cap_xg_p1 &= 0x1F00; + rg_lpf_cap_xg_p2 = mdio_direct_read_phy_ocp(tp, 0xBD5C); + rg_lpf_cap_xg_p2 &= 0x001F; + rg_lpf_cap_xg_p3 = mdio_direct_read_phy_ocp(tp, 0xBD5C); + rg_lpf_cap_xg_p3 &= 0x1F00; + rg_lpf_cap_p0 = mdio_direct_read_phy_ocp(tp, 0xBC18); + rg_lpf_cap_p0 &= 0x001F; + rg_lpf_cap_p1 = mdio_direct_read_phy_ocp(tp, 0xBC18); + rg_lpf_cap_p1 &= 0x1F00; + rg_lpf_cap_p2 = mdio_direct_read_phy_ocp(tp, 0xBC1A); + rg_lpf_cap_p2 &= 0x001F; + rg_lpf_cap_p3 = mdio_direct_read_phy_ocp(tp, 0xBC1A); + rg_lpf_cap_p3 &= 0x1F00; + + + ClearAndSetEthPhyOcpBit(tp, + 0xBD5A, + 0x001F, + rg_lpf_cap_xg_p3 >> 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBD5A, + 0x1F00, + rg_lpf_cap_xg_p2 << 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBD5C, + 0x001F, + rg_lpf_cap_xg_p1 >> 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBD5C, + 0x1F00, + rg_lpf_cap_xg_p0 << 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBC18, + 0x001F, + rg_lpf_cap_p3 >> 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBC18, + 0x1F00, + rg_lpf_cap_p2 << 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBC1A, + 0x001F, + rg_lpf_cap_p1 >> 8 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xBC1A, + 0x1F00, + rg_lpf_cap_p0 << 8 + ); + } + + + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8125_enable_phy_aldps(tp); + } + } +} + +static void +rtl8125_hw_phy_config_8125b_1(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + SetEthPhyOcpBit(tp, 0xA442, BIT_11); + + + SetEthPhyOcpBit(tp, 0xBC08, (BIT_3 | BIT_2)); + + + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8FFF); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x0400 + ); + } + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8560); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x19CC); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8562); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x19CC); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8564); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x19CC); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8566); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x147D); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8568); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x147D); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x856A); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x147D); + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FFE); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0907); + } + ClearAndSetEthPhyOcpBit(tp, + 0xACDA, + 0xFF00, + 0xFF00 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xACDE, + 0xF000, + 0xF000 + ); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80D6); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x2801); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80F2); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x2801); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80F4); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x6077); + mdio_direct_write_phy_ocp(tp, 0xB506, 0x01E7); + mdio_direct_write_phy_ocp(tp, 0xAC8C, 0x0FFC); + mdio_direct_write_phy_ocp(tp, 0xAC46, 0xB7B4); + mdio_direct_write_phy_ocp(tp, 0xAC50, 0x0FBC); + mdio_direct_write_phy_ocp(tp, 0xAC3C, 0x9240); + mdio_direct_write_phy_ocp(tp, 0xAC4E, 0x0DB4); + mdio_direct_write_phy_ocp(tp, 0xACC6, 0x0707); + mdio_direct_write_phy_ocp(tp, 0xACC8, 0xA0D3); + mdio_direct_write_phy_ocp(tp, 0xAD08, 0x0007); + + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8013); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0700); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FB9); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x2801); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FBA); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0100); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FBC); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x1900); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FBE); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xE100); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FC0); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0800); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FC2); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xE500); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FC4); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0F00); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FC6); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xF100); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FC8); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0400); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FCa); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xF300); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FCc); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xFD00); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FCe); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xFF00); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FD0); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xFB00); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FD2); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0100); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FD4); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xF400); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FD6); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xFF00); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8FD8); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xF600); + + + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x813D); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x390E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x814F); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x790E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80B0); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0F31); + SetEthPhyOcpBit(tp, 0xBF4C, BIT_1); + SetEthPhyOcpBit(tp, 0xBCCA, (BIT_9 | BIT_8)); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8141); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x320E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8153); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x720E); + ClearEthPhyOcpBit(tp, 0xA432, BIT_6); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8529); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x050E); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x816C); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xC4A0); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8170); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xC4A0); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8174); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x04A0); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8178); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x04A0); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x817C); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0719); + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8FF4); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0400); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8FF1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0404); + } + mdio_direct_write_phy_ocp(tp, 0xBF4A, 0x001B); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8033); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C13); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8037); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C13); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x803B); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0xFC32); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x803F); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C13); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8043); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C13); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8047); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x7C13); + + + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8145); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x370E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8157); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x770E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8169); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x0D0A); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x817B); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x1D0A); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8217); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x5000 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x821A); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x5000 + ); + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80DA); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0403); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80DC); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x1000 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80B3); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x0384); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80B7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2007); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80BA); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x6C00 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80B5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xF009); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80BD); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x9F00 + ); + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80C7); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xf083); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80DD); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x03f0); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80DF); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x1000 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80CB); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x2007); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80CE); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x6C00 + ); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80C9); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x8009); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80D1); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0x8000 + ); + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80A3); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x200A); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80A5); + mdio_direct_write_phy_ocp(tp, 0xA438, 0xF0AD); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x809F); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x6073); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80A1); + mdio_direct_write_phy_ocp(tp, 0xA438, 0x000B); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x80A9); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + 0xFF00, + 0xC000 + ); + + rtl8125_set_phy_mcu_patch_request(tp); + + ClearEthPhyOcpBit(tp, 0xB896, BIT_0); + ClearEthPhyOcpBit(tp, 0xB892, 0xFF00); + + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC23E); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0000); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC240); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0103); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC242); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0507); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC244); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x090B); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC246); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x0C0E); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC248); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1012); + mdio_direct_write_phy_ocp(tp, 0xB88E, 0xC24A); + mdio_direct_write_phy_ocp(tp, 0xB890, 0x1416); + + SetEthPhyOcpBit(tp, 0xB896, BIT_0); + + rtl8125_clear_phy_mcu_patch_request(tp); + + + SetEthPhyOcpBit(tp, 0xA86A, BIT_0); + SetEthPhyOcpBit(tp, 0xA6F0, BIT_0); + + + mdio_direct_write_phy_ocp(tp, 0xBFA0, 0xD70D); + mdio_direct_write_phy_ocp(tp, 0xBFA2, 0x4100); + mdio_direct_write_phy_ocp(tp, 0xBFA4, 0xE868); + mdio_direct_write_phy_ocp(tp, 0xBFA6, 0xDC59); + mdio_direct_write_phy_ocp(tp, 0xB54C, 0x3C18); + ClearEthPhyOcpBit(tp, 0xBFA4, BIT_5); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x817D); + SetEthPhyOcpBit(tp, 0xA438, BIT_12); + + + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8125_enable_phy_aldps(tp); + } + } +} + +static void +rtl8125_hw_phy_config_8125b_2(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + SetEthPhyOcpBit(tp, 0xA442, BIT_11); + + + ClearAndSetEthPhyOcpBit(tp, + 0xAC46, + 0x00F0, + 0x0090 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xAD30, + 0x0003, + 0x0001 + ); + + + RTL_W16(tp, EEE_TXIDLE_TIMER_8125, tp->eee.tx_lpi_timer); + + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x80F5); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x760E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8107); + mdio_direct_write_phy_ocp(tp, 0xB87E, 0x360E); + mdio_direct_write_phy_ocp(tp, 0xB87C, 0x8551); + ClearAndSetEthPhyOcpBit(tp, + 0xB87E, + BIT_15 | BIT_14 | BIT_13 | BIT_12 | BIT_11 | BIT_10 | BIT_9 | BIT_8, + BIT_11 + ); + + ClearAndSetEthPhyOcpBit(tp, + 0xbf00, + 0xE000, + 0xA000 + ); + ClearAndSetEthPhyOcpBit(tp, + 0xbf46, + 0x0F00, + 0x0300 + ); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x8044); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x804A); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x8050); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x8056); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x805C); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x8062); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x8068); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x806E); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x8074); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + mdio_direct_write_phy_ocp(tp, 0xa436, 0x807A); + mdio_direct_write_phy_ocp(tp, 0xa438, 0x2417); + + + SetEthPhyOcpBit(tp, 0xA4CA, BIT_6); + + + ClearAndSetEthPhyOcpBit(tp, + 0xBF84, + BIT_15 | BIT_14 | BIT_13, + BIT_15 | BIT_13 + ); + + + mdio_direct_write_phy_ocp(tp, 0xA436, 0x8170); + ClearAndSetEthPhyOcpBit(tp, + 0xA438, + BIT_13 | BIT_10 | BIT_9 | BIT_8, + BIT_15 | BIT_14 | BIT_12 | BIT_11 + ); + + /* + mdio_direct_write_phy_ocp(tp, 0xBFA0, 0xD70D); + mdio_direct_write_phy_ocp(tp, 0xBFA2, 0x4100); + mdio_direct_write_phy_ocp(tp, 0xBFA4, 0xE868); + mdio_direct_write_phy_ocp(tp, 0xBFA6, 0xDC59); + mdio_direct_write_phy_ocp(tp, 0xB54C, 0x3C18); + ClearEthPhyOcpBit(tp, 0xBFA4, BIT_5); + mdio_direct_write_phy_ocp(tp, 0xA436, 0x817D); + SetEthPhyOcpBit(tp, 0xA438, BIT_12); + */ + + + if (aspm) { + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + rtl8125_enable_phy_aldps(tp); + } + } +} + +static void +rtl8125_hw_phy_config(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (tp->resume_not_chg_speed) return; + + tp->phy_reset_enable(dev); + + if (HW_DASH_SUPPORT_TYPE_3(tp) && tp->HwPkgDet == 0x06) return; + +#ifndef ENABLE_USE_FIRMWARE_FILE + if (!tp->rtl_fw) { + rtl8125_set_hw_phy_before_init_phy_mcu(dev); + + rtl8125_init_hw_phy_mcu(dev); + } +#endif + + switch (tp->mcfg) { + case CFG_METHOD_2: + rtl8125_hw_phy_config_8125a_1(dev); + break; + case CFG_METHOD_3: + case CFG_METHOD_6: + rtl8125_hw_phy_config_8125a_2(dev); + break; + case CFG_METHOD_4: + rtl8125_hw_phy_config_8125b_1(dev); + break; + case CFG_METHOD_5: + case CFG_METHOD_7: + rtl8125_hw_phy_config_8125b_2(dev); + break; + } + + //legacy force mode(Chap 22) + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + default: + rtl8125_mdio_write(tp, 0x1F, 0x0A5B); + rtl8125_clear_eth_phy_bit(tp, 0x12, BIT_15); + rtl8125_mdio_write(tp, 0x1F, 0x0000); + break; + } + + /*ocp phy power saving*/ + /* + if (aspm) { + if (tp->mcfg == CFG_METHOD_2 || tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_6) + rtl8125_enable_ocp_phy_power_saving(dev); + } + */ + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + + if (HW_HAS_WRITE_PHY_MCU_RAM_CODE(tp)) { + if (tp->eee.eee_enabled) + rtl8125_enable_eee(tp); + else + rtl8125_disable_eee(tp); + } +} + +static void +rtl8125_up(struct net_device *dev) +{ + rtl8125_hw_init(dev); + rtl8125_hw_reset(dev); + rtl8125_powerup_pll(dev); + rtl8125_hw_ephy_config(dev); + rtl8125_hw_phy_config(dev); + rtl8125_hw_config(dev); +} + +/* +static inline void rtl8125_delete_esd_timer(struct net_device *dev, struct timer_list *timer) +{ + del_timer_sync(timer); +} + +static inline void rtl8125_request_esd_timer(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->esd_timer; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + setup_timer(timer, rtl8125_esd_timer, (unsigned long)dev); +#else + timer_setup(timer, rtl8125_esd_timer, 0); +#endif + mod_timer(timer, jiffies + RTL8125_ESD_TIMEOUT); +} +*/ + +/* +static inline void rtl8125_delete_link_timer(struct net_device *dev, struct timer_list *timer) +{ + del_timer_sync(timer); +} + +static inline void rtl8125_request_link_timer(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->link_timer; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + setup_timer(timer, rtl8125_link_timer, (unsigned long)dev); +#else + timer_setup(timer, rtl8125_link_timer, 0); +#endif + mod_timer(timer, jiffies + RTL8125_LINK_TIMEOUT); +} +*/ + +#ifdef CONFIG_NET_POLL_CONTROLLER +/* + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. + */ +static void +rtl8125_netpoll(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + for (i = 0; i < tp->irq_nvecs; i++) { + struct r8125_irq *irq = &tp->irq_tbl[i]; + struct r8125_napi *r8125napi = &tp->r8125napi[i]; + + disable_irq(irq->vector); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0) + irq->handler(irq->vector, r8125napi); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + irq->handler(irq->vector, r8125napi, NULL); +#else + irq->handler(irq->vector, r8125napi); +#endif + + enable_irq(irq->vector); + } +} +#endif //CONFIG_NET_POLL_CONTROLLER + +static void +rtl8125_get_bios_setting(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->bios_setting = RTL_R32(tp, TimeInt2); + break; + } +} + +static void +rtl8125_set_bios_setting(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W32(tp, TimeInt2, tp->bios_setting); + break; + } +} + +static void +rtl8125_setup_mqs_reg(struct rtl8125_private *tp) +{ + int i; + + //tx + tp->tx_ring[0].tdsar_reg = TxDescStartAddrLow; + for (i = 1; i < R8125_MAX_TX_QUEUES; i++) { + tp->tx_ring[i].tdsar_reg = (u16)(TNPDS_Q1_LOW_8125 + (i - 1) * 8); + } + + for (i = 0; i < R8125_MAX_TX_QUEUES; i++) { + tp->tx_ring[i].hw_clo_ptr_reg = (u16)(HW_CLO_PTR0_8125 + i * 4); + tp->tx_ring[i].sw_tail_ptr_reg = (u16)(SW_TAIL_PTR0_8125 + i * 4); + } + + //rx + tp->rx_ring[0].rdsar_reg = RxDescAddrLow; + for (i = 1; i < R8125_MAX_RX_QUEUES; i++) { + tp->rx_ring[i].rdsar_reg = (u16)(RDSAR_Q1_LOW_8125 + (i - 1) * 8); + } + + tp->isr_reg[0] = ISR0_8125; + for (i = 1; i < R8125_MAX_QUEUES; i++) { + tp->isr_reg[i] = (u16)(ISR1_8125 + (i - 1) * 4); + } + + tp->imr_reg[0] = IMR0_8125; + for (i = 1; i < R8125_MAX_QUEUES; i++) { + tp->imr_reg[i] = (u16)(IMR1_8125 + (i - 1) * 4); + } +} + +static void +rtl8125_init_software_variable(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + + rtl8125_get_bios_setting(dev); + +#ifdef ENABLE_LIB_SUPPORT + tp->ring_lib_enabled = 1; +#endif + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + //tp->HwSuppDashVer = 3; + break; + default: + tp->HwSuppDashVer = 0; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwPkgDet = rtl8125_mac_ocp_read(tp, 0xDC00); + tp->HwPkgDet = (tp->HwPkgDet >> 3) & 0x07; + break; + } + + if (HW_DASH_SUPPORT_TYPE_3(tp) && tp->HwPkgDet == 0x06) + eee_enable = 0; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppNowIsOobVer = 1; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwPcieSNOffset = 0x16C; + break; + } + +#ifdef ENABLE_REALWOW_SUPPORT + rtl8125_get_realwow_hw_version(dev); +#endif //ENABLE_REALWOW_SUPPORT + + if (HW_DASH_SUPPORT_DASH(tp) && rtl8125_check_dash(tp)) + tp->DASH = 1; + else + tp->DASH = 0; + + if (tp->DASH) { + if (HW_DASH_SUPPORT_TYPE_3(tp)) { + u64 CmacMemPhysAddress; + void __iomem *cmac_ioaddr = NULL; + + //map CMAC IO space + CmacMemPhysAddress = rtl8125_csi_other_fun_read(tp, 0, 0x18); + if (!(CmacMemPhysAddress & BIT_0)) { + if (CmacMemPhysAddress & BIT_2) + CmacMemPhysAddress |= (u64)rtl8125_csi_other_fun_read(tp, 0, 0x1C) << 32; + + CmacMemPhysAddress &= 0xFFFFFFF0; + /* ioremap MMIO region */ + cmac_ioaddr = ioremap(CmacMemPhysAddress, R8125_REGS_SIZE); + } + + if (cmac_ioaddr == NULL) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "cannot remap CMAC MMIO, aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + } + + if (cmac_ioaddr == NULL) { + tp->DASH = 0; + } else { + tp->mapped_cmac_ioaddr = cmac_ioaddr; + } + } + + eee_enable = 0; + } + + if (HW_DASH_SUPPORT_TYPE_3(tp)) + tp->cmac_ioaddr = tp->mapped_cmac_ioaddr; + + if (aspm) { + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->org_pci_offset_99 = rtl8125_csi_fun0_read_byte(tp, 0x99); + tp->org_pci_offset_99 &= ~(BIT_5|BIT_6); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + tp->org_pci_offset_180 = rtl8125_csi_fun0_read_byte(tp, 0x264); + break; + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->org_pci_offset_180 = rtl8125_csi_fun0_read_byte(tp, 0x214); + break; + } + } + + pci_read_config_byte(pdev, 0x80, &tp->org_pci_offset_80); + pci_read_config_byte(pdev, 0x81, &tp->org_pci_offset_81); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + default: + tp->use_timer_interrrupt = TRUE; + break; + } + + if (timer_count == 0 || tp->mcfg == CFG_METHOD_DEFAULT) + tp->use_timer_interrrupt = FALSE; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppMagicPktVer = WAKEUP_MAGIC_PACKET_V3; + break; + default: + tp->HwSuppMagicPktVer = WAKEUP_MAGIC_PACKET_NOT_SUPPORT; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppLinkChgWakeUpVer = 3; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppD0SpeedUpVer = 1; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppCheckPhyDisableModeVer = 3; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppTxNoCloseVer = 3; + break; + } + + if (tp->HwSuppTxNoCloseVer > 0 && tx_no_close_enable == 1) + tp->EnableTxNoClose = TRUE; + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + tp->RequireLSOPatch = TRUE; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_2; + break; + case CFG_METHOD_3: + case CFG_METHOD_6: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_3; + break; + case CFG_METHOD_4: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_4; + break; + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->sw_ram_code_ver = NIC_RAMCODE_VERSION_CFG_METHOD_5; + break; + } + + if (tp->HwIcVerUnknown) { + tp->NotWrRamCodeToMicroP = TRUE; + tp->NotWrMcuPatchCode = TRUE; + } + + switch (tp->mcfg) { + case CFG_METHOD_3: + case CFG_METHOD_6: + if ((rtl8125_mac_ocp_read(tp, 0xD442) & BIT_5) && + (mdio_direct_read_phy_ocp(tp, 0xD068) & BIT_1)) + tp->RequirePhyMdiSwapPatch = TRUE; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppMacMcuVer = 2; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->MacMcuPageSize = RTL8125_MAC_MCU_PAGE_SIZE; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->HwSuppNumTxQueues = 2; + tp->HwSuppNumRxQueues = 4; + break; + default: + tp->HwSuppNumTxQueues = 1; + tp->HwSuppNumRxQueues = 1; + break; + } + + tp->num_tx_rings = 1; +#ifdef ENABLE_MULTIPLE_TX_QUEUE +#ifndef ENABLE_LIB_SUPPORT + tp->num_tx_rings = tp->HwSuppNumTxQueues; +#endif +#endif + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->HwSuppRssVer = 5; + tp->HwSuppIndirTblEntries = 128; + break; + } + + tp->num_rx_rings = 1; +#ifdef ENABLE_RSS_SUPPORT +#ifdef ENABLE_LIB_SUPPORT + if (tp->HwSuppRssVer > 0) + tp->EnableRss = 1; +#else + if (tp->HwSuppRssVer > 0) { + u8 rss_queue_num = netif_get_num_default_rss_queues(); + tp->num_rx_rings = (tp->HwSuppNumRxQueues > rss_queue_num)? + rss_queue_num : tp->HwSuppNumRxQueues; + + if (!(tp->num_rx_rings >= 2 && tp->irq_nvecs >= tp->num_rx_rings)) + tp->num_rx_rings = 1; + + if (tp->num_rx_rings >= 2) + tp->EnableRss = 1; + } +#endif +#endif + + rtl8125_setup_mqs_reg(tp); + + rtl8125_set_ring_size(tp, NUM_RX_DESC, NUM_TX_DESC); + + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->HwSuppPtpVer = 1; + break; + } +#ifdef ENABLE_PTP_SUPPORT + if (tp->HwSuppPtpVer > 0) + tp->EnablePtp = 1; +#endif + + //init interrupt + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->HwSuppIsrVer = 2; + break; + default: + tp->HwSuppIsrVer = 1; + break; + } + + tp->HwCurrIsrVer = tp->HwSuppIsrVer; + if (tp->HwSuppIsrVer == 2) { + if (!(tp->features & RTL_FEATURE_MSIX) || + tp->irq_nvecs < R8125_MIN_MSIX_VEC_8125B) + tp->HwCurrIsrVer = 1; + } + + if (tp->HwCurrIsrVer < 2 || tp->irq_nvecs < 19) + tp->num_tx_rings = 1; + + if (tp->HwCurrIsrVer == 2) { + int i; + + tp->intr_mask = ISRIMR_V2_LINKCHG | ISRIMR_TOK_Q0; + if (tp->num_tx_rings > 1) + tp->intr_mask |= ISRIMR_TOK_Q1; + + for (i = 0; i < tp->num_rx_rings; i++) + tp->intr_mask |= ISRIMR_V2_ROK_Q0 << i; + } else { + tp->intr_mask = LinkChg | RxDescUnavail | TxOK | RxOK | SWInt; + tp->timer_intr_mask = LinkChg | PCSTimeout; + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + if (HW_DASH_SUPPORT_TYPE_3(tp)) { + tp->timer_intr_mask |= ( ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); + tp->intr_mask |= ( ISRIMR_DASH_INTR_EN | ISRIMR_DASH_INTR_CMAC_RESET); + } + } +#endif + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_6: + tp->HwSuppIntMitiVer = 3; + break; + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->HwSuppIntMitiVer = 4; + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + tp->HwSuppExtendTallyCounterVer = 1; + break; + } + + timer_count_v2 = (timer_count / 0x100); + +#ifndef ENABLE_LIB_SUPPORT + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + if (tp->HwSuppIsrVer == 2) { + tp->RequireRduNonStopPatch = 1; + tp->EnableRss = 0; + } + break; + } +#endif + + tp->InitRxDescType = RX_DESC_RING_TYPE_1; + if (tp->EnableRss || tp->EnablePtp) + tp->InitRxDescType = RX_DESC_RING_TYPE_3; + + tp->RxDescLength = RX_DESC_LEN_TYPE_1; + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + tp->RxDescLength = RX_DESC_LEN_TYPE_3; + + tp->rtl8125_rx_config = rtl_chip_info[tp->chipset].RCR_Cfg; + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + tp->rtl8125_rx_config |= EnableRxDescV3; + + tp->NicCustLedValue = RTL_R16(tp, CustomLED); + + tp->wol_opts = rtl8125_get_hw_wol(tp); + tp->wol_enabled = (tp->wol_opts) ? WOL_ENABLED : WOL_DISABLED; + + if (tp->mcfg == CFG_METHOD_6 || tp->mcfg == CFG_METHOD_7) + rtl8125_link_option_giga((u8*)&autoneg_mode, (u32*)&speed_mode, (u8*)&duplex_mode, (u32*)&advertising_mode); + else + rtl8125_link_option((u8*)&autoneg_mode, (u32*)&speed_mode, (u8*)&duplex_mode, (u32*)&advertising_mode); + + tp->autoneg = autoneg_mode; + tp->speed = speed_mode; + tp->duplex = duplex_mode; + tp->advertising = advertising_mode; + tp->fcpause = rtl8125_fc_full; + + tp->max_jumbo_frame_size = rtl_chip_info[tp->chipset].jumbo_frame_sz; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + /* MTU range: 60 - hw-specific max */ + dev->min_mtu = ETH_MIN_MTU; + dev->max_mtu = tp->max_jumbo_frame_size; +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + + if (tp->mcfg != CFG_METHOD_DEFAULT) { + struct ethtool_eee *eee = &tp->eee; + + eee->eee_enabled = eee_enable; + eee->supported = SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full; + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + eee->supported |= SUPPORTED_2500baseX_Full; + break; + } + eee->advertised = mmd_eee_adv_to_ethtool_adv_t(MDIO_EEE_1000T | MDIO_EEE_100TX); + eee->tx_lpi_timer = dev->mtu + ETH_HLEN + 0x20; + } + + tp->ptp_master_mode = enable_ptp_master_mode; + +#ifdef ENABLE_RSS_SUPPORT + if (tp->EnableRss) + rtl8125_init_rss(tp); +#endif +} + +static void +rtl8125_release_board(struct pci_dev *pdev, + struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + + rtl8125_set_bios_setting(dev); + rtl8125_rar_set(tp, tp->org_mac_addr); + tp->wol_enabled = WOL_DISABLED; + + if (!tp->DASH) + rtl8125_phy_power_down(dev); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + FreeAllocatedDashShareMemory(dev); +#endif + + if (tp->mapped_cmac_ioaddr != NULL) + iounmap(tp->mapped_cmac_ioaddr); + + iounmap(ioaddr); + pci_release_regions(pdev); + pci_clear_mwi(pdev); + pci_disable_device(pdev); + free_netdev(dev); +} + +static void +rtl8125_hw_address_set(struct net_device *dev, u8 mac_addr[MAC_ADDR_LEN]) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) + eth_hw_addr_set(dev, mac_addr); +#else + memcpy(dev->dev_addr, mac_addr, MAC_ADDR_LEN); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,17,0) +} + +static int +rtl8125_get_mac_address(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + u8 mac_addr[MAC_ADDR_LEN]; + + for (i = 0; i < MAC_ADDR_LEN; i++) + mac_addr[i] = RTL_R8(tp, MAC0 + i); + + if(tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + *(u32*)&mac_addr[0] = RTL_R32(tp, BACKUP_ADDR0_8125); + *(u16*)&mac_addr[4] = RTL_R16(tp, BACKUP_ADDR1_8125); + } + + if (!is_valid_ether_addr(mac_addr)) { + netif_err(tp, probe, dev, "Invalid ether addr %pM\n", + mac_addr); + eth_random_addr(mac_addr); + dev->addr_assign_type = NET_ADDR_RANDOM; + netif_info(tp, probe, dev, "Random ether addr %pM\n", + mac_addr); + tp->random_mac = 1; + } + + rtl8125_hw_address_set(dev, mac_addr); + rtl8125_rar_set(tp, mac_addr); + + /* keep the original MAC address */ + memcpy(tp->org_mac_addr, dev->dev_addr, MAC_ADDR_LEN); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); +#endif + return 0; +} + +/** + * rtl8125_set_mac_address - Change the Ethernet Address of the NIC + * @dev: network interface device structure + * @p: pointer to an address structure + * + * Return 0 on success, negative on failure + **/ +static int +rtl8125_set_mac_address(struct net_device *dev, + void *p) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + rtl8125_hw_address_set(dev, addr->sa_data); + + rtl8125_rar_set(tp, dev->dev_addr); + + return 0; +} + +/****************************************************************************** + * rtl8125_rar_set - Puts an ethernet address into a receive address register. + * + * tp - The private data structure for driver + * addr - Address to put into receive address register + *****************************************************************************/ +void +rtl8125_rar_set(struct rtl8125_private *tp, + const u8 *addr) +{ + uint32_t rar_low = 0; + uint32_t rar_high = 0; + + rar_low = ((uint32_t) addr[0] | + ((uint32_t) addr[1] << 8) | + ((uint32_t) addr[2] << 16) | + ((uint32_t) addr[3] << 24)); + + rar_high = ((uint32_t) addr[4] | + ((uint32_t) addr[5] << 8)); + + rtl8125_enable_cfg9346_write(tp); + RTL_W32(tp, MAC0, rar_low); + RTL_W32(tp, MAC4, rar_high); + + rtl8125_disable_cfg9346_write(tp); +} + +#ifdef ETHTOOL_OPS_COMPAT +static int ethtool_get_settings(struct net_device *dev, void *useraddr) +{ + struct ethtool_cmd cmd = { ETHTOOL_GSET }; + int err; + + if (!ethtool_ops->get_settings) + return -EOPNOTSUPP; + + err = ethtool_ops->get_settings(dev, &cmd); + if (err < 0) + return err; + + if (copy_to_user(useraddr, &cmd, sizeof(cmd))) + return -EFAULT; + return 0; +} + +static int ethtool_set_settings(struct net_device *dev, void *useraddr) +{ + struct ethtool_cmd cmd; + + if (!ethtool_ops->set_settings) + return -EOPNOTSUPP; + + if (copy_from_user(&cmd, useraddr, sizeof(cmd))) + return -EFAULT; + + return ethtool_ops->set_settings(dev, &cmd); +} + +static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr) +{ + struct ethtool_drvinfo info; + struct ethtool_ops *ops = ethtool_ops; + + if (!ops->get_drvinfo) + return -EOPNOTSUPP; + + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + ops->get_drvinfo(dev, &info); + + if (ops->self_test_count) + info.testinfo_len = ops->self_test_count(dev); + if (ops->get_stats_count) + info.n_stats = ops->get_stats_count(dev); + if (ops->get_regs_len) + info.regdump_len = ops->get_regs_len(dev); + if (ops->get_eeprom_len) + info.eedump_len = ops->get_eeprom_len(dev); + + if (copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; +} + +static int ethtool_get_regs(struct net_device *dev, char *useraddr) +{ + struct ethtool_regs regs; + struct ethtool_ops *ops = ethtool_ops; + void *regbuf; + int reglen, ret; + + if (!ops->get_regs || !ops->get_regs_len) + return -EOPNOTSUPP; + + if (copy_from_user(®s, useraddr, sizeof(regs))) + return -EFAULT; + + reglen = ops->get_regs_len(dev); + if (regs.len > reglen) + regs.len = reglen; + + regbuf = kmalloc(reglen, GFP_USER); + if (!regbuf) + return -ENOMEM; + + ops->get_regs(dev, ®s, regbuf); + + ret = -EFAULT; + if (copy_to_user(useraddr, ®s, sizeof(regs))) + goto out; + useraddr += offsetof(struct ethtool_regs, data); + if (copy_to_user(useraddr, regbuf, reglen)) + goto out; + ret = 0; + +out: + kfree(regbuf); + return ret; +} + +static int ethtool_get_wol(struct net_device *dev, char *useraddr) +{ + struct ethtool_wolinfo wol = { ETHTOOL_GWOL }; + + if (!ethtool_ops->get_wol) + return -EOPNOTSUPP; + + ethtool_ops->get_wol(dev, &wol); + + if (copy_to_user(useraddr, &wol, sizeof(wol))) + return -EFAULT; + return 0; +} + +static int ethtool_set_wol(struct net_device *dev, char *useraddr) +{ + struct ethtool_wolinfo wol; + + if (!ethtool_ops->set_wol) + return -EOPNOTSUPP; + + if (copy_from_user(&wol, useraddr, sizeof(wol))) + return -EFAULT; + + return ethtool_ops->set_wol(dev, &wol); +} + +static int ethtool_get_msglevel(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + + if (!ethtool_ops->get_msglevel) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_msglevel(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_msglevel(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_msglevel) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + ethtool_ops->set_msglevel(dev, edata.data); + return 0; +} + +static int ethtool_nway_reset(struct net_device *dev) +{ + if (!ethtool_ops->nway_reset) + return -EOPNOTSUPP; + + return ethtool_ops->nway_reset(dev); +} + +static int ethtool_get_link(struct net_device *dev, void *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GLINK }; + + if (!ethtool_ops->get_link) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_link(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_get_eeprom(struct net_device *dev, void *useraddr) +{ + struct ethtool_eeprom eeprom; + struct ethtool_ops *ops = ethtool_ops; + u8 *data; + int ret; + + if (!ops->get_eeprom || !ops->get_eeprom_len) + return -EOPNOTSUPP; + + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) + return -EFAULT; + + /* Check for wrap and zero */ + if (eeprom.offset + eeprom.len <= eeprom.offset) + return -EINVAL; + + /* Check for exceeding total eeprom len */ + if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) + return -EINVAL; + + data = kmalloc(eeprom.len, GFP_USER); + if (!data) + return -ENOMEM; + + ret = -EFAULT; + if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) + goto out; + + ret = ops->get_eeprom(dev, &eeprom, data); + if (ret) + goto out; + + ret = -EFAULT; + if (copy_to_user(useraddr, &eeprom, sizeof(eeprom))) + goto out; + if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_set_eeprom(struct net_device *dev, void *useraddr) +{ + struct ethtool_eeprom eeprom; + struct ethtool_ops *ops = ethtool_ops; + u8 *data; + int ret; + + if (!ops->set_eeprom || !ops->get_eeprom_len) + return -EOPNOTSUPP; + + if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) + return -EFAULT; + + /* Check for wrap and zero */ + if (eeprom.offset + eeprom.len <= eeprom.offset) + return -EINVAL; + + /* Check for exceeding total eeprom len */ + if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) + return -EINVAL; + + data = kmalloc(eeprom.len, GFP_USER); + if (!data) + return -ENOMEM; + + ret = -EFAULT; + if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) + goto out; + + ret = ops->set_eeprom(dev, &eeprom, data); + if (ret) + goto out; + + if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len)) + ret = -EFAULT; + +out: + kfree(data); + return ret; +} + +static int ethtool_get_coalesce(struct net_device *dev, void *useraddr) +{ + struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; + + if (!ethtool_ops->get_coalesce) + return -EOPNOTSUPP; + + ethtool_ops->get_coalesce(dev, &coalesce); + + if (copy_to_user(useraddr, &coalesce, sizeof(coalesce))) + return -EFAULT; + return 0; +} + +static int ethtool_set_coalesce(struct net_device *dev, void *useraddr) +{ + struct ethtool_coalesce coalesce; + + if (!ethtool_ops->get_coalesce) + return -EOPNOTSUPP; + + if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) + return -EFAULT; + + return ethtool_ops->set_coalesce(dev, &coalesce); +} + +static int ethtool_get_ringparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; + + if (!ethtool_ops->get_ringparam) + return -EOPNOTSUPP; + + ethtool_ops->get_ringparam(dev, &ringparam); + + if (copy_to_user(useraddr, &ringparam, sizeof(ringparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_ringparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_ringparam ringparam; + + if (!ethtool_ops->get_ringparam) + return -EOPNOTSUPP; + + if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) + return -EFAULT; + + return ethtool_ops->set_ringparam(dev, &ringparam); +} + +static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; + + if (!ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + ethtool_ops->get_pauseparam(dev, &pauseparam); + + if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam))) + return -EFAULT; + return 0; +} + +static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr) +{ + struct ethtool_pauseparam pauseparam; + + if (!ethtool_ops->get_pauseparam) + return -EOPNOTSUPP; + + if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) + return -EFAULT; + + return ethtool_ops->set_pauseparam(dev, &pauseparam); +} + +static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GRXCSUM }; + + if (!ethtool_ops->get_rx_csum) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_rx_csum(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_rx_csum) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + ethtool_ops->set_rx_csum(dev, edata.data); + return 0; +} + +static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTXCSUM }; + + if (!ethtool_ops->get_tx_csum) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_tx_csum(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_tx_csum) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return ethtool_ops->set_tx_csum(dev, edata.data); +} + +static int ethtool_get_sg(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GSG }; + + if (!ethtool_ops->get_sg) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_sg(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_sg(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_sg) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return ethtool_ops->set_sg(dev, edata.data); +} + +static int ethtool_get_tso(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata = { ETHTOOL_GTSO }; + + if (!ethtool_ops->get_tso) + return -EOPNOTSUPP; + + edata.data = ethtool_ops->get_tso(dev); + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; +} + +static int ethtool_set_tso(struct net_device *dev, char *useraddr) +{ + struct ethtool_value edata; + + if (!ethtool_ops->set_tso) + return -EOPNOTSUPP; + + if (copy_from_user(&edata, useraddr, sizeof(edata))) + return -EFAULT; + + return ethtool_ops->set_tso(dev, edata.data); +} + +static int ethtool_self_test(struct net_device *dev, char *useraddr) +{ + struct ethtool_test test; + struct ethtool_ops *ops = ethtool_ops; + u64 *data; + int ret; + + if (!ops->self_test || !ops->self_test_count) + return -EOPNOTSUPP; + + if (copy_from_user(&test, useraddr, sizeof(test))) + return -EFAULT; + + test.len = ops->self_test_count(dev); + data = kmalloc(test.len * sizeof(u64), GFP_USER); + if (!data) + return -ENOMEM; + + ops->self_test(dev, &test, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &test, sizeof(test))) + goto out; + useraddr += sizeof(test); + if (copy_to_user(useraddr, data, test.len * sizeof(u64))) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_get_strings(struct net_device *dev, void *useraddr) +{ + struct ethtool_gstrings gstrings; + struct ethtool_ops *ops = ethtool_ops; + u8 *data; + int ret; + + if (!ops->get_strings) + return -EOPNOTSUPP; + + if (copy_from_user(&gstrings, useraddr, sizeof(gstrings))) + return -EFAULT; + + switch (gstrings.string_set) { + case ETH_SS_TEST: + if (!ops->self_test_count) + return -EOPNOTSUPP; + gstrings.len = ops->self_test_count(dev); + break; + case ETH_SS_STATS: + if (!ops->get_stats_count) + return -EOPNOTSUPP; + gstrings.len = ops->get_stats_count(dev); + break; + default: + return -EINVAL; + } + + data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); + if (!data) + return -ENOMEM; + + ops->get_strings(dev, gstrings.string_set, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &gstrings, sizeof(gstrings))) + goto out; + useraddr += sizeof(gstrings); + if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN)) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_phys_id(struct net_device *dev, void *useraddr) +{ + struct ethtool_value id; + + if (!ethtool_ops->phys_id) + return -EOPNOTSUPP; + + if (copy_from_user(&id, useraddr, sizeof(id))) + return -EFAULT; + + return ethtool_ops->phys_id(dev, id.data); +} + +static int ethtool_get_stats(struct net_device *dev, void *useraddr) +{ + struct ethtool_stats stats; + struct ethtool_ops *ops = ethtool_ops; + u64 *data; + int ret; + + if (!ops->get_ethtool_stats || !ops->get_stats_count) + return -EOPNOTSUPP; + + if (copy_from_user(&stats, useraddr, sizeof(stats))) + return -EFAULT; + + stats.n_stats = ops->get_stats_count(dev); + data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER); + if (!data) + return -ENOMEM; + + ops->get_ethtool_stats(dev, &stats, data); + + ret = -EFAULT; + if (copy_to_user(useraddr, &stats, sizeof(stats))) + goto out; + useraddr += sizeof(stats); + if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64))) + goto out; + ret = 0; + +out: + kfree(data); + return ret; +} + +static int ethtool_ioctl(struct ifreq *ifr) +{ + struct net_device *dev = __dev_get_by_name(ifr->ifr_name); + void *useraddr = (void *) ifr->ifr_data; + u32 ethcmd; + + /* + * XXX: This can be pushed down into the ethtool_* handlers that + * need it. Keep existing behaviour for the moment. + */ + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!dev || !netif_device_present(dev)) + return -ENODEV; + + if (copy_from_user(ðcmd, useraddr, sizeof (ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GSET: + return ethtool_get_settings(dev, useraddr); + case ETHTOOL_SSET: + return ethtool_set_settings(dev, useraddr); + case ETHTOOL_GDRVINFO: + return ethtool_get_drvinfo(dev, useraddr); + case ETHTOOL_GREGS: + return ethtool_get_regs(dev, useraddr); + case ETHTOOL_GWOL: + return ethtool_get_wol(dev, useraddr); + case ETHTOOL_SWOL: + return ethtool_set_wol(dev, useraddr); + case ETHTOOL_GMSGLVL: + return ethtool_get_msglevel(dev, useraddr); + case ETHTOOL_SMSGLVL: + return ethtool_set_msglevel(dev, useraddr); + case ETHTOOL_NWAY_RST: + return ethtool_nway_reset(dev); + case ETHTOOL_GLINK: + return ethtool_get_link(dev, useraddr); + case ETHTOOL_GEEPROM: + return ethtool_get_eeprom(dev, useraddr); + case ETHTOOL_SEEPROM: + return ethtool_set_eeprom(dev, useraddr); + case ETHTOOL_GCOALESCE: + return ethtool_get_coalesce(dev, useraddr); + case ETHTOOL_SCOALESCE: + return ethtool_set_coalesce(dev, useraddr); + case ETHTOOL_GRINGPARAM: + return ethtool_get_ringparam(dev, useraddr); + case ETHTOOL_SRINGPARAM: + return ethtool_set_ringparam(dev, useraddr); + case ETHTOOL_GPAUSEPARAM: + return ethtool_get_pauseparam(dev, useraddr); + case ETHTOOL_SPAUSEPARAM: + return ethtool_set_pauseparam(dev, useraddr); + case ETHTOOL_GRXCSUM: + return ethtool_get_rx_csum(dev, useraddr); + case ETHTOOL_SRXCSUM: + return ethtool_set_rx_csum(dev, useraddr); + case ETHTOOL_GTXCSUM: + return ethtool_get_tx_csum(dev, useraddr); + case ETHTOOL_STXCSUM: + return ethtool_set_tx_csum(dev, useraddr); + case ETHTOOL_GSG: + return ethtool_get_sg(dev, useraddr); + case ETHTOOL_SSG: + return ethtool_set_sg(dev, useraddr); + case ETHTOOL_GTSO: + return ethtool_get_tso(dev, useraddr); + case ETHTOOL_STSO: + return ethtool_set_tso(dev, useraddr); + case ETHTOOL_TEST: + return ethtool_self_test(dev, useraddr); + case ETHTOOL_GSTRINGS: + return ethtool_get_strings(dev, useraddr); + case ETHTOOL_PHYS_ID: + return ethtool_phys_id(dev, useraddr); + case ETHTOOL_GSTATS: + return ethtool_get_stats(dev, useraddr); + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; +} +#endif //ETHTOOL_OPS_COMPAT + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0) +static int rtl8125_siocdevprivate(struct net_device *dev, struct ifreq *ifr, + void __user *data, int cmd) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ret = 0; + + switch (cmd) { +#ifdef ENABLE_DASH_SUPPORT + case SIOCDEVPRIVATE_RTLDASH: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8125_dash_ioctl(dev, ifr); + break; +#endif + +#ifdef ENABLE_REALWOW_SUPPORT + case SIOCDEVPRIVATE_RTLREALWOW: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + + ret = rtl8125_realwow_ioctl(dev, ifr); + break; +#endif + + case SIOCRTLTOOL: + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8125_tool_ioctl(tp, ifr); + break; + + default: + ret = -EOPNOTSUPP; + } + + return ret; +} +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0) + +static int +rtl8125_do_ioctl(struct net_device *dev, + struct ifreq *ifr, + int cmd) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct mii_ioctl_data *data = if_mii(ifr); + int ret = 0; + + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = 32; /* Internal PHY */ + break; + + case SIOCGMIIREG: + rtl8125_mdio_write(tp, 0x1F, 0x0000); + data->val_out = rtl8125_mdio_read(tp, data->reg_num); + break; + + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + rtl8125_mdio_write(tp, 0x1F, 0x0000); + rtl8125_mdio_write(tp, data->reg_num, data->val_in); + break; + +#ifdef ETHTOOL_OPS_COMPAT + case SIOCETHTOOL: + ret = ethtool_ioctl(ifr); + break; +#endif + +#ifdef ENABLE_PTP_SUPPORT + case SIOCSHWTSTAMP: + case SIOCGHWTSTAMP: + if (tp->EnablePtp) + ret = rtl8125_ptp_ioctl(dev, ifr, cmd); + else + ret = -EOPNOTSUPP; + break; +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) +#ifdef ENABLE_DASH_SUPPORT + case SIOCDEVPRIVATE_RTLDASH: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8125_dash_ioctl(dev, ifr); + break; +#endif + +#ifdef ENABLE_REALWOW_SUPPORT + case SIOCDEVPRIVATE_RTLREALWOW: + if (!netif_running(dev)) { + ret = -ENODEV; + break; + } + + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8125_realwow_ioctl(dev, ifr); + break; +#endif + + case SIOCRTLTOOL: + if (!capable(CAP_NET_ADMIN)) { + ret = -EPERM; + break; + } + + ret = rtl8125_tool_ioctl(tp, ifr); + break; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +static void +rtl8125_phy_power_up(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (rtl8125_is_in_phy_disable_mode(dev)) { + return; + } + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + rtl8125_mdio_write(tp, MII_BMCR, BMCR_ANENABLE); + + //wait ups resume (phy state 3) + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_wait_phy_ups_resume(dev, 3); + break; + }; +} + +static void +rtl8125_phy_power_down(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + rtl8125_mdio_write(tp, 0x1F, 0x0000); + rtl8125_mdio_write(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); +} + +static int __devinit +rtl8125_init_board(struct pci_dev *pdev, + struct net_device **dev_out, + void __iomem **ioaddr_out) +{ + void __iomem *ioaddr; + struct net_device *dev; + struct rtl8125_private *tp; + int rc = -ENOMEM, i, pm_cap; + + assert(ioaddr_out != NULL); + + /* dev zeroed in alloc_etherdev */ + dev = alloc_etherdev_mq(sizeof (*tp), R8125_MAX_QUEUES); + if (dev == NULL) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_drv(&debug)) + dev_err(&pdev->dev, "unable to alloc new ethernet\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out; + } + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + tp = netdev_priv(dev); + tp->dev = dev; + tp->pci_dev = pdev; + tp->msg_enable = netif_msg_init(debug.msg_enable, R8125_MSG_DEFAULT); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) + if (!aspm) + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); +#endif + + /* enable device (incl. PCI PM wakeup and hotplug setup) */ + rc = pci_enable_device(pdev); + if (rc < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "enable failure\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out_free_dev; + } + + if (pci_set_mwi(pdev) < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_drv(&debug)) + dev_info(&pdev->dev, "Mem-Wr-Inval unavailable.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + } + + /* save power state before pci_enable_device overwrites it */ + pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pm_cap) { + u16 pwr_command; + + pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command); + } else { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) { + dev_err(&pdev->dev, "PowerManagement capability not found.\n"); + } +#else + printk("PowerManagement capability not found.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + + } + + /* make sure PCI base addr 1 is MMIO */ + if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + rc = -ENODEV; + goto err_out_mwi; + } + /* check for weird/broken PCI region reporting */ + if (pci_resource_len(pdev, 2) < R8125_REGS_SIZE) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "Invalid PCI region size(s), aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + rc = -ENODEV; + goto err_out_mwi; + } + + rc = pci_request_regions(pdev, MODULENAME); + if (rc < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "could not request regions.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out_mwi; + } + + if ((sizeof(dma_addr_t) > 4) && + use_dac && + !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && + !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + dev->features |= NETIF_F_HIGHDMA; + } else { + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (rc < 0) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "DMA configuration failed.\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + goto err_out_free_res; + } + } + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); + if (ioaddr == NULL) { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_err(&pdev->dev, "cannot remap MMIO, aborting\n"); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + rc = -EIO; + goto err_out_free_res; + } + + tp->mmio_addr = ioaddr; + + /* Identify chip attached to board */ + rtl8125_get_mac_version(tp); + + rtl8125_print_mac_version(tp); + + for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { + if (tp->mcfg == rtl_chip_info[i].mcfg) + break; + } + + if (i < 0) { + /* Unknown chip: assume array element #0, original RTL-8125 */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (netif_msg_probe(tp)) + dev_printk(KERN_DEBUG, &pdev->dev, "unknown chip version, assuming %s\n", rtl_chip_info[0].name); +#else + printk("Realtek unknown chip version, assuming %s\n", rtl_chip_info[0].name); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + i++; + } + + tp->chipset = i; + + *ioaddr_out = ioaddr; + *dev_out = dev; +out: + return rc; + +err_out_free_res: + pci_release_regions(pdev); +err_out_mwi: + pci_clear_mwi(pdev); + pci_disable_device(pdev); +err_out_free_dev: + free_netdev(dev); +err_out: + *ioaddr_out = NULL; + *dev_out = NULL; + goto out; +} + +static void +rtl8125_esd_checker(struct rtl8125_private *tp) +{ + struct net_device *dev = tp->dev; + struct pci_dev *pdev = tp->pci_dev; + u8 cmd; + u16 io_base_l; + u16 mem_base_l; + u16 mem_base_h; + u8 ilr; + u16 resv_0x1c_h; + u16 resv_0x1c_l; + u16 resv_0x20_l; + u16 resv_0x20_h; + u16 resv_0x24_l; + u16 resv_0x24_h; + u16 resv_0x2c_h; + u16 resv_0x2c_l; + u32 pci_sn_l; + u32 pci_sn_h; + + if (unlikely(tp->rtk_enable_diag)) + goto exit; + + tp->esd_flag = 0; + + pci_read_config_byte(pdev, PCI_COMMAND, &cmd); + if (cmd != tp->pci_cfg_space.cmd) { + printk(KERN_ERR "%s: cmd = 0x%02x, should be 0x%02x \n.", dev->name, cmd, tp->pci_cfg_space.cmd); + pci_write_config_byte(pdev, PCI_COMMAND, tp->pci_cfg_space.cmd); + tp->esd_flag |= BIT_0; + + pci_read_config_byte(pdev, PCI_COMMAND, &cmd); + if (cmd == 0xff) { + printk(KERN_ERR "%s: pci link is down \n.", dev->name); + goto exit; + } + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_0, &io_base_l); + if (io_base_l != tp->pci_cfg_space.io_base_l) { + printk(KERN_ERR "%s: io_base_l = 0x%04x, should be 0x%04x \n.", dev->name, io_base_l, tp->pci_cfg_space.io_base_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_0, tp->pci_cfg_space.io_base_l); + tp->esd_flag |= BIT_1; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2, &mem_base_l); + if (mem_base_l != tp->pci_cfg_space.mem_base_l) { + printk(KERN_ERR "%s: mem_base_l = 0x%04x, should be 0x%04x \n.", dev->name, mem_base_l, tp->pci_cfg_space.mem_base_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_2, tp->pci_cfg_space.mem_base_l); + tp->esd_flag |= BIT_2; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, &mem_base_h); + if (mem_base_h!= tp->pci_cfg_space.mem_base_h) { + printk(KERN_ERR "%s: mem_base_h = 0x%04x, should be 0x%04x \n.", dev->name, mem_base_h, tp->pci_cfg_space.mem_base_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, tp->pci_cfg_space.mem_base_h); + tp->esd_flag |= BIT_3; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3, &resv_0x1c_l); + if (resv_0x1c_l != tp->pci_cfg_space.resv_0x1c_l) { + printk(KERN_ERR "%s: resv_0x1c_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x1c_l, tp->pci_cfg_space.resv_0x1c_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_3, tp->pci_cfg_space.resv_0x1c_l); + tp->esd_flag |= BIT_4; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3 + 2, &resv_0x1c_h); + if (resv_0x1c_h != tp->pci_cfg_space.resv_0x1c_h) { + printk(KERN_ERR "%s: resv_0x1c_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x1c_h, tp->pci_cfg_space.resv_0x1c_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_3 + 2, tp->pci_cfg_space.resv_0x1c_h); + tp->esd_flag |= BIT_5; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4, &resv_0x20_l); + if (resv_0x20_l != tp->pci_cfg_space.resv_0x20_l) { + printk(KERN_ERR "%s: resv_0x20_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x20_l, tp->pci_cfg_space.resv_0x20_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_4, tp->pci_cfg_space.resv_0x20_l); + tp->esd_flag |= BIT_6; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, &resv_0x20_h); + if (resv_0x20_h != tp->pci_cfg_space.resv_0x20_h) { + printk(KERN_ERR "%s: resv_0x20_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x20_h, tp->pci_cfg_space.resv_0x20_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, tp->pci_cfg_space.resv_0x20_h); + tp->esd_flag |= BIT_7; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5, &resv_0x24_l); + if (resv_0x24_l != tp->pci_cfg_space.resv_0x24_l) { + printk(KERN_ERR "%s: resv_0x24_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x24_l, tp->pci_cfg_space.resv_0x24_l); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_5, tp->pci_cfg_space.resv_0x24_l); + tp->esd_flag |= BIT_8; + } + + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, &resv_0x24_h); + if (resv_0x24_h != tp->pci_cfg_space.resv_0x24_h) { + printk(KERN_ERR "%s: resv_0x24_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x24_h, tp->pci_cfg_space.resv_0x24_h); + pci_write_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, tp->pci_cfg_space.resv_0x24_h); + tp->esd_flag |= BIT_9; + } + + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &ilr); + if (ilr != tp->pci_cfg_space.ilr) { + printk(KERN_ERR "%s: ilr = 0x%02x, should be 0x%02x \n.", dev->name, ilr, tp->pci_cfg_space.ilr); + pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, tp->pci_cfg_space.ilr); + tp->esd_flag |= BIT_10; + } + + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &resv_0x2c_l); + if (resv_0x2c_l != tp->pci_cfg_space.resv_0x2c_l) { + printk(KERN_ERR "%s: resv_0x2c_l = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x2c_l, tp->pci_cfg_space.resv_0x2c_l); + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, tp->pci_cfg_space.resv_0x2c_l); + tp->esd_flag |= BIT_11; + } + + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID + 2, &resv_0x2c_h); + if (resv_0x2c_h != tp->pci_cfg_space.resv_0x2c_h) { + printk(KERN_ERR "%s: resv_0x2c_h = 0x%04x, should be 0x%04x \n.", dev->name, resv_0x2c_h, tp->pci_cfg_space.resv_0x2c_h); + pci_write_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID + 2, tp->pci_cfg_space.resv_0x2c_h); + tp->esd_flag |= BIT_12; + } + + if (tp->HwPcieSNOffset > 0) { + pci_sn_l = rtl8125_csi_read(tp, tp->HwPcieSNOffset); + if (pci_sn_l != tp->pci_cfg_space.pci_sn_l) { + printk(KERN_ERR "%s: pci_sn_l = 0x%08x, should be 0x%08x \n.", dev->name, pci_sn_l, tp->pci_cfg_space.pci_sn_l); + rtl8125_csi_write(tp, tp->HwPcieSNOffset, tp->pci_cfg_space.pci_sn_l); + tp->esd_flag |= BIT_13; + } + + pci_sn_h = rtl8125_csi_read(tp, tp->HwPcieSNOffset + 4); + if (pci_sn_h != tp->pci_cfg_space.pci_sn_h) { + printk(KERN_ERR "%s: pci_sn_h = 0x%08x, should be 0x%08x \n.", dev->name, pci_sn_h, tp->pci_cfg_space.pci_sn_h); + rtl8125_csi_write(tp, tp->HwPcieSNOffset + 4, tp->pci_cfg_space.pci_sn_h); + tp->esd_flag |= BIT_14; + } + } + + if (tp->esd_flag != 0) { + printk(KERN_ERR "%s: esd_flag = 0x%04x\n.\n", dev->name, tp->esd_flag); + netif_tx_stop_all_queues(dev); + netif_carrier_off(dev); + rtl8125_hw_reset(dev); + rtl8125_tx_clear(tp); + rtl8125_rx_clear(tp); + rtl8125_init_ring(dev); + rtl8125_up(dev); + rtl8125_enable_hw_linkchg_interrupt(tp); + rtl8125_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + tp->esd_flag = 0; + } +exit: + return; +} +/* +static void +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +rtl8125_esd_timer(unsigned long __opaque) +#else +rtl8125_esd_timer(struct timer_list *t) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + struct net_device *dev = (struct net_device *)__opaque; + struct rtl8125_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->esd_timer; +#else + struct rtl8125_private *tp = from_timer(tp, t, esd_timer); + //struct net_device *dev = tp->dev; + struct timer_list *timer = t; +#endif + rtl8125_esd_checker(tp); + + mod_timer(timer, jiffies + timeout); +} +*/ + +/* +static void +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) +rtl8125_link_timer(unsigned long __opaque) +#else +rtl8125_link_timer(struct timer_list *t) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,14,0) + struct net_device *dev = (struct net_device *)__opaque; + struct rtl8125_private *tp = netdev_priv(dev); + struct timer_list *timer = &tp->link_timer; +#else + struct rtl8125_private *tp = from_timer(tp, t, link_timer); + struct net_device *dev = tp->dev; + struct timer_list *timer = t; +#endif + rtl8125_check_link_status(dev); + + mod_timer(timer, jiffies + RTL8125_LINK_TIMEOUT); +} +*/ + +int +rtl8125_enable_msix(struct rtl8125_private *tp) +{ + int i, nvecs = 0; + struct msix_entry msix_ent[R8125_MAX_MSIX_VEC]; + //struct net_device *dev = tp->dev; + //const int len = sizeof(tp->irq_tbl[0].name); + + for (i = 0; i < R8125_MAX_MSIX_VEC; i++) { + msix_ent[i].entry = i; + msix_ent[i].vector = 0; + } + + nvecs = pci_enable_msix_range(tp->pci_dev, msix_ent, + tp->min_irq_nvecs, tp->max_irq_nvecs); + if (nvecs < 0) + goto out; + + for (i = 0; i < nvecs; i++) { + struct r8125_irq *irq = &tp->irq_tbl[i]; + irq->vector = msix_ent[i].vector; + //snprintf(irq->name, len, "%s-%d", dev->name, i); + //irq->handler = rtl8125_interrupt_msix; + } + +out: + return nvecs; +} + +void rtl8125_dump_msix_tbl(struct rtl8125_private *tp) +{ + void __iomem *ioaddr; + + /* ioremap MMIO region */ + ioaddr = ioremap(pci_resource_start(tp->pci_dev, 4), pci_resource_len(tp->pci_dev, 4)); + if (ioaddr) { + int i = 0; + for (i=0; iirq_nvecs; i++) { + printk("entry 0x%d %08X %08X %08X %08X \n", + i, + readl(ioaddr + 16 * i), + readl(ioaddr + 16 * i + 4), + readl(ioaddr + 16 * i + 8), + readl(ioaddr + 16 * i + 12)); + } + iounmap(ioaddr); + } +} + +/* Cfg9346_Unlock assumed. */ +static int rtl8125_try_msi(struct rtl8125_private *tp) +{ + struct pci_dev *pdev = tp->pci_dev; + unsigned msi = 0; + int nvecs = 1; + + tp->max_irq_nvecs = 1; + tp->min_irq_nvecs = 1; +#ifndef DISABLE_MULTI_MSIX_VECTOR + switch (tp->mcfg) { + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_7: + tp->max_irq_nvecs = R8125_MAX_MSIX_VEC_8125B; + tp->min_irq_nvecs = R8125_MIN_MSIX_VEC_8125B; + break; + } +#endif + +#if defined(RTL_USE_NEW_INTR_API) + if ((nvecs = pci_alloc_irq_vectors(pdev, tp->min_irq_nvecs, tp->max_irq_nvecs, PCI_IRQ_MSIX)) > 0) + msi |= RTL_FEATURE_MSIX; + else if ((nvecs = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES)) > 0 && + pci_dev_msi_enabled(pdev)) + msi |= RTL_FEATURE_MSI; +#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + if ((nvecs = rtl8125_enable_msix(tp)) > 0) + msi |= RTL_FEATURE_MSIX; + else if (!pci_enable_msi(pdev)) + msi |= RTL_FEATURE_MSI; +#endif + if (!(msi & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))) + dev_info(&pdev->dev, "no MSI/MSI-X. Back to INTx.\n"); + + if (!(msi & RTL_FEATURE_MSIX) || nvecs < 1) + nvecs = 1; + + tp->irq_nvecs = nvecs; + + tp->features |= msi; + + return nvecs; +} + +static void rtl8125_disable_msi(struct pci_dev *pdev, struct rtl8125_private *tp) +{ +#if defined(RTL_USE_NEW_INTR_API) + if (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)) + pci_free_irq_vectors(pdev); +#elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13) + if (tp->features & (RTL_FEATURE_MSIX)) + pci_disable_msix(pdev); + else if (tp->features & (RTL_FEATURE_MSI)) + pci_disable_msi(pdev); +#endif + tp->features &= ~(RTL_FEATURE_MSI | RTL_FEATURE_MSIX); +} + +static int rtl8125_get_irq(struct pci_dev *pdev) +{ +#if defined(RTL_USE_NEW_INTR_API) + return pci_irq_vector(pdev, 0); +#else + return pdev->irq; +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +static const struct net_device_ops rtl8125_netdev_ops = { + .ndo_open = rtl8125_open, + .ndo_stop = rtl8125_close, + .ndo_get_stats = rtl8125_get_stats, + .ndo_start_xmit = rtl8125_start_xmit, + .ndo_tx_timeout = rtl8125_tx_timeout, + .ndo_change_mtu = rtl8125_change_mtu, + .ndo_set_mac_address = rtl8125_set_mac_address, +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) + .ndo_do_ioctl = rtl8125_do_ioctl, +#else + .ndo_siocdevprivate = rtl8125_siocdevprivate, + .ndo_eth_ioctl = rtl8125_do_ioctl, +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(5,15,0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0) + .ndo_set_multicast_list = rtl8125_set_rx_mode, +#else + .ndo_set_rx_mode = rtl8125_set_rx_mode, +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) +#ifdef CONFIG_R8125_VLAN + .ndo_vlan_rx_register = rtl8125_vlan_rx_register, +#endif +#else + .ndo_fix_features = rtl8125_fix_features, + .ndo_set_features = rtl8125_set_features, +#endif +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = rtl8125_netpoll, +#endif +}; +#endif + + +#ifdef CONFIG_R8125_NAPI + +static int rtl8125_poll(napi_ptr napi, napi_budget budget) +{ + struct r8125_napi *r8125napi = RTL_GET_PRIV(napi, struct r8125_napi); + struct rtl8125_private *tp = r8125napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + int i; + + for (i = 0; i < tp->num_tx_rings; i++) + rtl8125_tx_interrupt(&tp->tx_ring[i], budget); + + for (i = 0; i < tp->num_rx_rings; i++) + work_done += rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[i], budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + HandleDashInterrupt(tp->dev); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8125_switch_to_timer_interrupt(tp); + } + + return RTL_NAPI_RETURN_VALUE; +} + +#if 0 +static int rtl8125_poll_msix_ring(napi_ptr napi, napi_budget budget) +{ + struct r8125_napi *r8125napi = RTL_GET_PRIV(napi, struct r8125_napi); + struct rtl8125_private *tp = r8125napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + const int message_id = r8125napi->index; + + rtl8125_tx_interrupt_with_vector(tp, message_id, budget); + + work_done += rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH && message_id == 0) + HandleDashInterrupt(tp->dev); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8125_enable_hw_interrupt_v2(tp, message_id); + } + + return RTL_NAPI_RETURN_VALUE; +} +#endif + +static int rtl8125_poll_msix_tx(napi_ptr napi, napi_budget budget) +{ + struct r8125_napi *r8125napi = RTL_GET_PRIV(napi, struct r8125_napi); + struct rtl8125_private *tp = r8125napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + const int message_id = r8125napi->index; + + //suppress unused variable + (void)(dev); + + rtl8125_tx_interrupt_with_vector(tp, message_id, budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8125_enable_hw_interrupt_v2(tp, message_id); + } + + return RTL_NAPI_RETURN_VALUE; +} + +static int rtl8125_poll_msix_other(napi_ptr napi, napi_budget budget) +{ + struct r8125_napi *r8125napi = RTL_GET_PRIV(napi, struct r8125_napi); + struct rtl8125_private *tp = r8125napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + const int message_id = r8125napi->index; + + //suppress unused variable + (void)(dev); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + RTL_NETIF_RX_COMPLETE(dev, napi, work_to_do); +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_to_do); +#endif + + rtl8125_enable_hw_interrupt_v2(tp, message_id); + + return 1; +} + +static int rtl8125_poll_msix_rx(napi_ptr napi, napi_budget budget) +{ + struct r8125_napi *r8125napi = RTL_GET_PRIV(napi, struct r8125_napi); + struct rtl8125_private *tp = r8125napi->priv; + RTL_GET_NETDEV(tp) + unsigned int work_to_do = RTL_NAPI_QUOTA(budget, dev); + unsigned int work_done = 0; + const int message_id = r8125napi->index; + + work_done += rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); + + RTL_NAPI_QUOTA_UPDATE(dev, work_done, budget); + + if (work_done < work_to_do) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) + if (RTL_NETIF_RX_COMPLETE(dev, napi, work_done) == FALSE) return RTL_NAPI_RETURN_VALUE; +#else + RTL_NETIF_RX_COMPLETE(dev, napi, work_done); +#endif + /* + * 20040426: the barrier is not strictly required but the + * behavior of the irq handler could be less predictable + * without it. Btw, the lack of flush for the posted pci + * write is safe - FR + */ + smp_wmb(); + + rtl8125_enable_hw_interrupt_v2(tp, message_id); + } + + return RTL_NAPI_RETURN_VALUE; +} + +static void rtl8125_enable_napi(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + int i; + + for (i = 0; i < tp->irq_nvecs; i++) + RTL_NAPI_ENABLE(tp->dev, &tp->r8125napi[i].napi); +#endif +} + +static void rtl8125_disable_napi(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + int i; + + for (i = 0; i < tp->irq_nvecs; i++) + RTL_NAPI_DISABLE(tp->dev, &tp->r8125napi[i].napi); +#endif +} + +static void rtl8125_del_napi(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + int i; + + for (i = 0; i < tp->irq_nvecs; i++) + RTL_NAPI_DEL((&tp->r8125napi[i])); +#endif +} +#endif //CONFIG_R8125_NAPI + +static void rtl8125_init_napi(struct rtl8125_private *tp) +{ + int i; + + for (i=0; iirq_nvecs; i++) { + struct r8125_napi *r8125napi = &tp->r8125napi[i]; +#ifdef CONFIG_R8125_NAPI + int (*poll)(struct napi_struct *, int); + + if (tp->features & RTL_FEATURE_MSIX && + tp->HwCurrIsrVer == 2) { + if (i < R8125_MAX_RX_QUEUES_VEC_V3) + poll = rtl8125_poll_msix_rx; + else if (i == 16 || i == 18) + poll = rtl8125_poll_msix_tx; + else + poll = rtl8125_poll_msix_other; + } else { + poll = rtl8125_poll; + } + + RTL_NAPI_CONFIG(tp->dev, r8125napi, poll, R8125_NAPI_WEIGHT); +#endif + + r8125napi->priv = tp; + r8125napi->index = i; + } +} + +static int +rtl8125_set_real_num_queue(struct rtl8125_private *tp) +{ + int retval = 0; + + retval = netif_set_real_num_tx_queues(tp->dev, tp->num_tx_rings); + if (retval < 0) + goto exit; + + retval = netif_set_real_num_rx_queues(tp->dev, tp->num_rx_rings); + if (retval < 0) + goto exit; + +exit: + return retval; +} + +static int __devinit +rtl8125_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *dev = NULL; + struct rtl8125_private *tp; + void __iomem *ioaddr = NULL; + static int board_idx = -1; + + int rc; + + assert(pdev != NULL); + assert(ent != NULL); + + board_idx++; + + if (netif_msg_drv(&debug)) + printk(KERN_INFO "%s 2.5Gigabit Ethernet driver %s loaded\n", + MODULENAME, RTL8125_VERSION); + + rc = rtl8125_init_board(pdev, &dev, &ioaddr); + if (rc) + goto out; + + tp = netdev_priv(dev); + assert(ioaddr != NULL); + + tp->set_speed = rtl8125_set_speed_xmii; + tp->get_settings = rtl8125_gset_xmii; + tp->phy_reset_enable = rtl8125_xmii_reset_enable; + tp->phy_reset_pending = rtl8125_xmii_reset_pending; + tp->link_ok = rtl8125_xmii_link_ok; + + rc = rtl8125_try_msi(tp); + if (rc < 0) { + dev_err(&pdev->dev, "Can't allocate interrupt\n"); + goto err_out_1; + } +#ifdef ENABLE_PTP_SUPPORT + spin_lock_init(&tp->lock); +#endif + rtl8125_init_software_variable(dev); + + RTL_NET_DEVICE_OPS(rtl8125_netdev_ops); + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) + SET_ETHTOOL_OPS(dev, &rtl8125_ethtool_ops); +#endif + + dev->watchdog_timeo = RTL8125_TX_TIMEOUT; + dev->irq = rtl8125_get_irq(pdev); + dev->base_addr = (unsigned long) ioaddr; + + rtl8125_init_napi(tp); + +#ifdef CONFIG_R8125_VLAN + if (tp->mcfg != CFG_METHOD_DEFAULT) { + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + dev->vlan_rx_kill_vid = rtl8125_vlan_rx_kill_vid; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + } +#endif + + /* There has been a number of reports that using SG/TSO results in + * tx timeouts. However for a lot of people SG/TSO works fine. + * Therefore disable both features by default, but allow users to + * enable them. Use at own risk! + */ + tp->cp_cmd |= RTL_R16(tp, CPlusCmd); + if (tp->mcfg != CFG_METHOD_DEFAULT) { + dev->features |= NETIF_F_IP_CSUM; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + tp->cp_cmd |= RxChkSum; +#else + dev->features |= NETIF_F_RXCSUM; + dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; + dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | + NETIF_F_HIGHDMA; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0) + dev->hw_features |= NETIF_F_RXALL; + dev->hw_features |= NETIF_F_RXFCS; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6; + dev->features |= NETIF_F_IPV6_CSUM; + netif_set_gso_max_size(dev, LSO_64K); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) + dev->gso_max_segs = NIC_MAX_PHYS_BUF_COUNT_LSO2; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) + dev->gso_min_segs = NIC_MIN_PHYS_BUF_COUNT; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0) + +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + +#ifdef ENABLE_RSS_SUPPORT + if (tp->EnableRss) { + dev->hw_features |= NETIF_F_RXHASH; + dev->features |= NETIF_F_RXHASH; + } +#endif + } + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) + AllocateDashShareMemory(dev); +#endif + +#ifdef ENABLE_LIB_SUPPORT + ATOMIC_INIT_NOTIFIER_HEAD(&tp->lib_nh); +#endif + rtl8125_init_all_schedule_work(tp); + + rc = rtl8125_set_real_num_queue(tp); + if (rc < 0) + goto err_out; + + rtl8125_exit_oob(dev); + + rtl8125_powerup_pll(dev); + + rtl8125_hw_init(dev); + + rtl8125_hw_reset(dev); + + /* Get production from EEPROM */ + rtl8125_eeprom_type(tp); + + if (tp->eeprom_type == EEPROM_TYPE_93C46 || tp->eeprom_type == EEPROM_TYPE_93C56) + rtl8125_set_eeprom_sel_low(tp); + + rtl8125_get_mac_address(dev); + + tp->fw_name = rtl_chip_fw_infos[tp->mcfg].fw_name; + + tp->tally_vaddr = dma_alloc_coherent(&pdev->dev, sizeof(*tp->tally_vaddr), + &tp->tally_paddr, GFP_KERNEL); + if (!tp->tally_vaddr) { + rc = -ENOMEM; + goto err_out; + } + + rtl8125_tally_counter_clear(tp); + + pci_set_drvdata(pdev, dev); + + rc = register_netdev(dev); + if (rc) + goto err_out; + + printk(KERN_INFO "%s: This product is covered by one or more of the following patents: US6,570,884, US6,115,776, and US6,327,625.\n", MODULENAME); + + rtl8125_disable_rxdvgate(dev); + + device_set_wakeup_enable(&pdev->dev, tp->wol_enabled); + + netif_carrier_off(dev); + + printk("%s", GPL_CLAIM); + +out: + return rc; + +err_out: + if (tp->tally_vaddr != NULL) { + dma_free_coherent(&pdev->dev, sizeof(*tp->tally_vaddr), tp->tally_vaddr, + tp->tally_paddr); + + tp->tally_vaddr = NULL; + } +#ifdef CONFIG_R8125_NAPI + rtl8125_del_napi(tp); +#endif + rtl8125_disable_msi(pdev, tp); + +err_out_1: + rtl8125_release_board(pdev, dev); + + goto out; +} + +static void __devexit +rtl8125_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8125_private *tp = netdev_priv(dev); + + assert(dev != NULL); + assert(tp != NULL); + + set_bit(R8125_FLAG_DOWN, tp->task_flags); + + rtl8125_cancel_all_schedule_work(tp); + +#ifdef CONFIG_R8125_NAPI + rtl8125_del_napi(tp); +#endif + if (tp->DASH) + rtl8125_driver_stop(tp); + + unregister_netdev(dev); + rtl8125_disable_msi(pdev, tp); +#ifdef ENABLE_R8125_PROCFS + rtl8125_proc_remove(dev); +#endif + if (tp->tally_vaddr != NULL) { + dma_free_coherent(&pdev->dev, sizeof(*tp->tally_vaddr), tp->tally_vaddr, tp->tally_paddr); + tp->tally_vaddr = NULL; + } + + rtl8125_release_board(pdev, dev); + +#ifdef ENABLE_USE_FIRMWARE_FILE + rtl8125_release_firmware(tp); +#endif + + pci_set_drvdata(pdev, NULL); +} + +static void +rtl8125_set_rxbufsize(struct rtl8125_private *tp, + struct net_device *dev) +{ + unsigned int mtu = dev->mtu; + + tp->rx_buf_sz = (mtu > ETH_DATA_LEN) ? mtu + ETH_HLEN + 8 + 1 : RX_BUF_SIZE; +} + +static void rtl8125_free_irq(struct rtl8125_private *tp) +{ + int i; + + for (i=0; iirq_nvecs; i++) { + struct r8125_irq *irq = &tp->irq_tbl[i]; + struct r8125_napi *r8125napi = &tp->r8125napi[i]; + + if (irq->requested) { + irq->requested = 0; +#if defined(RTL_USE_NEW_INTR_API) + pci_free_irq(tp->pci_dev, i, r8125napi); +#else + free_irq(irq->vector, r8125napi); +#endif + } + } +} + +static int rtl8125_alloc_irq(struct rtl8125_private *tp) +{ + struct net_device *dev = tp->dev; + int rc = 0; + struct r8125_irq *irq; + struct r8125_napi *r8125napi; + int i = 0; + const int len = sizeof(tp->irq_tbl[0].name); + +#if defined(RTL_USE_NEW_INTR_API) + for (i=0; iirq_nvecs; i++) { + irq = &tp->irq_tbl[i]; + if (tp->features & RTL_FEATURE_MSIX && + tp->HwCurrIsrVer == 2) + irq->handler = rtl8125_interrupt_msix; + else + irq->handler = rtl8125_interrupt; + + r8125napi = &tp->r8125napi[i]; + snprintf(irq->name, len, "%s-%d", dev->name, i); + rc = pci_request_irq(tp->pci_dev, i, irq->handler, NULL, r8125napi, + irq->name); + if (rc) + break; + + irq->vector = pci_irq_vector(tp->pci_dev, i); + irq->requested = 1; + } +#else + unsigned long irq_flags = 0; +#ifdef ENABLE_LIB_SUPPORT + irq_flags |= IRQF_NO_SUSPEND; +#endif + if (tp->features & RTL_FEATURE_MSIX && + tp->HwCurrIsrVer == 2) { + for (i=0; iirq_nvecs; i++) { + irq = &tp->irq_tbl[i]; + irq->handler = rtl8125_interrupt_msix; + r8125napi = &tp->r8125napi[i]; + snprintf(irq->name, len, "%s-%d", dev->name, i); + rc = request_irq(irq->vector, irq->handler, irq_flags, irq->name, r8125napi); + + if (rc) + break; + + irq->requested = 1; + } + } else { + irq = &tp->irq_tbl[0]; + irq->handler = rtl8125_interrupt; + r8125napi = &tp->r8125napi[0]; + snprintf(irq->name, len, "%s-0", dev->name); + if (!(tp->features & RTL_FEATURE_MSIX)) + irq->vector = dev->irq; + irq_flags |= (tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX)) ? 0 : SA_SHIRQ; + rc = request_irq(irq->vector, irq->handler, irq_flags, irq->name, r8125napi); + + if (rc == 0) + irq->requested = 1; + } +#endif + if (rc) + rtl8125_free_irq(tp); + + return rc; +} + +static int rtl8125_alloc_tx_desc(struct rtl8125_private *tp) +{ + struct rtl8125_tx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + ring = &tp->tx_ring[i]; + ring->TxDescArray = dma_alloc_coherent(&pdev->dev, + (ring->num_tx_desc * sizeof(struct TxDesc)), + &ring->TxPhyAddr, + GFP_KERNEL); + + if (!ring->TxDescArray) + return -1; + } + + return 0; +} + +static int rtl8125_alloc_rx_desc(struct rtl8125_private *tp) +{ + struct rtl8125_rx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + ring = &tp->rx_ring[i]; + ring->RxDescArray = dma_alloc_coherent(&pdev->dev, + (ring->num_rx_desc * tp->RxDescLength), + &ring->RxPhyAddr, + GFP_KERNEL); + + if (!ring->RxDescArray) + return -1; + } + + return 0; +} + +static int rtl8125_alloc_patch_mem(struct rtl8125_private *tp) +{ + struct pci_dev *pdev = tp->pci_dev; + + if (tp->RequireRduNonStopPatch) { + tp->ShortPacketEmptyBuffer = dma_alloc_coherent(&pdev->dev, + SHORT_PACKET_PADDING_BUF_SIZE, + &tp->ShortPacketEmptyBufferPhy, + GFP_KERNEL); + if (!tp->ShortPacketEmptyBuffer) + return -1; + + memset(tp->ShortPacketEmptyBuffer, 0x0, SHORT_PACKET_PADDING_BUF_SIZE); + } + + return 0; +} + +static void rtl8125_free_tx_desc(struct rtl8125_private *tp) +{ + struct rtl8125_tx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + ring = &tp->tx_ring[i]; + if (ring->TxDescArray) { + dma_free_coherent(&pdev->dev, + (ring->num_tx_desc * sizeof(struct TxDesc)), + ring->TxDescArray, + ring->TxPhyAddr); + ring->TxDescArray = NULL; + } + } +} + +static void rtl8125_free_rx_desc(struct rtl8125_private *tp) +{ + struct rtl8125_rx_ring *ring; + struct pci_dev *pdev = tp->pci_dev; + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + ring = &tp->rx_ring[i]; + if (ring->RxDescArray) { + dma_free_coherent(&pdev->dev, + (ring->num_rx_desc * tp->RxDescLength), + ring->RxDescArray, + ring->RxPhyAddr); + ring->RxDescArray = NULL; + } + } +} + +static void rtl8125_free_patch_mem(struct rtl8125_private *tp) +{ + struct pci_dev *pdev = tp->pci_dev; + + if (tp->ShortPacketEmptyBuffer) { + dma_free_coherent(&pdev->dev, + SHORT_PACKET_PADDING_BUF_SIZE, + tp->ShortPacketEmptyBuffer, + tp->ShortPacketEmptyBufferPhy); + tp->ShortPacketEmptyBuffer = NULL; + } +} + +static void rtl8125_free_alloc_resources(struct rtl8125_private *tp) +{ + rtl8125_free_rx_desc(tp); + + rtl8125_free_tx_desc(tp); + + rtl8125_free_patch_mem(tp); +} + +#ifdef ENABLE_USE_FIRMWARE_FILE +static void rtl8125_request_firmware(struct rtl8125_private *tp) +{ + struct rtl8125_fw *rtl_fw; + + /* firmware loaded already or no firmware available */ + if (tp->rtl_fw || !tp->fw_name) + return; + + rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); + if (!rtl_fw) + return; + + rtl_fw->phy_write = rtl8125_mdio_write; + rtl_fw->phy_read = rtl8125_mdio_read; + rtl_fw->mac_mcu_write = mac_mcu_write; + rtl_fw->mac_mcu_read = mac_mcu_read; + rtl_fw->fw_name = tp->fw_name; + rtl_fw->dev = tp_to_dev(tp); + + if (rtl8125_fw_request_firmware(rtl_fw)) + kfree(rtl_fw); + else + tp->rtl_fw = rtl_fw; +} +#endif + +int rtl8125_open(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int retval; + + retval = -ENOMEM; + +#ifdef ENABLE_R8125_PROCFS + rtl8125_proc_init(dev); +#endif + rtl8125_set_rxbufsize(tp, dev); + /* + * Rx and Tx descriptors needs 256 bytes alignment. + * pci_alloc_consistent provides more. + */ + if (rtl8125_alloc_tx_desc(tp) < 0 || rtl8125_alloc_rx_desc(tp) < 0) + goto err_free_all_allocated_mem; + + retval = rtl8125_init_ring(dev); + if (retval < 0) + goto err_free_all_allocated_mem; + + retval = rtl8125_alloc_patch_mem(tp); + if (retval < 0) + goto err_free_all_allocated_mem; + + retval = rtl8125_alloc_irq(tp); + if (retval < 0) + goto err_free_all_allocated_mem; + + if (netif_msg_probe(tp)) { + printk(KERN_INFO "%s: 0x%lx, " + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, " + "IRQ %d\n", + dev->name, + dev->base_addr, + dev->dev_addr[0], dev->dev_addr[1], + dev->dev_addr[2], dev->dev_addr[3], + dev->dev_addr[4], dev->dev_addr[5], dev->irq); + } + +#ifdef ENABLE_USE_FIRMWARE_FILE + rtl8125_request_firmware(tp); +#endif + pci_set_master(tp->pci_dev); + +#ifdef CONFIG_R8125_NAPI + rtl8125_enable_napi(tp); +#endif + + rtl8125_exit_oob(dev); + + rtl8125_up(dev); + +#ifdef ENABLE_PTP_SUPPORT + if (tp->EnablePtp) + rtl8125_ptp_init(tp); +#endif + clear_bit(R8125_FLAG_DOWN, tp->task_flags); + + if (tp->resume_not_chg_speed) + rtl8125_check_link_status(dev); + else + rtl8125_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + + if (tp->esd_flag == 0) { + //rtl8125_request_esd_timer(dev); + + rtl8125_schedule_esd_work(tp); + } + + //rtl8125_request_link_timer(dev); + + rtl8125_enable_hw_linkchg_interrupt(tp); + +out: + + return retval; + +err_free_all_allocated_mem: + rtl8125_free_alloc_resources(tp); + + goto out; +} + +static void +set_offset70F(struct rtl8125_private *tp, u8 setting) +{ + u32 csi_tmp; + u32 temp = (u32)setting; + temp = temp << 24; + /*set PCI configuration space offset 0x70F to setting*/ + /*When the register offset of PCI configuration space larger than 0xff, use CSI to access it.*/ + + csi_tmp = rtl8125_csi_read(tp, 0x70c) & 0x00ffffff; + rtl8125_csi_write(tp, 0x70c, csi_tmp | temp); +} + +static void +set_offset79(struct rtl8125_private *tp, u8 setting) +{ + //Set PCI configuration space offset 0x79 to setting + + struct pci_dev *pdev = tp->pci_dev; + u8 device_control; + + if (hwoptimize & HW_PATCH_SOC_LAN) return; + + pci_read_config_byte(pdev, 0x79, &device_control); + device_control &= ~0x70; + device_control |= setting; + pci_write_config_byte(pdev, 0x79, device_control); +} + +void +rtl8125_hw_set_rx_packet_filter(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + u32 mc_filter[2]; /* Multicast hash filter */ + int rx_mode; + u32 tmp = 0; + + if (dev->flags & IFF_PROMISC) { + /* Unconditionally log net taps. */ + if (netif_msg_link(tp)) + printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", + dev->name); + + rx_mode = + AcceptBroadcast | AcceptMulticast | AcceptMyPhys | + AcceptAllPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else if ((netdev_mc_count(dev) > multicast_filter_limit) + || (dev->flags & IFF_ALLMULTI)) { + /* Too many to filter perfectly -- accept all multicasts. */ + rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0xffffffff; + } else { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) + struct dev_mc_list *mclist; + unsigned int i; + + rx_mode = AcceptBroadcast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0; + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + int bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + rx_mode |= AcceptMulticast; + } +#else + struct netdev_hw_addr *ha; + + rx_mode = AcceptBroadcast | AcceptMyPhys; + mc_filter[1] = mc_filter[0] = 0; + netdev_for_each_mc_addr(ha, dev) { + int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26; + mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31); + rx_mode |= AcceptMulticast; + } +#endif + } + + if (dev->features & NETIF_F_RXALL) + rx_mode |= (AcceptErr | AcceptRunt); + + tmp = mc_filter[0]; + mc_filter[0] = swab32(mc_filter[1]); + mc_filter[1] = swab32(tmp); + + tmp = tp->rtl8125_rx_config | rx_mode | (RTL_R32(tp, RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask); + + RTL_W32(tp, RxConfig, tmp); + RTL_W32(tp, MAR0 + 0, mc_filter[0]); + RTL_W32(tp, MAR0 + 4, mc_filter[1]); +} + +static void +rtl8125_set_rx_mode(struct net_device *dev) +{ + rtl8125_hw_set_rx_packet_filter(dev); +} + +void +rtl8125_set_rx_q_num(struct rtl8125_private *tp, + unsigned int num_rx_queues) +{ + u16 q_ctrl; + u16 rx_q_num; + + rx_q_num = (u16)ilog2(num_rx_queues); + rx_q_num &= (BIT_0 | BIT_1 | BIT_2); + rx_q_num <<= 2; + q_ctrl = RTL_R16(tp, Q_NUM_CTRL_8125); + q_ctrl &= ~(BIT_2 | BIT_3 | BIT_4); + q_ctrl |= rx_q_num; + RTL_W16(tp, Q_NUM_CTRL_8125, q_ctrl); +} + +void +rtl8125_set_tx_q_num(struct rtl8125_private *tp, + unsigned int num_tx_queues) +{ + u16 mac_ocp_data; + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE63E); + mac_ocp_data &= ~(BIT_11 | BIT_10); + mac_ocp_data |= ((ilog2(num_tx_queues) & 0x03) << 10); + rtl8125_mac_ocp_write(tp, 0xE63E, mac_ocp_data); +} + +void +rtl8125_hw_config(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + struct pci_dev *pdev = tp->pci_dev; + u16 mac_ocp_data; + int i; + + RTL_W32(tp, RxConfig, (RX_DMA_BURST << RxCfgDMAShift)); + + rtl8125_hw_reset(dev); + + rtl8125_enable_cfg9346_write(tp); + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, 0xF1, RTL_R8(tp, 0xF1) & ~BIT_7); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~BIT_7); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + break; + } + + //clear io_rdy_l23 + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~BIT_1); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + //IntMITI_0-IntMITI_31 + for (i=0xA00; i<0xB00; i+=4) + RTL_W32(tp, i, 0x00000000); + break; + } + + //keep magic packet only + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xC0B6); + mac_ocp_data &= BIT_0; + rtl8125_mac_ocp_write(tp, 0xC0B6, mac_ocp_data); + break; + } + + rtl8125_tally_counter_addr_fill(tp); + + rtl8125_enable_extend_tally_couter(tp); + + rtl8125_desc_addr_fill(tp); + + /* Set DMA burst size and Interframe Gap Time */ + RTL_W32(tp, TxConfig, (TX_DMA_BURST_unlimited << TxDMAShift) | + (InterFrameGap << TxInterFrameGapShift)); + + if (tp->EnableTxNoClose) + RTL_W32(tp, TxConfig, (RTL_R32(tp, TxConfig) | BIT_6)); + + if (tp->mcfg == CFG_METHOD_2 || + tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_4 || + tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_6 || + tp->mcfg == CFG_METHOD_7) { + set_offset70F(tp, 0x27); + set_offset79(tp, 0x50); + + RTL_W16(tp, 0x382, 0x221B); + +#ifdef ENABLE_RSS_SUPPORT + rtl8125_config_rss(tp); +#else + RTL_W32(tp, RSS_CTRL_8125, 0x00); +#endif + rtl8125_set_rx_q_num(tp, rtl8125_tot_rx_rings(tp)); + + RTL_W8(tp, Config1, RTL_R8(tp, Config1) & ~0x10); + + rtl8125_mac_ocp_write(tp, 0xC140, 0xFFFF); + rtl8125_mac_ocp_write(tp, 0xC142, 0xFFFF); + + //new tx desc format + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xEB58); + mac_ocp_data |= (BIT_0); + rtl8125_mac_ocp_write(tp, 0xEB58, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE614); + mac_ocp_data &= ~( BIT_10 | BIT_9 | BIT_8); + if (tp->mcfg == CFG_METHOD_4 || tp->mcfg == CFG_METHOD_5 || + tp->mcfg == CFG_METHOD_7) + mac_ocp_data |= ((2 & 0x07) << 8); + else + mac_ocp_data |= ((3 & 0x07) << 8); + rtl8125_mac_ocp_write(tp, 0xE614, mac_ocp_data); + + rtl8125_set_tx_q_num(tp, rtl8125_tot_tx_rings(tp)); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE63E); + mac_ocp_data &= ~(BIT_5 | BIT_4); + if (tp->mcfg == CFG_METHOD_2 || tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_6) + mac_ocp_data |= ((0x02 & 0x03) << 4); + rtl8125_mac_ocp_write(tp, 0xE63E, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xC0B4); + mac_ocp_data &= ~BIT_0; + rtl8125_mac_ocp_write(tp, 0xC0B4, mac_ocp_data); + mac_ocp_data |= BIT_0; + rtl8125_mac_ocp_write(tp, 0xC0B4, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xC0B4); + mac_ocp_data |= (BIT_3|BIT_2); + rtl8125_mac_ocp_write(tp, 0xC0B4, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xEB6A); + mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0); + mac_ocp_data |= (BIT_5 | BIT_4 | BIT_1 | BIT_0); + rtl8125_mac_ocp_write(tp, 0xEB6A, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xEB50); + mac_ocp_data &= ~(BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5); + mac_ocp_data |= (BIT_6); + rtl8125_mac_ocp_write(tp, 0xEB50, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE056); + mac_ocp_data &= ~(BIT_7 | BIT_6 | BIT_5 | BIT_4); + //mac_ocp_data |= (BIT_4 | BIT_5); + rtl8125_mac_ocp_write(tp, 0xE056, mac_ocp_data); + + RTL_W8(tp, TDFNR, 0x10); + + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) | BIT_7); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xE040); + mac_ocp_data &= ~(BIT_12); + rtl8125_mac_ocp_write(tp, 0xE040, mac_ocp_data); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xEA1C); + mac_ocp_data &= ~(BIT_1 | BIT_0); + mac_ocp_data |= (BIT_0); + rtl8125_mac_ocp_write(tp, 0xEA1C, mac_ocp_data); + + rtl8125_mac_ocp_write(tp, 0xE0C0, 0x4000); + + SetMcuAccessRegBit(tp, 0xE052, (BIT_6 | BIT_5)); + ClearMcuAccessRegBit(tp, 0xE052, BIT_3 | BIT_7); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xD430); + mac_ocp_data &= ~(BIT_11 | BIT_10 | BIT_9 | BIT_8 | BIT_7 | BIT_6 | BIT_5 | BIT_4 | BIT_3 | BIT_2 | BIT_1 | BIT_0); + mac_ocp_data |= 0x45F; + rtl8125_mac_ocp_write(tp, 0xD430, mac_ocp_data); + + //rtl8125_mac_ocp_write(tp, 0xE0C0, 0x4F87); + if (!tp->DASH) + RTL_W8(tp, 0xD0, RTL_R8(tp, 0xD0) | BIT_6 | BIT_7); + else + RTL_W8(tp, 0xD0, (RTL_R8(tp, 0xD0) & ~BIT_6) | BIT_7); + + if (tp->mcfg == CFG_METHOD_2 || tp->mcfg == CFG_METHOD_3 || + tp->mcfg == CFG_METHOD_6) + RTL_W8(tp, MCUCmd_reg, RTL_R8(tp, MCUCmd_reg) | BIT_0); + + rtl8125_disable_eee_plus(tp); + + mac_ocp_data = rtl8125_mac_ocp_read(tp, 0xEA1C); + mac_ocp_data &= ~(BIT_2); + rtl8125_mac_ocp_write(tp, 0xEA1C, mac_ocp_data); + + SetMcuAccessRegBit(tp, 0xEB54, BIT_0); + udelay(1); + ClearMcuAccessRegBit(tp, 0xEB54, BIT_0); + RTL_W16(tp, 0x1880, RTL_R16(tp, 0x1880) & ~(BIT_4 | BIT_5)); + } + + /* csum offload command for RTL8125 */ + tp->tx_tcp_csum_cmd = TxTCPCS_C; + tp->tx_udp_csum_cmd = TxUDPCS_C; + tp->tx_ip_csum_cmd = TxIPCS_C; + tp->tx_ipv6_csum_cmd = TxIPV6F_C; + + /* config interrupt type for RTL8125B */ + if (tp->HwSuppIsrVer == 2) + rtl8125_hw_set_interrupt_type(tp, tp->HwCurrIsrVer); + + //other hw parameters + rtl8125_hw_clear_timer_int(dev); + + rtl8125_hw_clear_int_miti(dev); + + if (tp->RequireRduNonStopPatch && + tp->ShortPacketEmptyBuffer) { + RTL_W32(tp, RSS_INDIRECTION_TBL_8125_V2, ((u64)tp->ShortPacketEmptyBufferPhy & DMA_BIT_MASK(32))); + RTL_W32(tp, RSS_INDIRECTION_TBL_8125_V2 + 4, ((u64)tp->ShortPacketEmptyBufferPhy >> 32)); + } + + if (tp->use_timer_interrrupt && + (tp->HwCurrIsrVer == 2) && + (tp->HwSuppIntMitiVer == 4) && + (tp->features & RTL_FEATURE_MSIX)) { + int i; + for (i = 0; i < tp->irq_nvecs; i++) + rtl8125_hw_set_timer_int_8125(tp, i, timer_count_v2); + } + + rtl8125_enable_exit_l1_mask(tp); + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + rtl8125_mac_ocp_write(tp, 0xE098, 0xC302); + break; + } + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + if (aspm) { + rtl8125_init_pci_offset_99(tp); + } + break; + } + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + if (aspm) { + rtl8125_init_pci_offset_180(tp); + } + break; + } + + tp->cp_cmd &= ~(EnableBist | Macdbgo_oe | Force_halfdup | + Force_rxflow_en | Force_txflow_en | Cxpl_dbg_sel | + ASF | Macdbgo_sel); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0) + RTL_W16(tp, CPlusCmd, tp->cp_cmd); +#else + rtl8125_hw_set_features(dev, dev->features); +#endif + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: { + int timeout; + for (timeout = 0; timeout < 10; timeout++) { + if ((rtl8125_mac_ocp_read(tp, 0xE00E) & BIT_13)==0) + break; + mdelay(1); + } + } + break; + } + + RTL_W16(tp, RxMaxSize, tp->rx_buf_sz); + + rtl8125_disable_rxdvgate(dev); + + if (!tp->pci_cfg_is_read) { + pci_read_config_byte(pdev, PCI_COMMAND, &tp->pci_cfg_space.cmd); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_0, &tp->pci_cfg_space.io_base_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_0 + 2, &tp->pci_cfg_space.io_base_h); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2, &tp->pci_cfg_space.mem_base_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_2 + 2, &tp->pci_cfg_space.mem_base_h); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3, &tp->pci_cfg_space.resv_0x1c_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_3 + 2, &tp->pci_cfg_space.resv_0x1c_h); + pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tp->pci_cfg_space.ilr); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4, &tp->pci_cfg_space.resv_0x20_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_4 + 2, &tp->pci_cfg_space.resv_0x20_h); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5, &tp->pci_cfg_space.resv_0x24_l); + pci_read_config_word(pdev, PCI_BASE_ADDRESS_5 + 2, &tp->pci_cfg_space.resv_0x24_h); + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &tp->pci_cfg_space.resv_0x2c_l); + pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID + 2, &tp->pci_cfg_space.resv_0x2c_h); + if (tp->HwPcieSNOffset > 0) { + tp->pci_cfg_space.pci_sn_l = rtl8125_csi_read(tp, tp->HwPcieSNOffset); + tp->pci_cfg_space.pci_sn_h = rtl8125_csi_read(tp, tp->HwPcieSNOffset + 4); + } + + tp->pci_cfg_is_read = 1; + } + + /* Set Rx packet filter */ + rtl8125_hw_set_rx_packet_filter(dev); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH && !tp->dash_printer_enabled) + NICChkTypeEnableDashInterrupt(tp); +#endif + + switch (tp->mcfg) { + case CFG_METHOD_2: + case CFG_METHOD_3: + case CFG_METHOD_4: + case CFG_METHOD_5: + case CFG_METHOD_6: + case CFG_METHOD_7: + if (aspm) { + RTL_W8(tp, Config5, RTL_R8(tp, Config5) | BIT_0); + RTL_W8(tp, Config2, RTL_R8(tp, Config2) | BIT_7); + } else { + RTL_W8(tp, Config2, RTL_R8(tp, Config2) & ~BIT_7); + RTL_W8(tp, Config5, RTL_R8(tp, Config5) & ~BIT_0); + } + break; + } + + rtl8125_disable_cfg9346_write(tp); + + udelay(10); +} + +void +rtl8125_hw_start(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); + + rtl8125_enable_hw_interrupt(tp); + + rtl8125_lib_reset_complete(tp); +} + +static int +rtl8125_change_mtu(struct net_device *dev, + int new_mtu) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ret = 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) + if (new_mtu < ETH_MIN_MTU) + return -EINVAL; + else if (new_mtu > tp->max_jumbo_frame_size) + new_mtu = tp->max_jumbo_frame_size; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) + + dev->mtu = new_mtu; + + if (!netif_running(dev)) + goto out; + + rtl8125_down(dev); + + rtl8125_set_rxbufsize(tp, dev); + + ret = rtl8125_init_ring(dev); + + if (ret < 0) + goto err_out; + +#ifdef CONFIG_R8125_NAPI + rtl8125_enable_napi(tp); +#endif//CONFIG_R8125_NAPI + + //netif_tx_stop_all_queues(dev); + //netif_carrier_off(dev); + rtl8125_hw_config(dev); + rtl8125_enable_hw_linkchg_interrupt(tp); + + rtl8125_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + + //mod_timer(&tp->esd_timer, jiffies + RTL8125_ESD_TIMEOUT); + //mod_timer(&tp->link_timer, jiffies + RTL8125_LINK_TIMEOUT); +out: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + netdev_update_features(dev); +#endif + +err_out: + return ret; +} + +static void +rtl8125_free_rx_skb(struct rtl8125_private *tp, + struct rtl8125_rx_ring *ring, + struct sk_buff **sk_buff, + struct RxDesc *desc, + const u32 cur_rx) +{ + struct pci_dev *pdev = tp->pci_dev; + + dma_unmap_single(&pdev->dev, ring->RxDescPhyAddr[cur_rx], tp->rx_buf_sz, + DMA_FROM_DEVICE); + dev_kfree_skb(*sk_buff); + *sk_buff = NULL; + rtl8125_make_unusable_by_asic(tp, desc); +} + +static inline void +rtl8125_mark_to_asic_v3(struct RxDescV3 *descv3, + u32 rx_buf_sz) +{ + u32 eor = le32_to_cpu(descv3->RxDescNormalDDWord4.opts1) & RingEnd; + + WRITE_ONCE(descv3->RxDescNormalDDWord4.opts1, cpu_to_le32(DescOwn | eor | rx_buf_sz)); +} + +void +rtl8125_mark_to_asic(struct rtl8125_private *tp, + struct RxDesc *desc, + u32 rx_buf_sz) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + rtl8125_mark_to_asic_v3((struct RxDescV3 *)desc, rx_buf_sz); + else { + u32 eor = le32_to_cpu(desc->opts1) & RingEnd; + + WRITE_ONCE(desc->opts1, cpu_to_le32(DescOwn | eor | rx_buf_sz)); + } +} + +static inline void +rtl8125_map_to_asic(struct rtl8125_private *tp, + struct rtl8125_rx_ring *ring, + struct RxDesc *desc, + dma_addr_t mapping, + u32 rx_buf_sz, + const u32 cur_rx) +{ + ring->RxDescPhyAddr[cur_rx] = mapping; + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + ((struct RxDescV3 *)desc)->addr = cpu_to_le64(mapping); + else + desc->addr = cpu_to_le64(mapping); + wmb(); + rtl8125_mark_to_asic(tp, desc, rx_buf_sz); +} + +static int +rtl8125_alloc_rx_skb(struct rtl8125_private *tp, + struct rtl8125_rx_ring *ring, + struct sk_buff **sk_buff, + struct RxDesc *desc, + int rx_buf_sz, + const u32 cur_rx, + u8 in_intr) +{ + struct sk_buff *skb; + dma_addr_t mapping; + int ret = 0; + + if (in_intr) + skb = RTL_ALLOC_SKB_INTR(&tp->r8125napi[ring->index].napi, rx_buf_sz + RTK_RX_ALIGN); + else + skb = dev_alloc_skb(rx_buf_sz + RTK_RX_ALIGN); + + if (unlikely(!skb)) + goto err_out; + + skb_reserve(skb, RTK_RX_ALIGN); + + mapping = dma_map_single(tp_to_dev(tp), skb->data, rx_buf_sz, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, tp->dev, "Failed to map RX DMA!\n"); + goto err_out; + } + + *sk_buff = skb; + rtl8125_map_to_asic(tp, ring, desc, mapping, rx_buf_sz, cur_rx); +out: + return ret; + +err_out: + if (skb) + dev_kfree_skb(skb); + ret = -ENOMEM; + rtl8125_make_unusable_by_asic(tp, desc); + goto out; +} + +static void +_rtl8125_rx_clear(struct rtl8125_private *tp, struct rtl8125_rx_ring *ring) +{ + int i; + + for (i = 0; i < ring->num_rx_desc; i++) { + if (ring->Rx_skbuff[i]) { + rtl8125_free_rx_skb(tp, + ring, + ring->Rx_skbuff + i, + rtl8125_get_rxdesc(tp, ring->RxDescArray, i), + i); + ring->Rx_skbuff[i] = NULL; + } + } +} + +void +rtl8125_rx_clear(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < tp->num_rx_rings; i++) + _rtl8125_rx_clear(tp, &tp->rx_ring[i]); +} + +static u32 +rtl8125_rx_fill(struct rtl8125_private *tp, + struct rtl8125_rx_ring *ring, + struct net_device *dev, + u32 start, + u32 end, + u8 in_intr) +{ + u32 cur; + + for (cur = start; end - cur > 0; cur++) { + int ret, i = cur % ring->num_rx_desc; + + if (ring->Rx_skbuff[i]) + continue; + + ret = rtl8125_alloc_rx_skb(tp, + ring, + ring->Rx_skbuff + i, + rtl8125_get_rxdesc(tp, ring->RxDescArray, i), + tp->rx_buf_sz, + i, + in_intr + ); + if (ret < 0) + break; + } + return cur - start; +} + +static inline void +rtl8125_mark_as_last_descriptor_8125(struct RxDescV3 *descv3) +{ + descv3->RxDescNormalDDWord4.opts1 |= cpu_to_le32(RingEnd); +} + +static inline void +rtl8125_mark_as_last_descriptor(struct rtl8125_private *tp, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + rtl8125_mark_as_last_descriptor_8125((struct RxDescV3 *)desc); + else + desc->opts1 |= cpu_to_le32(RingEnd); +} + +static void +rtl8125_desc_addr_fill(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8125_tx_ring *ring = &tp->tx_ring[i]; + RTL_W32(tp, ring->tdsar_reg, ((u64)ring->TxPhyAddr & DMA_BIT_MASK(32))); + RTL_W32(tp, ring->tdsar_reg + 4, ((u64)ring->TxPhyAddr >> 32)); + } + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8125_rx_ring *ring = &tp->rx_ring[i]; + RTL_W32(tp, ring->rdsar_reg, ((u64)ring->RxPhyAddr & DMA_BIT_MASK(32))); + RTL_W32(tp, ring->rdsar_reg + 4, ((u64)ring->RxPhyAddr >> 32)); + } +} + +static void +rtl8125_tx_desc_init(struct rtl8125_private *tp) +{ + int i = 0; + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8125_tx_ring *ring = &tp->tx_ring[i]; + memset(ring->TxDescArray, 0x0, (ring->num_tx_desc * sizeof(struct TxDesc))); + + ring->TxDescArray[ring->num_tx_desc - 1].opts1 = cpu_to_le32(RingEnd); + } +} + +static void +rtl8125_rx_desc_init(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8125_rx_ring *ring = &tp->rx_ring[i]; + memset(ring->RxDescArray, 0x0, + (ring->num_rx_desc * tp->RxDescLength)); + } +} + +int +rtl8125_init_ring(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + + rtl8125_init_ring_indexes(tp); + + rtl8125_tx_desc_init(tp); + rtl8125_rx_desc_init(tp); + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8125_tx_ring *ring = &tp->tx_ring[i]; + memset(ring->tx_skb, 0x0, sizeof(ring->tx_skb)); + } + + for (i = 0; i < tp->num_rx_rings; i++) { + struct rtl8125_rx_ring *ring = &tp->rx_ring[i]; + + memset(ring->Rx_skbuff, 0x0, sizeof(ring->Rx_skbuff)); + if (rtl8125_rx_fill(tp, ring, dev, 0, ring->num_rx_desc, 0) != ring->num_rx_desc) + goto err_out; + + rtl8125_mark_as_last_descriptor(tp, rtl8125_get_rxdesc(tp, ring->RxDescArray, ring->num_rx_desc - 1)); + } + + return 0; + +err_out: + rtl8125_rx_clear(tp); + return -ENOMEM; +} + +static void +rtl8125_unmap_tx_skb(struct pci_dev *pdev, + struct ring_info *tx_skb, + struct TxDesc *desc) +{ + unsigned int len = tx_skb->len; + + dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, DMA_TO_DEVICE); + + desc->opts1 = cpu_to_le32(RTK_MAGIC_DEBUG_VALUE); + desc->opts2 = 0x00; + desc->addr = RTL8125_MAGIC_NUMBER; + tx_skb->len = 0; +} + +static void +rtl8125_tx_clear_range(struct rtl8125_private *tp, + struct rtl8125_tx_ring *ring, + u32 start, + unsigned int n) +{ + unsigned int i; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + struct net_device *dev = tp->dev; +#endif + + for (i = 0; i < n; i++) { + unsigned int entry = (start + i) % ring->num_tx_desc; + struct ring_info *tx_skb = ring->tx_skb + entry; + unsigned int len = tx_skb->len; + + if (len) { + struct sk_buff *skb = tx_skb->skb; + + rtl8125_unmap_tx_skb(tp->pci_dev, tx_skb, + ring->TxDescArray + entry); + if (skb) { + RTLDEV->stats.tx_dropped++; + dev_kfree_skb_any(skb); + tx_skb->skb = NULL; + } + } + } +} + +void +rtl8125_tx_clear(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) { + struct rtl8125_tx_ring *ring = &tp->tx_ring[i]; + rtl8125_tx_clear_range(tp, ring, ring->dirty_tx, ring->num_tx_desc); + ring->cur_tx = ring->dirty_tx = 0; + } +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8125_schedule_reset_work(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8125_FLAG_TASK_RESET_PENDING, tp->task_flags); + schedule_delayed_work(&tp->reset_task, 4); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +static void rtl8125_schedule_esd_work(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8125_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->esd_task, RTL8125_ESD_TIMEOUT); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +static void rtl8125_schedule_linkchg_work(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + set_bit(R8125_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->linkchg_task, 4); +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) +} + +#define rtl8125_cancel_schedule_reset_work(a) +#define rtl8125_cancel_schedule_esd_work(a) +#define rtl8125_cancel_schedule_linkchg_work(a) + +#else +static void rtl8125_schedule_reset_work(struct rtl8125_private *tp) +{ + set_bit(R8125_FLAG_TASK_RESET_PENDING, tp->task_flags); + schedule_delayed_work(&tp->reset_task, 4); +} + +static void rtl8125_cancel_schedule_reset_work(struct rtl8125_private *tp) +{ + struct work_struct *work = &tp->reset_task.work; + + if (!work->func) return; + + cancel_delayed_work_sync(&tp->reset_task); +} + +static void rtl8125_schedule_esd_work(struct rtl8125_private *tp) +{ + set_bit(R8125_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->esd_task, RTL8125_ESD_TIMEOUT); +} + +static void rtl8125_cancel_schedule_esd_work(struct rtl8125_private *tp) +{ + struct work_struct *work = &tp->esd_task.work; + + if (!work->func) return; + + cancel_delayed_work_sync(&tp->esd_task); +} + +static void rtl8125_schedule_linkchg_work(struct rtl8125_private *tp) +{ + set_bit(R8125_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags); + schedule_delayed_work(&tp->linkchg_task, RTL8125_ESD_TIMEOUT); +} + +static void rtl8125_cancel_schedule_linkchg_work(struct rtl8125_private *tp) +{ + struct work_struct *work = &tp->linkchg_task.work; + + if (!work->func) return; + + cancel_delayed_work_sync(&tp->linkchg_task); +} +#endif + +static void rtl8125_init_all_schedule_work(struct rtl8125_private *tp) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) + INIT_WORK(&tp->reset_task, rtl8125_reset_task, dev); + INIT_WORK(&tp->esd_task, rtl8125_esd_task, dev); + INIT_WORK(&tp->linkchg_task, rtl8125_linkchg_task, dev); +#else + INIT_DELAYED_WORK(&tp->reset_task, rtl8125_reset_task); + INIT_DELAYED_WORK(&tp->esd_task, rtl8125_esd_task); + INIT_DELAYED_WORK(&tp->linkchg_task, rtl8125_linkchg_task); +#endif +} + +static void rtl8125_cancel_all_schedule_work(struct rtl8125_private *tp) +{ + rtl8125_cancel_schedule_reset_work(tp); + rtl8125_cancel_schedule_esd_work(tp); + rtl8125_cancel_schedule_linkchg_work(tp); +} + +static void +rtl8125_wait_for_irq_complete(struct rtl8125_private *tp) +{ + if (tp->features & RTL_FEATURE_MSIX) { + int i; + for (i = 0; i < tp->irq_nvecs; i++) + synchronize_irq(tp->irq_tbl[i].vector); + } else { + synchronize_irq(tp->dev->irq); + } +} + +static void +_rtl8125_wait_for_quiescence(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + /* Wait for any pending NAPI task to complete */ +#ifdef CONFIG_R8125_NAPI + rtl8125_disable_napi(tp); +#endif//CONFIG_R8125_NAPI + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,67) + /* Give a racing hard_start_xmit a few cycles to complete. */ + synchronize_net(); +#endif + + rtl8125_irq_mask_and_ack(tp); + + rtl8125_wait_for_irq_complete(tp); +} + +static void +rtl8125_wait_for_quiescence(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + //suppress unused variable + (void)(tp); + + _rtl8125_wait_for_quiescence(dev); + +#ifdef CONFIG_R8125_NAPI + rtl8125_enable_napi(tp); +#endif//CONFIG_R8125_NAPI +} + +static int rtl8125_rx_nostuck(struct rtl8125_private *tp) +{ + int i, ret = 1; + for (i = 0; i < tp->num_rx_rings; i++) + ret &= (tp->rx_ring[i].dirty_rx == tp->rx_ring[i].cur_rx); + return ret; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8125_reset_task(void *_data) +{ + struct net_device *dev = _data; + struct rtl8125_private *tp = netdev_priv(dev); +#else +static void rtl8125_reset_task(struct work_struct *work) +{ + struct rtl8125_private *tp = + container_of(work, struct rtl8125_private, reset_task.work); + struct net_device *dev = tp->dev; +#endif + u32 budget = ~(u32)0; + int i; + + rtnl_lock(); + + if (!netif_running(dev) || + test_bit(R8125_FLAG_DOWN, tp->task_flags) || + !test_and_clear_bit(R8125_FLAG_TASK_RESET_PENDING, tp->task_flags)) + goto out_unlock; + + rtl8125_wait_for_quiescence(dev); + + for (i = 0; i < tp->num_rx_rings; i++) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[i], &budget); +#else + rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[i], budget); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + } + + netif_tx_stop_all_queues(dev); + netif_carrier_off(dev); + rtl8125_hw_reset(dev); + + rtl8125_tx_clear(tp); + + if (rtl8125_rx_nostuck(tp)) { + rtl8125_rx_clear(tp); + rtl8125_init_ring(dev); +#ifdef ENABLE_PTP_SUPPORT + rtl8125_ptp_reset(tp); +#endif + if (tp->resume_not_chg_speed) { + _rtl8125_check_link_status(dev); + + tp->resume_not_chg_speed = 0; + } else { + rtl8125_enable_hw_linkchg_interrupt(tp); + + rtl8125_set_speed(dev, tp->autoneg, tp->speed, tp->duplex, tp->advertising); + } + } else { + if (unlikely(net_ratelimit())) { + struct rtl8125_private *tp = netdev_priv(dev); + + if (netif_msg_intr(tp)) { + printk(PFX KERN_EMERG + "%s: Rx buffers shortage\n", dev->name); + } + } + rtl8125_schedule_reset_work(tp); + } + +out_unlock: + rtnl_unlock(); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8125_esd_task(void *_data) +{ + struct net_device *dev = _data; + struct rtl8125_private *tp = netdev_priv(dev); +#else +static void rtl8125_esd_task(struct work_struct *work) +{ + struct rtl8125_private *tp = + container_of(work, struct rtl8125_private, esd_task.work); + struct net_device *dev = tp->dev; +#endif + rtnl_lock(); + + if (!netif_running(dev) || + test_bit(R8125_FLAG_DOWN, tp->task_flags) || + !test_and_clear_bit(R8125_FLAG_TASK_ESD_CHECK_PENDING, tp->task_flags)) + goto out_unlock; + + rtl8125_esd_checker(tp); + + rtl8125_schedule_esd_work(tp); + +out_unlock: + rtnl_unlock(); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void rtl8125_linkchg_task(void *_data) +{ + struct net_device *dev = _data; + //struct rtl8125_private *tp = netdev_priv(dev); +#else +static void rtl8125_linkchg_task(struct work_struct *work) +{ + struct rtl8125_private *tp = + container_of(work, struct rtl8125_private, linkchg_task.work); + struct net_device *dev = tp->dev; +#endif + rtnl_lock(); + + if (!netif_running(dev) || + test_bit(R8125_FLAG_DOWN, tp->task_flags) || + !test_and_clear_bit(R8125_FLAG_TASK_LINKCHG_CHECK_PENDING, tp->task_flags)) + goto out_unlock; + + rtl8125_check_link_status(dev); + +out_unlock: + rtnl_unlock(); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static void +rtl8125_tx_timeout(struct net_device *dev, unsigned int txqueue) +#else +static void +rtl8125_tx_timeout(struct net_device *dev) +#endif +{ + struct rtl8125_private *tp = netdev_priv(dev); + + /* Let's wait a bit while any (async) irq lands on */ + rtl8125_schedule_reset_work(tp); +} + +static u32 +rtl8125_get_txd_opts1(struct rtl8125_tx_ring *ring, + u32 opts1, + u32 len, + unsigned int entry) +{ + u32 status = opts1 | len; + + if (entry == ring->num_tx_desc - 1) + status |= RingEnd; + + return status; +} + +static int +rtl8125_xmit_frags(struct rtl8125_private *tp, + struct rtl8125_tx_ring *ring, + struct sk_buff *skb, + const u32 *opts) +{ + struct skb_shared_info *info = skb_shinfo(skb); + unsigned int cur_frag, entry; + struct TxDesc *txd = NULL; + const unsigned char nr_frags = info->nr_frags; + unsigned long PktLenCnt = 0; + bool LsoPatchEnabled = FALSE; + + entry = ring->cur_tx; + for (cur_frag = 0; cur_frag < nr_frags; cur_frag++) { + skb_frag_t *frag = info->frags + cur_frag; + dma_addr_t mapping; + u32 status, len; + void *addr; + + entry = (entry + 1) % ring->num_tx_desc; + + txd = ring->TxDescArray + entry; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) + len = frag->size; + addr = ((void *) page_address(frag->page)) + frag->page_offset; +#else + len = skb_frag_size(frag); + addr = skb_frag_address(frag); +#endif + if (tp->RequireLSOPatch && + (cur_frag == nr_frags - 1) && + (opts[0] & (GiantSendv4|GiantSendv6)) && + PktLenCnt < ETH_FRAME_LEN && + len > 1) { + len -= 1; + mapping = dma_map_single(tp_to_dev(tp), addr, len, DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, tp->dev, + "Failed to map TX fragments DMA!\n"); + goto err_out; + } + + /* anti gcc 2.95.3 bugware (sic) */ + status = rtl8125_get_txd_opts1(ring, opts[0], len, entry); + + txd->addr = cpu_to_le64(mapping); + + ring->tx_skb[entry].len = len; + + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); + txd->opts1 = cpu_to_le32(status); + + //second txd + addr += len; + len = 1; + entry = (entry + 1) % ring->num_tx_desc; + txd = ring->TxDescArray + entry; + cur_frag += 1; + + LsoPatchEnabled = TRUE; + } + + mapping = dma_map_single(tp_to_dev(tp), addr, len, DMA_TO_DEVICE); + + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, tp->dev, + "Failed to map TX fragments DMA!\n"); + goto err_out; + } + + /* anti gcc 2.95.3 bugware (sic) */ + status = rtl8125_get_txd_opts1(ring, opts[0], len, entry); + if (cur_frag == (nr_frags - 1) || LsoPatchEnabled == TRUE) { + //ring->tx_skb[entry].skb = skb; + status |= LastFrag; + } + + txd->addr = cpu_to_le64(mapping); + + ring->tx_skb[entry].len = len; + + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); + txd->opts1 = cpu_to_le32(status); + + PktLenCnt += len; + } + + return cur_frag; + +err_out: + rtl8125_tx_clear_range(tp, ring, ring->cur_tx + 1, cur_frag); + return -EIO; +} + +static inline +__be16 get_protocol(struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37) + return vlan_get_protocol(skb); +#else + __be16 protocol; + + if (skb->protocol == htons(ETH_P_8021Q)) + protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + return protocol; +#endif +} + +static inline +u8 rtl8125_get_l4_protocol(struct sk_buff *skb) +{ + int no = skb_network_offset(skb); + struct ipv6hdr *i6h, _i6h; + struct iphdr *ih, _ih; + u8 ip_protocol = IPPROTO_RAW; + + switch (get_protocol(skb)) { + case __constant_htons(ETH_P_IP): + ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih); + if (ih) + ip_protocol = ih->protocol; + break; + case __constant_htons(ETH_P_IPV6): + i6h = skb_header_pointer(skb, no, sizeof(_i6h), &_i6h); + if (i6h) + ip_protocol = i6h->nexthdr; + break; + } + + return ip_protocol; +} + +static bool rtl8125_skb_pad_with_len(struct sk_buff *skb, unsigned int len) +{ + if (skb_padto(skb, len)) + return false; + skb_put(skb, len - skb->len); + return true; +} + +static bool rtl8125_skb_pad(struct sk_buff *skb) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) + return rtl8125_skb_pad_with_len(skb, ETH_ZLEN); +#else + return !eth_skb_pad(skb); +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) +/* msdn_giant_send_check() + * According to the document of microsoft, the TCP Pseudo Header excludes the + * packet length for IPv6 TCP large packets. + */ +static int msdn_giant_send_check(struct sk_buff *skb) +{ + const struct ipv6hdr *ipv6h; + struct tcphdr *th; + int ret; + + ret = skb_cow_head(skb, 0); + if (ret) + return ret; + + ipv6h = ipv6_hdr(skb); + th = tcp_hdr(skb); + + th->check = 0; + th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0); + + return ret; +} +#endif + +#define MIN_PATCH_LEN (47) +static u32 +rtl8125_get_patch_pad_len(struct sk_buff *skb) +{ + u32 pad_len = 0; + int trans_data_len; + u32 hdr_len; + u32 pkt_len = skb->len; + u8 ip_protocol; + bool has_trans = skb_transport_header_was_set(skb); + + if (!(has_trans && (pkt_len < 175))) //128 + MIN_PATCH_LEN + goto no_padding; + + ip_protocol = rtl8125_get_l4_protocol(skb); + if (!(ip_protocol == IPPROTO_TCP || ip_protocol == IPPROTO_UDP)) + goto no_padding; + + trans_data_len = pkt_len - + (skb->transport_header - + skb_headroom(skb)); + if (ip_protocol == IPPROTO_UDP) { + if (trans_data_len > 3 && trans_data_len < MIN_PATCH_LEN) { + u16 dest_port = 0; + + skb_copy_bits(skb, skb->transport_header - skb_headroom(skb) + 2, &dest_port, 2); + dest_port = ntohs(dest_port); + + if (dest_port == 0x13f || + dest_port == 0x140) { + pad_len = MIN_PATCH_LEN - trans_data_len; + goto out; + } + } + } + + hdr_len = 0; + if (ip_protocol == IPPROTO_TCP) + hdr_len = 20; + else if (ip_protocol == IPPROTO_UDP) + hdr_len = 8; + if (trans_data_len < hdr_len) + pad_len = hdr_len - trans_data_len; + +out: + if ((pkt_len + pad_len) < ETH_ZLEN) + pad_len = ETH_ZLEN - pkt_len; + + return pad_len; + +no_padding: + + return 0; +} + +static bool +rtl8125_tso_csum(struct sk_buff *skb, + struct net_device *dev, + u32 *opts) +{ + struct rtl8125_private *tp = netdev_priv(dev); + unsigned long large_send = 0; + u32 csum_cmd = 0; + u8 sw_calc_csum = false; + u8 check_patch_required = true; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + if (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + u32 mss = skb_shinfo(skb)->tso_size; +#else + u32 mss = skb_shinfo(skb)->gso_size; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + + /* TCP Segmentation Offload (or TCP Large Send) */ + if (mss) { + u32 transport_offset = (u32)skb_transport_offset(skb); + assert((transport_offset%2) == 0); + switch (get_protocol(skb)) { + case __constant_htons(ETH_P_IP): + if (transport_offset <= GTTCPHO_MAX) { + opts[0] |= GiantSendv4; + opts[0] |= transport_offset << GTTCPHO_SHIFT; + opts[1] |= min(mss, MSS_MAX) << 18; + large_send = 1; + } + break; + case __constant_htons(ETH_P_IPV6): +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0) + if (msdn_giant_send_check(skb)) + return false; +#endif + if (transport_offset <= GTTCPHO_MAX) { + opts[0] |= GiantSendv6; + opts[0] |= transport_offset << GTTCPHO_SHIFT; + opts[1] |= min(mss, MSS_MAX) << 18; + large_send = 1; + } + break; + default: + if (unlikely(net_ratelimit())) + dprintk("tso proto=%x!\n", skb->protocol); + break; + } + + if (large_send == 0) + return false; + + return true; + } + } +#endif //LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + + if (skb->ip_summed == CHECKSUM_PARTIAL) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + const struct iphdr *ip = skb->nh.iph; + + if (dev->features & NETIF_F_IP_CSUM) { + if (ip->protocol == IPPROTO_TCP) + csum_cmd = tp->tx_ip_csum_cmd | tp->tx_tcp_csum_cmd; + else if (ip->protocol == IPPROTO_UDP) + csum_cmd = tp->tx_ip_csum_cmd | tp->tx_udp_csum_cmd; + else if (ip->protocol == IPPROTO_IP) + csum_cmd = tp->tx_ip_csum_cmd; + } +#else + u8 ip_protocol = IPPROTO_RAW; + + switch (get_protocol(skb)) { + case __constant_htons(ETH_P_IP): + if (dev->features & NETIF_F_IP_CSUM) { + ip_protocol = ip_hdr(skb)->protocol; + csum_cmd = tp->tx_ip_csum_cmd; + } + break; + case __constant_htons(ETH_P_IPV6): + if (dev->features & NETIF_F_IPV6_CSUM) { + u32 transport_offset = (u32)skb_transport_offset(skb); + if (transport_offset > 0 && transport_offset <= TCPHO_MAX) { + ip_protocol = ipv6_hdr(skb)->nexthdr; + csum_cmd = tp->tx_ipv6_csum_cmd; + csum_cmd |= transport_offset << TCPHO_SHIFT; + } + } + break; + default: + if (unlikely(net_ratelimit())) + dprintk("checksum_partial proto=%x!\n", skb->protocol); + break; + } + + if (ip_protocol == IPPROTO_TCP) + csum_cmd |= tp->tx_tcp_csum_cmd; + else if (ip_protocol == IPPROTO_UDP) + csum_cmd |= tp->tx_udp_csum_cmd; +#endif + if (csum_cmd == 0) { + sw_calc_csum = true; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + WARN_ON(1); /* we need a WARN() */ +#endif + } + + if (ip_protocol == IPPROTO_TCP) + check_patch_required = false; + } + + if (check_patch_required) { + u32 pad_len = rtl8125_get_patch_pad_len(skb); + + if (pad_len > 0) { + if (!rtl8125_skb_pad_with_len(skb, skb->len + pad_len)) + return false; + + if (csum_cmd != 0) + sw_calc_csum = true; + } + } + + if (skb->len < ETH_ZLEN) { + if (tp->UseSwPaddingShortPkt || + (tp->ShortPacketSwChecksum && csum_cmd != 0)) { + if (!rtl8125_skb_pad(skb)) + return false; + + if (csum_cmd != 0) + sw_calc_csum = true; + } + } + + if (sw_calc_csum) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) + skb_checksum_help(&skb, 0); +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) + skb_checksum_help(skb, 0); +#else + skb_checksum_help(skb); +#endif + } else + opts[1] |= csum_cmd; + + return true; +} + +static bool rtl8125_tx_slots_avail(struct rtl8125_private *tp, + struct rtl8125_tx_ring *ring) +{ + unsigned int slots_avail = READ_ONCE(ring->dirty_tx) + ring->num_tx_desc + - READ_ONCE(ring->cur_tx); + + /* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */ + return slots_avail > MAX_SKB_FRAGS; +} + +static netdev_tx_t +rtl8125_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + unsigned int entry; + struct TxDesc *txd; + dma_addr_t mapping; + u32 len; + u32 opts[2]; + netdev_tx_t ret = NETDEV_TX_OK; + int frags; + u8 EnableTxNoClose = tp->EnableTxNoClose; + const u16 queue_mapping = skb_get_queue_mapping(skb); + struct rtl8125_tx_ring *ring; + bool stop_queue; + + assert(queue_mapping < tp->num_tx_rings); + + ring = &tp->tx_ring[queue_mapping]; + + if (unlikely(!rtl8125_tx_slots_avail(tp, ring))) { + if (netif_msg_drv(tp)) { + printk(KERN_ERR + "%s: BUG! Tx Ring[%d] full when queue awake!\n", + dev->name, + queue_mapping); + } + goto err_stop; + } + + entry = ring->cur_tx % ring->num_tx_desc; + txd = ring->TxDescArray + entry; + + if (!EnableTxNoClose) { + if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) { + if (netif_msg_drv(tp)) { + printk(KERN_ERR + "%s: BUG! Tx Desc is own by hardware!\n", + dev->name); + } + goto err_stop; + } + } + + opts[0] = DescOwn; + opts[1] = rtl8125_tx_vlan_tag(tp, skb); + + if (unlikely(!rtl8125_tso_csum(skb, dev, opts))) + goto err_dma_0; + + frags = rtl8125_xmit_frags(tp, ring, skb, opts); + if (unlikely(frags < 0)) + goto err_dma_0; + if (frags) { + len = skb_headlen(skb); + opts[0] |= FirstFrag; + } else { + len = skb->len; + + //ring->tx_skb[entry].skb = skb; + + opts[0] |= FirstFrag | LastFrag; + } + + opts[0] = rtl8125_get_txd_opts1(ring, opts[0], len, entry); + mapping = dma_map_single(tp_to_dev(tp), skb->data, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(tp_to_dev(tp), mapping))) { + if (unlikely(net_ratelimit())) + netif_err(tp, drv, dev, "Failed to map TX DMA!\n"); + goto err_dma_1; + } + ring->tx_skb[entry].len = len; +#ifdef ENABLE_PTP_SUPPORT + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + if (tp->hwtstamp_config.tx_type == HWTSTAMP_TX_ON && + !tp->ptp_tx_skb) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + + tp->ptp_tx_skb = skb_get(skb); + tp->ptp_tx_start = jiffies; + schedule_work(&tp->ptp_tx_work); + } else { + tp->tx_hwtstamp_skipped++; + } + } +#endif + ring->tx_skb[entry].skb = skb; + txd->addr = cpu_to_le64(mapping); + txd->opts2 = cpu_to_le32(opts[1]); + wmb(); + txd->opts1 = cpu_to_le32(opts[0]); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + dev->trans_start = jiffies; +#else + skb_tx_timestamp(skb); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) + + /* rtl_tx needs to see descriptor changes before updated tp->cur_tx */ + smp_wmb(); + + WRITE_ONCE(ring->cur_tx, ring->cur_tx + frags + 1); + + stop_queue = !rtl8125_tx_slots_avail(tp, ring); + if (unlikely(stop_queue)) { + /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must + * not miss a ring update when it notices a stopped queue. + */ + smp_wmb(); + netif_stop_subqueue(dev, queue_mapping); + } + + if (EnableTxNoClose) + RTL_W16(tp, ring->sw_tail_ptr_reg, ring->cur_tx % MAX_TX_NO_CLOSE_DESC_PTR_V2); + else + RTL_W16(tp, TPPOLL_8125, BIT(ring->index)); /* set polling bit */ + + if (unlikely(stop_queue)) { + /* Sync with rtl_tx: + * - publish queue status and cur_tx ring index (write barrier) + * - refresh dirty_tx ring index (read barrier). + * May the current thread have a pessimistic view of the ring + * status and forget to wake up queue, a racing rtl_tx thread + * can't. + */ + smp_mb(); + if (rtl8125_tx_slots_avail(tp, ring)) + netif_start_subqueue(dev, queue_mapping); + } +out: + return ret; +err_dma_1: + ring->tx_skb[entry].skb = NULL; + rtl8125_tx_clear_range(tp, ring, ring->cur_tx + 1, frags); +err_dma_0: + RTLDEV->stats.tx_dropped++; + dev_kfree_skb_any(skb); + ret = NETDEV_TX_OK; + goto out; +err_stop: + netif_stop_subqueue(dev, queue_mapping); + ret = NETDEV_TX_BUSY; + RTLDEV->stats.tx_dropped++; + goto out; +} + +static inline u32 +rtl8125_fast_mod(const u32 input, const u32 ceil) +{ + return input >= ceil ? input % ceil : input; +} + +static int +rtl8125_tx_interrupt(struct rtl8125_tx_ring *ring, int budget) +{ + struct rtl8125_private *tp = ring->priv; + struct net_device *dev = tp->dev; + unsigned int dirty_tx, tx_left; + unsigned int count = 0; + u8 EnableTxNoClose = tp->EnableTxNoClose; + + dirty_tx = ring->dirty_tx; + smp_rmb(); + tx_left = READ_ONCE(ring->cur_tx) - dirty_tx; + if (EnableTxNoClose) { + unsigned int tx_desc_closed; + u32 NextHwDesCloPtr = RTL_R16(tp, ring->hw_clo_ptr_reg); + ring->NextHwDesCloPtr = NextHwDesCloPtr; + smp_rmb(); + tx_desc_closed = rtl8125_fast_mod(NextHwDesCloPtr - ring->BeginHwDesCloPtr, MAX_TX_NO_CLOSE_DESC_PTR_V2); + if(tx_left > tx_desc_closed) tx_left = tx_desc_closed; + ring->BeginHwDesCloPtr = NextHwDesCloPtr; + } + + while (tx_left > 0) { + unsigned int entry = dirty_tx % ring->num_tx_desc; + struct ring_info *tx_skb = ring->tx_skb + entry; + + if (!EnableTxNoClose && + (le32_to_cpu(ring->TxDescArray[entry].opts1) & DescOwn)) + break; + + RTLDEV->stats.tx_bytes += tx_skb->len; + RTLDEV->stats.tx_packets++; + + rtl8125_unmap_tx_skb(tp->pci_dev, + tx_skb, + ring->TxDescArray + entry); + + if (tx_skb->skb != NULL) { + RTL_NAPI_CONSUME_SKB_ANY(tx_skb->skb, budget); + tx_skb->skb = NULL; + } + dirty_tx++; + tx_left--; + } + + if (ring->dirty_tx != dirty_tx) { + count = dirty_tx - ring->dirty_tx; + WRITE_ONCE(ring->dirty_tx, dirty_tx); + smp_wmb(); + if (__netif_subqueue_stopped(dev, ring->index) && + (rtl8125_tx_slots_avail(tp, ring))) { + netif_start_subqueue(dev, ring->index); + } + smp_rmb(); + if (!EnableTxNoClose && (ring->cur_tx != dirty_tx)) { + RTL_W16(tp, TPPOLL_8125, BIT(ring->index)); + } + } + + return count; +} + +static int +rtl8125_tx_interrupt_with_vector(struct rtl8125_private *tp, + const int message_id, + int budget) +{ + int count = 0; + + if (message_id == 16) + count += rtl8125_tx_interrupt(&tp->tx_ring[0], budget); +#ifdef ENABLE_MULTIPLE_TX_QUEUE + else if (message_id == 18) + count += rtl8125_tx_interrupt(&tp->tx_ring[1], budget); +#endif + + return count; +} + +static inline int +rtl8125_fragmented_frame(struct rtl8125_private *tp, u32 status) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + return (status & (FirstFrag_V3 | LastFrag_V3)) != (FirstFrag_V3 | LastFrag_V3); + else + return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); +} + +static inline int +rtl8125_rx_desc_type(u32 status) +{ + return ((status >> 26) & 0x0F); +} + +static inline void +rtl8125_rx_v3_csum(struct rtl8125_private *tp, + struct sk_buff *skb, + struct RxDescV3 *descv3) +{ + //u32 opts1 = le32_to_cpu(descv3->RxDescNormalDDWord4.opts1); + u32 opts2 = le32_to_cpu(descv3->RxDescNormalDDWord4.opts2); + + /* rx csum offload for RTL8125 */ + if (((opts2 & RxV4F_v3) && !(opts2 & RxIPF_v3)) || (opts2 & RxV6F_v3)) { + if (((opts2 & RxTCPT_v3) && !(opts2 & RxTCPF_v3)) || + ((opts2 & RxUDPT_v3) && !(opts2 & RxUDPF_v3))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + } else + skb->ip_summed = CHECKSUM_NONE; +} + +static inline void +rtl8125_rx_csum(struct rtl8125_private *tp, + struct sk_buff *skb, + struct RxDesc *desc) +{ + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) + rtl8125_rx_v3_csum(tp, skb, (struct RxDescV3 *)desc); + else { + u32 opts1 = le32_to_cpu(rtl8125_rx_desc_opts1(tp, desc)); + u32 opts2 = le32_to_cpu(rtl8125_rx_desc_opts2(tp, desc)); + + /* rx csum offload for RTL8125 */ + if (((opts2 & RxV4F) && !(opts1 & RxIPF)) || (opts2 & RxV6F)) { + if (((opts1 & RxTCPT) && !(opts1 & RxTCPF)) || + ((opts1 & RxUDPT) && !(opts1 & RxUDPF))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + } else + skb->ip_summed = CHECKSUM_NONE; + } +} + +static inline int +rtl8125_try_rx_copy(struct rtl8125_private *tp, + struct rtl8125_rx_ring *ring, + struct sk_buff **sk_buff, + int pkt_size, + struct RxDesc *desc, + int rx_buf_sz) +{ + int ret = -1; + + if (pkt_size < rx_copybreak) { + struct sk_buff *skb; + + skb = RTL_ALLOC_SKB_INTR(&tp->r8125napi[ring->index].napi, pkt_size + RTK_RX_ALIGN); + if (skb) { + u8 *data; + + data = sk_buff[0]->data; + skb_reserve(skb, RTK_RX_ALIGN); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) + prefetch(data - RTK_RX_ALIGN); +#endif + eth_copy_and_sum(skb, data, pkt_size, 0); + *sk_buff = skb; + rtl8125_mark_to_asic(tp, desc, rx_buf_sz); + ret = 0; + } + } + return ret; +} + +static inline void +rtl8125_rx_skb(struct rtl8125_private *tp, + struct sk_buff *skb, + u32 ring_index) +{ +#ifdef CONFIG_R8125_NAPI +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + netif_receive_skb(skb); +#else + napi_gro_receive(&tp->r8125napi[ring_index].napi, skb); +#endif +#else + netif_rx(skb); +#endif +} + +static int +rtl8125_check_rx_desc_error(struct net_device *dev, + struct rtl8125_private *tp, + u32 status) +{ + int ret = 0; + + if (tp->InitRxDescType == RX_DESC_RING_TYPE_3) { + if (unlikely(status & RxRES_V3)) { + if (status & (RxRWT_V3 | RxRUNT_V3)) + RTLDEV->stats.rx_length_errors++; + if (status & RxCRC_V3) + RTLDEV->stats.rx_crc_errors++; + + ret = -1; + } + } else { + if (unlikely(status & RxRES)) { + if (status & (RxRWT | RxRUNT)) + RTLDEV->stats.rx_length_errors++; + if (status & RxCRC) + RTLDEV->stats.rx_crc_errors++; + + ret = -1; + } + } + + return ret; +} + +static int +rtl8125_rx_interrupt(struct net_device *dev, + struct rtl8125_private *tp, + struct rtl8125_rx_ring *ring, + napi_budget budget) +{ + unsigned int cur_rx, rx_left; + unsigned int delta, count = 0; + unsigned int entry; + struct RxDesc *desc; + u32 status; + u32 rx_quota; + u64 rx_buf_phy_addr; + u32 ring_index = ring->index; + + assert(dev != NULL); + assert(tp != NULL); + + if (ring->RxDescArray == NULL) + goto rx_out; + + rx_quota = RTL_RX_QUOTA(budget); + cur_rx = ring->cur_rx; + entry = cur_rx % ring->num_rx_desc; + desc = rtl8125_get_rxdesc(tp, ring->RxDescArray, entry); + rx_left = ring->num_rx_desc + ring->dirty_rx - cur_rx; + rx_left = rtl8125_rx_quota(rx_left, (u32)rx_quota); + + for (; rx_left > 0; rx_left--) { + rmb(); + status = le32_to_cpu(rtl8125_rx_desc_opts1(tp, desc)); + if (status & DescOwn) + break; + + if (unlikely(rtl8125_check_rx_desc_error(dev, tp, status) < 0)) { + if (netif_msg_rx_err(tp)) { + printk(KERN_INFO + "%s: Rx ERROR. status = %08x\n", + dev->name, status); + } + + RTLDEV->stats.rx_errors++; + + if (dev->features & NETIF_F_RXALL) + goto process_pkt; + + rtl8125_mark_to_asic(tp, desc, tp->rx_buf_sz); + } else { + struct sk_buff *skb; + int pkt_size; + +process_pkt: + if (likely(!(dev->features & NETIF_F_RXFCS))) + pkt_size = (status & 0x00003fff) - 4; + else + pkt_size = status & 0x00003fff; + + /* + * The driver does not support incoming fragmented + * frames. They are seen as a symptom of over-mtu + * sized frames. + */ + if (unlikely(rtl8125_fragmented_frame(tp, status))) { + RTLDEV->stats.rx_dropped++; + RTLDEV->stats.rx_length_errors++; + rtl8125_mark_to_asic(tp, desc, tp->rx_buf_sz); + continue; + } + + skb = ring->Rx_skbuff[entry]; + + if (!skb) + break; + +#ifdef ENABLE_PTP_SUPPORT + if (tp->EnablePtp) { + u8 desc_type; + + desc_type = rtl8125_rx_desc_type(status); + if (desc_type == RXDESC_TYPE_NEXT && rx_left > 0) { + u32 status_next; + struct RxDescV3 *desc_next; + unsigned int entry_next; + struct sk_buff *skb_next; + + entry_next = (cur_rx + 1) % ring->num_rx_desc; + desc_next = (struct RxDescV3 *)rtl8125_get_rxdesc(tp, ring->RxDescArray, entry_next); + rmb(); + status_next = le32_to_cpu(desc_next->RxDescNormalDDWord4.opts1); + if (unlikely(status_next & DescOwn)) { + udelay(1); + rmb(); + status_next = le32_to_cpu(desc_next->RxDescNormalDDWord4.opts1); + if (unlikely(status_next & DescOwn)) { + if (netif_msg_rx_err(tp)) { + printk(KERN_ERR + "%s: Rx Next Desc ERROR. status = %08x\n", + dev->name, status_next); + } + break; + } + } + + cur_rx++; + rx_left--; + desc_type = rtl8125_rx_desc_type(status_next); + if (desc_type == RXDESC_TYPE_PTP) + rtl8125_rx_ptp_pktstamp(tp, skb, desc_next); + else + WARN_ON(1); + + rx_buf_phy_addr = ring->RxDescPhyAddr[entry_next]; + dma_unmap_single(tp_to_dev(tp), rx_buf_phy_addr, + tp->rx_buf_sz, DMA_FROM_DEVICE); + skb_next = ring->Rx_skbuff[entry_next]; + dev_kfree_skb_any(skb_next); + ring->Rx_skbuff[entry_next] = NULL; + } else + WARN_ON(desc_type != RXDESC_TYPE_NORMAL); + } +#endif + rx_buf_phy_addr = ring->RxDescPhyAddr[entry]; + dma_sync_single_for_cpu(tp_to_dev(tp), + rx_buf_phy_addr, tp->rx_buf_sz, + DMA_FROM_DEVICE); + + if (rtl8125_try_rx_copy(tp, ring, &skb, pkt_size, + desc, tp->rx_buf_sz)) { + ring->Rx_skbuff[entry] = NULL; + dma_unmap_single(tp_to_dev(tp), rx_buf_phy_addr, + tp->rx_buf_sz, DMA_FROM_DEVICE); + } else { + dma_sync_single_for_device(tp_to_dev(tp), rx_buf_phy_addr, + tp->rx_buf_sz, DMA_FROM_DEVICE); + } + +#ifdef ENABLE_RSS_SUPPORT + rtl8125_rx_hash(tp, (struct RxDescV3 *)desc, skb); +#endif + + if (tp->cp_cmd & RxChkSum) + rtl8125_rx_csum(tp, skb, desc); + + skb->dev = dev; + skb_put(skb, pkt_size); + skb->protocol = eth_type_trans(skb, dev); + + if (skb->pkt_type == PACKET_MULTICAST) + RTLDEV->stats.multicast++; + + if (rtl8125_rx_vlan_skb(tp, desc, skb) < 0) + rtl8125_rx_skb(tp, skb, ring_index); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) + dev->last_rx = jiffies; +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(4,11,0) + RTLDEV->stats.rx_bytes += pkt_size; + RTLDEV->stats.rx_packets++; + } + + cur_rx++; + entry = cur_rx % ring->num_rx_desc; + desc = rtl8125_get_rxdesc(tp, ring->RxDescArray, entry); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,37) + prefetch(desc); +#endif + } + + count = cur_rx - ring->cur_rx; + ring->cur_rx = cur_rx; + + delta = rtl8125_rx_fill(tp, ring, dev, ring->dirty_rx, ring->cur_rx, 1); + if (!delta && count && netif_msg_intr(tp)) + printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); + ring->dirty_rx += delta; + + /* + * FIXME: until there is periodic timer to try and refill the ring, + * a temporary shortage may definitely kill the Rx process. + * - disable the asic to try and avoid an overflow and kick it again + * after refill ? + * - how do others driver handle this condition (Uh oh...). + */ + if ((ring->dirty_rx + ring->num_rx_desc == ring->cur_rx) && netif_msg_intr(tp)) + printk(KERN_EMERG "%s: Rx buffers exhausted\n", dev->name); + +rx_out: + return count; +} + +static bool +rtl8125_linkchg_interrupt(struct rtl8125_private *tp, u32 status) +{ + if (tp->HwCurrIsrVer == 2) + return status & ISRIMR_V2_LINKCHG; + + return status & LinkChg; +} + +/* + *The interrupt handler does all of the Rx thread work and cleans up after + *the Tx thread. + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8125_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +#else +static irqreturn_t rtl8125_interrupt(int irq, void *dev_instance) +#endif +{ + struct r8125_napi *r8125napi = dev_instance; + struct rtl8125_private *tp = r8125napi->priv; + struct net_device *dev = tp->dev; + u32 status; + int handled = 0; + + do { + status = RTL_R32(tp, tp->isr_reg[0]); + + if (!(tp->features & (RTL_FEATURE_MSI | RTL_FEATURE_MSIX))) { + /* hotplug/major error/no more work/shared irq */ + if (!status) + break; + + if (status == 0xFFFFFFFF) + break; + + if (!(status & (tp->intr_mask | tp->timer_intr_mask))) + break; + } + + handled = 1; + +#if defined(RTL_USE_NEW_INTR_API) + if (!tp->irq_tbl[0].requested) + break; +#endif + rtl8125_disable_hw_interrupt(tp); + + RTL_W32(tp, tp->isr_reg[0], status&~RxFIFOOver); + + if (rtl8125_linkchg_interrupt(tp, status)) + rtl8125_schedule_linkchg_work(tp); + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + if (HW_DASH_SUPPORT_TYPE_3(tp)) { + u8 DashIntType2Status; + + if (status & ISRIMR_DASH_INTR_CMAC_RESET) + tp->CmacResetIntr = TRUE; + + DashIntType2Status = RTL_CMAC_R8(tp, CMAC_IBISR0); + if (DashIntType2Status & ISRIMR_DASH_TYPE2_ROK) { + tp->RcvFwDashOkEvt = TRUE; + } + if (DashIntType2Status & ISRIMR_DASH_TYPE2_TOK) { + tp->SendFwHostOkEvt = TRUE; + } + if (DashIntType2Status & ISRIMR_DASH_TYPE2_RX_DISABLE_IDLE) { + tp->DashFwDisableRx = TRUE; + } + + RTL_CMAC_W8(tp, CMAC_IBISR0, DashIntType2Status); + } + } +#endif + +#ifdef CONFIG_R8125_NAPI + if (status & tp->intr_mask || tp->keep_intr_cnt-- > 0) { + if (status & tp->intr_mask) + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + + if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &tp->r8125napi[0].napi))) + __RTL_NETIF_RX_SCHEDULE(dev, &tp->r8125napi[0].napi); + else if (netif_msg_intr(tp)) + printk(KERN_INFO "%s: interrupt %04x in poll\n", + dev->name, status); + } else { + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + rtl8125_switch_to_hw_interrupt(tp); + } +#else + if (status & tp->intr_mask || tp->keep_intr_cnt-- > 0) { + u32 budget = ~(u32)0; + int i; + + if (status & tp->intr_mask) + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + + for (i = 0; i < tp->num_tx_rings; i++) + rtl8125_tx_interrupt(&tp->tx_ring[i], ~(u32)0); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[0], &budget); +#else + rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[0], budget); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + +#ifdef ENABLE_DASH_SUPPORT + if (tp->DASH) { + struct net_device *dev = tp->dev; + + HandleDashInterrupt(dev); + } +#endif + + rtl8125_switch_to_timer_interrupt(tp); + } else { + tp->keep_intr_cnt = RTK_KEEP_INTERRUPT_COUNT; + rtl8125_switch_to_hw_interrupt(tp); + } +#endif + } while (false); + + return IRQ_RETVAL(handled); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +static irqreturn_t rtl8125_interrupt_msix(int irq, void *dev_instance, struct pt_regs *regs) +#else +static irqreturn_t rtl8125_interrupt_msix(int irq, void *dev_instance) +#endif +{ + struct r8125_napi *r8125napi = dev_instance; + struct rtl8125_private *tp = r8125napi->priv; + struct net_device *dev = tp->dev; + int message_id = r8125napi->index; +#ifndef CONFIG_R8125_NAPI + u32 budget = ~(u32)0; +#endif + + do { +#if defined(RTL_USE_NEW_INTR_API) + if (!tp->irq_tbl[message_id].requested) + break; +#endif + rtl8125_disable_hw_interrupt_v2(tp, message_id); + + rtl8125_clear_hw_isr_v2(tp, message_id); + + //link change + if (message_id == 21) { + rtl8125_schedule_linkchg_work(tp); + break; + } + +#ifdef CONFIG_R8125_NAPI + if (likely(RTL_NETIF_RX_SCHEDULE_PREP(dev, &r8125napi->napi))) + __RTL_NETIF_RX_SCHEDULE(dev, &r8125napi->napi); + else if (netif_msg_intr(tp)) + printk(KERN_INFO "%s: interrupt message id %d in poll_msix\n", + dev->name, message_id); +#else + rtl8125_tx_interrupt_with_vector(tp, message_id, ~(u32)0); + + if (message_id < tp->num_rx_rings) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[message_id], &budget); +#else + rtl8125_rx_interrupt(dev, tp, &tp->rx_ring[message_id], budget); +#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + } + + rtl8125_enable_hw_interrupt_v2(tp, message_id); +#endif + + } while (false); + + return IRQ_HANDLED; +} + +static void rtl8125_down(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + //rtl8125_delete_esd_timer(dev, &tp->esd_timer); + + //rtl8125_delete_link_timer(dev, &tp->link_timer); + + netif_tx_disable(dev); + + _rtl8125_wait_for_quiescence(dev); + + netif_carrier_off(dev); + + rtl8125_hw_reset(dev); + + rtl8125_tx_clear(tp); + + rtl8125_rx_clear(tp); +} + +static int rtl8125_resource_freed(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < tp->num_tx_rings; i++) + if (tp->tx_ring[i].TxDescArray) return 0; + + for (i = 0; i < tp->num_rx_rings; i++) + if (tp->rx_ring[i].RxDescArray) return 0; + + return 1; +} + +int rtl8125_close(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + if (!rtl8125_resource_freed(tp)) { + set_bit(R8125_FLAG_DOWN, tp->task_flags); + + rtl8125_down(dev); + + pci_clear_master(tp->pci_dev); + +#ifdef ENABLE_PTP_SUPPORT + rtl8125_ptp_stop(tp); +#endif + rtl8125_hw_d3_para(dev); + + rtl8125_powerdown_pll(dev, 0); + + rtl8125_free_irq(tp); + + rtl8125_free_alloc_resources(tp); + } else { + rtl8125_hw_d3_para(dev); + + rtl8125_powerdown_pll(dev, 0); + } + + return 0; +} + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) +static void rtl8125_shutdown(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8125_private *tp = netdev_priv(dev); + + rtnl_lock(); + + if (tp->DASH) + rtl8125_driver_stop(tp); + + rtl8125_set_bios_setting(dev); + if (s5_keep_curr_mac == 0 && tp->random_mac == 0) + rtl8125_rar_set(tp, tp->org_mac_addr); + + if (s5wol == 0) + tp->wol_enabled = WOL_DISABLED; + + rtl8125_close(dev); + rtl8125_disable_msi(pdev, tp); + + rtnl_unlock(); + + if (system_state == SYSTEM_POWER_OFF) { + pci_clear_master(tp->pci_dev); + pci_wake_from_d3(pdev, tp->wol_enabled); + pci_set_power_state(pdev, PCI_D3hot); + } +} +#endif + +/** + * rtl8125_get_stats - Get rtl8125 read/write statistics + * @dev: The Ethernet Device to get statistics for + * + * Get TX/RX statistics for rtl8125 + */ +static struct +net_device_stats *rtl8125_get_stats(struct net_device *dev) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) + struct rtl8125_private *tp = netdev_priv(dev); +#endif + return &RTLDEV->stats; +} + +#ifdef CONFIG_PM + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +static int +rtl8125_suspend(struct pci_dev *pdev, u32 state) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) +static int +rtl8125_suspend(struct device *device) +#else +static int +rtl8125_suspend(struct pci_dev *pdev, pm_message_t state) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *dev = pci_get_drvdata(pdev); +#else + struct net_device *dev = pci_get_drvdata(pdev); +#endif + struct rtl8125_private *tp = netdev_priv(dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + u32 pci_pm_state = pci_choose_state(pdev, state); +#endif + if (!netif_running(dev)) + goto out; + + //rtl8125_cancel_all_schedule_work(tp); + + //rtl8125_delete_esd_timer(dev, &tp->esd_timer); + + //rtl8125_delete_link_timer(dev, &tp->link_timer); + + rtnl_lock(); + + set_bit(R8125_FLAG_DOWN, tp->task_flags); + + netif_tx_disable(dev); + + netif_carrier_off(dev); + + netif_device_detach(dev); + +#ifdef ENABLE_PTP_SUPPORT + rtl8125_ptp_suspend(tp); +#endif + rtl8125_hw_reset(dev); + + pci_clear_master(pdev); + + rtl8125_hw_d3_para(dev); + + rtl8125_powerdown_pll(dev, 1); + + if (tp->DASH) + rtl8125_driver_stop(tp); + + rtnl_unlock(); +out: + + pci_disable_device(pdev); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + pci_save_state(pdev, &pci_pm_state); +#else + pci_save_state(pdev); +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled); +#endif + + pci_prepare_to_sleep(pdev); + + return 0; +} + +static int +rtl8125_hw_d3_not_power_off(struct net_device *dev) +{ + return rtl8125_check_hw_phy_mcu_code_ver(dev); +} + +static int rtl8125_wait_phy_nway_complete_sleep(struct rtl8125_private *tp) +{ + int i, val; + + for (i = 0; i < 30; i++) { + val = rtl8125_mdio_read(tp, MII_BMSR) & BMSR_ANEGCOMPLETE; + if (val) + return 0; + + msleep(100); + } + + return -1; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) +static int +rtl8125_resume(struct pci_dev *pdev) +#else +static int +rtl8125_resume(struct device *device) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *dev = pci_get_drvdata(pdev); +#else + struct net_device *dev = pci_get_drvdata(pdev); +#endif + struct rtl8125_private *tp = netdev_priv(dev); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + u32 pci_pm_state = PCI_D0; +#endif + u32 err; + + rtnl_lock(); + + err = pci_enable_device(pdev); + if (err) { + dev_err(&pdev->dev, "Cannot enable PCI device from suspend\n"); + goto out_unlock; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) + pci_restore_state(pdev, &pci_pm_state); +#else + pci_restore_state(pdev); +#endif + pci_enable_wake(pdev, PCI_D0, 0); + + /* restore last modified mac address */ + rtl8125_rar_set(tp, dev->dev_addr); + + tp->resume_not_chg_speed = 0; + if (tp->check_keep_link_speed && + //tp->link_ok(dev) && + rtl8125_hw_d3_not_power_off(dev) && + rtl8125_wait_phy_nway_complete_sleep(tp) == 0) + tp->resume_not_chg_speed = 1; + + if (!netif_running(dev)) + goto out_unlock; + + pci_set_master(pdev); + + rtl8125_exit_oob(dev); + + rtl8125_up(dev); + + clear_bit(R8125_FLAG_DOWN, tp->task_flags); + + rtl8125_schedule_reset_work(tp); + + rtl8125_schedule_esd_work(tp); + + //mod_timer(&tp->esd_timer, jiffies + RTL8125_ESD_TIMEOUT); + //mod_timer(&tp->link_timer, jiffies + RTL8125_LINK_TIMEOUT); +out_unlock: + netif_device_attach(dev); + + rtnl_unlock(); + + return err; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + +static struct dev_pm_ops rtl8125_pm_ops = { + .suspend = rtl8125_suspend, + .resume = rtl8125_resume, + .freeze = rtl8125_suspend, + .thaw = rtl8125_resume, + .poweroff = rtl8125_suspend, + .restore = rtl8125_resume, +}; + +#define RTL8125_PM_OPS (&rtl8125_pm_ops) + +#endif + +#else /* !CONFIG_PM */ + +#define RTL8125_PM_OPS NULL + +#endif /* CONFIG_PM */ + +static struct pci_driver rtl8125_pci_driver = { + .name = MODULENAME, + .id_table = rtl8125_pci_tbl, + .probe = rtl8125_init_one, + .remove = __devexit_p(rtl8125_remove_one), +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,11) + .shutdown = rtl8125_shutdown, +#endif +#ifdef CONFIG_PM +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) + .suspend = rtl8125_suspend, + .resume = rtl8125_resume, +#else + .driver.pm = RTL8125_PM_OPS, +#endif +#endif +}; + +static int __init +rtl8125_init_module(void) +{ + int ret = 0; +#ifdef ENABLE_R8125_PROCFS + rtl8125_proc_module_init(); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) + + ret = pci_register_driver(&rtl8125_pci_driver); +#else + ret = pci_module_init(&rtl8125_pci_driver); +#endif + + return ret; +} + +static void __exit +rtl8125_cleanup_module(void) +{ + pci_unregister_driver(&rtl8125_pci_driver); + +#ifdef ENABLE_R8125_PROCFS + if (rtl8125_proc) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + remove_proc_subtree(MODULENAME, init_net.proc_net); +#else +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) + remove_proc_entry(MODULENAME, init_net.proc_net); +#else + remove_proc_entry(MODULENAME, proc_net); +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) +#endif //LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) + rtl8125_proc = NULL; + } +#endif +} + +module_init(rtl8125_init_module); +module_exit(rtl8125_cleanup_module); diff --git a/addons/r8125/src/4.4.180/r8125_ptp.c b/addons/r8125/src/4.4.180/r8125_ptp.c new file mode 100755 index 00000000..6010a180 --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_ptp.c @@ -0,0 +1,594 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "r8125.h" +#include "r8125_ptp.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) +static inline struct timespec timespec64_to_timespec(const struct timespec64 ts64) +{ + return *(const struct timespec *)&ts64; +} + +static inline struct timespec64 timespec_to_timespec64(const struct timespec ts) +{ + return *(const struct timespec64 *)&ts; +} +#endif + +static int _rtl8125_phc_gettime(struct rtl8125_private *tp, struct timespec64 *ts64) +{ + //get local time + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_LATCHED_LOCAL_TIME | PTP_EXEC_CMD)); + + /* nanoseconds */ + //0x6808[29:0] + ts64->tv_nsec = (RTL_R32(tp, PTP_SOFT_CONFIG_Time_NS_8125) & 0x3fffffff) + + tp->ptp_adjust; + + /* seconds */ + //0x680C[47:0] + ts64->tv_sec = RTL_R16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4); + ts64->tv_sec <<= 32; + ts64->tv_sec |= RTL_R32(tp, PTP_SOFT_CONFIG_Time_S_8125); + + return 0; +} + +static int _rtl8125_phc_settime(struct rtl8125_private *tp, const struct timespec64 *ts64) +{ + /* nanoseconds */ + //0x6808[29:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, (ts64->tv_nsec & 0x3fffffff)); + + /* seconds */ + //0x680C[47:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_S_8125, ts64->tv_sec); + RTL_W16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4, (ts64->tv_sec >> 32)); + + //set local time + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD)); + + return 0; +} + +#if 0 +static int _rtl8125_phc_adjtime(struct rtl8125_private *tp, s64 delta) +{ + struct timespec64 now, then = ns_to_timespec64(delta); + u32 nsec; + u64 sec; + + _rtl8125_phc_gettime(tp, &now); + now = timespec64_add(now, then); + + nsec = now.tv_nsec & 0x3fffffff; + sec = now.tv_sec & 0x0000ffffffffffff; + + /* nanoseconds */ + //0x6808[29:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, nsec); + + /* seconds */ + //0x680C[47:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_S_8125, sec); + RTL_W16(tp, PTP_SOFT_CONFIG_Time_S_8125 + 4, (sec >> 32)); + + //adjust local time + //RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_DRIFT_LOCAL_TIME | PTP_EXEC_CMD)); + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD)); + + return 0; +} +#endif + +static int rtl8125_phc_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct rtl8125_private *tp = container_of(ptp, struct rtl8125_private, ptp_clock_info); + unsigned long flags; + //int ret = 0; + + //netif_info(tp, drv, tp->dev, "phc adjust time\n"); + + spin_lock_irqsave(&tp->lock, flags); + //ret = _rtl8125_phc_adjtime(tp, delta); + tp->ptp_adjust += delta; + spin_unlock_irqrestore(&tp->lock, flags); + + return 0; +} + +/* +1ppm means every 125MHz plus 125Hz. It also means every 8ns minus 8ns*10^(-6) + +1ns=2^30 sub_ns + +8ns*10^(-6) = 8 * 2^30 sub_ns * 10^(-6) = 2^33 sub_ns * 10^(-6) = 8590 = 0x218E sub_ns + +1ppb means every 125MHz plus 0.125Hz. It also means every 8ns minus 8ns*10^(-9) + +1ns=2^30 sub_ns + +8ns*10^(-9) = 8 * 2^30 sub_ns * 10^(-9) = 2^33 sub_ns * 10^(-9) = 8.59 sub_ns = 9 sub_ns +*/ +static int _rtl8125_phc_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + struct rtl8125_private *tp = container_of(ptp, struct rtl8125_private, ptp_clock_info); + bool negative = false; + u32 sub_ns; + + if (ppb < 0) { + negative = true; + ppb = -ppb; + } + + sub_ns = ppb * 9; + if (negative) { + sub_ns = -sub_ns; + sub_ns &= 0x3fffffff; + sub_ns |= PTP_ADJUST_TIME_NS_NEGATIVE; + } else + sub_ns &= 0x3fffffff; + + /* nanoseconds */ + //0x6808[29:0] + RTL_W32(tp, PTP_SOFT_CONFIG_Time_NS_8125, sub_ns); + + //adjust local time + RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_DRIFT_LOCAL_TIME | PTP_EXEC_CMD)); + //RTL_W16(tp, PTP_TIME_CORRECT_CMD_8125, (PTP_CMD_SET_LOCAL_TIME | PTP_EXEC_CMD)); + + return 0; +} + +static int rtl8125_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta) +{ + //struct rtl8125_private *tp = container_of(ptp, struct rtl8125_private, ptp_clock_info); + + //netif_info(tp, drv, tp->dev, "phc adjust freq\n"); + + if (delta > ptp->max_adj || delta < -ptp->max_adj) + return -EINVAL; + + _rtl8125_phc_adjfreq(ptp, delta); + + return 0; +} + +static int rtl8125_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts64) +{ + struct rtl8125_private *tp = container_of(ptp, struct rtl8125_private, ptp_clock_info); + unsigned long flags; + int ret; + + //netif_info(tp, drv, tp->dev, "phc get ts\n"); + + spin_lock_irqsave(&tp->lock, flags); + ret = _rtl8125_phc_gettime(tp, ts64); + spin_unlock_irqrestore(&tp->lock, flags); + + return ret; +} + +static int rtl8125_phc_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts64) +{ + struct rtl8125_private *tp = container_of(ptp, struct rtl8125_private, ptp_clock_info); + unsigned long flags; + int ret; + + //netif_info(tp, drv, tp->dev, "phc set ts\n"); + + spin_lock_irqsave(&tp->lock, flags); + ret = _rtl8125_phc_settime(tp, ts64); + tp->ptp_adjust = 0; + spin_unlock_irqrestore(&tp->lock, flags); + + return ret; +} + +static int rtl8125_phc_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + struct rtl8125_private *tp = container_of(ptp, struct rtl8125_private, ptp_clock_info); + unsigned long flags; + u16 ptp_ctrl; + + //netif_info(tp, drv, tp->dev, "phc enable type %x on %d\n", rq->type, on); + + switch (rq->type) { + case PTP_CLK_REQ_PPS: + spin_lock_irqsave(&tp->lock, flags); + ptp_ctrl = RTL_R16(tp, PTP_CTRL_8125); + ptp_ctrl &= ~BIT_15; + if (on) + ptp_ctrl |= BIT_14; + else + ptp_ctrl &= ~BIT_14; + RTL_W16(tp, PTP_CTRL_8125, ptp_ctrl); + spin_unlock_irqrestore(&tp->lock, flags); + return 0; + default: + return -EOPNOTSUPP; + } +} + +int rtl8125_get_ts_info(struct net_device *netdev, + struct ethtool_ts_info *info) +{ + struct rtl8125_private *tp = netdev_priv(netdev); + + /* we always support timestamping disabled */ + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); + + if (tp->HwSuppPtpVer == 0) + return ethtool_op_get_ts_info(netdev, info); + + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + if (tp->ptp_clock) + info->phc_index = ptp_clock_index(tp->ptp_clock); + else + info->phc_index = -1; + + info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON); + + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | + BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) | + BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) | + BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) | + BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ); + + return 0; +} + +static const struct ptp_clock_info rtl_ptp_clock_info = { + .owner = THIS_MODULE, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, + .n_pins = 0, + .pps = 1, + .adjfreq = rtl8125_phc_adjfreq, + .adjtime = rtl8125_phc_adjtime, + .gettime64 = rtl8125_phc_gettime, + .settime64 = rtl8125_phc_settime, + .enable = rtl8125_phc_enable, +}; + +static int rtl8125_get_tx_ptp_pkt_tstamp(struct rtl8125_private *tp, struct timespec64 *ts64) +{ + return _rtl8125_phc_gettime(tp, ts64); +} + +static void rtl8125_ptp_tx_hwtstamp(struct rtl8125_private *tp) +{ + struct sk_buff *skb = tp->ptp_tx_skb; + struct skb_shared_hwtstamps shhwtstamps = {0}; + struct timespec64 ts64; + + RTL_W8(tp, PTP_ISR_8125, PTP_ISR_TOK | PTP_ISR_TER); + + rtl8125_get_tx_ptp_pkt_tstamp(tp, &ts64); + + /* Upper 32 bits contain s, lower 32 bits contain ns. */ + shhwtstamps.hwtstamp = ktime_set(ts64.tv_sec, + ts64.tv_nsec); + + /* Clear the lock early before calling skb_tstamp_tx so that + * applications are not woken up before the lock bit is clear. We use + * a copy of the skb pointer to ensure other threads can't change it + * while we're notifying the stack. + */ + tp->ptp_tx_skb = NULL; + + /* Notify the stack and free the skb after we've unlocked */ + skb_tstamp_tx(skb, &shhwtstamps); + dev_kfree_skb_any(skb); +} + +#define RTL8125_PTP_TX_TIMEOUT (HZ * 15) +static void rtl8125_ptp_tx_work(struct work_struct *work) +{ + struct rtl8125_private *tp = container_of(work, struct rtl8125_private, + ptp_tx_work); + unsigned long flags; + + spin_lock_irqsave(&tp->lock, flags); + + if (!tp->ptp_tx_skb) + goto Exit; + + if (time_is_before_jiffies(tp->ptp_tx_start + + RTL8125_PTP_TX_TIMEOUT)) { + dev_kfree_skb_any(tp->ptp_tx_skb); + tp->ptp_tx_skb = NULL; + tp->tx_hwtstamp_timeouts++; + /* Clear the tx valid bit in TSYNCTXCTL register to enable + * interrupt + */ + RTL_W8(tp, PTP_ISR_8125, PTP_ISR_TOK | PTP_ISR_TER); + goto Exit; + } + + if (RTL_R8(tp, PTP_ISR_8125) & (PTP_ISR_TOK)) + rtl8125_ptp_tx_hwtstamp(tp); + else + /* reschedule to check later */ + schedule_work(&tp->ptp_tx_work); + +Exit: + spin_unlock_irqrestore(&tp->lock, flags); +} + +static int rtl8125_hwtstamp_enable(struct rtl8125_private *tp, bool enable) +{ + RTL_W16(tp, PTP_CTRL_8125, 0); + if (enable) { + u16 ptp_ctrl; + struct timespec64 ts64; + + //clear ptp isr + RTL_W8(tp, PTP_ISR_8125, 0xff); + //ptp source 0:gphy 1:mac + rtl8125_mac_ocp_write(tp, 0xDC00, rtl8125_mac_ocp_read(tp, 0xDC00) | BIT_6); + //enable ptp + ptp_ctrl = (BIT_0 | BIT_3 | BIT_4 | BIT_6 | BIT_10 | BIT_12 | BIT_13); + if (tp->ptp_master_mode) { + ptp_ctrl &= ~BIT_13; + ptp_ctrl |= BIT_1; + } + RTL_W16(tp, PTP_CTRL_8125, ptp_ctrl); + + //set system time + /* + if (ktime_to_timespec64_cond(ktime_get_real(), &ts64)) + _rtl8125_phc_settime(tp, timespec64_to_timespec(ts64)); + */ + ktime_get_real_ts64(&ts64); + ts64.tv_nsec += tp->ptp_adjust; + _rtl8125_phc_settime(tp, &ts64); + tp->ptp_adjust = 0; + } + + return 0; +} + +static long rtl8125_ptp_create_clock(struct rtl8125_private *tp) +{ + struct net_device *netdev = tp->dev; + long err; + + if (!IS_ERR_OR_NULL(tp->ptp_clock)) + return 0; + + if (tp->HwSuppPtpVer == 0) { + tp->ptp_clock = NULL; + return -EOPNOTSUPP; + } + + tp->ptp_clock_info = rtl_ptp_clock_info; + snprintf(tp->ptp_clock_info.name, sizeof(tp->ptp_clock_info.name), + "%pm", tp->dev->dev_addr); + tp->ptp_clock_info.max_adj = 119304647; + tp->ptp_clock = ptp_clock_register(&tp->ptp_clock_info, &tp->pci_dev->dev); + if (IS_ERR(tp->ptp_clock)) { + err = PTR_ERR(tp->ptp_clock); + tp->ptp_clock = NULL; + netif_err(tp, drv, tp->dev, "ptp_clock_register failed\n"); + return err; + } else + netif_info(tp, drv, tp->dev, "registered PHC device on %s\n", netdev->name); + + return 0; +} + +void rtl8125_ptp_reset(struct rtl8125_private *tp) +{ + if (!tp->ptp_clock) + return; + + netif_info(tp, drv, tp->dev, "reset PHC clock\n"); + + rtl8125_hwtstamp_enable(tp, false); +} + +void rtl8125_ptp_init(struct rtl8125_private *tp) +{ + /* obtain a PTP device, or re-use an existing device */ + if (rtl8125_ptp_create_clock(tp)) + return; + + /* we have a clock so we can initialize work now */ + INIT_WORK(&tp->ptp_tx_work, rtl8125_ptp_tx_work); + + tp->ptp_adjust = 0; + + /* reset the PTP related hardware bits */ + rtl8125_ptp_reset(tp); + + return; +} + +void rtl8125_ptp_suspend(struct rtl8125_private *tp) +{ + if (!tp->ptp_clock) + return; + + netif_info(tp, drv, tp->dev, "suspend PHC clock\n"); + + rtl8125_hwtstamp_enable(tp, false); + + /* ensure that we cancel any pending PTP Tx work item in progress */ + cancel_work_sync(&tp->ptp_tx_work); +} + +void rtl8125_ptp_stop(struct rtl8125_private *tp) +{ + struct net_device *netdev = tp->dev; + + netif_info(tp, drv, tp->dev, "stop PHC clock\n"); + + /* first, suspend PTP activity */ + rtl8125_ptp_suspend(tp); + + /* disable the PTP clock device */ + if (tp->ptp_clock) { + ptp_clock_unregister(tp->ptp_clock); + tp->ptp_clock = NULL; + netif_info(tp, drv, tp->dev, "removed PHC on %s\n", + netdev->name); + } +} + +static int rtl8125_set_tstamp(struct net_device *netdev, struct ifreq *ifr) +{ + struct rtl8125_private *tp = netdev_priv(netdev); + struct hwtstamp_config config; + bool hwtstamp = 0; + + //netif_info(tp, drv, tp->dev, "ptp set ts\n"); + + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) + return -EFAULT; + + if (config.flags) + return -EINVAL; + + switch (config.tx_type) { + case HWTSTAMP_TX_ON: + hwtstamp = 1; + case HWTSTAMP_TX_OFF: + break; + case HWTSTAMP_TX_ONESTEP_SYNC: + default: + return -ERANGE; + } + + switch (config.rx_filter) { + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; + hwtstamp = 1; + case HWTSTAMP_FILTER_NONE: + break; + default: + return -ERANGE; + } + + if (tp->hwtstamp_config.tx_type != config.tx_type || + tp->hwtstamp_config.rx_filter != config.rx_filter) { + tp->hwtstamp_config = config; + rtl8125_hwtstamp_enable(tp, hwtstamp); + } + + return copy_to_user(ifr->ifr_data, &config, + sizeof(config)) ? -EFAULT : 0; +} + +static int rtl8125_get_tstamp(struct net_device *netdev, struct ifreq *ifr) +{ + struct rtl8125_private *tp = netdev_priv(netdev); + + //netif_info(tp, drv, tp->dev, "ptp get ts\n"); + + return copy_to_user(ifr->ifr_data, &tp->hwtstamp_config, + sizeof(tp->hwtstamp_config)) ? -EFAULT : 0; +} + +int rtl8125_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct rtl8125_private *tp = netdev_priv(netdev); + int ret; + unsigned long flags; + + //netif_info(tp, drv, tp->dev, "ptp ioctl\n"); + + ret = 0; + switch (cmd) { +#ifdef ENABLE_PTP_SUPPORT + case SIOCSHWTSTAMP: + spin_lock_irqsave(&tp->lock, flags); + ret = rtl8125_set_tstamp(netdev, ifr); + spin_unlock_irqrestore(&tp->lock, flags); + break; + case SIOCGHWTSTAMP: + spin_lock_irqsave(&tp->lock, flags); + ret = rtl8125_get_tstamp(netdev, ifr); + spin_unlock_irqrestore(&tp->lock, flags); + break; +#endif + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} + +void rtl8125_rx_ptp_pktstamp(struct rtl8125_private *tp, struct sk_buff *skb, + struct RxDescV3 *descv3) +{ + time64_t tv_sec; + long tv_nsec; + + tv_sec = le32_to_cpu(descv3->RxDescTimeStamp.TimeStampHigh) + + ((u64)le32_to_cpu(descv3->RxDescPTPDDWord4.TimeStampHHigh) << 32); + tv_nsec = le32_to_cpu(descv3->RxDescTimeStamp.TimeStampLow) + tp->ptp_adjust; + + skb_hwtstamps(skb)->hwtstamp = ktime_set(tv_sec, tv_nsec); +} diff --git a/addons/r8125/src/4.4.180/r8125_ptp.h b/addons/r8125/src/4.4.180/r8125_ptp.h new file mode 100755 index 00000000..7a1fe83b --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_ptp.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_rtl8125_PTP_H +#define _LINUX_rtl8125_PTP_H + +#include +#include +#include +#include +#include + +struct rtl8125_ptp_info { + s64 time_sec; + u32 time_ns; + u16 ts_info; +}; + +#ifndef _STRUCT_TIMESPEC +#define _STRUCT_TIMESPEC +struct timespec { + __kernel_old_time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +enum PTP_CMD_TYPE { + PTP_CMD_SET_LOCAL_TIME = 0, + PTP_CMD_DRIFT_LOCAL_TIME, + PTP_CMD_LATCHED_LOCAL_TIME, +}; + + +struct rtl8125_private; +struct RxDescV3; + +int rtl8125_get_ts_info(struct net_device *netdev, + struct ethtool_ts_info *info); + +void rtl8125_ptp_reset(struct rtl8125_private *tp); +void rtl8125_ptp_init(struct rtl8125_private *tp); +void rtl8125_ptp_suspend(struct rtl8125_private *tp); +void rtl8125_ptp_stop(struct rtl8125_private *tp); + +int rtl8125_ptp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); + +void rtl8125_rx_ptp_pktstamp(struct rtl8125_private *tp, struct sk_buff *skb, + struct RxDescV3 *descv3); + +#endif /* _LINUX_rtl8125_PTP_H */ diff --git a/addons/r8125/src/4.4.180/r8125_realwow.h b/addons/r8125/src/4.4.180/r8125_realwow.h new file mode 100755 index 00000000..e5e9b46d --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_realwow.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_R8125_REALWOW_H +#define _LINUX_R8125_REALWOW_H + +#define SIOCDEVPRIVATE_RTLREALWOW SIOCDEVPRIVATE+3 + +#define MAX_RealWoW_KCP_SIZE (100) +#define MAX_RealWoW_Payload (64) + +#define KA_TX_PACKET_SIZE (100) +#define KA_WAKEUP_PATTERN_SIZE (120) + +//HwSuppKeepAliveOffloadVer +#define HW_SUPPORT_KCP_OFFLOAD(_M) ((_M)->HwSuppKCPOffloadVer > 0) + +enum rtl_realwow_cmd { + + RTL_REALWOW_SET_KCP_DISABLE=0, + RTL_REALWOW_SET_KCP_INFO, + RTL_REALWOW_SET_KCP_CONTENT, + + RTL_REALWOW_SET_KCP_ACKPKTINFO, + RTL_REALWOW_SET_KCP_WPINFO, + RTL_REALWOW_SET_KCPDHCP_TIMEOUT, + + RTLT_REALWOW_COMMAND_INVALID +}; + +struct rtl_realwow_ioctl_struct { + __u32 cmd; + __u32 offset; + __u32 len; + union { + __u32 data; + void *data_buffer; + }; +}; + +typedef struct _MP_KCPInfo { + u8 DIPv4[4]; + u8 MacID[6]; + u16 UdpPort[2]; + u8 PKTLEN[2]; + + u16 ackLostCnt; + u8 KCP_WakePattern[MAX_RealWoW_Payload]; + u8 KCP_AckPacket[MAX_RealWoW_Payload]; + u32 KCP_interval; + u8 KCP_WakePattern_Len; + u8 KCP_AckPacket_Len; + u8 KCP_TxPacket[2][KA_TX_PACKET_SIZE]; +} MP_KCP_INFO, *PMP_KCP_INFO; + +typedef struct _KCPInfo { + u32 nId; // = id + u8 DIPv4[4]; + u8 MacID[6]; + u16 UdpPort; + u16 PKTLEN; +} KCPInfo, *PKCPInfo; + +typedef struct _KCPContent { + u32 id; // = id + u32 mSec; // = msec + u32 size; // =size + u8 bPacket[MAX_RealWoW_KCP_SIZE]; // put packet here +} KCPContent, *PKCPContent; + +typedef struct _RealWoWAckPktInfo { + u16 ackLostCnt; + u16 patterntSize; + u8 pattern[MAX_RealWoW_Payload]; +} RealWoWAckPktInfo,*PRealWoWAckPktInfo; + +typedef struct _RealWoWWPInfo { + u16 patterntSize; + u8 pattern[MAX_RealWoW_Payload]; +} RealWoWWPInfo,*PRealWoWWPInfo; + +int rtl8125_realwow_ioctl(struct net_device *dev, struct ifreq *ifr); +void rtl8125_realwow_hw_init(struct net_device *dev); +void rtl8125_get_realwow_hw_version(struct net_device *dev); +void rtl8125_set_realwow_d3_para(struct net_device *dev); + +#endif /* _LINUX_R8125_REALWOW_H */ diff --git a/addons/r8125/src/4.4.180/r8125_rss.c b/addons/r8125/src/4.4.180/r8125_rss.c new file mode 100755 index 00000000..1f55c447 --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_rss.c @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8168 is the Linux device driver released for Realtek Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include "r8125.h" + +enum rtl8125_rss_register_content { + /* RSS */ + RSS_CTRL_TCP_IPV4_SUPP = (1 << 0), + RSS_CTRL_IPV4_SUPP = (1 << 1), + RSS_CTRL_TCP_IPV6_SUPP = (1 << 2), + RSS_CTRL_IPV6_SUPP = (1 << 3), + RSS_HALF_SUPP = (1 << 7), + RSS_CTRL_UDP_IPV4_SUPP = (1 << 11), + RSS_CTRL_UDP_IPV6_SUPP = (1 << 12), + RSS_QUAD_CPU_EN = (1 << 16), + RSS_HQ_Q_SUP_R = (1 << 31), +}; + +static int rtl8125_get_rss_hash_opts(struct rtl8125_private *tp, + struct ethtool_rxnfc *cmd) +{ + cmd->data = 0; + + /* Report default options for RSS */ + switch (cmd->flow_type) { + case TCP_V4_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fallthrough */ + case UDP_V4_FLOW: + if (tp->rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fallthrough */ + case IPV4_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fallthrough */ + case UDP_V6_FLOW: + if (tp->rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) + cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fallthrough */ + case IPV6_FLOW: + cmd->data |= RXH_IP_SRC | RXH_IP_DST; + break; + default: + return -EINVAL; + } + + return 0; +} + +int rtl8125_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + u32 *rule_locs) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + netif_info(tp, drv, tp->dev, "rss get rxnfc\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return ret; + + switch (cmd->cmd) { + case ETHTOOL_GRXRINGS: + cmd->data = rtl8125_tot_rx_rings(tp); + ret = 0; + break; + case ETHTOOL_GRXFH: + ret = rtl8125_get_rss_hash_opts(tp, cmd); + break; + default: + break; + } + + return ret; +} + +u32 rtl8125_rss_indir_tbl_entries(struct rtl8125_private *tp) +{ + return tp->HwSuppIndirTblEntries; +} + +#define RSS_MASK_BITS_OFFSET (8) +#define RSS_CPU_NUM_OFFSET (16) +#define RTL8125_UDP_RSS_FLAGS (RTL_8125_RSS_FLAG_HASH_UDP_IPV4 | \ + RTL_8125_RSS_FLAG_HASH_UDP_IPV6) +static int _rtl8125_set_rss_hash_opt(struct rtl8125_private *tp) +{ + u32 rss_flags = tp->rss_flags; + u32 hash_mask_len; + u32 rss_ctrl; + + rss_ctrl = ilog2(rtl8125_tot_rx_rings(tp)); + rss_ctrl &= (BIT_0 | BIT_1 | BIT_2); + rss_ctrl <<= RSS_CPU_NUM_OFFSET; + + /* Perform hash on these packet types */ + rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP + | RSS_CTRL_IPV4_SUPP + | RSS_CTRL_IPV6_SUPP + | RSS_CTRL_TCP_IPV6_SUPP; + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) + rss_ctrl |= RSS_CTRL_UDP_IPV4_SUPP; + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) + rss_ctrl |= RSS_CTRL_UDP_IPV6_SUPP; + + hash_mask_len = ilog2(rtl8125_rss_indir_tbl_entries(tp)); + hash_mask_len &= (BIT_0 | BIT_1 | BIT_2); + rss_ctrl |= hash_mask_len << RSS_MASK_BITS_OFFSET; + + RTL_W32(tp, RSS_CTRL_8125, rss_ctrl); + + return 0; +} + +static int rtl8125_set_rss_hash_opt(struct rtl8125_private *tp, + struct ethtool_rxnfc *nfc) +{ + u32 rss_flags = tp->rss_flags; + + netif_info(tp, drv, tp->dev, "rss set hash\n"); + + /* + * RSS does not support anything other than hashing + * to queues on src and dst IPs and ports + */ + if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST | + RXH_L4_B_0_1 | RXH_L4_B_2_3)) + return -EINVAL; + + switch (nfc->flow_type) { + case TCP_V4_FLOW: + case TCP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST) || + !(nfc->data & RXH_L4_B_0_1) || + !(nfc->data & RXH_L4_B_2_3)) + return -EINVAL; + break; + case UDP_V4_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + rss_flags &= ~RTL_8125_RSS_FLAG_HASH_UDP_IPV4; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + rss_flags |= RTL_8125_RSS_FLAG_HASH_UDP_IPV4; + break; + default: + return -EINVAL; + } + break; + case UDP_V6_FLOW: + if (!(nfc->data & RXH_IP_SRC) || + !(nfc->data & RXH_IP_DST)) + return -EINVAL; + switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { + case 0: + rss_flags &= ~RTL_8125_RSS_FLAG_HASH_UDP_IPV6; + break; + case (RXH_L4_B_0_1 | RXH_L4_B_2_3): + rss_flags |= RTL_8125_RSS_FLAG_HASH_UDP_IPV6; + break; + default: + return -EINVAL; + } + break; + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case AH_V4_FLOW: + case ESP_V4_FLOW: + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case AH_V6_FLOW: + case ESP_V6_FLOW: + case IP_USER_FLOW: + case ETHER_FLOW: + /* RSS is not supported for these protocols */ + if (nfc->data) { + netif_err(tp, drv, tp->dev, "Command parameters not supported\n"); + return -EINVAL; + } + return 0; + break; + default: + return -EINVAL; + } + + /* if we changed something we need to update flags */ + if (rss_flags != tp->rss_flags) { + u32 rss_ctrl = RTL_R32(tp, RSS_CTRL_8125); + + if ((rss_flags & RTL8125_UDP_RSS_FLAGS) && + !(tp->rss_flags & RTL8125_UDP_RSS_FLAGS)) + netdev_warn(tp->dev, + "enabling UDP RSS: fragmented packets may " + "arrive out of order to the stack above\n"); + + tp->rss_flags = rss_flags; + + /* Perform hash on these packet types */ + rss_ctrl |= RSS_CTRL_TCP_IPV4_SUPP + | RSS_CTRL_IPV4_SUPP + | RSS_CTRL_IPV6_SUPP + | RSS_CTRL_TCP_IPV6_SUPP; + + rss_ctrl &= ~(RSS_CTRL_UDP_IPV4_SUPP | + RSS_CTRL_UDP_IPV6_SUPP); + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV4) + rss_ctrl |= RSS_CTRL_UDP_IPV4_SUPP; + + if (rss_flags & RTL_8125_RSS_FLAG_HASH_UDP_IPV6) + rss_ctrl |= RSS_CTRL_UDP_IPV6_SUPP; + + RTL_W32(tp, RSS_CTRL_8125, rss_ctrl); + } + + return 0; +} + +int rtl8125_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int ret = -EOPNOTSUPP; + + netif_info(tp, drv, tp->dev, "rss set rxnfc\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return ret; + + switch (cmd->cmd) { + case ETHTOOL_SRXFH: + ret = rtl8125_set_rss_hash_opt(tp, cmd); + break; + default: + break; + } + + return ret; +} + +static u32 _rtl8125_get_rxfh_key_size(struct rtl8125_private *tp) +{ + return sizeof(tp->rss_key); +} + +u32 rtl8125_get_rxfh_key_size(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + netif_info(tp, drv, tp->dev, "rss get key size\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return 0; + + return _rtl8125_get_rxfh_key_size(tp); +} + +u32 rtl8125_rss_indir_size(struct net_device *dev) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + netif_info(tp, drv, tp->dev, "rss get indir tbl size\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return 0; + + return rtl8125_rss_indir_tbl_entries(tp); +} + +static void rtl8125_get_reta(struct rtl8125_private *tp, u32 *indir) +{ + int i, reta_size = rtl8125_rss_indir_tbl_entries(tp); + + for (i = 0; i < reta_size; i++) + indir[i] = tp->rss_indir_tbl[i]; +} + +int rtl8125_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, + u8 *hfunc) +{ + struct rtl8125_private *tp = netdev_priv(dev); + + netif_info(tp, drv, tp->dev, "rss get rxfh\n"); + + if (!(dev->features & NETIF_F_RXHASH)) + return -EOPNOTSUPP; + + if (hfunc) + *hfunc = ETH_RSS_HASH_TOP; + + if (indir) + rtl8125_get_reta(tp, indir); + + if (key) + memcpy(key, tp->rss_key, rtl8125_get_rxfh_key_size(dev)); + + return 0; +} + +static u32 rtl8125_rss_key_reg(struct rtl8125_private *tp) +{ + return RSS_KEY_8125; +} + +static u32 rtl8125_rss_indir_tbl_reg(struct rtl8125_private *tp) +{ + return RSS_INDIRECTION_TBL_8125_V2; +} + +static void rtl8125_store_reta(struct rtl8125_private *tp) +{ + u16 indir_tbl_reg = rtl8125_rss_indir_tbl_reg(tp); + u32 i, reta_entries = rtl8125_rss_indir_tbl_entries(tp); + u32 reta = 0; + u8 *indir_tbl = tp->rss_indir_tbl; + + /* Write redirection table to HW */ + for (i = 0; i < reta_entries; i++) { + reta |= indir_tbl[i] << (i & 0x3) * 8; + if ((i & 3) == 3) { + RTL_W32(tp, indir_tbl_reg, reta); + + indir_tbl_reg += 4; + reta = 0; + } + } +} + +static void rtl8125_store_rss_key(struct rtl8125_private *tp) +{ + const u16 rss_key_reg = rtl8125_rss_key_reg(tp); + u32 i, rss_key_size = _rtl8125_get_rxfh_key_size(tp); + u32 *rss_key = (u32*)tp->rss_key; + + /* Write redirection table to HW */ + for (i = 0; i < rss_key_size; i+=4) + RTL_W32(tp, rss_key_reg + i, *rss_key++); +} + +int rtl8125_set_rxfh(struct net_device *dev, const u32 *indir, + const u8 *key, const u8 hfunc) +{ + struct rtl8125_private *tp = netdev_priv(dev); + int i; + u32 reta_entries = rtl8125_rss_indir_tbl_entries(tp); + + netif_info(tp, drv, tp->dev, "rss set rxfh\n"); + + /* We require at least one supported parameter to be changed and no + * change in any of the unsupported parameters + */ + if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP) + return -EOPNOTSUPP; + + /* Fill out the redirection table */ + if (indir) { + int max_queues = tp->num_rx_rings; + + /* Verify user input. */ + for (i = 0; i < reta_entries; i++) + if (indir[i] >= max_queues) + return -EINVAL; + + for (i = 0; i < reta_entries; i++) + tp->rss_indir_tbl[i] = indir[i]; + } + + /* Fill out the rss hash key */ + if (key) + memcpy(tp->rss_key, key, rtl8125_get_rxfh_key_size(dev)); + + rtl8125_store_reta(tp); + + rtl8125_store_rss_key(tp); + + return 0; +} + +static u32 rtl8125_get_rx_desc_hash(struct rtl8125_private *tp, + struct RxDescV3 *descv3) +{ + return le32_to_cpu(descv3->RxDescNormalDDWord2.RSSResult); +} + +#define RXS_8125B_RSS_UDP BIT(9) +#define RXS_8125_RSS_IPV4 BIT(10) +#define RXS_8125_RSS_IPV6 BIT(12) +#define RXS_8125_RSS_TCP BIT(13) +#define RTL8125_RXS_RSS_L3_TYPE_MASK (RXS_8125_RSS_IPV4 | RXS_8125_RSS_IPV6) +#define RTL8125_RXS_RSS_L4_TYPE_MASK (RXS_8125_RSS_TCP | RXS_8125B_RSS_UDP) +void rtl8125_rx_hash(struct rtl8125_private *tp, + struct RxDescV3 *descv3, + struct sk_buff *skb) +{ + u16 rss_header_info; + + if (!(tp->dev->features & NETIF_F_RXHASH)) + return; + + rss_header_info = le16_to_cpu(descv3->RxDescNormalDDWord2.HeaderInfo); + + if (!(rss_header_info & RTL8125_RXS_RSS_L3_TYPE_MASK)) + return; + + skb_set_hash(skb, rtl8125_get_rx_desc_hash(tp, descv3), + (RTL8125_RXS_RSS_L4_TYPE_MASK & rss_header_info) ? + PKT_HASH_TYPE_L4 : PKT_HASH_TYPE_L3); +} + +void rtl8125_disable_rss(struct rtl8125_private *tp) +{ + RTL_W32(tp, RSS_CTRL_8125, 0x00); +} + +void _rtl8125_config_rss(struct rtl8125_private *tp) +{ + _rtl8125_set_rss_hash_opt(tp); + + rtl8125_store_reta(tp); + + rtl8125_store_rss_key(tp); +} + +void rtl8125_config_rss(struct rtl8125_private *tp) +{ + if (!tp->EnableRss) { + rtl8125_disable_rss(tp); + return; + } + + _rtl8125_config_rss(tp); +} + +void rtl8125_init_rss(struct rtl8125_private *tp) +{ + int i; + + for (i = 0; i < rtl8125_rss_indir_tbl_entries(tp); i++) + tp->rss_indir_tbl[i] = ethtool_rxfh_indir_default(i, tp->num_rx_rings); + + netdev_rss_key_fill(tp->rss_key, RTL8125_RSS_KEY_SIZE); +} diff --git a/addons/r8125/src/4.4.180/r8125_rss.h b/addons/r8125/src/4.4.180/r8125_rss.h new file mode 100755 index 00000000..88641395 --- /dev/null +++ b/addons/r8125/src/4.4.180/r8125_rss.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_rtl8125_RSS_H +#define _LINUX_rtl8125_RSS_H + +#include +#include + +#define RTL8125_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ +#define RTL8125_MAX_INDIRECTION_TABLE_ENTRIES 128 + +enum rtl8125_rss_flag { + RTL_8125_RSS_FLAG_HASH_UDP_IPV4 = (1 << 0), + RTL_8125_RSS_FLAG_HASH_UDP_IPV6 = (1 << 1), +}; + +struct rtl8125_private; + +int rtl8125_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd, + u32 *rule_locs); +int rtl8125_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd); +u32 rtl8125_get_rxfh_key_size(struct net_device *netdev); +u32 rtl8125_rss_indir_size(struct net_device *netdev); +int rtl8125_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, + u8 *hfunc); +int rtl8125_set_rxfh(struct net_device *netdev, const u32 *indir, + const u8 *key, const u8 hfunc); +void rtl8125_rx_hash(struct rtl8125_private *tp, + struct RxDescV3 *descv3, + struct sk_buff *skb); +void _rtl8125_config_rss(struct rtl8125_private *tp); +void rtl8125_config_rss(struct rtl8125_private *tp); +void rtl8125_init_rss(struct rtl8125_private *tp); +u32 rtl8125_rss_indir_tbl_entries(struct rtl8125_private *tp); +void rtl8125_disable_rss(struct rtl8125_private *tp); + +#endif /* _LINUX_rtl8125_RSS_H */ diff --git a/addons/r8125/src/4.4.180/rtl_eeprom.c b/addons/r8125/src/4.4.180/rtl_eeprom.c new file mode 100755 index 00000000..03660dda --- /dev/null +++ b/addons/r8125/src/4.4.180/rtl_eeprom.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include + +#include "r8125.h" +#include "rtl_eeprom.h" + +//------------------------------------------------------------------- +//rtl8125_eeprom_type(): +// tell the eeprom type +//return value: +// 0: the eeprom type is 93C46 +// 1: the eeprom type is 93C56 or 93C66 +//------------------------------------------------------------------- +void rtl8125_eeprom_type(struct rtl8125_private *tp) +{ + u16 magic = 0; + + if (tp->mcfg == CFG_METHOD_DEFAULT) + goto out_no_eeprom; + + if(RTL_R8(tp, 0xD2)&0x04) { + //not support + //tp->eeprom_type = EEPROM_TWSI; + //tp->eeprom_len = 256; + goto out_no_eeprom; + } else if(RTL_R32(tp, RxConfig) & RxCfg_9356SEL) { + tp->eeprom_type = EEPROM_TYPE_93C56; + tp->eeprom_len = 256; + } else { + tp->eeprom_type = EEPROM_TYPE_93C46; + tp->eeprom_len = 128; + } + + magic = rtl8125_eeprom_read_sc(tp, 0); + +out_no_eeprom: + if ((magic != 0x8129) && (magic != 0x8128)) { + tp->eeprom_type = EEPROM_TYPE_NONE; + tp->eeprom_len = 0; + } +} + +void rtl8125_eeprom_cleanup(struct rtl8125_private *tp) +{ + u8 x; + + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EEDI | Cfg9346_EECS); + + RTL_W8(tp, Cfg9346, x); + + rtl8125_raise_clock(tp, &x); + rtl8125_lower_clock(tp, &x); +} + +int rtl8125_eeprom_cmd_done(struct rtl8125_private *tp) +{ + u8 x; + int i; + + rtl8125_stand_by(tp); + + for (i = 0; i < 50000; i++) { + x = RTL_R8(tp, Cfg9346); + + if (x & Cfg9346_EEDO) { + udelay(RTL_CLOCK_RATE * 2 * 3); + return 0; + } + udelay(1); + } + + return -1; +} + +//------------------------------------------------------------------- +//rtl8125_eeprom_read_sc(): +// read one word from eeprom +//------------------------------------------------------------------- +u16 rtl8125_eeprom_read_sc(struct rtl8125_private *tp, u16 reg) +{ + int addr_sz = 6; + u8 x; + u16 data; + + if(tp->eeprom_type == EEPROM_TYPE_NONE) { + return -1; + } + + if (tp->eeprom_type==EEPROM_TYPE_93C46) + addr_sz = 6; + else if (tp->eeprom_type==EEPROM_TYPE_93C56) + addr_sz = 8; + + x = Cfg9346_EEM1 | Cfg9346_EECS; + RTL_W8(tp, Cfg9346, x); + + rtl8125_shift_out_bits(tp, RTL_EEPROM_READ_OPCODE, 3); + rtl8125_shift_out_bits(tp, reg, addr_sz); + + data = rtl8125_shift_in_bits(tp); + + rtl8125_eeprom_cleanup(tp); + + RTL_W8(tp, Cfg9346, 0); + + return data; +} + +//------------------------------------------------------------------- +//rtl8125_eeprom_write_sc(): +// write one word to a specific address in the eeprom +//------------------------------------------------------------------- +void rtl8125_eeprom_write_sc(struct rtl8125_private *tp, u16 reg, u16 data) +{ + u8 x; + int addr_sz = 6; + int w_dummy_addr = 4; + + if(tp->eeprom_type == EEPROM_TYPE_NONE) { + return ; + } + + if (tp->eeprom_type==EEPROM_TYPE_93C46) { + addr_sz = 6; + w_dummy_addr = 4; + } else if (tp->eeprom_type==EEPROM_TYPE_93C56) { + addr_sz = 8; + w_dummy_addr = 6; + } + + x = Cfg9346_EEM1 | Cfg9346_EECS; + RTL_W8(tp, Cfg9346, x); + + rtl8125_shift_out_bits(tp, RTL_EEPROM_EWEN_OPCODE, 5); + rtl8125_shift_out_bits(tp, reg, w_dummy_addr); + rtl8125_stand_by(tp); + + rtl8125_shift_out_bits(tp, RTL_EEPROM_ERASE_OPCODE, 3); + rtl8125_shift_out_bits(tp, reg, addr_sz); + if (rtl8125_eeprom_cmd_done(tp) < 0) { + return; + } + rtl8125_stand_by(tp); + + rtl8125_shift_out_bits(tp, RTL_EEPROM_WRITE_OPCODE, 3); + rtl8125_shift_out_bits(tp, reg, addr_sz); + rtl8125_shift_out_bits(tp, data, 16); + if (rtl8125_eeprom_cmd_done(tp) < 0) { + return; + } + rtl8125_stand_by(tp); + + rtl8125_shift_out_bits(tp, RTL_EEPROM_EWDS_OPCODE, 5); + rtl8125_shift_out_bits(tp, reg, w_dummy_addr); + + rtl8125_eeprom_cleanup(tp); + RTL_W8(tp, Cfg9346, 0); +} + +void rtl8125_raise_clock(struct rtl8125_private *tp, u8 *x) +{ + *x = *x | Cfg9346_EESK; + RTL_W8(tp, Cfg9346, *x); + udelay(RTL_CLOCK_RATE); +} + +void rtl8125_lower_clock(struct rtl8125_private *tp, u8 *x) +{ + + *x = *x & ~Cfg9346_EESK; + RTL_W8(tp, Cfg9346, *x); + udelay(RTL_CLOCK_RATE); +} + +void rtl8125_shift_out_bits(struct rtl8125_private *tp, int data, int count) +{ + u8 x; + int mask; + + mask = 0x01 << (count - 1); + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); + + do { + if (data & mask) + x |= Cfg9346_EEDI; + else + x &= ~Cfg9346_EEDI; + + RTL_W8(tp, Cfg9346, x); + udelay(RTL_CLOCK_RATE); + rtl8125_raise_clock(tp, &x); + rtl8125_lower_clock(tp, &x); + mask = mask >> 1; + } while(mask); + + x &= ~Cfg9346_EEDI; + RTL_W8(tp, Cfg9346, x); +} + +u16 rtl8125_shift_in_bits(struct rtl8125_private *tp) +{ + u8 x; + u16 d, i; + + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EEDI | Cfg9346_EEDO); + + d = 0; + + for (i = 0; i < 16; i++) { + d = d << 1; + rtl8125_raise_clock(tp, &x); + + x = RTL_R8(tp, Cfg9346); + x &= ~Cfg9346_EEDI; + + if (x & Cfg9346_EEDO) + d |= 1; + + rtl8125_lower_clock(tp, &x); + } + + return d; +} + +void rtl8125_stand_by(struct rtl8125_private *tp) +{ + u8 x; + + x = RTL_R8(tp, Cfg9346); + x &= ~(Cfg9346_EECS | Cfg9346_EESK); + RTL_W8(tp, Cfg9346, x); + udelay(RTL_CLOCK_RATE); + + x |= Cfg9346_EECS; + RTL_W8(tp, Cfg9346, x); +} + +void rtl8125_set_eeprom_sel_low(struct rtl8125_private *tp) +{ + RTL_W8(tp, Cfg9346, Cfg9346_EEM1); + RTL_W8(tp, Cfg9346, Cfg9346_EEM1 | Cfg9346_EESK); + + udelay(20); + + RTL_W8(tp, Cfg9346, Cfg9346_EEM1); +} diff --git a/addons/r8125/src/4.4.180/rtl_eeprom.h b/addons/r8125/src/4.4.180/rtl_eeprom.h new file mode 100755 index 00000000..8faed17c --- /dev/null +++ b/addons/r8125/src/4.4.180/rtl_eeprom.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +//EEPROM opcodes +#define RTL_EEPROM_READ_OPCODE 06 +#define RTL_EEPROM_WRITE_OPCODE 05 +#define RTL_EEPROM_ERASE_OPCODE 07 +#define RTL_EEPROM_EWEN_OPCODE 19 +#define RTL_EEPROM_EWDS_OPCODE 16 + +#define RTL_CLOCK_RATE 3 + +void rtl8125_eeprom_type(struct rtl8125_private *tp); +void rtl8125_eeprom_cleanup(struct rtl8125_private *tp); +u16 rtl8125_eeprom_read_sc(struct rtl8125_private *tp, u16 reg); +void rtl8125_eeprom_write_sc(struct rtl8125_private *tp, u16 reg, u16 data); +void rtl8125_shift_out_bits(struct rtl8125_private *tp, int data, int count); +u16 rtl8125_shift_in_bits(struct rtl8125_private *tp); +void rtl8125_raise_clock(struct rtl8125_private *tp, u8 *x); +void rtl8125_lower_clock(struct rtl8125_private *tp, u8 *x); +void rtl8125_stand_by(struct rtl8125_private *tp); +void rtl8125_set_eeprom_sel_low(struct rtl8125_private *tp); diff --git a/addons/r8125/src/4.4.180/rtltool.c b/addons/r8125/src/4.4.180/rtltool.c new file mode 100755 index 00000000..f40df6fe --- /dev/null +++ b/addons/r8125/src/4.4.180/rtltool.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "r8125.h" +#include "rtl_eeprom.h" +#include "rtltool.h" + +int rtl8125_tool_ioctl(struct rtl8125_private *tp, struct ifreq *ifr) +{ + struct rtltool_cmd my_cmd; + int ret; + + if (copy_from_user(&my_cmd, ifr->ifr_data, sizeof(my_cmd))) + return -EFAULT; + + ret = 0; + switch (my_cmd.cmd) { + case RTLTOOL_READ_MAC: + if (my_cmd.len==1) + my_cmd.data = readb(tp->mmio_addr+my_cmd.offset); + else if (my_cmd.len==2) + my_cmd.data = readw(tp->mmio_addr+(my_cmd.offset&~1)); + else if (my_cmd.len==4) + my_cmd.data = readl(tp->mmio_addr+(my_cmd.offset&~3)); + else { + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTLTOOL_WRITE_MAC: + if (my_cmd.len==1) + writeb(my_cmd.data, tp->mmio_addr+my_cmd.offset); + else if (my_cmd.len==2) + writew(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~1)); + else if (my_cmd.len==4) + writel(my_cmd.data, tp->mmio_addr+(my_cmd.offset&~3)); + else { + ret = -EOPNOTSUPP; + break; + } + + break; + + case RTLTOOL_READ_PHY: + my_cmd.data = rtl8125_mdio_prot_read(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_PHY: + rtl8125_mdio_prot_write(tp, my_cmd.offset, my_cmd.data); + break; + + case RTLTOOL_READ_EPHY: + my_cmd.data = rtl8125_ephy_read(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_EPHY: + rtl8125_ephy_write(tp, my_cmd.offset, my_cmd.data); + break; + + case RTLTOOL_READ_ERI: + my_cmd.data = 0; + if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) { + my_cmd.data = rtl8125_eri_read(tp, my_cmd.offset, my_cmd.len, ERIAR_ExGMAC); + } else { + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_ERI: + if (my_cmd.len==1 || my_cmd.len==2 || my_cmd.len==4) { + rtl8125_eri_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data, ERIAR_ExGMAC); + } else { + ret = -EOPNOTSUPP; + break; + } + break; + + case RTLTOOL_READ_PCI: + my_cmd.data = 0; + if (my_cmd.len==1) + pci_read_config_byte(tp->pci_dev, my_cmd.offset, + (u8 *)&my_cmd.data); + else if (my_cmd.len==2) + pci_read_config_word(tp->pci_dev, my_cmd.offset, + (u16 *)&my_cmd.data); + else if (my_cmd.len==4) + pci_read_config_dword(tp->pci_dev, my_cmd.offset, + &my_cmd.data); + else { + ret = -EOPNOTSUPP; + break; + } + + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTLTOOL_WRITE_PCI: + if (my_cmd.len==1) + pci_write_config_byte(tp->pci_dev, my_cmd.offset, + my_cmd.data); + else if (my_cmd.len==2) + pci_write_config_word(tp->pci_dev, my_cmd.offset, + my_cmd.data); + else if (my_cmd.len==4) + pci_write_config_dword(tp->pci_dev, my_cmd.offset, + my_cmd.data); + else { + ret = -EOPNOTSUPP; + break; + } + + break; + + case RTLTOOL_READ_EEPROM: + my_cmd.data = rtl8125_eeprom_read_sc(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTLTOOL_WRITE_EEPROM: + rtl8125_eeprom_write_sc(tp, my_cmd.offset, my_cmd.data); + break; + + case RTL_READ_OOB_MAC: + rtl8125_oob_mutex_lock(tp); + my_cmd.data = rtl8125_ocp_read(tp, my_cmd.offset, 4); + rtl8125_oob_mutex_unlock(tp); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTL_WRITE_OOB_MAC: + if (my_cmd.len == 0 || my_cmd.len > 4) + return -EOPNOTSUPP; + + rtl8125_oob_mutex_lock(tp); + rtl8125_ocp_write(tp, my_cmd.offset, my_cmd.len, my_cmd.data); + rtl8125_oob_mutex_unlock(tp); + break; + + case RTL_ENABLE_PCI_DIAG: + tp->rtk_enable_diag = 1; + + dprintk("enable rtk diag\n"); + break; + + case RTL_DISABLE_PCI_DIAG: + tp->rtk_enable_diag = 0; + + dprintk("disable rtk diag\n"); + break; + + case RTL_READ_MAC_OCP: + if (my_cmd.offset % 2) + return -EOPNOTSUPP; + + my_cmd.data = rtl8125_mac_ocp_read(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + break; + + case RTL_WRITE_MAC_OCP: + if ((my_cmd.offset % 2) || (my_cmd.len != 2)) + return -EOPNOTSUPP; + + rtl8125_mac_ocp_write(tp, my_cmd.offset, (u16)my_cmd.data); + break; + + case RTL_DIRECT_READ_PHY_OCP: + my_cmd.data = rtl8125_mdio_prot_direct_read_phy_ocp(tp, my_cmd.offset); + if (copy_to_user(ifr->ifr_data, &my_cmd, sizeof(my_cmd))) { + ret = -EFAULT; + break; + } + + break; + + case RTL_DIRECT_WRITE_PHY_OCP: + rtl8125_mdio_prot_direct_write_phy_ocp(tp, my_cmd.offset, my_cmd.data); + break; + + default: + ret = -EOPNOTSUPP; + break; + } + + return ret; +} diff --git a/addons/r8125/src/4.4.180/rtltool.h b/addons/r8125/src/4.4.180/rtltool.h new file mode 100755 index 00000000..a54f8e6a --- /dev/null +++ b/addons/r8125/src/4.4.180/rtltool.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +################################################################################ +# +# r8125 is the Linux device driver released for Realtek 2.5Gigabit Ethernet +# controllers with PCI-Express interface. +# +# Copyright(c) 2022 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Author: +# Realtek NIC software team +# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan +# +################################################################################ +*/ + +/************************************************************************************ + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + ***********************************************************************************/ + +#ifndef _LINUX_RTLTOOL_H +#define _LINUX_RTLTOOL_H + +#define SIOCRTLTOOL SIOCDEVPRIVATE+1 + +enum rtl_cmd { + RTLTOOL_READ_MAC=0, + RTLTOOL_WRITE_MAC, + RTLTOOL_READ_PHY, + RTLTOOL_WRITE_PHY, + RTLTOOL_READ_EPHY, + RTLTOOL_WRITE_EPHY, + RTLTOOL_READ_ERI, + RTLTOOL_WRITE_ERI, + RTLTOOL_READ_PCI, + RTLTOOL_WRITE_PCI, + RTLTOOL_READ_EEPROM, + RTLTOOL_WRITE_EEPROM, + + RTL_READ_OOB_MAC, + RTL_WRITE_OOB_MAC, + + RTL_ENABLE_PCI_DIAG, + RTL_DISABLE_PCI_DIAG, + + RTL_READ_MAC_OCP, + RTL_WRITE_MAC_OCP, + + RTL_DIRECT_READ_PHY_OCP, + RTL_DIRECT_WRITE_PHY_OCP, + + RTLTOOL_INVALID +}; + +struct rtltool_cmd { + __u32 cmd; + __u32 offset; + __u32 len; + __u32 data; +}; + +enum mode_access { + MODE_NONE=0, + MODE_READ, + MODE_WRITE +}; + +#ifdef __KERNEL__ +int rtl8125_tool_ioctl(struct rtl8125_private *tp, struct ifreq *ifr); +#endif + +#endif /* _LINUX_RTLTOOL_H */ diff --git a/files/board/arpl/overlayfs/opt/arpl/model-configs/DS1621+.yml b/files/board/arpl/overlayfs/opt/arpl/model-configs/DS1621+.yml index 187d9d14..82a0cd1a 100644 --- a/files/board/arpl/overlayfs/opt/arpl/model-configs/DS1621+.yml +++ b/files/board/arpl/overlayfs/opt/arpl/model-configs/DS1621+.yml @@ -11,6 +11,8 @@ modules-notneeded: &modules-notneeded - ehci-pci - uhci_hcd synoinfo: &synoinfo + support_disk_compatibility: "no" + support_memory_compatibility: "no" rss_server: "http://example.com/null.xml" rss_server_ssl: "https://example.com/null.xml" rss_server_v2: "https://example.com/autoupdate/v2/getList" diff --git a/files/board/arpl/overlayfs/opt/arpl/model-configs/DS3622xs+.yml b/files/board/arpl/overlayfs/opt/arpl/model-configs/DS3622xs+.yml index 707abed6..8aa71421 100644 --- a/files/board/arpl/overlayfs/opt/arpl/model-configs/DS3622xs+.yml +++ b/files/board/arpl/overlayfs/opt/arpl/model-configs/DS3622xs+.yml @@ -15,8 +15,8 @@ modules-notneeded: &modules-notneeded synoinfo: &synoinfo esataportcfg: "0x00" support_bde_internal_10g: "no" - support_disk_compatibility : "no" - support_memory_compatibility : "no" + support_disk_compatibility: "no" + support_memory_compatibility: "no" supportraidgroup: "no" supportssdcache: "no" rss_server: "http://example.com/null.xml" diff --git a/files/board/arpl/p3/addons/r8125/apollolake-4.4.180.tgz b/files/board/arpl/p3/addons/r8125/apollolake-4.4.180.tgz new file mode 100644 index 0000000000000000000000000000000000000000..9748cd1566791e2f5d2f9b6b23ce1ee09c0c480c GIT binary patch literal 67101 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

j!78<&oFkyyYxk&;C1D>!c@1r-I2C-pDa*r)@( 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 literal 0 HcmV?d00001 diff --git a/files/board/arpl/p3/addons/r8125/broadwell-4.4.180.tgz b/files/board/arpl/p3/addons/r8125/broadwell-4.4.180.tgz new file mode 100644 index 0000000000000000000000000000000000000000..19a96760b2c11fa746d2937d431e2106d732c7b5 GIT binary patch literal 66406 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 literal 0 HcmV?d00001 diff --git a/files/board/arpl/p3/addons/r8125/broadwellnk-4.4.180.tgz b/files/board/arpl/p3/addons/r8125/broadwellnk-4.4.180.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5bcd9a51a0a0f04bcb1b1fefb9bc4b8c233a2b76 GIT binary patch literal 66405 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

$By)%8rf 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%0D6!`HnJ=9|C*Pke@tp@+^R zD*5qtn0f4cUGabm`(Tntw8Mz5EAHpJPF1k+8v3;U$@xC!JKyYqJ4gG_GiN)4_%m5sP8n0AWH96$O!J<0V?Cc11D1&Ov@?i4&nX@f$R2d|ytK;RF zJ)*iiUd`51eqK|@opqh81wb>!hyaMKCHTO!V6KcL*@7Q&dvZdCF zwUe^7^Om^nX_hX=ugDE=d*0w2N1aW_|Dw^*yoHO*T3QEZSNR?rfD_a){oR1@O_9Vy zAE7eWoWsOvzp$2EG;A9nae8N8J-?F?1tXm~54u#4zqB1L)E*vz%J zOdqJm@yFNAe6p&|6}NtUQ>pqF(!K@0sUmwgNkd6_-2hdPMJQ0Th)OG{AP5a4kZP;Q z!?!N0*u_;>)C7Ehq~3(~dWo%P-h&3FIqzKT8{?FHj!>qQ{(al^v#ugigRrj)AZM2^+tdsU{cOnGx{-|DQl? z9CE`k1t(iJU?iOe zPZBasH#BBTCC%_ru*=e92`F>tw7Z01Pgk?&geo4PyBCMIF1gkkpAFdlF-D+#PZ3xW z5uZM$hx<}YS^E=lfyRWf5y_3S8xObBcQjjlb_v4a8!2trUrw6WK9`%mS8 zq}`DsPfLPR+Tdwn(#sNp&d?I>&8sqv^;-Ss%WVUF{h-!%fMDV^8z!5PZJ)y6vfM}9W9P&M&Zj6=S}B( z!{eue3d`)b2dIm2pvhI=L74T2d9%FX^|+Xd9R36&#*GzAwT#NJ#Rtv2X%4QyLNQ;b zxQ4HNXvbCUKlDQ5vMq?@XqUE$pKDY8+V|sk~iDCM$n3d+70N3XbOh!Z*0!_^1StEFv1*=ySS({ zR>rFsFimL0E|vJwd+D9FobcXbP~uXavYJuONKe%$8JiTENvEVhu^Nr!E22}h7BjY& z&rxat0q%GRx%EV12suk@fzsAkY$&o*^HD^NfAI53;&PY1ByH05mSm~qthAc_U3A0~BHor*IN!Q+4=^$)KcQXFb#yJ)`0DZdZ(eB}vC zcNAZW*8gS#ZST%BFt;#%ao4)C_N&j~YByBxJKuZfN7(D=%v-MM3-f>%WW;N&VYA8D z7in4ipTxWx#Y<_;Aw0~p`!02RE?u8bvX_SNXmvurv*dtMJk`d6(Gg)JIURd>XxtOrwC_az=V> zD-4wLiWpPQjryM!pIuLX)|ujC3plkL_Xkw8?WKF)yBl)VDNbk+)<*P!ts);g%Xg($ zo$Q2;-=|3``@7TfpahB$+m&HUxaPtGpa$A}P2rw7;Y@9fq|d4QBVR%Fv#WpleP%M` z>5X>}RT=Br6RPmt=vCziWWU(zyE>~L&rjAf#S2;)n>XxEPHPIxav~UCvwr*5 z8-6JR28za8ylQra7jo9!lT|_Y-I#Ktj@6VL@>k$3eS3cy{_E-rY;A%@Nb)Vpf$7cR zDo9U{O|WEZbe`}$+=_L0#`;qqn(CFuT6{lwq>?qi0ZR^O#2)G0!_dw1lJ4rO?V7sO z=PUy-z4fi%#$rBbn?Qw)b{VD6Uuf5i7NAj_;Ye}N$5~9?=_;6=-aod;k{x}FW;}7d zfD31@`qDZY9%Ss>x#~SmZ&H$5O>34jAWzBu^V~{<9I?u+r=&s&$ED>D<1kXub-53I zU7^@bnoo9N@3gnQNA+yF*uUsgrq`a}#s02AWG8>J00W_6s^ zH)fp89|p84V=mct8^soVB*rckR)HoF#kqqO^eiZ7bRgagXO*Z@JyS($)hI0Po<$dRG+IZa!A1!Xq0++W9_PV?fEatCvunc}>5i_{M!e_7_m%(0?!SUY8!<{_3?Vg^o z`!HjpDPwCX7Y{y7nZkW_FNz|i8y=CPE=iw?oxR{=%#rVb9Q9?E^nTx6FWlI?4aECv z%IYLavnQlfj%I&}Rbx$%Vx;78cH;WHHW<+0@Ej@wU3tuTxPJJ_%MNcKLI2XmZ_0aF z!%V&IC>m;{=XU z-~cW_g2EDAXW$ajiO1d6rY)!p`+YP>vtf&FQmdUIr3$xtzcW{z>y$PG3ZPLSl> zbxJq)ut;{WS@G=gjYn@P*%-gS!kd(wuR5iYdgZwcK!t6pf6ws33*l3F4*yCewO68h z8fjAHm}+TqHSmM771}NZyHP82&I^yvQK}p7$yIO4$b(ip3+DxzOi_np#qiX6H^wJ~ z8hiRL<@oDPr(NwFB{$tslkH%nk7eM_fRxp&${?%YMGa+ z?Di`Aa+I%gDi3w?$`v-46YaUyCirv&7VftAyXC0Y_noMw4i42ne7(2wJ3AKns&N02 z>h#PUxiAy*Y0a@dmkqypN%=58UgJ=wI=sqf+H8Xwz5^#2g$d<$DU?c+Om`YD9JGu| z&I@0j8y@WfO~EzhW8Xp-3@jeye&?`ir3n^XH#ofE)M?(zgPn7do(&{nA)my!VIubZ z$)#TFbgA>Zxst9;9rmkytmiyOQ{Yt$ZleOEdB)z~&DYPXF024jM;Y5@KIm01&sUyZ zrinanHVy;uPn>;ldu0f^7C7%S@co(NQUskBuHxSflZEwY`9MFzJW?JG$A^d?W zE=spJp)V``Ly^Z|jjs9+HE!a^%iQqzxIC^-pNci5EG&{ro};soJFD`Q6@c|kGuQ%K+%Nu@=ED)8@!w{%GZdbFNRw&CPkmd@xwWqZB z)-EUyY5`g>wzMd9%8F5xY$yYNDjPa^lO{U?TQF{nW;D(u!Ov(E^FYo5|F)o$7^f6! zu%eN5F-c@gVH5STo)+Igq{~&;)uECUsI|}<`qpGyXulLHbg*b(MD=7Hg6{SY2rlxh zl^c@AC9!oV2ItGA*0;8;;HE_5qs zv{_n5-K0t?DJh~Dn!6HBfhF8q3P!uqBvX+S&dRk`=MLMOFCTMAp^;r#%;7G>m*SX# z($!m9`g=E)DH_{<17Kq+Nzu%8u=*l72!WEBw@xa$6&KSRu1g6V@9Bd-$x`SlDo|dL zJ3P{>7GOrb!wc$Yu2ryvu3@`e)@q=af-ghN$P=uF5BbDcsjxe4|BS{F^k%~J3r z8ybp~-_>PUG1lEl3sN{=Pa7k zl`&`y$+d6r{5G`J{{ zfOP+fUveu{Y;RbnyP8QtU~>9^WZU&>rxkQLu|bi8rOxjymg=TWsDx;QwlLq3f&6~p5PHFbSIu|r`%Os<3Z*CmcV=W z3ham2GgTP{-J2xW(K!AQbevf<)Y<#E)m7Nlqzz+3F=fjP>P~lbqAofIyQnAV$*Kne zOLF+nF^{rWxh+r~@>1`s3C+b{igLw`s5gc(QCSK1iT1Ig(lF3H)*q0bspvus(2;V~ zC+HknsnNz`T|b8c(S&8D}U|=N=+JQGRe8hZ7aRjT{+>dn)Gd$8$KDTGD#D4T6KqN$!@m*TNY z@3iKsx2;4)F4y`ZR*!qkhghjDWu`@1T+ebahcs4qx)oLso2U?HqxF9euUwe~YdgC) zT!L}7%!5?I*ig)MnxzQ7lFo6fk96}^o=Ar2ubbDpPrb?EwSMFd_fuxB%2WQEhm+^` zopO`@?r;UlhOiy92XGMzZQ&arZJ@S*wt?n|-rJT~U=^ZAAZkER%hJ3BTQK)g2$P+5P^jt++Rng3~QmBnJZnbBvHF^PXc|xEqU*QR#Cl$$d)?eM~eL+{jrx0%%>k`9P z2C3{c?z>X{8}8~>ek|BQHJ_cTz!)2`jtS9FkL;5B$6PhAk7lnzqsWBpqR9B|sJJ*e zk->43P3bwMy42)J6Dv_DAS|a;mmHK75*QE^Yc-Q0CMS1?_0Ho}SJ2#}Zo$dMD_24L zAGCX|J95I$^uf7Jx!FnmO}QB~jVTTg1!W3Kf?FA(b-cvrVTJXYqu4G5e?~b^^w6uq zsaJT_7fCjs#184U9*`@o3Vo}Soa)uxlAb_g|6#Q_O+H&CEq)*wO2#Ha|77poAw4RW zx}@{Iq1rMmM=hcKh20JL%3{z%tTJo zQs$n|+PF#U$DZ(CW4M~fZ7RKSZb%jzXG${l=Z$=S{tt9Yp+A$x&T1d}^6%7lt-BH( zoNp#&1qv{A>2BI#k{V9*X?5W$WiRx>WvpB0szk2lu-=`w68iO+&p-~b^Fr^=kw3EK zfF7A^-PgV=L&S5mzUwWh#IW!b=(C`24rzJ7u6hD4a!2J-s$E;@L$0>6!O`jtUy!H# z#Cqc0j%X5Y%Qxd7&K9P&Hcimu{Uj4K4%Stod(rO}Ov_TqKbQ_tz;uY?q(jim3_nGr zLqH8bVWmKv)aJ7zfyx|fb>6V*eEB#mYi%|PUi@EBiL~jrIq($D&%OzmA?RO(CZ)t1 zwmYEmrINbJR_CxP`MA|LD62lJd1IQzVT(^wFKY34)uK9mM$f9qs+USiak7L=t}3U& z__MrldN*%)e&2jt9XK)mMGkTRMRB#%x#YIFbWY-&f3>Ufa4#3N+7r<`upnc;$W=V6 z+)Ccs`NMF5;0=!%)&vWxl}fd4i3ZiQ(yivL%~d_Cq)^PR8)nFbvv4U;&Ncz{T1N+1 zFw>)>MXMD0uN~_#L<%h1eglQR5Ec5SKoJVFl?kL4S9B*eiyqhV*2K`c2wE4H66s`Y z(Zj;DD)k>USu5WwdtLI!_Tlf*v_9sjR5%!toG6vdNV9pucd>@`eNIj2+Yudy>)Mhk z>^m#)1ni?+^}Zsx(Jr?pNrg-BD&_!b7-49IxhJ z!3n(USc-q#ia#h#*;n~puaw)0qgz_gQ`qAF`d4d;k<<4w4sp=3uTjgYq)Fshx8)9h z4TaOK9F%{w794NGlY+vzw7s(&Wx-W>s23qy0LJCmd3&FBklkW2mv?-xpo`zNv5 zihhdaey2$oc-eRequ+E`Pz5C#|LSO&a3vjenm67mT5e@kMEd~|sMRR?`>gG?=kukd zF)OD%e*nP742!w;JOJ_y+H-Pr%OA1WCTwGD7nd3e&whOc0)yhkd0i-zA2 z+c0$Zwc+(X)IxnbPy_XCi!OwALB;tTD_-8a%q9P9m)nx&T@mh$IrS*Nhr77skL)bN zt}&m0jtn0lIJuc1I3sCM;oC#&2H&UA?Z3xj?L;H`*Q2;g5*PYl*HftWU2fPXJBlvG z#%z-c-@_iFom39ntM@X{mhl*PMC|l+&N@u=UOeI%vm5obTTtg(x@T}JzsWz^<>MF3d$iO+HC8Rj*Fm^@SW~#SwMwa$kHb0xG0{ozrxX`TjsMYO z8rViLWkXD-=}Xamn9I0az&v__&vo=H%u9}KSf#QHC5SfDu_g0sJnOWGq!Q0MT(9I` zG{Fk14=ZE`jXlv=Fx(sRX|2LME?)f`#FQC*=Qpz^MX4Uw(|WUmga9GLpub1@%!TrjiX0Xg8hZT@Luzbe2Uo z;c*r_eCH%g;mDW=&E43Ex^5wVI{SG2j_JDrVGzqxe$G>0pS1?}535nz$O|3HQ9qo6 z28hARB;3Ml(d|cstD*X*jsjP(BI=mDm2q?uyP^Oj+X z%`}Z+w0S1RnWM*>#++@6^_pU*np}^Vk$$5o?JQI59Mf{lHO2Z&u@9SK7nt642{4&3 zxmkI-fTGg{EID1kveN}TbGm?)rwe%DbOEa@yle|MeOFuBi9Mo=%{b`(@#zBAoi5;m z(*=~CE?~1oy8~vpMV7ED;*E=NL@>}AgU#=MjL=2{9GM1B*N5NWK{|SQk%kL4NO(j0 zrC=59V~^LC21z-JJsnRQ=(rL-oOE!gPU?%leWj8~{qX}--bn-SBSW2(hQFEWq;&ip zjb~{1kqsZ2_yND8@pme)jKhx`;bT00%z~h7{FnnDUi_E~A5-z;VfeT)M+q`XRVU5D z?;`d+2ftCe)Jb#kb0vNH@N*S?K8&Bm^tk{(=}cS3m=G!@D5yad1QlseEkR2(i1s|? zWg4`Ppl39wfuNNd6d~vZ4Qe82l?JsEv|5Ak>_(M~HON8GS`DHLMe;fg>PyfE8k9y* zsRm^bv{{328$WLDUsjQ7(QWP8X}!^tr_dxM+oHR?PMs;0)H7Su$jZHVWK7nS%T8x+ zIb*fCy(JgTE3d`P5qNtlN{^;HA6Y?b)XR4x^)iFKarZY2_QpE7?{x}5`ueQxy6Jz9 zFSR6j`W;#Idic+KO~Qd+i}aV*^&A`cweZhO!cG0B4^245hWM>t(S}VxS;mGCqi6K` z@>z~}8<}`Uf1gj!=zn`K?|+*_hJ0&l8x(?X?Jvq7aEP*?`_|r+fBO4TRIDa6K1+Vp zYRUJ6V*WhzJw7@-4PCOdqHbI78rGbne32u6Y|F8Jkz+jyy6^xru8~T5d&9Tb&R~g^@M7!w<&L(@U<>p1A z=UbOm?^c@fT`esTkxTi)rBwL0BYFAcLv;GMlW3JH(42S52T!`>h9p-?9fiWIUl+Hn zZCtLO7qRiv9lpRd1HFGwcPod(=V)g`Kcbr7QV#>=psJMJQps+9C`MaGywRJa+Z%JY z7beb-8-6L8I3sJjX0pS4Iak8~LiWW8dm*OesY}VS9`99jk_yM5&8l|j)m(L<6vDGo z`CxC?=2vLz`ArM?wI%<~*%;->7`f%eJ%jQ)8fkWk42&f_24AAt%%6BQL06}F7XIPY zgcspG?3Qk1_p1rseHw1-s|lCT8CraAF&v(fm%pmvo&%h!VsT(u%}O*s7Xx;^mPlw? z10#O4jYW{jxhuZ@RkDddG$h7+MNMS5NSD{pHal!jC)-%Q3Nj(4Xd14CsFE6s1b;#2 zPge`K!C1uV87(6nXc@V`Ww-pDP5DaRVMj~Dukg!(2Pf>)`6eEhXh7PVc>hZSvH@@) zpf}lSW0Q^4nrsVevX5vM>!TL#gIwe*Pk3j+G8%KARnPK2SNHl22y8-<)LTwzzJ>vL z$!ZOG*(=x!KS{JAVbfj_n~{)RUlH4pkj<;ah9u;HRbopLawi~N>XLNUm`Ak6ypDCE zSH;#O6XsaAeWXtA8>;a2S10#(tA!un=Jl8gsnCXE(mF|6e9VH{Vs5&_ z4T=dQ5!&v%%B@ti)P-uLkOwzEK$$^HV8T`UuJ)?y|F>(EXd9!d#5<_crLZKpsQe## zRk=3t5QA5##*Flj#|-2v$#X$fJZ6^)dSY()ExPw72O$(ULlE0nk)Ht&Kl>}hho7mT z3Pncm3%-XU`6pRl{-%zsu=mrZg;z`Jn8X}%OK#McQg3Vfv7g_hgDw!|OjY2KFR@2uIZY5uE(`*F_rTy;NPOTM4G zAQ_*RB50r%tnl~IZzc=|1vDPVyiV-#1ni+$n0sr{wkWGUH~bo9hneI<_Zzu0VJKft zPZ(&{^8Fy7ac%qiD-kP8H$_jErDPKIzE2WS??+6Tr58pY+4_lgjiWccr>V_%C4;Kq?XZ~r0b`8zaceM@$aDtERz0wVlMhoQ)`@9 zrh-#wmG8R%KCm@?gIw~dF1|m(-`PYht*8iAlwy!u^85z>M>q%kH$u9Bg?pgU3zG2I z>Qoo$nM!1pp7HGTr3AOrNa0(ELRXYm7rEvn3DhuYLtdRH*epE*HTZ=Miwcz$`~*wE zJy2nzn{ay&<)uq1ML}|krz=m<2jmLNqiiMzSH9ku7gu$V+`>Q%ORa2M!Emtx zGaN#r)Qtnt?f1q-XmU_XS37E~lBX8Gv*FuD-`xW6X{XP?PP|d!fNxjW!T=}KNCnIi zft`4}A`Kx|*a|!?H8_*Ik+xtnxt60>(Rzlhft}r4^5%5BA)O?-YlEPqFQGdr9$2zY zrQaoVtHl3s{QkpOw~|+jx;t8XI%;``s?*iHI_e8j$>-RrKi2S}m!g(WQjWSkhVKx< z&vL7IwIskUjsN&FOzogM%8?}}VzEU3_Tu(z)BmYaq#!D=@kY_aObSk90J{=$14m+o z2`{Hj>zbG$WgGPw<_s%v=pav=(`u!UON8Olm zpv{^sJyY%P4*kGFv;$6I7JO1*;Z92_-mj5Dc#x7EY}Rpu5Z7`tF)l#gLNI>)4wOV~ zTxd9%s5DzNwOv`6V7p3VKo{+=?Qg{2TSA47y|*;~f|=!k27TIPE<=Z&!ueYH7UpXV z(k5KIvtRzSk<=0=eY%04n*%gnmHytzlDHg}cy=i9N*@{)3)AlP@eA(1;+)d3sE9t| zldO5DANA3^o3aPM=kN!nzXr>)^pEt zu{3Te!@E)CeRWc-$9QP;R$R0))nLR&99#6SIALAVz%dOyiSOtjN~vle6PBhBJ%co^ zD}SD617(X4{ANHRnV)ewI-P$3u8rA7Nu;`P@|(0Mc$gLi)Ac39Re`OK(T6KC=OgSa z<>-eG&DA#3VbmYCL?%bj2JN%F(}S(d=|MCVZHUx&&?81pc)Y9m<1{IR+l7%kkD`B< zXGMvrsj$#MIn|z%#DaQB8@$QNu9m%neoOh>9m+0(GKWuI+)3WE#wWBg_AQQJ@hu40UlSt1WE<-1i=g z8;fx;$GakER1XQ!63+joem%Ixvxf$gEjXBL!Xr*8h~BT-MJ5HyEc_ki6E@lwHXUMhAqKPv$qJRCe3oY7i63OtWBS1{kOrSi6-C!MOWw&tjDvWlbxF&mxt?X_! z%!p6n1ylH4OgBpb9>sp2#T%zCwHVi?Lu?^~F|Sr*KdC zU|O-w*EM{Jyeqr85-*n)+kICzR|b5O13Lo64qvCh_g4Rul-I z?$?AWdgx>#k?oL-gI!&OXncGxsF2u|WlCyAgAith0QyDZ%0f^L^IiU4%(M2w$r9$V3!m6 z3Vz`Mgw0ayj01Lyw!4XdgKk)V1;gTVw2-T3#&Lnq0{DruQE4{TFeq^B#;9vEn)|p4 zcH+9-qcpe*YBB!&P|PEF8r;ec1)pIO`JrZ55d7d)4x`+s ztp;#=kM{MTd}zw=*6$0cd3%bJlpU}*8}t=wt?tl4my&0fR#dr^+Z@t{dXI8fH)%tK zOPT3(g`F%7?RA0;!v7rwi+Vu6poBl){z!zwW(|q6H{BL1aJM_?^L@y@`MR9NmQUe{jdC86U9CVRX^oNj@=P(S^!4y7q(% zNZmBT#6f@O$3FvxGx%fqcSOgW#yh|0U(YRV_}MkXt^Di`51#I7*`pun4QjxPYPez; zZ*rh#lxI@zwDH;dKno%z~HL1#7F2NFPH^~1z)x9<^MikDAzH@M_Bt8Z{AUPU3m<~vKh zt+ose<98oa_7N@#^dg8_oi=w+-R=lPaD}+Xp`BWezKcbPfHt?Vjm0~Lzfl4L0J`n zWAt1+@VQDYmXaq*1T}tp)3*9=p#p;z$IDG?j>R>(f z693oeUI_|Y@*XtzXIc9-5EEqFwmA1d|G~`tV%=$!K-eE27zRSSx8MZjYj3ikNLwrT{Bqkgbq19rOFldkcTT6g_77t zB&w7ZQei%-;bC;DQrQ5*`h@Q2_stzX8(Gd#W^Q&Xb)N8G=(?WpCD?oA!zU9x*rR;s zs{Ag=C7*&B{J4cSkZn@Xiu$bbAFMKqYa>=1^t{~%ATY@-xlvuk`_)t_uJC0!;R$Z# zwmQhp9@21W2qU*Ii2RSM<#YF-T2yl(ig368vQeOqYj@NQ!^_0Eu5dD{!c_jQp3N>S zHL44)@Y(FM@}MK7?u>&8o1=c%gc))V`_4V4aY6q??`QkZX+r0}cj!q^_t2M2F+>X5_F_deuE+7g6GlIwu2OM;(C*u6bM!bG9tMt!j}05O zv4OGigTrEEwuOzgd5D;qG%aq~sD!6jaHzCeDSm2U|X1oe%sfNuUAm8o=& zLQ^wb@=wtG&ug?#$7AWw(F7}e)%xj0Du*|vyiCBlw$$mPQe)rt^e*{`)n^Y@_zx6a zWmp_N5I&9r4tFW;6e(8RwUi>orMOevt$1;V;v8PQNYUc%<#2bs1B$zUd_OkNMs_lp znY^>RPcmVMVx-4yXBkjlcbtZjjjK?RaJ?Mh#>xw4)=VP*B-_KoE(H$z2t)0>Q`MougM0PWWPk>_m zx?Di2m#p#~r3-&{q=%QWw+t1f#INR@q_3NvkIs)KZIO2jRT)eo+f$+0QnLjH?`CrF zq_?M(iVX6zw!99=(sexgSGSQp%;kuim$dLsma5Kg9Rd``r!YnOZJMFILTZxTMLR^-xv6d=YYmkvZRtJ8a6( zDY-31e{(JvHN^YvZp-tXDw?F&o0+3OJFFlw&9P@1L94~}cJb}8^q&R!mV)`W_1>aKUOmDYaOOrC4^szzu;#9EKOA$oS=&W-b zMHah5-FgVpDFasjy2@5Ze9ggr@en!A(m=bGs{Hz$+=yEtlt_gC*qp@gYQ?GWL@Js! zKdX`KySsryod6itrT-SIht%Y^Cfd7!RogqOihysIzyF9A44pEG|TemFWm`6!=oVX_-1Dy7~anTpfTOK8UBz2OMhKUf~E zaoTmAc-**>tCvr9)3E>Y*Ql~c1)Lw7+jm90hlh5RHsj0}fPMMR>i5sD%J~z&`Mu$E zH$LZaJpIGfRzSV)@TIYJd_o5Dh?c6!*rx46qrHcazd^K2>x2xU6sy@Ki)vT`k#VWZ zl}tP@$tP1qhHiT;mV{Rlo-Iua2jd&$^Q7XSo6-<@#UGx830GX~z+;!X43zNP0($+= z{Zh+*)B2lGxLbG2y6w}D-kkvq@{@RK*g59BQu~>q%gx9_bg!N{Z%V0!lp8L$`a2Wj z$;7*1=-^FjMuFdHw#ye6r(y%E(+1Z2Z3-70&``OwT&J1U)<3&y^h33PdWIbRm`jHs zzGsA^Y4oEVU$kYSy_P|NiEdL^I#iXtv&cH(?+@fk3g?C4Uyoq;a=SemNv=y~PTRkm&UEyJ zzwDT0!Ft|utS39;u_C4w!WSlsD+k&GujCqq3>S(yZb!$3hfzZ;9kq^k6C=(3&7wZo z*PXxB%)IM1dJa%9cVMS3rhQjj@@ZFzzc%P8fq{#^ty11ua7`#uE z|D0_k0$+|22{rUdzpL&a;Q66lAaWz4e70ibXDM{x+e6l=2LIGuijHEjv_%C+)*_0> zVsGy9OEB!(;5r?$ESK@Q^>-r8h4D)6F9fn{n@^)ZM&UIl8wIrY)*7!9r%Z_CbaMXB z%91WipY%Y@bVaehWOnjTeZ50#d2$=G-&0;KU&;1+tWqX(qbO-bF=^5P>SNcCO8QLfT zjkDXKQ~lCx!b%PKLO!ovn=eM@RPHkho!cME)4X~G-;5wWw3)?u_fC^P=Q0~qIKS8~CN%d%wE3;Y?|QtgmRdlVf`VQAS?7-phUTB%H)^U45kI0R>uoHF zMfgIbgFNn58AB=Q-=;rP!SVQBQmWp`nL_rUeu@)3Q;Yj=92k0z5bVh#{Z0nbuaQ;p zrq^wMM|VrP#Chsa7~D1EWqoE5$x>Lo!S)-}GSJD-3eJD>f#eN^Y#@k)9R9V6Q+&$r zc^W0tw#D3*N&|5*r<0joT#v|9Pizkd=dGOjxo?(vq#Y+-YB zo}ru!AuPTIZM|RGKQ(AqH6E-2Ruw);vi2V{kE!NLOQP(T@alOqs$pIU&8s<)Apb@} z%F9Htl4hBr*7{%&a1)innK|^frk3C!oCwdZXUrr#@{@%!X1i3# zOE(@uo~Do+8)}}ZUshqUlfhP<#=~Fr^?p3*xlU!POfp|S>)ZN6qkf=(AIUS8YGW6bN3xz2BhOZ+JxSz^oO2@O@xgjp=q2;x6VK;0fgj2 z_^$tfOygs1EV_|9+6^|&^+D)|z+=;iVhL64PmEbO+BU1te&uWrk76}ama;-@RL8M< z_My^mGqFxw(ZpSnft(y)vq|2tYze{}o1Vk|4thKSDwY}~B;YFl#OK#1#NvWrs8juhGXF>X$ zkNtsqg)doAA|cd=%6CH{^W(_mgO4N{A&wQ(&tFpLR_J{g>%zRIeajcBU1zo{WPzk1 zMnqkU+^6V%wz_azo)E_AdBRhRl4?QDkL0v#DKJUj#aqoR#|8m-#T8~nzr4}5#Ka)( zs+aF-SCG--X^Nr|{$>TbU-PCd&!o}-^pgNb9Mh#cp|2qMX^>;_b~<7%+yOPG)EuZJJQMVsS}4u`QR8s>dyZ$RRO^V!?C_vN*zIu=c&sdxs9L3?!aw-7bu2yKdvxoQA_=UhMJQqaonzt zwpX$2nhEQ`A)0tg3e_$}+?L(r2jNQemJPw75)YQ2b0-F}mmiDNV5)1f>gs|?e``ab zmPDP0U1ec*H`*FR^@*}CQBlT4j(IC{NGdMNcE}368lfL0PIPK2=I6Y#8?xp;q+@zZ zGl876m_yp$`-do;Vb7q7G7lz8S4Ksr7BsNLsA3$ceLAHD=ABUjXM|Vl^8{%OFL1Ee zI4&*fKtW&*xJ3<4TL^KEmzqOEwz}j=@(|&hK&%PbcB!@z8f|?Ha9i`>t;wFv)HN)B z>oiiYtNtK8vuE~o7r2;Cv%(^XKyh42Dtop_ak%)6VFu9WBwpYmRH3FpR9B8vZa0Ku zR8@XrP47MEiLyvv5T@Ud3miBl`EJbK6uIqbW&cDU%t|PIt)Zk_$%7x<2W(Px6lf2{$b+%^hO~pyHlUq{a zQ(G3r_V2j-Y=V$4+{c)8q6}%Q$uv(8ytV;-;zgYJ%bx=juRI+0U2H#(+G(wpCSV7h z;kwb*3!bN5o0`Qil&}htx)QP-g)L_xsAXm9yf@E7_Jv@U5%+lV`5COdL9ucCipbKL zK6|8lRce!Ha50B`&-^Pi*M&TU2GqG(;(*C}A*N(8so_6RLh$8O$4R;wTzp@fNbsn*eXMo%6PKcbduP4l9;Q?g6*CxdV8{(M~2FnphyU5 z2JtH@gMjDPo}r4yfPP^;n_=aP334($q_GDCZ328+4$ZptUbzJh)JT6kbi}U+u{?9m zoPB?iRIQyV6UiEP7!s|$a_YUJR}p>U6c)(H$hFrH%gu?B<-jwFF zm{zO@?X@s#J~N{hHG-Sor8iVHjxpPx&J1JPyHr*VsiSP)nv=!NIft%Kc;`@XVY!Vs|yp!K!TbNf%_Tp~6Wzn}yCFSQ;rAMQ3!6 z#KW2gf7PmO3X7B%;-ob~Gf{q8O}}A$Yv_J|fVBIg%3o9hm4G`wFxZN&lIPpSd~VUwu56ZX1F1FIt}Zot_s{7jY2_N0emjZ8 zIo6MkFEqRM=>75IG0h7bDvw{gL0>Bs>OM&hJ+3+X=GGq@$@yVlc<7zmBBM_B@%VW@ zoj!YhG)2CqbL-PDMf&OU!^-?R$@jGc^cASZ9Cg1hddV|*8tUN;1RT|~UxgL1(66?% z?CoQ-6jNPfJ{XAvuXPno;MhV)E ze^k^@eCIyLR=RK7>&>u-X3YthZL5{hXSAb>hQ3~v?+$vHq<`$&?=%0i-~Y-~m}Y{# z?8IjcfE5mCT&{T2TVDLyEcNwa)2qSJxP)-0;5Q z#N<5T6LfZJJ@QAv$D->Y$p_Xxf8FYSo@%ru{U}TNQ7F!1s=Z=biy5QW=v?wW_`A9! zmFotZzb5#kqGbU|MWM02K#1$%fF%znF=uEH_pkNrJ}O_Z*6>3`UWv=>l;Yl8wp+$~ z$J(%mdo|~Gb2s`v4hGz9jOb4bl`<1@FP|K}KB)0GEg=O^IH&|~%*W-mS0DT>cVfti z=|RdUru$VCLFH5DTv#UR^5}gi6|Ph_qJu%8C?yF#%OuU{Of872{-;u&lJT%(kTJ$B zMw?r?<5!t2@+rqgv)|h&d+&O!nX&=V(QBrSrtCH*jiE@HPWqd6({-iKH8Vbi^MF{`_C+qlAQMXbrq%g#0^ z)S^!e_l}5&e(%JBZPuE3i%;&iSLsQ1i!f!uyJcybAM9JPSsGF*v)fqJEkmv)eV^^8 z;Kdn6y{|DKlE1^bgwk6?Dx{pu9~iucSdIz;$i}B5S)OyK$l&)M^~!0$1W~?MU!&(u z%j^K|_rkw^iQSFhN6160HlufTx3OIZvOf{dMk_4Us*5EM2t0n?=rny1HHpB~#(Y&cK z+4n}u`U7*vN*HtrvPNH^p4YeNagvf+Wz9&PspnpFqh)SzM)i?BNcVCFGrfZcIB~x{ zzvCWYbY^>wz9!v-!NT%ccUjcBie}rg)DfbwbyxcIcKylfc6zF>GZK*_*Q&YCHJc2Cf|!-`LZX;-U)P}_FS zh~k%>YyF-{Xwa*N8|fnPlfoyWC;V$>9m+3@w^RFNxI+HdTd_`Lf-5An+b+Gr$a6XK zMF}wONxEM36VjvWj+#2x)E*&yfgb}=Xsl?S{@u2JBrhqzbN7t)1?aFhf1AU&SliAi zF(HPtZSTfliaM)_s;dE4jY+Iwj4Ntj?>AP1g%=o?BFMJ8SA2z=A*nn4OX@CcVjAC^ zU>o&*6V_r$r=j+3F1o4p7}+g;BPl<935?h;<3l65s-i-Wy3sj%Qs*xe*>e1VEUu_R z{kEU4G{4QPU6)oP&3GwtP30WOA;{j{mx<1f16hzRW@mB^`16U_x#oHpG|(4OqqJiQ zA`(1xlvYjuipwq4JTv(jbowPq7Pp!Dxb(_PeI!ezi&tZIY~s}(D`-8-`2?ywmlXCr zxY?JbTU3|~z_8cf-u8xV%i6smrjS=FHL`k_(Qi?cw~s9OmbXF6(5AR>cd>7O5}T&} zJB^S~a;i+Z1*RvrbyHuFQo{v;GJDqm%HK8SR=fq3tVuzDMapf5oz zW=u{z5sm$E8wm03GG^bf6Qj;X|G0|?-3H#DArODrvZ)H-0bLiZvV#BUV5`i>PsiE$ zheuT=zPDyYx=gyqx8oH$R<$0+1B}?!481iPMpx?@{6rjkUvvlmjX&SM>ZZET3CLyr z9+aZ;S1hJ#E{7_kmD=HB;wa=+z8iLQmRNfE`TJMnZ^4a3+l7t&-xrH9^+oBNH#0x5 zexzZFPQrTUW-)pJ}~L{Gy3~akaXn;%v{|I~!dzHsZ)$cNsO4qO69V^;=(C7Le4gV}^hI``ykDgMrr;Ei zpkibzVx7v~o}-EJrO#UFdZm>V*$&<4CkFarChTSe&(aw-(IvCb1~l3t&Hg*Px>Ck@ zNY*L{Lp_uF{amQ)D^)R0PljoIrC*V%xQy~wIU218Pc+dwP5|$d#Ip5!w;%_9I-=z- z+cV#JAFjMk(;WLMB`#)}fPV7#c_o|L^+t86mMgABE5;0g760H?0UOVOLXnru8QDw0 zmUGBOizb-l(w=Nz(DEu|Ka+=+N!U)JX?gjeH|iGGi8J4_(3d+DFm0Hroxbs9m0Oa~ z%gFh)H<0ru_lUAJCz}*%`$120DejWWBlKaS=+n?VjPsVqA9vxadifApgnm|PC)*eQ zDX&?;$bMqb6QKY zh=+eKt?#~I2phsw;8Ll|{$w&0wnRIg_NygqQ+f4$+l)NfflP?NsK1AXZRnqP?t=)> z0p6GcqntJs@4ep4lS$kHMf5I<_{R6)vkIt}*`K|4Z5h8a9MIfT(ati&SF|K1DvtjC z=>L?lt@N?Bf+1fZmA82FiIDO=NY<7!zAUrIKBb>4`N~8j%(UZ6gdiekQ&aR^oCnuu zJK~E~a^%YUk{W~i^-BFKn{V_MUd!pwu`Sh=I!RXz{6R(5x$B?!i?UU2LCAI7!Gn-h zVEVC$+@!RR_DokoPQ$l(3LvL>9xI{94ujD%%>$Ah6gYEVCv z!Tl`VVTe~RuRCdNz3Qj;(I=q_1NoP!s-IG>YVs#`+G>(){|1mP8QS~nhox7S7Yv=x zNNo%DRU4geT;FE48Vvth#mYAQHlFGIRNMXMSJX{}yWi(&I_hC=g>1`ol1Z*sYqr)O+ojF@^7#5xWbnn)H9Z!- z)%us4c&r!qsm~IEl*mIyc1+&)MB#iTvm%Y(G&JTcw8gNpGxifZRS8lQ3pz8Ol(+J( z^{x$&cGKos%)*(kmH$YzEEasM^2Z$YW|5J7G17;YO{s%Urqlf1Mwg?#aPVT@p43=v zi8p9sg|EFZR}z3sGOF9SrFP`D`9hEPV|g~OC_7#}Uz#uLn$ z(uX7LmxD|N8J~U394)i^8Kvb3dlq4E7g7=1snK?SSM~(%2-Q50iXXJr?fSf{2yu|! zu*dBqP)8Tx z(ZX1Xfv7ihkxCn1PvZzEqdzv$oFcY$xy2HZ@PRxA6vk)2Z0JjG9Bbm}R3ItyyQro4 zWg!__g8z+auM37rh$KX4uMe~Kb;Y)+_`~3})DXe{Bfr4Uh;>ki)dYx>#~tqZ2Q_#kr=?IFXGrlL<1!yDbuh7>eFJd*uV72jT8BS>9Z^ZCn`qFvfC;8KuL89z1 z0gm^ewJz5jvmMCzp}4N;#;ORcDXfcq)%%G_f#7-23p!sXvw!HqUj1So*|QEqRpvPv zmMZcscaG)loiMpS6G_Xu`1z&JU~LTQf309VajtDNxfUWY>JeD`fUn0J=HhFbaaZ$@^e>*R@;?#27u=y%%hxG{_^qHl8s!7k5TE(`G|f_(r*J!hHQlT|FpFmV5$8 ze%|5dz(%9TCy*_OqsxxA1dZAj>M@DP)Rv(aEA}7XF?2cak*YmFVC0fzNHJwsyl&g` zUOD*0Z|((*8XYl$sxKfZVO>pkb9(k*-wYTV4@itBdi!x%)^xS4$92zueh$;YW>D}w z2j1bHQcm5CtPVfnK#QPYaJEQm9o~toXhp0#Cf&kxsGCDU^$XJC2nU%FQqbr9i}g?` zV=ccs?sw+>p{9{_-i_gyLGq<;hma-`Ak#Ty8#5?d*ctL2Bgi3V+5!A8v&Z?FQy&BJ z*Y%habPXSH?yv`6oOv&6et^(n#OET=RHh} z#y1IIwKQQSuaf^Zd|4_<+ZuoxRKb&NwT^@=I*JrjZ4;Emj)Tt21PrQZ=t_INb)SBP zpD-dFry!luj%}5jc@GCmBZ=DZ*4DFyV$z*&`FSsfd9k+C?k!H(AY=~(8jTaObQNZG z{w;qV97~&!u{NHM-D}zK31YdVbHgQ~gZpI=-pXX0+}qF&0Z_gTCq;DpeTH6`Q(1hmfnkocjAMuM(eLgzR-E#eFu6&n$Y5*WX94n^orOfPFkqWm9Qei7n@bSKw^Grz;&Gs{hu*Gdw}2rVfzv zk*EtrmUAgmdFkt$2I-31(B9C$pazYLehqDpo}_=$pF)znT=O4yiONPI z%ZESmO8jJ@E^m#|sC)xV$tsN_DLarYhw>#^CZT8V7$okfvyy%AN@9?xb#~J~PvQ-_ ziH2zFaG@J;qI((7%NDlqeIKSp)9F84y2qyLGsNo6@Gp1uN47F0sm%@KvhG41)7qxA zzAn80y$l(ck74>Af zNetq>S86U3K60X>3SB6af2Hjze~ zxFWvW8;tQ~LT+HX6{hOdW&}xLkOfg^Mlr9CT(mFY8U>+tQ}|-k2}PLzi+?o&eOSiR zCUK3d@PiNUNU%!Wae4f^Pt! zscOJ_`5INUp7mn$I~nHN{zbc$0j`(CFC`o=+;W3BBz`s#Zu@z-q+{=-)kv*-@L4Io4`?i- z!CVvUzbEerb9YfFT^FoWG8^WVba{={ux>1ROdmjH5IrNRUcxm#<3pO+|3F=})0CrR zSrew{3L4K1O%wXANEpX=VnuA)aQW4bKjAVPpzQVa%Qqw>T#SxRLlr^}!tSXXB&T2C z)J~>AcHEUlWk5;9Mw}-S=V#F28gADyGe`F<3zx-IxPc|11-5P1qgK&Ju_y zbDE+J;xqtFzJHHmNFD6h$rhMF`{$Vfp-mCQ-|;qZTgK@S9Vnm*vVCC))Q;Y$f+3v> z;jUbKMre}+b$($EY>G7Qbp?8rfGPd804GGr3I%r%6Ln$W`g%tKa_E9bH4y%>1;>jsYh}|0 z-b8J9$^yOW!2X7B0}XLkT674Eaeam9J;-q%wN?Jr(3TEuNzepe-|0-c@kC1;}U zBsD>vYIASbl`QYc%i2w8by#+W?8*&%2 zGz8r@d#D>uxW20#flsnd&7T3S5ysupz=iufK-|H*K*uY*u5Q}f@f;wWpj)a0&?pat z6L%L=0&gv`zi^>v_Kd+e-)-#=|7$W5pEwC?>}!Z&df@V{7CUN)L4bk33{0W)p(=rh zp@d9R5B>5wAna!YfFoXa%LB+M3Y@ym8kiQfvGfh(6af}{;Yaw#94zaJZfq9^fZ})4 z1rT;E(*6-Q0+d8 zTl`w`$0O{2`8>M)Ut*p4He^0h>TR%Ganx)2P)!)B0%|g%dzEAA&j01ruqf#=Fni}0 z@=vlg8!XOm$8ftIWKV0f0gm|HqUxYi8{A)+Y_H9$ZX*6~{^$SRi+;%b&jY?Jjobe; z)~(Pta%G)PKnQ>FyY09Cp9LKOMF1@PZq02_O*~kPR|_B?zaGXHG?}`%K%t}-NYYIjU91)U48<-$ewO0fKJoc5dIQ(zgVJeVBkKQ zhX9lbx?_pajf=rm%^v|M5gSqHNHtmDkzST?C|67Ypf1Ci zz!LbbAoI}^_t8+}ha+M4YC)!N3Ro-Z%Y`+rul7vlIDR*=EQ63H=!`l7(Vq79BR_)O z0ZU*2VYg!octa6)C4)BbhfIy4h#(ZN+w_duI}codz6T+`dsPw?8#T$RAdzWV07IN2KBc(Js?`uoC1NxP9KW1b=c z-9JRYv~6);Eyip*PUn~J??%-}4{e%7SYg*z-!`m&3HhSZw1YAdpWrLVj0-A^V=pPr z?9;a&p&W~b;!S9Vz<(rnM1A`78l2z~Xq#MQ+#$JgT6yh80~2NPA9Hn2))lQ^&bG|y zD&RL0c#t9XSb_zCJXRbNP7r#YJHN9!`Y!9D4R?hY5^cdcC5YS6qeY_~2cpTP++|Ne zN8)X=+Wh#z!nY)(!c9yc-}Lp@Ac6}5#4QN&u4vaSIuAMo-8)JW9XF~6E-AO~9`(|5 zF|%PFTvLcjAG$l$=u0JlG-1!_2Nw|?*|0kovp^8H!C?vV-K^!>T}(e`6&1YXeBU7z*JUC#5gUIS z{_`3nTkQmzmB3kj!T&(Mb0n^K3*Dph9|@uElk?3*4N|FWPCw^S^xjb*zgJ5#eKut0O#=2;M876pmu-zE*MP4 zwd;5~bW`L`zGN{lh%S|h+HEXm%Vqm57{Pb0Stp0Eyl{JATJ&{mQFA6T{q+dC7`JaMah5yYtDGmoD-%?4({^NevS3E8zq4 zC8GnW@7Zh?^lSt#5gC0KVa_0RB`|lR6NpX`976A7JhB?Vf8GG$-rRQ2XlDd1`d0c` zOF2>I_Pv+D!7OMI&P}Tcr8rw%Qk@&f#Q6)et)wdU1zthjeKqMbPG`?`g}rJ;y9s@p zDtKtT;y;@b;=I16CD)1XOhloshm#2g3o?Ql7RkE_>VBQo`cW2>%dWm3gXS~fi_zGM z=W-4&xy5a$;|KTq&dmWO-H3|qYllGX4!I4yX!igUIS8tl^dNwX~rW)1#{81 zT>|%?8GRcI$-B?CDa?<=Uxk2IB!SbuM@+ZQN^ypy2)65V1_d0ywcY00jaNMsh0b5! zG5UI5q-3n9&UJ`eCh>}e*-PM1gfp*qS6De_oj%nD(&?B=O(vpj^lCnpd^8I_!E^~q;D3)SyI6|e zUkejYZ1BZc$2}$GbQQQpNsVk1Ek6o2PY&I9yQ26WDuN4qE8p?b;3VA&7q{WujA32) z^1JnUX6Vk{ei0rG$&3BG69uVIM6YjpS=lkEXIbIE5jpiV{Oi$E9Is6b7>G~9E&P>NE>I&g(KtG zlZ<|+dgG5Twrn1^kr`L(k@z}T8Ggm)V-&je$#vn4Wiu(`RtTMrqZBp$84r$3Nxi}y z7rxjijJ$j76$)Z>=h*ka_ogGe;kenO`IQvAe>R)2)YfdIj7K-YhQMHWQFyFxsHJZk zQOYX`^Ra2wxhbyQhIO*L7SFz$>1syZtUg>{)BmYEQb%BQC);bgz;`LmM6F+29|_g{ zGU&!NHys(L;y%wd8%XQNt><%3Xy8zKwQfFuWIa={-LCA-Zrm*;KTXXUjIYT(xxqQz zWzzG*nI*_`hvwP@9RnE6M69=56cKQMqK7s#=s)}Z!K}C>OrBO@Cqy0$uTSZ0! z0sW&YZpvCTa0(h z_}Bd26$Z_QK}A3+L}Pu;9RkE%4Pn@k%A#CREm5f%gqYt(Vuc61PZ++HC;1OnkH)x; z7lBmN<5WR9!T42R#s(Mv0~SeDSM3PhVNATYxk_s$g;xCbsZS~Oo8V1(8Xf*#?@H{*9W zHS0oHDS&WZAgkq^<7DV|`yJ*tUOgJwQV3F!)l&v&*8fI6t&MU8Q{GNy!RIz)I%p6I zoI9R~5aMKjI1Er{nBqAOoAZEDCwl`gfEZOpgfvhI^friS8goNb#1`BBdt?=lp&BbN zWTOZE4Wy$F4D8uj(S_{(NPGG09|d>WL)n<)h-=7i2Z6iSHDF|2t8cLPhsJAa$fZhy{03$s2i}~!fP?3Zjwao(7uGKwIzDT^1LIr^Z(IxbN zrOPE@0%_tFo_SL;H(+5EkG&WQ_`EHsYZ(@Z&}PAOgjJsj*Feeq7+ALu)PgIaJ3|c9 zR$ihgrJXFpN{%PQ6rNZYe+W|7sh>tZwaiH<7eE?bj!<^blL3}u@dN@A7xI+)1e*k~ z2fBYVP8KPns?sAdhP)mYD~;r=a3Q;iBQ?iTa0Lz-yfyn4r3$#X@M;~KpEo@b6{VHR7lX4 z?|y_lG_EC1MjNyGjt(ee8e$3}3C5-EYYq~S+q(I1!+z(ki3bo+49pV&{KVTZbEC8e zoNSo`N25cxPkgxkIyEp67d{KHx9n05GDyNkpxFXgn$|n-*g=^LN#j+ ztLTN?mt&a%TaG&D0?UtDwtQ`KDgLyvI#B{cHchevvd<6?21LICs_(>vPl*afqk^nj zfH!m!Z+^{v*z)zMmWKufRkQ*-Wdfy01n?0w8Vp74A&37O5KqLF+(^7=5IIjdfu%O~ zOwiWr^d0zKf_^;Ql1?QIz_A5;je)5`T5;8+K5$3jTosL8UZR|cw~cFR3r;|F%%lP* zL_|xh_IuAdd~>o>bbIGaUfLHGW-@XQ>ji%^J{OFWfCWf&KABRlj7aHVsN^#=Bsb#&8O82;GeL{5~3FQN1}fcKgR zMPJ-1F*d(rC*+}TiPX_{#FdD>Qw6D*J?Emtx~3{!Z=Y;Qa?9jhFakq9cb~-r%1inp zT>pLW#_WZzMZwWbntbB{MjKBW3%lfO(DV5`p}RQ*ZnAF66@@@<0oBaUfjXct(yqfD z*JCL+qkLBiU@5o=Jb^}Mjt@ILv|s)HmQJ|(?_Jm9UmmOd=) z>IVVtxTFl7#jbylcJ*98gy-sWqrR-u9yIvH;X0ro%&dwn0}SoWTKxg+)A0*14hI4u zPihI8m{S^roNlmezo32girOvu%d`w}bW7{Er!KZfX69^w8CQ=Qq8DMmH)X09-eiAa z6%#_ONys=VCk|aQK8(;-={(`&5?DnGD2-0Jh>-hWmYAC zGG_MtOkGYfDzXs#`ScymN3SxH$+9Xk$-w!U8;;iDRt}*P?!X&}fK?BQCd(ue1<;rW zQ5kUh4q*nPI#nRv@ZB&v%^fBYNwpv`!VK^F`mU3h4S+)tLbct~k6fIE-lYL7{j@&@ z_>~;Cwc?qw3f0U|u6)7Y;J!YJ$&PEviAFv>uC8D9=AYhV7&8MHP8kDBmmCv@u27 z!>A&ZH7z|~U6h6YC%|l;MSpYnxM1h#UGA9qDpK}1j)Y+K`#?{t#3P7|+lXK)fCj!Y zv#YNQ(Tln$*h_ef8Wn^9y5YWlKY9hn0Beh(9_xluZYjCqQJbK z^-cV|0fT=SAb-K|hEM4J+62+-8&UesN4Mulc=Clg@Gb1*m92^(flgMa?&O_8+QkJs zY>R~@f$#!QS++q;&Wf&Cr2Jj4u&o+2;s+*5d2IR z=yFU4)$J3+$kuCtR5U{h4WN=+hBrX! z)qEIG^L%uE3V3FkHC^P|Qa}e$^B~%I5(XEy4Yil)cH-Nn`cR{0$Y?9%BEq%M{F@Ka zKbMZSfz7s1z=-!Asjd&i{-!2hro=~w4ETC9?CS1gl0X2@a>q}*DutH1C2WnJcU%vz zeJn^JdMzi}!BAyNAg!G#Nd~q-O94nl ze9YWK_RsIX0!@TgSJR63+;}AO7^!#?Pdx8Ou)C_&viq+`c$hJxNNpwq0&L2^SJ*k? zQUmE^aH-)2zRx8iQ-uQI1;?i4FFro`|HH3w$UewA4A-M7vzz zD*~k>kkIHrY$GldN?RLds?|IH{bP_YiQ&uz1Z;4RP88K%3iKbl8$=v)9US1~frZjs zQbe-^((qyAt<-njcvCUA-lM3%5R(v1Heikur%5E6s4@}kbrnV$yvKRyDHC9{B{q)+ zDy{T?A%yj8k%v>^gy3Y~x9pFYiYK6mXD@yVRPo*T`-M#*{)eIq+i~3|YN1)&CASIz%SVBU0 zX(XJ8e4nE)UiVE46VtTN2pojrO340c?85Fd3!y+a-&ci9&)mh!@MAMM(t-2#bSS`_ zz|Q(d709?U=WyMbKl>rtBM-v4$>Ir=X)FkL3N|{m4Qj2L!(HXq(f$F(iI&#*4BY8| zxN~)0d%xE4b3~@(pqv^(W09&zz-OeHK-Y)dabA;jvaID3W0yw^XTqzqv;de(x#Vt9vV zCz^v;Psun-C+w-agh@=wS*0AEDaAif%9h%0PH8eo@O*f? z6P3Uvmr6Ofz(K+f6L4!q%`@cOYo^5@f-Ov5qkmxP#4^M_I9L(uXo{Zl2kd-~hHa~! zgS&s|zsPG9e5y@#YN7#Hy^eI%p8_H2)UHc@_D=zl+A2i8D$cbtQKke72mUc| z=HN9BxP&eNKJ20Q{jb%hahz&>E7=f0nr(~8hZH+QdJ26xas-2c|$- zzYC;E1W?nt#C{dvaad~dpOjuPk2SXXDK`*oin@Dl+_ zA~2Z%kqCS*&ZFY(c5X&=s>JUS;9rdJJOR|c+{e?5bEr70rH>oa{JI)AdEZF@wZnf7 z0aV!siF3@L3~M{wH%x~``hU;fLC3dpT)pq ziB4ToX99G=OZtQWs;86`=ZypGz)?h}j#>C~5($hwxCRaY?t zP!YZ&fa)pb#d%?WliUn1sW7`FtgB#lN!U{^|L6w_V1sTkfEV50uB-V(r|N1b0irQ* z8v>{XtuD@!``L9>is)2bWpf3-^MfBy=Vt6TfS046U017!?p3^`2?S7O?@9pGQ|gKH zkiHq#nH3d?PF+%70@TGzdN|S1Q%+5kH|H2T@K&b7z_S>DJ*7VZR8MIv&fR0|x~f5R zs;*upfQk@G0M%1|o?x7Bo0pUIRq^Nj0~7qZt1SUoM1Vo+_kRL>h7H1|IrPLKENT4G(TB|sFG{YL_*-`9GGb6s(cTmZ>U zh)%sByh8x>5>kKw>Xedy#~J6{y-ad&F z^5t^^r~?to5ugx8cvhT~d)fthG{!OCK1Tr69P0_7PJNkT056|7$KuI)1BoshHb-*; zsOG4`%8t$Pf;f-sVc#?nM0XsQaDEx>2h>qGy9l6;!kKFTFT&?Mn&{MW#5FepVA*EcSwl1W=EQZUj&-&-KN*me0AO zD{wvn4938J4<}{E0qpc}S$gbZ_xEi?rxpwn8GwNY5I~)S(?pyrh_gBgrY6y;yS)ej z)M8i|1F)U14U?tE&KcHWFb9V@CNhf&pw7V=!2leG4~W{20FzyFQdWF7WA{MgX;7n@j*TdJYulP@i*0zYYfb+B(eOFXARhh%B z{V(D+siSdw2{px)W~lZ3mzAkL5x6%vfb#fYnZ$`(F4Sxaq)D_g^PqB2AY~hIo6#Y| z`eD9KAWc~-Q@z3G4y1e-Z`=xroBA>SO1##nLs-(RO!Yf_iq3>CGD@uGwa>6lUg;UH z8~V2T{nN@+C$3boGS!dNFNj+)af?SygjII+h3M@;I#Zppa>&XYh2>msGQGv^GOQC; zrVa|=*3ZgRC#y6IqD3fBwc}xDf1r{}Cfs$u@0{<8EYZjtyU-p~EDM(t|YWo7;t zf$x7-rrOIfQrwQUFm4s_2JK;K)J}$mR%YL)@cqZi3`OPh;?_Xisz-q)v!zkH7jE^_ znKf}1e$dKPdp4H!ljYOq8P>UDQ!I_zvC!Ab%#6yWR_05ntR`-a#4Q{r@x}WE=;7I| z%oUp8ryEg0=Y#7a{EtjojDnYwWGb|rzmk#yDm0Z8uhrD**kz+oRygmH=?u> zx4#-0x5c5yNrTKXwj0h^p0zUb=Yq@!y^LEQaSO)9j7z-&1l(?AHo$;$t;{@X z{ZHH;e=TmfL+U%*4XgRHKt*}W%6uP-l26=X#Z3jwWNGqNh0Gh@TelP{|Bt<|0dJzp z8lFi)8=x|gKPwtG(N+;Dpe|ZLy1J_fB>`MSQYL9T4zu8b|0uF% zwI~R?V5xvK<)qs8>?6pOBYJ>o^$U_GZSij_xrx*d7tNfwvTY`+~x?wu*_O&S!|X$IH9VAM$Frlol{iAMJeI17>neL>COeMy75f2`|QD6RBfkanr= z`?n;TOzqsdrJCD!^Ynw|+PT%w!_URp(xMorEpjOX9ly*5v)49f-M011IHN)qoaE&lGMPB%!7=QJq0I$-u>K`di;hG)A zDJ;1rc~BdCew214O4GUKu~ZBvBn>_>UNd-oaf-Fm7p1*538Y=Dom*^93fCM<9@Of& zCuz{44Zeyw`0G|qXHE*&Oqr8nZa1T}jdv%n?kkdLwrfKuEm@jYmFR5! z;0SF2vVS&y=5~R!cavyz#lQ=*Qv|}oq`{z;@_v+7IT2q!YrDtKPNDwQsnowHX>hpK zLCueYv{5Kcr~appr%-?U<0;f%or-b^O51)H?g3i$fA@F__3ua;v})D2rIOYgrQLd0 zvfs|nN}+yaRtko@W~GR)H()Tja{@@yslP0VM)xscaVlvAvr@#D9i_QYnoj-8Q!zB9 zQvaWirHHS6Fc_`76Qteupr(7%V=1IP_gD(`pGZadYm|07O4EI#>q??IJVrA(ENO6{ zma==Qxt)9zKN-FQq`js4{_oKgG+UDf7izz8dL?O4_lcbkrQLB#B0MXv#|( zT%)DDHWg)0ly)#5q^;2X`!BysLGwk@;PYC_npBj*-{EK9C{5AQsHtdXCk-ysQr?}4 zG8?5G&P#q@G$<8~A!$%|a6R$c6qI!^7@d}v{J!WfdK%4b=kvOer}dYlzt<0H$O=); z*SE)FMMWcoL4FQ@3PkyYV~S(4qaaVc)-fqhz4C5%$+s`Sh^VXvwp=4(<;njfFc5O8 zBZa_A&~&S#t$FG-q}yGx2mc>cw!O9nTMG`5UQyZ9YCyzAT;q+8w8wng#-U2J(s-iT zqoOiatl+)&lk`k}b?4(WT|`+jsVpb3L~)V|8|Xq&1G zoP~U%e9TQkW!YHZI-2)fI@;jv#SoOT8{XtOc}d1a95-#3u%*likIM7dDH_WVL$*lO z`-gBGFRIJNLHAZvWQP&{n)jiwg=bhr@mlc;8aaQnvpoL;!G8)=%2S7` zmx}VDdY5W%%24m)9izS!{4-(1)}R_4XFS&4;*6d7>J7Wy@*cOeV;H^%^?o8Mu6m`M z0~ZKed_RDSa{hjYuwjqe=(J|~7JUH5bA<%|b->4=IIU(;SyZpuwq|i=gH&r4Ra355 z6G;>KuqcHyY0#>c{6K@?9|R20(T?KC68l+t4^A$6^A=;J?UIE+XMpg}t%)9G5SQsd2wYto2PS zmdAsb+$^!?WQL>4fKqC{PRo-Es$A-0K>nf2wwJAz{Q5klpekQ}4lQ!K?EE&%_a60? zk`K~-B!C=d;hk2cV85t%L&OC4@ig+l$bpyJV=?*AHLlI*m|=7&k#(fF_S<4|ZQNQ~ z^8}6pQ66vtV}!)&^+&eif88A{PCP?Jd4ahkD|RcF+w?lfw?r30bc;$C|U zt-+~UWY=!Ddg+-K2P_5*2#5R;2877(QpQ{OTIW?Ck2)ocI~8b=yn_#;5Y+;kOc{#)`ZdVTr*miI1R&54D1sEcL0e) z?QI25-wLbmfD|>2Hp=-21-~0dN{$2KNL$EJg1=onQg}85F%rNbuw>mGsku;~4 zve~P7E=vexLBHZXi1{{O_GZ!TM$IPq7u!V+Ij|imgv!8jfKnuVv_bIapo>`u3;tfn zWUOf|GYT;vD`DgeEN^X<1FkGD82K{KrM@K_TSb}RU^0uAU^y_qPkxQG=w^Hdac;Y43ZXT_#xOUqb&dliz5xhDP!Jmu9doqR0?$To+UI|JnwE)C_CMQCv-QAqBQz zCs|0w_(C$$h2+N};5`+2cj!d}3*rn+L);ME0tqPLH!EN%cbgRBnVqPf*BNM7Fy7(& z^E2?&7TtV4k+{|Ydu41U2?-$(g^}>sOfu5Fod|vy1xBl2fZ%xFRV^jQxLgBQau#jl z$r!@jiChnC63@T_c|B6YIlsC9I8M*tpnb z3+a~!F3mjUv5nD#Z5WSATB)icJP98<4R8FQeyq(Nk-U-uzoQTumay@3Sx!eFl zWSSgzG3mDm{>vemV@WXh7WAeNcn5Hz8PM4ggZ`B`H#J)fhfxt$b48!R$hy#B5m4E7 zBwC20B-SzTRWnAs;;lop7taukp`CHHg`z!>64LU85|L+Ozj3M~9FttO<7C%qg=%&q z$zO}=l@(^tDNmVe2{d@FcF))iMWy&i$PUpAez3rp3n+M8=_l8;$DBE@BYyG6ij;w4 zwiqzQ2*vnz&j^cZFQ6VtsCW8a#XTb*(!@?O>0i0j#eCzL))=taM#xpGsd%qTy}{}l zbz*)m)Xfa#u4auoU|z5tlPUSO+18LEq?hL^>SlS&RN8<(d5kD*k^GP-l@$wCW1VP} zEluleAwUu;C20*QGB1N7^98_GB+u%2f!S2%vb99j&lRXW&;yg5YBoDk==n13vd}`!))$2H*`9dAy$2otN0j2l+#lvU><&KVNF) z!)2chp({OH7U^iU&WyL(I$DR=Xr8>G9-5v};j-RE@xjcF*2p*Fts6R8mLg0|gw$Mw znRm-lYwZv$v;%wHs^6Lin4ZD%gf?*2sC{8dm20BX9zHFqKAirOU$~%9sT+c^-Qo&_ z-0CXp@gcZlH)1-41Ij{^SaYn4t%dIOMwdE|mm0zSFOxM>6X_xvrTx{ALdmA!%Gpe~ z74LQ^+pTy83B&|{7jhI_Wu5c}kpsG}wEh*2LC9U$(2Frg)(+4HsUQMC1Zr4(z@bo{ zffi4W?Fez-A}+CL?cgU{3#?f3j|6tq#Na`q$lv2E$>MFHQ+yasiC$~8H_WlbO!S7O z$^^P{sN#b36O6R%g8rPXxR(h5EP8TV!m#zOr7e>Xz|R)dZf-TLCTeWiY5Gxo+tV$a zPFATDHnr?Dc)Awhv#2gMNXK}Ou{Ir4*=yS?s+$gd3AsU$zWoxj9cDEsY@Yui7Rw=B zLZE~rj-|#@b7R7WonYMZ1ow#EiUhhsWtCc+|i66E-fjARQzPEwYVLEDkQUbcF?T=MDxhtSny zex9x#a{O%QU{rM)#2~Mg)Rl1duz{eaXD>Wo=Bc+jCc8_*R`6@$y=dyXp{C z@IOh8n>V?XL2hN7#T7W>QtoUc#lJrr)8-6UokQ);!UVE54And3Y5SXc=3|C;j+(h& zD9s=zO2O7JRyAFI=9K&oxBR(V+GEI*8zHn!q7e#ob!8gv3(9R4nEx)Z=BqCG(3OcB zxbXoK2**u4Pr29ZP$rt$W-cmo&4NG5>5JY^$ur&9hv3Fewm>*Q=gHHm;8;kvGN%F^ z3Unw1A+aicCd&^T2^+uPvA#PiO+|UE*%2ONrpCC69Lro4^nRk|gvqVu0OJsuswnvi zardX?gYmI?oI6Mf-5&Ojz?TPFRO8x`UK@gSM&KIQT@-2i5cKHVm{X-j zLs3||0WV`XskIBVvq>8o_ITrF(hy32M^5HB;Np(kA}#DVEhrKVanH4|?f+~HlkLB8 z%u2HNlOR5D0VgtRn6dn2o_Yo2jmo=Ab`#}Wp)NYXky(K9Lg@+O_Z1yiLF67tqW3_8 zzbEKV?}7-1A|>vE$h5wr5>}KOaou=^IaC*<%Ex$iluL(<;KS3KOb;i{oVO9P_z=6y z68vdAu@_nsa{)0WY1m1l3LF-ruE;8qiCG2zrDXrVKB>qu#$xoc?T4N1v7+VC0LB5i z$rA$oNv$H`6rRp~w8A9#y8<>f3^PR88LUNNr`_R;uuC(k&Ojc7E%hDuebM@MQk#%V zuod(YOk$T{+t?+TqQ3+aN)Heko?&Wh6nYUB-3SOf(m1-+H_idog~}CZA(%6o#t$i} z2KjY~59UuRhjbAzie+`J3i7KXmZFuHtIM9#D9TJP3 zX~SD2qdX>;nk%{sidpTDAu&{OzB9*ELt!n|#iBR1cjjRn>EDj^v6>D`QtX1l;}pERY&udN0sKe8gKODwk1)N9ZN6&^>>~clnQeha4d(4sT>-*|yUpuP%C_(XpbP zWV}MvsL6TSX`&1l+bZ31Elki|Qj1e|1@_{s3$f&QFuI?lCT|tYyN=CU@IOxygpq6# z3X{TVbevTdS9k52iC3FhPS(8En>Ka?q3Dm4r_^KiwuOk z4Wil|Yftv#gyj{QRm^z9AlIN1ELg3V)L=Y^UE48+#K2xr&aW5zpOD1g5la3r*^j;3 zA;RlBBK)6xBEpaGEW)=FjW{yIa7m2&t!AyT+MM@O7z3vT*H?X>ZtITmYn_<~mQMhw>yeZf}b5Gt2iCDS`rx+GEXiE0e5t7Nt(1QZ&F{xx7$mmOa)?p>lQ?fEIuzfMz`B!>~~{S>rq94Q=$S zrH}XcXy1Q(~acZz|AYdd_Jav6WeBPcds`C>`8{LC(Z^ zh?HE)YWnivbLMMy=QooqUyrtKo_80m%mNMGuD)&8lQ-1U=xGZQczUh0;7wk8?%9MJ zAyMG=-?NyN@B)`JdhGF|OZ=>{lAJY`;=b`xp8S2|+WqaZrX|2*D#;Mw<@s*tc}6>J zTZ?ZS5t%DITdRu=Qj2SkNc#IYr!p=Rb8Vmp-YwlRAh1^m;P03glsuJ%8D1He1r|~! z_a=wNZP?|IKX(da8>=`IzI8i~z$uJxEP1Lo*%HPcE;)yN!uUfutMPV8@Ry?vl<^`M z8IL8;aI|)1!E!Z(2;Pn%E{l;o{usoFA7Vt#jK>H>#t#m5F$PiC2V&19uOl~O^UT;9 zP}GqKyj{s;(aRmiVAFTzY(Nsv7YT*@kHZRVoDRo^_;(f2Y0y*k4g8gSe<`((75>nV z*B_*nvdzG9RIPAlGjgrqZCqU$4tjMW;)a{Zazmr%DK0QGY*LI$0FY% z@*m?1Znx^Z5vrG53)rSc=#FZ+#Jw>&arecu7>5(}c8A=(3EPI^UTpO|WX%e5(`Z(^l6t|w>{sD2bl5r2laett=2MMkf zaR(>kejLYbrnnyy+$~_}t=44RLvh>|ihGFQ-iEkClW`BnaZgj+!vyzph_kJulX3UP z-S!Q2+g^0r97G+SjQT~K?ODq93&PffxFeErKa1nGQryo7E}s09O#^tm+Vl=kR$w&Y z<>)s?wj|2&7jqvx&+c9NL4~L&ZNOnvoe)@H!W53gO+|fNPi@gt8=_0kri#0Wp4z0R<}vAaHtbte z2m3{rvz@&v@7t#Djo)Lt)nEM#WE*AE&|kjC{{13ykG&2+@c}KT2hXz4Cb7fe+Y#S$ zAI5cCsm#Eu+Z7LyhfR3b7p~v;im!@W|kG0m}oX5ya&wbNGcGW(Ywy!On=q* z?4$UlCcZD$?bmtA7E58rRy{7hQ)lssof_MGagRiag_|_KXa}1KPeS68GM<7BT78=X zMo_oiL@ZRm>EF@6hle1M--)&(Z|Tue6F$Y)^sgg*@!nswy|Mxkp=g>%jvUv=j~gW? zb8E1Oke0W@k%Ir2+)yiG8>=fvmE+MvSXm=f?!A1UII7wE6@E_uY<}658y2>ADA?gj z-?lQ8;LY#Emt*UM%G-A-ckdP|$HGn%CJD6}DSP7=&iL^Rs{_4*3Hjgf*JNL7r%uZK z8V`zudvqyAeM{*Yybbdlyuj~GHQM@%oo>>fo;pE3Br2Ckk)O)POpxkK(1u2J!F8}) zzB^g0h_-)x zO+F7nC7n+fPH;%a+nn-O0M1Jv7+isqZYA9zI6u=VCLeOcR6rLd!y(iC9H`C#zO%eg zgX}oa?p-f^^)DCzCYpn8XWu7G&QouqOMuwS@jj*`>8myf3>SY~`oQE?(sZi8GvGlf zE!FWYyLhMIiV#_PtRjc>9q)brKER7Fl;s8FRgdN@AyhtJvzolJNM}{K%l4h`tid6y z+~ZV-y7=$FtPW{UT2(m^!rZsw0gt>zp%WFhoOa;)N_yu8&>`=pO{JGD1e9?_zzDke zqZ(3m+hrVQ_FRM}@HN0lg~`*aRzltI%~d@@?mj%WrYpJ5id^qiwPiTS7lq4k(8tju zI5Jgzhn@l|II+!tA4n*ofgy5y(?^|sA3|*}ef6VATtO!gIZX}YEdKd^FO zGD^aPlY6=E0?IBaC?P&t$QFAcs|BMpeN@?wy%-ejOnyfwB`v5Ve>k@Lzy$Q2Gg+8b ze)4jI-3q|od zBL2+7^8>i^!yFoUsnsZy-5%4t;t?tf8kPKSg)JJjI~qWHg%%kbqyj?pjvkmLEqg5F zfDl)mVE~UWN!hLuAZ!UmvFrk+!me-0vO@dfTLxm^FL`R;0NJ_7ZwILP;5T=MQgB?E zZ5NdV)N|2SkV`?MTu&y)&+96k1+qt=m%NSmR_hJWq=2F`p-EKN!=P=imLi%%@RPX+ z*qbz+i#x?UabAxZ{pLJ%MJw<54NMjGJO9fZo9resb{x1!kv6x{WR=0^(LW_9M4<3Y zA-H7}mmw-#^qKRW$)DN564A<$-$dGl&rgH*L*TvWlsLC`>@HGpM%aI=Mk6{zR1(fJ zuYfm%N-(m9#dqHlBb z?+HYiT)VOgqac}tUbAwZfqIsVAHC}*l-z%Q{ulmWl`@I5;Ozl78K9ZKT)d6|n8jU7 zpn-fBKZ*RU|FJ~+M}|gjirf;J61gu@7?~bdkOlB-w;DDVgCU0q=-9$+_*BpSS6}w9?eNWS+qizAm$+W% zPG!xTb;aXXj_$W+@Vky*Y?=+DfHa~f6TRpFjpP9xv-JjeDGa!^wCDHXV=}n-<%SC%S^j*j&E5kp(nqg z^Y1L$+J7e6K1)v>ZN5&Tt+i*Yf77^Fe?txT-n|zk+E@4Z{}m7a`T5V!e}4Y=|CBz| zr+bgCqb~lR*5f}v|Fb{YL95RmMq`exrx$EWp4$Va)~#q7bZfIkW7%ipvIyMIFQuD-+`tO?nJA^3AI%xx>ojfb(T zhQOEs>am zAmBYXjp1ifSzWTgCxG{94$Q49?e7b4Iq0zW0DXQ4cs&QtYvI`l^D?ag`((g8yV7}D zwgXRq{D<%dbmo^p|A%zUznjt+_S=IO{SC%8(0(J@bu7&BeZ3DhJwWk)0(rF{uNmY_ z=s|rxAXnf2S`XT{5c>9D-yi6+`IRJ|i}lazAE3{BdQ&}0Z1&&=u+jR$1RnNpeSpqC zjB~93-Cu`408QXG3)+yy#S;UwgF_+C7XY*ZT#=C-91L)}B|Dh)8u}wUmJ0Z_=?l(zAm-)=(Q| zFxZVjGlOXW^8pXnWTqM73gGZ=5LW=7f_@7?0c`gq*!)<2xV zOBn3O;AIS6%wQISy&1fg!7CWNj=`Y-|J7;_M$W?e4uG%hpwoKD;i#X{9vlgJ7Yzbm zes2%%1pWI#`^D@;8@pCNc7%-?fc9db8*>rZ1Mm!E?7>B|Xuq+4 z(wIv#)-P#Hq+>+Ztts@l^S`Ob?J4xQBZVG!(Xq)emQ_#3NdF|-Puf#7?R#lEaMT|B z9@d@+b{z(>{XOW{ANGy)Jghm011InaMC`$%U~@UZXs0n+?1#L(EZ$$J>0fCNJ{#|! zq3M4K)=#{@i0K3ISUno*29Plee7qiF^TuIR_A;b_Soqg6y=>AC@o{dMUN-4(vj@*F z)5|9P?Xa$vT`2n~$X)|FT@LoX3F2(f4G?=yd+_N1wNJGI`#;ky0_$UWy#E<{uu#+g zT)h8zdvJ!Pe^tC6_O2q<{|@vI%B6Ca#>Z8?oIl3G|7yLQqZxD^ znMT2yTL&>{qR$&320w+qbx=n%e*^0p#@0bzYzDiw#@k>^Zar&*{hH(br|rQX;_Zzf zC*B757W}~+g>uit?d_-b9*Xvkf~-#Zvwnhnw2t+|T3QAD!`9O^Z@u0gw6pft*Fmnp zTH_qeeJ#sq?(33HpIh1U{!8ieS@!(ZF#6oap2u70b31!>L2kVt;J_=hgM|Rc*|USw z0e(F+JNOXNUkCeJ72EF^e44?f4BD$OCuddRK0gcQ=EqzMxp;Xg%gwMi1yi(_oP>G7 z{^7@5x7;3dfUhDD|38Agu%0l$`V0c!w0EFh!Dp~X9Xy-bXwJL`*1r#8eLd8x23Wtw zcc>24yX?VzciV##aedXnUJ2_f0PT~*Dev!Ly`O(J!RLF3f$B#RH0yw7Fwpo8LO;Zf zzm)b@uZ8_Z(|%ghR$2SxS}FtMZD@e4MTnoDpl{hRuxksA6Bn$%D=|Ky_B##FCpn5^ zz&!?I8|D!iO2?K#oDcsA&nD15ZV#Sd{GNmPpKsUO<8F*6i1E6KP-m}6>?4PP=M)?( zrelN;%Qd9mtLbOChV(Dc^s`(;`WI^YS*{`dkJ5hJzfbnU_yg#pbU4R$_8en2dJ**E z0k;~~Pad=X8nD07NNrF(AAF(dHz?H47)OzZF#f51s{fVnQ)Df!1J-{o;WO-Si}#;T z_z(NrE{;!?d$ooi_RUO0*39Is2Hts z$Mka+oy-<*>ib7Sy+0}07tE)m|EUXoO8QGK^yws)pOSs5ox5!fjiomO|95NS`?ZO6 zcL4L})ezSQSR3Xz?f|XPFm_O$w#~y>8rWd=pP>%;FgutDx#t#BcCa77*VD3t16WQP z$lwG9Co;HzK|h1n0W@;iqz1#99MAsoy8wg(0bUNdjsEh>FW(<<|K|O{5C(5%(8-|0 zpxO!S33c`STzdY!$3fwXPzyL0Q=HyVC*?vO<^Ra;DEd>JAyzsz2-+tgcF*;r<6QsF zdAcbJ&2+c?t}-7eK=&^c-Cbe0V=SfAH*_GOIVmo8O(DO{YO^@~fG^ z=OKEY*gYL${Xy8%3n|{ceSx+H+88Ft5ovH5WL(k(F zuT};JGl=K$DSha9e12bg9`|;q=kZGh(DS&dKRb^P`sFj|;t~qqUP583#NyIV;Uos{ zVQ?nEi(y_FupTWEy^EO#ab$!%Ze(Xe3FbQpp1F(YJx{!ib6wPp!hC=|nceR1M&rp3 z^EYVDocC+ar6}h|;M?mU9lHs}ESh#NwDlVLJO-Z4Ft2VfR}17GALP&5fUl_Gi~I_v zQ~n;{KXe9--*jkq!?<}Z!OP^Mbx8b~_tE*{{n4?QehzN~y?Lv?Pl0$azeM?>j2j{D zFVg7V`-5MWhjZy{9&!7mO{cua|C{=g`!OG->7mgn>plG()&bwF7xjHh7gIaV{V(>e z1vswiJg;Q=Az@-efdCHp7^7l?-m>Mj zlk49F&Ak{mD|AWnSrVA*cPaKf#QnSx`>cy8PJVBGzTm~_xqR|s$fT!$PUTpA$t?a! zzIi+P=zP)lzt8^;{O@Oq;01noX#w9NpOgKI+P!pcroVpk4xR&(J^u@AU~!hWrS)$K zWU~anm;D}m_wpjX`!~WLC~q(33oAaMFMQ$DJbhpC7aBk4uUDX-J)kMg&cu=bybC>d z6!4!_`+WcTw7yUlu;v?f=d%Ae2ulmm$M_?l0+ z9useG!3JyQsShuHEh-}KV)5!v_Wke1t3~sSS9N4h7`r~8gF__a`yk7|fc&1!_t&G8 zM*>!c{ZIqNJBjaR$fKoD{(;{YI(dC>Czs8)A^SH)zCp5ovqDVXpN_MQE1&I z`m2A<$M<}eWVGj~fBz-VpJY5=8IbMWD{>36Me1W!v%k+MrfV9b5HIr`xA7Ck<#ngT zcv9SzdHTNC8}-NM7yG<9uSdU&<-L?N9~zJR;bO|?18e_DjQ3nIAKK5$<#e8av70c) zg#lYD7yGQg+sbvYXD`3Er2OTR#K>a%p!wMI;0xeKl55tJE7~^i=4)3mdko5+=5iZ; z!|3m7%;WG;J}0tsFK5m5i#c8_$)ng98ztTzDZtz9MSP25=I(_&mhkf}|NHJgAxHT~ z-ll#jkMZA&@IA=qfV(_^dn?L+wFv)hy2IDc`lb2$p*rb@=pNd__wXh6bJ;JT@((%P zHB0>%NNp$vlHJ|EPrNw+|F0rX`ZMseya2Do;Bx&h*J3^gc=@J?$S0TkH1wW@&VN?k z%g0*{Sc}Ms$&VgxLc0SzmyqR8`f%-cRXF?hLXqEG%FFkj67M;dia9I_XU}2YeJ}EU zFTHc7KD~Q*qMt7JbxD4gstIRbS;WU1#2l7>pVPH1;`iyTi}-!|Tjl&d{gp-hKK=AU zexLrvdHgB&-lpMFl^^>{_0O2!0ni^RMGn;px{$d0z}y}N z&14C`r=v363H)+(IQ!uT`2GwsITOyF84qWtej3h>qK^dK&mSv51E8an3=H z)0p46Z-ujedzRn5tOVaHGsv5-3TMx6L%AJoFkTsK>;B83_euVH2m1e4^c6zi+rUFR z#i5nZiut2>7JG-B)u@PB+1Fxm@F z^7+=`+kpP3(Z?Ix_}v8Eef+z)k64a&lNW@uKZjjTfcFI}IS*4kSU<&>KkXL$fIgYv z^4kyIkJA|>bmoBOg=1V+qZlh9-c?LvKGQnlV?Fu@KX;b$cT@LW#qZJ1d??*5{sHph zN^wuShL598i~D-Wa|PD>wK|cqeRs)qB{t!S1Gzcdiq-Y53Q<2lDUvh`;e^(eFy$?^XD1ARERwQx~Fsn9JxT z$mmCqPb2V~34bNNC6DHB-!heH2C;f44o6Ghr?B=77 z!`T?*dYJCU2N2iL|J_tZ?)}=2Fcy{H!CcT^Dc!LnC#nl^`sZjZ?47w*1;0PU_nlwC z?nRuq@FL6w^7x9dhn-1o+b1#KlC|8P9)bOIfc8eR4Z7C?-Gcq%oeJ#n{RjMaDldol zI~96QvU^(CRvnjtTW;j~U-Q0SC)}F%^6TnS?&B_OH;3JYaZ530wh?96@gtCVM~TE2 zWVi6Qqd$dh%FCN8GQZbO1@T6%%t}a$4mXU2=@TL613Bp(-hrtf!_y%{JsJl z_^mC3dzHUYT8Tc-r}-dP-h7Ymw=3|wa)FO)l5m#?a2q8#+%O9tJ@e$FZ5BRmn1zq6 z67I$ATs~94bxZuUOXZtI`83L72O(G3Nd?x}g^0xr<&qWrz1+$h`1_*W-n$?roV`V~ zeI0FM9vo}ffCNu?aM;8S32u3C#JDd@JWy;2?cy!u>yy_lKy8?O2apZ;9Z;;-S z4TZDOgTl6N;kNC#yjSfA4gn5`3Wjtjoki;aP|jY`3F89lrPcRF-mX2;Fmvs8!-ZT zcrWDMPj3qG-G%QT;~T+u2wx4~W4}OOkk75h_`9j6SMzsMuR8qQ)HlStsW)%n@1}aM z;_s$DcM*R#^~6e?}{eq-4*&-4%%Pu;^#M0bYCy}o0Z218=|L`Qr)r?Ymp}dlGj}(0zN4C_l!>S?1v$=eRE7 z4?c6;lix6Z!!`99>`j9GM!=qwU>^wBQxc5c1^xUr{(k0h0jIaMw|0qfk8?R6LHV^a z0``Oi`$)i^lwcnV*i#bhtUs@u4kvhdGh`8C+$WyF_Z?4WC~twCAENT}{0`%=D3>Cq zTYDMbqm%xR!Uk&=%#@d_>-T+moo?r{@#c}E`M{SI(R_Hsp99fULARkoeV@ti`=dgA zf1Ka<*+Ad!+oG>?S%o}%M!tJRnP~r?h_{FQ_WyN6v>B7e`0sG`tA~7ho-)31@!-eT`lZUq$&*%rAs> zy8EgBpSB#LSa6uX13MY!@4#Bi_&cz7w(xggmv83p!1k8&cVGuYh2MeQQ1l%bz5nvw zg3a{~?6c4R&5tt{Nh#40&9MvPtvT>$uUVF96+u(`x$sHdwl%c~UPn}!|0C({W>FME6(zX^ci_TBrW3gHBN+MANuWB*K zuZVzwPbiLL9W(LhxhPuFUt>d|{$=|tL;?B7EG4N$9Mg;>Ok;Q^9;z>Hf7TrGv*wVW zHHZ8x(*KBIW{ilLikhl66Q5L~e1e7AOZHn(K%#w79|zuvD#?gynWB`Y8x^ zv}9_IseJbNJ$zJcC@uS}s@uvCR-05ZVy9CnM238N&ERM!1-mChi6rx!3jSi4k!Zq% zOLE%$_I4fG4eL>{>W1POGv(+>{dO&+X}KnVpy#Mbk%OFDRiflcQ8P6@WNFHX)ZhBZ zh^D0?(X?feCjyW$6CuSUU3Way|M#~?HX%FNBo$@5MT*GC%(_KZ_P%o6YefjznYReZ zxFn;Dd(9i-78zySYu>W%z2?OoKcDaKkN5kp`@ZkjWT_`MJ7SQo^O+Bj~qwe|hi|K2pUc z%H=DDh&vbAsiQC6p$!m~mJPY)QyX`cw|_Y;og^RdRmzKg^hw=Rx*5k?^(Za3?Q@z{ zdcmx1t$k9PQpi!^#*`#d)%J6BuF~|>eBVje8z;Vv)It9-B}}92gp+aWsZtazp(n8Z zQ{xkVo9LI2H$Iq+p`bR`=J4HDX|G4^KGfAjG_^EzeyMBd;$H}?udVBE@A=yKrQK)% zoUGPBx^nxvsMr;S#)>!WAs6#ySf+z4*513`IeP5yKFIrhYXhQ6+$AGkBfz-6S;yKY zVpODXL)=*kIgNWF#xR?#=kGzcIhC3lFH)*SZ&9jeQA(!(k&r%X>Peq%Pygywm+fdM zB4p=OafQw8EBst|ky08NU=5BH(f3Y;XausLH0{6daiFj2l zNbZ~U;;*P;U#@#5x2pYmvopjv`ZxQ_m0$B!-GJ#;WIRi@>9B5mz`LWA`94QLDd(C> z+3we8={5?|$Zo=i_ZBD~|VL7H+@+ll(IkGLbq;!HI3tuzz;8f_=DfnZ>P> z&vO%Bs}5@a1y25r`kps>hCcKtBXCO4dFb0)?knb5S+AztwGK=>`+tO~<5Bl90bV*= zl3_kEftR+60#06gMLc<~9!JSsR(T7k^eDYzCw0~Jy@Id)pPaTbiw69McQI(N}$e5lnwdM;Lvr7CAfF=mlQCupn40T<}fh!CT$^+-uAG z+iAwq@HL(kuI9SM;@u2))DrvuuoM%Fb0!*F>tJt zeM3V#oHa4eKW^l1ep2J7Ji`>a3qxXG$5QKMsyz@{8eoJdUIb2!6y7 zAPsKZjq@+5sEnc|HFaIjwo-X7bDREK8T|>9TiFb02d36N5uM8Mmhp;_4vZKVZ=(xW z32|J@%F`{|z5Rtz39c5BuwvKEm_AS1p)bZ5I2LkukVSA7W8l|k(5Z|ZHxDzz^|(Xt zX&uw~^fQ7|T-@|&Rw|m-$BHUfPlu94&hfq#@wS!Bv#9P0l^nHy?Wyu@_f=R`sVb<( z^mYL0JBjtK9N)oSn&fyf4Bjci=Tt~%5b=-m@-|gMP*v=oUGth`B$CiAK%nH zzGLG)E~s5umfntd;-`$7b}zf|_q|59ws4M1waAM*>&XKKn(xQy9R5i6KXs)@w36)c z^-r9aPBkc*JMq^D{YC;NCqoyQFFZ3(h>y*Y-(V{-`fVAE2s>i(zq z4tA{7U7^xeb9&(V?Y~wLjJH)-mM@?e@NLCcRo{=+!=#w5NgA%X1}m-xnC}S*Mmwt* zd~rFjH}Sse$@9uuXR^d%_7B~ss`*BvAGH*x&omO61n$a**{{`n z*r{=ki026aIWCxM6(F$Z@_zZ3e0XA#|FQkNaZcM67Qz{Fv4uU4U$WQjoM#Vflc%b$ zmTY_|GB5sYlFBnPKiwVklnl%UT(H7C?{_jqL=W=l`_L6UglE~AjI^~4@JcewE z*CL!5EgkN)B7>IqVO=|YwJ>uztMFE3;mEauB=_IE)yS=VUS=uvb!PdZiLt4lWv^Gr zCw%v^zu0$4s0t{R1##l$Ld9S=stuWHNm}Ve_O>2*^It+!B$|?o4>ULWM_%ucqF-s* z(ia>`u3~m-X1+g8e}ADVU-q#5^2hf-uDsJ-3H+NbJ@xj3&~kHDLt|8L+EVh(vUs*)VTe>-(P3F`-_7{v?K8Y7&Y6`NR z{B~^hs`#&{d*Ze=gOAhe!m4brw4^yd{WYWhDqcY@Rte5SO}hq+m4hHRye?Gb;9#@v zroT^LT=E8ksMt;08#n6Ve2ks9v!!pCWjLP%&p+{Vn*NmhHJPRU!Tr9UcO9edakPxR zF-k^@KQR3?#s<7*Jm(&gCQ6z=sK10FU!4XAb6a}Nz8!kBH%%=c?~QL8cdhSC**+^s z`Rz!~9vEMztA57K+280stEt?^vhrhgy<_G5&8cax>qW&+WLy)^i`RPDs{4;McJ~a4 zvD4gzzUeQL&ZEXOWbUdvB{*J8Or%??EilN7#9DKQ2`~!1_^0wx&5_%#Onj2MOumZ? zP3&k0abm&hMl6-l`WL^@p{z@z!B2n3Wn_4Ih#{_WTxiPZT6EP{z5E(@A(5+ZR*&J( zr&Tvc$WLl(Ya}Ntg+V$>T%M2VN)qo#K3)9dTkOIYgO^s52s%3zuQ{x4Ehq_JkrvN? zY4)O0ORG_ec9u8tn!9Og_b?*mvVBn5(bX!+l zz+NAl!QNO?Ti0A_J=W%lBnhrH>?&Qd{%*E`;B;+G#cR4XJD30G9q8y;UM|CbJ`}S0 z{_{-F3*ZCK$qRa4Ud+iD3a)F*67T&nU)*^**1L0%{O4^%ca!`=eXjn10K=hviWiz} z43pT*s^Koa{e${g#OE+|R$hOTi$_R%W$1$9K4JS6- zTK&^p+a>jepWXxrW?grlCen^gW{aYZ73VkiwY#(Bn(ceSt;JIBR<>q?JXF$`3ezS@ ze{?K7e@f*U^4xaj^}YK?)5e6)&Vpwy#wlOwO={Tf_C~Aj>60$I|2{>_&jwUe-PPhq9|Nzb_ay~metW6-D)1*s8DS%61XI7d8bQtwde)g zJ<`v$V;4L!RH%gOvT&VnquPfuJZ2Dit~E+5W<>5+K zbg9?gh z&{Q``RC(Z+!SmV&LnlLDt7kVr^^k?HH~b#KJ_fy<(JUXHA?5_Ch+S|#aopBz>9RdEV` zp8GRr68LF=W-V0f8L89FsMR+k5#sp145IJ)y(YKn{R@Y3Pd(9@+_9?>EzF&ous{Ds zJ_ke+;)rJC?S0hqEjFin{FopCMA&E1>gx$gBMQ`)=E_994XI*?C zrz@zJydT=t79Vwya@kEyK8Dk6ulKAw4jV2vlOT+oNq{ngnM$9nN)vw4(WFU^`A~f_ z{>E1~m)&9Pime5~7dvH_(;kmz0n#nfLqw){NG7*x1i|OK*ukuz2d(B9Hi(@dLNja? zH>V2S!Z4n8HvxFSQY0(8^y|k6`1R+Y+2(GiQ#@y}kPR#0;UZ6jfz#3T> z$=8(0lnGvcKq2m71F#v`qePwrn^T%3Nl|MGYgwy@twUlMvU=m)7^v6s1;|ebl?ua= zQ!MwilFvEmv9G-v)rhUF69iu@pv2xY zT0jn>Y$Y|4f)XqZ#1FBnM?&#YZ*Tt$dn1TV{LloMg>eTq2?H&&yqVU4gN z`==_VHFnjoBuW5Q278J`FuG~ER{tEUw15d9@3?dl)=hXGOb00=dCq`q*n)bev|>GG{MPGopzQZi0bP0?XN& z)h1B05c$C`h$ITH&d%LmbF8+KOjgz(Q)H~sJ|r3)#;2RP=>{8 zvXgUsx2R;3SHSaD73DP6Ql0O2{$75QMqIWpx^j{5p)5^{6?$Hwo&hHI5;`5H#!YDH zm7#}7lTPh)&~a*03r&c?kM-WlN<`i23dySnVyI}I1fB}%dF~#mgRA>o?2QaG z1wwI*Ea~z-lz#EhXc(44iFv>Go{8sDrU6)V2OlMeVJUktX*K@fdd8fu@i0}osQMTy zdbTyk^Q3KNZPRNae#xB)^uFgdH5MwwYRSN z*B?wn1Kv{aeWTL*0+J3%I{5-rn%yidS&Jc;O?#)(3Y~R7n2Dr8m|fu~D|{E`qm{3s z`gJYJp7n4=o0XJ_SwFs6D z<+Hiz)|kakRL#`A1!_5~q04@}+pJN&cbJGs+;{Kl;i4SIQCCH40Zg$@fZB#^of~$~ zk2MqFA16kE_1P!qg>$G6en@fWL8Zd4Byu4SUkEccqe zan^>Zgr};yQ<1bBfzvQiDdDO<`+CBO3aV8*34=3Yj2)4w_G}Z|w9qTPLlzofh!cms- z;}Ii7fs}#0Am5ZR(pU>h?8)nh0rz zi%ic5{euLS_Q!IkJMh7RUeHLwiIlk}JgLImCZ;6()oK9RM8Z6(ff<{P9@ZFR6+qce z2PMYp3Q@BdFz!v3q9nl|smvqMmA%wDmL4<`cAenONrqXMOPh!LkSPtl<*fYqq;N(+ zbmK3nyA%(dfL75h&Ay&E*7KI}HS3`;_~)?CDJq;go$u5GM>WP|g09VC0krO1FY7kWg%RV0EffV6#tUj1-#q!pa^7{H30b$cdLCN zCqUbvjwQVG;+s$xPs$_IyD~lb?PjoF+2f|5>x9X7lk|u?n=H=AdyRSjwz0m67Vvmr z5Egioz{*Ls&Z}YBhK(HSk+gI!W#Hi=;gCS=$`2(y#Yx}&&SDeK(`Xh*TD+zh=@ARW zmkA2>4nYes-=m z$GWH9hAC|6zBNK0NZy>KmBk|-pV?x>_OqhJq(cH9i6q%gzNdO~0Knqbc|iv>Zi2pH zFSdn_r(9iTa?%dvI*fS?NZ`4&bgiv*<}m_|l)6EXy3o+++ zd#oM(DS;$b;dD5jmjO5XbDW?xve}Cv-FUPrvT>Z3BZv6gnIjTu0pC89P3NwIHFnM3 zibRf7t1kz@%f`=_*$yw-ea{;(*oZW+Yx0lux`umS$)zID{6+x>t16i!KE1z{EepD7 z=hbR||6o?PjGnj@){yfp=}?KQ@TKr)_xOzx2+cMI7%l@9$Lnrks_rxd|Fhy&S8T{^wj!r*04UxznP<; z>~&{SZt85cI`A=A6U$jq2 z=$DLWpQtd;&hP-|pFesw+K!AR)ZfMBuGkl7% z|EBZvm9zQXl1;GFsrpm-YaN~A@o`U$W*?HI13v%}mow|>5P!h%*F%vY zr|$6e+`;hKq7cjVgG(nx9L>IqjjM60hYtHe=8NO2HgX8Nw4b)Kvt;Mhk18AMuceOI zFxmxp{y>E=-x4SkHT~y-LywPo3cf>0p>S7i_Q8P`x$~BL)BS_+7B}m85d&q8cM>WG z>7Au&g?;Pbpxa}!bNrV34x6{+_R_|VYOqrxLO&&5&zk(Ke(=MkHEvPF=P#sXH}+mF z@L%y(`JR*AP7x_pK!j8A3QLsDtHaRq4lLbY@3@#vA5$K-J!p=oxn5q;aO2~cci6`+ zoxv-ph2`+Ne(3`@JVY)^XU*_$(+cV6LJ5-YcumM{hP~`#1|5Ay8tVF$I-j2aJ$3^U z$!<*NK@nHo$ITtS4B#(KJbQkz9%N8vwc@}F?s9eX-BvR9-?@>>kFi-Oar>_p;A{)E ztN7K5Z?%nq>n0-*dEiTbYhbGd}w%Ll@zt-UtXjf~KkxtYLl!yS6DTKfyWN=b)% zxxEZh=I0&q#*T;!-uYj>|4>Oqrp$WWw1SE8sqke;*8CfgX@PABdv1u1EQ++8k5D&U=3@V`8fNf)|1cKKL-yDP7XeX zDLx(6WNmG!`m|_Ikg!uzpU!9wc_n&`d*f02_|b-Kpojgu``lvW&d^?aL%U{UOLKs^ zYwq1yT+&Wer)PJ!WORGFM^ituU9$#!tt$jS-H44MDa3aoAsgP#2@)Rve(%f zb=Z-OAR1leUwau{B=WVyNvJXvX4jFTU@tikS19vy%hR^^-UrVQpxHv6?@{~@Sap;` z1NYY$!{lzv5v~EJU|=~>PS!gXkkNIna7M?U{D18bhW zz?%S+7&pjq6^GgU;o|CNzm)j#YRQkG%|7$h*H)oe0idfrKTWUaJzrMJYpY%SM@N#? z3%a~q1`d7|9#G!s>CuhPZ{Dq)H~8>Z+3(VWAsIbQnt|V@qLal5{h-}x-Bqq?Mm-+S zB&+EFjhcp#wVh})g9w%@UyI;tYJ9%!4ucyP*0=u%@z_7K?77fVQ8F#>D8s9ku`GwR zB2#Ae&+*PxPNi78ULf|3F3k;D_&!Iye=xbvKSA}qW;RY42qf!ujk+y4ZROa!peL%k z1m?Wx*UJpK98`Nh@Xlq2j|0C_!7e%_zYK5lC7oX@)tym^^s<@O_IW$D7DYVH5;8h^ z`t?5e?yn+i`>3K9WvYdvt9i1dYYmrt*I2TIE1 z{9X#i0gH3nc>N1Ge5t2m?_R`wNSzYa^duUK3bh$3S{-k>{`nULYO#vC5)!sNQ}%WL z;mDexTa~@`y8En@Td6~0K*}w62E7BXU7Y*H#F=ZRL%G$^K^jreJwX~wqt@x|HPp>ESvMD~1 z6#OjVlX6qJ?X!_)+C{~``Vkv*we1Fnon3wlr}%QG(Q0%quB+8=rtza|=Y}nFe`$5T z(87eTPhdlaWjU`NMMPMK`kVUtwGi74+Q7BSgwueUal)%PXZD?B@n`fqj1h)&U0t75 z9lvHP#sAn8O(av>t=6@yVdhJW!@RsJc=p@SxQ)S1aIU(+!%3J4l9txN?aGUN0+%c|s z+Z!J*Ivg@Sy|c5E5EgRf57XFt?4^O|pl575kMAnTXNjrn%t{}*p8siN)NznJp3X3C zf5D|X_4>V|P)^RtS2Hs2X8iwc@WZyOh7@!+HD^DSE_Xz%?R2DYW@o*#3B~1=Q8%~}Wsu~`5 za;gfu+=3sS=R%4^a_xLUncp{M3tX#IcqRUiyYsjW_E_r4`G!wi{ zegZ$S2^(!z0f$}tC85MM{(Wm_euKNQu7bn#;ndDMSrZi3LF8bg=muSq#s|o#F%R&b zti}ws`J2eq%YWX?v(z1K7~^%qSYDPQj=&#c=ZykR+wvDpniz~?v$1L6r=q=vx^$UOMa7u+r^v~1aa_^(ynzkW_-q(kHxyw0aIH5$ z?V4x8q#*iJ3rSD0mFB_Sr)3v&v`9W zhvZ%zPQ1UKknTIA1n+KIKCrh#%q#>wv8?;6GHx7n+M|DsOJ$~^%&)Cl3wNOWP9$Z~ zlYS(3%J+LE!Fr{)2}$0i|eku3V^>v zQp{9BgPT4U{-6`HaU68kE=vl;3dB1wm(w3x=$BxQ^m!l#q|yAKos!rWq`5c%Jy}Z$ zjZ?680URC7O`6=3h%zBudFr{nw&y9?%&SgthFh9WEm`2QXaX zGb^|AWdMHc6v+Ym@vxCXSPM%dFT!3m29oF$2{@-UO=CocbRXFrhsi-NkQ{j`<304> z-_C4teRFUlV^yzVz4JcVd~hrbCzQSBT1A#v#wkK>k>qn)9FC<@p)W~NDhMkwI+a$r zI~Hc&$Pm@zQC|7zQ=5K`QvftG8shX|SJx9c;(A0^-{D6DMfR~6=QcQkOxpU&aQ8SX4O32{``A~cE&_I?o zRn3dSk3j5>n&D!3i8lE_SF*-3poUz%46r0SrGuqMl05`Jw0HU6JyiBtomu#F+GL{|c{EqMssnWy}J_I8vQyGxU5iSQw z7|}%cT3n)@UxNt)%19jfz}w?Pr^m`2F;fGSZERJqiyEgPY37w)`)1l|EC6Kdc zneTCu0r*gwma``?{N>!d$fxV*smqVhFq;KE;f8Ykn(E!k?_ob*LN$ZEd#<|(_`D1K zbALQmwx)aJT36l3KN;m9uQR7hfvAf(x*A<#>bNbXC#~DAxy}HFA>Ja(aZRY z)Q~kPVcK~jf(7#%=xL@8HX{RUd!nHx!@Ap$16>LgIsi8&$K(O+hwLg-F?PqT19)Td zyOAJiYVfk914NVP%?C~0O?gSKazA`LS2qI1^~un^%0;774Z^kcMLBH**=M+ zt)D<>Z%FODv@2^+c}UoDloeH**eL+GeY}3Vad-e$L1rVuE>aEGW&~))%RvvRvCBdK zaUx2HCb0~CM`j|T`DvPKS;7bqV<)gG9s`r1HVhz~j~^|!Uxcu(!G#gJL{=3V7g0)v zYJ%0G>WOG&0@Q4eQ^rmhq)-`AN;DfH4=+tISR4+qTyrTXMSly;_xnq9bOCZvwDVVc zt6N3?ggGf;zPC#dSBAkhb{6bK_!U|2Ys0^9g@&4rM`Al5M~tY0xvp$fP~RHE&X)W4 zFrY94oRc~*Bne1eVLTh!fQV_iN$GKr;T^#4(G?oAo{-k`94GdO9{9WvVNhZc>!q^j zNYeSH6jy3A0+*-G$>Q{L_6Q4-2)<1Lk~x+&4jQ-Og^Zo)jBg*>u1H12Jke#!+@#dW zpAAA=FYf9<)$xgGJ{!mHqB-Edf8pB&4FtgcJT+|aiSOev^if~!5k-gd-w|%#HO_;( z3=9%h{h2bi_hhiM<0|tj!~&!r9flbU3OfxQlLw0})vyIk^o@7YXVFvHh{C)*f~3w_ z9{+#Dm^g0%sxsjKxfchBLrGwRmLWV^JDSO#ciU4UKb4L9tQ~_&pWi=T@3;vgam25L z1Te2^;e^+_nMzE@Z{NUFY|da$PXHr$h0y~>qS(E;J!j)N3Txa7u}URauV+36j>?TY zk_IafYT|%jFe@qXg;3;*6azwvWU|F0K;JyZ;#(#{vm5cH`UkmwzzT+FzuJ5CUmc}}k z52S37jr!CWQK9xeLAV?2S1#CabIzm#E2^pZS&BwsT zKN9+xs3Tq77_tynH*SWWY9X8@#YDa5kcIB0KGi%u*_d8%8~>`mrOg;K8)k9%`P4J! zH>C`@$pHH?x8mB2I0qIX+>**t8$9Ic(r;72cJx#;;5qadwWcjod)!V#+Tbrf#pZAO z1px%(J)%F>iK|at(l(+khxjYBp8OuQIhzElksw)|qOZ;glRBU#44DUAi3DJrM>kjO zKu=e{RC8gNXs|!d`OJ2aKkPoxcac5j@}L~>svP{#n0DhqGaMZpT|^b(Az_R328U9M zjG2_zm^eJM+eZYVbp1>5+UeY$UmQLUr=VmRK!`m;C?W1dABAx&1M0~m%TdzQTWd3d zfOt~vNRT{4l!#M4)3e6|XnTknafT0?vYR`AF(wO)z~rf&1GI<7djqs&QehtAKDllH z@gxp|7C`LMbpkDqV+Monkf%qW4&=50d;?i+0GdQH9ids1tp{L@>c@N5cYt4c@3&U4P6ehrWzBYcxi8T%|_$KP5;v2%O=%Hy3vE6>-M$-7j?JwQ`I|max)c=pws# z;U@j^kv#QJb0qbs`LGl!0B|o|fa{L$z{GGln;M`FVvW5W$m@03{Ca5PBmV4nMYN8LeKI5|9 z>jT&fBsFzaFt2Dw(vZu+dUy*fZLcnULGTvOQ#z>7sh~3I)t;JycIPmdM}Q`QowX#L z*E+OpgaxX3yJAz~pd8{eX7il7Kt}Qff+ZW^9%wimst=agq#TByKKFkMZdp9@5d?!> z@Yj@4zo0>cW-5viwQFgky$(s{%-OqMgcn-Io#}rFn^xmdiPv+mG~qY0S>K-}b2K8A z5Cv=6vv1MM++MZrn7K-3)tWXc^WN4I zJ!^KQg-N1L;x^nEINod==@nBMv6WYg(^|sK5&uJYQ*>~N6COk7_xLv1@;V3%x9iB zq6=9b<{9q*8^^fI*39pfBUs4J>_I18BiX$|0<(IF&4M^tx79!Nh%srUm+A-Agxx^ba1AEs#WmA?w!yUoBKeZzYgRFCdTC>4~J) zV*8_KMP&|->*z0bp%a1twHG7K)f@Llq8UJck0d563=+g$@SX*8IA>?#vpxm2BlOXu zM{4Q4sMAus(-Qg`0wZ4Eajd`YIHDiT@tTpgdc)iwbWkXhjmNvmm(00bqL5sv zw8yC5j~=E33kvdlqilA^r$E$Xwi^J1AF*nmXd)HhFaYhPKb+iidhBqF6Klb!dKcQ2 z!x*X8379x8P}#`v{2DbxfB1`e=>5h+-1)#Lnqy$AKCWQuuv7?ZNr&JeXkaJfJrE~K z*kNQ{BavjVmDNBTSs^!6&PO@MG~jqx5xT+iK?o+W5CQWN<6njf0b^%%&NLzQeeY;_ z)|_t?79?57Abz?H=Y`m=(JpUR52!!_+cxi~l~B;CNtnit-!zR&T}8`Y(R0dyhh{KF zJkw}|pjKu~_-OOqJ7hDYoHwv-GRw0QB1A?!iLs&@5P>XGaHCjuGB*|{&5H77fIm0L zM1Q7VWI)4#2ZcCqCChW9S)kK7ai~)Q9c(sm?j<=+#mBN~$(YVQ<;J8C#WN4@yo zu1W&M5?ryf<(mNntwVS@bLLuCS1$k~TNE^$akv)H@e^^jt_RYiM4a>A$CW_V`;}3g zY?1NeE{nrRVpN!V{0hi8dBif8eEd-lFtU3^e$TZ5yhrYK7!Fw%sj=Am$)rGX+EPE+PFSHaR3SNdZ+H_s-WDO1O0WtzP z$>lS8nWr!+lBjp$i3N#+RnaRQF!D8Yxzy}Ni1@u{tm31;gX;7F>8o1|JDosgtpc3- zGEAmx;HEC3h`^H6F5ktvl*kUd1!7rJG7pXgiBMTc?RF$$EV2`3Nan=O zTHMDIw91dBSTa{wekL7V0&6X`ut8G^+wV*9yfm>sM)+KGL|+Nt;tK*NwkN~{JARy} zH?0-y(SyR!BcglsYZ#ZH^qJdFE)W&?09mA%`1bxti%^E3*|0`v|BmJ*DkUjOT03Mw z%9yN>N@E~u^3u4L5k_Qp-EHdFSzzS4+%6B{>BGG)of<$GlEtEaQxvhFdDGvX=py4# z2wmoiUQwrh=4rehmejeP*txw&32u+=5l)3tN+M~Hv!6;`>iXNGcI5H+90>&b9+m`` z1#>K&veV)SL2L+f(2Mr1F8L+ZI2=9Rf(+_I@fnm52G8t4PcA_qiIzwROA^L-;PTnw z_dps;W$aQWB%i)Xc4#@FH3@%_%(f&YK-FJD2uNB###tjn$leu%ip}StSBT=nk4#BI zeMbUR`Xvl6q=;}XX8Y_#57>gtKvI2s?0}*5&aCf+1joJ<0fT%(bdt9~`8^VSA3&CT zc?rP}S%B!mjX~#^w%PDzApRxaB(xk^u1{0I?G`B}2_{Xxw1l&a5l2V$oPHla0 z!(ELI8DV}`5d9m_-{{FIBN`I!)`N!(0`t|5fnI_tyTqR2p!k&tg1ec%ffUFNI~f;6 zXK)_mfCWL#E)k4DdV+2mZn9`~7iNRZntb3oQ2<%k^_Tb@Y1X|OLhgpfU^_77T;Q9M zQE`Zua}vSg4y8SP4e42?E@Hx zIP4x@b8nAZaZnTPGMxbr=^<7tv-_M@Ico!}fe~uCK%BK*|ITBoU+` zk6y`QgzBJyu=So+=4iKQLsUp~;5f^e?iaA;>gN~a+-T~WlicQ}5%wL%tQhBH#NBwL zk&uAi92k>VgNf ztKrMH51;G457oIpeiryDU}u48vr8dcXbpL?^x2Z5-K+oIuK#yC)g>Q54Gm}#;I5!! zR%{2Yi%t9p2Bkw$aQQR(nMbNo==K>j8EG{~y<nv+uBpp z@#vf|id&3De>b)C>9FtDnexf}RoS{ypJ5TB(Dj_sLc7dp1X4aHENQjWT6s`rW&P1)D&SLrKvk-kp zoGufUopVY#@ZG6tXu`NrAxL6}x`>u!l)+pOa1nkqS9p{{Ib7@R!1Q!Y^2`=$?#0DM zAJL<5LT=hvc#3~*3P0=iL2z!V;y*~}H4?>wfiSaVu&3Iwi1~~&S8Cd01pYq80=LN! zML;HNq=H_?*)jx#G?}MQMe5UDNRszie+|hDsUq37r;My)%wjU2BQapP;-Jy9Zsjj! zBr)9NX_-ib+>%)4>?n<8DP|Zu!wAO+P!V<8|;V@LczW5y@04+2ACdM zg=_*JGK8`&)jC7d#%3c`#P<$)#xWMdl%=w>oUIsvl^)#}$$W+>z8klqg+4mVmhfzg zzgWS8N9i$~T_+(i7BXkj2~x?KtQfJQK?l zZe$Fj6dl{jZb>4h6#K_5&PGXB~Byoutr9N49SstogV+l z_lBwdn-J!17cL|Ur*MZ}O`s!ES)S%;(mTp8`3_{a*JCnR$dP3W&L*6s0TlG^hvW)8 zAYT}Sf5Ug{@-NyDA5LVY+I1BZK+6g$)E2_|oZP$Q@IgdA)rMuMC=Kvt8#4Z|>kGku zun^L^FjETyBFA~egPl=rLz2>Vq~bk!K0bP{TUk*3sK^vAmXB4BEftR_wD#r!LrQ@ZxsW3Q0B5}-~Y&oDcI{c zZd4y+K+{R`%pa?{McVqN36J3ACIry|vIlQLw-)!Z8}>ZGHywyJyKWf_gB)p{FiVwk zCA|K9B|OdxT2}q#a?5e-$E9kDry|6HyQ!#nG^YI1`K-KSFBP{pJCJc}J=fi^i0JnQ zdxC1OLxmI}_ep$ZYOEh@(okD?b9%AD7ndvarY^jsYr zR88<1gBNm%cm9RlZx`4X9H9C+5(ImRu7o7=NY$-U^enfQ9wyIGnzamj}c~EBU z`1zMK)aYqUreYxXw-;&N_fZ=;XYO>x@60ki2;i5IB~~Tgo1UjtW zLbQxu(sKwCf$JKc5p;SMBk5Jt!C<_S@QyQgbICUip{D)sk8rsus9+g$4sAc52T1v@ zSx7pTMa2E;SHg}%(^tDTKQE{DaR}m7$@R+(FJLxZJp{8f2Y$)F>p0*@wC|(A_H$WQ z;5@>!G>3w{c9TJmK{y=rilA5~qvu4N%#o@j@hwRRqJ__-%dXEu5T>Z-Mr`ZL6~qK= z*iUD6}JcFU=?!Sna61v?ALqIIxeHD}$7YU%@v8m&$6e$R2B1B>ev+nSd_p zCGsi&Y<5HRnD$mo4Kib}r#m6@{r|U<=coQDnbiMSZbtuO=^uaQyi`czoM{27F~ zLw=quYkDl zPWAtbp13o8@2#KoCu6F-=38U8r{dH9CAm+!Kl#b=)qi$Pn!g4(T~o(((qH+f#XR5& zWlP{q;(t6&o>%&LQ^h{~>Fl>=@lVaC{$ZL_-|}RB*w^H9?A)Ps+9&P3Kb@agGdca! z+0W^xnD}F*C;Z`fFe9F~!Z#;e>;4nBm4D(U$@_jv_Nem*&PLr9Uj2#Pv(DzEzuM1C zt@}FlyH3gL{ghO(pZp|!HLxqE{T5-*p({P;v8 zb3;{q(zasTItkUk=C*Ya3eo{KAHV)s2*-u{VhgGpf93SO{Znsgx%}n1Z?Q2SC4O#S z_h{Grg8nHhw>*0G1GojfK2do}`Sz4!8g-eS(Tk>(d@uIZT>P?q#^alNQ~v4R-xxk= z+1-Cnet-Xa^1JnnlWA_I#SYY0CdVqyJO>Km3z?^3Ut=^5^-#c+dSg9r4Uw z>p|{o3(*sQf_MGgInUo{=6}tZ^(C(P|DNi6p0DsZf7w3y)H;FU=K12m|Iek}&wo-^ zA8%=Yyl#zgD(jom|BH*K^906h|1Zw;?WunC^4)*Z>fh?rA3d=3^nB-M^0yDEDvMr! zUC%qSzJ|H{AMiNLGymC6|JgqAr~HJU`9ZwF=j-Kv)YNx*KUMeh|AsU67tYNs)NC#N`?q^) z{J!=77o4tan_|Ct=5N>HxTjP0uUh&?wQJ{_SwFYyzx%y!=9gc^>$Jr-S3LX8EqeX- z``)AL)(WRr?cbXh`0xG9m&Y2GzI*t4`%3*6?{D8)XB=B~W9iqW$!~e?yNm4J_V3ih vpYF?c-LLnTb@g~f literal 0 HcmV?d00001 diff --git a/files/board/arpl/p3/addons/r8125/geminilake-4.4.180.tgz b/files/board/arpl/p3/addons/r8125/geminilake-4.4.180.tgz new file mode 100644 index 0000000000000000000000000000000000000000..c55d02bbde8adfb228db69fb88c6e331addfb67a GIT binary patch literal 66402 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

XXfv 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%0DK{%KnkAF?DLmI#)%>4k_>vB=V@= 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 literal 0 HcmV?d00001 diff --git a/files/board/arpl/p3/addons/r8125/manifest.yml b/files/board/arpl/p3/addons/r8125/manifest.yml new file mode 100644 index 00000000..9a7074c3 --- /dev/null +++ b/files/board/arpl/p3/addons/r8125/manifest.yml @@ -0,0 +1,25 @@ +version: 1 +name: r8125 +description: "Driver for RealTek RTL8125 2.5Gigabit PCI-e Ethernet adapter" +available-for: + apollolake-4.4.180: + install-script: &script "install.sh" + modules: true + broadwell-4.4.180: + install-script: *script + modules: true + broadwellnk-4.4.180: + install-script: *script + modules: true + denverton-4.4.180: + install-script: *script + modules: true + geminilake-4.4.180: + install-script: *script + modules: true + v1000-4.4.180: + install-script: *script + modules: true + purley-4.4.180: + install-script: *script + modules: true diff --git a/files/board/arpl/p3/addons/r8125/purley-4.4.180.tgz b/files/board/arpl/p3/addons/r8125/purley-4.4.180.tgz new file mode 100644 index 0000000000000000000000000000000000000000..df342de71f07a5391b12d690d0d835a4784ff93e GIT binary patch literal 66406 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

@TID-L|h7GDXK9Y)tOh~vhGyl1xJ^9%1U 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

S`@UOMw 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
)bb*=u2_S z0!?}t8~&eX7{8KWM40?%p}1@Hjy=yMlHE^=v^FMM0G~UQ zEj~ZmQygDlI?gK{L%~Vn?4Y=gaSLC9X;l9zMdu&eVj>FYcY>~uE6RbHMUL($5*8=m zVyiZ^Xbq0|VL%+H-)xX{R$~sN%?u!xks(qfDB%8`-f%4#AW~l(tvO2iSr2>xe@k&| z6f!9(x{rW6u>{3-{svW4@pi5PrIF4ovoHafo{NNVJq}Wb36O=2ogHVj->qiX%fh-b zy!x8um)b$POg1WS6s3mB+kS2f)u7r6LEcc>vJBLEN*PVpT^fbkI}9+EJ{2xdks-*+ zJezN8paTtiZi4bh3+tl*8|s!=d!`>CLch&)z?40t!$b_2LKd#Xe;4Js^F+P)u9qtS zPlg8V!02LL$bXtaQSJzZUu9?sVcSoeS<(rynx|0 z$B{0e#Xn}Cvf(yeX|q3f_meo(8vgNBmT2TCE|zD@ma@P^*Iwr&;sPli$Wy#RZguiG z1EGmYXo&z4_n71Pl6#rZ`AS^QaYD{MGwB&7N(PpL(b9u{!k{iQtP#fAtVm*+n1O*< zT{;_bV!Mz?%fsySXuR0D!Z?aRR#LKs3@$Uwi1Lyk%2Y}zDeO9W%99f2ka?XLJQsF2 zIc_CfX6_Z~J~6WpD?Lyr2}dwQh)G#Awtv&?fzged0z@beMtB+8d(*A197hLq%52nx z((18zG+`?TrbB%*060Fn+U3q@OXY^ka1F9($q(nl#F5jt%RHGI<3M|9662vdfD7~) z2t2VWy%g1W*jSq2;)*#b#TnkX`R*ZI%>m>&V5mZc@~Wo}ab8g#nje4(Qr+VYQcvSL zlC5D!!+5G=`Pq4%brr`6^kB?ZU{%|UN2dwB7dhJuFKG$ z6W__hJGbN5Kkn?`L6%r0lse3z$^08w^{Vg${TtUL;C^kOZ9hq5-nohzvM9a2T}6#O zc{Ozn0p_@E4=?9ng>$d~1eoRx{VlOkv>>rz_>A5Qpwgkt@?<%YdhM?OI28qR`TFt)Pv~f-nkdoDDN)tnr1~h<-a;43+w)(1N#fA25z9uuU$WS_Ci@-iD=QZF{I2Ik?6d&r z=;(67m-PK4syi?;pEN1{p#P*@yYovDja^9RumyuiJ1}i;+*Z|l^elSwXx}`;u)G~@ zcbHrA1vz>1H8CoU-j}whJy`eH1XN<2Yl6xgk>$it&@KZcy_Y1Y#+-3h6pUSL0-83& z6C&F4ei;y-W!A8fYTdhGr)OpjJq4J<7Xc8J6}>lHZ|ga1Tt<@oZbUm+3S!+gueP7G z9e6ad!roJw1dH(S@9ikRjytl!m5TJU|J#1ftRi{ZZf}U!en^Y^PHU=uYHU~mxH04q zTt9-jETL_bjQHlEQ^c_7W?`bQk2E#49k&Zk+sc0Z! zVaJEq6-If3@dsa^rOQ+_Pz+`KE|e{r+K(H!G87T$cNFpeq-I(wlyjo8OLt{Hp3S#( zWVOwO>jFDvIDEW`n-?s+l{{^`rlrF?NF5)jmqFgi!S?5HG;Gl}1f(`FNhW!(j`x*{ zoGJ0E^n@H(TD8GddYcZj_&@C8-nHfSU^*KMwiUX7-tg9HNc9TxsA^)q7xnkrY7o*f zn`Q>C6WvdWy>TiM*0?($I!*0zpfU1x1wTvhE{z)0YsjfEo`TN7w#0qE^f-Na=f$F0>L;;K?|M7?Op(!Ju3j zD*s_coh;`r0*#`eb-KPsjdzt|3NAAu5Xf4Jj*x*TqgV)HXF;Dk9X}jnIikUN#aM4U z{Q^);Ie{o}WvC;-Zj5^f+&fB=OphHe1OT?gtL{?&|5rY;Jv@czv62vEoXq!0S)R6= zgg{_|h7j6`K$GopBIF6d{RrW@yoefH4aKFjCINs5)V2T<0`03dnIu#-*ZV9-+5^IFuPp)14g{3G>&=O~M(T5rJ10Zijidr_9bEkJVfvc1q)!B_; zv|6Yhg~?OP%=t#wa_Tp8w&4%jpQAchp1ll?30- zr3WkVqmn>@UXu4hdtRU= z2;sKRM>7GfXYgHs!92Yh+H!XBIMC9QA9{>xlSMP5xeg?#MxUTMb^z32N2$8R0ts}5 z304iL-jmAc5kCYyow;|TomH0l&+THOzPM604N8e2S^(x~mw%xpI3S?R28c?CFkjp> zhNYT7c32rEr0MrR$9Fr!Vp_nozd=YhK=$@?n=;y3x_uh$Ece?;GnKnk7-4ojJDQOX z%_lHGiWEiSWL6ZMu1X!wBEyWzDmHss;UL9k@qK1tsC6 zJuL6|CdeQ=_K(az0u-I#9NqKIN4nf#QK_FWYM1CYam0mdu`XU5^w5PgtXMOdz-=Ah z+Pp!$u9`D#S7)<36Jhqy#_Z*kU0uJ5HEtifp0`LHNa%X9?bVxL5!Hejk|OOr&CRAI z54ZjI4w8JLjN=o*GN0gm0zW>wL6RTnV6$GBv>}m}su4Zmrljl@`g5nU9T3v0Y{wJn z2vx1?mmXj3coH8_TDg!+xe#rE)`V$Oe--TqII;`|l(Kic0x$Mnb0OqT?Gj>0@%|xv||^5^tGv zH!Jhc*#R3GZ$)n)FY(`X6lkLTG|w(zGj&fGT~Lud5EzoDb}I$^e|Z zum`QZZt#V9>IIsK4dN)}fKURkN{U!%&F($~_6p-T0(CilmQ)-e3p1p4b|hbBBoBxm z=NzUAcd)u7D5(SWkgR+#A5|+GsKQXW8Tq%-w9PI;@xoFC{i# zClu&F)1@{&H0D%tut-^sC$S9OVPIDW*Puodjk}Mui2v!_Xa_;{R>4FLf^mgd-gc;L zIy7H%bj`wcK>SaleHoJ0{g_cRAg>GD;aTQqz!m5@NrR)DLy?UJ-4G!Yv@zi}F*&O) z3unhVM1+I5QR+1uxG&NWjP0j3En(L(O$VBf z6AhBhieSpCrkuTjwC)L}?kavtb}2zr-I9!abP zkGv0XlyQLK)K?B}tj0>SY%R!^E`;5*@P3nk4|sCAyf#y+ZyIm9q&ryWGCnN~v-}LE z$@F+pPFNVXUZvRdDjnn+S1fvK#H)xX$|ARNdM;9YB9LRlLO6X!;+*k&8;Zec{d;my zQE03X2l%<9QwC|7voN1Iab+~pvNIhsc@Xd*Yex!d)(Ec?_UrkrDlWmoQm|K{_hpkS z@YB$sf*~CX2!(*0UHqDc7E4aW7Z4Mn*?5~O)D`GondELf0{_1bp-ut3bSDM6tSE7P zo`O9pU9Qw?s1=&|p*i*xR8tyh-<8t7i`qw)eJ$N3iFN!T>=$D+VMTE=dL;VTU*)4K z#Wx;hSA=)wt*XWPXw|r8+s3z z((R++aoX{U6H(oG=d8dYUZw%$DRp4a`{QtgZ=z6z;KGT1Tj;Ht!2~Ou6~*Y?be-Vl z-fLyvLppyx7ljryS_>g}#;X(_)lT-jpO#28AHH z3=&>6t&@Sef(gA!Uz6o(YN&jaHs&U0?*0<%YfCj2?%5Bm!|$Y%rC1&m%QWo%0_Vd# zBoa&85dcfG_(qbF1Yt^l!dKJ6(_tz2g7iQkm~?z2J}{Le2o!>r;jiI$({>IaPcU$j z+yi~asU?SDE5lcH{6Ahhw-igSOA_qi?@GtdM{>^x_M!IiM4D4J)3}Fu#AA{D??qr5 zE|aZ1!4JsW`AwIH8ZQJIo~JlcDxUSFK~mV9GyKRbHv0a-@O@ZWmT^0dda#fDnXQqK z#tZA$W7vs&`z+Wa-ndgB&$E4KA7m(bA4zB-gZlG!ALJm~fl?ot{OLTUXYQ9YAY~^r zvV$qFGW>5+RIqoMlr%AX|6h2SL`f0A!C<(5?Uz>JFyG!VG(3~E9VOE}f{Uuey3x-7 zhTesh7rZOk-TG70K+BzMKEHy#0F={7+zC!63sGPOejvh@2JfX-z1#$pIk=|IQIudM zlxML2*DN!3o)fkt7STsIU8)!kKW`39qU>!Z%=a^lF=#(3DMoyov?aO#sdPG3xr^ zZ-}@`hOrQwcaDoN_XNXOhhw0}F~7iU-@VaH0f=$SbGZ70xLs3t8`nvI$Z6frsN+#l zegk{=JESHGKll0|2u$V0qVx9FzGApi40&yi2Jc3cI1djARG3~LWv32C&iL@cWW^FSlz$sl z4W|TF;A7f;A94RVyV#Reqm1{M2xO zBsaI1f@2x1rhFs8shWGeCqnS)WpMI{!f)Ee793rl9!gFnr+^+uh-OlZq zGA^uXiiEx-2p7N@NMHZMMLnUE?#)tsL17rOlq5&`62rgwM8X9bCj}1e8+k{h?RGJv zI(^KtZU9a#JjdZr5}=Y5CArhLtRNU0={ roqipa@Ea=Z@81v|=>Nj5`{&QkpPxTJe}4Y_U;OzWoToK+07wG>rH$^k literal 0 HcmV?d00001 diff --git a/files/board/arpl/p3/addons/r8125/v1000-4.4.180.tgz b/files/board/arpl/p3/addons/r8125/v1000-4.4.180.tgz new file mode 100644 index 0000000000000000000000000000000000000000..1b7963562ee57a89b64a9b9eac8994cabfe0366c GIT binary patch literal 66400 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

b?kw*sg0r?2w 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 literal 0 HcmV?d00001