* [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621)
@ 2001-12-04 15:35 Michael Clark
2001-12-04 21:24 ` Rob Myers
0 siblings, 1 reply; 9+ messages in thread
From: Michael Clark @ 2001-12-04 15:35 UTC (permalink / raw)
To: LKML; +Cc: Benjamin LaHaise
[-- Attachment #1: Type: text/plain, Size: 587 bytes --]
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
[-- Attachment #2: ns83820-optical.patch --]
[-- Type: text/plain, Size: 6431 bytes --]
--- 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 <michael@metaparadigm.com>
*
* 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);
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-04 15:35 [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) Michael Clark @ 2001-12-04 21:24 ` Rob Myers 2001-12-04 21:31 ` Jeff Garzik 2001-12-05 1:48 ` Michael Clark 0 siblings, 2 replies; 9+ messages in thread From: Rob Myers @ 2001-12-04 21:24 UTC (permalink / raw) To: Michael Clark; +Cc: LKML, Benjamin LaHaise 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 <michael@metaparadigm.com> > * > * 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); ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-04 21:24 ` Rob Myers @ 2001-12-04 21:31 ` Jeff Garzik 2001-12-05 1:48 ` Michael Clark 1 sibling, 0 replies; 9+ messages in thread From: Jeff Garzik @ 2001-12-04 21:31 UTC (permalink / raw) To: Rob Myers; +Cc: Michael Clark, LKML, Benjamin LaHaise 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-04 21:24 ` Rob Myers 2001-12-04 21:31 ` Jeff Garzik @ 2001-12-05 1:48 ` Michael Clark 2001-12-05 5:02 ` Michael Clark ` (2 more replies) 1 sibling, 3 replies; 9+ messages in thread From: Michael Clark @ 2001-12-05 1:48 UTC (permalink / raw) To: Rob Myers; +Cc: LKML, Benjamin LaHaise 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. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-05 1:48 ` Michael Clark @ 2001-12-05 5:02 ` Michael Clark 2001-12-05 12:55 ` Jeff Garzik 2001-12-05 22:50 ` Benjamin LaHaise 2 siblings, 0 replies; 9+ messages in thread From: Michael Clark @ 2001-12-05 5:02 UTC (permalink / raw) To: Rob Myers, LKML; +Cc: Benjamin LaHaise [-- Attachment #1: Type: text/plain, Size: 917 bytes --] Michael Clark wrote: > Rob Myers wrote: > >> 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. This patch resolves the duplicate link message and calls register_netdev earlier (with another unregister added for correct handling of error conditions). Here's the output on my machine: eth0: disabling 64 bit PCI. eth0: enabling optical transceiver eth0: ns83820.c v0.13b: DP83820 00:40:f4:29:5c:ba pciaddr=0xfb102000 irq=26 rev 0x103 eth0: link now 1000F mbps, full duplex and up. I've also cleaned up the new register defines to be consistent with Benjamin's. This patch also updates Configure.help adding the GA621 to the list of supported boards ~mc [-- Attachment #2: ns83820-optical-0.13b.patch --] [-- Type: text/plain, Size: 9409 bytes --] --- 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 <bcrl@redhat.com> * * $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 <michael@metaparadigm.com> + * 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-05 1:48 ` Michael Clark 2001-12-05 5:02 ` Michael Clark @ 2001-12-05 12:55 ` Jeff Garzik 2001-12-05 14:37 ` Michael Clark 2001-12-05 22:50 ` Benjamin LaHaise 2 siblings, 1 reply; 9+ messages in thread From: Jeff Garzik @ 2001-12-05 12:55 UTC (permalink / raw) To: Michael Clark; +Cc: Rob Myers, LKML, Benjamin LaHaise 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-05 12:55 ` Jeff Garzik @ 2001-12-05 14:37 ` Michael Clark 2001-12-05 16:56 ` Rob Myers 0 siblings, 1 reply; 9+ messages in thread From: Michael Clark @ 2001-12-05 14:37 UTC (permalink / raw) To: Jeff Garzik; +Cc: Rob Myers, LKML, Benjamin LaHaise [-- Attachment #1: Type: text/plain, Size: 1247 bytes --] Jeff Garzik wrote: > Michael Clark wrote: > >>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. Okay, I didn't really need to move the register_netdev call back so early in the initialization function. In fact there are no failure conditions after the first printk so i've moved it to just before this so there are now no failure conditions after the register_netdev. > 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]. Problem solved. New patch attached. ~mc [-- Attachment #2: ns83820-optical-0.13c.patch --] [-- Type: text/plain, Size: 9086 bytes --] --- 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 <bcrl@redhat.com> * * $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 <michael@metaparadigm.com> + * 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-05 14:37 ` Michael Clark @ 2001-12-05 16:56 ` Rob Myers 0 siblings, 0 replies; 9+ messages in thread From: Rob Myers @ 2001-12-05 16:56 UTC (permalink / raw) To: Michael Clark; +Cc: Jeff Garzik, LKML, Benjamin LaHaise 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. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) 2001-12-05 1:48 ` Michael Clark 2001-12-05 5:02 ` Michael Clark 2001-12-05 12:55 ` Jeff Garzik @ 2001-12-05 22:50 ` Benjamin LaHaise 2 siblings, 0 replies; 9+ messages in thread From: Benjamin LaHaise @ 2001-12-05 22:50 UTC (permalink / raw) To: Michael Clark; +Cc: Rob Myers, LKML 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2001-12-05 22:50 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2001-12-04 15:35 [PATCH] - 2.4.16 ns83820 optical support (Netgear GA621) Michael Clark 2001-12-04 21:24 ` Rob Myers 2001-12-04 21:31 ` Jeff Garzik 2001-12-05 1:48 ` Michael Clark 2001-12-05 5:02 ` Michael Clark 2001-12-05 12:55 ` Jeff Garzik 2001-12-05 14:37 ` Michael Clark 2001-12-05 16:56 ` Rob Myers 2001-12-05 22:50 ` Benjamin LaHaise
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox