netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch inside] kernel crash, RTL8101E [10ec:8136]
@ 2008-07-24 15:34 martin capitanio
  2008-07-24 15:57 ` Cédric Augonnet
  0 siblings, 1 reply; 10+ messages in thread
From: martin capitanio @ 2008-07-24 15:34 UTC (permalink / raw)
  To: Francois Romieu, Mario Limonciello; +Cc: kernel, netdev, c4p7n1

----- original message --------
http://marc.info/?l=linux-netdev&m=121274740606834&w=2

Subject: Re: [BUG or cosmic ray] WARNING: at net/sched/sch_generic.c:222 dev_watchdog+0xe8/0x100()
Sent: Sat, 14 Jun 2008
From: Francois Romieu<romieu@fr.zoreil.com>
> If lspci can not read the device registers correctly, chances are high
> that the device driver can not either.
> 
> If you can reproduce the "!!! Unknown header type 7f" error with lspci
> on 2.6.26-rc6 we have a problem which goes beyond the sole r8169 device
> driver. linux-kernel or linux-pci will probably be more helpful than
> netdev then.

Hi Francois and Mario,

(apologies if I missed something)
it comes out that by a "bad luck" the RTL8101E internally crashes and is no more
reachable on the pcie bus and/or freezes the the kernel immediately.

Marcus Sundberg found, I think, a first relevant bug
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=77332894c21165404496c56763d7df6c15c4bb09
r8169: avoid thrashing PCI conf space above RTL_GIGA_MAC_VER_06

that helps, but not quite. Mario Limonciello <Mario_Limonciello@Dell.com>
extracted from the Realtek driver some start-up magic feed. It would be great
if someone RTL* savvy can double check.

I am personally wondering why the Realtek guys keep brainless pushing magic
numbers in their obviously Dead End gpl driver[s] (if any) and are not sending
patches helping (at least with the magic) here directly? Sure, it's better than
nothing. You know, it's easy to shorten an eeprom mtbf from years to weeks just
applying a wrong bias. Hint: _That can long-term burn a lot of Dells at al money._

However, I can't test this on the current linus' tree, the kernel is broken
itself, but I can confirm, applied to the vanilla v2.6.26, solves the problem and
makes my notebook more happy. (Fixing remaining rtl8187b, drm/x3100/intelfb/x11
issues seems to be on the go :-))

-----------------

OriginalAuthor: Mario Limonciello <Mario_Limonciello@Dell.com>
This fix was created based upon the differences in the startup procedures
of the Realtek r8101 driver and the upstream r8169 driver.

Properly merged with
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=77332894c21165404496c56763d7df6c15c4bb09
solves the bug on the Toshiba L300 laptop reported here
http://marc.info/?l=linux-netdev&m=121274740606834&w=2

Signed-off-by: Martin Capitanio <c4p7n1@capitanio.org>
---

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 6572425..8e82546 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1139,6 +1139,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
                { 0x7cf00000, 0x34000000,       RTL_GIGA_MAC_VER_13 },
                { 0x7cf00000, 0x34200000,       RTL_GIGA_MAC_VER_16 },
                { 0x7c800000, 0x34000000,       RTL_GIGA_MAC_VER_16 },
+               /* 8102EL */
+               { 0x7c800000, 0x24800000,       RTL_GIGA_MAC_VER_16 },
+               /* 8102E */
+               { 0x7c800000, 0x34800000,       RTL_GIGA_MAC_VER_16 },
                /* FIXME: where did these entries come from ? -- FR */
                { 0xfc800000, 0x38800000,       RTL_GIGA_MAC_VER_15 },
                { 0xfc800000, 0x30800000,       RTL_GIGA_MAC_VER_14 },
@@ -1299,6 +1303,21 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
+static void rtl8101_hw_phy_config(void __iomem *ioaddr)
+{
+       struct phy_reg phy_reg_init[] = {
+               { 0x1f, 0x0000 },
+               { 0x11, mdio_read(ioaddr,0x11) | 0x1000 },
+               { 0x19, mdio_read(ioaddr,0x19) | 0x2000 },
+               { 0x1f, 0x0003 },
+               { 0x08, 0x441D },
+               { 0x01, 0xc066 },
+               { 0x1f, 0x0000 }
+       };
+
+       rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
 static void rtl_hw_phy_config(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -1316,6 +1335,9 @@ static void rtl_hw_phy_config(struct net_device *dev)
        case RTL_GIGA_MAC_VER_04:
                rtl8169sb_hw_phy_config(ioaddr);
                break;
+       case RTL_GIGA_MAC_VER_13:
+       case RTL_GIGA_MAC_VER_16:
+               rtl8101_hw_phy_config(ioaddr);
        case RTL_GIGA_MAC_VER_18:
                rtl8168cp_hw_phy_config(ioaddr);
                break;
@@ -1438,8 +1460,10 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 
        rtl_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_06) {
+               dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+               RTL_W8(0x82, 0x01);
+       }
 
        pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
 

--------------------
--------------------

It only remains other (cosmetic?) not-linux-only issue: the *E chip-sets have
a built in 100Mb/s transceiver

http://www.realtek.com.tw/products/productsView.aspx?Langid=1&PNid=14&PFid=7&Level=5&Conn=4&ProdID=19

but the driver advertises 1G:

Settings for eth0:
	Supported ports: [ TP ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: Twisted Pair
	PHYAD: 0
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pumbg
	Wake-on: g
	Current message level: 0x00000033 (51)
	Link detected: yes
   
I had heard that a many confused people/helpdesks hopelessly send
around the globe Laptops to repair their nonexistent 1G PHY ;-)


Thanks everyone involved!
        Martin Capitanio


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [patch inside] kernel crash, RTL8101E [10ec:8136]
@ 2008-07-24 15:54 c4p7n1
  2008-07-24 21:09 ` Francois Romieu
  0 siblings, 1 reply; 10+ messages in thread
From: c4p7n1 @ 2008-07-24 15:54 UTC (permalink / raw)
  To: Francois Romieu, Mario Limonciello; +Cc: kernel, netdev, c4p7n1

----- original message --------
http://marc.info/?l=linux-netdev&m=121274740606834&w=2

Subject: Re: [BUG or cosmic ray] WARNING: at net/sched/sch_generic.c:222 dev_watchdog+0xe8/0x100()
Sent: Sat, 14 Jun 2008
From: Francois Romieu<romieu@fr.zoreil.com>
> If lspci can not read the device registers correctly, chances are high
> that the device driver can not either.
> 
> If you can reproduce the "!!! Unknown header type 7f" error with lspci
> on 2.6.26-rc6 we have a problem which goes beyond the sole r8169 device
> driver. linux-kernel or linux-pci will probably be more helpful than
> netdev then.

Hi Francois and Mario,

(apologies if I missed something)
it comes out that by a "bad luck" the RTL8101E internally crashes and is no more
reachable on the pcie bus and/or freezes the the kernel immediately.

Marcus Sundberg found, I think, a first relevant bug
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=77332894c21165404496c56763d7df6c15c4bb09
r8169: avoid thrashing PCI conf space above RTL_GIGA_MAC_VER_06

that helps, but not quite. Mario Limonciello <Mario_Limonciello@Dell.com>
extracted from the Realtek driver some start-up magic feed. It would be great
if someone RTL* savvy can double check.

I am personally wondering why the Realtek guys keep brainless pushing magic
numbers in their obviously Dead End gpl driver[s] (if any) and are not sending
patches helping at least with the magic here directly? Sure, it's better than
nothing. You know, it's easy to shorten an eeprom mtbf from years to weeks just
applying a wrong bias. Hint: _That can long-term burn a lot of Dells at al money._

However, I can't test this on the current linus' tree, the kernel is broken
itself, but I can confirm, applied to the vanilla v2.6.26, solves the problem and
makes my notebook more happy. (Fixing remaining rtl8187b, drm/x3100/intelfb/x11
issues seems to be on the go :-))

-----------------

OriginalAuthor: Mario Limonciello <Mario_Limonciello@Dell.com>
This fix was created based upon the differences in the startup procedures
of the Realtek r8101 driver and the upstream r8169 driver.

Properly merged with
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=77332894c21165404496c56763d7df6c15c4bb09
solves the bug on the Toshiba L300 laptop reported here
http://marc.info/?l=linux-netdev&m=121274740606834&w=2

Signed-off-by: Martin Capitanio <c4p7n1@capitanio.org>
---

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 6572425..8e82546 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1139,6 +1139,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
                { 0x7cf00000, 0x34000000,       RTL_GIGA_MAC_VER_13 },
                { 0x7cf00000, 0x34200000,       RTL_GIGA_MAC_VER_16 },
                { 0x7c800000, 0x34000000,       RTL_GIGA_MAC_VER_16 },
+               /* 8102EL */
+               { 0x7c800000, 0x24800000,       RTL_GIGA_MAC_VER_16 },
+               /* 8102E */
+               { 0x7c800000, 0x34800000,       RTL_GIGA_MAC_VER_16 },
                /* FIXME: where did these entries come from ? -- FR */
                { 0xfc800000, 0x38800000,       RTL_GIGA_MAC_VER_15 },
                { 0xfc800000, 0x30800000,       RTL_GIGA_MAC_VER_14 },
@@ -1299,6 +1303,21 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
        rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
+static void rtl8101_hw_phy_config(void __iomem *ioaddr)
+{
+       struct phy_reg phy_reg_init[] = {
+               { 0x1f, 0x0000 },
+               { 0x11, mdio_read(ioaddr,0x11) | 0x1000 },
+               { 0x19, mdio_read(ioaddr,0x19) | 0x2000 },
+               { 0x1f, 0x0003 },
+               { 0x08, 0x441D },
+               { 0x01, 0xc066 },
+               { 0x1f, 0x0000 }
+       };
+
+       rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
 static void rtl_hw_phy_config(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -1316,6 +1335,9 @@ static void rtl_hw_phy_config(struct net_device *dev)
        case RTL_GIGA_MAC_VER_04:
                rtl8169sb_hw_phy_config(ioaddr);
                break;
+       case RTL_GIGA_MAC_VER_13:
+       case RTL_GIGA_MAC_VER_16:
+               rtl8101_hw_phy_config(ioaddr);
        case RTL_GIGA_MAC_VER_18:
                rtl8168cp_hw_phy_config(ioaddr);
                break;
@@ -1438,8 +1460,10 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 
        rtl_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_06) {
+               dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+               RTL_W8(0x82, 0x01);
+       }
 
        pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
 

--------------------
--------------------

It only remains other (cosmetic?) not-linux-only issue: the *E chip-sets have
a built in 100Mb/s transceiver

http://www.realtek.com.tw/products/productsView.aspx?Langid=1&PNid=14&PFid=7&Level=5&Conn=4&ProdID=19

but the driver advertises 1G:

Settings for eth0:
	Supported ports: [ TP ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Full 
	Supports auto-negotiation: Yes
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Full 
	Advertised auto-negotiation: Yes
	Speed: 100Mb/s
	Duplex: Full
	Port: Twisted Pair
	PHYAD: 0
	Transceiver: internal
	Auto-negotiation: on
	Supports Wake-on: pumbg
	Wake-on: g
	Current message level: 0x00000033 (51)
	Link detected: yes
   
I had heard that a many confused people/helpdesks hopelessly send
around the globe Laptops to repair their nonexistent 1G PHY ;-)


Thanks a lot everyone involved!
        Martin Capitanio


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
  2008-07-24 15:34 martin capitanio
@ 2008-07-24 15:57 ` Cédric Augonnet
  2008-07-24 21:02   ` Francois Romieu
  0 siblings, 1 reply; 10+ messages in thread
From: Cédric Augonnet @ 2008-07-24 15:57 UTC (permalink / raw)
  To: martin capitanio
  Cc: Francois Romieu, Mario Limonciello, kernel, netdev, c4p7n1

Hi all,

>        case RTL_GIGA_MAC_VER_04:
>                rtl8169sb_hw_phy_config(ioaddr);
>                break;
> +       case RTL_GIGA_MAC_VER_13:
> +       case RTL_GIGA_MAC_VER_16:
> +               rtl8101_hw_phy_config(ioaddr);

Should not there be a "break;" here or is it intended to go through
the next case as well?

>        case RTL_GIGA_MAC_VER_18:
>                rtl8168cp_hw_phy_config(ioaddr);
>                break;

Perhaps i missed something obvious, sorry if that's the case ...

Cheers,
Cédric

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
@ 2008-07-24 20:23 martin capitanio
  0 siblings, 0 replies; 10+ messages in thread
From: martin capitanio @ 2008-07-24 20:23 UTC (permalink / raw)
  To: Cédric Augonnet, Francois Romieu, Mario Limonciello
  Cc: kernel, netdev, c4p7n1

----- original message --------

Subject: Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
Sent: Thu, 24 Jul 2008
From: Cédric Augonnet<cedric.augonnet@gmail.com>

> Hi all,
> 
> >        case RTL_GIGA_MAC_VER_04:
> >                rtl8169sb_hw_phy_config(ioaddr);
> >                break;
> > +       case RTL_GIGA_MAC_VER_13:
> > +       case RTL_GIGA_MAC_VER_16:
> > +               rtl8101_hw_phy_config(ioaddr);
> 
> Should not there be a "break;" here or is it intended to go through
> the next case as well?

Good question. If you can read c code and are willing to spend your time,
the answer may be buried here:

LINUX driver for kernel 2.6.X and 2.4.X (Support x86 and x64)
ftp://152.104.238.19/cn/nic/r8101-1.007.00.tar.bz2

> 
> >        case RTL_GIGA_MAC_VER_18:
> >                rtl8168cp_hw_phy_config(ioaddr);
> >                break;
> 
> Perhaps i missed something obvious, sorry if that's the case ...

No, there is nothing obvious, even in the Hsinchu Science Park ;-)

static void rtl8168cp_hw_phy_config(void __iomem *ioaddr)
{
	struct phy_reg phy_reg_init[] = {
		{ 0x1f, 0x0000 },
		{ 0x1d, 0x0f00 },
		{ 0x1f, 0x0002 },
		{ 0x0c, 0x1ec8 },
		{ 0x1f, 0x0000 }
	};

	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}

        Martin Capitanio


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
  2008-07-24 15:57 ` Cédric Augonnet
@ 2008-07-24 21:02   ` Francois Romieu
  0 siblings, 0 replies; 10+ messages in thread
From: Francois Romieu @ 2008-07-24 21:02 UTC (permalink / raw)
  To: Cédric Augonnet
  Cc: martin capitanio, Mario Limonciello, kernel, netdev, c4p7n1

Cédric Augonnet <cedric.augonnet@gmail.com> :
> Hi all,
> 
> >        case RTL_GIGA_MAC_VER_04:
> >                rtl8169sb_hw_phy_config(ioaddr);
> >                break;
> > +       case RTL_GIGA_MAC_VER_13:
> > +       case RTL_GIGA_MAC_VER_16:
> > +               rtl8101_hw_phy_config(ioaddr);
> 
> Should not there be a "break;" here or is it intended to go through
> the next case as well?

8101 and 8102 should be handled differently, yes.

On top of curent 2.6.26-git, it could look like:

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a3e3895..86ee894 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -95,6 +95,10 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
 	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
 	RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
+	RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
+	RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
+	RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
+	RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
 	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
 	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
 	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
@@ -121,6 +125,10 @@ static const struct {
 	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
 	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
 	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
+	_R("RTL8102e",		RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
+	_R("RTL8102e",		RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
+	_R("RTL8102e",		RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
+	_R("RTL8101e",		RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
 	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
 	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
 	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
@@ -482,6 +490,11 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
 	return value;
 }
 
+static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
+{
+	mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
+}
+
 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
 {
 	RTL_W16(IntrMask, 0x0000);
@@ -1116,8 +1129,16 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
 		{ 0x7c800000, 0x30000000,	RTL_GIGA_MAC_VER_11 },
 
 		/* 8101 family. */
+		{ 0x7cf00000, 0x34a00000,	RTL_GIGA_MAC_VER_09 },
+		{ 0x7cf00000, 0x24a00000,	RTL_GIGA_MAC_VER_09 },
+		{ 0x7cf00000, 0x34900000,	RTL_GIGA_MAC_VER_08 },
+		{ 0x7cf00000, 0x24900000,	RTL_GIGA_MAC_VER_08 },
+		{ 0x7cf00000, 0x34800000,	RTL_GIGA_MAC_VER_07 },
+		{ 0x7cf00000, 0x24800000,	RTL_GIGA_MAC_VER_07 },
 		{ 0x7cf00000, 0x34000000,	RTL_GIGA_MAC_VER_13 },
+		{ 0x7cf00000, 0x34300000,	RTL_GIGA_MAC_VER_10 },
 		{ 0x7cf00000, 0x34200000,	RTL_GIGA_MAC_VER_16 },
+		{ 0x7c800000, 0x34800000,	RTL_GIGA_MAC_VER_09 },
 		{ 0x7c800000, 0x34000000,	RTL_GIGA_MAC_VER_16 },
 		/* FIXME: where did these entries come from ? -- FR */
 		{ 0xfc800000, 0x38800000,	RTL_GIGA_MAC_VER_15 },
@@ -1279,6 +1300,22 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
 	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
+static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0003 },
+		{ 0x08, 0x441d },
+		{ 0x01, 0x9100 },
+		{ 0x1f, 0x0000 }
+	};
+
+	mdio_write(ioaddr, 0x1f, 0x0000);
+	mdio_patch(ioaddr, 0x11, 1 << 12);
+	mdio_patch(ioaddr, 0x19, 1 << 13);
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
 static void rtl_hw_phy_config(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -1296,6 +1333,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
 	case RTL_GIGA_MAC_VER_04:
 		rtl8169sb_hw_phy_config(ioaddr);
 		break;
+	case RTL_GIGA_MAC_VER_07:
+	case RTL_GIGA_MAC_VER_08:
+	case RTL_GIGA_MAC_VER_09:
+		rtl8102e_hw_phy_config(ioaddr);
+		break;
 	case RTL_GIGA_MAC_VER_18:
 		rtl8168cp_hw_phy_config(ioaddr);
 		break;
---

On top of 2.6.26, one needs to apply beforehand:

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=f887cce8de019bb32917789379af89ae4c0294ee
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=77332894c21165404496c56763d7df6c15c4bb09

-- 
Ueimor

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
  2008-07-24 15:54 [patch inside] kernel crash, RTL8101E [10ec:8136] c4p7n1
@ 2008-07-24 21:09 ` Francois Romieu
  0 siblings, 0 replies; 10+ messages in thread
From: Francois Romieu @ 2008-07-24 21:09 UTC (permalink / raw)
  To: c4p7n1; +Cc: Mario Limonciello, kernel, netdev, Edward Hsu

c4p7n1@capitanio.org <c4p7n1@capitanio.org> :
[...]
> It only remains other (cosmetic?) not-linux-only issue: the *E chip-sets have
> a built in 100Mb/s transceiver
> 
> http://www.realtek.com.tw/products/productsView.aspx?Langid=1&PNid=14&PFid=7&Level=5&Conn=4&ProdID=19
> 
> but the driver advertises 1G:
> 
> Settings for eth0:
> 	Supported ports: [ TP ]
> 	Supported link modes:   10baseT/Half 10baseT/Full 
> 	                        100baseT/Half 100baseT/Full 
> 	                        1000baseT/Full 

Ahem.

Can you give the completely untested patch below a try (say, against
2.6.26 or more) ?

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a3e3895..1a8a21f 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -406,13 +406,15 @@ struct rtl8169_private {
 	struct vlan_group *vlgrp;
 #endif
 	int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
-	void (*get_settings)(struct net_device *, struct ethtool_cmd *);
+	int (*get_settings)(struct net_device *, struct ethtool_cmd *);
 	void (*phy_reset_enable)(void __iomem *);
 	void (*hw_start)(struct net_device *);
 	unsigned int (*phy_reset_pending)(void __iomem *);
 	unsigned int (*link_ok)(void __iomem *);
 	struct delayed_work task;
 	unsigned features;
+
+	struct mii_if_info mii;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -482,6 +484,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
 	return value;
 }
 
+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
+			   int val)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	mdio_write(ioaddr, location, val);
+}
+
+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	return mdio_read(ioaddr, location);
+}
+
 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
 {
 	RTL_W16(IntrMask, 0x0000);
@@ -850,7 +869,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
 
 #endif
 
-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -867,65 +886,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	cmd->speed = SPEED_1000;
 	cmd->duplex = DUPLEX_FULL; /* Always set */
+
+	return 0;
 }
 
-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	u8 status;
-
-	cmd->supported = SUPPORTED_10baseT_Half |
-			 SUPPORTED_10baseT_Full |
-			 SUPPORTED_100baseT_Half |
-			 SUPPORTED_100baseT_Full |
-			 SUPPORTED_1000baseT_Full |
-			 SUPPORTED_Autoneg |
-			 SUPPORTED_TP;
-
-	cmd->autoneg = 1;
-	cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
-
-	if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
-		cmd->advertising |= ADVERTISED_10baseT_Half;
-	if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
-		cmd->advertising |= ADVERTISED_10baseT_Full;
-	if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
-		cmd->advertising |= ADVERTISED_100baseT_Half;
-	if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
-		cmd->advertising |= ADVERTISED_100baseT_Full;
-	if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
-		cmd->advertising |= ADVERTISED_1000baseT_Full;
-
-	status = RTL_R8(PHYstatus);
-
-	if (status & _1000bpsF)
-		cmd->speed = SPEED_1000;
-	else if (status & _100bps)
-		cmd->speed = SPEED_100;
-	else if (status & _10bps)
-		cmd->speed = SPEED_10;
-
-	if (status & TxFlowCtrl)
-		cmd->advertising |= ADVERTISED_Asym_Pause;
-	if (status & RxFlowCtrl)
-		cmd->advertising |= ADVERTISED_Pause;
-
-	cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
-		      DUPLEX_FULL : DUPLEX_HALF;
+
+	return mii_ethtool_gset(&tp->mii, cmd);
 }
 
 static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&tp->lock, flags);
 
-	tp->get_settings(dev, cmd);
+	rc = tp->get_settings(dev, cmd);
 
 	spin_unlock_irqrestore(&tp->lock, flags);
-	return 0;
+	return rc;
 }
 
 static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
@@ -1578,6 +1561,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
 	const unsigned int region = cfg->region;
 	struct rtl8169_private *tp;
+	struct mii_if_info *mii;
 	struct net_device *dev;
 	void __iomem *ioaddr;
 	unsigned int i;
@@ -1602,6 +1586,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	tp->pci_dev = pdev;
 	tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
 
+	mii = &tp->mii;
+	mii->dev = dev;
+	mii->mdio_read = rtl_mdio_read;
+	mii->mdio_write = rtl_mdio_write;
+	mii->phy_id_mask = 0x1f;
+	mii->reg_num_mask = 0x1f;
+
 	/* enable device (incl. PCI PM wakeup and hotplug setup) */
 	rc = pci_enable_device(pdev);
 	if (rc < 0) {
-- 
Ueimor

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
@ 2008-07-27 19:04 c4p7n1
  2008-07-28 18:40 ` Francois Romieu
  0 siblings, 1 reply; 10+ messages in thread
From: c4p7n1 @ 2008-07-27 19:04 UTC (permalink / raw)
  To: Francois Romieu
  Cc: Mario Limonciello, Edward Hsu, Linus Torvalds, Martin Capitanio,
	netdev

Francois Romieu<romieu@fr.zoreil.com> :
> Martin Capitanio <c4p7n1@capitanio.org> :
> [...]
> > It's a foreign language and my outside view may be completely wrong,
> 
> The communication with Realtek has not halted in 2007.
I guess Realtek doesn't have enough resources and that's why taking
the easier approach...

----

Boiling hot Sunday. So I decided to spend some time for digging to this issue.
I see some parts that may not behave as intended. Could someone take a care?  

Fist I thought that the pci system and the subsystem disagrees about the
chip-set:

02:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8101E PCI
Express Fast Ethernet controller [10ec:8136] (rev 02)
Subsystem: Toshiba America Info Systems Unknown device [1179:ff64]
means Realtek RTL8102E Family PCI-E Fast Ethernet NIC (NDIS 6.0)
[Toshiba America Information Systems] 1179:ff64 rev 02

But this system id catches a lot of different chipsets:
listing. driveragent. com/pci/10ec/8136?q=10ec%3A8136

The pci entry just confuse people, the correct message were something like
Realtek Semiconductor Co., Ltd. RTL81xxx Ethernet controller

Everything depending on this information may break, right?
drivers/net/r8169.c:166:{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,0x8136),0,0,RTL_CFG_2 },

Checking the web for the differences btw RTL8102E and RTL8101E:
the RTL8102E claims to support receive-side scaling, is this implemented
somewhere in linux (aka NAPI?)? Can miss-detecting have a bad side-effects?

RTL8102E offers an option for non-EEPROM (=OTP) design. Can the driver break the
hardware?

----

The Realtek driver walks for this device:

#define RTL8101_VERSION "1.007.00" NAPI_SUFFIX
#define MODULENAME "r8101"
printk(KERN_INFO "%s Fast Ethernet driver %s loaded\n",
		       MODULENAME, RTL8101_VERSION);

/* write/read MMIO register */
#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))

rtl8101_get_mac_version
val32 = RTL_R32(TxConfig)     -> 0x37a00600	
reg = val32 & 0x7c800000;     -> 0x34800000
ICVerID = val32 & 0x00700000; -> 0x00200000
	switch (reg) {
		case 0x34800000: //RTL8102E
		case 0x24800000: //RTL8102EL
			else if (ICVerID == 0x00200000)
				tp->mcfg = CFG_METHOD_5;

_R("RTL8102E", CFG_METHOD_5, 0xff7e1880),

rtl8101_hw_phy_config
	} else if (tp->mcfg == CFG_METHOD_5) {
		mdio_write(ioaddr, 0x1f, 0x0000);
		mdio_write(ioaddr, 0x11, 0x15C0);
		mdio_write(ioaddr, 0x19, 0x2080);
		mdio_write(ioaddr, 0x1f, 0x0000);
	}

Not the same I posted, something is wrong.

+static void rtl8101_hw_phy_config(void __iomem *ioaddr)
+{
+       struct phy_reg phy_reg_init[] = {
+               { 0x1f, 0x0000 },
+               { 0x11, mdio_read(ioaddr,0x11) | 0x1000 },
+               { 0x19, mdio_read(ioaddr,0x19) | 0x2000 },
+               { 0x1f, 0x0003 },
+               { 0x08, 0x441D },
+               { 0x01, 0xc066 },
+               { 0x1f, 0x0000 }
+       };
+
+       rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+

Double check.
The driver website got updated in the meantime, walking again:

+#define RTL8101_VERSION "1.009.00" NAPI_SUFFIX
+printk(KERN_INFO "%s: This product is covered by one or more of the
	following patents: US5,307,459, US5,434,872, US5,732,094, US6,570,884,
	US6,115,776, and US6,327,625.\n", MODULENAME);
me: [0-9]Com and this ill patent system sucks.

Lot of changes, just closing my eyes and scrolling down.

 	} else if (tp->mcfg == CFG_METHOD_5) {
 		mdio_write(ioaddr, 0x1f, 0x0000);
+		mdio_write(ioaddr, 0x11, mdio_read(ioaddr, 0x11) | 0x1000);
+		mdio_write(ioaddr, 0x19, mdio_read(ioaddr, 0x19) | 0x2000);
+
+		mdio_write(ioaddr, 0x1f, 0x0003);
+		mdio_write(ioaddr, 0x08, 0x441D);
+		mdio_write(ioaddr, 0x01, 0x9100); <-
 		mdio_write(ioaddr, 0x1f, 0x0000);
 	}

True. The device doesn't need the second pill, Mario forgot that break and
there is a minor change for the drive magic.


> marc.info/?l=linux-netdev&m=121699353804102
> Can you give the completely untested patch below a try (say, against
> 2.6.26 or more) ?
This works.

----

 r8169 Gigabit Ethernet driver 2.2LK-NAPI loaded
[  892.510803] PCI: 0000:02:00.0 has unsupported PM cap regs version (7)
??
[  892.510803] ACPI: PCI Interrupt 0000:02:00.0[A] -> GSI 16 (level, low) -> IRQ 16
[  892.510803] PCI: Setting latency timer of device 0000:02:00.0 to 64
[  892.510803] **** MAC: (37a00600)
[  892.510803] r8169: mac_version = 0x11
[  892.511499] eth0: RTL8101e at 0xf895a000, , XID 34a00000 IRQ 220
[  892.511506] r8169: mac_version = 0x11
[  892.511511] **** RTL_GIGA_MAC_VER_16
[  892.534089] r8169: eth0: link down
[  892.534089] r8169: eth0: link down
??
[  894.026724] r8169: eth0: link up

----

Uncle, may I have my notebook back?
.Yes, just let me reboot ...
I like those two penguins.

.kernel: rtl8187: 8187B chip detected. Support is EXPERIMENTAL, and could damage
.        your hardware, use at your own risk
What's that??
.Don't fear, that's wireless.
.Here, plug this network cable.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
  2008-07-27 19:04 c4p7n1
@ 2008-07-28 18:40 ` Francois Romieu
  0 siblings, 0 replies; 10+ messages in thread
From: Francois Romieu @ 2008-07-28 18:40 UTC (permalink / raw)
  To: c4p7n1; +Cc: Mario Limonciello, Edward Hsu, netdev


(removed Linus from the Cc:)

c4p7n1@capitanio.org <c4p7n1@capitanio.org> :
[...]
> Boiling hot Sunday. So I decided to spend some time for digging to this issue.
> I see some parts that may not behave as intended. Could someone take a care?  
> 
> Fist I thought that the pci system and the subsystem disagrees about the
> chip-set:
[...]
> Subsystem: Toshiba America Info Systems Unknown device [1179:ff64]
> means Realtek RTL8102E Family PCI-E Fast Ethernet NIC (NDIS 6.0)
> [Toshiba America Information Systems] 1179:ff64 rev 02
[...]
> The pci entry just confuse people, the correct message were something like
> Realtek Semiconductor Co., Ltd. RTL81xxx Ethernet controller

10ec:8136 covers the 8101 and the 8102, as expected.

> Everything depending on this information may break, right?
> drivers/net/r8169.c:166:{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,0x8136),0,0,RTL_CFG_2 },

I do not get it. Where do you see a breakage ?

[...]
> Checking the web for the differences btw RTL8102E and RTL8101E:
> the RTL8102E claims to support receive-side scaling, is this implemented
> somewhere in linux (aka NAPI?) ?

1. RSS is available with Linux.
2. RSS is not related in any way or shape with NAPI.
3. RSS is not implemented in Realtek's driver yet.

> Can miss-detecting have a bad side-effects?

Some users have been turned into giant walking mushrooms.

Not sure if they were comestible or not though.

> RTL8102E offers an option for non-EEPROM (=OTP) design. Can the driver
> break the hardware ?

The driver is not supposed to break the hardware.

[...]
> > Can you give the completely untested patch below a try (say, against
> > 2.6.26 or more) ?
> This works.

Thanks.

What does ethtool report for this device ? Does it still claim gigabit
to be supported ?

-- 
Ueimor

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
@ 2008-07-28 20:58 martin capitanio
  0 siblings, 0 replies; 10+ messages in thread
From: martin capitanio @ 2008-07-28 20:58 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Mario Limonciello, Edward Hsu, netdev

> [...]
> > The pci entry just confuse people, the correct message were something
> like
> > Realtek Semiconductor Co., Ltd. RTL81xxx Ethernet controller
> 
> 10ec:8136 covers the 8101 and the 8102, as expected.
Then RTL8101(E)/8102(E) ?
I get here RTL8101E but the real hardware is RTL8102E
The website claims RTL8139  and what ever. If that's not the case ...
> 
> > Everything depending on this information may break, right?
> > drivers/net/r8169.c:166:{
> PCI_DEVICE(PCI_VENDOR_ID_REALTEK,0x8136),0,0,RTL_CFG_2 },
> 
> I do not get it. Where do you see a breakage ?
Sorry misunderstanding. See above.
> 
> [...]
> > Checking the web for the differences btw RTL8102E and RTL8101E:
> > the RTL8102E claims to support receive-side scaling, is this implemented
> > somewhere in linux (aka NAPI?) ?
> 
> 1. RSS is available with Linux.
> 2. RSS is not related in any way or shape with NAPI.
> 3. RSS is not implemented in Realtek's driver yet.
Thanks. I found it.
> 
> > Can miss-detecting have a bad side-effects?
> 
> Some users have been turned into giant walking mushrooms.
I meant RTL8101E/RTL8102E have the same pci id but different features.
> 
> Not sure if they were comestible or not though.
If you kill their hardware, be sure they were not ;-)
> 
> > RTL8102E offers an option for non-EEPROM (=OTP) design. Can the driver
> > break the hardware ?
> 
> The driver is not supposed to break the hardware.
True, just that you know about that possibility. (_One Time Programming_)
> What does ethtool report for this device ? Does it still claim gigabit
> to be supported ?
Works correct,  as expected 10/100M.

Nice to know somebody cares! (Rest in pm)
Thanks for your work,
        Martin


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [patch inside] kernel crash, RTL8101E [10ec:8136]
@ 2008-07-30 18:05 c4p7n1
  0 siblings, 0 replies; 10+ messages in thread
From: c4p7n1 @ 2008-07-30 18:05 UTC (permalink / raw)
  To: Francois Romieu; +Cc: Mario Limonciello, Edward Hsu, netdev

> [...]
> > Subsystem: Toshiba America Info Systems Unknown device [1179:ff64]
> > means Realtek RTL8102E Family PCI-E Fast Ethernet NIC (NDIS 6.0)
> > [Toshiba America Information Systems] 1179:ff64 rev 02
> [...]

After solving another unrelated rc1 issue, I can confirm that this device
works without any problems.

[   13.388384] r8169 Gigabit Ethernet driver 2.3LK-NAPI loaded
[   13.388457] r8169 0000:02:00.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16
[   13.388537] r8169 0000:02:00.0: setting latency timer to 64
[   13.388665] PM: Adding info for No Bus:eth0
[   13.388855] eth0: RTL8102e at 0xf8924000, , XID 34a00000 IRQ 220


Thanks everybody involved for help.
Martin Capitanio

-----
git diff v2.6.27-rc1

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a3e3895..9810aeb 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -95,6 +95,10 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
 	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
 	RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
+	RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
+	RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
+	RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
+	RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
 	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
 	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
 	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
@@ -121,6 +125,10 @@ static const struct {
 	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
 	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
 	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
+	_R("RTL8102e",		RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
+	_R("RTL8102e",		RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
+	_R("RTL8102e",		RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
+	_R("RTL8101e",		RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
 	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
 	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
 	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
@@ -406,13 +414,15 @@ struct rtl8169_private {
 	struct vlan_group *vlgrp;
 #endif
 	int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
-	void (*get_settings)(struct net_device *, struct ethtool_cmd *);
+	int (*get_settings)(struct net_device *, struct ethtool_cmd *);
 	void (*phy_reset_enable)(void __iomem *);
 	void (*hw_start)(struct net_device *);
 	unsigned int (*phy_reset_pending)(void __iomem *);
 	unsigned int (*link_ok)(void __iomem *);
 	struct delayed_work task;
 	unsigned features;
+
+	struct mii_if_info mii;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew ");
@@ -482,6 +492,28 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
 	return value;
 }
 
+static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
+{
+	mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
+}
+
+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
+			   int val)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	mdio_write(ioaddr, location, val);
+}
+
+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	return mdio_read(ioaddr, location);
+}
+
 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
 {
 	RTL_W16(IntrMask, 0x0000);
@@ -850,7 +882,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp,
struct RxDesc *desc,
 
 #endif
 
-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -867,65 +899,30 @@ static void rtl8169_gset_tbi(struct net_device *dev,
struct ethtool_cmd *cmd)
 
 	cmd->speed = SPEED_1000;
 	cmd->duplex = DUPLEX_FULL; /* Always set */
+
+	return 0;
 }
 
-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	u8 status;
-
-	cmd->supported = SUPPORTED_10baseT_Half |
-			 SUPPORTED_10baseT_Full |
-			 SUPPORTED_100baseT_Half |
-			 SUPPORTED_100baseT_Full |
-			 SUPPORTED_1000baseT_Full |
-			 SUPPORTED_Autoneg |
-			 SUPPORTED_TP;
-
-	cmd->autoneg = 1;
-	cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
-
-	if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
-		cmd->advertising |= ADVERTISED_10baseT_Half;
-	if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
-		cmd->advertising |= ADVERTISED_10baseT_Full;
-	if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
-		cmd->advertising |= ADVERTISED_100baseT_Half;
-	if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
-		cmd->advertising |= ADVERTISED_100baseT_Full;
-	if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
-		cmd->advertising |= ADVERTISED_1000baseT_Full;
-
-	status = RTL_R8(PHYstatus);
-
-	if (status & _1000bpsF)
-		cmd->speed = SPEED_1000;
-	else if (status & _100bps)
-		cmd->speed = SPEED_100;
-	else if (status & _10bps)
-		cmd->speed = SPEED_10;
-
-	if (status & TxFlowCtrl)
-		cmd->advertising |= ADVERTISED_Asym_Pause;
-	if (status & RxFlowCtrl)
-		cmd->advertising |= ADVERTISED_Pause;
-
-	cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
-		      DUPLEX_FULL : DUPLEX_HALF;
+
+	return mii_ethtool_gset(&tp->mii, cmd);
 }
 
 static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd
*cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	unsigned long flags;
+	int rc;
 
 	spin_lock_irqsave(&tp->lock, flags);
 
 	tp->get_settings(dev, cmd);
+	rc = tp->get_settings(dev, cmd);
 
 	spin_unlock_irqrestore(&tp->lock, flags);
-	return 0;
+	return rc;
 }
 
 static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs
*regs,
@@ -1116,8 +1113,16 @@ static void rtl8169_get_mac_version(struct
rtl8169_private *tp,
 		{ 0x7c800000, 0x30000000,	RTL_GIGA_MAC_VER_11 },
 
 		/* 8101 family. */
+		{ 0x7cf00000, 0x34a00000,	RTL_GIGA_MAC_VER_09 },
+		{ 0x7cf00000, 0x24a00000,	RTL_GIGA_MAC_VER_09 },
+		{ 0x7cf00000, 0x34900000,	RTL_GIGA_MAC_VER_08 },
+		{ 0x7cf00000, 0x24900000,	RTL_GIGA_MAC_VER_08 },
+		{ 0x7cf00000, 0x34800000,	RTL_GIGA_MAC_VER_07 },
+		{ 0x7cf00000, 0x24800000,	RTL_GIGA_MAC_VER_07 },
 		{ 0x7cf00000, 0x34000000,	RTL_GIGA_MAC_VER_13 },
+		{ 0x7cf00000, 0x34300000,	RTL_GIGA_MAC_VER_10 },
 		{ 0x7cf00000, 0x34200000,	RTL_GIGA_MAC_VER_16 },
+		{ 0x7c800000, 0x34800000,	RTL_GIGA_MAC_VER_09 },
 		{ 0x7c800000, 0x34000000,	RTL_GIGA_MAC_VER_16 },
 		/* FIXME: where did these entries come from ? -- FR */
 		{ 0xfc800000, 0x38800000,	RTL_GIGA_MAC_VER_15 },
@@ -1279,6 +1284,22 @@ static void rtl8168cx_hw_phy_config(void __iomem
*ioaddr)
 	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
 }
 
+static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0003 },
+		{ 0x08, 0x441d },
+		{ 0x01, 0x9100 },
+		{ 0x1f, 0x0000 }
+	};
+
+	mdio_write(ioaddr, 0x1f, 0x0000);
+	mdio_patch(ioaddr, 0x11, 1 << 12);
+	mdio_patch(ioaddr, 0x19, 1 << 13);
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
 static void rtl_hw_phy_config(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -1296,6 +1317,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
 	case RTL_GIGA_MAC_VER_04:
 		rtl8169sb_hw_phy_config(ioaddr);
 		break;
+	case RTL_GIGA_MAC_VER_07:
+	case RTL_GIGA_MAC_VER_08:
+	case RTL_GIGA_MAC_VER_09:
+		rtl8102e_hw_phy_config(ioaddr);
+		break;
 	case RTL_GIGA_MAC_VER_18:
 		rtl8168cp_hw_phy_config(ioaddr);
 		break;
@@ -1578,6 +1604,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct
pci_device_id *ent)
 	const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
 	const unsigned int region = cfg->region;
 	struct rtl8169_private *tp;
+	struct mii_if_info *mii;
 	struct net_device *dev;
 	void __iomem *ioaddr;
 	unsigned int i;
@@ -1602,6 +1629,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct
pci_device_id *ent)
 	tp->pci_dev = pdev;
 	tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
 
+	mii = &tp->mii;
+	mii->dev = dev;
+	mii->mdio_read = rtl_mdio_read;
+	mii->mdio_write = rtl_mdio_write;
+	mii->phy_id_mask = 0x1f;
+	mii->reg_num_mask = 0x1f;
+
 	/* enable device (incl. PCI PM wakeup and hotplug setup) */
 	rc = pci_enable_device(pdev);
 	if (rc < 0) {



^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-07-30 18:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-24 15:54 [patch inside] kernel crash, RTL8101E [10ec:8136] c4p7n1
2008-07-24 21:09 ` Francois Romieu
  -- strict thread matches above, loose matches on Subject: below --
2008-07-30 18:05 c4p7n1
2008-07-28 20:58 martin capitanio
2008-07-27 19:04 c4p7n1
2008-07-28 18:40 ` Francois Romieu
2008-07-24 20:23 martin capitanio
2008-07-24 15:34 martin capitanio
2008-07-24 15:57 ` Cédric Augonnet
2008-07-24 21:02   ` Francois Romieu

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).