Commit efdc1590 authored by François Romieu's avatar François Romieu Committed by Jeff Garzik

[netdrvr r8169] Merge of changes done by Realtek to rtl8169_init_one():

- phy capability settings allows lower or equal capability as suggested
  in Realtek's changes;
- I/O voodoo;
- no need to s/mdio_write/RTL8169_WRITE_GMII_REG/;
- s/rtl8169_hw_PHY_config/rtl8169_hw_phy_config/;
- rtl8169_hw_phy_config(): ad-hoc struct "phy_magic" to limit duplication
  of code (yep, the u16 -> int conversions should work as expected);
- variable renames and whitepace changes ignored.
parent c69ac7bb
......@@ -336,6 +336,11 @@ static const u16 rtl8169_intr_mask =
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
#define PHY_Cap_10_Half_Or_Less PHY_Cap_10_Half
#define PHY_Cap_10_Full_Or_Less PHY_Cap_10_Full | PHY_Cap_10_Half_Or_Less
#define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less
#define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less
void
mdio_write(void *ioaddr, int RegAddr, int value)
{
......@@ -373,6 +378,17 @@ mdio_read(void *ioaddr, int RegAddr)
return value;
}
static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, int bitnum,
int bitval)
{
int val;
val = mdio_read(ioaddr, reg);
val = (bitval == 1) ?
val | (bitval << bitnum) : val & ~(0x0001 << bitnum);
mdio_write(ioaddr, reg, val & 0xffff);
}
static void rtl8169_get_mac_version(struct rtl8169_private *tp, void *ioaddr)
{
const struct {
......@@ -456,6 +472,74 @@ static void rtl8169_print_phy_version(struct rtl8169_private *tp)
dprintk("phy_version == Unknown\n");
}
static void rtl8169_hw_phy_config(struct net_device *dev)
{
struct rtl8169_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
struct {
u16 regs[5]; /* Beware of bit-sign propagation */
} phy_magic[5] = { {
{ 0x0000, //w 4 15 12 0
0x00a1, //w 3 15 0 00a1
0x0008, //w 2 15 0 0008
0x1020, //w 1 15 0 1020
0x1000 } },{ //w 0 15 0 1000
{ 0x7000, //w 4 15 12 7
0xff41, //w 3 15 0 ff41
0xde60, //w 2 15 0 de60
0x0140, //w 1 15 0 0140
0x0077 } },{ //w 0 15 0 0077
{ 0xa000, //w 4 15 12 a
0xdf01, //w 3 15 0 df01
0xdf20, //w 2 15 0 df20
0xff95, //w 1 15 0 ff95
0xfa00 } },{ //w 0 15 0 fa00
{ 0xb000, //w 4 15 12 b
0xff41, //w 3 15 0 ff41
0xde20, //w 2 15 0 de20
0x0140, //w 1 15 0 0140
0x00bb } },{ //w 0 15 0 00bb
{ 0xf000, //w 4 15 12 f
0xdf01, //w 3 15 0 df01
0xdf20, //w 2 15 0 df20
0xff95, //w 1 15 0 ff95
0xbf00 } //w 0 15 0 bf00
}
}, *p = phy_magic;
int i;
rtl8169_print_mac_version(tp);
rtl8169_print_phy_version(tp);
if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
return;
if (tp->phy_version >= RTL_GIGA_PHY_VER_F)
return;
dprintk("MAC version != 0 && PHY version == 0 or 1\n");
dprintk("Do final_reg2.cfg\n");
/* Shazam ! */
// phy config for RTL8169s mac_version C chip
mdio_write(ioaddr, 31, 0x0001); //w 31 2 0 1
mdio_write(ioaddr, 21, 0x1000); //w 21 15 0 1000
mdio_write(ioaddr, 24, 0x65c7); //w 24 15 0 65c7
rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
for (i = ARRAY_SIZE(phy_magic); i > 0; i++, p++) {
int val, pos = 4;
val = (mdio_read(ioaddr, pos) & 0x0fff) | (p->regs[0] & 0xffff);
mdio_write(ioaddr, pos, val);
while (--pos >= 0)
mdio_write(ioaddr, pos, p->regs[4 - pos] & 0xffff);
rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1
rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
}
mdio_write(ioaddr, 31, 0x0000); //w 31 2 0 0
}
static int __devinit
rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
void **ioaddr_out)
......@@ -642,6 +726,23 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->dev_addr[2], dev->dev_addr[3],
dev->dev_addr[4], dev->dev_addr[5], dev->irq);
rtl8169_hw_phy_config(dev);
dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
RTL_W8(0x82, 0x01);
if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
dprintk("Set PCI Latency=0x40\n");
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
}
if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
RTL_W8(0x82, 0x01);
dprintk("Set PHY Reg 0x0bh = 0x00h\n");
mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
}
// if TBI is not endbled
if (!(RTL_R8(PHYstatus) & TBI_Enable)) {
int val = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);
......@@ -654,23 +755,23 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
Cap10_100 = 0, Cap1000 = 0;
switch (option) {
case _10_Half:
Cap10_100 = PHY_Cap_10_Half;
Cap10_100 = PHY_Cap_10_Half_Or_Less;
Cap1000 = PHY_Cap_Null;
break;
case _10_Full:
Cap10_100 = PHY_Cap_10_Full;
Cap10_100 = PHY_Cap_10_Full_Or_Less;
Cap1000 = PHY_Cap_Null;
break;
case _100_Half:
Cap10_100 = PHY_Cap_100_Half;
Cap10_100 = PHY_Cap_100_Half_Or_Less;
Cap1000 = PHY_Cap_Null;
break;
case _100_Full:
Cap10_100 = PHY_Cap_100_Full;
Cap10_100 = PHY_Cap_100_Full_Or_Less;
Cap1000 = PHY_Cap_Null;
break;
case _1000_Full:
Cap10_100 = PHY_Cap_Null;
Cap10_100 = PHY_Cap_100_Full_Or_Less;
Cap1000 = PHY_Cap_1000_Full;
break;
default:
......@@ -684,9 +785,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
// enable 10/100 Full/Half Mode, leave PHY_AUTO_NEGO_REG bit4:0 unchanged
mdio_write(ioaddr, PHY_AUTO_NEGO_REG,
PHY_Cap_10_Half | PHY_Cap_10_Full |
PHY_Cap_100_Half | PHY_Cap_100_Full | (val &
0x1F));
PHY_Cap_100_Full_Or_Less | (val & 0x1f));
// enable 1000 Full Mode
mdio_write(ioaddr, PHY_1000_CTRL_REG,
......
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