diff options
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 40bcb82d911..02339b3352e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -239,6 +239,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, @@ -694,7 +695,7 @@ struct rtl8169_private { size_t size; } phy_action; } *rtl_fw; -#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); +#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) }; MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); @@ -1091,6 +1092,21 @@ rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type) rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type); } +struct exgmac_reg { + u16 addr; + u16 mask; + u32 val; +}; + +static void rtl_write_exgmac_batch(void __iomem *ioaddr, + const struct exgmac_reg *r, int len) +{ + while (len-- > 0) { + rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC); + r++; + } +} + static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) { u8 value = 0xff; @@ -2160,12 +2176,9 @@ static void rtl8169sb_hw_phy_config(struct rtl8169_private *tp) static void rtl8169scd_hw_phy_config_quirk(struct rtl8169_private *tp) { struct pci_dev *pdev = tp->pci_dev; - u16 vendor_id, device_id; - - pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &vendor_id); - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &device_id); - if ((vendor_id != PCI_VENDOR_ID_GIGABYTE) || (device_id != 0xe000)) + if ((pdev->subsystem_vendor != PCI_VENDOR_ID_GIGABYTE) || + (pdev->subsystem_device != 0xe000)) return; rtl_writephy(tp, 0x1f, 0x0001); @@ -3119,6 +3132,18 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) RTL_W32(MAC0, low); RTL_R32(MAC0); + if (tp->mac_version == RTL_GIGA_MAC_VER_34) { + const struct exgmac_reg e[] = { + { .addr = 0xe0, ERIAR_MASK_1111, .val = low }, + { .addr = 0xe4, ERIAR_MASK_1111, .val = high }, + { .addr = 0xf0, ERIAR_MASK_1111, .val = low << 16 }, + { .addr = 0xf4, ERIAR_MASK_1111, .val = high << 16 | + low >> 16 }, + }; + + rtl_write_exgmac_batch(ioaddr, e, ARRAY_SIZE(e)); + } + RTL_W8(Cfg9346, Cfg9346_Lock); spin_unlock_irq(&tp->lock); |