/*
################################################################################
#
# r8168 is the Linux device driver released for RealTek RTL8168B/8111B,
# RTL8168C/8111C, RTL8168CP/8111CP, RTL8168D/8111D, RTL8168DP/8111DP, and
# RTL8168E/8111E Gigabit Ethernet controllers with PCI-Express interface.
#
# Copyright(c) 2012 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see <http://www.gnu.org/licenses/>.
#
# Author:
# Realtek NIC software team <nicfae@realtek.com>
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
#
################################################################################
*/
/*
* This product is covered by one or more of the following patents:
* US5,307,459, US5,434,872, US5,732,094, US6,570,884, US6,115,776, and US6,327,625.
*/
/*
* This driver is modified from r8169.c in Linux kernel 2.6.18
*/
#include <linux/module.h>
#include <linux/version.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/if_vlan.h>
#include <linux/crc32.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
#define dev_printk(A,B,fmt,args...) printk(A fmt,##args)
#else
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#endif
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include "r8168.h"
#include "r8168_asf.h"
#include "rtl_eeprom.h"
#include "rtltool.h"
static int eee_enable = 0 ;
module_param(eee_enable, int, S_IRUGO);
#ifdef CONFIG_DOWN_SPEED_100
static int config_down_speed_100 = 1;
#else
static int config_down_speed_100 = 0;
#endif
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static const int max_interrupt_work = 20;
/* 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;
#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("RTL8168B/8111B",
CFG_METHOD_1,
(Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_4k),
_R("RTL8168B/8111B",
CFG_METHOD_2,
(Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_4k),
_R("RTL8168B/8111B",
CFG_METHOD_3,
(Reserved2_data << Reserved2_shift) | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_4k),
_R("RTL8168C/8111C",
CFG_METHOD_4, RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST <<
RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_6k),
_R("RTL8168C/8111C",
CFG_METHOD_5,
RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_6k),
_R("RTL8168C/8111C",
CFG_METHOD_6,
RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_6k),
_R("RTL8168CP/8111CP",
CFG_METHOD_7,
RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_6k),
_R("RTL8168CP/8111CP",
CFG_METHOD_8,
RxCfg_128_int_en | RxCfg_fet_multi_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_6k),
_R("RTL8168D/8111D",
CFG_METHOD_9,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168D/8111D",
CFG_METHOD_10,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168DP/8111DP",
CFG_METHOD_11,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168DP/8111DP",
CFG_METHOD_12,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168DP/8111DP",
CFG_METHOD_13,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168E/8111E",
CFG_METHOD_14,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168E/8111E",
CFG_METHOD_15,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168E-VL/8111E-VL",
CFG_METHOD_16,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e0080,
Jumbo_Frame_9k),
_R("RTL8168E-VL/8111E-VL",
CFG_METHOD_17,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168F/8111F",
CFG_METHOD_18,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8168F/8111F",
CFG_METHOD_19,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("RTL8411",
CFG_METHOD_20,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
Jumbo_Frame_9k),
_R("Unknown",
CFG_METHOD_DEFAULT,
RxCfg_128_int_en | (RX_DMA_BURST << RxCfgDMAShift),
0xff7e1880,
RX_BUF_SIZE)
};
#undef _R
#ifndef PCI_VENDOR_ID_DLINK
#define PCI_VENDOR_ID_DLINK 0x1186
#endif
static struct pci_device_id rtl8168_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), },
{ PCI_VENDOR_ID_DLINK, 0x4300, 0x1186, 0x4b10,},
{0,},
};
MODULE_DEVICE_TABLE(pci, rtl8168_pci_tbl);
static int rx_copybreak = 200;
static int use_dac;
static struct {
u32 msg_enable;
} debug = { -1 };
/* media options */
#define MAX_UNITS 8
static int speed[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
static int duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
static int autoneg[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
MODULE_AUTHOR("Realtek and the Linux r8168 crew <netdev@vger.kernel.org>");
MODULE_DESCRIPTION("RealTek RTL-8168 Gigabit Ethernet driver");
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM(autoneg, "1-" __MODULE_STRING(MAX_UNITS) "i");
#else
static int num_speed = 0;
static int num_duplex = 0;
static int num_autoneg = 0;
module_param_array(speed, int, &num_speed, 0);
module_param_array(duplex, int, &num_duplex, 0);
module_param_array(autoneg, int, &num_autoneg, 0);
#endif
MODULE_PARM_DESC(speed, "force phy operation. Deprecated by ethtool (8).");
MODULE_PARM_DESC(duplex, "force phy operation. Deprecated by ethtool (8).");
MODULE_PARM_DESC(autoneg, "force phy operation. Deprecated by ethtool (8).");
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.");
#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");
MODULE_VERSION(RTL8168_VERSION);
static void rtl8168_sleep_rx_enable(struct net_device *dev);
static void rtl8168_dsm(struct net_device *dev, int dev_state);
static void rtl8168_esd_timer(unsigned long __opaque);
static void rtl8168_link_timer(unsigned long __opaque);
static void rtl8168_tx_clear(struct rtl8168_private *tp);
static void rtl8168_rx_clear(struct rtl8168_private *tp);
static int rtl8168_open(struct net_device *dev);
static int rtl8168_start_xmit(struct sk_buff *skb, struct net_device *dev);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance, struct pt_regs
*regs);
#else
static irqreturn_t rtl8168_interrupt(int irq, void *dev_instance);
#endif
static void rtl8168_rx_desc_offset0_init(struct rtl8168_private *, int);
static int rtl8168_init_ring(struct net_device *dev);
static void rtl8168_hw_start(struct net_device *dev);
static int rtl8168_close(struct net_device *dev);
static void rtl8168_set_rx_mode(struct net_device *dev);
static void rtl8168_tx_timeout(struct net_device *dev);
static struct net_device_stats *rtl8168_get_stats(struct net_device *dev);
static int rtl8168_rx_interrupt(struct net_device *, struct rtl8168_private *, void
__iomem *, u32 budget);
static int rtl8168_change_mtu(struct net_device *dev, int new_mtu);
static void rtl8168_down(struct net_device *dev);
static int rtl8168_set_mac_address(struct net_device *dev, void *p);
void rtl8168_rar_set(struct rtl8168_private *tp, uint8_t *addr);
static void rtl8168_tx_desc_init(struct rtl8168_private *tp);
static void rtl8168_rx_desc_init(struct rtl8168_private *tp);
static void rtl8168_nic_reset(struct net_device *dev);
static void rtl8168_phy_power_up (struct net_device *dev);
static void rtl8168_phy_power_down (struct net_device *dev);
static int rtl8168_set_speed(struct net_device *dev, u8 autoneg, u16 speed, u8
duplex);
#ifdef CONFIG_R8168_NAPI
static int rtl8168_poll(napi_ptr napi, napi_budget budget);
#endif
static u16 rtl8168_intr_mask = SYSErr | LinkChg | RxDescUnavail | TxErr | TxOK |
RxErr | RxOK;
static const u16 rtl8168_napi_event =
RxOK | RxDescUnavail | RxFIFOOver | TxOK | TxErr;
#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(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)
void mdio_write(struct rtl8168_private *tp,
u32 RegAddr,
u32 value)
{
void __iomem *ioaddr = tp->mmio_addr;
int i;
if (tp->mcfg==CFG_METHOD_11)
{
RTL_W32(OCPDR, OCPDR_Write |
(RegAddr & OCPDR_Reg_Mask) << OCPDR_GPHY_Reg_shift |
(value & OCPDR_Data_Mask));
RTL_W32(OCPAR, OCPAR_GPHY_Write);
RTL_W32(EPHY_RXER_NUM, 0);
for (i = 0; i < 100; i++)
{
mdelay(1);
if (!(RTL_R32(OCPAR) & OCPAR_Flag))
break;
}
}
else
{
if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13)
RTL_W32(0xD0, RTL_R32(0xD0) & ~0x00020000);
RTL_W32(PHYAR, PHYAR_Write |
(RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift |
(value & PHYAR_Data_Mask));
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed writing to the specified MII register */
if (!(RTL_R32(PHYAR) & PHYAR_Flag))
{
udelay(20);
break;
}
}
if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13)
RTL_W32(0xD0, RTL_R32(0xD0) | 0x00020000);
}
}
u32 mdio_read(struct rtl8168_private *tp,
u32 RegAddr)
{
void __iomem *ioaddr = tp->mmio_addr;
int i, value = -1;
if (tp->mcfg==CFG_METHOD_11)
{
RTL_W32(OCPDR, OCPDR_Read |
(RegAddr & OCPDR_Reg_Mask) << OCPDR_GPHY_Reg_shift);
RTL_W32(OCPAR, OCPAR_GPHY_Write);
RTL_W32(EPHY_RXER_NUM, 0);
for (i = 0; i < 100; i++)
{
mdelay(1);
if (!(RTL_R32(OCPAR) & OCPAR_Flag))
break;
}
mdelay(1);
RTL_W32(OCPAR, OCPAR_GPHY_Read);
RTL_W32(EPHY_RXER_NUM, 0);
for (i = 0; i < 100; i++)
{
mdelay(1);
if (RTL_R32(OCPAR) & OCPAR_Flag)
break;
}
value = (int) (RTL_R32(OCPDR) & OCPDR_Data_Mask);
}
else
{
if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13)
RTL_W32(0xD0, RTL_R32(0xD0) & ~0x00020000);
RTL_W32(PHYAR,
PHYAR_Read | (RegAddr & PHYAR_Reg_Mask) << PHYAR_Reg_shift);
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed retrieving data from the specified MII
register */
if (RTL_R32(PHYAR) & PHYAR_Flag) {
value = (int) (RTL_R32(PHYAR) & PHYAR_Data_Mask);
udelay(20);
break;
}
}
if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13)
RTL_W32(0xD0, RTL_R32(0xD0) | 0x00020000);
}
return value;
}
u32 OCP_read(struct rtl8168_private *tp, u8 mask, u16 Reg)
{
void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W32(OCPAR, ((u32)mask&0xF)<<12 | (Reg&0xFFF));
for (i=0;i<20;i++)
{
udelay(100);
if (RTL_R32(OCPAR) & OCPAR_Flag)
break;
}
return RTL_R32(OCPDR);
}
void OCP_write(struct rtl8168_private *tp, u8 mask, u16 Reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W32(OCPDR, data);
RTL_W32(OCPAR, OCPAR_Flag | ((u32)mask&0xF)<<12 | (Reg&0xFFF));
for (i=0;i<20;i++)
{
udelay(100);
if ( (RTL_R32(OCPAR)&OCPAR_Flag) == 0)
break;
}
}
static void OOB_mutex_lock(struct rtl8168_private *tp)
{
u32 reg;
if (tp->mcfg == CFG_METHOD_13)
reg = 0x04;
else
reg = 0x14;
OCP_write(tp, 0x8, reg, 0x01000000);
while (OCP_read(tp, 0xF, reg) & 0x00FF0000) {
if (OCP_read(tp, 0xF, 0x09C) & 0x000000FF) {
OCP_write(tp, 0x8, reg, 0x00000000);
while (OCP_read(tp, 0xF, 0x09C) & 0x000000FF);
OCP_write(tp, 0x8, reg, 0x01000000);
}
}
}
static void OOB_mutex_unlock(struct rtl8168_private *tp)
{
u32 reg;
if (tp->mcfg == CFG_METHOD_13)
reg = 0x04;
else
reg = 0x14;
OCP_write(tp, 0x1, 0x9C, 0x00000001);
OCP_write(tp, 0x8, reg, 0x00000000);
}
void OOB_notify(struct rtl8168_private *tp, u8 cmd)
{
void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W8(ERIDR, cmd);
RTL_W32(ERIAR, 0x800010E8);
mdelay(2);
for (i = 0; i < 5; i++) {
udelay(100);
if ( !(RTL_R32(ERIAR) & ERIAR_Flag))
break;
}
OCP_write(tp, 0x1, 0x30, 0x00000001);
}
static int rtl8168_check_dash(struct rtl8168_private *tp)
{
u32 reg;
if (tp->mcfg == CFG_METHOD_13)
reg = 0xb8;
else
reg = 0x10;
if (OCP_read(tp, 0xF, reg) & 0x00008000)
return 1;
else
return 0;
}
static void rtl8168_mac_loopback_test(struct rtl8168_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
struct net_device *dev = tp->dev;
struct sk_buff *skb, *rx_skb;
dma_addr_t mapping;
struct TxDesc *txd;
struct RxDesc *rxd;
void *tmpAddr;
u32 len, rx_len, rx_cmd;
u16 type;
u8 pattern;
int i;
if (rtl8168_check_dash(tp))
return;
pattern = 0x5A;
len = 60;
type = htons(ETH_P_IP);
txd = tp->TxDescArray;
rxd = tp->RxDescArray;
rx_skb = tp->Rx_skbuff[0];
RTL_W32(TxConfig, (RTL_R32(TxConfig) & ~0x00060000) | 0x00020000);
do {
skb = dev_alloc_skb(len + RTK_RX_ALIGN);
if (unlikely(!skb))
dev_printk(KERN_NOTICE, &tp->pci_dev->dev, "-ENOMEM;\n");
} while (unlikely(skb == NULL));
skb_reserve(skb, RTK_RX_ALIGN);
memcpy(skb_put(skb, dev->addr_len), dev->dev_addr, dev->addr_len);
memcpy(skb_put(skb, dev->addr_len), dev->dev_addr, dev->addr_len);
memcpy(skb_put(skb, sizeof(type)), &type, sizeof(type));
tmpAddr = skb_put(skb, len - 14);
mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
pci_dma_sync_single_for_cpu(tp->pci_dev, le64_to_cpu(mapping),
len, PCI_DMA_TODEVICE);
txd->addr = cpu_to_le64(mapping);
txd->opts2 = 0;
while (1) {
memset(tmpAddr, pattern++, len - 14);
pci_dma_sync_single_for_device(tp->pci_dev,
le64_to_cpu(mapping),
len, PCI_DMA_TODEVICE);
txd->opts1 = cpu_to_le32(DescOwn | FirstFrag | LastFrag | len);
RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptMyPhys);
smp_wmb();
RTL_W8(TxPoll, NPQ); /* set polling bit */
for (i = 0; i < 50; i++) {
udelay(200);
rx_cmd = le32_to_cpu(rxd->opts1);
if ((rx_cmd & DescOwn) == 0)
break;
}
RTL_W32(RxConfig, RTL_R32(RxConfig) & ~(AcceptErr | AcceptRunt | AcceptBroadcast |
AcceptMulticast | AcceptMyPhys | AcceptAllPhys));
rx_len = rx_cmd & 0x3FFF;
rx_len -= 4;
rxd->opts1 = cpu_to_le32(DescOwn | tp->rx_buf_sz);
pci_dma_sync_single_for_cpu(tp->pci_dev, le64_to_cpu(mapping), len,
PCI_DMA_TODEVICE);
if (rx_len == len) {
pci_dma_sync_single_for_cpu(tp->pci_dev, le64_to_cpu(rxd->addr), tp->rx_buf_sz,
PCI_DMA_FROMDEVICE);
i = memcmp(skb->data, rx_skb->data, rx_len);
pci_dma_sync_single_for_device(tp->pci_dev, le64_to_cpu(rxd->addr),
tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
if (i == 0) {
// dev_printk(KERN_INFO, &tp->pci_dev->dev, "loopback test finished\n",rx_len,len);
break;
}
}
rtl8168_nic_reset(dev);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
}
tp->dirty_tx++;
tp->dirty_rx++;
tp->cur_tx++;
tp->cur_rx++;
pci_unmap_single(tp->pci_dev, le64_to_cpu(mapping),
len, PCI_DMA_TODEVICE);
RTL_W32(TxConfig, RTL_R32(TxConfig) & ~0x00060000);
dev_kfree_skb_any(skb);
RTL_W16(IntrStatus, 0xFFBF);
}
static void rtl8168_driver_start(struct rtl8168_private *tp)
{
int timeout;
u32 reg;
OOB_notify(tp, OOB_CMD_DRIVER_START);
if (tp->mcfg == CFG_METHOD_13)
reg = 0xB8;
else
reg = 0x10;
for (timeout = 0; timeout < 10; timeout++) {
mdelay(10);
if (OCP_read(tp, 0xF, reg) & BIT_11)
break;
}
}
static void rtl8168_driver_stop(struct rtl8168_private *tp)
{
int timeout;
u32 reg;
OOB_notify(tp, OOB_CMD_DRIVER_STOP);
if (tp->mcfg == CFG_METHOD_13)
reg = 0xB8;
else
reg = 0x10;
for (timeout = 0; timeout < 10; timeout++) {
mdelay(10);
if ((OCP_read(tp, 0xF, reg) & BIT_11) == 0)
break;
}
}
void rtl8168_ephy_write(void __iomem *ioaddr, int RegAddr, int value)
{
int i;
RTL_W32(EPHYAR,
EPHYAR_Write |
(RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift |
(value & EPHYAR_Data_Mask));
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed EPHY write */
if (!(RTL_R32(EPHYAR) & EPHYAR_Flag))
break;
}
udelay(20);
}
u16 rtl8168_ephy_read(void __iomem *ioaddr, int RegAddr)
{
int i;
u16 value = 0xffff;
RTL_W32(EPHYAR,
EPHYAR_Read | (RegAddr & EPHYAR_Reg_Mask) << EPHYAR_Reg_shift);
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed EPHY read */
if (RTL_R32(EPHYAR) & EPHYAR_Flag) {
value = (u16) (RTL_R32(EPHYAR) & EPHYAR_Data_Mask);
break;
}
}
udelay(20);
return value;
}
static void
rtl8168_csi_write(struct rtl8168_private *tp,
u32 addr,
u32 value)
{
void __iomem *ioaddr = tp->mmio_addr;
u32 cmd;
int i;
RTL_W32(CSIDR, value);
cmd = CSIAR_Write | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask);
if (tp->mcfg == CFG_METHOD_20)
cmd |= 0x00020000;
RTL_W32(CSIAR, cmd);
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed CSI write */
if (!(RTL_R32(CSIAR) & CSIAR_Flag))
break;
}
udelay(20);
}
static int
rtl8168_csi_read(struct rtl8168_private *tp,
u32 addr)
{
void __iomem *ioaddr = tp->mmio_addr;
u32 cmd;
int i, value = -1;
cmd = CSIAR_Read | CSIAR_ByteEn << CSIAR_ByteEn_shift | (addr & CSIAR_Addr_Mask);
if (tp->mcfg == CFG_METHOD_20)
cmd |= 0x00020000;
RTL_W32(CSIAR, cmd);
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed CSI read */
if (RTL_R32(CSIAR) & CSIAR_Flag) {
value = (int)RTL_R32(CSIDR);
break;
}
}
udelay(20);
return value;
}
u32 rtl8168_eri_read(void __iomem *ioaddr, int addr, int len, int type)
{
int i, val_shift, shift = 0;
u32 value1 = 0, value2 = 0, mask;
if (len > 4 || len <= 0)
return -1;
while (len > 0) {
val_shift = addr % ERIAR_Addr_Align;
addr = addr & ~0x3;
RTL_W32(ERIAR,
ERIAR_Read |
type << ERIAR_Type_shift |
ERIAR_ByteEn << ERIAR_ByteEn_shift |
addr);
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed ERI read */
if (RTL_R32(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(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;
}
}
return value2;
}
int rtl8168_eri_write(void __iomem *ioaddr, int addr, int len, u32 value, int type)
{
int i, val_shift, shift = 0;
u32 value1 = 0, mask;
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 = rtl8168_eri_read(ioaddr, addr, 4, type) & ~mask;
value1 |= ((value << val_shift * 8) >> shift * 8);
RTL_W32(ERIDR, value1);
RTL_W32(ERIAR,
ERIAR_Write |
type << ERIAR_Type_shift |
ERIAR_ByteEn << ERIAR_ByteEn_shift |
addr);
for (i = 0; i < 10; i++) {
udelay(100);
/* Check if the RTL8168 has completed ERI write */
if (!(RTL_R32(ERIAR) & ERIAR_Flag))
break;
}
if (len <= 4 - val_shift)
len = 0;
else {
len -= (4 - val_shift);
shift = 4 - val_shift;
addr += 4;
}
}
return 0;
}
static void
rtl8168_irq_mask_and_ack(void __iomem *ioaddr)
{
RTL_W16(IntrMask, 0x0000);
}
static void
rtl8168_asic_down(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
rtl8168_irq_mask_and_ack(ioaddr);
rtl8168_nic_reset(dev);
}
static void
rtl8168_nic_reset(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W32(RxConfig, RTL_R32(RxConfig) &
~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast |
AcceptMyPhys | AcceptAllPhys));
switch (tp->mcfg) {
case CFG_METHOD_1:
case CFG_METHOD_2:
case CFG_METHOD_3:
break;
case CFG_METHOD_4:
case CFG_METHOD_5:
case CFG_METHOD_6:
case CFG_METHOD_7:
case CFG_METHOD_8:
case CFG_METHOD_9:
case CFG_METHOD_10:
case CFG_METHOD_14:
case CFG_METHOD_15:
RTL_W8(ChipCmd, StopReq | CmdRxEnb | CmdTxEnb);
udelay(100);
break;
case CFG_METHOD_11:
case CFG_METHOD_12:
case CFG_METHOD_13:
while (RTL_R8(TxPoll) & NPQ)
udelay(20);
break;
default:
RTL_W8(ChipCmd, StopReq | CmdRxEnb | CmdTxEnb);
while (!(RTL_R32(TxConfig) & BIT_11)) udelay(100);
break;
}
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
/* Check that the chip has finished the reset. */
for (i = 100; i > 0; i--) {
udelay(100);
if ((RTL_R8(ChipCmd) & CmdReset) == 0)
break;
}
if (tp->mcfg == CFG_METHOD_11)
{
OOB_mutex_lock(tp);
OCP_write(tp, 0x3, 0x10, OCP_read(tp, 0xF, 0x010)&~0x00004000);
OOB_mutex_unlock(tp);
OOB_notify(tp, OOB_CMD_RESET);
for (i=0;i<10;i++)
{
mdelay(10);
if (OCP_read(tp, 0xF, 0x010)&0x00004000)
break;
}
for (i=0;i<5;i++)
{
if ( (OCP_read(tp, 0xF, 0x034) & 0xFFFF) == 0)
break;
}
}
}
static unsigned int
rtl8168_xmii_reset_pending(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
unsigned long flags;
unsigned int retval;
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0000);
retval = mdio_read(tp, MII_BMCR) & BMCR_RESET;
spin_unlock_irqrestore(&tp->phy_lock, flags);
return retval;
}
static unsigned int
rtl8168_xmii_link_ok(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned int retval;
retval = RTL_R8(PHYstatus) & LinkStatus;
return retval;
}
static void
rtl8168_xmii_reset_enable(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
unsigned long flags;
int i, val = 0;
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, MII_BMCR, mdio_read(tp, MII_BMCR) | BMCR_RESET);
spin_unlock_irqrestore(&tp->phy_lock, flags);
for (i = 0; i < 2500; i++) {
spin_lock_irqsave(&tp->phy_lock, flags);
val = mdio_read(tp, MII_BMSR) & BMCR_RESET;
spin_unlock_irqrestore(&tp->phy_lock, flags);
if (!val)
return;
mdelay(1);
}
}
static void
rtl8168dp_10mbps_gphy_para(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
u8 status = RTL_R8(PHYstatus);
unsigned long flags;
spin_lock_irqsave(&tp->phy_lock, flags);
if ((status & LinkStatus) && (status & _10bps)) {
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x10, 0x04EE);
} else {
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x10, 0x01EE);
}
spin_unlock_irqrestore(&tp->phy_lock, flags);
}
void rtl8168_init_ring_indexes(struct rtl8168_private *tp);
static void
rtl8168_check_link_status(struct net_device *dev,
struct rtl8168_private *tp,
void __iomem *ioaddr)
{
unsigned long flags;
if (tp->mcfg == CFG_METHOD_11)
{
rtl8168dp_10mbps_gphy_para(dev);
}
spin_lock_irqsave(&tp->lock, flags);
if (tp->link_ok(dev)) {
if (tp->mcfg == CFG_METHOD_18 || tp->mcfg == CFG_METHOD_19 || tp->mcfg ==
CFG_METHOD_20) {
if (RTL_R8(PHYstatus) & _1000bpsF) {
rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC);
rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
} else {
rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x0000003f, ERIAR_ExGMAC);
}
if (netif_running(dev) && (RTL_R8(ChipCmd) & (CmdRxEnb | CmdTxEnb))==0) {
int timeout;
for (timeout = 0; timeout < 10; timeout++) {
if ((rtl8168_eri_read(ioaddr, 0x1AE, 4, ERIAR_ExGMAC) & BIT_13)==0)
break;
mdelay(1);
}
rtl8168_init_ring_indexes(tp);
RTL_W8(ChipCmd, CmdRxEnb | CmdTxEnb);
}
} else if ((tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) &&
netif_running(dev)) {
u32 eri_data;
if (tp->mcfg == CFG_METHOD_16 && (RTL_R8(PHYstatus) & _10bps))
RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptAllPhys);
else if (tp->mcfg == CFG_METHOD_17) {
if (RTL_R8(PHYstatus) & _1000bpsF) {
rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x00000011, ERIAR_ExGMAC);
rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
} else if (RTL_R8(PHYstatus) & _100bps) {
rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x00000005, ERIAR_ExGMAC);
} else {
rtl8168_eri_write(ioaddr, 0x1bc, 4, 0x0000001f, ERIAR_ExGMAC);
rtl8168_eri_write(ioaddr, 0x1dc, 4, 0x0000003f, ERIAR_ExGMAC);
}
}
eri_data = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC);
eri_data &= ~BIT_0;
rtl8168_eri_write(ioaddr, 0xDC, 1, eri_data, ERIAR_ExGMAC);
eri_data |= BIT_0;
rtl8168_eri_write(ioaddr, 0xDC, 1, eri_data, ERIAR_ExGMAC);
if ((RTL_R8(ChipCmd) & (CmdRxEnb | CmdTxEnb))==0) {
int timeout;
for (timeout = 0; timeout < 10; timeout++) {
if ((rtl8168_eri_read(ioaddr, 0x1AE, 4, ERIAR_ExGMAC) & BIT_13)==0)
break;
mdelay(1);
}
rtl8168_init_ring_indexes(tp);
RTL_W8(ChipCmd, CmdRxEnb | CmdTxEnb);
}
} else if ((tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) && eee_enable
==1){
//Full -Duplex mode
if (RTL_R8(PHYstatus)&FullDup){
mdio_write(tp, 0x1F, 0x0006);
mdio_write(tp, 0x00, 0x5a30);
mdio_write(tp, 0x1F, 0x0000);
}else{
mdio_write(tp, 0x1F, 0x0006);
mdio_write(tp, 0x00, 0x5a00);
mdio_write(tp, 0x1F, 0x0000);
}
}
netif_carrier_on(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);
netif_carrier_off(dev);
}
spin_unlock_irqrestore(&tp->lock, flags);
}
static void
rtl8168_link_option(int idx,
u8 *aut,
u16 *spd,
u8 *dup)
{
unsigned char opt_speed;
unsigned char opt_duplex;
unsigned char opt_autoneg;
opt_speed = ((idx < MAX_UNITS) && (idx >= 0)) ? speed[idx] : 0xff;
opt_duplex = ((idx < MAX_UNITS) && (idx >= 0)) ? duplex[idx] : 0xff;
opt_autoneg = ((idx < MAX_UNITS) && (idx >= 0)) ? autoneg[idx] : 0xff;
if ((opt_speed == 0xff) |
(opt_duplex == 0xff) |
(opt_autoneg == 0xff)) {
*spd = SPEED_1000;
*dup = DUPLEX_FULL;
*aut = AUTONEG_ENABLE;
} else {
*spd = speed[idx];
*dup = duplex[idx];
*aut = autoneg[idx];
}
}
static void
rtl8168_powerdown_pll(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
int auto_nego = 0;
int giga_ctrl = 0;
if ((tp->mcfg == CFG_METHOD_11 || tp->mcfg == CFG_METHOD_12 ||
tp->mcfg == CFG_METHOD_13) && rtl8168_check_dash(tp))
return;
if (((tp->mcfg == CFG_METHOD_7) || (tp->mcfg == CFG_METHOD_8)) &&
(RTL_R16(CPlusCmd) & ASF))
return;
// if (tp->mcfg == CFG_METHOD_17) {
// void __iomem *ioaddr = tp->mmio_addr;
// unsigned long flags;
// u32 data;
// spin_lock_irqsave(&tp->phy_lock, flags);
// mdio_write(tp, 0x1f, 0x0000);
// data = mdio_read(tp, MII_CTRL1000);
// data &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
// mdio_write(tp, MII_CTRL1000, data);
// mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
// spin_unlock_irqrestore(&tp->phy_lock, flags);
// ssleep(3);
// RTL_W16(IntrStatus, RTL_R16(IntrStatus));
// RTL_W32(MAR0, 0);
// RTL_W32(MAR0 + 4, 0);
// RTL_W16(RxMaxSize, 0x05f3);
// RTL_W8(0xD3, RTL_R8(0xD3) | BIT_7);
// data = rtl8168_eri_read(ioaddr, 0xDC, 1, ERIAR_ExGMAC);
// data &= ~BIT_0;
// rtl8168_eri_write(ioaddr, 0xDC, 1, data, ERIAR_ExGMAC);
// data |= BIT_0;
// rtl8168_eri_write(ioaddr, 0xDC, 1, data, ERIAR_ExGMAC);
// RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast |
AcceptMyPhys);
// return;
// }
if (tp->wol_enabled == WOL_ENABLED) {
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0000);
auto_nego = mdio_read(tp, MII_ADVERTISE);
auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL
| ADVERTISE_100HALF | ADVERTISE_100FULL);
if (config_down_speed_100)
auto_nego |= ADVERTISE_100FULL;
else
auto_nego |= ADVERTISE_10HALF;
giga_ctrl = mdio_read(tp, MII_CTRL1000) & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
mdio_write(tp, MII_ADVERTISE, auto_nego);
mdio_write(tp, MII_CTRL1000, giga_ctrl);
mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
spin_unlock_irqrestore(&tp->phy_lock, flags);
RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast |
AcceptMyPhys);
return;
}
rtl8168_phy_power_down(dev);
switch (tp->mcfg) {
case CFG_METHOD_9:
case CFG_METHOD_10:
case CFG_METHOD_11:
case CFG_METHOD_12:
case CFG_METHOD_13:
case CFG_METHOD_14:
case CFG_METHOD_15:
RTL_W8(PMCH, RTL_R8(PMCH) & ~BIT_7);
break;
}
}
static void rtl8168_powerup_pll(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
switch (tp->mcfg) {
case CFG_METHOD_9:
case CFG_METHOD_10:
case CFG_METHOD_11:
case CFG_METHOD_12:
case CFG_METHOD_13:
case CFG_METHOD_14:
case CFG_METHOD_15:
RTL_W8(PMCH, RTL_R8(PMCH) | BIT_7);
break;
}
rtl8168_phy_power_up(dev);
rtl8168_set_speed(dev, tp->autoneg, tp->speed, tp->duplex);
}
static void
rtl8168_get_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
u8 options;
u32 csi_tmp;
wol->wolopts = 0;
#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
if (tp->mcfg == CFG_METHOD_DEFAULT) {
wol->supported = 0;
return;
} else {
wol->supported = WAKE_ANY;
}
spin_lock_irq(&tp->lock);
options = RTL_R8(Config1);
if (!(options & PMEnable))
goto out_unlock;
options = RTL_R8(Config3);
if (options & LinkUp)
wol->wolopts |= WAKE_PHY;
if (tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) {
csi_tmp = rtl8168_eri_read(ioaddr, 0xDE, 4, ERIAR_ExGMAC);
if (csi_tmp & BIT_0)
wol->wolopts |= WAKE_MAGIC;
} else {
if (options & MagicPacket)
wol->wolopts |= WAKE_MAGIC;
}
options = RTL_R8(Config5);
if (options & UWF)
wol->wolopts |= WAKE_UCAST;
if (options & BWF)
wol->wolopts |= WAKE_BCAST;
if (options & MWF)
wol->wolopts |= WAKE_MCAST;
out_unlock:
spin_unlock_irq(&tp->lock);
}
static int
rtl8168_set_wol(struct net_device *dev,
struct ethtool_wolinfo *wol)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
int i,tmp;
u32 csi_tmp;
static struct {
u32 opt;
u16 reg;
u8 mask;
} cfg[] = {
{ WAKE_ANY, Config1, PMEnable },
{ WAKE_PHY, Config3, LinkUp },
{ WAKE_UCAST, Config5, UWF },
{ WAKE_BCAST, Config5, BWF },
{ WAKE_MCAST, Config5, MWF },
{ WAKE_ANY, Config5, LanWake },
{ WAKE_MAGIC, Config3, MagicPacket },
};
if (tp->mcfg == CFG_METHOD_DEFAULT)
return -EOPNOTSUPP;
spin_lock_irq(&tp->lock);
RTL_W8(Cfg9346, Cfg9346_Unlock);
if (tp->mcfg == CFG_METHOD_16 || tp->mcfg == CFG_METHOD_17) {
tmp = ARRAY_SIZE(cfg) - 1;
csi_tmp = rtl8168_eri_read(ioaddr, 0xDE, 4, ERIAR_ExGMAC);
if (wol->wolopts & WAKE_MAGIC)
csi_tmp |= BIT_0;
else
csi_tmp &=~ BIT_0;
rtl8168_eri_write(ioaddr, 0xDE, 4, csi_tmp, ERIAR_ExGMAC);
} else {
tmp = ARRAY_SIZE(cfg);
}
for (i = 0; i < tmp; i++) {
u8 options = RTL_R8(cfg[i].reg) & ~cfg[i].mask;
if (wol->wolopts & cfg[i].opt)
options |= cfg[i].mask;
RTL_W8(cfg[i].reg, options);
}
RTL_W8(Cfg9346, Cfg9346_Lock);
tp->wol_enabled = (wol->wolopts) ? WOL_ENABLED : WOL_DISABLED;
spin_unlock_irq(&tp->lock);
return 0;
}
static void
rtl8168_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
struct rtl8168_private *tp = netdev_priv(dev);
strcpy(info->driver, MODULENAME);
strcpy(info->version, RTL8168_VERSION);
strcpy(info->bus_info, pci_name(tp->pci_dev));
info->regdump_len = R8168_REGS_SIZE;
info->eedump_len = tp->eeprom_len;
}
static int
rtl8168_get_regs_len(struct net_device *dev)
{
return R8168_REGS_SIZE;
}
static int
rtl8168_set_speed_xmii(struct net_device *dev,
u8 autoneg,
u16 speed,
u8 duplex)
{
struct rtl8168_private *tp = netdev_priv(dev);
int auto_nego = 0;
int giga_ctrl = 0;
int bmcr_true_force = 0;
unsigned long flags;
if ((speed != SPEED_1000) &&
(speed != SPEED_100) &&
(speed != SPEED_10)) {
speed = SPEED_1000;
duplex = DUPLEX_FULL;
}
if ((autoneg == AUTONEG_ENABLE) || (speed == SPEED_1000)) {
/*n-way force*/
if ((speed == SPEED_10) && (duplex == DUPLEX_HALF)) {
auto_nego |= ADVERTISE_10HALF;
} else if ((speed == SPEED_10) && (duplex == DUPLEX_FULL)) {
auto_nego |= ADVERTISE_10HALF |
ADVERTISE_10FULL;
} else if ((speed == SPEED_100) && (duplex == DUPLEX_HALF)) {
auto_nego |= ADVERTISE_100HALF |
ADVERTISE_10HALF |
ADVERTISE_10FULL;
} else if ((speed == SPEED_100) && (duplex == DUPLEX_FULL)) {
auto_nego |= ADVERTISE_100HALF |
ADVERTISE_100FULL |
ADVERTISE_10HALF |
ADVERTISE_10FULL;
} else if (speed == SPEED_1000) {
giga_ctrl |= ADVERTISE_1000HALF |
ADVERTISE_1000FULL;
auto_nego |= ADVERTISE_100HALF |
ADVERTISE_100FULL |
ADVERTISE_10HALF |
ADVERTISE_10FULL;
}
//flow contorol
auto_nego |= ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM;
tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
tp->autoneg = autoneg;
tp->speed = speed;
tp->duplex = duplex;
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, MII_ADVERTISE, auto_nego);
mdio_write(tp, MII_CTRL1000, giga_ctrl);
mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE | BMCR_ANRESTART);
spin_unlock_irqrestore(&tp->phy_lock, flags);
mdelay(20);
} else {
/*true force*/
#ifndef BMCR_SPEED100
#define BMCR_SPEED100 0x0040
#endif
#ifndef BMCR_SPEED10
#define BMCR_SPEED10 0x0000
#endif
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;
}
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, MII_BMCR, bmcr_true_force);
spin_unlock_irqrestore(&tp->phy_lock, flags);
}
if (tp->mcfg == CFG_METHOD_11)
rtl8168dp_10mbps_gphy_para(dev);
return 0;
}
static int
rtl8168_set_speed(struct net_device *dev,
u8 autoneg,
u16 speed,
u8 duplex)
{
struct rtl8168_private *tp = netdev_priv(dev);
int ret;
ret = tp->set_speed(dev, autoneg, speed, duplex);
return ret;
}
static int
rtl8168_set_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
struct rtl8168_private *tp = netdev_priv(dev);
unsigned long flags;
int ret;
spin_lock_irqsave(&tp->lock, flags);
ret = rtl8168_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex);
spin_unlock_irqrestore(&tp->lock, flags);
return ret;
}
static u32
rtl8168_get_tx_csum(struct net_device *dev)
{
return (dev->features & NETIF_F_IP_CSUM) != 0;
}
static u32
rtl8168_get_rx_csum(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
return tp->cp_cmd & RxChkSum;
}
static int
rtl8168_set_tx_csum(struct net_device *dev,
u32 data)
{
struct rtl8168_private *tp = netdev_priv(dev);
if (tp->mcfg == CFG_METHOD_DEFAULT)
return -EOPNOTSUPP;
if (data)
dev->features |= NETIF_F_IP_CSUM;
else
dev->features &= ~NETIF_F_IP_CSUM;
return 0;
}
static int
rtl8168_set_rx_csum(struct net_device *dev,
u32 data)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
if (tp->mcfg == CFG_METHOD_DEFAULT)
return -EOPNOTSUPP;
spin_lock_irqsave(&tp->lock, flags);
if (data)
tp->cp_cmd |= RxChkSum;
else
tp->cp_cmd &= ~RxChkSum;
RTL_W16(CPlusCmd, tp->cp_cmd);
spin_unlock_irqrestore(&tp->lock, flags);
return 0;
}
#ifdef CONFIG_R8168_VLAN
static inline u32
rtl8168_tx_vlan_tag(struct rtl8168_private *tp,
struct sk_buff *skb)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
return (tp->vlgrp && vlan_tx_tag_present(skb)) ?
#else
return (vlan_tx_tag_present(skb)) ?
#endif
TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
static void
rtl8168_vlan_rx_register(struct net_device *dev,
struct vlan_group *grp)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
spin_lock_irqsave(&tp->lock, flags);
tp->vlgrp = grp;
if (tp->vlgrp)
tp->cp_cmd |= RxVlan;
else
tp->cp_cmd &= ~RxVlan;
RTL_W16(CPlusCmd, tp->cp_cmd);
RTL_R16(CPlusCmd);
spin_unlock_irqrestore(&tp->lock, flags);
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
static void
rtl8168_vlan_rx_kill_vid(struct net_device *dev,
unsigned short vid)
{
struct rtl8168_private *tp = netdev_priv(dev);
unsigned long flags;
spin_lock_irqsave(&tp->lock, flags);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
if (tp->vlgrp)
tp->vlgrp->vlan_devices[vid] = NULL;
#else
vlan_group_set_device(tp->vlgrp, vid, NULL);
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
spin_unlock_irqrestore(&tp->lock, flags);
}
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
static int
rtl8168_rx_vlan_skb(struct rtl8168_private *tp,
struct RxDesc *desc,
struct sk_buff *skb)
{
u32 opts2 = le32_to_cpu(desc->opts2);
int ret = -1;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
if (tp->vlgrp && (opts2 & RxVlanTag)) {
rtl8168_rx_hwaccel_skb(skb, tp->vlgrp,
swab16(opts2 & 0xffff));
ret = 0;
}
#else
if (opts2 & RxVlanTag)
__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));
#endif
desc->opts2 = 0;
return ret;
}
#else /* !CONFIG_R8168_VLAN */
static inline u32
rtl8168_tx_vlan_tag(struct rtl8168_private *tp,
struct sk_buff *skb)
{
return 0;
}
static int
rtl8168_rx_vlan_skb(struct rtl8168_private *tp,
struct RxDesc *desc,
struct sk_buff *skb)
{
return -1;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
static u32 rtl8168_fix_features(struct net_device *dev, u32 features)
{
if (dev->mtu > MSSMask)
features &= ~NETIF_F_ALL_TSO;
return features;
}
static int rtl8168_set_features(struct net_device *dev, u32 features)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
spin_lock_irqsave(&tp->lock, flags);
if (features & NETIF_F_RXCSUM)
tp->cp_cmd |= RxChkSum;
else
tp->cp_cmd &= ~RxChkSum;
if (dev->features & NETIF_F_HW_VLAN_RX)
tp->cp_cmd |= RxVlan;
else
tp->cp_cmd &= ~RxVlan;
RTL_W16(CPlusCmd, tp->cp_cmd);
RTL_R16(CPlusCmd);
spin_unlock_irqrestore(&tp->lock, flags);
return 0;
}
#endif
static void rtl8168_gset_xmii(struct net_device *dev,
struct ethtool_cmd *cmd)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
u8 status;
unsigned long flags;
cmd->supported = SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_1000baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP;
spin_lock_irqsave(&tp->phy_lock, flags);
cmd->autoneg = (mdio_read(tp, MII_BMCR) & BMCR_ANENABLE) ? 1 : 0;
spin_unlock_irqrestore(&tp->phy_lock, flags);
cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
cmd->advertising |= ADVERTISED_10baseT_Half;
if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
cmd->advertising |= ADVERTISED_10baseT_Full;
if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
cmd->advertising |= ADVERTISED_100baseT_Half;
if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
cmd->advertising |= ADVERTISED_100baseT_Full;
if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
cmd->advertising |= ADVERTISED_1000baseT_Full;
status = RTL_R8(PHYstatus);
if (status & _1000bpsF)
cmd->speed = SPEED_1000;
else if (status & _100bps)
cmd->speed = SPEED_100;
else if (status & _10bps)
cmd->speed = SPEED_10;
if (status & TxFlowCtrl)
cmd->advertising |= ADVERTISED_Asym_Pause;
if (status & RxFlowCtrl)
cmd->advertising |= ADVERTISED_Pause;
cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
DUPLEX_FULL : DUPLEX_HALF;
}
static int
rtl8168_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
struct rtl8168_private *tp = netdev_priv(dev);
unsigned long flags;
spin_lock_irqsave(&tp->lock, flags);
tp->get_settings(dev, cmd);
spin_unlock_irqrestore(&tp->lock, flags);
return 0;
}
static void rtl8168_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *p)
{
struct rtl8168_private *tp = netdev_priv(dev);
unsigned long flags;
if (regs->len > R8168_REGS_SIZE)
regs->len = R8168_REGS_SIZE;
spin_lock_irqsave(&tp->lock, flags);
memcpy_fromio(p, tp->mmio_addr, regs->len);
spin_unlock_irqrestore(&tp->lock, flags);
}
static u32
rtl8168_get_msglevel(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
return tp->msg_enable;
}
static void
rtl8168_set_msglevel(struct net_device *dev,
u32 value)
{
struct rtl8168_private *tp = netdev_priv(dev);
tp->msg_enable = value;
}
static const char rtl8168_gstrings[][ETH_GSTRING_LEN] = {
"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",
};
struct rtl8168_counters {
u64 tx_packets;
u64 rx_packets;
u64 tx_errors;
u32 rx_errors;
u16 rx_missed;
u16 align_errors;
u32 tx_one_collision;
u32 tx_multi_collision;
u64 rx_unicast;
u64 rx_broadcast;
u32 rx_multicast;
u16 tx_aborted;
u16 tx_underun;
};
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
static int rtl8168_get_stats_count(struct net_device *dev)
{
return ARRAY_SIZE(rtl8168_gstrings);
}
#else
static int rtl8168_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
case ETH_SS_STATS:
return ARRAY_SIZE(rtl8168_gstrings);
default:
return -EOPNOTSUPP;
}
}
#endif
static void
rtl8168_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats,
u64 *data)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct rtl8168_counters *counters;
dma_addr_t paddr;
u32 cmd;
ASSERT_RTNL();
counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
if (!counters)
return;
RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
cmd = (u64)paddr & DMA_BIT_MASK(32);
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
while (RTL_R32(CounterAddrLow) & CounterDump) {
if (msleep_interruptible(1))
break;
}
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
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_underun);
pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
}
static void
rtl8168_get_strings(struct net_device *dev,
u32 stringset,
u8 *data)
{
switch (stringset) {
case ETH_SS_STATS:
memcpy(data, *rtl8168_gstrings, sizeof(rtl8168_gstrings));
break;
}
}
static int rtl_get_eeprom_len(struct net_device *dev)
{
struct rtl8168_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 rtl8168_private *tp = netdev_priv(dev);
int i,j,ret;
int start_w, end_w;
int VPD_addr, VPD_data;
u32 *eeprom_buff;
u16 tmp;
void __iomem *ioaddr = tp->mmio_addr;
if (tp->eeprom_type==EEPROM_TYPE_NONE)
{
dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Detect none EEPROM\n");
return -EOPNOTSUPP;
}
else if (eeprom->len == 0 || (eeprom->offset+eeprom->len) > tp->eeprom_len)
{
dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Invalid parameter\n");
return -EINVAL;
}
switch (tp->mcfg)
{
case CFG_METHOD_9:
case CFG_METHOD_10:
VPD_addr = 0xCE;
VPD_data = 0xD0;
break;
case CFG_METHOD_4:
case CFG_METHOD_5:
case CFG_METHOD_6:
case CFG_METHOD_7:
case CFG_METHOD_8:
case CFG_METHOD_14:
case CFG_METHOD_15:
VPD_addr = 0xD2;
VPD_data = 0xD4;
break;
case CFG_METHOD_1:
case CFG_METHOD_2:
case CFG_METHOD_3:
default:
return -EOPNOTSUPP;
}
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;
}
RTL_W8(Cfg9346, Cfg9346_Unlock);
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]);
}
RTL_W8(Cfg9346, Cfg9346_Lock);
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
u32 _kc_ethtool_op_get_link(struct net_device *dev)
{
return netif_carrier_ok(dev) ? 1 : 0;
}
#undef ethtool_op_get_sg
#define ethtool_op_get_sg _kc_ethtool_op_get_sg
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
int _kc_ethtool_op_set_sg(struct net_device *dev, u32 data)
{
struct rtl8168_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;
}
static struct ethtool_ops rtl8168_ethtool_ops = {
.get_drvinfo = rtl8168_get_drvinfo,
.get_regs_len = rtl8168_get_regs_len,
.get_link = ethtool_op_get_link,
.get_settings = rtl8168_get_settings,
.set_settings = rtl8168_set_settings,
.get_msglevel = rtl8168_get_msglevel,
.set_msglevel = rtl8168_set_msglevel,
//.get_rx_csum = rtl8168_get_rx_csum,
//.set_rx_csum = rtl8168_set_rx_csum,
//.get_tx_csum = rtl8168_get_tx_csum,
//.set_tx_csum = rtl8168_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
.get_regs = rtl8168_get_regs,
.get_wol = rtl8168_get_wol,
.set_wol = rtl8168_set_wol,
.get_strings = rtl8168_get_strings,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)
.get_stats_count = rtl8168_get_stats_count,
#else
.get_sset_count = rtl8168_get_sset_count,
#endif
.get_ethtool_stats = rtl8168_get_ethtool_stats,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
#ifdef ETHTOOL_GPERMADDR
.get_perm_addr = ethtool_op_get_perm_addr,
#endif
#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
.get_eeprom = rtl_get_eeprom,
.get_eeprom_len = rtl_get_eeprom_len,
};
static int rtl8168_enable_EEE(struct rtl8168_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
int ret;
unsigned long flags;
__u16 data;
ret = 0;
switch (tp->mcfg) {
case CFG_METHOD_14:
case CFG_METHOD_15:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1E, 0x0020);
data = mdio_read(tp, 0x15) | 0x0100;
mdio_write(tp, 0x15, data);
mdio_write(tp, 0x1F, 0x0006);
mdio_write(tp, 0x00, 0x5A30);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0x0007);
mdio_write(tp, 0x0E, 0x003C);
mdio_write(tp, 0x0D, 0x4007);
mdio_write(tp, 0x0E, 0x0006);
mdio_write(tp, 0x0D, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
if((RTL_R8(Config4)&0x40) && (RTL_R8(0x6D) & BIT_7))
{
data = RTL_R16(CustomLED);
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8AC8);
mdio_write(tp, 0x06, data);
mdio_write(tp, 0x05, 0x8B82);
data = mdio_read(tp, 0x06) | 0x0010;
mdio_write(tp, 0x05, 0x8B82);
mdio_write(tp, 0x06, data);
mdio_write(tp, 0x1F, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
}
break;
case CFG_METHOD_16:
case CFG_METHOD_17:
spin_lock_irqsave(&tp->phy_lock,flags);
data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC) | 0x0003;
rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC);
mdio_write(tp,0x1F , 0x0004);
mdio_write(tp,0x1F , 0x0007);
mdio_write(tp,0x1E , 0x0020);
data = mdio_read(tp, 0x15)|0x0100;
mdio_write(tp,0x15 , data);
mdio_write(tp,0x1F , 0x0002);
mdio_write(tp,0x1F , 0x0005);
mdio_write(tp,0x05 , 0x8B85);
data = mdio_read(tp, 0x06)|0x2000;
mdio_write(tp,0x06 , data);
mdio_write(tp,0x1F , 0x0000);
mdio_write(tp,0x0D , 0x0007);
mdio_write(tp,0x0E , 0x003C);
mdio_write(tp,0x0D , 0x4007);
mdio_write(tp,0x0E , 0x0006);
mdio_write(tp,0x1D , 0x0000);
spin_unlock_irqrestore(&tp->phy_lock,flags);
break;
case CFG_METHOD_18:
case CFG_METHOD_19:
case CFG_METHOD_20:
spin_lock_irqsave(&tp->phy_lock,flags);
data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC);
data |= BIT_1 | BIT_0;
rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1e, 0x0020);
data = mdio_read(tp, 0x15);
data |= BIT_8;
mdio_write(tp, 0x15, data);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8B85);
data = mdio_read(tp, 0x06);
data |= BIT_13;
mdio_write(tp, 0x06, data);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0x0007);
mdio_write(tp, 0x0E, 0x003C);
mdio_write(tp, 0x0D, 0x4007);
mdio_write(tp, 0x0E, 0x0006);
mdio_write(tp, 0x0D, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock,flags);
break;
default:
// dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support EEE\n");
ret = -EOPNOTSUPP;
}
return ret;
}
static int rtl8168_disable_EEE(struct rtl8168_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
int ret;
unsigned long flags;
__u16 data;
ret = 0;
switch (tp->mcfg) {
case CFG_METHOD_14:
case CFG_METHOD_15:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1E, 0x0020);
data = mdio_read(tp, 0x15) & ~0x0100;
mdio_write(tp, 0x15, data);
mdio_write(tp, 0x1F, 0x0006);
mdio_write(tp, 0x00, 0x5A00);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0x0007);
mdio_write(tp, 0x0E, 0x003C);
mdio_write(tp, 0x0D, 0x4007);
mdio_write(tp, 0x0E, 0x0000);
mdio_write(tp, 0x0D, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
if (RTL_R8(Config4) & 0x40)
{
data = RTL_R16(CustomLED);
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8B82);
data = mdio_read(tp, 0x06) & ~0x0010;
mdio_write(tp, 0x05, 0x8B82);
mdio_write(tp, 0x06, data);
mdio_write(tp, 0x1F, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
}
break;
case CFG_METHOD_16:
case CFG_METHOD_17:
spin_lock_irqsave(&tp->phy_lock,flags);
data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC)& ~0x0003;
rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8B85);
data = mdio_read(tp, 0x06) & ~0x2000;
mdio_write(tp, 0x06, data);
mdio_write(tp, 0x1F, 0x0004);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1E, 0x0020);
data = mdio_read(tp, 0x15) & ~0x0100;
mdio_write(tp,0x15 , data);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0x0007);
mdio_write(tp, 0x0E, 0x003C);
mdio_write(tp, 0x0D, 0x4007);
mdio_write(tp, 0x0E, 0x0000);
mdio_write(tp, 0x0D, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
break;
case CFG_METHOD_18:
case CFG_METHOD_19:
case CFG_METHOD_20:
spin_lock_irqsave(&tp->phy_lock,flags);
data = rtl8168_eri_read(ioaddr,0x1B0 ,4,ERIAR_ExGMAC);
data &= ~(BIT_1 | BIT_0);
rtl8168_eri_write(ioaddr, 0x1B0, 4, data, ERIAR_ExGMAC);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8B85);
data = mdio_read(tp, 0x06);
data &= ~BIT_13;
mdio_write(tp, 0x06, data);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1e, 0x0020);
data = mdio_read(tp, 0x15);
data &= ~BIT_8;
mdio_write(tp, 0x15, data);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0x0007);
mdio_write(tp, 0x0E, 0x003C);
mdio_write(tp, 0x0D, 0x4007);
mdio_write(tp, 0x0E, 0x0000);
mdio_write(tp, 0x0D, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock,flags);
break;
default:
// dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support EEE\n");
ret = -EOPNOTSUPP;
break;
}
return ret;
}
static int rtl8168_green_table(struct rtl8168_private *tp)
{
struct pci_dev *pdev = tp->pci_dev;
unsigned long flags;
u16 gphy_val;
int i;
static const u16 evl_phy_value[] = {
0x8B56, 0x8B5F, 0x8B68, 0x8B71,
0x8B7A, 0x8A7B, 0x8A7E, 0x8A81,
0x8A84, 0x8A87
};
switch (tp->mcfg) {
case CFG_METHOD_16:
case CFG_METHOD_17:
if (pdev->subsystem_vendor == 0x1043 &&
pdev->subsystem_device == 0x13F7) {
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0005);
for (i=0; i < ARRAY_SIZE(evl_phy_value); i++) {
mdio_write(tp, 0x05, evl_phy_value[i]);
gphy_val = (0xAA << 8) | (mdio_read(tp, 0x06) & 0xFF);
mdio_write(tp, 0x06, gphy_val);
}
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1E, 0x0078);
mdio_write(tp, 0x17, 0x51AA);
mdio_write(tp, 0x1F, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
}
break;
default:
break;
}
switch (tp->mcfg) {
case CFG_METHOD_16:
case CFG_METHOD_17:
case CFG_METHOD_18:
case CFG_METHOD_19:
case CFG_METHOD_20:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0x8B54);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_11);
mdio_write(tp, 0x05, 0x8B5D);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_11);
mdio_write(tp, 0x05, 0x8A7C);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8);
mdio_write(tp, 0x05, 0x8A7F);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) | BIT_8);
mdio_write(tp, 0x05, 0x8A82);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8);
mdio_write(tp, 0x05, 0x8A85);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8);
mdio_write(tp, 0x05, 0x8A88);
mdio_write(tp, 0x06, mdio_read(tp, 0x06) & BIT_8);
mdio_write(tp, 0x1f, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
break;
default:
break;
}
return 0;
}
#if 0
static int rtl8168_enable_green_feature(struct rtl8168_private *tp)
{
unsigned long flags;
u16 gphy_val;
switch (tp->mcfg) {
case CFG_METHOD_14:
case CFG_METHOD_15:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0003);
gphy_val = mdio_read(tp, 0x10) | 0x0400;
mdio_write(tp, 0x10, gphy_val);
gphy_val = mdio_read(tp, 0x19) | 0x0001;
mdio_write(tp, 0x19, gphy_val);
mdio_write(tp, 0x1F, 0x0005);
gphy_val = mdio_read(tp, 0x01) & ~0x0100;
mdio_write(tp, 0x01, gphy_val);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x00, 0x9200);
mdelay(20);
spin_unlock_irqrestore(&tp->phy_lock, flags);
break;
case CFG_METHOD_17:
case CFG_METHOD_18:
case CFG_METHOD_19:
case CFG_METHOD_20:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0003);
gphy_val = mdio_read(tp, 0x10);
gphy_val |= BIT_10;
mdio_write(tp, 0x10, gphy_val);
gphy_val = mdio_read(tp, 0x19);
gphy_val |= BIT_0;
mdio_write(tp, 0x19, gphy_val);
mdio_write(tp, 0x1F, 0x0005);
gphy_val = mdio_read(tp, 0x01);
gphy_val |= BIT_8;
mdio_write(tp, 0x01, gphy_val);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x00, 0x9200);
spin_unlock_irqrestore(&tp->phy_lock, flags);
break;
default:
dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support Green Feature\n");
break;
}
return 0;
}
static int rtl8168_disable_green_feature(struct rtl8168_private *tp)
{
unsigned long flags;
u16 gphy_val;
switch (tp->mcfg) {
case CFG_METHOD_14:
case CFG_METHOD_15:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0005);
gphy_val = mdio_read(tp, 0x01) | 0x0100;
mdio_write(tp, 0x01, gphy_val);
mdio_write(tp, 0x1F, 0x0003);
gphy_val = mdio_read(tp, 0x10) & ~0x0400;
mdio_write(tp, 0x10, gphy_val);
gphy_val = mdio_read(tp, 0x19) & ~0x0001;
mdio_write(tp, 0x19, gphy_val);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x06) & ~0x7000;
gphy_val |= 0x3000;
mdio_write(tp, 0x06, gphy_val);
gphy_val = mdio_read(tp, 0x0D) & 0x0700;
gphy_val |= 0x0500;
mdio_write(tp, 0x0D, gphy_val);
mdio_write(tp, 0x1F, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
break;
case CFG_METHOD_17:
case CFG_METHOD_18:
case CFG_METHOD_19:
case CFG_METHOD_20:
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0003);
gphy_val = mdio_read(tp, 0x19);
gphy_val &= ~BIT_0;
mdio_write(tp, 0x19, gphy_val);
gphy_val = mdio_read(tp, 0x10);
gphy_val &= ~BIT_10;
mdio_write(tp, 0x10, gphy_val);
mdio_write(tp, 0x1f, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
break;
default:
dev_printk(KERN_DEBUG, &tp->pci_dev->dev, "Not Support Green Feature\n");
break;
}
return 0;
}
#endif
static void rtl8168_get_mac_version(struct rtl8168_private *tp, void __iomem *ioaddr)
{
u32 reg,val32;
u32 ICVerID;
val32 = RTL_R32(TxConfig) ;
reg = val32 & 0x7c800000;
ICVerID = val32 & 0x00700000;
switch (reg) {
case 0x30000000:
tp->mcfg = CFG_METHOD_1;
tp->efuse = EFUSE_NOT_SUPPORT;
break;
case 0x38000000:
if (ICVerID == 0x00000000) {
tp->mcfg = CFG_METHOD_2;
} else if (ICVerID == 0x00500000) {
tp->mcfg = CFG_METHOD_3;
} else {
tp->mcfg = CFG_METHOD_3;
}
tp->efuse = EFUSE_NOT_SUPPORT;
break;
case 0x3C000000:
if (ICVerID == 0x00000000) {
tp->mcfg = CFG_METHOD_4;
} else if (ICVerID == 0x00200000) {
tp->mcfg = CFG_METHOD_5;
} else if (ICVerID == 0x00400000) {
tp->mcfg = CFG_METHOD_6;
} else {
tp->mcfg = CFG_METHOD_6;
}
tp->efuse = EFUSE_NOT_SUPPORT;
break;
case 0x3C800000:
if (ICVerID == 0x00100000){
tp->mcfg = CFG_METHOD_7;
} else if (ICVerID == 0x00300000){
tp->mcfg = CFG_METHOD_8;
} else {
tp->mcfg = CFG_METHOD_8;
}
tp->efuse = EFUSE_NOT_SUPPORT;
break;
case 0x28000000:
if (ICVerID == 0x00100000) {
tp->mcfg = CFG_METHOD_9;
} else if (ICVerID == 0x00300000) {
tp->mcfg = CFG_METHOD_10;
} else {
tp->mcfg = CFG_METHOD_10;
}
tp->efuse = EFUSE_SUPPORT;
break;
case 0x28800000:
if (ICVerID == 0x00000000)
tp->mcfg = CFG_METHOD_11;
else if (ICVerID == 0x00200000) {
tp->mcfg = CFG_METHOD_12;
RTL_W32(0xD0, RTL_R32(0xD0) | 0x00020000);
} else// if (ICVerID == 0x00300000)
tp->mcfg = CFG_METHOD_13;
tp->efuse = EFUSE_SUPPORT;
break;
case 0x2C000000:
if (ICVerID == 0x00100000)
tp->mcfg = CFG_METHOD_14;
else if (ICVerID == 0x00200000)
tp->mcfg = CFG_METHOD_15;
tp->efuse = EFUSE_SUPPORT;
break;
case 0x2C800000:
if (ICVerID == 0x00000000)
tp->mcfg = CFG_METHOD_16;
else if (ICVerID == 0x00100000)
tp->mcfg = CFG_METHOD_17;
tp->efuse = EFUSE_SUPPORT;
break;
case 0x48000000:
if (ICVerID == 0x00000000)
tp->mcfg = CFG_METHOD_18;
else if (ICVerID == 0x00100000)
tp->mcfg = CFG_METHOD_19;
tp->efuse = EFUSE_SUPPORT;
break;
case 0x48800000:
tp->mcfg = CFG_METHOD_20;
tp->efuse = EFUSE_SUPPORT;
break;
default:
printk("unknown chip version (%x)\n",reg);
tp->mcfg = CFG_METHOD_DEFAULT;
tp->efuse = EFUSE_NOT_SUPPORT;
break;
}
}
static void
rtl8168_print_mac_version(struct rtl8168_private *tp)
{
int i;
for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) {
if (tp->mcfg == rtl_chip_info[i].mcfg){
dprintk("mcfg == %s (%04d)\n", rtl_chip_info[i].name,
rtl_chip_info[i].mcfg);
return;
}
}
dprintk("mac_version == Unknown\n");
}
static u8 rtl8168_efuse_read(struct rtl8168_private *tp, u16 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
u8 efuse_data;
u32 temp;
int cnt;
if (tp->efuse == EFUSE_NOT_SUPPORT)
return EFUSE_READ_FAIL;
temp = EFUSE_READ | ((reg & EFUSE_Reg_Mask) << EFUSE_Reg_Shift);
RTL_W32(EFUSEAR, temp);
do {
udelay(100);
temp = RTL_R32(EFUSEAR);
cnt++;
} while (!(temp & EFUSE_READ_OK) && (temp < EFUSE_Check_Cnt));
if (temp == EFUSE_Check_Cnt)
efuse_data = EFUSE_READ_FAIL;
else
efuse_data = (u8)(RTL_R32(EFUSEAR) & EFUSE_Data_Mask);
return efuse_data;
}
static void
rtl8168_hw_phy_config(struct net_device *dev)
{
struct rtl8168_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
unsigned int gphy_val,i;
spin_lock_irqsave(&tp->phy_lock, flags);
if (tp->mcfg == CFG_METHOD_1) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x0B, 0x94B0);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x12, 0x6096);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0xF8A0);
} else if (tp->mcfg == CFG_METHOD_2) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x0B, 0x94B0);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x12, 0x6096);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_3) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x0B, 0x94B0);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x12, 0x6096);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_4) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x12, 0x2300);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x16, 0x000A);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x12, 0xC096);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x00, 0x88DE);
mdio_write(tp, 0x01, 0x82B1);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x08, 0x9E30);
mdio_write(tp, 0x09, 0x01F0);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0A, 0x5500);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x03, 0x7002);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0C, 0x00C8);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5));
mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5));
} else if (tp->mcfg == CFG_METHOD_5) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x12, 0x2300);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x16, 0x0F0A);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x00, 0x88DE);
mdio_write(tp, 0x01, 0x82B1);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0C, 0x7EB8);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x06, 0x0761);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x03, 0x802F);
mdio_write(tp, 0x02, 0x4F02);
mdio_write(tp, 0x01, 0x0409);
mdio_write(tp, 0x00, 0xF099);
mdio_write(tp, 0x04, 0x9800);
mdio_write(tp, 0x04, 0x9000);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x16, mdio_read(tp, 0x16) | (1 << 0));
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5));
mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5));
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x1D, 0x3D98);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_6) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x12, 0x2300);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x16, 0x0F0A);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x00, 0x88DE);
mdio_write(tp, 0x01, 0x82B1);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0C, 0x7EB8);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x06, 0x5461);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x06, 0x5461);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x16, mdio_read(tp, 0x16) | (1 << 0));
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5));
mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5));
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x1D, 0x3D98);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1f, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_7) {
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5));
mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5));
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x1D, 0x3D98);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x14, 0xCAA3);
mdio_write(tp, 0x1C, 0x000A);
mdio_write(tp, 0x18, 0x65D0);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x17, 0xB580);
mdio_write(tp, 0x18, 0xFF54);
mdio_write(tp, 0x19, 0x3954);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0D, 0x310C);
mdio_write(tp, 0x0E, 0x310C);
mdio_write(tp, 0x0F, 0x311C);
mdio_write(tp, 0x06, 0x0761);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x18, 0xFF55);
mdio_write(tp, 0x19, 0x3955);
mdio_write(tp, 0x18, 0xFF54);
mdio_write(tp, 0x19, 0x3954);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_8) {
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x14, mdio_read(tp, 0x14) | (1 << 5));
mdio_write(tp, 0x0D, mdio_read(tp, 0x0D) & ~(1 << 5));
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x14, 0xCAA3);
mdio_write(tp, 0x1C, 0x000A);
mdio_write(tp, 0x18, 0x65D0);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x17, 0xB580);
mdio_write(tp, 0x18, 0xFF54);
mdio_write(tp, 0x19, 0x3954);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0D, 0x310C);
mdio_write(tp, 0x0E, 0x310C);
mdio_write(tp, 0x0F, 0x311C);
mdio_write(tp, 0x06, 0x0761);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x18, 0xFF55);
mdio_write(tp, 0x19, 0x3955);
mdio_write(tp, 0x18, 0xFF54);
mdio_write(tp, 0x19, 0x3954);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x16, mdio_read(tp, 0x16) | (1 << 0));
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_9) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x06, 0x4064);
mdio_write(tp, 0x07, 0x2863);
mdio_write(tp, 0x08, 0x059C);
mdio_write(tp, 0x09, 0x26B4);
mdio_write(tp, 0x0A, 0x6A19);
mdio_write(tp, 0x0B, 0xDCC8);
mdio_write(tp, 0x10, 0xF06D);
mdio_write(tp, 0x14, 0x7F68);
mdio_write(tp, 0x18, 0x7FD9);
mdio_write(tp, 0x1C, 0xF0FF);
mdio_write(tp, 0x1D, 0x3D9C);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x12, 0xF49F);
mdio_write(tp, 0x13, 0x070B);
mdio_write(tp, 0x1A, 0x05AD);
mdio_write(tp, 0x14, 0x94C0);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x0B) & 0xFF00;
gphy_val |= 0x10;
mdio_write(tp, 0x0B, gphy_val);
gphy_val = mdio_read(tp, 0x0C) & 0x00FF;
gphy_val |= 0xA200;
mdio_write(tp, 0x0C, gphy_val);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x06, 0x5561);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8332);
mdio_write(tp, 0x06, 0x5561);
if (rtl8168_efuse_read(tp, 0x01) == 0xb1) {
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x05, 0x669A);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8330);
mdio_write(tp, 0x06, 0x669A);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x0D);
if ((gphy_val & 0x00FF) != 0x006C) {
gphy_val &= 0xFF00;
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0D, gphy_val | 0x0065);
mdio_write(tp, 0x0D, gphy_val | 0x0066);
mdio_write(tp, 0x0D, gphy_val | 0x0067);
mdio_write(tp, 0x0D, gphy_val | 0x0068);
mdio_write(tp, 0x0D, gphy_val | 0x0069);
mdio_write(tp, 0x0D, gphy_val | 0x006A);
mdio_write(tp, 0x0D, gphy_val | 0x006B);
mdio_write(tp, 0x0D, gphy_val | 0x006C);
}
} else {
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x05, 0x6662);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8330);
mdio_write(tp, 0x06, 0x6662);
}
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x0D);
gphy_val |= BIT_9;
gphy_val |= BIT_8;
mdio_write(tp, 0x0D, gphy_val);
gphy_val = mdio_read(tp, 0x0F);
gphy_val |= BIT_4;
mdio_write(tp, 0x0F, gphy_val);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x02);
gphy_val &= ~BIT_10;
gphy_val &= ~BIT_9;
gphy_val |= BIT_8;
mdio_write(tp, 0x02, gphy_val);
gphy_val = mdio_read(tp, 0x03);
gphy_val &= ~BIT_15;
gphy_val &= ~BIT_14;
gphy_val &= ~BIT_13;
mdio_write(tp, 0x03, gphy_val);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
spin_unlock_irqrestore(&tp->phy_lock, flags);
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x001B);
if (mdio_read(tp, 0x06) == 0xBF00) {
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x0080);
mdio_write(tp, 0x05, 0x8000);
mdio_write(tp, 0x06, 0xf8f9);
mdio_write(tp, 0x06, 0xfaef);
mdio_write(tp, 0x06, 0x59ee);
mdio_write(tp, 0x06, 0xf8ea);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0xf8eb);
mdio_write(tp, 0x06, 0x00e0);
mdio_write(tp, 0x06, 0xf87c);
mdio_write(tp, 0x06, 0xe1f8);
mdio_write(tp, 0x06, 0x7d59);
mdio_write(tp, 0x06, 0x0fef);
mdio_write(tp, 0x06, 0x0139);
mdio_write(tp, 0x06, 0x029e);
mdio_write(tp, 0x06, 0x06ef);
mdio_write(tp, 0x06, 0x1039);
mdio_write(tp, 0x06, 0x089f);
mdio_write(tp, 0x06, 0x2aee);
mdio_write(tp, 0x06, 0xf8ea);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0xf8eb);
mdio_write(tp, 0x06, 0x01e0);
mdio_write(tp, 0x06, 0xf87c);
mdio_write(tp, 0x06, 0xe1f8);
mdio_write(tp, 0x06, 0x7d58);
mdio_write(tp, 0x06, 0x409e);
mdio_write(tp, 0x06, 0x0f39);
mdio_write(tp, 0x06, 0x46aa);
mdio_write(tp, 0x06, 0x0bbf);
mdio_write(tp, 0x06, 0x8290);
mdio_write(tp, 0x06, 0xd682);
mdio_write(tp, 0x06, 0x9802);
mdio_write(tp, 0x06, 0x014f);
mdio_write(tp, 0x06, 0xae09);
mdio_write(tp, 0x06, 0xbf82);
mdio_write(tp, 0x06, 0x98d6);
mdio_write(tp, 0x06, 0x82a0);
mdio_write(tp, 0x06, 0x0201);
mdio_write(tp, 0x06, 0x4fef);
mdio_write(tp, 0x06, 0x95fe);
mdio_write(tp, 0x06, 0xfdfc);
mdio_write(tp, 0x06, 0x05f8);
mdio_write(tp, 0x06, 0xf9fa);
mdio_write(tp, 0x06, 0xeef8);
mdio_write(tp, 0x06, 0xea00);
mdio_write(tp, 0x06, 0xeef8);
mdio_write(tp, 0x06, 0xeb00);
mdio_write(tp, 0x06, 0xe2f8);
mdio_write(tp, 0x06, 0x7ce3);
mdio_write(tp, 0x06, 0xf87d);
mdio_write(tp, 0x06, 0xa511);
mdio_write(tp, 0x06, 0x1112);
mdio_write(tp, 0x06, 0xd240);
mdio_write(tp, 0x06, 0xd644);
mdio_write(tp, 0x06, 0x4402);
mdio_write(tp, 0x06, 0x8217);
mdio_write(tp, 0x06, 0xd2a0);
mdio_write(tp, 0x06, 0xd6aa);
mdio_write(tp, 0x06, 0xaa02);
mdio_write(tp, 0x06, 0x8217);
mdio_write(tp, 0x06, 0xae0f);
mdio_write(tp, 0x06, 0xa544);
mdio_write(tp, 0x06, 0x4402);
mdio_write(tp, 0x06, 0xae4d);
mdio_write(tp, 0x06, 0xa5aa);
mdio_write(tp, 0x06, 0xaa02);
mdio_write(tp, 0x06, 0xae47);
mdio_write(tp, 0x06, 0xaf82);
mdio_write(tp, 0x06, 0x13ee);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0x0fee);
mdio_write(tp, 0x06, 0x834c);
mdio_write(tp, 0x06, 0x0fee);
mdio_write(tp, 0x06, 0x834f);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8351);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x834a);
mdio_write(tp, 0x06, 0xffee);
mdio_write(tp, 0x06, 0x834b);
mdio_write(tp, 0x06, 0xffe0);
mdio_write(tp, 0x06, 0x8330);
mdio_write(tp, 0x06, 0xe183);
mdio_write(tp, 0x06, 0x3158);
mdio_write(tp, 0x06, 0xfee4);
mdio_write(tp, 0x06, 0xf88a);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x8be0);
mdio_write(tp, 0x06, 0x8332);
mdio_write(tp, 0x06, 0xe183);
mdio_write(tp, 0x06, 0x3359);
mdio_write(tp, 0x06, 0x0fe2);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0x0c24);
mdio_write(tp, 0x06, 0x5af0);
mdio_write(tp, 0x06, 0x1e12);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x8ce5);
mdio_write(tp, 0x06, 0xf88d);
mdio_write(tp, 0x06, 0xaf82);
mdio_write(tp, 0x06, 0x13e0);
mdio_write(tp, 0x06, 0x834f);
mdio_write(tp, 0x06, 0x10e4);
mdio_write(tp, 0x06, 0x834f);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x009f);
mdio_write(tp, 0x06, 0x0ae0);
mdio_write(tp, 0x06, 0x834f);
mdio_write(tp, 0x06, 0xa010);
mdio_write(tp, 0x06, 0xa5ee);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x01e0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7805);
mdio_write(tp, 0x06, 0x9e9a);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x049e);
mdio_write(tp, 0x06, 0x10e0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7803);
mdio_write(tp, 0x06, 0x9e0f);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x019e);
mdio_write(tp, 0x06, 0x05ae);
mdio_write(tp, 0x06, 0x0caf);
mdio_write(tp, 0x06, 0x81f8);
mdio_write(tp, 0x06, 0xaf81);
mdio_write(tp, 0x06, 0xa3af);
mdio_write(tp, 0x06, 0x81dc);
mdio_write(tp, 0x06, 0xaf82);
mdio_write(tp, 0x06, 0x13ee);
mdio_write(tp, 0x06, 0x8348);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8349);
mdio_write(tp, 0x06, 0x00e0);
mdio_write(tp, 0x06, 0x8351);
mdio_write(tp, 0x06, 0x10e4);
mdio_write(tp, 0x06, 0x8351);
mdio_write(tp, 0x06, 0x5801);
mdio_write(tp, 0x06, 0x9fea);
mdio_write(tp, 0x06, 0xd000);
mdio_write(tp, 0x06, 0xd180);
mdio_write(tp, 0x06, 0x1f66);
mdio_write(tp, 0x06, 0xe2f8);
mdio_write(tp, 0x06, 0xeae3);
mdio_write(tp, 0x06, 0xf8eb);
mdio_write(tp, 0x06, 0x5af8);
mdio_write(tp, 0x06, 0x1e20);
mdio_write(tp, 0x06, 0xe6f8);
mdio_write(tp, 0x06, 0xeae5);
mdio_write(tp, 0x06, 0xf8eb);
mdio_write(tp, 0x06, 0xd302);
mdio_write(tp, 0x06, 0xb3fe);
mdio_write(tp, 0x06, 0xe2f8);
mdio_write(tp, 0x06, 0x7cef);
mdio_write(tp, 0x06, 0x325b);
mdio_write(tp, 0x06, 0x80e3);
mdio_write(tp, 0x06, 0xf87d);
mdio_write(tp, 0x06, 0x9e03);
mdio_write(tp, 0x06, 0x7dff);
mdio_write(tp, 0x06, 0xff0d);
mdio_write(tp, 0x06, 0x581c);
mdio_write(tp, 0x06, 0x551a);
mdio_write(tp, 0x06, 0x6511);
mdio_write(tp, 0x06, 0xa190);
mdio_write(tp, 0x06, 0xd3e2);
mdio_write(tp, 0x06, 0x8348);
mdio_write(tp, 0x06, 0xe383);
mdio_write(tp, 0x06, 0x491b);
mdio_write(tp, 0x06, 0x56ab);
mdio_write(tp, 0x06, 0x08ef);
mdio_write(tp, 0x06, 0x56e6);
mdio_write(tp, 0x06, 0x8348);
mdio_write(tp, 0x06, 0xe783);
mdio_write(tp, 0x06, 0x4910);
mdio_write(tp, 0x06, 0xd180);
mdio_write(tp, 0x06, 0x1f66);
mdio_write(tp, 0x06, 0xa004);
mdio_write(tp, 0x06, 0xb9e2);
mdio_write(tp, 0x06, 0x8348);
mdio_write(tp, 0x06, 0xe383);
mdio_write(tp, 0x06, 0x49ef);
mdio_write(tp, 0x06, 0x65e2);
mdio_write(tp, 0x06, 0x834a);
mdio_write(tp, 0x06, 0xe383);
mdio_write(tp, 0x06, 0x4b1b);
mdio_write(tp, 0x06, 0x56aa);
mdio_write(tp, 0x06, 0x0eef);
mdio_write(tp, 0x06, 0x56e6);
mdio_write(tp, 0x06, 0x834a);
mdio_write(tp, 0x06, 0xe783);
mdio_write(tp, 0x06, 0x4be2);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0xe683);
mdio_write(tp, 0x06, 0x4ce0);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0xa000);
mdio_write(tp, 0x06, 0x0caf);
mdio_write(tp, 0x06, 0x81dc);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4d10);
mdio_write(tp, 0x06, 0xe483);
mdio_write(tp, 0x06, 0x4dae);
mdio_write(tp, 0x06, 0x0480);
mdio_write(tp, 0x06, 0xe483);
mdio_write(tp, 0x06, 0x4de0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7803);
mdio_write(tp, 0x06, 0x9e0b);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x049e);
mdio_write(tp, 0x06, 0x04ee);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x02e0);
mdio_write(tp, 0x06, 0x8332);
mdio_write(tp, 0x06, 0xe183);
mdio_write(tp, 0x06, 0x3359);
mdio_write(tp, 0x06, 0x0fe2);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0x0c24);
mdio_write(tp, 0x06, 0x5af0);
mdio_write(tp, 0x06, 0x1e12);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x8ce5);
mdio_write(tp, 0x06, 0xf88d);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x30e1);
mdio_write(tp, 0x06, 0x8331);
mdio_write(tp, 0x06, 0x6801);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x8ae5);
mdio_write(tp, 0x06, 0xf88b);
mdio_write(tp, 0x06, 0xae37);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4e03);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4ce1);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0x1b01);
mdio_write(tp, 0x06, 0x9e04);
mdio_write(tp, 0x06, 0xaaa1);
mdio_write(tp, 0x06, 0xaea8);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4e04);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4f00);
mdio_write(tp, 0x06, 0xaeab);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4f78);
mdio_write(tp, 0x06, 0x039f);
mdio_write(tp, 0x06, 0x14ee);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x05d2);
mdio_write(tp, 0x06, 0x40d6);
mdio_write(tp, 0x06, 0x5554);
mdio_write(tp, 0x06, 0x0282);
mdio_write(tp, 0x06, 0x17d2);
mdio_write(tp, 0x06, 0xa0d6);
mdio_write(tp, 0x06, 0xba00);
mdio_write(tp, 0x06, 0x0282);
mdio_write(tp, 0x06, 0x17fe);
mdio_write(tp, 0x06, 0xfdfc);
mdio_write(tp, 0x06, 0x05f8);
mdio_write(tp, 0x06, 0xe0f8);
mdio_write(tp, 0x06, 0x60e1);
mdio_write(tp, 0x06, 0xf861);
mdio_write(tp, 0x06, 0x6802);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x60e5);
mdio_write(tp, 0x06, 0xf861);
mdio_write(tp, 0x06, 0xe0f8);
mdio_write(tp, 0x06, 0x48e1);
mdio_write(tp, 0x06, 0xf849);
mdio_write(tp, 0x06, 0x580f);
mdio_write(tp, 0x06, 0x1e02);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x48e5);
mdio_write(tp, 0x06, 0xf849);
mdio_write(tp, 0x06, 0xd000);
mdio_write(tp, 0x06, 0x0282);
mdio_write(tp, 0x06, 0x5bbf);
mdio_write(tp, 0x06, 0x8350);
mdio_write(tp, 0x06, 0xef46);
mdio_write(tp, 0x06, 0xdc19);
mdio_write(tp, 0x06, 0xddd0);
mdio_write(tp, 0x06, 0x0102);
mdio_write(tp, 0x06, 0x825b);
mdio_write(tp, 0x06, 0x0282);
mdio_write(tp, 0x06, 0x77e0);
mdio_write(tp, 0x06, 0xf860);
mdio_write(tp, 0x06, 0xe1f8);
mdio_write(tp, 0x06, 0x6158);
mdio_write(tp, 0x06, 0xfde4);
mdio_write(tp, 0x06, 0xf860);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x61fc);
mdio_write(tp, 0x06, 0x04f9);
mdio_write(tp, 0x06, 0xfafb);
mdio_write(tp, 0x06, 0xc6bf);
mdio_write(tp, 0x06, 0xf840);
mdio_write(tp, 0x06, 0xbe83);
mdio_write(tp, 0x06, 0x50a0);
mdio_write(tp, 0x06, 0x0101);
mdio_write(tp, 0x06, 0x071b);
mdio_write(tp, 0x06, 0x89cf);
mdio_write(tp, 0x06, 0xd208);
mdio_write(tp, 0x06, 0xebdb);
mdio_write(tp, 0x06, 0x19b2);
mdio_write(tp, 0x06, 0xfbff);
mdio_write(tp, 0x06, 0xfefd);
mdio_write(tp, 0x06, 0x04f8);
mdio_write(tp, 0x06, 0xe0f8);
mdio_write(tp, 0x06, 0x48e1);
mdio_write(tp, 0x06, 0xf849);
mdio_write(tp, 0x06, 0x6808);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x48e5);
mdio_write(tp, 0x06, 0xf849);
mdio_write(tp, 0x06, 0x58f7);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x48e5);
mdio_write(tp, 0x06, 0xf849);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0x4d20);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x4e22);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x4ddf);
mdio_write(tp, 0x06, 0xff01);
mdio_write(tp, 0x06, 0x4edd);
mdio_write(tp, 0x06, 0xff01);
mdio_write(tp, 0x06, 0xf8fa);
mdio_write(tp, 0x06, 0xfbef);
mdio_write(tp, 0x06, 0x79bf);
mdio_write(tp, 0x06, 0xf822);
mdio_write(tp, 0x06, 0xd819);
mdio_write(tp, 0x06, 0xd958);
mdio_write(tp, 0x06, 0x849f);
mdio_write(tp, 0x06, 0x09bf);
mdio_write(tp, 0x06, 0x82be);
mdio_write(tp, 0x06, 0xd682);
mdio_write(tp, 0x06, 0xc602);
mdio_write(tp, 0x06, 0x014f);
mdio_write(tp, 0x06, 0xef97);
mdio_write(tp, 0x06, 0xfffe);
mdio_write(tp, 0x06, 0xfc05);
mdio_write(tp, 0x06, 0x17ff);
mdio_write(tp, 0x06, 0xfe01);
mdio_write(tp, 0x06, 0x1700);
mdio_write(tp, 0x06, 0x0102);
mdio_write(tp, 0x05, 0x83d8);
mdio_write(tp, 0x06, 0x8051);
mdio_write(tp, 0x05, 0x83d6);
mdio_write(tp, 0x06, 0x82a0);
mdio_write(tp, 0x05, 0x83d4);
mdio_write(tp, 0x06, 0x8000);
mdio_write(tp, 0x02, 0x2010);
mdio_write(tp, 0x03, 0xdc00);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x0b, 0x0600);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x00fc);
mdio_write(tp, 0x1f, 0x0000);
}
spin_unlock_irqrestore(&tp->phy_lock, flags);
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0xF880);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_10) {
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x06, 0x4064);
mdio_write(tp, 0x07, 0x2863);
mdio_write(tp, 0x08, 0x059C);
mdio_write(tp, 0x09, 0x26B4);
mdio_write(tp, 0x0A, 0x6A19);
mdio_write(tp, 0x0B, 0xDCC8);
mdio_write(tp, 0x10, 0xF06D);
mdio_write(tp, 0x14, 0x7F68);
mdio_write(tp, 0x18, 0x7FD9);
mdio_write(tp, 0x1C, 0xF0FF);
mdio_write(tp, 0x1D, 0x3D9C);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x12, 0xF49F);
mdio_write(tp, 0x13, 0x070B);
mdio_write(tp, 0x1A, 0x05AD);
mdio_write(tp, 0x14, 0x94C0);
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x06, 0x5561);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8332);
mdio_write(tp, 0x06, 0x5561);
if (rtl8168_efuse_read(tp, 0x01) == 0xb1) {
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x05, 0x669A);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8330);
mdio_write(tp, 0x06, 0x669A);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x0D);
if ((gphy_val & 0x00FF) != 0x006C) {
gphy_val &= 0xFF00;
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x0D, gphy_val | 0x0065);
mdio_write(tp, 0x0D, gphy_val | 0x0066);
mdio_write(tp, 0x0D, gphy_val | 0x0067);
mdio_write(tp, 0x0D, gphy_val | 0x0068);
mdio_write(tp, 0x0D, gphy_val | 0x0069);
mdio_write(tp, 0x0D, gphy_val | 0x006A);
mdio_write(tp, 0x0D, gphy_val | 0x006B);
mdio_write(tp, 0x0D, gphy_val | 0x006C);
}
} else {
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x05, 0x2642);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x8330);
mdio_write(tp, 0x06, 0x2642);
}
if (rtl8168_efuse_read(tp, 0x30) == 0x98) {
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x11, mdio_read(tp, 0x11) & ~BIT_1);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x01, mdio_read(tp, 0x01) | BIT_9);
} else if (rtl8168_efuse_read(tp, 0x30) == 0x90) {
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x01, mdio_read(tp, 0x01) & ~BIT_9);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x16, 0x5101);
}
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x02);
gphy_val &= ~BIT_10;
gphy_val &= ~BIT_9;
gphy_val |= BIT_8;
mdio_write(tp, 0x02, gphy_val);
gphy_val = mdio_read(tp, 0x03);
gphy_val &= ~BIT_15;
gphy_val &= ~BIT_14;
gphy_val &= ~BIT_13;
mdio_write(tp, 0x03, gphy_val);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x0F);
gphy_val |= BIT_4;
gphy_val |= BIT_2;
gphy_val |= BIT_1;
gphy_val |= BIT_0;
mdio_write(tp, 0x0F, gphy_val);
spin_unlock_irqrestore(&tp->phy_lock, flags);
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x05, 0x001B);
if (mdio_read(tp, 0x06) == 0xB300) {
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x0080);
mdio_write(tp, 0x05, 0x8000);
mdio_write(tp, 0x06, 0xf8f9);
mdio_write(tp, 0x06, 0xfaee);
mdio_write(tp, 0x06, 0xf8ea);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0xf8eb);
mdio_write(tp, 0x06, 0x00e2);
mdio_write(tp, 0x06, 0xf87c);
mdio_write(tp, 0x06, 0xe3f8);
mdio_write(tp, 0x06, 0x7da5);
mdio_write(tp, 0x06, 0x1111);
mdio_write(tp, 0x06, 0x12d2);
mdio_write(tp, 0x06, 0x40d6);
mdio_write(tp, 0x06, 0x4444);
mdio_write(tp, 0x06, 0x0281);
mdio_write(tp, 0x06, 0xc6d2);
mdio_write(tp, 0x06, 0xa0d6);
mdio_write(tp, 0x06, 0xaaaa);
mdio_write(tp, 0x06, 0x0281);
mdio_write(tp, 0x06, 0xc6ae);
mdio_write(tp, 0x06, 0x0fa5);
mdio_write(tp, 0x06, 0x4444);
mdio_write(tp, 0x06, 0x02ae);
mdio_write(tp, 0x06, 0x4da5);
mdio_write(tp, 0x06, 0xaaaa);
mdio_write(tp, 0x06, 0x02ae);
mdio_write(tp, 0x06, 0x47af);
mdio_write(tp, 0x06, 0x81c2);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4e00);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4d0f);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4c0f);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4f00);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x5100);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4aff);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4bff);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x30e1);
mdio_write(tp, 0x06, 0x8331);
mdio_write(tp, 0x06, 0x58fe);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x8ae5);
mdio_write(tp, 0x06, 0xf88b);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x32e1);
mdio_write(tp, 0x06, 0x8333);
mdio_write(tp, 0x06, 0x590f);
mdio_write(tp, 0x06, 0xe283);
mdio_write(tp, 0x06, 0x4d0c);
mdio_write(tp, 0x06, 0x245a);
mdio_write(tp, 0x06, 0xf01e);
mdio_write(tp, 0x06, 0x12e4);
mdio_write(tp, 0x06, 0xf88c);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x8daf);
mdio_write(tp, 0x06, 0x81c2);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4f10);
mdio_write(tp, 0x06, 0xe483);
mdio_write(tp, 0x06, 0x4fe0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7800);
mdio_write(tp, 0x06, 0x9f0a);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4fa0);
mdio_write(tp, 0x06, 0x10a5);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4e01);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x059e);
mdio_write(tp, 0x06, 0x9ae0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7804);
mdio_write(tp, 0x06, 0x9e10);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x039e);
mdio_write(tp, 0x06, 0x0fe0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7801);
mdio_write(tp, 0x06, 0x9e05);
mdio_write(tp, 0x06, 0xae0c);
mdio_write(tp, 0x06, 0xaf81);
mdio_write(tp, 0x06, 0xa7af);
mdio_write(tp, 0x06, 0x8152);
mdio_write(tp, 0x06, 0xaf81);
mdio_write(tp, 0x06, 0x8baf);
mdio_write(tp, 0x06, 0x81c2);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4800);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4900);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x5110);
mdio_write(tp, 0x06, 0xe483);
mdio_write(tp, 0x06, 0x5158);
mdio_write(tp, 0x06, 0x019f);
mdio_write(tp, 0x06, 0xead0);
mdio_write(tp, 0x06, 0x00d1);
mdio_write(tp, 0x06, 0x801f);
mdio_write(tp, 0x06, 0x66e2);
mdio_write(tp, 0x06, 0xf8ea);
mdio_write(tp, 0x06, 0xe3f8);
mdio_write(tp, 0x06, 0xeb5a);
mdio_write(tp, 0x06, 0xf81e);
mdio_write(tp, 0x06, 0x20e6);
mdio_write(tp, 0x06, 0xf8ea);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0xebd3);
mdio_write(tp, 0x06, 0x02b3);
mdio_write(tp, 0x06, 0xfee2);
mdio_write(tp, 0x06, 0xf87c);
mdio_write(tp, 0x06, 0xef32);
mdio_write(tp, 0x06, 0x5b80);
mdio_write(tp, 0x06, 0xe3f8);
mdio_write(tp, 0x06, 0x7d9e);
mdio_write(tp, 0x06, 0x037d);
mdio_write(tp, 0x06, 0xffff);
mdio_write(tp, 0x06, 0x0d58);
mdio_write(tp, 0x06, 0x1c55);
mdio_write(tp, 0x06, 0x1a65);
mdio_write(tp, 0x06, 0x11a1);
mdio_write(tp, 0x06, 0x90d3);
mdio_write(tp, 0x06, 0xe283);
mdio_write(tp, 0x06, 0x48e3);
mdio_write(tp, 0x06, 0x8349);
mdio_write(tp, 0x06, 0x1b56);
mdio_write(tp, 0x06, 0xab08);
mdio_write(tp, 0x06, 0xef56);
mdio_write(tp, 0x06, 0xe683);
mdio_write(tp, 0x06, 0x48e7);
mdio_write(tp, 0x06, 0x8349);
mdio_write(tp, 0x06, 0x10d1);
mdio_write(tp, 0x06, 0x801f);
mdio_write(tp, 0x06, 0x66a0);
mdio_write(tp, 0x06, 0x04b9);
mdio_write(tp, 0x06, 0xe283);
mdio_write(tp, 0x06, 0x48e3);
mdio_write(tp, 0x06, 0x8349);
mdio_write(tp, 0x06, 0xef65);
mdio_write(tp, 0x06, 0xe283);
mdio_write(tp, 0x06, 0x4ae3);
mdio_write(tp, 0x06, 0x834b);
mdio_write(tp, 0x06, 0x1b56);
mdio_write(tp, 0x06, 0xaa0e);
mdio_write(tp, 0x06, 0xef56);
mdio_write(tp, 0x06, 0xe683);
mdio_write(tp, 0x06, 0x4ae7);
mdio_write(tp, 0x06, 0x834b);
mdio_write(tp, 0x06, 0xe283);
mdio_write(tp, 0x06, 0x4de6);
mdio_write(tp, 0x06, 0x834c);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4da0);
mdio_write(tp, 0x06, 0x000c);
mdio_write(tp, 0x06, 0xaf81);
mdio_write(tp, 0x06, 0x8be0);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0x10e4);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0xae04);
mdio_write(tp, 0x06, 0x80e4);
mdio_write(tp, 0x06, 0x834d);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x4e78);
mdio_write(tp, 0x06, 0x039e);
mdio_write(tp, 0x06, 0x0be0);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x7804);
mdio_write(tp, 0x06, 0x9e04);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4e02);
mdio_write(tp, 0x06, 0xe083);
mdio_write(tp, 0x06, 0x32e1);
mdio_write(tp, 0x06, 0x8333);
mdio_write(tp, 0x06, 0x590f);
mdio_write(tp, 0x06, 0xe283);
mdio_write(tp, 0x06, 0x4d0c);
mdio_write(tp, 0x06, 0x245a);
mdio_write(tp, 0x06, 0xf01e);
mdio_write(tp, 0x06, 0x12e4);
mdio_write(tp, 0x06, 0xf88c);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x8de0);
mdio_write(tp, 0x06, 0x8330);
mdio_write(tp, 0x06, 0xe183);
mdio_write(tp, 0x06, 0x3168);
mdio_write(tp, 0x06, 0x01e4);
mdio_write(tp, 0x06, 0xf88a);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x8bae);
mdio_write(tp, 0x06, 0x37ee);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x03e0);
mdio_write(tp, 0x06, 0x834c);
mdio_write(tp, 0x06, 0xe183);
mdio_write(tp, 0x06, 0x4d1b);
mdio_write(tp, 0x06, 0x019e);
mdio_write(tp, 0x06, 0x04aa);
mdio_write(tp, 0x06, 0xa1ae);
mdio_write(tp, 0x06, 0xa8ee);
mdio_write(tp, 0x06, 0x834e);
mdio_write(tp, 0x06, 0x04ee);
mdio_write(tp, 0x06, 0x834f);
mdio_write(tp, 0x06, 0x00ae);
mdio_write(tp, 0x06, 0xabe0);
mdio_write(tp, 0x06, 0x834f);
mdio_write(tp, 0x06, 0x7803);
mdio_write(tp, 0x06, 0x9f14);
mdio_write(tp, 0x06, 0xee83);
mdio_write(tp, 0x06, 0x4e05);
mdio_write(tp, 0x06, 0xd240);
mdio_write(tp, 0x06, 0xd655);
mdio_write(tp, 0x06, 0x5402);
mdio_write(tp, 0x06, 0x81c6);
mdio_write(tp, 0x06, 0xd2a0);
mdio_write(tp, 0x06, 0xd6ba);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x81c6);
mdio_write(tp, 0x06, 0xfefd);
mdio_write(tp, 0x06, 0xfc05);
mdio_write(tp, 0x06, 0xf8e0);
mdio_write(tp, 0x06, 0xf860);
mdio_write(tp, 0x06, 0xe1f8);
mdio_write(tp, 0x06, 0x6168);
mdio_write(tp, 0x06, 0x02e4);
mdio_write(tp, 0x06, 0xf860);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x61e0);
mdio_write(tp, 0x06, 0xf848);
mdio_write(tp, 0x06, 0xe1f8);
mdio_write(tp, 0x06, 0x4958);
mdio_write(tp, 0x06, 0x0f1e);
mdio_write(tp, 0x06, 0x02e4);
mdio_write(tp, 0x06, 0xf848);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x49d0);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x820a);
mdio_write(tp, 0x06, 0xbf83);
mdio_write(tp, 0x06, 0x50ef);
mdio_write(tp, 0x06, 0x46dc);
mdio_write(tp, 0x06, 0x19dd);
mdio_write(tp, 0x06, 0xd001);
mdio_write(tp, 0x06, 0x0282);
mdio_write(tp, 0x06, 0x0a02);
mdio_write(tp, 0x06, 0x8226);
mdio_write(tp, 0x06, 0xe0f8);
mdio_write(tp, 0x06, 0x60e1);
mdio_write(tp, 0x06, 0xf861);
mdio_write(tp, 0x06, 0x58fd);
mdio_write(tp, 0x06, 0xe4f8);
mdio_write(tp, 0x06, 0x60e5);
mdio_write(tp, 0x06, 0xf861);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xf9fa);
mdio_write(tp, 0x06, 0xfbc6);
mdio_write(tp, 0x06, 0xbff8);
mdio_write(tp, 0x06, 0x40be);
mdio_write(tp, 0x06, 0x8350);
mdio_write(tp, 0x06, 0xa001);
mdio_write(tp, 0x06, 0x0107);
mdio_write(tp, 0x06, 0x1b89);
mdio_write(tp, 0x06, 0xcfd2);
mdio_write(tp, 0x06, 0x08eb);
mdio_write(tp, 0x06, 0xdb19);
mdio_write(tp, 0x06, 0xb2fb);
mdio_write(tp, 0x06, 0xfffe);
mdio_write(tp, 0x06, 0xfd04);
mdio_write(tp, 0x06, 0xf8e0);
mdio_write(tp, 0x06, 0xf848);
mdio_write(tp, 0x06, 0xe1f8);
mdio_write(tp, 0x06, 0x4968);
mdio_write(tp, 0x06, 0x08e4);
mdio_write(tp, 0x06, 0xf848);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x4958);
mdio_write(tp, 0x06, 0xf7e4);
mdio_write(tp, 0x06, 0xf848);
mdio_write(tp, 0x06, 0xe5f8);
mdio_write(tp, 0x06, 0x49fc);
mdio_write(tp, 0x06, 0x044d);
mdio_write(tp, 0x06, 0x2000);
mdio_write(tp, 0x06, 0x024e);
mdio_write(tp, 0x06, 0x2200);
mdio_write(tp, 0x06, 0x024d);
mdio_write(tp, 0x06, 0xdfff);
mdio_write(tp, 0x06, 0x014e);
mdio_write(tp, 0x06, 0xddff);
mdio_write(tp, 0x06, 0x01f8);
mdio_write(tp, 0x06, 0xfafb);
mdio_write(tp, 0x06, 0xef79);
mdio_write(tp, 0x06, 0xbff8);
mdio_write(tp, 0x06, 0x22d8);
mdio_write(tp, 0x06, 0x19d9);
mdio_write(tp, 0x06, 0x5884);
mdio_write(tp, 0x06, 0x9f09);
mdio_write(tp, 0x06, 0xbf82);
mdio_write(tp, 0x06, 0x6dd6);
mdio_write(tp, 0x06, 0x8275);
mdio_write(tp, 0x06, 0x0201);
mdio_write(tp, 0x06, 0x4fef);
mdio_write(tp, 0x06, 0x97ff);
mdio_write(tp, 0x06, 0xfefc);
mdio_write(tp, 0x06, 0x0517);
mdio_write(tp, 0x06, 0xfffe);
mdio_write(tp, 0x06, 0x0117);
mdio_write(tp, 0x06, 0x0001);
mdio_write(tp, 0x06, 0x0200);
mdio_write(tp, 0x05, 0x83d8);
mdio_write(tp, 0x06, 0x8000);
mdio_write(tp, 0x05, 0x83d6);
mdio_write(tp, 0x06, 0x824f);
mdio_write(tp, 0x02, 0x2010);
mdio_write(tp, 0x03, 0xdc00);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x0b, 0x0600);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x00fc);
mdio_write(tp, 0x1f, 0x0000);
}
spin_unlock_irqrestore(&tp->phy_lock, flags);
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x0D, 0xF880);
mdio_write(tp, 0x1F, 0x0000);
} else if (tp->mcfg == CFG_METHOD_11) {
mdio_write(tp, 0x1F, 0x0002);
mdio_write(tp, 0x10, 0x0008);
mdio_write(tp, 0x0D, 0x006C);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x0B, 0xA4D8);
mdio_write(tp, 0x09, 0x281C);
mdio_write(tp, 0x07, 0x2883);
mdio_write(tp, 0x0A, 0x6B35);
mdio_write(tp, 0x1D, 0x3DA4);
mdio_write(tp, 0x1C, 0xEFFD);
mdio_write(tp, 0x14, 0x7F52);
mdio_write(tp, 0x18, 0x7FC6);
mdio_write(tp, 0x08, 0x0601);
mdio_write(tp, 0x06, 0x4063);
mdio_write(tp, 0x10, 0xF074);
mdio_write(tp, 0x1F, 0x0003);
mdio_write(tp, 0x13, 0x0789);
mdio_write(tp, 0x12, 0xF4BD);
mdio_write(tp, 0x1A, 0x04FD);
mdio_write(tp, 0x14, 0x84B0);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x00, 0x9200);
mdio_write(tp, 0x1F, 0x0005);
mdio_write(tp, 0x01, 0x0340);
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x04, 0x4000);
mdio_write(tp, 0x03, 0x1D21);
mdio_write(tp, 0x02, 0x0C32);
mdio_write(tp, 0x01, 0x0200);
mdio_write(tp, 0x00, 0x5554);
mdio_write(tp, 0x04, 0x4800);
mdio_write(tp, 0x04, 0x4000);
mdio_write(tp, 0x04, 0xF000);
mdio_write(tp, 0x03, 0xDF01);
mdio_write(tp, 0x02, 0xDF20);
mdio_write(tp, 0x01, 0x101A);
mdio_write(tp, 0x00, 0xA0FF);
mdio_write(tp, 0x04, 0xF800);
mdio_write(tp, 0x04, 0xF000);
mdio_write(tp, 0x1F, 0x0000);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1E, 0x0023);
mdio_write(tp, 0x16, 0x0000);
mdio_write(tp, 0x1F, 0x0000);
gphy_val = mdio_read(tp, 0x0D);
gphy_val |= BIT_5;
mdio_write(tp, 0x0D, gphy_val);
} else if (tp->mcfg == CFG_METHOD_12 || tp->mcfg == CFG_METHOD_13) {
// TO DO:
mdio_write(tp, 0x1F, 0x0001);
mdio_write(tp, 0x17, 0x0CC0);
mdio_write(tp, 0x1F, 0x0007);
mdio_write(tp, 0x1E, 0x002D);
mdio_write(tp, 0x18, 0x0040);
mdio_write(tp, 0x1F, 0x0000);
gphy_val = mdio_read(tp, 0x0D);
gphy_val |= BIT_5;
mdio_write(tp, 0x0D, gphy_val);
mdio_write(tp, 0x1F, 0x0002);
gphy_val = mdio_read(tp, 0x0C);
gphy_val |= BIT_10;
mdio_write(tp, 0x0C, gphy_val);
} else if (tp->mcfg == CFG_METHOD_14 || tp->mcfg == CFG_METHOD_15) {
struct pci_dev *pdev = tp->pci_dev;
spin_unlock_irqrestore(&tp->phy_lock, flags);
RTL_W8(0xF3, RTL_R8(0xF3) | BIT_2);
if (tp->mcfg == CFG_METHOD_14) {
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x00, 0x1800);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0023);
mdio_write(tp, 0x17, 0x0117);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1E, 0x002C);
mdio_write(tp, 0x1B, 0x5000);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x16, 0x4104);
for (i = 0; i < 200; i++) {
udelay(100);
gphy_val = mdio_read(tp, 0x1E);
gphy_val &= 0x03FF;
if (gphy_val == 0x000C)
break;
}
mdio_write(tp, 0x1f, 0x0005);
for (i = 0; i < 200; i++) {
udelay(100);
gphy_val = mdio_read(tp, 0x07);
if ((gphy_val & BIT_5) == 0)
break;
}
gphy_val = mdio_read(tp, 0x07);
if (gphy_val & BIT_5) {
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x00a1);
mdio_write(tp, 0x17, 0x1000);
mdio_write(tp, 0x17, 0x0000);
mdio_write(tp, 0x17, 0x2000);
mdio_write(tp, 0x1e, 0x002f);
mdio_write(tp, 0x18, 0x9bfb);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x07, 0x0000);
mdio_write(tp, 0x1f, 0x0000);
}
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x0080);
gphy_val = mdio_read(tp, 0x00);
gphy_val &= ~(BIT_7);
mdio_write(tp, 0x00, gphy_val);
mdio_write(tp, 0x1f, 0x0002);
gphy_val = mdio_read(tp, 0x08);
gphy_val &= ~(BIT_7);
mdio_write(tp, 0x08, gphy_val);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0023);
mdio_write(tp, 0x16, 0x0306);
mdio_write(tp, 0x16, 0x0307);
mdio_write(tp, 0x15, 0x000e);
mdio_write(tp, 0x19, 0x000a);
mdio_write(tp, 0x15, 0x0010);
mdio_write(tp, 0x19, 0x0008);
mdio_write(tp, 0x15, 0x0018);
mdio_write(tp, 0x19, 0x4801);
mdio_write(tp, 0x15, 0x0019);
mdio_write(tp, 0x19, 0x6801);
mdio_write(tp, 0x15, 0x001a);
mdio_write(tp, 0x19, 0x66a1);
mdio_write(tp, 0x15, 0x001f);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0020);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0021);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0022);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0023);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0024);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0025);
mdio_write(tp, 0x19, 0x64a1);
mdio_write(tp, 0x15, 0x0026);
mdio_write(tp, 0x19, 0x40ea);
mdio_write(tp, 0x15, 0x0027);
mdio_write(tp, 0x19, 0x4503);
mdio_write(tp, 0x15, 0x0028);
mdio_write(tp, 0x19, 0x9f00);
mdio_write(tp, 0x15, 0x0029);
mdio_write(tp, 0x19, 0xa631);
mdio_write(tp, 0x15, 0x002a);
mdio_write(tp, 0x19, 0x9717);
mdio_write(tp, 0x15, 0x002b);
mdio_write(tp, 0x19, 0x302c);
mdio_write(tp, 0x15, 0x002c);
mdio_write(tp, 0x19, 0x4802);
mdio_write(tp, 0x15, 0x002d);
mdio_write(tp, 0x19, 0x58da);
mdio_write(tp, 0x15, 0x002e);
mdio_write(tp, 0x19, 0x400d);
mdio_write(tp, 0x15, 0x002f);
mdio_write(tp, 0x19, 0x4488);
mdio_write(tp, 0x15, 0x0030);
mdio_write(tp, 0x19, 0x9e00);
mdio_write(tp, 0x15, 0x0031);
mdio_write(tp, 0x19, 0x63c8);
mdio_write(tp, 0x15, 0x0032);
mdio_write(tp, 0x19, 0x6481);
mdio_write(tp, 0x15, 0x0033);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0034);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0035);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0036);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0037);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0038);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0039);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x003a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x003b);
mdio_write(tp, 0x19, 0x63e8);
mdio_write(tp, 0x15, 0x003c);
mdio_write(tp, 0x19, 0x7d00);
mdio_write(tp, 0x15, 0x003d);
mdio_write(tp, 0x19, 0x59d4);
mdio_write(tp, 0x15, 0x003e);
mdio_write(tp, 0x19, 0x63f8);
mdio_write(tp, 0x15, 0x0040);
mdio_write(tp, 0x19, 0x64a1);
mdio_write(tp, 0x15, 0x0041);
mdio_write(tp, 0x19, 0x30de);
mdio_write(tp, 0x15, 0x0044);
mdio_write(tp, 0x19, 0x480f);
mdio_write(tp, 0x15, 0x0045);
mdio_write(tp, 0x19, 0x6800);
mdio_write(tp, 0x15, 0x0046);
mdio_write(tp, 0x19, 0x6680);
mdio_write(tp, 0x15, 0x0047);
mdio_write(tp, 0x19, 0x7c10);
mdio_write(tp, 0x15, 0x0048);
mdio_write(tp, 0x19, 0x63c8);
mdio_write(tp, 0x15, 0x0049);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004b);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004c);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004d);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004e);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004f);
mdio_write(tp, 0x19, 0x40ea);
mdio_write(tp, 0x15, 0x0050);
mdio_write(tp, 0x19, 0x4503);
mdio_write(tp, 0x15, 0x0051);
mdio_write(tp, 0x19, 0x58ca);
mdio_write(tp, 0x15, 0x0052);
mdio_write(tp, 0x19, 0x63c8);
mdio_write(tp, 0x15, 0x0053);
mdio_write(tp, 0x19, 0x63d8);
mdio_write(tp, 0x15, 0x0054);
mdio_write(tp, 0x19, 0x66a0);
mdio_write(tp, 0x15, 0x0055);
mdio_write(tp, 0x19, 0x9f00);
mdio_write(tp, 0x15, 0x0056);
mdio_write(tp, 0x19, 0x3000);
mdio_write(tp, 0x15, 0x006E);
mdio_write(tp, 0x19, 0x9afa);
mdio_write(tp, 0x15, 0x00a1);
mdio_write(tp, 0x19, 0x3044);
mdio_write(tp, 0x15, 0x00ab);
mdio_write(tp, 0x19, 0x5820);
mdio_write(tp, 0x15, 0x00ac);
mdio_write(tp, 0x19, 0x5e04);
mdio_write(tp, 0x15, 0x00ad);
mdio_write(tp, 0x19, 0xb60c);
mdio_write(tp, 0x15, 0x00af);
mdio_write(tp, 0x19, 0x000a);
mdio_write(tp, 0x15, 0x00b2);
mdio_write(tp, 0x19, 0x30b9);
mdio_write(tp, 0x15, 0x00b9);
mdio_write(tp, 0x19, 0x4408);
mdio_write(tp, 0x15, 0x00ba);
mdio_write(tp, 0x19, 0x480b);
mdio_write(tp, 0x15, 0x00bb);
mdio_write(tp, 0x19, 0x5e00);
mdio_write(tp, 0x15, 0x00bc);
mdio_write(tp, 0x19, 0x405f);
mdio_write(tp, 0x15, 0x00bd);
mdio_write(tp, 0x19, 0x4448);
mdio_write(tp, 0x15, 0x00be);
mdio_write(tp, 0x19, 0x4020);
mdio_write(tp, 0x15, 0x00bf);
mdio_write(tp, 0x19, 0x4468);
mdio_write(tp, 0x15, 0x00c0);
mdio_write(tp, 0x19, 0x9c02);
mdio_write(tp, 0x15, 0x00c1);
mdio_write(tp, 0x19, 0x58a0);
mdio_write(tp, 0x15, 0x00c2);
mdio_write(tp, 0x19, 0xb605);
mdio_write(tp, 0x15, 0x00c3);
mdio_write(tp, 0x19, 0xc0d3);
mdio_write(tp, 0x15, 0x00c4);
mdio_write(tp, 0x19, 0x00e6);
mdio_write(tp, 0x15, 0x00c5);
mdio_write(tp, 0x19, 0xdaec);
mdio_write(tp, 0x15, 0x00c6);
mdio_write(tp, 0x19, 0x00fa);
mdio_write(tp, 0x15, 0x00c7);
mdio_write(tp, 0x19, 0x9df9);
mdio_write(tp, 0x15, 0x00c8);
mdio_write(tp, 0x19, 0x307a);
mdio_write(tp, 0x15, 0x0112);
mdio_write(tp, 0x19, 0x6421);
mdio_write(tp, 0x15, 0x0113);
mdio_write(tp, 0x19, 0x7c08);
mdio_write(tp, 0x15, 0x0114);
mdio_write(tp, 0x19, 0x63f0);
mdio_write(tp, 0x15, 0x0115);
mdio_write(tp, 0x19, 0x4003);
mdio_write(tp, 0x15, 0x0116);
mdio_write(tp, 0x19, 0x4418);
mdio_write(tp, 0x15, 0x0117);
mdio_write(tp, 0x19, 0x9b00);
mdio_write(tp, 0x15, 0x0118);
mdio_write(tp, 0x19, 0x6461);
mdio_write(tp, 0x15, 0x0119);
mdio_write(tp, 0x19, 0x64e1);
mdio_write(tp, 0x15, 0x011a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0150);
mdio_write(tp, 0x19, 0x7c80);
mdio_write(tp, 0x15, 0x0151);
mdio_write(tp, 0x19, 0x6461);
mdio_write(tp, 0x15, 0x0152);
mdio_write(tp, 0x19, 0x4003);
mdio_write(tp, 0x15, 0x0153);
mdio_write(tp, 0x19, 0x4540);
mdio_write(tp, 0x15, 0x0154);
mdio_write(tp, 0x19, 0x9f00);
mdio_write(tp, 0x15, 0x0155);
mdio_write(tp, 0x19, 0x9d00);
mdio_write(tp, 0x15, 0x0156);
mdio_write(tp, 0x19, 0x7c40);
mdio_write(tp, 0x15, 0x0157);
mdio_write(tp, 0x19, 0x6421);
mdio_write(tp, 0x15, 0x0158);
mdio_write(tp, 0x19, 0x7c80);
mdio_write(tp, 0x15, 0x0159);
mdio_write(tp, 0x19, 0x64a1);
mdio_write(tp, 0x15, 0x015a);
mdio_write(tp, 0x19, 0x30fe);
mdio_write(tp, 0x15, 0x021e);
mdio_write(tp, 0x19, 0x5410);
mdio_write(tp, 0x15, 0x0225);
mdio_write(tp, 0x19, 0x5400);
mdio_write(tp, 0x15, 0x023D);
mdio_write(tp, 0x19, 0x4050);
mdio_write(tp, 0x15, 0x0295);
mdio_write(tp, 0x19, 0x6c08);
mdio_write(tp, 0x15, 0x02bd);
mdio_write(tp, 0x19, 0xa523);
mdio_write(tp, 0x15, 0x02be);
mdio_write(tp, 0x19, 0x32ca);
mdio_write(tp, 0x15, 0x02ca);
mdio_write(tp, 0x19, 0x48b3);
mdio_write(tp, 0x15, 0x02cb);
mdio_write(tp, 0x19, 0x4020);
mdio_write(tp, 0x15, 0x02cc);
mdio_write(tp, 0x19, 0x4823);
mdio_write(tp, 0x15, 0x02cd);
mdio_write(tp, 0x19, 0x4510);
mdio_write(tp, 0x15, 0x02ce);
mdio_write(tp, 0x19, 0xb63a);
mdio_write(tp, 0x15, 0x02cf);
mdio_write(tp, 0x19, 0x7dc8);
mdio_write(tp, 0x15, 0x02d6);
mdio_write(tp, 0x19, 0x9bf8);
mdio_write(tp, 0x15, 0x02d8);
mdio_write(tp, 0x19, 0x85f6);
mdio_write(tp, 0x15, 0x02d9);
mdio_write(tp, 0x19, 0x32e0);
mdio_write(tp, 0x15, 0x02e0);
mdio_write(tp, 0x19, 0x4834);
mdio_write(tp, 0x15, 0x02e1);
mdio_write(tp, 0x19, 0x6c08);
mdio_write(tp, 0x15, 0x02e2);
mdio_write(tp, 0x19, 0x4020);
mdio_write(tp, 0x15, 0x02e3);
mdio_write(tp, 0x19, 0x4824);
mdio_write(tp, 0x15, 0x02e4);
mdio_write(tp, 0x19, 0x4520);
mdio_write(tp, 0x15, 0x02e5);
mdio_write(tp, 0x19, 0x4008);
mdio_write(tp, 0x15, 0x02e6);
mdio_write(tp, 0x19, 0x4560);
mdio_write(tp, 0x15, 0x02e7);
mdio_write(tp, 0x19, 0x9d04);
mdio_write(tp, 0x15, 0x02e8);
mdio_write(tp, 0x19, 0x48c4);
mdio_write(tp, 0x15, 0x02e9);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x02ea);
mdio_write(tp, 0x19, 0x4844);
mdio_write(tp, 0x15, 0x02eb);
mdio_write(tp, 0x19, 0x7dc8);
mdio_write(tp, 0x15, 0x02f0);
mdio_write(tp, 0x19, 0x9cf7);
mdio_write(tp, 0x15, 0x02f1);
mdio_write(tp, 0x19, 0xdf94);
mdio_write(tp, 0x15, 0x02f2);
mdio_write(tp, 0x19, 0x0002);
mdio_write(tp, 0x15, 0x02f3);
mdio_write(tp, 0x19, 0x6810);
mdio_write(tp, 0x15, 0x02f4);
mdio_write(tp, 0x19, 0xb614);
mdio_write(tp, 0x15, 0x02f5);
mdio_write(tp, 0x19, 0xc42b);
mdio_write(tp, 0x15, 0x02f6);
mdio_write(tp, 0x19, 0x00d4);
mdio_write(tp, 0x15, 0x02f7);
mdio_write(tp, 0x19, 0xc455);
mdio_write(tp, 0x15, 0x02f8);
mdio_write(tp, 0x19, 0x0093);
mdio_write(tp, 0x15, 0x02f9);
mdio_write(tp, 0x19, 0x92ee);
mdio_write(tp, 0x15, 0x02fa);
mdio_write(tp, 0x19, 0xefed);
mdio_write(tp, 0x15, 0x02fb);
mdio_write(tp, 0x19, 0x3312);
mdio_write(tp, 0x15, 0x0312);
mdio_write(tp, 0x19, 0x49b5);
mdio_write(tp, 0x15, 0x0313);
mdio_write(tp, 0x19, 0x7d00);
mdio_write(tp, 0x15, 0x0314);
mdio_write(tp, 0x19, 0x4d00);
mdio_write(tp, 0x15, 0x0315);
mdio_write(tp, 0x19, 0x6810);
mdio_write(tp, 0x15, 0x031e);
mdio_write(tp, 0x19, 0x404f);
mdio_write(tp, 0x15, 0x031f);
mdio_write(tp, 0x19, 0x44c8);
mdio_write(tp, 0x15, 0x0320);
mdio_write(tp, 0x19, 0xd64f);
mdio_write(tp, 0x15, 0x0321);
mdio_write(tp, 0x19, 0x00e7);
mdio_write(tp, 0x15, 0x0322);
mdio_write(tp, 0x19, 0x7c08);
mdio_write(tp, 0x15, 0x0323);
mdio_write(tp, 0x19, 0x8203);
mdio_write(tp, 0x15, 0x0324);
mdio_write(tp, 0x19, 0x4d48);
mdio_write(tp, 0x15, 0x0325);
mdio_write(tp, 0x19, 0x3327);
mdio_write(tp, 0x15, 0x0326);
mdio_write(tp, 0x19, 0x4d40);
mdio_write(tp, 0x15, 0x0327);
mdio_write(tp, 0x19, 0xc8d7);
mdio_write(tp, 0x15, 0x0328);
mdio_write(tp, 0x19, 0x0003);
mdio_write(tp, 0x15, 0x0329);
mdio_write(tp, 0x19, 0x7c20);
mdio_write(tp, 0x15, 0x032a);
mdio_write(tp, 0x19, 0x4c20);
mdio_write(tp, 0x15, 0x032b);
mdio_write(tp, 0x19, 0xc8ed);
mdio_write(tp, 0x15, 0x032c);
mdio_write(tp, 0x19, 0x00f4);
mdio_write(tp, 0x15, 0x032d);
mdio_write(tp, 0x19, 0x82b3);
mdio_write(tp, 0x15, 0x032e);
mdio_write(tp, 0x19, 0xd11d);
mdio_write(tp, 0x15, 0x032f);
mdio_write(tp, 0x19, 0x00b1);
mdio_write(tp, 0x15, 0x0330);
mdio_write(tp, 0x19, 0xde18);
mdio_write(tp, 0x15, 0x0331);
mdio_write(tp, 0x19, 0x0008);
mdio_write(tp, 0x15, 0x0332);
mdio_write(tp, 0x19, 0x91ee);
mdio_write(tp, 0x15, 0x0333);
mdio_write(tp, 0x19, 0x3339);
mdio_write(tp, 0x15, 0x033a);
mdio_write(tp, 0x19, 0x4064);
mdio_write(tp, 0x15, 0x0340);
mdio_write(tp, 0x19, 0x9e06);
mdio_write(tp, 0x15, 0x0341);
mdio_write(tp, 0x19, 0x7c08);
mdio_write(tp, 0x15, 0x0342);
mdio_write(tp, 0x19, 0x8203);
mdio_write(tp, 0x15, 0x0343);
mdio_write(tp, 0x19, 0x4d48);
mdio_write(tp, 0x15, 0x0344);
mdio_write(tp, 0x19, 0x3346);
mdio_write(tp, 0x15, 0x0345);
mdio_write(tp, 0x19, 0x4d40);
mdio_write(tp, 0x15, 0x0346);
mdio_write(tp, 0x19, 0xd11d);
mdio_write(tp, 0x15, 0x0347);
mdio_write(tp, 0x19, 0x0099);
mdio_write(tp, 0x15, 0x0348);
mdio_write(tp, 0x19, 0xbb17);
mdio_write(tp, 0x15, 0x0349);
mdio_write(tp, 0x19, 0x8102);
mdio_write(tp, 0x15, 0x034a);
mdio_write(tp, 0x19, 0x334d);
mdio_write(tp, 0x15, 0x034b);
mdio_write(tp, 0x19, 0xa22c);
mdio_write(tp, 0x15, 0x034c);
mdio_write(tp, 0x19, 0x3397);
mdio_write(tp, 0x15, 0x034d);
mdio_write(tp, 0x19, 0x91f2);
mdio_write(tp, 0x15, 0x034e);
mdio_write(tp, 0x19, 0xc218);
mdio_write(tp, 0x15, 0x034f);
mdio_write(tp, 0x19, 0x00f0);
mdio_write(tp, 0x15, 0x0350);
mdio_write(tp, 0x19, 0x3397);
mdio_write(tp, 0x15, 0x0351);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0364);
mdio_write(tp, 0x19, 0xbc05);
mdio_write(tp, 0x15, 0x0367);
mdio_write(tp, 0x19, 0xa1fc);
mdio_write(tp, 0x15, 0x0368);
mdio_write(tp, 0x19, 0x3377);
mdio_write(tp, 0x15, 0x0369);
mdio_write(tp, 0x19, 0x328b);
mdio_write(tp, 0x15, 0x036a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0377);
mdio_write(tp, 0x19, 0x4b97);
mdio_write(tp, 0x15, 0x0378);
mdio_write(tp, 0x19, 0x6818);
mdio_write(tp, 0x15, 0x0379);
mdio_write(tp, 0x19, 0x4b07);
mdio_write(tp, 0x15, 0x037a);
mdio_write(tp, 0x19, 0x40ac);
mdio_write(tp, 0x15, 0x037b);
mdio_write(tp, 0x19, 0x4445);
mdio_write(tp, 0x15, 0x037c);
mdio_write(tp, 0x19, 0x404e);
mdio_write(tp, 0x15, 0x037d);
mdio_write(tp, 0x19, 0x4461);
mdio_write(tp, 0x15, 0x037e);
mdio_write(tp, 0x19, 0x9c09);
mdio_write(tp, 0x15, 0x037f);
mdio_write(tp, 0x19, 0x63da);
mdio_write(tp, 0x15, 0x0380);
mdio_write(tp, 0x19, 0x5440);
mdio_write(tp, 0x15, 0x0381);
mdio_write(tp, 0x19, 0x4b98);
mdio_write(tp, 0x15, 0x0382);
mdio_write(tp, 0x19, 0x7c60);
mdio_write(tp, 0x15, 0x0383);
mdio_write(tp, 0x19, 0x4c00);
mdio_write(tp, 0x15, 0x0384);
mdio_write(tp, 0x19, 0x4b08);
mdio_write(tp, 0x15, 0x0385);
mdio_write(tp, 0x19, 0x63d8);
mdio_write(tp, 0x15, 0x0386);
mdio_write(tp, 0x19, 0x338d);
mdio_write(tp, 0x15, 0x0387);
mdio_write(tp, 0x19, 0xd64f);
mdio_write(tp, 0x15, 0x0388);
mdio_write(tp, 0x19, 0x0080);
mdio_write(tp, 0x15, 0x0389);
mdio_write(tp, 0x19, 0x820c);
mdio_write(tp, 0x15, 0x038a);
mdio_write(tp, 0x19, 0xa10b);
mdio_write(tp, 0x15, 0x038b);
mdio_write(tp, 0x19, 0x9df3);
mdio_write(tp, 0x15, 0x038c);
mdio_write(tp, 0x19, 0x3395);
mdio_write(tp, 0x15, 0x038d);
mdio_write(tp, 0x19, 0xd64f);
mdio_write(tp, 0x15, 0x038e);
mdio_write(tp, 0x19, 0x00f9);
mdio_write(tp, 0x15, 0x038f);
mdio_write(tp, 0x19, 0xc017);
mdio_write(tp, 0x15, 0x0390);
mdio_write(tp, 0x19, 0x0005);
mdio_write(tp, 0x15, 0x0391);
mdio_write(tp, 0x19, 0x6c0b);
mdio_write(tp, 0x15, 0x0392);
mdio_write(tp, 0x19, 0xa103);
mdio_write(tp, 0x15, 0x0393);
mdio_write(tp, 0x19, 0x6c08);
mdio_write(tp, 0x15, 0x0394);
mdio_write(tp, 0x19, 0x9df9);
mdio_write(tp, 0x15, 0x0395);
mdio_write(tp, 0x19, 0x6c08);
mdio_write(tp, 0x15, 0x0396);
mdio_write(tp, 0x19, 0x3397);
mdio_write(tp, 0x15, 0x0399);
mdio_write(tp, 0x19, 0x6810);
mdio_write(tp, 0x15, 0x03a4);
mdio_write(tp, 0x19, 0x7c08);
mdio_write(tp, 0x15, 0x03a5);
mdio_write(tp, 0x19, 0x8203);
mdio_write(tp, 0x15, 0x03a6);
mdio_write(tp, 0x19, 0x4d08);
mdio_write(tp, 0x15, 0x03a7);
mdio_write(tp, 0x19, 0x33a9);
mdio_write(tp, 0x15, 0x03a8);
mdio_write(tp, 0x19, 0x4d00);
mdio_write(tp, 0x15, 0x03a9);
mdio_write(tp, 0x19, 0x9bfa);
mdio_write(tp, 0x15, 0x03aa);
mdio_write(tp, 0x19, 0x33b6);
mdio_write(tp, 0x15, 0x03bb);
mdio_write(tp, 0x19, 0x4056);
mdio_write(tp, 0x15, 0x03bc);
mdio_write(tp, 0x19, 0x44e9);
mdio_write(tp, 0x15, 0x03bd);
mdio_write(tp, 0x19, 0x405e);
mdio_write(tp, 0x15, 0x03be);
mdio_write(tp, 0x19, 0x44f8);
mdio_write(tp, 0x15, 0x03bf);
mdio_write(tp, 0x19, 0xd64f);
mdio_write(tp, 0x15, 0x03c0);
mdio_write(tp, 0x19, 0x0037);
mdio_write(tp, 0x15, 0x03c1);
mdio_write(tp, 0x19, 0xbd37);
mdio_write(tp, 0x15, 0x03c2);
mdio_write(tp, 0x19, 0x9cfd);
mdio_write(tp, 0x15, 0x03c3);
mdio_write(tp, 0x19, 0xc639);
mdio_write(tp, 0x15, 0x03c4);
mdio_write(tp, 0x19, 0x0011);
mdio_write(tp, 0x15, 0x03c5);
mdio_write(tp, 0x19, 0x9b03);
mdio_write(tp, 0x15, 0x03c6);
mdio_write(tp, 0x19, 0x7c01);
mdio_write(tp, 0x15, 0x03c7);
mdio_write(tp, 0x19, 0x4c01);
mdio_write(tp, 0x15, 0x03c8);
mdio_write(tp, 0x19, 0x9e03);
mdio_write(tp, 0x15, 0x03c9);
mdio_write(tp, 0x19, 0x7c20);
mdio_write(tp, 0x15, 0x03ca);
mdio_write(tp, 0x19, 0x4c20);
mdio_write(tp, 0x15, 0x03cb);
mdio_write(tp, 0x19, 0x9af4);
mdio_write(tp, 0x15, 0x03cc);
mdio_write(tp, 0x19, 0x7c12);
mdio_write(tp, 0x15, 0x03cd);
mdio_write(tp, 0x19, 0x4c52);
mdio_write(tp, 0x15, 0x03ce);
mdio_write(tp, 0x19, 0x4470);
mdio_write(tp, 0x15, 0x03cf);
mdio_write(tp, 0x19, 0x7c12);
mdio_write(tp, 0x15, 0x03d0);
mdio_write(tp, 0x19, 0x4c40);
mdio_write(tp, 0x15, 0x03d1);
mdio_write(tp, 0x19, 0x33bf);
mdio_write(tp, 0x15, 0x03d6);
mdio_write(tp, 0x19, 0x4047);
mdio_write(tp, 0x15, 0x03d7);
mdio_write(tp, 0x19, 0x4469);
mdio_write(tp, 0x15, 0x03d8);
mdio_write(tp, 0x19, 0x492b);
mdio_write(tp, 0x15, 0x03d9);
mdio_write(tp, 0x19, 0x4479);
mdio_write(tp, 0x15, 0x03da);
mdio_write(tp, 0x19, 0x7c09);
mdio_write(tp, 0x15, 0x03db);
mdio_write(tp, 0x19, 0x8203);
mdio_write(tp, 0x15, 0x03dc);
mdio_write(tp, 0x19, 0x4d48);
mdio_write(tp, 0x15, 0x03dd);
mdio_write(tp, 0x19, 0x33df);
mdio_write(tp, 0x15, 0x03de);
mdio_write(tp, 0x19, 0x4d40);
mdio_write(tp, 0x15, 0x03df);
mdio_write(tp, 0x19, 0xd64f);
mdio_write(tp, 0x15, 0x03e0);
mdio_write(tp, 0x19, 0x0017);
mdio_write(tp, 0x15, 0x03e1);
mdio_write(tp, 0x19, 0xbd17);
mdio_write(tp, 0x15, 0x03e2);
mdio_write(tp, 0x19, 0x9b03);
mdio_write(tp, 0x15, 0x03e3);
mdio_write(tp, 0x19, 0x7c20);
mdio_write(tp, 0x15, 0x03e4);
mdio_write(tp, 0x19, 0x4c20);
mdio_write(tp, 0x15, 0x03e5);
mdio_write(tp, 0x19, 0x88f5);
mdio_write(tp, 0x15, 0x03e6);
mdio_write(tp, 0x19, 0xc428);
mdio_write(tp, 0x15, 0x03e7);
mdio_write(tp, 0x19, 0x0008);
mdio_write(tp, 0x15, 0x03e8);
mdio_write(tp, 0x19, 0x9af2);
mdio_write(tp, 0x15, 0x03e9);
mdio_write(tp, 0x19, 0x7c12);
mdio_write(tp, 0x15, 0x03ea);
mdio_write(tp, 0x19, 0x4c52);
mdio_write(tp, 0x15, 0x03eb);
mdio_write(tp, 0x19, 0x4470);
mdio_write(tp, 0x15, 0x03ec);
mdio_write(tp, 0x19, 0x7c12);
mdio_write(tp, 0x15, 0x03ed);
mdio_write(tp, 0x19, 0x4c40);
mdio_write(tp, 0x15, 0x03ee);
mdio_write(tp, 0x19, 0x33da);
mdio_write(tp, 0x15, 0x03ef);
mdio_write(tp, 0x19, 0x3312);
mdio_write(tp, 0x16, 0x0306);
mdio_write(tp, 0x16, 0x0300);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x17, 0x2179);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0040);
mdio_write(tp, 0x18, 0x0645);
mdio_write(tp, 0x19, 0xe200);
mdio_write(tp, 0x18, 0x0655);
mdio_write(tp, 0x19, 0x9000);
mdio_write(tp, 0x18, 0x0d05);
mdio_write(tp, 0x19, 0xbe00);
mdio_write(tp, 0x18, 0x0d15);
mdio_write(tp, 0x19, 0xd300);
mdio_write(tp, 0x18, 0x0d25);
mdio_write(tp, 0x19, 0xfe00);
mdio_write(tp, 0x18, 0x0d35);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x0d45);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x0d55);
mdio_write(tp, 0x19, 0x1000);
mdio_write(tp, 0x18, 0x0d65);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x0d75);
mdio_write(tp, 0x19, 0x8200);
mdio_write(tp, 0x18, 0x0d85);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x0d95);
mdio_write(tp, 0x19, 0x7000);
mdio_write(tp, 0x18, 0x0da5);
mdio_write(tp, 0x19, 0x0f00);
mdio_write(tp, 0x18, 0x0db5);
mdio_write(tp, 0x19, 0x0100);
mdio_write(tp, 0x18, 0x0dc5);
mdio_write(tp, 0x19, 0x9b00);
mdio_write(tp, 0x18, 0x0dd5);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x0de5);
mdio_write(tp, 0x19, 0xe000);
mdio_write(tp, 0x18, 0x0df5);
mdio_write(tp, 0x19, 0xef00);
mdio_write(tp, 0x18, 0x16d5);
mdio_write(tp, 0x19, 0xe200);
mdio_write(tp, 0x18, 0x16e5);
mdio_write(tp, 0x19, 0xab00);
mdio_write(tp, 0x18, 0x2904);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x2914);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x2924);
mdio_write(tp, 0x19, 0x0100);
mdio_write(tp, 0x18, 0x2934);
mdio_write(tp, 0x19, 0x2000);
mdio_write(tp, 0x18, 0x2944);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2954);
mdio_write(tp, 0x19, 0x4600);
mdio_write(tp, 0x18, 0x2964);
mdio_write(tp, 0x19, 0xfc00);
mdio_write(tp, 0x18, 0x2974);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2984);
mdio_write(tp, 0x19, 0x5000);
mdio_write(tp, 0x18, 0x2994);
mdio_write(tp, 0x19, 0x9d00);
mdio_write(tp, 0x18, 0x29a4);
mdio_write(tp, 0x19, 0xff00);
mdio_write(tp, 0x18, 0x29b4);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x29c4);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x29d4);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x29e4);
mdio_write(tp, 0x19, 0x2000);
mdio_write(tp, 0x18, 0x29f4);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2a04);
mdio_write(tp, 0x19, 0xe600);
mdio_write(tp, 0x18, 0x2a14);
mdio_write(tp, 0x19, 0xff00);
mdio_write(tp, 0x18, 0x2a24);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2a34);
mdio_write(tp, 0x19, 0x5000);
mdio_write(tp, 0x18, 0x2a44);
mdio_write(tp, 0x19, 0x8500);
mdio_write(tp, 0x18, 0x2a54);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x2a64);
mdio_write(tp, 0x19, 0xac00);
mdio_write(tp, 0x18, 0x2a74);
mdio_write(tp, 0x19, 0x0800);
mdio_write(tp, 0x18, 0x2a84);
mdio_write(tp, 0x19, 0xfc00);
mdio_write(tp, 0x18, 0x2a94);
mdio_write(tp, 0x19, 0xe000);
mdio_write(tp, 0x18, 0x2aa4);
mdio_write(tp, 0x19, 0x7400);
mdio_write(tp, 0x18, 0x2ab4);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x2ac4);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x2ad4);
mdio_write(tp, 0x19, 0x0100);
mdio_write(tp, 0x18, 0x2ae4);
mdio_write(tp, 0x19, 0xff00);
mdio_write(tp, 0x18, 0x2af4);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2b04);
mdio_write(tp, 0x19, 0x4400);
mdio_write(tp, 0x18, 0x2b14);
mdio_write(tp, 0x19, 0xfc00);
mdio_write(tp, 0x18, 0x2b24);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2b34);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x2b44);
mdio_write(tp, 0x19, 0x9d00);
mdio_write(tp, 0x18, 0x2b54);
mdio_write(tp, 0x19, 0xff00);
mdio_write(tp, 0x18, 0x2b64);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x2b74);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x2b84);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2b94);
mdio_write(tp, 0x19, 0xff00);
mdio_write(tp, 0x18, 0x2ba4);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2bb4);
mdio_write(tp, 0x19, 0xfc00);
mdio_write(tp, 0x18, 0x2bc4);
mdio_write(tp, 0x19, 0xff00);
mdio_write(tp, 0x18, 0x2bd4);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2be4);
mdio_write(tp, 0x19, 0x4000);
mdio_write(tp, 0x18, 0x2bf4);
mdio_write(tp, 0x19, 0x8900);
mdio_write(tp, 0x18, 0x2c04);
mdio_write(tp, 0x19, 0x8300);
mdio_write(tp, 0x18, 0x2c14);
mdio_write(tp, 0x19, 0xe000);
mdio_write(tp, 0x18, 0x2c24);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x18, 0x2c34);
mdio_write(tp, 0x19, 0xac00);
mdio_write(tp, 0x18, 0x2c44);
mdio_write(tp, 0x19, 0x0800);
mdio_write(tp, 0x18, 0x2c54);
mdio_write(tp, 0x19, 0xfa00);
mdio_write(tp, 0x18, 0x2c64);
mdio_write(tp, 0x19, 0xe100);
mdio_write(tp, 0x18, 0x2c74);
mdio_write(tp, 0x19, 0x7f00);
mdio_write(tp, 0x18, 0x0001);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x17, 0x2100);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x0080);
mdio_write(tp, 0x05, 0x8b88);
mdio_write(tp, 0x06, 0x0000);
mdio_write(tp, 0x06, 0x0000);
mdio_write(tp, 0x06, 0x0000);
mdio_write(tp, 0x06, 0x0000);
mdio_write(tp, 0x05, 0x8000);
mdio_write(tp, 0x06, 0xd480);
mdio_write(tp, 0x06, 0xc1e4);
mdio_write(tp, 0x06, 0x8b9a);
mdio_write(tp, 0x06, 0xe58b);
mdio_write(tp, 0x06, 0x9bee);
mdio_write(tp, 0x06, 0x8b83);
mdio_write(tp, 0x06, 0x41bf);
mdio_write(tp, 0x06, 0x8b88);
mdio_write(tp, 0x06, 0xec00);
mdio_write(tp, 0x06, 0x19a9);
mdio_write(tp, 0x06, 0x8b90);
mdio_write(tp, 0x06, 0xf9ee);
mdio_write(tp, 0x06, 0xfff6);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0xfff7);
mdio_write(tp, 0x06, 0xffe0);
mdio_write(tp, 0x06, 0xe140);
mdio_write(tp, 0x06, 0xe1e1);
mdio_write(tp, 0x06, 0x41f7);
mdio_write(tp, 0x06, 0x2ff6);
mdio_write(tp, 0x06, 0x28e4);
mdio_write(tp, 0x06, 0xe140);
mdio_write(tp, 0x06, 0xe5e1);
mdio_write(tp, 0x06, 0x41f7);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x020c);
mdio_write(tp, 0x06, 0x0202);
mdio_write(tp, 0x06, 0x1d02);
mdio_write(tp, 0x06, 0x0230);
mdio_write(tp, 0x06, 0x0202);
mdio_write(tp, 0x06, 0x4002);
mdio_write(tp, 0x06, 0x028b);
mdio_write(tp, 0x06, 0x0280);
mdio_write(tp, 0x06, 0x6c02);
mdio_write(tp, 0x06, 0x8085);
mdio_write(tp, 0x06, 0xe08b);
mdio_write(tp, 0x06, 0x88e1);
mdio_write(tp, 0x06, 0x8b89);
mdio_write(tp, 0x06, 0x1e01);
mdio_write(tp, 0x06, 0xe18b);
mdio_write(tp, 0x06, 0x8a1e);
mdio_write(tp, 0x06, 0x01e1);
mdio_write(tp, 0x06, 0x8b8b);
mdio_write(tp, 0x06, 0x1e01);
mdio_write(tp, 0x06, 0xe18b);
mdio_write(tp, 0x06, 0x8c1e);
mdio_write(tp, 0x06, 0x01e1);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0x1e01);
mdio_write(tp, 0x06, 0xe18b);
mdio_write(tp, 0x06, 0x8e1e);
mdio_write(tp, 0x06, 0x01a0);
mdio_write(tp, 0x06, 0x00c7);
mdio_write(tp, 0x06, 0xaec3);
mdio_write(tp, 0x06, 0xf8e0);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0xad20);
mdio_write(tp, 0x06, 0x10ee);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x1310);
mdio_write(tp, 0x06, 0x021f);
mdio_write(tp, 0x06, 0x9d02);
mdio_write(tp, 0x06, 0x1f0c);
mdio_write(tp, 0x06, 0x0227);
mdio_write(tp, 0x06, 0x49fc);
mdio_write(tp, 0x06, 0x04f8);
mdio_write(tp, 0x06, 0xe08b);
mdio_write(tp, 0x06, 0x8ead);
mdio_write(tp, 0x06, 0x200b);
mdio_write(tp, 0x06, 0xf620);
mdio_write(tp, 0x06, 0xe48b);
mdio_write(tp, 0x06, 0x8e02);
mdio_write(tp, 0x06, 0x830e);
mdio_write(tp, 0x06, 0x021b);
mdio_write(tp, 0x06, 0x67ad);
mdio_write(tp, 0x06, 0x2211);
mdio_write(tp, 0x06, 0xf622);
mdio_write(tp, 0x06, 0xe48b);
mdio_write(tp, 0x06, 0x8e02);
mdio_write(tp, 0x06, 0x2ba5);
mdio_write(tp, 0x06, 0x022a);
mdio_write(tp, 0x06, 0x2402);
mdio_write(tp, 0x06, 0x80c6);
mdio_write(tp, 0x06, 0x022a);
mdio_write(tp, 0x06, 0xf0ad);
mdio_write(tp, 0x06, 0x2511);
mdio_write(tp, 0x06, 0xf625);
mdio_write(tp, 0x06, 0xe48b);
mdio_write(tp, 0x06, 0x8e02);
mdio_write(tp, 0x06, 0x8226);
mdio_write(tp, 0x06, 0x0204);
mdio_write(tp, 0x06, 0x0302);
mdio_write(tp, 0x06, 0x19cc);
mdio_write(tp, 0x06, 0x022b);
mdio_write(tp, 0x06, 0x5bfc);
mdio_write(tp, 0x06, 0x04ee);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0x0105);
mdio_write(tp, 0x06, 0xf8e0);
mdio_write(tp, 0x06, 0x8b83);
mdio_write(tp, 0x06, 0xad24);
mdio_write(tp, 0x06, 0x44e0);
mdio_write(tp, 0x06, 0xe022);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x23ad);
mdio_write(tp, 0x06, 0x223b);
mdio_write(tp, 0x06, 0xe08a);
mdio_write(tp, 0x06, 0xbea0);
mdio_write(tp, 0x06, 0x0005);
mdio_write(tp, 0x06, 0x0228);
mdio_write(tp, 0x06, 0xdeae);
mdio_write(tp, 0x06, 0x42a0);
mdio_write(tp, 0x06, 0x0105);
mdio_write(tp, 0x06, 0x0228);
mdio_write(tp, 0x06, 0xf1ae);
mdio_write(tp, 0x06, 0x3aa0);
mdio_write(tp, 0x06, 0x0205);
mdio_write(tp, 0x06, 0x0281);
mdio_write(tp, 0x06, 0x25ae);
mdio_write(tp, 0x06, 0x32a0);
mdio_write(tp, 0x06, 0x0305);
mdio_write(tp, 0x06, 0x0229);
mdio_write(tp, 0x06, 0x9aae);
mdio_write(tp, 0x06, 0x2aa0);
mdio_write(tp, 0x06, 0x0405);
mdio_write(tp, 0x06, 0x0229);
mdio_write(tp, 0x06, 0xaeae);
mdio_write(tp, 0x06, 0x22a0);
mdio_write(tp, 0x06, 0x0505);
mdio_write(tp, 0x06, 0x0229);
mdio_write(tp, 0x06, 0xd7ae);
mdio_write(tp, 0x06, 0x1aa0);
mdio_write(tp, 0x06, 0x0605);
mdio_write(tp, 0x06, 0x0229);
mdio_write(tp, 0x06, 0xfeae);
mdio_write(tp, 0x06, 0x12ee);
mdio_write(tp, 0x06, 0x8ac0);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8ac1);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8ac6);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8abe);
mdio_write(tp, 0x06, 0x00ae);
mdio_write(tp, 0x06, 0x00fc);
mdio_write(tp, 0x06, 0x04f8);
mdio_write(tp, 0x06, 0x022a);
mdio_write(tp, 0x06, 0x67e0);
mdio_write(tp, 0x06, 0xe022);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x230d);
mdio_write(tp, 0x06, 0x0658);
mdio_write(tp, 0x06, 0x03a0);
mdio_write(tp, 0x06, 0x0202);
mdio_write(tp, 0x06, 0xae2d);
mdio_write(tp, 0x06, 0xa001);
mdio_write(tp, 0x06, 0x02ae);
mdio_write(tp, 0x06, 0x2da0);
mdio_write(tp, 0x06, 0x004d);
mdio_write(tp, 0x06, 0xe0e2);
mdio_write(tp, 0x06, 0x00e1);
mdio_write(tp, 0x06, 0xe201);
mdio_write(tp, 0x06, 0xad24);
mdio_write(tp, 0x06, 0x44e0);
mdio_write(tp, 0x06, 0x8ac2);
mdio_write(tp, 0x06, 0xe48a);
mdio_write(tp, 0x06, 0xc4e0);
mdio_write(tp, 0x06, 0x8ac3);
mdio_write(tp, 0x06, 0xe48a);
mdio_write(tp, 0x06, 0xc5ee);
mdio_write(tp, 0x06, 0x8abe);
mdio_write(tp, 0x06, 0x03e0);
mdio_write(tp, 0x06, 0x8b83);
mdio_write(tp, 0x06, 0xad25);
mdio_write(tp, 0x06, 0x3aee);
mdio_write(tp, 0x06, 0x8abe);
mdio_write(tp, 0x06, 0x05ae);
mdio_write(tp, 0x06, 0x34e0);
mdio_write(tp, 0x06, 0x8ace);
mdio_write(tp, 0x06, 0xae03);
mdio_write(tp, 0x06, 0xe08a);
mdio_write(tp, 0x06, 0xcfe1);
mdio_write(tp, 0x06, 0x8ac2);
mdio_write(tp, 0x06, 0x4905);
mdio_write(tp, 0x06, 0xe58a);
mdio_write(tp, 0x06, 0xc4e1);
mdio_write(tp, 0x06, 0x8ac3);
mdio_write(tp, 0x06, 0x4905);
mdio_write(tp, 0x06, 0xe58a);
mdio_write(tp, 0x06, 0xc5ee);
mdio_write(tp, 0x06, 0x8abe);
mdio_write(tp, 0x06, 0x0502);
mdio_write(tp, 0x06, 0x2ab6);
mdio_write(tp, 0x06, 0xac20);
mdio_write(tp, 0x06, 0x1202);
mdio_write(tp, 0x06, 0x819b);
mdio_write(tp, 0x06, 0xac20);
mdio_write(tp, 0x06, 0x0cee);
mdio_write(tp, 0x06, 0x8ac1);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8ac6);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8abe);
mdio_write(tp, 0x06, 0x02fc);
mdio_write(tp, 0x06, 0x04d0);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x81ad);
mdio_write(tp, 0x06, 0x590f);
mdio_write(tp, 0x06, 0x3902);
mdio_write(tp, 0x06, 0xaa04);
mdio_write(tp, 0x06, 0xd001);
mdio_write(tp, 0x06, 0xae02);
mdio_write(tp, 0x06, 0xd000);
mdio_write(tp, 0x06, 0x04f9);
mdio_write(tp, 0x06, 0xfae2);
mdio_write(tp, 0x06, 0xe2d2);
mdio_write(tp, 0x06, 0xe3e2);
mdio_write(tp, 0x06, 0xd3f9);
mdio_write(tp, 0x06, 0x5af7);
mdio_write(tp, 0x06, 0xe6e2);
mdio_write(tp, 0x06, 0xd2e7);
mdio_write(tp, 0x06, 0xe2d3);
mdio_write(tp, 0x06, 0xe2e0);
mdio_write(tp, 0x06, 0x2ce3);
mdio_write(tp, 0x06, 0xe02d);
mdio_write(tp, 0x06, 0xf95b);
mdio_write(tp, 0x06, 0xe01e);
mdio_write(tp, 0x06, 0x30e6);
mdio_write(tp, 0x06, 0xe02c);
mdio_write(tp, 0x06, 0xe7e0);
mdio_write(tp, 0x06, 0x2de2);
mdio_write(tp, 0x06, 0xe2cc);
mdio_write(tp, 0x06, 0xe3e2);
mdio_write(tp, 0x06, 0xcdf9);
mdio_write(tp, 0x06, 0x5a0f);
mdio_write(tp, 0x06, 0x6a50);
mdio_write(tp, 0x06, 0xe6e2);
mdio_write(tp, 0x06, 0xcce7);
mdio_write(tp, 0x06, 0xe2cd);
mdio_write(tp, 0x06, 0xe0e0);
mdio_write(tp, 0x06, 0x3ce1);
mdio_write(tp, 0x06, 0xe03d);
mdio_write(tp, 0x06, 0xef64);
mdio_write(tp, 0x06, 0xfde0);
mdio_write(tp, 0x06, 0xe2cc);
mdio_write(tp, 0x06, 0xe1e2);
mdio_write(tp, 0x06, 0xcd58);
mdio_write(tp, 0x06, 0x0f5a);
mdio_write(tp, 0x06, 0xf01e);
mdio_write(tp, 0x06, 0x02e4);
mdio_write(tp, 0x06, 0xe2cc);
mdio_write(tp, 0x06, 0xe5e2);
mdio_write(tp, 0x06, 0xcdfd);
mdio_write(tp, 0x06, 0xe0e0);
mdio_write(tp, 0x06, 0x2ce1);
mdio_write(tp, 0x06, 0xe02d);
mdio_write(tp, 0x06, 0x59e0);
mdio_write(tp, 0x06, 0x5b1f);
mdio_write(tp, 0x06, 0x1e13);
mdio_write(tp, 0x06, 0xe4e0);
mdio_write(tp, 0x06, 0x2ce5);
mdio_write(tp, 0x06, 0xe02d);
mdio_write(tp, 0x06, 0xfde0);
mdio_write(tp, 0x06, 0xe2d2);
mdio_write(tp, 0x06, 0xe1e2);
mdio_write(tp, 0x06, 0xd358);
mdio_write(tp, 0x06, 0xf75a);
mdio_write(tp, 0x06, 0x081e);
mdio_write(tp, 0x06, 0x02e4);
mdio_write(tp, 0x06, 0xe2d2);
mdio_write(tp, 0x06, 0xe5e2);
mdio_write(tp, 0x06, 0xd3ef);
mdio_write(tp, 0x06, 0x46fe);
mdio_write(tp, 0x06, 0xfd04);
mdio_write(tp, 0x06, 0xf8f9);
mdio_write(tp, 0x06, 0xfaef);
mdio_write(tp, 0x06, 0x69e0);
mdio_write(tp, 0x06, 0xe022);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x2358);
mdio_write(tp, 0x06, 0xc4e1);
mdio_write(tp, 0x06, 0x8b6e);
mdio_write(tp, 0x06, 0x1f10);
mdio_write(tp, 0x06, 0x9e58);
mdio_write(tp, 0x06, 0xe48b);
mdio_write(tp, 0x06, 0x6ead);
mdio_write(tp, 0x06, 0x2222);
mdio_write(tp, 0x06, 0xac27);
mdio_write(tp, 0x06, 0x55ac);
mdio_write(tp, 0x06, 0x2602);
mdio_write(tp, 0x06, 0xae1a);
mdio_write(tp, 0x06, 0xd106);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xba02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd107);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xbd02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd107);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xc002);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xae30);
mdio_write(tp, 0x06, 0xd103);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xc302);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd100);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xc602);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd100);
mdio_write(tp, 0x06, 0xbf82);
mdio_write(tp, 0x06, 0xca02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd10f);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xba02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd101);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xbd02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd101);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xc002);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xef96);
mdio_write(tp, 0x06, 0xfefd);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xd100);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xc302);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd011);
mdio_write(tp, 0x06, 0x022b);
mdio_write(tp, 0x06, 0xfb59);
mdio_write(tp, 0x06, 0x03ef);
mdio_write(tp, 0x06, 0x01d1);
mdio_write(tp, 0x06, 0x00a0);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0xd101);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0xc602);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xd111);
mdio_write(tp, 0x06, 0xad20);
mdio_write(tp, 0x06, 0x020c);
mdio_write(tp, 0x06, 0x11ad);
mdio_write(tp, 0x06, 0x2102);
mdio_write(tp, 0x06, 0x0c12);
mdio_write(tp, 0x06, 0xbf82);
mdio_write(tp, 0x06, 0xca02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xaec8);
mdio_write(tp, 0x06, 0x70e4);
mdio_write(tp, 0x06, 0x2602);
mdio_write(tp, 0x06, 0x82d1);
mdio_write(tp, 0x06, 0x05f8);
mdio_write(tp, 0x06, 0xfaef);
mdio_write(tp, 0x06, 0x69e0);
mdio_write(tp, 0x06, 0xe2fe);
mdio_write(tp, 0x06, 0xe1e2);
mdio_write(tp, 0x06, 0xffad);
mdio_write(tp, 0x06, 0x2d1a);
mdio_write(tp, 0x06, 0xe0e1);
mdio_write(tp, 0x06, 0x4ee1);
mdio_write(tp, 0x06, 0xe14f);
mdio_write(tp, 0x06, 0xac2d);
mdio_write(tp, 0x06, 0x22f6);
mdio_write(tp, 0x06, 0x0302);
mdio_write(tp, 0x06, 0x033b);
mdio_write(tp, 0x06, 0xf703);
mdio_write(tp, 0x06, 0xf706);
mdio_write(tp, 0x06, 0xbf84);
mdio_write(tp, 0x06, 0x4402);
mdio_write(tp, 0x06, 0x2d21);
mdio_write(tp, 0x06, 0xae11);
mdio_write(tp, 0x06, 0xe0e1);
mdio_write(tp, 0x06, 0x4ee1);
mdio_write(tp, 0x06, 0xe14f);
mdio_write(tp, 0x06, 0xad2d);
mdio_write(tp, 0x06, 0x08bf);
mdio_write(tp, 0x06, 0x844f);
mdio_write(tp, 0x06, 0x022d);
mdio_write(tp, 0x06, 0x21f6);
mdio_write(tp, 0x06, 0x06ef);
mdio_write(tp, 0x06, 0x96fe);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xf8fa);
mdio_write(tp, 0x06, 0xef69);
mdio_write(tp, 0x06, 0x0283);
mdio_write(tp, 0x06, 0x4502);
mdio_write(tp, 0x06, 0x83a2);
mdio_write(tp, 0x06, 0xe0e0);
mdio_write(tp, 0x06, 0x00e1);
mdio_write(tp, 0x06, 0xe001);
mdio_write(tp, 0x06, 0xad27);
mdio_write(tp, 0x06, 0x1fd1);
mdio_write(tp, 0x06, 0x01bf);
mdio_write(tp, 0x06, 0x843b);
mdio_write(tp, 0x06, 0x022d);
mdio_write(tp, 0x06, 0xc1e0);
mdio_write(tp, 0x06, 0xe020);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x21ad);
mdio_write(tp, 0x06, 0x200e);
mdio_write(tp, 0x06, 0xd100);
mdio_write(tp, 0x06, 0xbf84);
mdio_write(tp, 0x06, 0x3b02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xbf3b);
mdio_write(tp, 0x06, 0x9602);
mdio_write(tp, 0x06, 0x2d21);
mdio_write(tp, 0x06, 0xef96);
mdio_write(tp, 0x06, 0xfefc);
mdio_write(tp, 0x06, 0x04f8);
mdio_write(tp, 0x06, 0xf9fa);
mdio_write(tp, 0x06, 0xef69);
mdio_write(tp, 0x06, 0xe08b);
mdio_write(tp, 0x06, 0x87ad);
mdio_write(tp, 0x06, 0x204c);
mdio_write(tp, 0x06, 0xd200);
mdio_write(tp, 0x06, 0xe0e2);
mdio_write(tp, 0x06, 0x0058);
mdio_write(tp, 0x06, 0x010c);
mdio_write(tp, 0x06, 0x021e);
mdio_write(tp, 0x06, 0x20e0);
mdio_write(tp, 0x06, 0xe000);
mdio_write(tp, 0x06, 0x5810);
mdio_write(tp, 0x06, 0x1e20);
mdio_write(tp, 0x06, 0xe0e0);
mdio_write(tp, 0x06, 0x3658);
mdio_write(tp, 0x06, 0x031e);
mdio_write(tp, 0x06, 0x20e0);
mdio_write(tp, 0x06, 0xe022);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x2358);
mdio_write(tp, 0x06, 0xe01e);
mdio_write(tp, 0x06, 0x20e0);
mdio_write(tp, 0x06, 0x8b64);
mdio_write(tp, 0x06, 0x1f02);
mdio_write(tp, 0x06, 0x9e22);
mdio_write(tp, 0x06, 0xe68b);
mdio_write(tp, 0x06, 0x64ad);
mdio_write(tp, 0x06, 0x3214);
mdio_write(tp, 0x06, 0xad34);
mdio_write(tp, 0x06, 0x11ef);
mdio_write(tp, 0x06, 0x0258);
mdio_write(tp, 0x06, 0x039e);
mdio_write(tp, 0x06, 0x07ad);
mdio_write(tp, 0x06, 0x3508);
mdio_write(tp, 0x06, 0x5ac0);
mdio_write(tp, 0x06, 0x9f04);
mdio_write(tp, 0x06, 0xd101);
mdio_write(tp, 0x06, 0xae02);
mdio_write(tp, 0x06, 0xd100);
mdio_write(tp, 0x06, 0xbf84);
mdio_write(tp, 0x06, 0x3e02);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xef96);
mdio_write(tp, 0x06, 0xfefd);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xf8f9);
mdio_write(tp, 0x06, 0xfbe0);
mdio_write(tp, 0x06, 0x8b85);
mdio_write(tp, 0x06, 0xad25);
mdio_write(tp, 0x06, 0x22e0);
mdio_write(tp, 0x06, 0xe022);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x23e2);
mdio_write(tp, 0x06, 0xe036);
mdio_write(tp, 0x06, 0xe3e0);
mdio_write(tp, 0x06, 0x375a);
mdio_write(tp, 0x06, 0xc40d);
mdio_write(tp, 0x06, 0x0158);
mdio_write(tp, 0x06, 0x021e);
mdio_write(tp, 0x06, 0x20e3);
mdio_write(tp, 0x06, 0x8ae7);
mdio_write(tp, 0x06, 0xac31);
mdio_write(tp, 0x06, 0x60ac);
mdio_write(tp, 0x06, 0x3a08);
mdio_write(tp, 0x06, 0xac3e);
mdio_write(tp, 0x06, 0x26ae);
mdio_write(tp, 0x06, 0x67af);
mdio_write(tp, 0x06, 0x8437);
mdio_write(tp, 0x06, 0xad37);
mdio_write(tp, 0x06, 0x61e0);
mdio_write(tp, 0x06, 0x8ae8);
mdio_write(tp, 0x06, 0x10e4);
mdio_write(tp, 0x06, 0x8ae8);
mdio_write(tp, 0x06, 0xe18a);
mdio_write(tp, 0x06, 0xe91b);
mdio_write(tp, 0x06, 0x109e);
mdio_write(tp, 0x06, 0x02ae);
mdio_write(tp, 0x06, 0x51d1);
mdio_write(tp, 0x06, 0x00bf);
mdio_write(tp, 0x06, 0x8441);
mdio_write(tp, 0x06, 0x022d);
mdio_write(tp, 0x06, 0xc1ee);
mdio_write(tp, 0x06, 0x8ae8);
mdio_write(tp, 0x06, 0x00ae);
mdio_write(tp, 0x06, 0x43ad);
mdio_write(tp, 0x06, 0x3627);
mdio_write(tp, 0x06, 0xe08a);
mdio_write(tp, 0x06, 0xeee1);
mdio_write(tp, 0x06, 0x8aef);
mdio_write(tp, 0x06, 0xef74);
mdio_write(tp, 0x06, 0xe08a);
mdio_write(tp, 0x06, 0xeae1);
mdio_write(tp, 0x06, 0x8aeb);
mdio_write(tp, 0x06, 0x1b74);
mdio_write(tp, 0x06, 0x9e2e);
mdio_write(tp, 0x06, 0x14e4);
mdio_write(tp, 0x06, 0x8aea);
mdio_write(tp, 0x06, 0xe58a);
mdio_write(tp, 0x06, 0xebef);
mdio_write(tp, 0x06, 0x74e0);
mdio_write(tp, 0x06, 0x8aee);
mdio_write(tp, 0x06, 0xe18a);
mdio_write(tp, 0x06, 0xef1b);
mdio_write(tp, 0x06, 0x479e);
mdio_write(tp, 0x06, 0x0fae);
mdio_write(tp, 0x06, 0x19ee);
mdio_write(tp, 0x06, 0x8aea);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0x8aeb);
mdio_write(tp, 0x06, 0x00ae);
mdio_write(tp, 0x06, 0x0fac);
mdio_write(tp, 0x06, 0x390c);
mdio_write(tp, 0x06, 0xd101);
mdio_write(tp, 0x06, 0xbf84);
mdio_write(tp, 0x06, 0x4102);
mdio_write(tp, 0x06, 0x2dc1);
mdio_write(tp, 0x06, 0xee8a);
mdio_write(tp, 0x06, 0xe800);
mdio_write(tp, 0x06, 0xe68a);
mdio_write(tp, 0x06, 0xe7ff);
mdio_write(tp, 0x06, 0xfdfc);
mdio_write(tp, 0x06, 0x0400);
mdio_write(tp, 0x06, 0xe234);
mdio_write(tp, 0x06, 0xcce2);
mdio_write(tp, 0x06, 0x0088);
mdio_write(tp, 0x06, 0xe200);
mdio_write(tp, 0x06, 0xa725);
mdio_write(tp, 0x06, 0xe50a);
mdio_write(tp, 0x06, 0x1de5);
mdio_write(tp, 0x06, 0x0a2c);
mdio_write(tp, 0x06, 0xe50a);
mdio_write(tp, 0x06, 0x6de5);
mdio_write(tp, 0x06, 0x0a1d);
mdio_write(tp, 0x06, 0xe50a);
mdio_write(tp, 0x06, 0x1ce5);
mdio_write(tp, 0x06, 0x0a2d);
mdio_write(tp, 0x06, 0xa755);
mdio_write(tp, 0x05, 0x8b64);
mdio_write(tp, 0x06, 0x0000);
mdio_write(tp, 0x05, 0x8b94);
mdio_write(tp, 0x06, 0x82cd);
mdio_write(tp, 0x05, 0x8b85);
mdio_write(tp, 0x06, 0x2000);
mdio_write(tp, 0x05, 0x8aee);
mdio_write(tp, 0x06, 0x03b8);
mdio_write(tp, 0x05, 0x8ae8);
mdio_write(tp, 0x06, 0x0002);
gphy_val = mdio_read(tp, 0x01);
gphy_val |= BIT_0;
mdio_write(tp, 0x01, gphy_val);
gphy_val = mdio_read(tp, 0x00);
gphy_val |= BIT_0;
mdio_write(tp, 0x00, gphy_val);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x1f, 0x0005);
for (i = 0; i < 200; i++) {
udelay(100);
gphy_val = mdio_read(tp, 0x00);
if (gphy_val & BIT_7)
break;
}
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0023);
gphy_val = mdio_read(tp, 0x17);
gphy_val &= ~(BIT_0);
if ((pdev->subsystem_vendor == 0x144d &&
pdev->subsystem_device == 0xc098) ||
(pdev->subsystem_vendor == 0x144d &&
pdev->subsystem_device == 0xc0b1)) {
gphy_val &= ~(BIT_2);
}
mdio_write(tp, 0x17, gphy_val);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0028);
mdio_write(tp, 0x15, 0x0010);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0041);
mdio_write(tp, 0x15, 0x0802);
mdio_write(tp, 0x16, 0x2185);
mdio_write(tp, 0x1f, 0x0000);
spin_unlock_irqrestore(&tp->phy_lock, flags);
} else {
spin_lock_irqsave(&tp->phy_lock, flags);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x00, 0x1800);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0023);
mdio_write(tp, 0x17, 0x0117);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1E, 0x002C);
mdio_write(tp, 0x1B, 0x5000);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x16, 0x4104);
for (i = 0; i < 200; i++) {
udelay(100);
gphy_val = mdio_read(tp, 0x1E);
gphy_val &= 0x03FF;
if (gphy_val==0x000C)
break;
}
mdio_write(tp, 0x1f, 0x0005);
for (i = 0; i < 200; i++) {
udelay(100);
gphy_val = mdio_read(tp, 0x07);
if ((gphy_val & BIT_5) == 0)
break;
}
gphy_val = mdio_read(tp, 0x07);
if (gphy_val & BIT_5) {
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x00a1);
mdio_write(tp, 0x17, 0x1000);
mdio_write(tp, 0x17, 0x0000);
mdio_write(tp, 0x17, 0x2000);
mdio_write(tp, 0x1e, 0x002f);
mdio_write(tp, 0x18, 0x9bfb);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x07, 0x0000);
mdio_write(tp, 0x1f, 0x0000);
}
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x0080);
gphy_val = mdio_read(tp, 0x00);
gphy_val &= ~(BIT_7);
mdio_write(tp, 0x00, gphy_val);
mdio_write(tp, 0x1f, 0x0002);
gphy_val = mdio_read(tp, 0x08);
gphy_val &= ~(BIT_7);
mdio_write(tp, 0x08, gphy_val);
mdio_write(tp, 0x1f, 0x0000);
mdio_write(tp, 0x1f, 0x0007);
mdio_write(tp, 0x1e, 0x0023);
mdio_write(tp, 0x16, 0x0306);
mdio_write(tp, 0x16, 0x0307);
mdio_write(tp, 0x15, 0x000e);
mdio_write(tp, 0x19, 0x000a);
mdio_write(tp, 0x15, 0x0010);
mdio_write(tp, 0x19, 0x0008);
mdio_write(tp, 0x15, 0x0018);
mdio_write(tp, 0x19, 0x4801);
mdio_write(tp, 0x15, 0x0019);
mdio_write(tp, 0x19, 0x6801);
mdio_write(tp, 0x15, 0x001a);
mdio_write(tp, 0x19, 0x66a1);
mdio_write(tp, 0x15, 0x001f);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0020);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0021);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0022);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0023);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0024);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0025);
mdio_write(tp, 0x19, 0x64a1);
mdio_write(tp, 0x15, 0x0026);
mdio_write(tp, 0x19, 0x40ea);
mdio_write(tp, 0x15, 0x0027);
mdio_write(tp, 0x19, 0x4503);
mdio_write(tp, 0x15, 0x0028);
mdio_write(tp, 0x19, 0x9f00);
mdio_write(tp, 0x15, 0x0029);
mdio_write(tp, 0x19, 0xa631);
mdio_write(tp, 0x15, 0x002a);
mdio_write(tp, 0x19, 0x9717);
mdio_write(tp, 0x15, 0x002b);
mdio_write(tp, 0x19, 0x302c);
mdio_write(tp, 0x15, 0x002c);
mdio_write(tp, 0x19, 0x4802);
mdio_write(tp, 0x15, 0x002d);
mdio_write(tp, 0x19, 0x58da);
mdio_write(tp, 0x15, 0x002e);
mdio_write(tp, 0x19, 0x400d);
mdio_write(tp, 0x15, 0x002f);
mdio_write(tp, 0x19, 0x4488);
mdio_write(tp, 0x15, 0x0030);
mdio_write(tp, 0x19, 0x9e00);
mdio_write(tp, 0x15, 0x0031);
mdio_write(tp, 0x19, 0x63c8);
mdio_write(tp, 0x15, 0x0032);
mdio_write(tp, 0x19, 0x6481);
mdio_write(tp, 0x15, 0x0033);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0034);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0035);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0036);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0037);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0038);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0039);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x003a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x003b);
mdio_write(tp, 0x19, 0x63e8);
mdio_write(tp, 0x15, 0x003c);
mdio_write(tp, 0x19, 0x7d00);
mdio_write(tp, 0x15, 0x003d);
mdio_write(tp, 0x19, 0x59d4);
mdio_write(tp, 0x15, 0x003e);
mdio_write(tp, 0x19, 0x63f8);
mdio_write(tp, 0x15, 0x0040);
mdio_write(tp, 0x19, 0x64a1);
mdio_write(tp, 0x15, 0x0041);
mdio_write(tp, 0x19, 0x30de);
mdio_write(tp, 0x15, 0x0044);
mdio_write(tp, 0x19, 0x480f);
mdio_write(tp, 0x15, 0x0045);
mdio_write(tp, 0x19, 0x6800);
mdio_write(tp, 0x15, 0x0046);
mdio_write(tp, 0x19, 0x6680);
mdio_write(tp, 0x15, 0x0047);
mdio_write(tp, 0x19, 0x7c10);
mdio_write(tp, 0x15, 0x0048);
mdio_write(tp, 0x19, 0x63c8);
mdio_write(tp, 0x15, 0x0049);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004b);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004c);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004d);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004e);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x004f);
mdio_write(tp, 0x19, 0x40ea);
mdio_write(tp, 0x15, 0x0050);
mdio_write(tp, 0x19, 0x4503);
mdio_write(tp, 0x15, 0x0051);
mdio_write(tp, 0x19, 0x58ca);
mdio_write(tp, 0x15, 0x0052);
mdio_write(tp, 0x19, 0x63c8);
mdio_write(tp, 0x15, 0x0053);
mdio_write(tp, 0x19, 0x63d8);
mdio_write(tp, 0x15, 0x0054);
mdio_write(tp, 0x19, 0x66a0);
mdio_write(tp, 0x15, 0x0055);
mdio_write(tp, 0x19, 0x9f00);
mdio_write(tp, 0x15, 0x0056);
mdio_write(tp, 0x19, 0x3000);
mdio_write(tp, 0x15, 0x00a1);
mdio_write(tp, 0x19, 0x3044);
mdio_write(tp, 0x15, 0x00ab);
mdio_write(tp, 0x19, 0x5820);
mdio_write(tp, 0x15, 0x00ac);
mdio_write(tp, 0x19, 0x5e04);
mdio_write(tp, 0x15, 0x00ad);
mdio_write(tp, 0x19, 0xb60c);
mdio_write(tp, 0x15, 0x00af);
mdio_write(tp, 0x19, 0x000a);
mdio_write(tp, 0x15, 0x00b2);
mdio_write(tp, 0x19, 0x30b9);
mdio_write(tp, 0x15, 0x00b9);
mdio_write(tp, 0x19, 0x4408);
mdio_write(tp, 0x15, 0x00ba);
mdio_write(tp, 0x19, 0x480b);
mdio_write(tp, 0x15, 0x00bb);
mdio_write(tp, 0x19, 0x5e00);
mdio_write(tp, 0x15, 0x00bc);
mdio_write(tp, 0x19, 0x405f);
mdio_write(tp, 0x15, 0x00bd);
mdio_write(tp, 0x19, 0x4448);
mdio_write(tp, 0x15, 0x00be);
mdio_write(tp, 0x19, 0x4020);
mdio_write(tp, 0x15, 0x00bf);
mdio_write(tp, 0x19, 0x4468);
mdio_write(tp, 0x15, 0x00c0);
mdio_write(tp, 0x19, 0x9c02);
mdio_write(tp, 0x15, 0x00c1);
mdio_write(tp, 0x19, 0x58a0);
mdio_write(tp, 0x15, 0x00c2);
mdio_write(tp, 0x19, 0xb605);
mdio_write(tp, 0x15, 0x00c3);
mdio_write(tp, 0x19, 0xc0d3);
mdio_write(tp, 0x15, 0x00c4);
mdio_write(tp, 0x19, 0x00e6);
mdio_write(tp, 0x15, 0x00c5);
mdio_write(tp, 0x19, 0xdaec);
mdio_write(tp, 0x15, 0x00c6);
mdio_write(tp, 0x19, 0x00fa);
mdio_write(tp, 0x15, 0x00c7);
mdio_write(tp, 0x19, 0x9df9);
mdio_write(tp, 0x15, 0x0112);
mdio_write(tp, 0x19, 0x6421);
mdio_write(tp, 0x15, 0x0113);
mdio_write(tp, 0x19, 0x7c08);
mdio_write(tp, 0x15, 0x0114);
mdio_write(tp, 0x19, 0x63f0);
mdio_write(tp, 0x15, 0x0115);
mdio_write(tp, 0x19, 0x4003);
mdio_write(tp, 0x15, 0x0116);
mdio_write(tp, 0x19, 0x4418);
mdio_write(tp, 0x15, 0x0117);
mdio_write(tp, 0x19, 0x9b00);
mdio_write(tp, 0x15, 0x0118);
mdio_write(tp, 0x19, 0x6461);
mdio_write(tp, 0x15, 0x0119);
mdio_write(tp, 0x19, 0x64e1);
mdio_write(tp, 0x15, 0x011a);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0150);
mdio_write(tp, 0x19, 0x7c80);
mdio_write(tp, 0x15, 0x0151);
mdio_write(tp, 0x19, 0x6461);
mdio_write(tp, 0x15, 0x0152);
mdio_write(tp, 0x19, 0x4003);
mdio_write(tp, 0x15, 0x0153);
mdio_write(tp, 0x19, 0x4540);
mdio_write(tp, 0x15, 0x0154);
mdio_write(tp, 0x19, 0x9f00);
mdio_write(tp, 0x15, 0x0155);
mdio_write(tp, 0x19, 0x9d00);
mdio_write(tp, 0x15, 0x0156);
mdio_write(tp, 0x19, 0x7c40);
mdio_write(tp, 0x15, 0x0157);
mdio_write(tp, 0x19, 0x6421);
mdio_write(tp, 0x15, 0x0158);
mdio_write(tp, 0x19, 0x7c80);
mdio_write(tp, 0x15, 0x0159);
mdio_write(tp, 0x19, 0x64a1);
mdio_write(tp, 0x15, 0x015a);
mdio_write(tp, 0x19, 0x30fe);
mdio_write(tp, 0x15, 0x02e7);
mdio_write(tp, 0x19, 0x0000);
mdio_write(tp, 0x15, 0x0329);
mdio_write(tp, 0x19, 0x7c00);
mdio_write(tp, 0x15, 0x0382);
mdio_write(tp, 0x19, 0x7c40);
mdio_write(tp, 0x15, 0x03bd);
mdio_write(tp, 0x19, 0x405e);
mdio_write(tp, 0x15, 0x03c9);
mdio_write(tp, 0x19, 0x7c00);
mdio_write(tp, 0x15, 0x03e3);
mdio_write(tp, 0x19, 0x7c00);
mdio_write(tp, 0x16, 0x0306);
mdio_write(tp, 0x16, 0x0300);
mdio_write(tp, 0x1f, 0x0005);
mdio_write(tp, 0x05, 0xfff6);
mdio_write(tp, 0x06, 0x0080);
mdio_write(tp, 0x05, 0x8000);
mdio_write(tp, 0x06, 0x0280);
mdio_write(tp, 0x06, 0x48f7);
mdio_write(tp, 0x06, 0x00e0);
mdio_write(tp, 0x06, 0xfff7);
mdio_write(tp, 0x06, 0xa080);
mdio_write(tp, 0x06, 0x02ae);
mdio_write(tp, 0x06, 0xf602);
mdio_write(tp, 0x06, 0x0200);
mdio_write(tp, 0x06, 0x0280);
mdio_write(tp, 0x06, 0x8c02);
mdio_write(tp, 0x06, 0x0224);
mdio_write(tp, 0x06, 0x0202);
mdio_write(tp, 0x06, 0x3402);
mdio_write(tp, 0x06, 0x027f);
mdio_write(tp, 0x06, 0x0280);
mdio_write(tp, 0x06, 0xa202);
mdio_write(tp, 0x06, 0x80bb);
mdio_write(tp, 0x06, 0xe08b);
mdio_write(tp, 0x06, 0x88e1);
mdio_write(tp, 0x06, 0x8b89);
mdio_write(tp, 0x06, 0x1e01);
mdio_write(tp, 0x06, 0xe18b);
mdio_write(tp, 0x06, 0x8a1e);
mdio_write(tp, 0x06, 0x01e1);
mdio_write(tp, 0x06, 0x8b8b);
mdio_write(tp, 0x06, 0x1e01);
mdio_write(tp, 0x06, 0xe18b);
mdio_write(tp, 0x06, 0x8c1e);
mdio_write(tp, 0x06, 0x01e1);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0x1e01);
mdio_write(tp, 0x06, 0xe18b);
mdio_write(tp, 0x06, 0x8e1e);
mdio_write(tp, 0x06, 0x01a0);
mdio_write(tp, 0x06, 0x00c7);
mdio_write(tp, 0x06, 0xaebb);
mdio_write(tp, 0x06, 0xee8a);
mdio_write(tp, 0x06, 0xe600);
mdio_write(tp, 0x06, 0xee8a);
mdio_write(tp, 0x06, 0xee03);
mdio_write(tp, 0x06, 0xee8a);
mdio_write(tp, 0x06, 0xefb8);
mdio_write(tp, 0x06, 0xee8a);
mdio_write(tp, 0x06, 0xe902);
mdio_write(tp, 0x06, 0xee8b);
mdio_write(tp, 0x06, 0x8520);
mdio_write(tp, 0x06, 0xee8b);
mdio_write(tp, 0x06, 0x8701);
mdio_write(tp, 0x06, 0xd481);
mdio_write(tp, 0x06, 0x31e4);
mdio_write(tp, 0x06, 0x8b94);
mdio_write(tp, 0x06, 0xe58b);
mdio_write(tp, 0x06, 0x95bf);
mdio_write(tp, 0x06, 0x8b88);
mdio_write(tp, 0x06, 0xec00);
mdio_write(tp, 0x06, 0x19a9);
mdio_write(tp, 0x06, 0x8b90);
mdio_write(tp, 0x06, 0xf9ee);
mdio_write(tp, 0x06, 0xfff6);
mdio_write(tp, 0x06, 0x00ee);
mdio_write(tp, 0x06, 0xfff7);
mdio_write(tp, 0x06, 0xffe0);
mdio_write(tp, 0x06, 0xe140);
mdio_write(tp, 0x06, 0xe1e1);
mdio_write(tp, 0x06, 0x41f7);
mdio_write(tp, 0x06, 0x2ff6);
mdio_write(tp, 0x06, 0x28e4);
mdio_write(tp, 0x06, 0xe140);
mdio_write(tp, 0x06, 0xe5e1);
mdio_write(tp, 0x06, 0x4104);
mdio_write(tp, 0x06, 0xf8e0);
mdio_write(tp, 0x06, 0x8b89);
mdio_write(tp, 0x06, 0xad20);
mdio_write(tp, 0x06, 0x0dee);
mdio_write(tp, 0x06, 0x8b89);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x82ed);
mdio_write(tp, 0x06, 0x021f);
mdio_write(tp, 0x06, 0x4102);
mdio_write(tp, 0x06, 0x2812);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xf8e0);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0xad20);
mdio_write(tp, 0x06, 0x10ee);
mdio_write(tp, 0x06, 0x8b8d);
mdio_write(tp, 0x06, 0x0002);
mdio_write(tp, 0x06, 0x139d);
mdio_write(tp, 0x06, 0x0281);
mdio_write(tp, 0x06, 0xcf02);
mdio_write(tp, 0x06, 0x1f99);
mdio_write(tp, 0x06, 0x0227);
mdio_write(tp, 0x06, 0xeafc);
mdio_write(tp, 0x06, 0x04f8);
mdio_write(tp, 0x06, 0xe08b);
mdio_write(tp, 0x06, 0x8ead);
mdio_write(tp, 0x06, 0x2014);
mdio_write(tp, 0x06, 0xf620);
mdio_write(tp, 0x06, 0xe48b);
mdio_write(tp, 0x06, 0x8e02);
mdio_write(tp, 0x06, 0x8100);
mdio_write(tp, 0x06, 0x021b);
mdio_write(tp, 0x06, 0xf402);
mdio_write(tp, 0x06, 0x2c9c);
mdio_write(tp, 0x06, 0x0281);
mdio_write(tp, 0x06, 0x7202);
mdio_write(tp, 0x06, 0x843c);
mdio_write(tp, 0x06, 0xad22);
mdio_write(tp, 0x06, 0x11f6);
mdio_write(tp, 0x06, 0x22e4);
mdio_write(tp, 0x06, 0x8b8e);
mdio_write(tp, 0x06, 0x022c);
mdio_write(tp, 0x06, 0x4602);
mdio_write(tp, 0x06, 0x2ac5);
mdio_write(tp, 0x06, 0x0229);
mdio_write(tp, 0x06, 0x2002);
mdio_write(tp, 0x06, 0x2b91);
mdio_write(tp, 0x06, 0xad25);
mdio_write(tp, 0x06, 0x11f6);
mdio_write(tp, 0x06, 0x25e4);
mdio_write(tp, 0x06, 0x8b8e);
mdio_write(tp, 0x06, 0x0203);
mdio_write(tp, 0x06, 0x5a02);
mdio_write(tp, 0x06, 0x043a);
mdio_write(tp, 0x06, 0x021a);
mdio_write(tp, 0x06, 0x5902);
mdio_write(tp, 0x06, 0x2bfc);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xf8fa);
mdio_write(tp, 0x06, 0xef69);
mdio_write(tp, 0x06, 0xe0e0);
mdio_write(tp, 0x06, 0x00e1);
mdio_write(tp, 0x06, 0xe001);
mdio_write(tp, 0x06, 0xad27);
mdio_write(tp, 0x06, 0x1fd1);
mdio_write(tp, 0x06, 0x01bf);
mdio_write(tp, 0x06, 0x84eb);
mdio_write(tp, 0x06, 0x022f);
mdio_write(tp, 0x06, 0x50e0);
mdio_write(tp, 0x06, 0xe020);
mdio_write(tp, 0x06, 0xe1e0);
mdio_write(tp, 0x06, 0x21ad);
mdio_write(tp, 0x06, 0x200e);
mdio_write(tp, 0x06, 0xd100);
mdio_write(tp, 0x06, 0xbf84);
mdio_write(tp, 0x06, 0xeb02);
mdio_write(tp, 0x06, 0x2f50);
mdio_write(tp, 0x06, 0xbf3d);
mdio_write(tp, 0x06, 0x3902);
mdio_write(tp, 0x06, 0x2eb0);
mdio_write(tp, 0x06, 0xef96);
mdio_write(tp, 0x06, 0xfefc);
mdio_write(tp, 0x06, 0x0402);
mdio_write(tp, 0x06, 0x8135);
mdio_write(tp, 0x06, 0x05f8);
mdio_write(tp, 0x06, 0xfaef);
mdio_write(tp, 0x06, 0x69e0);
mdio_write(tp, 0x06, 0xe2fe);
mdio_write(tp, 0x06, 0xe1e2);
mdio_write(tp, 0x06, 0xffad);
mdio_write(tp, 0x06, 0x2d1a);
mdio_write(tp, 0x06, 0xe0e1);
mdio_write(tp, 0x06, 0x4ee1);
mdio_write(tp, 0x06, 0xe14f);
mdio_write(tp, 0x06, 0xac2d);
mdio_write(tp, 0x06, 0x22f6);
mdio_write(tp, 0x06, 0x0302);
mdio_write(tp, 0x06, 0x0336);
mdio_write(tp, 0x06, 0xf703);
mdio_write(tp, 0x06, 0xf706);
mdio_write(tp, 0x06, 0xbf84);
mdio_write(tp, 0x06, 0xd502);
mdio_write(tp, 0x06, 0x2eb0);
mdio_write(tp, 0x06, 0xae11);
mdio_write(tp, 0x06, 0xe0e1);
mdio_write(tp, 0x06, 0x4ee1);
mdio_write(tp, 0x06, 0xe14f);
mdio_write(tp, 0x06, 0xad2d);
mdio_write(tp, 0x06, 0x08bf);
mdio_write(tp, 0x06, 0x84e0);
mdio_write(tp, 0x06, 0x022e);
mdio_write(tp, 0x06, 0xb0f6);
mdio_write(tp, 0x06, 0x06ef);
mdio_write(tp, 0x06, 0x96fe);
mdio_write(tp, 0x06, 0xfc04);
mdio_write(tp, 0x06, 0xf8f9);
mdio_write(tp, 0x06, 0xfaef);
mdio_write(tp, 0x06, 0x69e0);
mdio_write(tp, 0x06, 0x8b87);
mdio_write(tp, 0x06, 0xad20);
mdio_write(tp, 0x06, 0x4cd2);
mdio_write(tp, 0x06, 0x00e0);
mdio_write(tp, 0x06, 0xe200);
mdio_write(tp, 0x06, 0x5801);
mdio_write(tp, 0x06, 0x0c02);
mdio_write(tp, 0x06, 0x1e20);
mdio_write(tp, 0x06, 0xe0e0);