2001-12-04 15:36:28

by Michael Clark

[permalink] [raw]
Subject: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

--- linux/drivers/net/ns83820.c.orig Tue Dec 4 20:27:10 2001
+++ linux/drivers/net/ns83820.c Tue Dec 4 23:33:34 2001
@@ -43,10 +43,12 @@
* otherwise fragments get lost
* - fix >> 32 bugs
* 0.12 - add statistics counters
* - add allmulti/promisc support
* 20011009 0.13 - hotplug support, other smaller pci api cleanups
+ * 20011204 0.13a - optical transceiver support added
+ * by Michael Clark <[email protected]>
*
* Driver Overview
* ===============
*
* This driver was originally written for the National Semiconductor
@@ -63,10 +65,11 @@
*
* Cameo SOHO-GA2000T SOHO-GA2500T
* D-Link DGE-500T
* PureData PDP8023Z-TG
* SMC SMC9452TX SMC9462TX
+ * Netgear GA621
*
* Special thanks to SMC for providing hardware to test this driver on.
*
* Reports of success or failure would be greatly appreciated.
*/
@@ -210,10 +213,11 @@
#define CFG_SPDSTS 0x60000000
#define CFG_SPDSTS1 0x40000000
#define CFG_SPDSTS0 0x20000000
#define CFG_DUPSTS 0x10000000
#define CFG_TBI_EN 0x01000000
+#define CFG_AUTO_1000 0x00200000
#define CFG_MODE_1000 0x00400000
#define CFG_PINT_CTL 0x001c0000
#define CFG_PINT_DUPSTS 0x00100000
#define CFG_PINT_LNKSTS 0x00080000
#define CFG_PINT_SPDSTS 0x00040000
@@ -314,10 +318,44 @@
#define VRCR 0xbc
#define VTCR 0xc0
#define VDR 0xc4
#define CCSR 0xcc

+#define TBICR 0xe0
+#define TBISR 0xe4
+#define TANAR 0xe8
+#define TANLPAR 0xec
+#define TANER 0xf0
+#define TESR 0xf4
+
+/* TBICR bit definitions */
+
+#define MR_AN_ENABLE 0x00001000
+#define MR_RESTART_AN 0x00000200
+
+/* TBISR bit definitions */
+
+#define MR_LINK_STATUS 0x00000020
+#define MR_AN_COMPLETE 0x00000004
+
+/* TANAR, TANALPAR bit definitions */
+
+#define PS2 0x00000100
+#define PS1 0x00000080
+#define HALF_DUP 0x00000040
+#define FULL_DUP 0x00000020
+
+/* GPIOR bit definitions */
+
+#define GP5_OE 0x00000200
+#define GP4_OE 0x00000100
+#define GP3_OE 0x00000080
+#define GP2_OE 0x00000040
+#define GP1_OE 0x00000020
+#define GP3_OUT 0x00000004
+#define GP1_OUT 0x00000001
+
#define __kick_rx(dev) writel(CR_RXE, dev->base + CR)

#define kick_rx(dev) do { \
dprintk("kick_rx: maybe kicking\n"); \
if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
@@ -543,28 +581,82 @@
build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
}

static void phy_intr(struct ns83820 *dev)
{
- static char *speeds[] = { "10", "100", "1000", "1000(?)" };
+ static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
u32 cfg, new_cfg;
+ u32 tbisr, tanar, tanlpar;
+ int speed, fullduplex = 0;

- new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;

- if (cfg & CFG_SPDSTS1)
- new_cfg |= CFG_MODE_1000 | CFG_SB;
- else
- new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+ if (dev->CFG_cache & CFG_TBI_EN) {

- if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
- writel(new_cfg, dev->base + CFG);
- dev->CFG_cache = new_cfg;
- }
+ /* we have an optical transceiver */
+ tbisr = readl(dev->base + TBISR);
+ tanar = readl(dev->base + TANAR);
+ tanlpar = readl(dev->base + TANLPAR);
+ dprintk("phy_intr: tbisr=%08x, tanar=%08x, tanlpar=%08x\n",
+ tbisr, tanar, tanlpar);
+
+ if (!tanlpar && !tbisr) {
+ dprintk("%s: waiting for autoneg to complete\n",
+ dev->net_dev.name);
+ return;
+ }
+
+ if ( (fullduplex = (tanlpar & FULL_DUP)
+ && (tanar & FULL_DUP)) ) {

- dev->CFG_cache &= ~CFG_SPDSTS;
- dev->CFG_cache |= cfg & CFG_SPDSTS;
+ /* both of us are full duplex */
+ writel(readl(dev->base + TXCFG)
+ | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
+ dev->base + TXCFG);
+ writel(readl(dev->base + RXCFG) | RXCFG_RX_FD,
+ dev->base + RXCFG);
+ /* Light up full duplex LED */
+ writel(readl(dev->base + GPIOR) | GP1_OUT,
+ dev->base + GPIOR);
+
+ } else if(((tanlpar & HALF_DUP) && (tanar & HALF_DUP))
+ || ((tanlpar & FULL_DUP) && (tanar & HALF_DUP))
+ || ((tanlpar & HALF_DUP) && (tanar & FULL_DUP))) {
+
+ /* one or both of us are half duplex */
+ writel((readl(dev->base + TXCFG)
+ & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
+ dev->base + TXCFG);
+ writel(readl(dev->base + RXCFG) & ~RXCFG_RX_FD,
+ dev->base + RXCFG);
+ /* Turn off full duplex LED */
+ writel(readl(dev->base + GPIOR) & ~GP1_OUT,
+ dev->base + GPIOR);
+ }
+
+ speed = 4; /* 1000F */
+
+ } else {
+ /* we have a copper transceiver */
+ new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
+
+ if (cfg & CFG_SPDSTS1)
+ new_cfg |= CFG_MODE_1000 | CFG_SB;
+ else
+ new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+
+ if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
+ writel(new_cfg, dev->base + CFG);
+ dev->CFG_cache = new_cfg;
+ }
+
+ dev->CFG_cache &= ~CFG_SPDSTS;
+ dev->CFG_cache |= cfg & CFG_SPDSTS;
+
+ speed = ((cfg / CFG_SPDSTS0) & 3);
+ fullduplex = (cfg & CFG_DUPSTS);
+ }

if (cfg & CFG_LNKSTS) {
netif_start_queue(&dev->net_dev);
netif_wake_queue(&dev->net_dev);
} else {
@@ -572,12 +664,12 @@
}

if (cfg & CFG_LNKSTS)
printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
dev->net_dev.name,
- speeds[((cfg / CFG_SPDSTS0) & 3)],
- (cfg & CFG_DUPSTS) ? "full" : "half");
+ speeds[speed],
+ fullduplex ? "full" : "half");
else
printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
}

static int ns83820_setup_rx(struct ns83820 *dev)
@@ -1341,10 +1433,27 @@
dev->CFG_cache |= CFG_BEM;
#else
#error This driver only works for big or little endian!!!
#endif

+ /* setup optical transceiver if we have one */
+ if(dev->CFG_cache & CFG_TBI_EN) {
+ printk("%s: enabling optical transceiver\n",
+ dev->net_dev.name);
+ writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
+
+ /* setup auto negotiation feature advertisement */
+ writel(readl(dev->base + TANAR) | HALF_DUP | FULL_DUP,
+ dev->base + TANAR);
+
+ /* start auto negotiation */
+ writel(MR_AN_ENABLE | MR_RESTART_AN, dev->base + TBICR);
+ writel(MR_AN_ENABLE, dev->base + TBICR);
+
+ dev->CFG_cache |= CFG_MODE_1000;
+ }
+
writel(dev->CFG_cache, dev->base + CFG);
dprintk("CFG: %08x\n", dev->CFG_cache);

if (readl(dev->base + SRR))
writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);


Attachments:
ns83820-optical.patch (6.28 kB)

2001-12-04 21:22:40

by Rob Myers

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

cool, i've tested your patch and it seems to work. now i will be free
of that unfriendly netgear driver. :) i tested it on an updated redhat
7.2 box. (2.4.9-13smp) it is an asus p2b-d motherboard. (p3 smp,
32bitpci).

i did notice some odd dmesg output, however:

eth%d: enabling 64 bit PCI.
eth%d: enabling optical transceiver
eth1: ns83820.c v0.13: DP83820 00:40:f4:29:ea:d7 pciaddr=0xe1000000
irq=12 rev 0x103
eth1: link now 1000F mbps, full duplex and up.
eth1: link now 1000F mbps, full duplex and up.

[now keeping in mind i know nothing of linux device drivers...]

this is only a 32bit pci box so why would it enable 64bit pci?

are references to dev->net_dev.name valid before
register_netdev(&dev->net_dev) in ns83820_init_one()?

is/why phy_intr() called 2wice?

thanks for the patch!

rob.


On Tue, 2001-12-04 at 10:35, Michael Clark wrote:
> Hi,
>
> This patch adds Netgear GA621 support to the ns83820 driver
> by adding code to configure the optical transceiver on
> these boards. People currently using Netgear driver (gam)
> may like to test this.
>
> I decided to add support for GA621 to the ns83820 driver after
> suffering an oops with the netgear supplied driver whose code
> is rather convoluted on not very Linux like (appears to be a
> port of a NDIS driver) ie. it won't probably ever make it into
> the kernel without a lot of rework.
>
> It would be good if someone could test this on copper
> cards to make sure it still works okay.
>
> ~mc
>
> ----
>

> --- linux/drivers/net/ns83820.c.orig Tue Dec 4 20:27:10 2001
> +++ linux/drivers/net/ns83820.c Tue Dec 4 23:33:34 2001
> @@ -43,10 +43,12 @@
> * otherwise fragments get lost
> * - fix >> 32 bugs
> * 0.12 - add statistics counters
> * - add allmulti/promisc support
> * 20011009 0.13 - hotplug support, other smaller pci api cleanups
> + * 20011204 0.13a - optical transceiver support added
> + * by Michael Clark <[email protected]>
> *
> * Driver Overview
> * ===============
> *
> * This driver was originally written for the National Semiconductor
> @@ -63,10 +65,11 @@
> *
> * Cameo SOHO-GA2000T SOHO-GA2500T
> * D-Link DGE-500T
> * PureData PDP8023Z-TG
> * SMC SMC9452TX SMC9462TX
> + * Netgear GA621
> *
> * Special thanks to SMC for providing hardware to test this driver on.
> *
> * Reports of success or failure would be greatly appreciated.
> */
> @@ -210,10 +213,11 @@
> #define CFG_SPDSTS 0x60000000
> #define CFG_SPDSTS1 0x40000000
> #define CFG_SPDSTS0 0x20000000
> #define CFG_DUPSTS 0x10000000
> #define CFG_TBI_EN 0x01000000
> +#define CFG_AUTO_1000 0x00200000
> #define CFG_MODE_1000 0x00400000
> #define CFG_PINT_CTL 0x001c0000
> #define CFG_PINT_DUPSTS 0x00100000
> #define CFG_PINT_LNKSTS 0x00080000
> #define CFG_PINT_SPDSTS 0x00040000
> @@ -314,10 +318,44 @@
> #define VRCR 0xbc
> #define VTCR 0xc0
> #define VDR 0xc4
> #define CCSR 0xcc
>
> +#define TBICR 0xe0
> +#define TBISR 0xe4
> +#define TANAR 0xe8
> +#define TANLPAR 0xec
> +#define TANER 0xf0
> +#define TESR 0xf4
> +
> +/* TBICR bit definitions */
> +
> +#define MR_AN_ENABLE 0x00001000
> +#define MR_RESTART_AN 0x00000200
> +
> +/* TBISR bit definitions */
> +
> +#define MR_LINK_STATUS 0x00000020
> +#define MR_AN_COMPLETE 0x00000004
> +
> +/* TANAR, TANALPAR bit definitions */
> +
> +#define PS2 0x00000100
> +#define PS1 0x00000080
> +#define HALF_DUP 0x00000040
> +#define FULL_DUP 0x00000020
> +
> +/* GPIOR bit definitions */
> +
> +#define GP5_OE 0x00000200
> +#define GP4_OE 0x00000100
> +#define GP3_OE 0x00000080
> +#define GP2_OE 0x00000040
> +#define GP1_OE 0x00000020
> +#define GP3_OUT 0x00000004
> +#define GP1_OUT 0x00000001
> +
> #define __kick_rx(dev) writel(CR_RXE, dev->base + CR)
>
> #define kick_rx(dev) do { \
> dprintk("kick_rx: maybe kicking\n"); \
> if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
> @@ -543,28 +581,82 @@
> build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
> }
>
> static void phy_intr(struct ns83820 *dev)
> {
> - static char *speeds[] = { "10", "100", "1000", "1000(?)" };
> + static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
> u32 cfg, new_cfg;
> + u32 tbisr, tanar, tanlpar;
> + int speed, fullduplex = 0;
>
> - new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
> cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;
>
> - if (cfg & CFG_SPDSTS1)
> - new_cfg |= CFG_MODE_1000 | CFG_SB;
> - else
> - new_cfg &= ~CFG_MODE_1000 | CFG_SB;
> + if (dev->CFG_cache & CFG_TBI_EN) {
>
> - if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
> - writel(new_cfg, dev->base + CFG);
> - dev->CFG_cache = new_cfg;
> - }
> + /* we have an optical transceiver */
> + tbisr = readl(dev->base + TBISR);
> + tanar = readl(dev->base + TANAR);
> + tanlpar = readl(dev->base + TANLPAR);
> + dprintk("phy_intr: tbisr=%08x, tanar=%08x, tanlpar=%08x\n",
> + tbisr, tanar, tanlpar);
> +
> + if (!tanlpar && !tbisr) {
> + dprintk("%s: waiting for autoneg to complete\n",
> + dev->net_dev.name);
> + return;
> + }
> +
> + if ( (fullduplex = (tanlpar & FULL_DUP)
> + && (tanar & FULL_DUP)) ) {
>
> - dev->CFG_cache &= ~CFG_SPDSTS;
> - dev->CFG_cache |= cfg & CFG_SPDSTS;
> + /* both of us are full duplex */
> + writel(readl(dev->base + TXCFG)
> + | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
> + dev->base + TXCFG);
> + writel(readl(dev->base + RXCFG) | RXCFG_RX_FD,
> + dev->base + RXCFG);
> + /* Light up full duplex LED */
> + writel(readl(dev->base + GPIOR) | GP1_OUT,
> + dev->base + GPIOR);
> +
> + } else if(((tanlpar & HALF_DUP) && (tanar & HALF_DUP))
> + || ((tanlpar & FULL_DUP) && (tanar & HALF_DUP))
> + || ((tanlpar & HALF_DUP) && (tanar & FULL_DUP))) {
> +
> + /* one or both of us are half duplex */
> + writel((readl(dev->base + TXCFG)
> + & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
> + dev->base + TXCFG);
> + writel(readl(dev->base + RXCFG) & ~RXCFG_RX_FD,
> + dev->base + RXCFG);
> + /* Turn off full duplex LED */
> + writel(readl(dev->base + GPIOR) & ~GP1_OUT,
> + dev->base + GPIOR);
> + }
> +
> + speed = 4; /* 1000F */
> +
> + } else {
> + /* we have a copper transceiver */
> + new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
> +
> + if (cfg & CFG_SPDSTS1)
> + new_cfg |= CFG_MODE_1000 | CFG_SB;
> + else
> + new_cfg &= ~CFG_MODE_1000 | CFG_SB;
> +
> + if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
> + writel(new_cfg, dev->base + CFG);
> + dev->CFG_cache = new_cfg;
> + }
> +
> + dev->CFG_cache &= ~CFG_SPDSTS;
> + dev->CFG_cache |= cfg & CFG_SPDSTS;
> +
> + speed = ((cfg / CFG_SPDSTS0) & 3);
> + fullduplex = (cfg & CFG_DUPSTS);
> + }
>
> if (cfg & CFG_LNKSTS) {
> netif_start_queue(&dev->net_dev);
> netif_wake_queue(&dev->net_dev);
> } else {
> @@ -572,12 +664,12 @@
> }
>
> if (cfg & CFG_LNKSTS)
> printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
> dev->net_dev.name,
> - speeds[((cfg / CFG_SPDSTS0) & 3)],
> - (cfg & CFG_DUPSTS) ? "full" : "half");
> + speeds[speed],
> + fullduplex ? "full" : "half");
> else
> printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
> }
>
> static int ns83820_setup_rx(struct ns83820 *dev)
> @@ -1341,10 +1433,27 @@
> dev->CFG_cache |= CFG_BEM;
> #else
> #error This driver only works for big or little endian!!!
> #endif
>
> + /* setup optical transceiver if we have one */
> + if(dev->CFG_cache & CFG_TBI_EN) {
> + printk("%s: enabling optical transceiver\n",
> + dev->net_dev.name);
> + writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
> +
> + /* setup auto negotiation feature advertisement */
> + writel(readl(dev->base + TANAR) | HALF_DUP | FULL_DUP,
> + dev->base + TANAR);
> +
> + /* start auto negotiation */
> + writel(MR_AN_ENABLE | MR_RESTART_AN, dev->base + TBICR);
> + writel(MR_AN_ENABLE, dev->base + TBICR);
> +
> + dev->CFG_cache |= CFG_MODE_1000;
> + }
> +
> writel(dev->CFG_cache, dev->base + CFG);
> dprintk("CFG: %08x\n", dev->CFG_cache);
>
> if (readl(dev->base + SRR))
> writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);


2001-12-04 21:31:30

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

Rob Myers wrote:
> are references to dev->net_dev.name valid before
> register_netdev(&dev->net_dev) in ns83820_init_one()?

no. register_netdev is where an interface number(name) is assigned.

--
Jeff Garzik | Only so many songs can be sung
Building 1024 | with two lips, two lungs, and one tongue.
MandrakeSoft | - nomeansno

2001-12-05 01:49:01

by Michael Clark

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

Rob Myers wrote:

> cool, i've tested your patch and it seems to work. now i will be free
> of that unfriendly netgear driver. :) i tested it on an updated redhat
> 7.2 box. (2.4.9-13smp) it is an asus p2b-d motherboard. (p3 smp,
> 32bitpci).
>
> i did notice some odd dmesg output, however:
>
> eth%d: enabling 64 bit PCI.
> eth%d: enabling optical transceiver
> eth1: ns83820.c v0.13: DP83820 00:40:f4:29:ea:d7 pciaddr=0xe1000000
> irq=12 rev 0x103
> eth1: link now 1000F mbps, full duplex and up.
> eth1: link now 1000F mbps, full duplex and up.
>
> [now keeping in mind i know nothing of linux device drivers...]
>
> this is only a 32bit pci box so why would it enable 64bit pci?


The code reads a 64bit detect flag from the ns chip - so I guess it
must be bogus with some motherboards. Mine is okay. Ben??


> are references to dev->net_dev.name valid before
> register_netdev(&dev->net_dev) in ns83820_init_one()?


Okay, so i'll move the register_netdev call earlier on in the
initialisation and add any necessary unregister call for failures.


> is/why phy_intr() called 2wice?


The card issues multiple interrupts during auto-negotiation. If you
change the dprintk to a printk on the line with the tbisr=, tanar=,
you'll see the details of the phy interrupt. The driver needs a link
status variable so we then only print link status changes when
link status changes. The current problem is purely cosmetic.


> thanks for the patch!
>
> rob.



2001-12-05 05:03:29

by Michael Clark

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

--- linux/drivers/net/ns83820.c.orig Tue Dec 4 20:27:10 2001
+++ linux/drivers/net/ns83820.c Wed Dec 5 12:39:08 2001
@@ -1,6 +1,6 @@
-#define VERSION "0.13"
+#define VERSION "0.13b"
/* ns83820.c by Benjamin LaHaise <[email protected]>
*
* $Revision: 1.34.2.8 $
*
* Copyright 2001 Benjamin LaHaise.
@@ -43,10 +43,14 @@
* otherwise fragments get lost
* - fix >> 32 bugs
* 0.12 - add statistics counters
* - add allmulti/promisc support
* 20011009 0.13 - hotplug support, other smaller pci api cleanups
+ * 20011204 0.13a - optical transceiver support added
+ * by Michael Clark <[email protected]>
+ * 20011205 0.13b - call register_netdev earlier in initialization
+ * suppress duplicate link status messages
*
* Driver Overview
* ===============
*
* This driver was originally written for the National Semiconductor
@@ -63,10 +67,11 @@
*
* Cameo SOHO-GA2000T SOHO-GA2500T
* D-Link DGE-500T
* PureData PDP8023Z-TG
* SMC SMC9452TX SMC9462TX
+ * Netgear GA621
*
* Special thanks to SMC for providing hardware to test this driver on.
*
* Reports of success or failure would be greatly appreciated.
*/
@@ -210,10 +215,11 @@
#define CFG_SPDSTS 0x60000000
#define CFG_SPDSTS1 0x40000000
#define CFG_SPDSTS0 0x20000000
#define CFG_DUPSTS 0x10000000
#define CFG_TBI_EN 0x01000000
+#define CFG_AUTO_1000 0x00200000
#define CFG_MODE_1000 0x00400000
#define CFG_PINT_CTL 0x001c0000
#define CFG_PINT_DUPSTS 0x00100000
#define CFG_PINT_LNKSTS 0x00080000
#define CFG_PINT_SPDSTS 0x00040000
@@ -314,10 +320,40 @@
#define VRCR 0xbc
#define VTCR 0xc0
#define VDR 0xc4
#define CCSR 0xcc

+#define TBICR 0xe0
+#define TBISR 0xe4
+#define TANAR 0xe8
+#define TANLPAR 0xec
+#define TANER 0xf0
+#define TESR 0xf4
+
+#define TBICR_MR_AN_ENABLE 0x00001000
+#define TBICR_MR_RESTART_AN 0x00000200
+
+#define TBISR_MR_LINK_STATUS 0x00000020
+#define TBISR_MR_AN_COMPLETE 0x00000004
+
+#define TANAR_PS2 0x00000100
+#define TANAR_PS1 0x00000080
+#define TANAR_HALF_DUP 0x00000040
+#define TANAR_FULL_DUP 0x00000020
+
+#define GPIOR_GP5_OE 0x00000200
+#define GPIOR_GP4_OE 0x00000100
+#define GPIOR_GP3_OE 0x00000080
+#define GPIOR_GP2_OE 0x00000040
+#define GPIOR_GP1_OE 0x00000020
+#define GPIOR_GP3_OUT 0x00000004
+#define GPIOR_GP1_OUT 0x00000001
+
+#define LINK_AUTONEGOTIATE 0x01
+#define LINK_DOWN 0x02
+#define LINK_UP 0x04
+
#define __kick_rx(dev) writel(CR_RXE, dev->base + CR)

#define kick_rx(dev) do { \
dprintk("kick_rx: maybe kicking\n"); \
if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
@@ -388,10 +424,11 @@

u32 MEAR_cache;
u32 IMR_cache;
struct eeprom ee;

+ unsigned linkstate;

spinlock_t tx_lock;

long tx_idle;
u32 tx_done_idx;
@@ -543,43 +580,97 @@
build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
}

static void phy_intr(struct ns83820 *dev)
{
- static char *speeds[] = { "10", "100", "1000", "1000(?)" };
+ static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
u32 cfg, new_cfg;
+ u32 tbisr, tanar, tanlpar;
+ int speed, fullduplex, newlinkstate;

- new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;

- if (cfg & CFG_SPDSTS1)
- new_cfg |= CFG_MODE_1000 | CFG_SB;
- else
- new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+ if (dev->CFG_cache & CFG_TBI_EN) {

- if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
- writel(new_cfg, dev->base + CFG);
- dev->CFG_cache = new_cfg;
- }
+ /* we have an optical transceiver */
+ tbisr = readl(dev->base + TBISR);
+ tanar = readl(dev->base + TANAR);
+ tanlpar = readl(dev->base + TANLPAR);
+ dprintk("phy_intr: tbisr=%08x, tanar=%08x, tanlpar=%08x\n",
+ tbisr, tanar, tanlpar);
+
+ if ( (fullduplex = (tanlpar & TANAR_FULL_DUP)
+ && (tanar & TANAR_FULL_DUP)) ) {
+
+ /* both of us are full duplex */
+ writel(readl(dev->base + TXCFG)
+ | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
+ dev->base + TXCFG);
+ writel(readl(dev->base + RXCFG) | RXCFG_RX_FD,
+ dev->base + RXCFG);
+ /* Light up full duplex LED */
+ writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT,
+ dev->base + GPIOR);
+
+ } else if(((tanlpar & TANAR_HALF_DUP)
+ && (tanar & TANAR_HALF_DUP))
+ || ((tanlpar & TANAR_FULL_DUP)
+ && (tanar & TANAR_HALF_DUP))
+ || ((tanlpar & TANAR_HALF_DUP)
+ && (tanar & TANAR_FULL_DUP))) {
+
+ /* one or both of us are half duplex */
+ writel((readl(dev->base + TXCFG)
+ & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
+ dev->base + TXCFG);
+ writel(readl(dev->base + RXCFG) & ~RXCFG_RX_FD,
+ dev->base + RXCFG);
+ /* Turn off full duplex LED */
+ writel(readl(dev->base + GPIOR) & ~GPIOR_GP1_OUT,
+ dev->base + GPIOR);
+ }

- dev->CFG_cache &= ~CFG_SPDSTS;
- dev->CFG_cache |= cfg & CFG_SPDSTS;
+ speed = 4; /* 1000F */

- if (cfg & CFG_LNKSTS) {
- netif_start_queue(&dev->net_dev);
- netif_wake_queue(&dev->net_dev);
} else {
- netif_stop_queue(&dev->net_dev);
+ /* we have a copper transceiver */
+ new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
+
+ if (cfg & CFG_SPDSTS1)
+ new_cfg |= CFG_MODE_1000 | CFG_SB;
+ else
+ new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+
+ if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
+ writel(new_cfg, dev->base + CFG);
+ dev->CFG_cache = new_cfg;
+ }
+
+ dev->CFG_cache &= ~CFG_SPDSTS;
+ dev->CFG_cache |= cfg & CFG_SPDSTS;
+
+ speed = ((cfg / CFG_SPDSTS0) & 3);
+ fullduplex = (cfg & CFG_DUPSTS);
}

- if (cfg & CFG_LNKSTS)
+ newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
+
+ if (newlinkstate & LINK_UP
+ && dev->linkstate != newlinkstate) {
+ netif_start_queue(&dev->net_dev);
+ netif_wake_queue(&dev->net_dev);
printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
dev->net_dev.name,
- speeds[((cfg / CFG_SPDSTS0) & 3)],
- (cfg & CFG_DUPSTS) ? "full" : "half");
- else
+ speeds[speed],
+ fullduplex ? "full" : "half");
+ } else if (newlinkstate & LINK_DOWN
+ && dev->linkstate != newlinkstate) {
+ netif_stop_queue(&dev->net_dev);
printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
+ }
+
+ dev->linkstate = newlinkstate;
}

static int ns83820_setup_rx(struct ns83820 *dev)
{
unsigned i;
@@ -1248,10 +1339,12 @@
dev->ee.lock = &dev->misc_lock;
dev->net_dev.owner = THIS_MODULE;

PREPARE_TQUEUE(&dev->tq_refill, queue_refill, dev);

+ if(register_netdev(&dev->net_dev)) goto out_reg;
+
err = pci_enable_device(pci_dev);
if (err) {
printk(KERN_INFO "ns83820: pci_enable_dev: %d\n", err);
goto out_free;
}
@@ -1341,10 +1434,30 @@
dev->CFG_cache |= CFG_BEM;
#else
#error This driver only works for big or little endian!!!
#endif

+ /* setup optical transceiver if we have one */
+ if(dev->CFG_cache & CFG_TBI_EN) {
+ printk("%s: enabling optical transceiver\n",
+ dev->net_dev.name);
+ writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
+
+ /* setup auto negotiation feature advertisement */
+ writel(readl(dev->base + TANAR)
+ | TANAR_HALF_DUP | TANAR_FULL_DUP,
+ dev->base + TANAR);
+
+ /* start auto negotiation */
+ writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN,
+ dev->base + TBICR);
+ writel(TBICR_MR_AN_ENABLE, dev->base + TBICR);
+ dev->linkstate = LINK_AUTONEGOTIATE;
+
+ dev->CFG_cache |= CFG_MODE_1000;
+ }
+
writel(dev->CFG_cache, dev->base + CFG);
dprintk("CFG: %08x\n", dev->CFG_cache);

if (readl(dev->base + SRR))
writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);
@@ -1395,12 +1508,10 @@
dev->net_dev.features |= NETIF_F_IP_CSUM;
#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
dev->net_dev.features |= NETIF_F_HIGHDMA;
#endif

- register_netdev(&dev->net_dev);
-
printk(KERN_INFO "%s: ns83820.c v" VERSION ": DP83820 %02x:%02x:%02x:%02x:%02x:%02x pciaddr=0x%08lx irq=%d rev 0x%x\n",
dev->net_dev.name,
dev->net_dev.dev_addr[0], dev->net_dev.dev_addr[1],
dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
@@ -1415,10 +1526,12 @@
out_disable:
pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_TX_DESC, dev->tx_descs, dev->tx_phy_descs);
pci_free_consistent(pci_dev, 4 * DESC_SIZE * NR_RX_DESC, dev->rx_info.descs, dev->rx_info.phy_descs);
pci_disable_device(pci_dev);
out_free:
+ unregister_netdev(&dev->net_dev);
+out_reg:
kfree(dev);
pci_set_drvdata(pci_dev, NULL);
out:
return err;
}
--- linux/Documentation/Configure.help.orig Fri Nov 23 17:09:30 2001
+++ linux/Documentation/Configure.help Wed Dec 5 12:57:08 2001
@@ -22441,12 +22441,12 @@
National Semiconductor DP83820 series driver
CONFIG_NS83820
This is a driver for the National Semiconductor DP83820 series
of gigabit ethernet MACs. Cards using this chipset include
the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
- SOHO-GA2000T, SOHO-GA2500T. The driver supports the use of
- zero copy.
+ SOHO-GA2000T, SOHO-GA2500T and Netgear GA621. The driver
+ supports the use of zero copy.

Toshiba Type-O IR Port device driver
CONFIG_TOSHIBA_FIR
Say Y here if you want to build support for the Toshiba Type-O IR
chipset. This chipset is used by the Toshiba Libretto 100CT, and


Attachments:
ns83820-optical-0.13b.patch (9.19 kB)

2001-12-05 12:56:09

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

Michael Clark wrote:
> > are references to dev->net_dev.name valid before
> > register_netdev(&dev->net_dev) in ns83820_init_one()?
>
> Okay, so i'll move the register_netdev call earlier on in the
> initialisation and add any necessary unregister call for failures.

Not a solution but more of a problem... a user might see:

eth0: startup message
eth0: startup message
{failure, unregisters eth0}
eth0: startup message
eth0: startup message
{failure, unregisters eth0}
eth0: startup message
eth0: startup message
{failure, unregisters eth0}

That's particularly messy to diagnose when eth0 may not really be eth0.
Further in a hotplug multi-threaded world you are reserving an ethernet
interface which may not be used.

I greatly prefer assigning board numbers (ns83820_0, ns83820_0, or ns0,
ns1, ns2) temporarily until you are sure you can register the interface
with the likelihood it will not be unregistered until module removal
time, or never [if built into kernel].

Jeff



--
Jeff Garzik | Only so many songs can be sung
Building 1024 | with two lips, two lungs, and one tongue.
MandrakeSoft | - nomeansno

2001-12-05 14:38:07

by Michael Clark

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

--- linux/drivers/net/ns83820.c.orig Wed Dec 5 22:17:34 2001
+++ linux/drivers/net/ns83820.c Wed Dec 5 22:05:38 2001
@@ -1,6 +1,6 @@
-#define VERSION "0.13"
+#define VERSION "0.13b"
/* ns83820.c by Benjamin LaHaise <[email protected]>
*
* $Revision: 1.34.2.8 $
*
* Copyright 2001 Benjamin LaHaise.
@@ -43,10 +43,14 @@
* otherwise fragments get lost
* - fix >> 32 bugs
* 0.12 - add statistics counters
* - add allmulti/promisc support
* 20011009 0.13 - hotplug support, other smaller pci api cleanups
+ * 20011204 0.13a - optical transceiver support added
+ * by Michael Clark <[email protected]>
+ * 20011205 0.13b - call register_netdev earlier in initialization
+ * suppress duplicate link status messages
*
* Driver Overview
* ===============
*
* This driver was originally written for the National Semiconductor
@@ -63,10 +67,11 @@
*
* Cameo SOHO-GA2000T SOHO-GA2500T
* D-Link DGE-500T
* PureData PDP8023Z-TG
* SMC SMC9452TX SMC9462TX
+ * Netgear GA621
*
* Special thanks to SMC for providing hardware to test this driver on.
*
* Reports of success or failure would be greatly appreciated.
*/
@@ -210,10 +215,11 @@
#define CFG_SPDSTS 0x60000000
#define CFG_SPDSTS1 0x40000000
#define CFG_SPDSTS0 0x20000000
#define CFG_DUPSTS 0x10000000
#define CFG_TBI_EN 0x01000000
+#define CFG_AUTO_1000 0x00200000
#define CFG_MODE_1000 0x00400000
#define CFG_PINT_CTL 0x001c0000
#define CFG_PINT_DUPSTS 0x00100000
#define CFG_PINT_LNKSTS 0x00080000
#define CFG_PINT_SPDSTS 0x00040000
@@ -314,10 +320,40 @@
#define VRCR 0xbc
#define VTCR 0xc0
#define VDR 0xc4
#define CCSR 0xcc

+#define TBICR 0xe0
+#define TBISR 0xe4
+#define TANAR 0xe8
+#define TANLPAR 0xec
+#define TANER 0xf0
+#define TESR 0xf4
+
+#define TBICR_MR_AN_ENABLE 0x00001000
+#define TBICR_MR_RESTART_AN 0x00000200
+
+#define TBISR_MR_LINK_STATUS 0x00000020
+#define TBISR_MR_AN_COMPLETE 0x00000004
+
+#define TANAR_PS2 0x00000100
+#define TANAR_PS1 0x00000080
+#define TANAR_HALF_DUP 0x00000040
+#define TANAR_FULL_DUP 0x00000020
+
+#define GPIOR_GP5_OE 0x00000200
+#define GPIOR_GP4_OE 0x00000100
+#define GPIOR_GP3_OE 0x00000080
+#define GPIOR_GP2_OE 0x00000040
+#define GPIOR_GP1_OE 0x00000020
+#define GPIOR_GP3_OUT 0x00000004
+#define GPIOR_GP1_OUT 0x00000001
+
+#define LINK_AUTONEGOTIATE 0x01
+#define LINK_DOWN 0x02
+#define LINK_UP 0x04
+
#define __kick_rx(dev) writel(CR_RXE, dev->base + CR)

#define kick_rx(dev) do { \
dprintk("kick_rx: maybe kicking\n"); \
if (test_and_clear_bit(0, &dev->rx_info.idle)) { \
@@ -388,10 +424,11 @@

u32 MEAR_cache;
u32 IMR_cache;
struct eeprom ee;

+ unsigned linkstate;

spinlock_t tx_lock;

long tx_idle;
u32 tx_done_idx;
@@ -543,43 +580,97 @@
build_rx_desc(dev, dev->rx_info.descs + (DESC_SIZE * i), 0, 0, CMDSTS_OWN, 0);
}

static void phy_intr(struct ns83820 *dev)
{
- static char *speeds[] = { "10", "100", "1000", "1000(?)" };
+ static char *speeds[] = { "10", "100", "1000", "1000(?)", "1000F" };
u32 cfg, new_cfg;
+ u32 tbisr, tanar, tanlpar;
+ int speed, fullduplex, newlinkstate;

- new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;

- if (cfg & CFG_SPDSTS1)
- new_cfg |= CFG_MODE_1000 | CFG_SB;
- else
- new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+ if (dev->CFG_cache & CFG_TBI_EN) {

- if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
- writel(new_cfg, dev->base + CFG);
- dev->CFG_cache = new_cfg;
- }
+ /* we have an optical transceiver */
+ tbisr = readl(dev->base + TBISR);
+ tanar = readl(dev->base + TANAR);
+ tanlpar = readl(dev->base + TANLPAR);
+ dprintk("phy_intr: tbisr=%08x, tanar=%08x, tanlpar=%08x\n",
+ tbisr, tanar, tanlpar);
+
+ if ( (fullduplex = (tanlpar & TANAR_FULL_DUP)
+ && (tanar & TANAR_FULL_DUP)) ) {
+
+ /* both of us are full duplex */
+ writel(readl(dev->base + TXCFG)
+ | TXCFG_CSI | TXCFG_HBI | TXCFG_ATP,
+ dev->base + TXCFG);
+ writel(readl(dev->base + RXCFG) | RXCFG_RX_FD,
+ dev->base + RXCFG);
+ /* Light up full duplex LED */
+ writel(readl(dev->base + GPIOR) | GPIOR_GP1_OUT,
+ dev->base + GPIOR);
+
+ } else if(((tanlpar & TANAR_HALF_DUP)
+ && (tanar & TANAR_HALF_DUP))
+ || ((tanlpar & TANAR_FULL_DUP)
+ && (tanar & TANAR_HALF_DUP))
+ || ((tanlpar & TANAR_HALF_DUP)
+ && (tanar & TANAR_FULL_DUP))) {
+
+ /* one or both of us are half duplex */
+ writel((readl(dev->base + TXCFG)
+ & ~(TXCFG_CSI | TXCFG_HBI)) | TXCFG_ATP,
+ dev->base + TXCFG);
+ writel(readl(dev->base + RXCFG) & ~RXCFG_RX_FD,
+ dev->base + RXCFG);
+ /* Turn off full duplex LED */
+ writel(readl(dev->base + GPIOR) & ~GPIOR_GP1_OUT,
+ dev->base + GPIOR);
+ }

- dev->CFG_cache &= ~CFG_SPDSTS;
- dev->CFG_cache |= cfg & CFG_SPDSTS;
+ speed = 4; /* 1000F */

- if (cfg & CFG_LNKSTS) {
- netif_start_queue(&dev->net_dev);
- netif_wake_queue(&dev->net_dev);
} else {
- netif_stop_queue(&dev->net_dev);
+ /* we have a copper transceiver */
+ new_cfg = dev->CFG_cache & ~(CFG_SB | CFG_MODE_1000 | CFG_SPDSTS);
+
+ if (cfg & CFG_SPDSTS1)
+ new_cfg |= CFG_MODE_1000 | CFG_SB;
+ else
+ new_cfg &= ~CFG_MODE_1000 | CFG_SB;
+
+ if ((cfg & CFG_LNKSTS) && ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) {
+ writel(new_cfg, dev->base + CFG);
+ dev->CFG_cache = new_cfg;
+ }
+
+ dev->CFG_cache &= ~CFG_SPDSTS;
+ dev->CFG_cache |= cfg & CFG_SPDSTS;
+
+ speed = ((cfg / CFG_SPDSTS0) & 3);
+ fullduplex = (cfg & CFG_DUPSTS);
}

- if (cfg & CFG_LNKSTS)
+ newlinkstate = (cfg & CFG_LNKSTS) ? LINK_UP : LINK_DOWN;
+
+ if (newlinkstate & LINK_UP
+ && dev->linkstate != newlinkstate) {
+ netif_start_queue(&dev->net_dev);
+ netif_wake_queue(&dev->net_dev);
printk(KERN_INFO "%s: link now %s mbps, %s duplex and up.\n",
dev->net_dev.name,
- speeds[((cfg / CFG_SPDSTS0) & 3)],
- (cfg & CFG_DUPSTS) ? "full" : "half");
- else
+ speeds[speed],
+ fullduplex ? "full" : "half");
+ } else if (newlinkstate & LINK_DOWN
+ && dev->linkstate != newlinkstate) {
+ netif_stop_queue(&dev->net_dev);
printk(KERN_INFO "%s: link now down.\n", dev->net_dev.name);
+ }
+
+ dev->linkstate = newlinkstate;
}

static int ns83820_setup_rx(struct ns83820 *dev)
{
unsigned i;
@@ -1285,10 +1376,12 @@
printk(KERN_INFO "ns83820: unable to register irq %d\n",
pci_dev->irq);
goto out_unmap;
}

+ if(register_netdev(&dev->net_dev)) goto out_unmap;
+
dev->net_dev.open = ns83820_open;
dev->net_dev.stop = ns83820_stop;
dev->net_dev.hard_start_xmit = ns83820_hard_start_xmit;
dev->net_dev.change_mtu = ns83820_change_mtu;
dev->net_dev.get_stats = ns83820_get_stats;
@@ -1341,10 +1434,30 @@
dev->CFG_cache |= CFG_BEM;
#else
#error This driver only works for big or little endian!!!
#endif

+ /* setup optical transceiver if we have one */
+ if(dev->CFG_cache & CFG_TBI_EN) {
+ printk("%s: enabling optical transceiver\n",
+ dev->net_dev.name);
+ writel(readl(dev->base + GPIOR) | 0x3e8, dev->base + GPIOR);
+
+ /* setup auto negotiation feature advertisement */
+ writel(readl(dev->base + TANAR)
+ | TANAR_HALF_DUP | TANAR_FULL_DUP,
+ dev->base + TANAR);
+
+ /* start auto negotiation */
+ writel(TBICR_MR_AN_ENABLE | TBICR_MR_RESTART_AN,
+ dev->base + TBICR);
+ writel(TBICR_MR_AN_ENABLE, dev->base + TBICR);
+ dev->linkstate = LINK_AUTONEGOTIATE;
+
+ dev->CFG_cache |= CFG_MODE_1000;
+ }
+
writel(dev->CFG_cache, dev->base + CFG);
dprintk("CFG: %08x\n", dev->CFG_cache);

if (readl(dev->base + SRR))
writel(readl(dev->base+0x20c) | 0xfe00, dev->base + 0x20c);
@@ -1395,12 +1508,10 @@
dev->net_dev.features |= NETIF_F_IP_CSUM;
#if defined(USE_64BIT_ADDR) || defined(CONFIG_HIGHMEM4G)
dev->net_dev.features |= NETIF_F_HIGHDMA;
#endif

- register_netdev(&dev->net_dev);
-
printk(KERN_INFO "%s: ns83820.c v" VERSION ": DP83820 %02x:%02x:%02x:%02x:%02x:%02x pciaddr=0x%08lx irq=%d rev 0x%x\n",
dev->net_dev.name,
dev->net_dev.dev_addr[0], dev->net_dev.dev_addr[1],
dev->net_dev.dev_addr[2], dev->net_dev.dev_addr[3],
dev->net_dev.dev_addr[4], dev->net_dev.dev_addr[5],
--- linux/Documentation/Configure.help.orig Fri Nov 23 17:09:30 2001
+++ linux/Documentation/Configure.help Wed Dec 5 12:57:08 2001
@@ -22441,12 +22441,12 @@
National Semiconductor DP83820 series driver
CONFIG_NS83820
This is a driver for the National Semiconductor DP83820 series
of gigabit ethernet MACs. Cards using this chipset include
the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
- SOHO-GA2000T, SOHO-GA2500T. The driver supports the use of
- zero copy.
+ SOHO-GA2000T, SOHO-GA2500T and Netgear GA621. The driver
+ supports the use of zero copy.

Toshiba Type-O IR Port device driver
CONFIG_TOSHIBA_FIR
Say Y here if you want to build support for the Toshiba Type-O IR
chipset. This chipset is used by the Toshiba Libretto 100CT, and


Attachments:
ns83820-optical-0.13c.patch (8.87 kB)

2001-12-05 16:55:34

by Rob Myers

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

On Wed, 2001-12-05 at 09:37, Michael Clark wrote:
> Problem solved. New patch attached.

ns83820-optical-0.13c.patch works, too. although you forgot to bump the
version letter to c. ;) the versions in the dmesg output below are
correct. (i tested the p2b-d with v0.13c and the cur-dls with v0.13b)

i wonder what implications there are that its trying to do 64bit pci on
the p2b-d board?

thanks again michael, jeff, and ben!

rob.

asus p2b-d dmesg output: (32bit pci slot / redhat 7.2 / 2.4.9 stock
kernel)
eth1: enabling 64 bit PCI.
eth1: enabling optical transceiver
eth1: ns83820.c v0.13c: DP83820 00:40:f4:29:ea:d7 pciaddr=0xe1000000
irq=12 rev 0x103
eth1: link now 1000F mbps, full duplex and up.

asus p2b-d dmesg output: (same 32bit pci slot / 2.4.16)
eth1: enabling 64 bit PCI.
eth1: enabling optical transceiver
eth1: ns83820.c v0.13c: DP83820 00:40:f4:29:ea:d7 pciaddr=0xe1000000
irq=12 rev 0x103
eth1: link now 1000F mbps, full duplex and up.

tyan cur-dls dmesg output: (64bit pci slot / 2.4.16)
eth2: enabling 64 bit PCI.
eth2: enabling optical transceiver
eth2: ns83820.c v0.13b: DP83820 00:40:f4:29:ea:d7 pciaddr=0xf8800000
irq=21 rev 0x103
eth2: link now 1000F mbps, full duplex and up.

tyan cur-dls dmesg output: (32bit pci slot / 2.4.16)
eth2: disabling 64 bit PCI.
eth2: enabling optical transceiver
eth2: ns83820.c v0.13b: DP83820 00:40:f4:29:ea:d7 pciaddr=0xfc000000
irq=17 rev 0x103
eth2: link now 1000F mbps, full duplex and up.



2001-12-05 22:50:58

by Benjamin LaHaise

[permalink] [raw]
Subject: Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)

On Wed, Dec 05, 2001 at 09:48:26AM +0800, Michael Clark wrote:
> The code reads a 64bit detect flag from the ns chip - so I guess it
> must be bogus with some motherboards. Mine is okay. Ben??

Actually, it's 64 bit addressing that it detects. I'll change the
message to reflect this.

> Okay, so i'll move the register_netdev call earlier on in the
> initialisation and add any necessary unregister call for failures.

Thanks for the patch -- I've now just got to add subsystem id support to
catch an odd 83820 on a motherboard setup that has different polarity for
the duplex + speed inputs. Why do hardware vendors have to be different?

-ben