aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfrançois romieu <romieu@fr.zoreil.com>2011-08-02 03:53:43 +0000
committerDavid S. Miller <davem@davemloft.net>2011-08-02 17:08:58 -0700
commitc28aa38567101bad4e020f4392df41d0bf6c165c (patch)
treef8bae264b8d64d0b077badcb334b601868541320
parentbnx2x: Prevent restarting Tx during bnx2x_nic_unload (diff)
downloadlinux-dev-c28aa38567101bad4e020f4392df41d0bf6c165c.tar.xz
linux-dev-c28aa38567101bad4e020f4392df41d0bf6c165c.zip
r8169 : MAC address change fix for the 8168e-vl.
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=39252 Hayes suggested that the usual MAC{0, 4} register writes be completed with writes to extended GigaMAC registers : - 0xe0 .. 0xe5 - 0xf2 .. 0xf7 Registers 0xf0 and 0xf1 should be set to 0. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Cc: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/r8169.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c77286edba4d..02339b3352e7 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1092,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;
@@ -3117,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);