From: Ivan Vecera <ivecera@redhat.com>
To: Francois Romieu <romieu@fr.zoreil.com>,
Mikael Pettersson <mikpe@it.uu.se>,
Tim Durack <tdurack@gmail.com>
Cc: netdev@vger.kernel.org
Subject: 3rd attempt to initialize MAC address on r8169
Date: Fri, 19 Jun 2009 09:21:25 +0200 [thread overview]
Message-ID: <4A3B3C75.5090200@redhat.com> (raw)
In-Reply-To: <20090315100953.GA16632@electric-eye.fr.zoreil.com>
Francois Romieu napsal(a):
> Mikael Pettersson <mikpe@it.uu.se> :
> [...]
>> May I suggest that 6709fe9a27e43a4931938fe0d7f2cc5edef31386 is reverted
>> until this regression is debugged and fixed?
>
> Yes.
>
Hello guys,
I made 3rd attempt to enable the ability to initialize r8169's MAC address
on initialization. The proposed patch below works for all my Realtek devices,
but you had some issues with the previous one. Could you please test it on your
devices? I would like to close finally this long term issue.
Thanks,
Ivan
---
drivers/net/r8169.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 3b19e0c..60c8811 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -80,9 +80,9 @@ static const int multicast_filter_limit = 32;
#define RTL8169_TX_TIMEOUT (6*HZ)
#define RTL8169_PHY_TIMEOUT (10*HZ)
-#define RTL_EEPROM_SIG cpu_to_le32(0x8129)
-#define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff)
+#define RTL_EEPROM_SIG 0x8129
#define RTL_EEPROM_SIG_ADDR 0x0000
+#define RTL_EEPROM_MAC_ADDR 0x0007
/* write/read MMIO register */
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
@@ -292,6 +292,11 @@ enum rtl_register_content {
/* Cfg9346Bits */
Cfg9346_Lock = 0x00,
Cfg9346_Unlock = 0xc0,
+ Cfg9346_Program = 0x88, /* Programming mode */
+ Cfg9346_EECS = 0x08, /* Chip select */
+ Cfg9346_EESK = 0x04, /* Serial data clock */
+ Cfg9346_EEDI = 0x02, /* Data input */
+ Cfg9346_EEDO = 0x01, /* Data output */
/* rx_mode_bits */
AcceptErr = 0x20,
@@ -304,6 +309,7 @@ enum rtl_register_content {
/* RxConfigBits */
RxCfgFIFOShift = 13,
RxCfgDMAShift = 8,
+ RxCfg9356SEL = 6, /* EEPROM type: 0 = 9346, 1 = 9356 */
/* TxConfigBits */
TxInterFrameGapShift = 24,
@@ -1962,6 +1968,88 @@ static const struct net_device_ops rtl8169_netdev_ops = {
};
+/* delay between EEPROM clock transitions - force out buffered PCI writes. */
+#define RTL_EEPROM_DELAY() (void)RTL_R8(Cfg9346)
+#define RTL_EEPROM_READ_CMD 6
+
+/* read 16bit word stored in EEPROM. EEPROM is addressed by words. */
+static u16 rtl_eeprom_read(void __iomem *ioaddr, int addr)
+{
+ int read_cmd, addr_len, i;
+ u16 result = 0;
+
+ /* check for EEPROM address size (in bits) */
+ addr_len = (RTL_R32(RxConfig) & (1 << RxCfg9356SEL)) ? 8 : 6;
+ read_cmd = addr | (RTL_EEPROM_READ_CMD << addr_len);
+
+ /* enter programming mode */
+ RTL_W8(Cfg9346, Cfg9346_Program & ~Cfg9346_EECS);
+ RTL_W8(Cfg9346, Cfg9346_Program);
+ RTL_EEPROM_DELAY();
+
+ /* shift out read command and requested address */
+ for (i = 4 + addr_len; i >= 0; i--) {
+ int val = (read_cmd & (1 << i)) ? Cfg9346_EEDI : 0;
+ RTL_W8(Cfg9346, Cfg9346_Program | val);
+ RTL_EEPROM_DELAY();
+ RTL_W8(Cfg9346, Cfg9346_Program | val | Cfg9346_EESK);
+ RTL_EEPROM_DELAY();
+ }
+ RTL_W8(Cfg9346, Cfg9346_Program);
+ RTL_EEPROM_DELAY();
+
+ /* read back 16bit value */
+ for (i = 16; i > 0; i--) {
+ RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EESK);
+ RTL_EEPROM_DELAY();
+
+ result <<= 1;
+ result |= (RTL_R8 (Cfg9346) & Cfg9346_EEDO) ? 1 : 0;
+
+ RTL_W8(Cfg9346, Cfg9346_Program);
+ RTL_EEPROM_DELAY();
+ }
+
+ /* leave programming mode - lock configuration */
+ RTL_W8(Cfg9346, Cfg9346_Lock);
+ RTL_EEPROM_DELAY();
+
+ return result;
+}
+
+static void rtl_init_mac_address(struct rtl8169_private *tp,
+ void __iomem *ioaddr)
+{
+ struct pci_dev *pdev = tp->pci_dev;
+ int i;
+ u16 x;
+ u8 mac[8];
+
+ /* read EEPROM signature */
+ x = rtl_eeprom_read(ioaddr, RTL_EEPROM_SIG_ADDR);
+ if (x != RTL_EEPROM_SIG) {
+ dev_info(&pdev->dev, "Missing EEPROM signature: %04x\n", x);
+ return;
+ }
+
+ /* read MAC address */
+ for (i = 0; i < 3; i++) {
+ x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + i);
+ mac[i*2] = x & 0xff;
+ mac[i*2+1] = x >> 8;
+ }
+
+ if (netif_msg_probe(tp)) {
+ DECLARE_MAC_BUF(buf);
+
+ dev_info(&pdev->dev, "MAC address found in EEPROM: %s\n",
+ print_mac(buf, mac));
+ }
+
+ if (is_valid_ether_addr(mac))
+ rtl_rar_set(tp, mac);
+}
+
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -2141,6 +2229,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->mmio_addr = ioaddr;
+ rtl_init_mac_address(tp, ioaddr);
+
/* Get MAC address */
for (i = 0; i < MAC_ADDR_LEN; i++)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
--
1.6.0.4
next prev parent reply other threads:[~2009-06-19 7:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-09 20:29 [BUG] 2.6.29-rc7 broke r8169 MAC on Thecus n2100 ARM board Mikael Pettersson
2009-03-13 20:15 ` Francois Romieu
2009-03-14 2:23 ` Tim Durack
[not found] ` <9e246b4d0903131921k6fba9b04ge945c2902d4117d0@mail.gmail.com>
2009-03-14 11:37 ` Mikael Pettersson
2009-03-15 10:09 ` Francois Romieu
2009-06-19 7:21 ` Ivan Vecera [this message]
2009-06-19 11:30 ` 3rd attempt to initialize MAC address on r8169 Mikael Pettersson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A3B3C75.5090200@redhat.com \
--to=ivecera@redhat.com \
--cc=mikpe@it.uu.se \
--cc=netdev@vger.kernel.org \
--cc=romieu@fr.zoreil.com \
--cc=tdurack@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).