Commit 061a5c31 authored by David S. Miller's avatar David S. Miller

Merge branch 'davem-next.r8169' of git://violet.fr.zoreil.com/romieu/linux

Francois Romieu (4):
      r8169: mdio_ops signature change.
      r8169: csi_ops signature change.
      r8169: ephy, eri and efuse functions signature changes.
      r8169: abstract out loop conditions.

Hayes Wang (2):
      r8169: add RTL8106E support.
      r8169: support RTL8168G
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 59399c59 c558386b
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
#define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw"
#define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw"
#define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw"
#define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw"
#define FIRMWARE_8168G_1 "rtl_nic/rtl8168g-1.fw"
#ifdef RTL8169_DEBUG #ifdef RTL8169_DEBUG
#define assert(expr) \ #define assert(expr) \
...@@ -141,6 +143,9 @@ enum mac_version { ...@@ -141,6 +143,9 @@ enum mac_version {
RTL_GIGA_MAC_VER_36, RTL_GIGA_MAC_VER_36,
RTL_GIGA_MAC_VER_37, RTL_GIGA_MAC_VER_37,
RTL_GIGA_MAC_VER_38, RTL_GIGA_MAC_VER_38,
RTL_GIGA_MAC_VER_39,
RTL_GIGA_MAC_VER_40,
RTL_GIGA_MAC_VER_41,
RTL_GIGA_MAC_NONE = 0xff, RTL_GIGA_MAC_NONE = 0xff,
}; };
...@@ -259,6 +264,14 @@ static const struct { ...@@ -259,6 +264,14 @@ static const struct {
[RTL_GIGA_MAC_VER_38] = [RTL_GIGA_MAC_VER_38] =
_R("RTL8411", RTL_TD_1, FIRMWARE_8411_1, _R("RTL8411", RTL_TD_1, FIRMWARE_8411_1,
JUMBO_9K, false), JUMBO_9K, false),
[RTL_GIGA_MAC_VER_39] =
_R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1,
JUMBO_1K, true),
[RTL_GIGA_MAC_VER_40] =
_R("RTL8168g/8111g", RTL_TD_1, FIRMWARE_8168G_1,
JUMBO_9K, false),
[RTL_GIGA_MAC_VER_41] =
_R("RTL8168g/8111g", RTL_TD_1, NULL, JUMBO_9K, false),
}; };
#undef _R #undef _R
...@@ -389,8 +402,12 @@ enum rtl8168_8101_registers { ...@@ -389,8 +402,12 @@ enum rtl8168_8101_registers {
TWSI = 0xd2, TWSI = 0xd2,
MCU = 0xd3, MCU = 0xd3,
#define NOW_IS_OOB (1 << 7) #define NOW_IS_OOB (1 << 7)
#define TX_EMPTY (1 << 5)
#define RX_EMPTY (1 << 4)
#define RXTX_EMPTY (TX_EMPTY | RX_EMPTY)
#define EN_NDP (1 << 3) #define EN_NDP (1 << 3)
#define EN_OOB_RESET (1 << 2) #define EN_OOB_RESET (1 << 2)
#define LINK_LIST_RDY (1 << 1)
EFUSEAR = 0xdc, EFUSEAR = 0xdc,
#define EFUSEAR_FLAG 0x80000000 #define EFUSEAR_FLAG 0x80000000
#define EFUSEAR_WRITE_CMD 0x80000000 #define EFUSEAR_WRITE_CMD 0x80000000
...@@ -416,6 +433,7 @@ enum rtl8168_registers { ...@@ -416,6 +433,7 @@ enum rtl8168_registers {
#define ERIAR_MASK_SHIFT 12 #define ERIAR_MASK_SHIFT 12
#define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT)
EPHY_RXER_NUM = 0x7c, EPHY_RXER_NUM = 0x7c,
OCPDR = 0xb0, /* OCP GPHY access */ OCPDR = 0xb0, /* OCP GPHY access */
...@@ -428,10 +446,14 @@ enum rtl8168_registers { ...@@ -428,10 +446,14 @@ enum rtl8168_registers {
#define OCPAR_FLAG 0x80000000 #define OCPAR_FLAG 0x80000000
#define OCPAR_GPHY_WRITE_CMD 0x8000f060 #define OCPAR_GPHY_WRITE_CMD 0x8000f060
#define OCPAR_GPHY_READ_CMD 0x0000f060 #define OCPAR_GPHY_READ_CMD 0x0000f060
GPHY_OCP = 0xb8,
RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */
MISC = 0xf0, /* 8168e only. */ MISC = 0xf0, /* 8168e only. */
#define TXPLA_RST (1 << 29) #define TXPLA_RST (1 << 29)
#define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */
#define PWM_EN (1 << 22) #define PWM_EN (1 << 22)
#define RXDV_GATED_EN (1 << 19)
#define EARLY_TALLY_EN (1 << 16)
}; };
enum rtl_register_content { enum rtl_register_content {
...@@ -721,8 +743,8 @@ struct rtl8169_private { ...@@ -721,8 +743,8 @@ struct rtl8169_private {
u16 event_slow; u16 event_slow;
struct mdio_ops { struct mdio_ops {
void (*write)(void __iomem *, int, int); void (*write)(struct rtl8169_private *, int, int);
int (*read)(void __iomem *, int); int (*read)(struct rtl8169_private *, int);
} mdio_ops; } mdio_ops;
struct pll_power_ops { struct pll_power_ops {
...@@ -736,8 +758,8 @@ struct rtl8169_private { ...@@ -736,8 +758,8 @@ struct rtl8169_private {
} jumbo_ops; } jumbo_ops;
struct csi_ops { struct csi_ops {
void (*write)(void __iomem *, int, int); void (*write)(struct rtl8169_private *, int, int);
u32 (*read)(void __iomem *, int); u32 (*read)(struct rtl8169_private *, int);
} csi_ops; } csi_ops;
int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv);
...@@ -774,6 +796,8 @@ struct rtl8169_private { ...@@ -774,6 +796,8 @@ struct rtl8169_private {
} phy_action; } phy_action;
} *rtl_fw; } *rtl_fw;
#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN)
u32 ocp_base;
}; };
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
...@@ -794,6 +818,8 @@ MODULE_FIRMWARE(FIRMWARE_8168F_1); ...@@ -794,6 +818,8 @@ MODULE_FIRMWARE(FIRMWARE_8168F_1);
MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8168F_2);
MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8402_1);
MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8411_1);
MODULE_FIRMWARE(FIRMWARE_8106E_1);
MODULE_FIRMWARE(FIRMWARE_8168G_1);
static void rtl_lock_work(struct rtl8169_private *tp) static void rtl_lock_work(struct rtl8169_private *tp)
{ {
...@@ -818,47 +844,113 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) ...@@ -818,47 +844,113 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
} }
} }
struct rtl_cond {
bool (*check)(struct rtl8169_private *);
const char *msg;
};
static void rtl_udelay(unsigned int d)
{
udelay(d);
}
static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c,
void (*delay)(unsigned int), unsigned int d, int n,
bool high)
{
int i;
for (i = 0; i < n; i++) {
delay(d);
if (c->check(tp) == high)
return true;
}
netif_err(tp, drv, tp->dev, c->msg);
return false;
}
static bool rtl_udelay_loop_wait_high(struct rtl8169_private *tp,
const struct rtl_cond *c,
unsigned int d, int n)
{
return rtl_loop_wait(tp, c, rtl_udelay, d, n, true);
}
static bool rtl_udelay_loop_wait_low(struct rtl8169_private *tp,
const struct rtl_cond *c,
unsigned int d, int n)
{
return rtl_loop_wait(tp, c, rtl_udelay, d, n, false);
}
static bool rtl_msleep_loop_wait_high(struct rtl8169_private *tp,
const struct rtl_cond *c,
unsigned int d, int n)
{
return rtl_loop_wait(tp, c, msleep, d, n, true);
}
static bool rtl_msleep_loop_wait_low(struct rtl8169_private *tp,
const struct rtl_cond *c,
unsigned int d, int n)
{
return rtl_loop_wait(tp, c, msleep, d, n, false);
}
#define DECLARE_RTL_COND(name) \
static bool name ## _check(struct rtl8169_private *); \
\
static const struct rtl_cond name = { \
.check = name ## _check, \
.msg = #name \
}; \
\
static bool name ## _check(struct rtl8169_private *tp)
DECLARE_RTL_COND(rtl_ocpar_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(OCPAR) & OCPAR_FLAG;
}
static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
{ {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
for (i = 0; i < 20; i++) {
udelay(100); return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ?
if (RTL_R32(OCPAR) & OCPAR_FLAG) RTL_R32(OCPDR) : ~0;
break;
}
return RTL_R32(OCPDR);
} }
static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data) static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
{ {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W32(OCPDR, data); RTL_W32(OCPDR, data);
RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
for (i = 0; i < 20; i++) {
udelay(100); rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20);
if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0) }
break;
} DECLARE_RTL_COND(rtl_eriar_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(ERIAR) & ERIAR_FLAG;
} }
static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
{ {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W8(ERIDR, cmd); RTL_W8(ERIDR, cmd);
RTL_W32(ERIAR, 0x800010e8); RTL_W32(ERIAR, 0x800010e8);
msleep(2); msleep(2);
for (i = 0; i < 5; i++) {
udelay(100); if (!rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 5))
if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) return;
break;
}
ocp_write(tp, 0x1, 0x30, 0x00000001); ocp_write(tp, 0x1, 0x30, 0x00000001);
} }
...@@ -872,36 +964,27 @@ static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp) ...@@ -872,36 +964,27 @@ static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp)
return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10; return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10;
} }
static void rtl8168_driver_start(struct rtl8169_private *tp) DECLARE_RTL_COND(rtl_ocp_read_cond)
{ {
u16 reg; u16 reg;
int i;
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
reg = rtl8168_get_ocp_reg(tp); reg = rtl8168_get_ocp_reg(tp);
for (i = 0; i < 10; i++) { return ocp_read(tp, 0x0f, reg) & 0x00000800;
msleep(10);
if (ocp_read(tp, 0x0f, reg) & 0x00000800)
break;
}
} }
static void rtl8168_driver_stop(struct rtl8169_private *tp) static void rtl8168_driver_start(struct rtl8169_private *tp)
{ {
u16 reg; rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
int i;
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP); rtl_msleep_loop_wait_high(tp, &rtl_ocp_read_cond, 10, 10);
}
reg = rtl8168_get_ocp_reg(tp); static void rtl8168_driver_stop(struct rtl8169_private *tp)
{
rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
for (i = 0; i < 10; i++) { rtl_msleep_loop_wait_low(tp, &rtl_ocp_read_cond, 10, 10);
msleep(10);
if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0)
break;
}
} }
static int r8168dp_check_dash(struct rtl8169_private *tp) static int r8168dp_check_dash(struct rtl8169_private *tp)
...@@ -911,21 +994,124 @@ static int r8168dp_check_dash(struct rtl8169_private *tp) ...@@ -911,21 +994,124 @@ static int r8168dp_check_dash(struct rtl8169_private *tp)
return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
} }
static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg)
{ {
int i; if (reg & 0xffff0001) {
netif_err(tp, drv, tp->dev, "Invalid ocp reg %x!\n", reg);
return true;
}
return false;
}
RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff)); DECLARE_RTL_COND(rtl_ocp_gphy_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
for (i = 20; i > 0; i--) { return RTL_R32(GPHY_OCP) & OCPAR_FLAG;
/* }
* Check if the RTL8169 has completed writing to the specified
* MII register. static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
*/ {
if (!(RTL_R32(PHYAR) & 0x80000000)) void __iomem *ioaddr = tp->mmio_addr;
break;
udelay(25); if (rtl_ocp_reg_failure(tp, reg))
return;
RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data);
rtl_udelay_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10);
}
static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
if (rtl_ocp_reg_failure(tp, reg))
return 0;
RTL_W32(GPHY_OCP, reg << 15);
return rtl_udelay_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ?
(RTL_R32(GPHY_OCP) & 0xffff) : ~0;
}
static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m)
{
int val;
val = r8168_phy_ocp_read(tp, reg);
r8168_phy_ocp_write(tp, reg, (val | p) & ~m);
}
DECLARE_RTL_COND(rtl_ocpdr_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(OCPDR) & OCPAR_FLAG;
}
static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data)
{
void __iomem *ioaddr = tp->mmio_addr;
if (rtl_ocp_reg_failure(tp, reg))
return;
RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data);
rtl_udelay_loop_wait_low(tp, &rtl_ocpdr_cond, 25, 10);
}
static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg)
{
void __iomem *ioaddr = tp->mmio_addr;
if (rtl_ocp_reg_failure(tp, reg))
return 0;
RTL_W32(OCPDR, reg << 15);
return rtl_udelay_loop_wait_high(tp, &rtl_ocpdr_cond, 25, 10) ?
RTL_R32(OCPDR) : ~0;
}
#define OCP_STD_PHY_BASE 0xa400
static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value)
{
if (reg == 0x1f) {
tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE;
return;
} }
if (tp->ocp_base != OCP_STD_PHY_BASE)
reg -= 0x10;
r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value);
}
static int r8168g_mdio_read(struct rtl8169_private *tp, int reg)
{
if (tp->ocp_base != OCP_STD_PHY_BASE)
reg -= 0x10;
return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2);
}
DECLARE_RTL_COND(rtl_phyar_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(PHYAR) & 0x80000000;
}
static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
RTL_W32(PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff));
rtl_udelay_loop_wait_low(tp, &rtl_phyar_cond, 25, 20);
/* /*
* According to hardware specs a 20us delay is required after write * According to hardware specs a 20us delay is required after write
* complete indication, but before sending next command. * complete indication, but before sending next command.
...@@ -933,23 +1119,16 @@ static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) ...@@ -933,23 +1119,16 @@ static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
udelay(20); udelay(20);
} }
static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr) static int r8169_mdio_read(struct rtl8169_private *tp, int reg)
{ {
int i, value = -1; void __iomem *ioaddr = tp->mmio_addr;
int value;
RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16); RTL_W32(PHYAR, 0x0 | (reg & 0x1f) << 16);
value = rtl_udelay_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ?
RTL_R32(PHYAR) & 0xffff : ~0;
for (i = 20; i > 0; i--) {
/*
* Check if the RTL8169 has completed retrieving data from
* the specified MII register.
*/
if (RTL_R32(PHYAR) & 0x80000000) {
value = RTL_R32(PHYAR) & 0xffff;
break;
}
udelay(25);
}
/* /*
* According to hardware specs a 20us delay is required after read * According to hardware specs a 20us delay is required after read
* complete indication, but before sending next command. * complete indication, but before sending next command.
...@@ -959,45 +1138,35 @@ static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr) ...@@ -959,45 +1138,35 @@ static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr)
return value; return value;
} }
static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data) static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data)
{ {
int i; void __iomem *ioaddr = tp->mmio_addr;
RTL_W32(OCPDR, data | RTL_W32(OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD); RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
RTL_W32(EPHY_RXER_NUM, 0); RTL_W32(EPHY_RXER_NUM, 0);
for (i = 0; i < 100; i++) { rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100);
mdelay(1);
if (!(RTL_R32(OCPAR) & OCPAR_FLAG))
break;
}
} }
static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value) static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value)
{ {
r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD | r8168dp_1_mdio_access(tp, reg,
(value & OCPDR_DATA_MASK)); OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK));
} }
static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr) static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg)
{ {
int i; void __iomem *ioaddr = tp->mmio_addr;
r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD); r8168dp_1_mdio_access(tp, reg, OCPDR_READ_CMD);
mdelay(1); mdelay(1);
RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD); RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
RTL_W32(EPHY_RXER_NUM, 0); RTL_W32(EPHY_RXER_NUM, 0);
for (i = 0; i < 100; i++) { return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ?
mdelay(1); RTL_R32(OCPDR) & OCPDR_DATA_MASK : ~0;
if (RTL_R32(OCPAR) & OCPAR_FLAG)
break;
}
return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
} }
#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000
...@@ -1012,22 +1181,25 @@ static void r8168dp_2_mdio_stop(void __iomem *ioaddr) ...@@ -1012,22 +1181,25 @@ static void r8168dp_2_mdio_stop(void __iomem *ioaddr)
RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT); RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
} }
static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value) static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value)
{ {
void __iomem *ioaddr = tp->mmio_addr;
r8168dp_2_mdio_start(ioaddr); r8168dp_2_mdio_start(ioaddr);
r8169_mdio_write(ioaddr, reg_addr, value); r8169_mdio_write(tp, reg, value);
r8168dp_2_mdio_stop(ioaddr); r8168dp_2_mdio_stop(ioaddr);
} }
static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr) static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg)
{ {
void __iomem *ioaddr = tp->mmio_addr;
int value; int value;
r8168dp_2_mdio_start(ioaddr); r8168dp_2_mdio_start(ioaddr);
value = r8169_mdio_read(ioaddr, reg_addr); value = r8169_mdio_read(tp, reg);
r8168dp_2_mdio_stop(ioaddr); r8168dp_2_mdio_stop(ioaddr);
...@@ -1036,12 +1208,12 @@ static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr) ...@@ -1036,12 +1208,12 @@ static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr)
static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
{ {
tp->mdio_ops.write(tp->mmio_addr, location, val); tp->mdio_ops.write(tp, location, val);
} }
static int rtl_readphy(struct rtl8169_private *tp, int location) static int rtl_readphy(struct rtl8169_private *tp, int location)
{ {
return tp->mdio_ops.read(tp->mmio_addr, location); return tp->mdio_ops.read(tp, location);
} }
static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value) static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value)
...@@ -1072,79 +1244,64 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location) ...@@ -1072,79 +1244,64 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
return rtl_readphy(tp, location); return rtl_readphy(tp, location);
} }
static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value) DECLARE_RTL_COND(rtl_ephyar_cond)
{ {
unsigned int i; void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(EPHYAR) & EPHYAR_FLAG;
}
static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
(reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
for (i = 0; i < 100; i++) { rtl_udelay_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100);
if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
break; udelay(10);
udelay(10);
}
} }
static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr) static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr)
{ {
u16 value = 0xffff; void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
for (i = 0; i < 100; i++) { return rtl_udelay_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ?
if (RTL_R32(EPHYAR) & EPHYAR_FLAG) { RTL_R32(EPHYAR) & EPHYAR_DATA_MASK : ~0;
value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
break;
}
udelay(10);
}
return value;
} }
static static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask,
void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type) u32 val, int type)
{ {
unsigned int i; void __iomem *ioaddr = tp->mmio_addr;
BUG_ON((addr & 3) || (mask == 0)); BUG_ON((addr & 3) || (mask == 0));
RTL_W32(ERIDR, val); RTL_W32(ERIDR, val);
RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr); RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr);
for (i = 0; i < 100; i++) { rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100);
if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
break;
udelay(100);
}
} }
static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type) static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type)
{ {
u32 value = ~0x00; void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr);
for (i = 0; i < 100; i++) { return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ?
if (RTL_R32(ERIAR) & ERIAR_FLAG) { RTL_R32(ERIDR) : ~0;
value = RTL_R32(ERIDR);
break;
}
udelay(100);
}
return value;
} }
static void static void rtl_w1w0_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p,
rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type) u32 m, int type)
{ {
u32 val; u32 val;
val = rtl_eri_read(ioaddr, addr, type); val = rtl_eri_read(tp, addr, type);
rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type); rtl_eri_write(tp, addr, mask, (val & ~m) | p, type);
} }
struct exgmac_reg { struct exgmac_reg {
...@@ -1153,31 +1310,30 @@ struct exgmac_reg { ...@@ -1153,31 +1310,30 @@ struct exgmac_reg {
u32 val; u32 val;
}; };
static void rtl_write_exgmac_batch(void __iomem *ioaddr, static void rtl_write_exgmac_batch(struct rtl8169_private *tp,
const struct exgmac_reg *r, int len) const struct exgmac_reg *r, int len)
{ {
while (len-- > 0) { while (len-- > 0) {
rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC); rtl_eri_write(tp, r->addr, r->mask, r->val, ERIAR_EXGMAC);
r++; r++;
} }
} }
static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) DECLARE_RTL_COND(rtl_efusear_cond)
{ {
u8 value = 0xff; void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT); return RTL_R32(EFUSEAR) & EFUSEAR_FLAG;
}
for (i = 0; i < 300; i++) { static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr)
if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) { {
value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK; void __iomem *ioaddr = tp->mmio_addr;
break;
}
udelay(100);
}
return value; RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT);
return rtl_udelay_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ?
RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK : ~0;
} }
static u16 rtl_get_events(struct rtl8169_private *tp) static u16 rtl_get_events(struct rtl8169_private *tp)
...@@ -1276,48 +1432,48 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp) ...@@ -1276,48 +1432,48 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp)
if (tp->mac_version == RTL_GIGA_MAC_VER_34 || if (tp->mac_version == RTL_GIGA_MAC_VER_34 ||
tp->mac_version == RTL_GIGA_MAC_VER_38) { tp->mac_version == RTL_GIGA_MAC_VER_38) {
if (RTL_R8(PHYstatus) & _1000bpsF) { if (RTL_R8(PHYstatus) & _1000bpsF) {
rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011,
0x00000011, ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
0x00000005, ERIAR_EXGMAC); ERIAR_EXGMAC);
} else if (RTL_R8(PHYstatus) & _100bps) { } else if (RTL_R8(PHYstatus) & _100bps) {
rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
0x0000001f, ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
0x00000005, ERIAR_EXGMAC); ERIAR_EXGMAC);
} else { } else {
rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
0x0000001f, ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f,
0x0000003f, ERIAR_EXGMAC); ERIAR_EXGMAC);
} }
/* Reset packet filter */ /* Reset packet filter */
rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01,
ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00,
ERIAR_EXGMAC); ERIAR_EXGMAC);
} else if (tp->mac_version == RTL_GIGA_MAC_VER_35 || } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 ||
tp->mac_version == RTL_GIGA_MAC_VER_36) { tp->mac_version == RTL_GIGA_MAC_VER_36) {
if (RTL_R8(PHYstatus) & _1000bpsF) { if (RTL_R8(PHYstatus) & _1000bpsF) {
rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011,
0x00000011, ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005,
0x00000005, ERIAR_EXGMAC); ERIAR_EXGMAC);
} else { } else {
rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f,
0x0000001f, ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f,
0x0000003f, ERIAR_EXGMAC); ERIAR_EXGMAC);
} }
} else if (tp->mac_version == RTL_GIGA_MAC_VER_37) { } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) {
if (RTL_R8(PHYstatus) & _10bps) { if (RTL_R8(PHYstatus) & _10bps) {
rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02,
0x4d02, ERIAR_EXGMAC); ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_0011, rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060,
0x0060, ERIAR_EXGMAC); ERIAR_EXGMAC);
} else { } else {
rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000,
0x0000, ERIAR_EXGMAC); ERIAR_EXGMAC);
} }
} }
} }
...@@ -1784,6 +1940,13 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset) ...@@ -1784,6 +1940,13 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
} }
} }
DECLARE_RTL_COND(rtl_counters_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(CounterAddrLow) & CounterDump;
}
static void rtl8169_update_counters(struct net_device *dev) static void rtl8169_update_counters(struct net_device *dev)
{ {
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
...@@ -1792,7 +1955,6 @@ static void rtl8169_update_counters(struct net_device *dev) ...@@ -1792,7 +1955,6 @@ static void rtl8169_update_counters(struct net_device *dev)
struct rtl8169_counters *counters; struct rtl8169_counters *counters;
dma_addr_t paddr; dma_addr_t paddr;
u32 cmd; u32 cmd;
int wait = 1000;
/* /*
* Some chips are unable to dump tally counters when the receiver * Some chips are unable to dump tally counters when the receiver
...@@ -1810,13 +1972,8 @@ static void rtl8169_update_counters(struct net_device *dev) ...@@ -1810,13 +1972,8 @@ static void rtl8169_update_counters(struct net_device *dev)
RTL_W32(CounterAddrLow, cmd); RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump); RTL_W32(CounterAddrLow, cmd | CounterDump);
while (wait--) { if (rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000))
if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) { memcpy(&tp->counters, counters, sizeof(*counters));
memcpy(&tp->counters, counters, sizeof(*counters));
break;
}
udelay(10);
}
RTL_W32(CounterAddrLow, 0); RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0); RTL_W32(CounterAddrHigh, 0);
...@@ -1894,6 +2051,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, ...@@ -1894,6 +2051,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
u32 val; u32 val;
int mac_version; int mac_version;
} mac_info[] = { } mac_info[] = {
/* 8168G family. */
{ 0x7cf00000, 0x4c100000, RTL_GIGA_MAC_VER_41 },
{ 0x7cf00000, 0x4c000000, RTL_GIGA_MAC_VER_40 },
/* 8168F family. */ /* 8168F family. */
{ 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 }, { 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 },
{ 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 }, { 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 },
...@@ -1933,6 +2094,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, ...@@ -1933,6 +2094,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
/* 8101 family. */ /* 8101 family. */
{ 0x7cf00000, 0x44900000, RTL_GIGA_MAC_VER_39 },
{ 0x7c800000, 0x44800000, RTL_GIGA_MAC_VER_39 },
{ 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 }, { 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 },
{ 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 },
{ 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 },
...@@ -2186,7 +2349,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2186,7 +2349,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
index -= regno; index -= regno;
break; break;
case PHY_READ_EFUSE: case PHY_READ_EFUSE:
predata = rtl8168d_efuse_read(tp->mmio_addr, regno); predata = rtl8168d_efuse_read(tp, regno);
index++; index++;
break; break;
case PHY_CLEAR_READCOUNT: case PHY_CLEAR_READCOUNT:
...@@ -2626,7 +2789,6 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) ...@@ -2626,7 +2789,6 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
{ 0x1f, 0x0000 }, { 0x1f, 0x0000 },
{ 0x0d, 0xf880 } { 0x0d, 0xf880 }
}; };
void __iomem *ioaddr = tp->mmio_addr;
rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
...@@ -2638,7 +2800,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) ...@@ -2638,7 +2800,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp)
rtl_w1w0_phy(tp, 0x0b, 0x0010, 0x00ef); rtl_w1w0_phy(tp, 0x0b, 0x0010, 0x00ef);
rtl_w1w0_phy(tp, 0x0c, 0xa200, 0x5d00); rtl_w1w0_phy(tp, 0x0c, 0xa200, 0x5d00);
if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) {
static const struct phy_reg phy_reg_init[] = { static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0002 }, { 0x1f, 0x0002 },
{ 0x05, 0x669a }, { 0x05, 0x669a },
...@@ -2738,11 +2900,10 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) ...@@ -2738,11 +2900,10 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp)
{ 0x1f, 0x0000 }, { 0x1f, 0x0000 },
{ 0x0d, 0xf880 } { 0x0d, 0xf880 }
}; };
void __iomem *ioaddr = tp->mmio_addr;
rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0));
if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) {
static const struct phy_reg phy_reg_init[] = { static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0002 }, { 0x1f, 0x0002 },
{ 0x05, 0x669a }, { 0x05, 0x669a },
...@@ -3010,8 +3171,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) ...@@ -3010,8 +3171,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x1f, 0x0000);
/* EEE setting */ /* EEE setting */
rtl_w1w0_eri(tp->mmio_addr, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, ERIAR_EXGMAC);
ERIAR_EXGMAC);
rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x1f, 0x0005);
rtl_writephy(tp, 0x05, 0x8b85); rtl_writephy(tp, 0x05, 0x8b85);
rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
...@@ -3115,7 +3275,6 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) ...@@ -3115,7 +3275,6 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp)
static void rtl8411_hw_phy_config(struct rtl8169_private *tp) static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr;
static const struct phy_reg phy_reg_init[] = { static const struct phy_reg phy_reg_init[] = {
/* Channel estimation fine tune */ /* Channel estimation fine tune */
{ 0x1f, 0x0003 }, { 0x1f, 0x0003 },
...@@ -3189,7 +3348,7 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) ...@@ -3189,7 +3348,7 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x1f, 0x0000);
/* eee setting */ /* eee setting */
rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x00, 0x03, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x00, 0x03, ERIAR_EXGMAC);
rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x1f, 0x0005);
rtl_writephy(tp, 0x05, 0x8b85); rtl_writephy(tp, 0x05, 0x8b85);
rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
...@@ -3211,6 +3370,55 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) ...@@ -3211,6 +3370,55 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x1f, 0x0000);
} }
static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp)
{
static const u16 mac_ocp_patch[] = {
0xe008, 0xe01b, 0xe01d, 0xe01f,
0xe021, 0xe023, 0xe025, 0xe027,
0x49d2, 0xf10d, 0x766c, 0x49e2,
0xf00a, 0x1ec0, 0x8ee1, 0xc60a,
0x77c0, 0x4870, 0x9fc0, 0x1ea0,
0xc707, 0x8ee1, 0x9d6c, 0xc603,
0xbe00, 0xb416, 0x0076, 0xe86c,
0xc602, 0xbe00, 0x0000, 0xc602,
0xbe00, 0x0000, 0xc602, 0xbe00,
0x0000, 0xc602, 0xbe00, 0x0000,
0xc602, 0xbe00, 0x0000, 0xc602,
0xbe00, 0x0000, 0xc602, 0xbe00,
0x0000, 0x0000, 0x0000, 0x0000
};
u32 i;
/* Patch code for GPHY reset */
for (i = 0; i < ARRAY_SIZE(mac_ocp_patch); i++)
r8168_mac_ocp_write(tp, 0xf800 + 2*i, mac_ocp_patch[i]);
r8168_mac_ocp_write(tp, 0xfc26, 0x8000);
r8168_mac_ocp_write(tp, 0xfc28, 0x0075);
rtl_apply_firmware(tp);
if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100)
rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x0000, 0x8000);
else
rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x8000, 0x0000);
if (r8168_phy_ocp_read(tp, 0xa466) & 0x0100)
rtl_w1w0_phy_ocp(tp, 0xc41a, 0x0002, 0x0000);
else
rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x0000, 0x0002);
rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x0000);
rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x0000);
r8168_phy_ocp_write(tp, 0xa436, 0x8012);
rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x0000);
rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000);
}
static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
{ {
static const struct phy_reg phy_reg_init[] = { static const struct phy_reg phy_reg_init[] = {
...@@ -3256,8 +3464,6 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) ...@@ -3256,8 +3464,6 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp)
static void rtl8402_hw_phy_config(struct rtl8169_private *tp) static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr;
/* Disable ALDPS before setting firmware */ /* Disable ALDPS before setting firmware */
rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, 0x18, 0x0310); rtl_writephy(tp, 0x18, 0x0310);
...@@ -3266,13 +3472,35 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) ...@@ -3266,13 +3472,35 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp)
rtl_apply_firmware(tp); rtl_apply_firmware(tp);
/* EEE setting */ /* EEE setting */
rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_writephy(tp, 0x1f, 0x0004); rtl_writephy(tp, 0x1f, 0x0004);
rtl_writephy(tp, 0x10, 0x401f); rtl_writephy(tp, 0x10, 0x401f);
rtl_writephy(tp, 0x19, 0x7030); rtl_writephy(tp, 0x19, 0x7030);
rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x1f, 0x0000);
} }
static void rtl8106e_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
{ 0x1f, 0x0004 },
{ 0x10, 0xc07f },
{ 0x19, 0x7030 },
{ 0x1f, 0x0000 }
};
/* Disable ALDPS before ram code */
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, 0x18, 0x0310);
msleep(100);
rtl_apply_firmware(tp);
rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
}
static void rtl_hw_phy_config(struct net_device *dev) static void rtl_hw_phy_config(struct net_device *dev)
{ {
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
...@@ -3369,6 +3597,15 @@ static void rtl_hw_phy_config(struct net_device *dev) ...@@ -3369,6 +3597,15 @@ static void rtl_hw_phy_config(struct net_device *dev)
rtl8411_hw_phy_config(tp); rtl8411_hw_phy_config(tp);
break; break;
case RTL_GIGA_MAC_VER_39:
rtl8106e_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_40:
rtl8168g_1_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_41:
default: default:
break; break;
} }
...@@ -3426,18 +3663,16 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, ...@@ -3426,18 +3663,16 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
free_netdev(dev); free_netdev(dev);
} }
DECLARE_RTL_COND(rtl_phy_reset_cond)
{
return tp->phy_reset_pending(tp);
}
static void rtl8169_phy_reset(struct net_device *dev, static void rtl8169_phy_reset(struct net_device *dev,
struct rtl8169_private *tp) struct rtl8169_private *tp)
{ {
unsigned int i;
tp->phy_reset_enable(tp); tp->phy_reset_enable(tp);
for (i = 0; i < 100; i++) { rtl_msleep_loop_wait_low(tp, &rtl_phy_reset_cond, 1, 100);
if (!tp->phy_reset_pending(tp))
return;
msleep(1);
}
netif_err(tp, link, dev, "PHY reset failed\n");
} }
static bool rtl_tbi_enabled(struct rtl8169_private *tp) static bool rtl_tbi_enabled(struct rtl8169_private *tp)
...@@ -3512,7 +3747,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) ...@@ -3512,7 +3747,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
low >> 16 }, low >> 16 },
}; };
rtl_write_exgmac_batch(ioaddr, e, ARRAY_SIZE(e)); rtl_write_exgmac_batch(tp, e, ARRAY_SIZE(e));
} }
RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W8(Cfg9346, Cfg9346_Lock);
...@@ -3589,6 +3824,11 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) ...@@ -3589,6 +3824,11 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
ops->write = r8168dp_2_mdio_write; ops->write = r8168dp_2_mdio_write;
ops->read = r8168dp_2_mdio_read; ops->read = r8168dp_2_mdio_read;
break; break;
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
ops->write = r8168g_mdio_write;
ops->read = r8168g_mdio_read;
break;
default: default:
ops->write = r8169_mdio_write; ops->write = r8169_mdio_write;
ops->read = r8169_mdio_read; ops->read = r8169_mdio_read;
...@@ -3608,6 +3848,9 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) ...@@ -3608,6 +3848,9 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_34: case RTL_GIGA_MAC_VER_34:
case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_37:
case RTL_GIGA_MAC_VER_38: case RTL_GIGA_MAC_VER_38:
case RTL_GIGA_MAC_VER_39:
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
RTL_W32(RxConfig, RTL_R32(RxConfig) | RTL_W32(RxConfig, RTL_R32(RxConfig) |
AcceptBroadcast | AcceptMulticast | AcceptMyPhys); AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
break; break;
...@@ -3761,7 +4004,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) ...@@ -3761,7 +4004,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
if (tp->mac_version == RTL_GIGA_MAC_VER_32 || if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
tp->mac_version == RTL_GIGA_MAC_VER_33) tp->mac_version == RTL_GIGA_MAC_VER_33)
rtl_ephy_write(ioaddr, 0x19, 0xff64); rtl_ephy_write(tp, 0x19, 0xff64);
if (rtl_wol_pll_power_down(tp)) if (rtl_wol_pll_power_down(tp))
return; return;
...@@ -3830,6 +4073,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) ...@@ -3830,6 +4073,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_29: case RTL_GIGA_MAC_VER_29:
case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_30:
case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_37:
case RTL_GIGA_MAC_VER_39:
ops->down = r810x_pll_power_down; ops->down = r810x_pll_power_down;
ops->up = r810x_pll_power_up; ops->up = r810x_pll_power_up;
break; break;
...@@ -3855,6 +4099,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) ...@@ -3855,6 +4099,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_35: case RTL_GIGA_MAC_VER_35:
case RTL_GIGA_MAC_VER_36: case RTL_GIGA_MAC_VER_36:
case RTL_GIGA_MAC_VER_38: case RTL_GIGA_MAC_VER_38:
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
ops->down = r8168_pll_power_down; ops->down = r8168_pll_power_down;
ops->up = r8168_pll_power_up; ops->up = r8168_pll_power_up;
break; break;
...@@ -4051,6 +4297,8 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) ...@@ -4051,6 +4297,8 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp)
* No action needed for jumbo frames with 8169. * No action needed for jumbo frames with 8169.
* No jumbo for 810x at all. * No jumbo for 810x at all.
*/ */
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
default: default:
ops->disable = NULL; ops->disable = NULL;
ops->enable = NULL; ops->enable = NULL;
...@@ -4058,20 +4306,20 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) ...@@ -4058,20 +4306,20 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp)
} }
} }
DECLARE_RTL_COND(rtl_chipcmd_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R8(ChipCmd) & CmdReset;
}
static void rtl_hw_reset(struct rtl8169_private *tp) static void rtl_hw_reset(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
int i;
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset); RTL_W8(ChipCmd, CmdReset);
/* Check that the chip has finished the reset. */ rtl_udelay_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100);
for (i = 0; i < 100; i++) {
if ((RTL_R8(ChipCmd) & CmdReset) == 0)
break;
udelay(100);
}
} }
static void rtl_request_uncached_firmware(struct rtl8169_private *tp) static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
...@@ -4125,6 +4373,20 @@ static void rtl_rx_close(struct rtl8169_private *tp) ...@@ -4125,6 +4373,20 @@ static void rtl_rx_close(struct rtl8169_private *tp)
RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK); RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK);
} }
DECLARE_RTL_COND(rtl_npq_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R8(TxPoll) & NPQ;
}
DECLARE_RTL_COND(rtl_txcfg_empty_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(TxConfig) & TXCFG_EMPTY;
}
static void rtl8169_hw_reset(struct rtl8169_private *tp) static void rtl8169_hw_reset(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
...@@ -4137,16 +4399,16 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) ...@@ -4137,16 +4399,16 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
if (tp->mac_version == RTL_GIGA_MAC_VER_27 || if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
tp->mac_version == RTL_GIGA_MAC_VER_28 || tp->mac_version == RTL_GIGA_MAC_VER_28 ||
tp->mac_version == RTL_GIGA_MAC_VER_31) { tp->mac_version == RTL_GIGA_MAC_VER_31) {
while (RTL_R8(TxPoll) & NPQ) rtl_udelay_loop_wait_low(tp, &rtl_npq_cond, 20, 42*42);
udelay(20);
} else if (tp->mac_version == RTL_GIGA_MAC_VER_34 || } else if (tp->mac_version == RTL_GIGA_MAC_VER_34 ||
tp->mac_version == RTL_GIGA_MAC_VER_35 || tp->mac_version == RTL_GIGA_MAC_VER_35 ||
tp->mac_version == RTL_GIGA_MAC_VER_36 || tp->mac_version == RTL_GIGA_MAC_VER_36 ||
tp->mac_version == RTL_GIGA_MAC_VER_37 || tp->mac_version == RTL_GIGA_MAC_VER_37 ||
tp->mac_version == RTL_GIGA_MAC_VER_40 ||
tp->mac_version == RTL_GIGA_MAC_VER_41 ||
tp->mac_version == RTL_GIGA_MAC_VER_38) { tp->mac_version == RTL_GIGA_MAC_VER_38) {
RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
udelay(100);
} else { } else {
RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
udelay(100); udelay(100);
...@@ -4352,15 +4614,12 @@ static void rtl_hw_start_8169(struct net_device *dev) ...@@ -4352,15 +4614,12 @@ static void rtl_hw_start_8169(struct net_device *dev)
static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value)
{ {
if (tp->csi_ops.write) if (tp->csi_ops.write)
tp->csi_ops.write(tp->mmio_addr, addr, value); tp->csi_ops.write(tp, addr, value);
} }
static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) static u32 rtl_csi_read(struct rtl8169_private *tp, int addr)
{ {
if (tp->csi_ops.read) return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) : ~0;
return tp->csi_ops.read(tp->mmio_addr, addr);
else
return ~0;
} }
static void rtl_csi_access_enable(struct rtl8169_private *tp, u32 bits) static void rtl_csi_access_enable(struct rtl8169_private *tp, u32 bits)
...@@ -4381,73 +4640,56 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp) ...@@ -4381,73 +4640,56 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp)
rtl_csi_access_enable(tp, 0x27000000); rtl_csi_access_enable(tp, 0x27000000);
} }
static void r8169_csi_write(void __iomem *ioaddr, int addr, int value) DECLARE_RTL_COND(rtl_csiar_cond)
{ {
unsigned int i; void __iomem *ioaddr = tp->mmio_addr;
return RTL_R32(CSIAR) & CSIAR_FLAG;
}
static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value)
{
void __iomem *ioaddr = tp->mmio_addr;
RTL_W32(CSIDR, value); RTL_W32(CSIDR, value);
RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
for (i = 0; i < 100; i++) { rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
break;
udelay(10);
}
} }
static u32 r8169_csi_read(void __iomem *ioaddr, int addr) static u32 r8169_csi_read(struct rtl8169_private *tp, int addr)
{ {
u32 value = ~0x00; void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
for (i = 0; i < 100; i++) { return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
if (RTL_R32(CSIAR) & CSIAR_FLAG) { RTL_R32(CSIDR) : ~0;
value = RTL_R32(CSIDR);
break;
}
udelay(10);
}
return value;
} }
static void r8402_csi_write(void __iomem *ioaddr, int addr, int value) static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value)
{ {
unsigned int i; void __iomem *ioaddr = tp->mmio_addr;
RTL_W32(CSIDR, value); RTL_W32(CSIDR, value);
RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT | CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT |
CSIAR_FUNC_NIC); CSIAR_FUNC_NIC);
for (i = 0; i < 100; i++) { rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100);
if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
break;
udelay(10);
}
} }
static u32 r8402_csi_read(void __iomem *ioaddr, int addr) static u32 r8402_csi_read(struct rtl8169_private *tp, int addr)
{ {
u32 value = ~0x00; void __iomem *ioaddr = tp->mmio_addr;
unsigned int i;
RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC | RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC |
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
for (i = 0; i < 100; i++) { return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ?
if (RTL_R32(CSIAR) & CSIAR_FLAG) { RTL_R32(CSIDR) : ~0;
value = RTL_R32(CSIDR);
break;
}
udelay(10);
}
return value;
} }
static void __devinit rtl_init_csi_ops(struct rtl8169_private *tp) static void __devinit rtl_init_csi_ops(struct rtl8169_private *tp)
...@@ -4492,13 +4734,14 @@ struct ephy_info { ...@@ -4492,13 +4734,14 @@ struct ephy_info {
u16 bits; u16 bits;
}; };
static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int len) static void rtl_ephy_init(struct rtl8169_private *tp, const struct ephy_info *e,
int len)
{ {
u16 w; u16 w;
while (len-- > 0) { while (len-- > 0) {
w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits; w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits;
rtl_ephy_write(ioaddr, e->offset, w); rtl_ephy_write(tp, e->offset, w);
e++; e++;
} }
} }
...@@ -4582,7 +4825,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) ...@@ -4582,7 +4825,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp)
static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168cp[] = { static const struct ephy_info e_info_8168cp[] = {
{ 0x01, 0, 0x0001 }, { 0x01, 0, 0x0001 },
{ 0x02, 0x0800, 0x1000 }, { 0x02, 0x0800, 0x1000 },
...@@ -4593,7 +4835,7 @@ static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) ...@@ -4593,7 +4835,7 @@ static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp)
rtl_csi_access_enable_2(tp); rtl_csi_access_enable_2(tp);
rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); rtl_ephy_init(tp, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
__rtl_hw_start_8168cp(tp); __rtl_hw_start_8168cp(tp);
} }
...@@ -4644,14 +4886,13 @@ static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) ...@@ -4644,14 +4886,13 @@ static void rtl_hw_start_8168c_1(struct rtl8169_private *tp)
RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); rtl_ephy_init(tp, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1));
__rtl_hw_start_8168cp(tp); __rtl_hw_start_8168cp(tp);
} }
static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) static void rtl_hw_start_8168c_2(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168c_2[] = { static const struct ephy_info e_info_8168c_2[] = {
{ 0x01, 0, 0x0001 }, { 0x01, 0, 0x0001 },
{ 0x03, 0x0400, 0x0220 } { 0x03, 0x0400, 0x0220 }
...@@ -4659,7 +4900,7 @@ static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) ...@@ -4659,7 +4900,7 @@ static void rtl_hw_start_8168c_2(struct rtl8169_private *tp)
rtl_csi_access_enable_2(tp); rtl_csi_access_enable_2(tp);
rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); rtl_ephy_init(tp, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
__rtl_hw_start_8168cp(tp); __rtl_hw_start_8168cp(tp);
} }
...@@ -4727,8 +4968,8 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private *tp) ...@@ -4727,8 +4968,8 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private *tp)
const struct ephy_info *e = e_info_8168d_4 + i; const struct ephy_info *e = e_info_8168d_4 + i;
u16 w; u16 w;
w = rtl_ephy_read(ioaddr, e->offset); w = rtl_ephy_read(tp, e->offset);
rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits); rtl_ephy_write(tp, 0x03, (w & e->mask) | e->bits);
} }
rtl_enable_clock_request(pdev); rtl_enable_clock_request(pdev);
...@@ -4756,7 +4997,7 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) ...@@ -4756,7 +4997,7 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp)
rtl_csi_access_enable_2(tp); rtl_csi_access_enable_2(tp);
rtl_ephy_init(ioaddr, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1));
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
...@@ -4782,19 +5023,18 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) ...@@ -4782,19 +5023,18 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp)
rtl_csi_access_enable_1(tp); rtl_csi_access_enable_1(tp);
rtl_ephy_init(ioaddr, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2));
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC); rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC);
ERIAR_EXGMAC);
RTL_W8(MaxTxPacketSize, EarlySize); RTL_W8(MaxTxPacketSize, EarlySize);
...@@ -4820,16 +5060,16 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp) ...@@ -4820,16 +5060,16 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp)
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0x1d0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0x1d0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC); rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC);
RTL_W8(MaxTxPacketSize, EarlySize); RTL_W8(MaxTxPacketSize, EarlySize);
...@@ -4854,10 +5094,9 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) ...@@ -4854,10 +5094,9 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
rtl_hw_start_8168f(tp); rtl_hw_start_8168f(tp);
rtl_ephy_init(ioaddr, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC);
ERIAR_EXGMAC);
/* Adjust EEE LED frequency */ /* Adjust EEE LED frequency */
RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
...@@ -4865,7 +5104,6 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) ...@@ -4865,7 +5104,6 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp)
static void rtl_hw_start_8411(struct rtl8169_private *tp) static void rtl_hw_start_8411(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr;
static const struct ephy_info e_info_8168f_1[] = { static const struct ephy_info e_info_8168f_1[] = {
{ 0x06, 0x00c0, 0x0020 }, { 0x06, 0x00c0, 0x0020 },
{ 0x0f, 0xffff, 0x5200 }, { 0x0f, 0xffff, 0x5200 },
...@@ -4875,10 +5113,39 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) ...@@ -4875,10 +5113,39 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp)
rtl_hw_start_8168f(tp); rtl_hw_start_8168f(tp);
rtl_ephy_init(ioaddr, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1));
rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC);
ERIAR_EXGMAC); }
static void rtl_hw_start_8168g_1(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
struct pci_dev *pdev = tp->pci_dev;
rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
rtl_csi_access_enable_1(tp);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);
RTL_W8(MaxTxPacketSize, EarlySize);
rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
/* Adjust EEE LED frequency */
RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC);
} }
static void rtl_hw_start_8168(struct net_device *dev) static void rtl_hw_start_8168(struct net_device *dev)
...@@ -4982,6 +5249,11 @@ static void rtl_hw_start_8168(struct net_device *dev) ...@@ -4982,6 +5249,11 @@ static void rtl_hw_start_8168(struct net_device *dev)
rtl_hw_start_8411(tp); rtl_hw_start_8411(tp);
break; break;
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
rtl_hw_start_8168g_1(tp);
break;
default: default:
printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
dev->name, tp->mac_version); dev->name, tp->mac_version);
...@@ -5036,7 +5308,7 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) ...@@ -5036,7 +5308,7 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private *tp)
if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
RTL_W8(Config1, cfg1 & ~LEDS0); RTL_W8(Config1, cfg1 & ~LEDS0);
rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); rtl_ephy_init(tp, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
} }
static void rtl_hw_start_8102e_2(struct rtl8169_private *tp) static void rtl_hw_start_8102e_2(struct rtl8169_private *tp)
...@@ -5056,7 +5328,7 @@ static void rtl_hw_start_8102e_3(struct rtl8169_private *tp) ...@@ -5056,7 +5328,7 @@ static void rtl_hw_start_8102e_3(struct rtl8169_private *tp)
{ {
rtl_hw_start_8102e_2(tp); rtl_hw_start_8102e_2(tp);
rtl_ephy_write(tp->mmio_addr, 0x03, 0xc2f9); rtl_ephy_write(tp, 0x03, 0xc2f9);
} }
static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
...@@ -5082,15 +5354,13 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) ...@@ -5082,15 +5354,13 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp)
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
} }
static void rtl_hw_start_8105e_2(struct rtl8169_private *tp) static void rtl_hw_start_8105e_2(struct rtl8169_private *tp)
{ {
void __iomem *ioaddr = tp->mmio_addr;
rtl_hw_start_8105e_1(tp); rtl_hw_start_8105e_1(tp);
rtl_ephy_write(ioaddr, 0x1e, rtl_ephy_read(ioaddr, 0x1e) | 0x8000); rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000);
} }
static void rtl_hw_start_8402(struct rtl8169_private *tp) static void rtl_hw_start_8402(struct rtl8169_private *tp)
...@@ -5109,18 +5379,29 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp) ...@@ -5109,18 +5379,29 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
rtl_ephy_init(ioaddr, e_info_8402, ARRAY_SIZE(e_info_8402)); rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402));
rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT);
rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC); rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC); rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, ERIAR_EXGMAC);
ERIAR_EXGMAC); }
static void rtl_hw_start_8106(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
/* Force LAN exit from ASPM if Rx/Tx are not idle */
RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800);
RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN);
RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
} }
static void rtl_hw_start_8101(struct net_device *dev) static void rtl_hw_start_8101(struct net_device *dev)
...@@ -5167,6 +5448,10 @@ static void rtl_hw_start_8101(struct net_device *dev) ...@@ -5167,6 +5448,10 @@ static void rtl_hw_start_8101(struct net_device *dev)
case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_37:
rtl_hw_start_8402(tp); rtl_hw_start_8402(tp);
break; break;
case RTL_GIGA_MAC_VER_39:
rtl_hw_start_8106(tp);
break;
} }
RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W8(Cfg9346, Cfg9346_Lock);
...@@ -6435,6 +6720,67 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, ...@@ -6435,6 +6720,67 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp,
return msi; return msi;
} }
DECLARE_RTL_COND(rtl_link_list_ready_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return RTL_R8(MCU) & LINK_LIST_RDY;
}
DECLARE_RTL_COND(rtl_rxtx_empty_cond)
{
void __iomem *ioaddr = tp->mmio_addr;
return (RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY;
}
static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
u32 data;
tp->ocp_base = OCP_STD_PHY_BASE;
RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN);
if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42))
return;
if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42))
return;
RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb));
msleep(1);
RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB);
data = r8168_mac_ocp_read(ioaddr, 0xe8de);
data &= ~(1 << 14);
r8168_mac_ocp_write(tp, 0xe8de, data);
if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42))
return;
data = r8168_mac_ocp_read(ioaddr, 0xe8de);
data |= (1 << 15);
r8168_mac_ocp_write(tp, 0xe8de, data);
if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42))
return;
}
static void __devinit rtl_hw_initialize(struct rtl8169_private *tp)
{
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41:
rtl_hw_init_8168g(tp);
break;
default:
break;
}
}
static int __devinit static int __devinit
rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
...@@ -6544,6 +6890,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -6544,6 +6890,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl_irq_disable(tp); rtl_irq_disable(tp);
rtl_hw_initialize(tp);
rtl_hw_reset(tp); rtl_hw_reset(tp);
rtl_ack_events(tp, 0xffff); rtl_ack_events(tp, 0xffff);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment