mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
bitkeeper revision 1.39 (3e4d27e05zcnRwImrI-d9Wwi2axQLg)
network.c, dev.c, smp.h, e1000_osdep.h, Makefile: Minor cleanups to network code. .del-8139cp.c~52a760252927c3e8: Delete: xen-2.4.16/drivers/net/8139cp.c .del-eepro100.c~a29abf1c46dbaa08: Delete: xen-2.4.16/drivers/net/eepro100.c .del-pcnet32.c~7c61ad8be47473e4: Delete: xen-2.4.16/drivers/net/pcnet32.c .del-.depend~6dcd8dfbf6773eeb: Delete: xen-2.4.16/drivers/net/tulip/.depend .del-tulip_core.c~80117514fcabac13: Delete: xen-2.4.16/drivers/net/tulip/tulip_core.c .del-tulip.h~54606639dd5b212e: Delete: xen-2.4.16/drivers/net/tulip/tulip.h .del-timer.c~56eb96781641c48f: Delete: xen-2.4.16/drivers/net/tulip/timer.c .del-pnic2.c~cc9e8fae127ab7c4: Delete: xen-2.4.16/drivers/net/tulip/pnic2.c .del-pnic.c~4e4579265b47c3b6: Delete: xen-2.4.16/drivers/net/tulip/pnic.c .del-media.c~5b3d5b7b7749ae09: Delete: xen-2.4.16/drivers/net/tulip/media.c .del-interrupt.c~3a02cdd4ea7dfca7: Delete: xen-2.4.16/drivers/net/tulip/interrupt.c .del-eeprom.c~5662bb4a831735: Delete: xen-2.4.16/drivers/net/tulip/eeprom.c .del-Makefile~67195a81ff533a91: Delete: xen-2.4.16/drivers/net/tulip/Makefile .del-ChangeLog~48ee537632ad6a0: Delete: xen-2.4.16/drivers/net/tulip/ChangeLog .del-21142.c~b87c3c8b27ab44ba: Delete: xen-2.4.16/drivers/net/tulip/21142.c
This commit is contained in:
1 parent
f834467529
commit
9a224b7822
21 files changed
+33
-10807
No files matched your search
@@ -88,7 +88,6 @@
|
||||
3ddb79bdPyAvT_WZTAFhaX0jp-yXSw xen-2.4.16/drivers/ide/ide_modes.h
|
||||
3e4a8d401aSwOzCScQXR3lsmNlAwUQ xen-2.4.16/drivers/ide/piix.c
|
||||
3ddb79bfMlOcWUwjtg6oMYhGySHDDw xen-2.4.16/drivers/net/3c59x.c
|
||||
3ddb79bfl_DWxZQFKiJ2BXrSedV4lg xen-2.4.16/drivers/net/8139cp.c
|
||||
3ddb79c0tWiE8xIFHszxipeVCGKTSA xen-2.4.16/drivers/net/Makefile
|
||||
3ddb79bfU-H1Hms4BuJEPPydjXUEaQ xen-2.4.16/drivers/net/Space.c
|
||||
3e4540ccS4bfbx9rLiLElP0F1OVwZA xen-2.4.16/drivers/net/e1000/LICENSE
|
||||
@@ -100,28 +99,14 @@
|
||||
3e4540ccvQ9Dtoh9tV-L3ULUwN9X7g xen-2.4.16/drivers/net/e1000/e1000_main.c
|
||||
3e4540cc3t7_y-YLeyMG2pX9xtdXPA xen-2.4.16/drivers/net/e1000/e1000_osdep.h
|
||||
3e4540cct_8Ig-Y1W_vM2gS_u7mC0A xen-2.4.16/drivers/net/e1000/e1000_param.c
|
||||
3ddb79c0GejJrp1U6W4G6dYi-RiH4A xen-2.4.16/drivers/net/eepro100.c
|
||||
3e465c00t2nochqR27eEY_FBjxsUCw xen-2.4.16/drivers/net/ne/8390.c
|
||||
3e465c00AIRmk20x1vYETtnL71eGvA xen-2.4.16/drivers/net/ne/8390.h
|
||||
3e465c00UIvPTAtAcgcQWCVFa2bwww xen-2.4.16/drivers/net/ne/Makefile
|
||||
3e465c00rWSHiXmHuOWLRf7r2n8S3g xen-2.4.16/drivers/net/ne/ne.c
|
||||
3ddb79bfKvn9mt0kofpkw0QaWjxO6A xen-2.4.16/drivers/net/net_init.c
|
||||
3ddb79c0fQgORkFlqWZdP-6cDHyFIQ xen-2.4.16/drivers/net/pcnet32.c
|
||||
3ddb79bf_CBcu3QWYwq4bNAOnM2RqQ xen-2.4.16/drivers/net/setup.c
|
||||
3e45a0c6u66EL2AI36eLOmf_abXs7g xen-2.4.16/drivers/net/tg3.c
|
||||
3e45a0c6yrXj5pmQT0PvVSJ01YLABQ xen-2.4.16/drivers/net/tg3.h
|
||||
3ddb79bfh8ucmq_HqRSaURalpeAmPg xen-2.4.16/drivers/net/tulip/.depend
|
||||
3ddb79bfsJ-hdQ17EXTFiUOHisjNgQ xen-2.4.16/drivers/net/tulip/21142.c
|
||||
3ddb79bf0lzTL-ywAdOO7vctTYAmJA xen-2.4.16/drivers/net/tulip/ChangeLog
|
||||
3ddb79bfRbGBTu5mznHtxpFPtnQYSQ xen-2.4.16/drivers/net/tulip/Makefile
|
||||
3ddb79bfLLamkCaJZDJ7i6qrCUhwBw xen-2.4.16/drivers/net/tulip/eeprom.c
|
||||
3ddb79bf-zt39-zIUgWC9Kb4As--Ew xen-2.4.16/drivers/net/tulip/interrupt.c
|
||||
3ddb79bfdr1I4DtFnXCzpaHkEkHE2Q xen-2.4.16/drivers/net/tulip/media.c
|
||||
3ddb79bftPnJDLCAo0Do4KPr5raERA xen-2.4.16/drivers/net/tulip/pnic.c
|
||||
3ddb79bf5lr4NIjy1oZOM_jhpxGidw xen-2.4.16/drivers/net/tulip/pnic2.c
|
||||
3ddb79bfBhawkz-2DT9lakMPbqzljQ xen-2.4.16/drivers/net/tulip/timer.c
|
||||
3ddb79bf7yw7hGBMM60aMgMgxY_G2g xen-2.4.16/drivers/net/tulip/tulip.h
|
||||
3ddb79bfhUr3baP8Lf4oZjhBX7i5kw xen-2.4.16/drivers/net/tulip/tulip_core.c
|
||||
3ddb79beUWngyIhMHgyPtuTem4o4JA xen-2.4.16/drivers/pci/Makefile
|
||||
3ddb79beU9td0Mnm0VUMklerBa37qQ xen-2.4.16/drivers/pci/compat.c
|
||||
3ddb79beHkGQE58z5t5gyUCYiwOxvw xen-2.4.16/drivers/pci/gen-devlist.c
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -3,13 +3,11 @@ include $(BASEDIR)/Rules.mk
|
||||
|
||||
default: $(OBJS)
|
||||
$(MAKE) -C ne
|
||||
$(MAKE) -C tulip
|
||||
$(MAKE) -C e1000
|
||||
$(LD) -r -o driver.o e1000/e1000.o $(OBJS) tulip/tulip.o ne/ne_drv.o
|
||||
$(LD) -r -o driver.o e1000/e1000.o $(OBJS) ne/ne_drv.o
|
||||
|
||||
clean:
|
||||
$(MAKE) -C ne clean
|
||||
$(MAKE) -C tulip clean
|
||||
rm -f *.o *~ core
|
||||
|
||||
.PHONY: default clean
|
||||
@@ -69,7 +69,6 @@ typedef enum {
|
||||
TRUE = 1
|
||||
} boolean_t;
|
||||
|
||||
#define ASSERT(x) if(!(x)) BUG()
|
||||
#define MSGOUT(S, A, B) printk(KERN_DEBUG S "\n", A, B)
|
||||
|
||||
//#define DBG 1
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,58 +0,0 @@
|
||||
21142.o: 21142.c \
|
||||
tulip.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h
|
||||
eeprom.o: eeprom.c \
|
||||
tulip.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/init.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/unaligned.h
|
||||
interrupt.o: interrupt.c \
|
||||
tulip.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/etherdevice.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/net/hw/flowcontrol.h)
|
||||
media.o: media.c \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/kernel.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/mii.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/init.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h \
|
||||
tulip.h
|
||||
pnic2.o: pnic2.c \
|
||||
tulip.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h
|
||||
pnic.o: pnic.c \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/kernel.h \
|
||||
tulip.h
|
||||
timer.o: timer.c \
|
||||
tulip.h
|
||||
tulip_core.o: tulip_core.c \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/module.h \
|
||||
tulip.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/pci.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/init.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/etherdevice.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/mii.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/ethtool.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/unaligned.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/uaccess.h \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/net/hw/flowcontrol.h) \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/tulip/mwi.h) \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/ddb5476.h) \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/ddb5477.h) \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/pm.h)
|
||||
tulip.h: \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/kernel.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/types.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/spinlock.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/netdevice.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/timer.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/linux/delay.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/io.h \
|
||||
/home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/asm/irq.h \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/tulip/mmio.h) \
|
||||
$(wildcard /home/kaf24/xeno/build/linux-2.4.16-kdb-orig/include/config/net/hw/flowcontrol.h)
|
||||
@touch tulip.h
|
||||
.PRECIOUS: tulip.h \
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/21142.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
#include "tulip.h"
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
|
||||
u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
|
||||
static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
|
||||
|
||||
|
||||
/* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
|
||||
of available transceivers. */
|
||||
void t21142_timer(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int csr12 = inl(ioaddr + CSR12);
|
||||
int next_tick = 60*HZ;
|
||||
int new_csr6 = 0;
|
||||
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_INFO"%s: 21143 negotiation status %8.8x, %s.\n",
|
||||
dev->name, csr12, medianame[dev->if_port]);
|
||||
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
|
||||
tulip_check_duplex(dev);
|
||||
next_tick = 60*HZ;
|
||||
} else if (tp->nwayset) {
|
||||
/* Don't screw up a negotiated session! */
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: Using NWay-set %s media, csr12 %8.8x.\n",
|
||||
dev->name, medianame[dev->if_port], csr12);
|
||||
} else if (tp->medialock) {
|
||||
;
|
||||
} else if (dev->if_port == 3) {
|
||||
if (csr12 & 2) { /* No 100mbps link beat, revert to 10mbps. */
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: No 21143 100baseTx link beat, %8.8x, "
|
||||
"trying NWay.\n", dev->name, csr12);
|
||||
t21142_start_nway(dev);
|
||||
next_tick = 3*HZ;
|
||||
}
|
||||
} else if ((csr12 & 0x7000) != 0x5000) {
|
||||
/* Negotiation failed. Search media types. */
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: 21143 negotiation failed, status %8.8x.\n",
|
||||
dev->name, csr12);
|
||||
if (!(csr12 & 4)) { /* 10mbps link beat good. */
|
||||
new_csr6 = 0x82420000;
|
||||
dev->if_port = 0;
|
||||
outl(0, ioaddr + CSR13);
|
||||
outl(0x0003FFFF, ioaddr + CSR14);
|
||||
outw(t21142_csr15[dev->if_port], ioaddr + CSR15);
|
||||
outl(t21142_csr13[dev->if_port], ioaddr + CSR13);
|
||||
} else {
|
||||
/* Select 100mbps port to check for link beat. */
|
||||
new_csr6 = 0x83860000;
|
||||
dev->if_port = 3;
|
||||
outl(0, ioaddr + CSR13);
|
||||
outl(0x0003FF7F, ioaddr + CSR14);
|
||||
outw(8, ioaddr + CSR15);
|
||||
outl(1, ioaddr + CSR13);
|
||||
}
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: Testing new 21143 media %s.\n",
|
||||
dev->name, medianame[dev->if_port]);
|
||||
if (new_csr6 != (tp->csr6 & ~0x00D5)) {
|
||||
tp->csr6 &= 0x00D5;
|
||||
tp->csr6 |= new_csr6;
|
||||
outl(0x0301, ioaddr + CSR12);
|
||||
tulip_restart_rxtx(tp);
|
||||
}
|
||||
next_tick = 3*HZ;
|
||||
}
|
||||
|
||||
/* mod_timer synchronizes us with potential add_timer calls
|
||||
* from interrupts.
|
||||
*/
|
||||
mod_timer(&tp->timer, RUN_AT(next_tick));
|
||||
}
|
||||
|
||||
|
||||
void t21142_start_nway(struct net_device *dev)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int csr14 = ((tp->sym_advertise & 0x0780) << 9) |
|
||||
((tp->sym_advertise & 0x0020) << 1) | 0xffbf;
|
||||
|
||||
dev->if_port = 0;
|
||||
tp->nway = tp->mediasense = 1;
|
||||
tp->nwayset = tp->lpar = 0;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%8.8x.\n",
|
||||
dev->name, csr14);
|
||||
outl(0x0001, ioaddr + CSR13);
|
||||
udelay(100);
|
||||
outl(csr14, ioaddr + CSR14);
|
||||
tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0);
|
||||
outl(tp->csr6, ioaddr + CSR6);
|
||||
if (tp->mtable && tp->mtable->csr15dir) {
|
||||
outl(tp->mtable->csr15dir, ioaddr + CSR15);
|
||||
outl(tp->mtable->csr15val, ioaddr + CSR15);
|
||||
} else
|
||||
outw(0x0008, ioaddr + CSR15);
|
||||
outl(0x1301, ioaddr + CSR12); /* Trigger NWAY. */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void t21142_lnk_change(struct net_device *dev, int csr5)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int csr12 = inl(ioaddr + CSR12);
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: 21143 link status interrupt %8.8x, CSR5 %x, "
|
||||
"%8.8x.\n", dev->name, csr12, csr5, inl(ioaddr + CSR14));
|
||||
|
||||
/* If NWay finished and we have a negotiated partner capability. */
|
||||
if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) {
|
||||
int setup_done = 0;
|
||||
int negotiated = tp->sym_advertise & (csr12 >> 16);
|
||||
tp->lpar = csr12 >> 16;
|
||||
tp->nwayset = 1;
|
||||
if (negotiated & 0x0100) dev->if_port = 5;
|
||||
else if (negotiated & 0x0080) dev->if_port = 3;
|
||||
else if (negotiated & 0x0040) dev->if_port = 4;
|
||||
else if (negotiated & 0x0020) dev->if_port = 0;
|
||||
else {
|
||||
tp->nwayset = 0;
|
||||
if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180))
|
||||
dev->if_port = 3;
|
||||
}
|
||||
tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0;
|
||||
|
||||
if (tulip_debug > 1) {
|
||||
if (tp->nwayset)
|
||||
printk(KERN_INFO "%s: Switching to %s based on link "
|
||||
"negotiation %4.4x & %4.4x = %4.4x.\n",
|
||||
dev->name, medianame[dev->if_port], tp->sym_advertise,
|
||||
tp->lpar, negotiated);
|
||||
else
|
||||
printk(KERN_INFO "%s: Autonegotiation failed, using %s,"
|
||||
" link beat status %4.4x.\n",
|
||||
dev->name, medianame[dev->if_port], csr12);
|
||||
}
|
||||
|
||||
if (tp->mtable) {
|
||||
int i;
|
||||
for (i = 0; i < tp->mtable->leafcount; i++)
|
||||
if (tp->mtable->mleaf[i].media == dev->if_port) {
|
||||
tp->cur_index = i;
|
||||
tulip_select_media(dev, 1);
|
||||
setup_done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! setup_done) {
|
||||
tp->csr6 = (dev->if_port & 1 ? 0x838E0000 : 0x82420000) | (tp->csr6 & 0x20ff);
|
||||
if (tp->full_duplex)
|
||||
tp->csr6 |= 0x0200;
|
||||
outl(1, ioaddr + CSR13);
|
||||
}
|
||||
#if 0 /* Restart shouldn't be needed. */
|
||||
outl(tp->csr6 | RxOn, ioaddr + CSR6);
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Restarting Tx and Rx, CSR5 is %8.8x.\n",
|
||||
dev->name, inl(ioaddr + CSR5));
|
||||
#endif
|
||||
tulip_start_rxtx(tp);
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Setting CSR6 %8.8x/%x CSR12 %8.8x.\n",
|
||||
dev->name, tp->csr6, inl(ioaddr + CSR6),
|
||||
inl(ioaddr + CSR12));
|
||||
} else if ((tp->nwayset && (csr5 & 0x08000000)
|
||||
&& (dev->if_port == 3 || dev->if_port == 5)
|
||||
&& (csr12 & 2) == 2) ||
|
||||
(tp->nway && (csr5 & (TPLnkFail)))) {
|
||||
/* Link blew? Maybe restart NWay. */
|
||||
del_timer_sync(&tp->timer);
|
||||
t21142_start_nway(dev);
|
||||
tp->timer.expires = RUN_AT(3*HZ);
|
||||
add_timer(&tp->timer);
|
||||
} else if (dev->if_port == 3 || dev->if_port == 5) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: 21143 %s link beat %s.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
(csr12 & 2) ? "failed" : "good");
|
||||
if ((csr12 & 2) && ! tp->medialock) {
|
||||
del_timer_sync(&tp->timer);
|
||||
t21142_start_nway(dev);
|
||||
tp->timer.expires = RUN_AT(3*HZ);
|
||||
add_timer(&tp->timer);
|
||||
} else if (dev->if_port == 5)
|
||||
outl(inl(ioaddr + CSR14) & ~0x080, ioaddr + CSR14);
|
||||
} else if (dev->if_port == 0 || dev->if_port == 4) {
|
||||
if ((csr12 & 4) == 0)
|
||||
printk(KERN_INFO"%s: 21143 10baseT link beat good.\n",
|
||||
dev->name);
|
||||
} else if (!(csr12 & 4)) { /* 10mbps link beat good. */
|
||||
if (tulip_debug)
|
||||
printk(KERN_INFO"%s: 21143 10mbps sensed media.\n",
|
||||
dev->name);
|
||||
dev->if_port = 0;
|
||||
} else if (tp->nwayset) {
|
||||
if (tulip_debug)
|
||||
printk(KERN_INFO"%s: 21143 using NWay-set %s, csr6 %8.8x.\n",
|
||||
dev->name, medianame[dev->if_port], tp->csr6);
|
||||
} else { /* 100mbps link beat good. */
|
||||
if (tulip_debug)
|
||||
printk(KERN_INFO"%s: 21143 100baseTx sensed media.\n",
|
||||
dev->name);
|
||||
dev->if_port = 3;
|
||||
tp->csr6 = 0x838E0000 | (tp->csr6 & 0x20ff);
|
||||
outl(0x0003FF7F, ioaddr + CSR14);
|
||||
outl(0x0301, ioaddr + CSR12);
|
||||
tulip_restart_rxtx(tp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,520 +0,0 @@
|
||||
2001-11-13 David S. Miller <davem@redhat.com>
|
||||
|
||||
* tulip_core.c (tulip_mwi_config): Kill unused label early_out.
|
||||
|
||||
2001-11-06 Richard Mortimer <richm@oldelvet.netscapeonline.co.uk>
|
||||
|
||||
* tulip_core.c: Correct set of values to mask out of csr0,
|
||||
for DM9102A chips. Limit burst/alignment of DM9102A chips
|
||||
on Sparcs.
|
||||
|
||||
2001-11-06 Jun Sun <jsun@mvista.com>
|
||||
|
||||
* tulip_core.c: Support finding MAC address on
|
||||
two MIPS boards, DDB5476 and DDB5477.
|
||||
|
||||
2001-11-06 Kevin B. Hendricks <khendricks@ivey.uwo.ca>
|
||||
|
||||
* Makefile, tulip.h, tulip_core.c, pnic2.c, 21142.c:
|
||||
Fixes for PNIC II support.
|
||||
|
||||
2001-11-06 David S. Miller <davem@redhat.com>
|
||||
|
||||
* tulip_core.c: Support reading MAC address from
|
||||
Sparc OBP property local-mac-address.
|
||||
|
||||
2001-07-17 Erik A. Hendriks <hendriks@lanl.gov>
|
||||
|
||||
* 21142.c: Merge fix from tulip.c 0.92w which prevents the
|
||||
overwriting of csr6 bits we want to preserve.
|
||||
|
||||
2001-07-10 Jeff Golds <jgolds@resilience.com>
|
||||
|
||||
* tulip_core.c: Fix two comments
|
||||
|
||||
2001-07-06 Stephen Degler <sdegler@degler.net>
|
||||
|
||||
* media.c:
|
||||
The media selection process at the end of NWAY is busted
|
||||
because for the case of MII/SYM it needs to be:
|
||||
|
||||
csr13 <- 0
|
||||
csr14 <- 0
|
||||
csr6 <- the value calculated is okay.
|
||||
|
||||
In the other media cases csr14 is computed by
|
||||
t21142_csr14val[dev->if_port], which seems ok. The value of
|
||||
zero as opposed to 3FFFFF comes straight from appendix D of the
|
||||
21143 data book, and it makes logical sense because you're
|
||||
bypassing all the SIA interface when you usa MII or SYM (see
|
||||
figure 1-1 in the data book if your're visually oriented)
|
||||
|
||||
2001-07-03 Jeff Golds <jgolds@resilience.com>
|
||||
|
||||
* tulip_core.c (tulip_clean_tx_ring):
|
||||
Clear status for in-progress Tx's, and count
|
||||
Tx errors for all packets being released.
|
||||
|
||||
2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip.h, tulip_core.c:
|
||||
Integrate MMIO support from devel branch, but default
|
||||
it to off for stable kernel and driver series.
|
||||
|
||||
2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_init_one):
|
||||
Free descriptor rings on error.
|
||||
|
||||
2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_mwi_config, tulip_init_one):
|
||||
Large update to csr0 bus configuration code. This is not stable
|
||||
yet, so it is only conditionally enabled, via CONFIG_TULIP_MWI.
|
||||
|
||||
2001-06-16 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c:
|
||||
Initialize timer in tulip_init_one and tulip_down,
|
||||
not in tulip_up.
|
||||
|
||||
2001-06-14 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c:
|
||||
- Update tulip_suspend, tulip_resume for new PCI PM API.
|
||||
- Surround suspend/resume code with CONFIG_PM.
|
||||
|
||||
2001-06-12 Jeff Golds <jgolds@resilience.com>
|
||||
|
||||
* tulip_core.c:
|
||||
- Reset sw ring ptrs in tulip_up. Fixes PM resume case.
|
||||
- Clean rx and tx rings on device down.
|
||||
|
||||
2001-06-05 David Miller <davem@redhat.com>
|
||||
|
||||
* tulip_core (set_rx_mode): Do not use set_bit
|
||||
on an integer variable. Also fix endianness issue.
|
||||
|
||||
2001-06-04 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* interrupt.c:
|
||||
Simplify rx processing when CONFIG_NET_HW_FLOWCONTROL is
|
||||
active, and in the process fix a bug where flow control
|
||||
and low load caused rx not to be acknowledged properly.
|
||||
|
||||
2001-06-01 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip.h:
|
||||
- Remove tulip_outl_csr helper, redundant.
|
||||
- Add tulip_start_rxtx inline helper.
|
||||
- tulip_stop_rxtx helper: Add synchronization. Always use current
|
||||
csr6 value, instead of tp->csr6 value or value passed as arg.
|
||||
- tulip_restart_rxtx helper: Add synchronization. Always
|
||||
use tp->csr6 for desired mode, not value passed as arg.
|
||||
- New RxOn, TxOn, RxTx constants for csr6 modes.
|
||||
- Remove now-redundant constants csr6_st, csr6_sr.
|
||||
|
||||
* 21142.c, interrupt.c, media.c, pnic.c, tulip_core.c:
|
||||
Update for above rxtx helper changes.
|
||||
|
||||
* interrupt.c:
|
||||
- whitespace cleanup around #ifdef CONFIG_NET_HW_FLOWCONTROL,
|
||||
convert tabs to spaces.
|
||||
- Move tp->stats.rx_missed_errors update outside the ifdef.
|
||||
|
||||
2001-05-18 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Added ethtool support.
|
||||
ETHTOOL_GDRVINFO ioctl only, for now.
|
||||
|
||||
2001-05-14 Robert Olsson <Robert.Olsson@data.slu.se>
|
||||
|
||||
* Restored HW_FLOWCONTROL from Linux 2.1 series tulip (ANK)
|
||||
plus Jamal's NETIF_RX_* feedback control.
|
||||
|
||||
2001-05-14 Robert Olsson <Robert.Olsson@data.slu.se>
|
||||
|
||||
* Added support for 21143's Interrupt Mitigation.
|
||||
Jamal original instigator.
|
||||
|
||||
2001-05-14 Robert Olsson <Robert.Olsson@data.slu.se>
|
||||
|
||||
* tulip_refill_rx prototype added to tulip.h
|
||||
|
||||
2001-05-13 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Remove HAS_PCI_MWI flag from Comet, untested.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c, tulip.h: Remove Conexant PCI id, no chip
|
||||
docs are available to fix problems with support.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_init_one): Do not call
|
||||
unregister_netdev in error cleanup. Remnant of old
|
||||
usage of init_etherdev.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* media.c (tulip_find_mii): Simple write the updated BMCR
|
||||
twice, as it seems the best thing to do for both broken and
|
||||
sane chips.
|
||||
If the mii_advert value, as read from MII_ADVERTISE, is zero,
|
||||
then generate a value we should advertise from the capability
|
||||
bits in BMSR.
|
||||
Fill in tp->advertising for all cases.
|
||||
Just to be safe, clear all unwanted bits.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (private_ioctl): Fill in tp->advertising
|
||||
when advertising value is changed by the user.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Mark Comet chips as needed the updated MWI
|
||||
csr0 configuration.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* media.c, tulip_core.c: Move MII scan into
|
||||
from inlined inside tulip_init_one to new function
|
||||
tulip_find_mii in media.c.
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* media.c (tulip_check_duplex):
|
||||
Only restart Rx/Tx engines if they are active
|
||||
(and csr6 changes)
|
||||
|
||||
2001-05-12 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_mwi_config):
|
||||
Clamp values read from PCI cache line size register to
|
||||
values acceptable to tulip chip. Done for safety and
|
||||
-almost- certainly unneeded.
|
||||
|
||||
2001-05-11 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_init_one):
|
||||
Instead of unconditionally enabling autonegotiation, disable
|
||||
autonegotiation if not using the default port. Further,
|
||||
flip the nway bit immediately, and then update the
|
||||
speed/duplex in a separate MII transaction. We do this
|
||||
because some boards require that nway be disabled separately,
|
||||
before media selection is forced.
|
||||
|
||||
TODO: Investigate if we can simply write the same value
|
||||
to BMCR twice, to avoid setting unnecessarily changing
|
||||
phy settings.
|
||||
|
||||
2001-05-11 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip.h, tulip_core.c: If HAS_PCI_MWI is set for a
|
||||
given chip, adjust the csr0 values not according to
|
||||
provided values but according to system cache line size.
|
||||
Currently cache alignment is matched as closely to cache
|
||||
line size as possible. Currently programmable burst limit
|
||||
is set (ie. never unlimited), and always equal to cache
|
||||
alignment and system cache size. Currently MWI bit is set
|
||||
only if the MWI bit is present in the PCI command register.
|
||||
|
||||
2001-05-11 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* media.c (tulip_select_media):
|
||||
For media types 1 and 3, only use the provided eeprom
|
||||
advertising value if it is non-zero.
|
||||
(tulip_check_duplex):
|
||||
Do not exit ASAP if full_duplex_lock is set. This
|
||||
ensures that the csr6 value is written if an update
|
||||
is needed.
|
||||
|
||||
2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
Merge PNIC-II-specific stuff from Becker's tulip.c:
|
||||
|
||||
* tulip.h, 21142.c (pnic2_lnk_change): new function
|
||||
* tulip_core.c (tulip_init_one): use it
|
||||
|
||||
* tulip_core.c (tulip_tx_timeout): Add specific
|
||||
debugging for PNIC2.
|
||||
|
||||
2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_init_one): Print out
|
||||
tulip%d instead of PCI device number, for
|
||||
consistency.
|
||||
|
||||
2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* Merge changes from Becker's tulip.c:
|
||||
Fix bugs in ioctl.
|
||||
Fix several bugs by distinguishing between MII
|
||||
and SYM advertising values.
|
||||
Set CSR14 autonegotiation bit for media types 2 and 4,
|
||||
where the SIA CSR setup values are not provided.
|
||||
|
||||
2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* media.c (tulip_select_media): Only update MII
|
||||
advertising value if startup arg < 2.
|
||||
|
||||
* tulip.h: Do not enable CSR13/14/15 autoconfiguration
|
||||
for 21041.
|
||||
|
||||
* tulip_core.c:
|
||||
21041: add specific code for reset, and do not set CAC bit
|
||||
When resetting media, for media table type 11 media, pass
|
||||
value 2 as 'startup' arg to select_media, to avoid updating
|
||||
MII advertising value.
|
||||
|
||||
2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* pnic.c (pnic_check_duplex): remove
|
||||
pnic.c (pnic_lnk_change, pnic_timer): use
|
||||
tulip_check_duplex not pnic_check_duplex.
|
||||
|
||||
* media.c (tulip_check_duplex):
|
||||
Clean up to use symbolic names instead of numeric constants.
|
||||
Set TxThreshold mode as necessary as well as clearing it.
|
||||
Update csr6 if csr6 changes, not simply if duplex changes.
|
||||
|
||||
(found by Manfred Spraul)
|
||||
|
||||
2001-05-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* 21142.c, eeprom.c, tulip.h, tulip_core.c:
|
||||
Remove DPRINTK as another, better method of
|
||||
debug message printing is available.
|
||||
|
||||
2001-05-09 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* 21142.c (t21142_lnk_change): Pass arg startup==1
|
||||
to tulip_select_media, in order to force csr13 to be
|
||||
zeroed out prior to going to full duplex mode. Fixes
|
||||
autonegotiation on a quad-port Znyx card.
|
||||
(from Stephen Dengler)
|
||||
|
||||
2001-05-09 Russell King <rmk@arm.linux.org.uk>
|
||||
|
||||
* interrupt.c: Better PCI bus error reporting.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Now that dev->name is only available late
|
||||
in the probe, insert a hack to replace a not-evaluated
|
||||
"eth%d" string with an evaluated "tulip%d" string.
|
||||
Also, remove obvious comment and an indentation cleanup.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: If we are a module, always print out the
|
||||
version string. If we are built into the kernel, only print
|
||||
the version string if at least one tulip is detected.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
Merged from Becker's tulip.c 0.92t:
|
||||
|
||||
* tulip_core.c: Add support for Conexant LANfinity.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Only suspend/resume if the interface
|
||||
is up and running. Use alloc_etherdev and pci_request_regions.
|
||||
Spelling fix.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Remove code that existed when one or more of
|
||||
the following defines existed. These defines were never used
|
||||
by normal users in practice: TULIP_FULL_DUPLEX,
|
||||
TULIP_DEFAULT_MEDIA, and TULIP_NO_MEDIA_SWITCH.
|
||||
|
||||
* tulip.h, eeprom.c: Move EE_* constants from tulip.h to eeprom.c.
|
||||
* tulip.h, media.c: Move MDIO_* constants from tulip.h to media.c.
|
||||
|
||||
* media.c: Add barrier() to mdio_read/write's PNIC status check
|
||||
loops.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
Merged from Becker's tulip.c 0.92t:
|
||||
|
||||
* tulip.h: Add MEDIA_MASK constant for bounding medianame[]
|
||||
array lookups.
|
||||
* eeprom.c, media.c, timer.c, tulip_core.c: Use it.
|
||||
|
||||
* media.c, tulip_core.c: mdio_{read,write} cleanup. Since this
|
||||
is called [pretty much] directly from ioctl, we mask
|
||||
read/write arguments to limit the values passed.
|
||||
Added mii_lock. Added comet_miireg2offset and better
|
||||
Comet-specific mdio_read/write code. Pay closer attention
|
||||
to the bits we set in ioctl. Remove spinlocks from ioctl,
|
||||
they are in mdio_read/write now. Use mask to limit
|
||||
phy number in tulip_init_one's MII scan.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
Merged from Becker's tulip.c 0.92t:
|
||||
|
||||
* 21142.c, tulip_core.c: PNIC2 MAC address and NWay fixes.
|
||||
* tulip.h: Add FullDuplex constant, used in above change.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* timer.c: Do not call netif_carrier_{on,off}, it is not used in
|
||||
the main tree. Leave code in, disabled, as markers for future
|
||||
carrier notification.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
Merged from Becker's tulip.c 0.92t, except for the tulip.h
|
||||
whitespace cleanup:
|
||||
|
||||
* interrupt.c: If Rx stops, make sure to update the
|
||||
multicast filter before restarting.
|
||||
* tulip.h: Add COMET_MAC_ADDR feature flag, clean up flags.
|
||||
Add Accept* Rx mode bit constants.
|
||||
Add mc_filter[] to driver private struct.
|
||||
* tulip_core.c: Add new Comet PCI id 0x1113:0x9511.
|
||||
Add COMET_MAC_ADDR feature flag to comet entry in board info array.
|
||||
Prefer to test COMET_MAC_ADDR flag to testing chip_id for COMET,
|
||||
when dealing with the Comet's MAC address.
|
||||
Enable Tx underrun recovery for Comet chips.
|
||||
Use new Accept* constants in set_rx_mode.
|
||||
Prefer COMET_MAC_ADDR flag test to chip_id test in set_rx_mode.
|
||||
Store built mc_filter for later use in intr handler by Comets.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: Use tp->cur_tx when building the
|
||||
setup frame, instead of assuming that the setup
|
||||
frame is always built in slot zero. This case is
|
||||
hit during PM resume.
|
||||
|
||||
2001-04-03 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* *.c: Update file headers (copyright, urls, etc.)
|
||||
* Makefile: re-order to that chip-specific modules on own line
|
||||
* eeprom.c: BSS/zero-init cleanup (Andrey Panin)
|
||||
* tulip_core.c: merge medianame[] update from tulip.c.
|
||||
Additional arch-specific rx_copybreak, csr0 values. (various)
|
||||
|
||||
2001-02-20 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* media.c (tulip_select_media): No need to initialize
|
||||
new_csr6, all cases initialize it properly.
|
||||
|
||||
2001-02-18 Manfred Spraul <manfred@colorfullife.com>
|
||||
|
||||
* interrupt.c (tulip_refill_rx): Make public.
|
||||
If PNIC chip stops due to lack of Rx buffers, restart it.
|
||||
(tulip_interrupt): PNIC doesn't have a h/w timer, emulate
|
||||
with software timers.
|
||||
* pnic.c (pnic_check_duplex): New function, PNIC-specific
|
||||
version of tulip_check_duplex.
|
||||
(pnic_lnk_change): Call pnic_check_duplex. If we use an
|
||||
external MII, then we mustn't use the internal negotiation.
|
||||
(pnic_timer): Support Rx refilling on work overflow in
|
||||
interrupt handler, as PNIC doesn't support a h/w timer.
|
||||
* tulip_core.c (tulip_tbl[]): Modify default csr6
|
||||
|
||||
2001-02-11 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_init_one): Call pci_enable_device
|
||||
to ensure wakeup/resource assignment before checking those
|
||||
values.
|
||||
(tulip_init_one): Replace PCI ids with constants from pci_id.h.
|
||||
(tulip_suspend, tulip_resume, tulip_remove_one): Call
|
||||
pci_power_on/off (commented out for now).
|
||||
|
||||
2001-02-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip.h: Add CFDD_xxx bits for Tulip power management
|
||||
* tulip_core.c (tulip_set_power_state): New function,
|
||||
manipulating Tulip chip power state where supported.
|
||||
(tulip_up, tulip_down, tulip_init_one): Use it.
|
||||
|
||||
2001-02-10 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_tx_timeout): Call netif_wake_queue
|
||||
to ensure the next Tx is always sent to us.
|
||||
|
||||
2001-01-27 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (tulip_remove_one): Fix mem leak by freeing
|
||||
tp->media_tbl. Add check for !dev, reformat code appropriately.
|
||||
|
||||
2001-01-27 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_tbl[]: Comment all entries to make order and chip_id
|
||||
relationship more clear.
|
||||
* tulip_pci_tbl[]: Add new Accton PCI id (COMET chipset).
|
||||
|
||||
2001-01-16 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: static vars no longer explicitly
|
||||
initialized to zero.
|
||||
* eeprom.c (tulip_read_eeprom): Make sure to delay between
|
||||
EE_ENB and EE_ENB|EE_SHIFT_CLK. Merged from becker tulip.c.
|
||||
|
||||
2001-01-05 Peter De Schrijver <p2@mind.be>
|
||||
|
||||
* eeprom.c (tulip_parse_eeprom): Interpret a bit more of 21142
|
||||
extended format type 3 info blocks in a tulip SROM.
|
||||
|
||||
2001-01-03 Matti Aarnio <matti.aarnio@zmailer.org>
|
||||
|
||||
* media.c (tulip_select_media): Support media types 5 and 6
|
||||
|
||||
2001-??-?? ??
|
||||
|
||||
* tulip_core.c: Add comment about LanMedia needing
|
||||
a different driver.
|
||||
Enable workarounds for early PCI chipsets.
|
||||
Add IA64 csr0 support, update HPPA csr0 support.
|
||||
|
||||
2000-12-17 Alan Cox <alan@redhat.com>
|
||||
|
||||
* eeprom.c, timer.c, tulip.h, tulip_core.c: Merge support
|
||||
for the Davicom's quirks into the main tulip.
|
||||
Patch by Tobias Ringstrom
|
||||
|
||||
2000-11-08 Jim Studt <jim@federated.com>
|
||||
|
||||
* eeprom.c (tulip_parse_eeprom): Check array bounds for
|
||||
medianame[] and block_name[] arrays to avoid oops due
|
||||
to bad values returned from hardware.
|
||||
|
||||
2000-11-02 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c (set_rx_mode): This is synchronized via
|
||||
dev->xmit_lock, so only the queueing of the setup frame needs to
|
||||
be locked, against tulip_interrupt.
|
||||
|
||||
2000-11-02 Alexey Kuznetov <kuznet@ms2.inr.ac.ru>
|
||||
|
||||
* timer.c (tulip_timer): Call netif_carrier_{on,off} to report
|
||||
link state to the rest of the kernel, and userspace.
|
||||
* interrupt.c (tulip_interrupt): Remove tx_full.
|
||||
* tulip.h: Likewise.
|
||||
* tulip_core.c (tulip_init_ring, tulip_start_xmit, set_rx_mode):
|
||||
Likewise.
|
||||
|
||||
2000-10-18 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* tulip_core.c: (tulip_init_one) Print out ethernet interface
|
||||
on error. Print out a message when pci_enable_device fails.
|
||||
Handle DMA alloc failure.
|
||||
|
||||
2000-10-18 Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
|
||||
* Makefile: New file.
|
||||
* tulip_core.c (tulip_init_one): Correct error messages
|
||||
on PIO/MMIO region reserve failure.
|
||||
(tulip_init_one) Add new check to ensure that PIO region is
|
||||
sufficient for our needs.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
include $(BASEDIR)/Rules.mk
|
||||
|
||||
default: $(OBJS)
|
||||
$(LD) -r -o tulip.o $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ core
|
||||
@@ -1,320 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/eeprom.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
#include "tulip.h"
|
||||
#include <linux/init.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
|
||||
|
||||
/* Serial EEPROM section. */
|
||||
/* The main routine to parse the very complicated SROM structure.
|
||||
Search www.digital.com for "21X4 SROM" to get details.
|
||||
This code is very complex, and will require changes to support
|
||||
additional cards, so I'll be verbose about what is going on.
|
||||
*/
|
||||
|
||||
/* Known cards that have old-style EEPROMs. */
|
||||
static struct eeprom_fixup eeprom_fixups[] __devinitdata = {
|
||||
{"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
|
||||
0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
|
||||
{"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
|
||||
0x0000, 0x009E, /* 10baseT */
|
||||
0x0004, 0x009E, /* 10baseT-FD */
|
||||
0x0903, 0x006D, /* 100baseTx */
|
||||
0x0905, 0x006D, /* 100baseTx-FD */ }},
|
||||
{"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
|
||||
0x0107, 0x8021, /* 100baseFx */
|
||||
0x0108, 0x8021, /* 100baseFx-FD */
|
||||
0x0100, 0x009E, /* 10baseT */
|
||||
0x0104, 0x009E, /* 10baseT-FD */
|
||||
0x0103, 0x006D, /* 100baseTx */
|
||||
0x0105, 0x006D, /* 100baseTx-FD */ }},
|
||||
{"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
|
||||
0x1001, 0x009E, /* 10base2, CSR12 0x10*/
|
||||
0x0000, 0x009E, /* 10baseT */
|
||||
0x0004, 0x009E, /* 10baseT-FD */
|
||||
0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
|
||||
0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
|
||||
{"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
|
||||
0x1B01, 0x0000, /* 10base2, CSR12 0x1B */
|
||||
0x0B00, 0x009E, /* 10baseT, CSR12 0x0B */
|
||||
0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
|
||||
0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
|
||||
0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
|
||||
}},
|
||||
{"NetWinder", 0x00, 0x10, 0x57,
|
||||
/* Default media = MII
|
||||
* MII block, reset sequence (3) = 0x0821 0x0000 0x0001, capabilities 0x01e1
|
||||
*/
|
||||
{ 0x1e00, 0x0000, 0x000b, 0x8f01, 0x0103, 0x0300, 0x0821, 0x000, 0x0001, 0x0000, 0x01e1 }
|
||||
},
|
||||
{0, 0, 0, 0, {}}};
|
||||
|
||||
|
||||
static const char *block_name[] __devinitdata = {
|
||||
"21140 non-MII",
|
||||
"21140 MII PHY",
|
||||
"21142 Serial PHY",
|
||||
"21142 MII PHY",
|
||||
"21143 SYM PHY",
|
||||
"21143 reset method"
|
||||
};
|
||||
|
||||
|
||||
void __devinit tulip_parse_eeprom(struct net_device *dev)
|
||||
{
|
||||
/* The last media info list parsed, for multiport boards. */
|
||||
static struct mediatable *last_mediatable;
|
||||
static unsigned char *last_ee_data;
|
||||
static int controller_index;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
unsigned char *ee_data = tp->eeprom;
|
||||
int i;
|
||||
|
||||
tp->mtable = 0;
|
||||
/* Detect an old-style (SA only) EEPROM layout:
|
||||
memcmp(eedata, eedata+16, 8). */
|
||||
for (i = 0; i < 8; i ++)
|
||||
if (ee_data[i] != ee_data[16+i])
|
||||
break;
|
||||
if (i >= 8) {
|
||||
if (ee_data[0] == 0xff) {
|
||||
if (last_mediatable) {
|
||||
controller_index++;
|
||||
printk(KERN_INFO "%s: Controller %d of multiport board.\n",
|
||||
dev->name, controller_index);
|
||||
tp->mtable = last_mediatable;
|
||||
ee_data = last_ee_data;
|
||||
goto subsequent_board;
|
||||
} else
|
||||
printk(KERN_INFO "%s: Missing EEPROM, this interface may "
|
||||
"not work correctly!\n",
|
||||
dev->name);
|
||||
return;
|
||||
}
|
||||
/* Do a fix-up based on the vendor half of the station address prefix. */
|
||||
for (i = 0; eeprom_fixups[i].name; i++) {
|
||||
if (dev->dev_addr[0] == eeprom_fixups[i].addr0
|
||||
&& dev->dev_addr[1] == eeprom_fixups[i].addr1
|
||||
&& dev->dev_addr[2] == eeprom_fixups[i].addr2) {
|
||||
if (dev->dev_addr[2] == 0xE8 && ee_data[0x1a] == 0x55)
|
||||
i++; /* An Accton EN1207, not an outlaw Maxtech. */
|
||||
memcpy(ee_data + 26, eeprom_fixups[i].newtable,
|
||||
sizeof(eeprom_fixups[i].newtable));
|
||||
printk(KERN_INFO "%s: Old format EEPROM on '%s' board. Using"
|
||||
" substitute media control info.\n",
|
||||
dev->name, eeprom_fixups[i].name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
|
||||
printk(KERN_INFO "%s: Old style EEPROM with no media selection "
|
||||
"information.\n",
|
||||
dev->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
controller_index = 0;
|
||||
if (ee_data[19] > 1) { /* Multiport board. */
|
||||
last_ee_data = ee_data;
|
||||
}
|
||||
subsequent_board:
|
||||
|
||||
if (ee_data[27] == 0) { /* No valid media table. */
|
||||
} else if (tp->chip_id == DC21041) {
|
||||
unsigned char *p = (void *)ee_data + ee_data[27 + controller_index*3];
|
||||
int media = get_u16(p);
|
||||
int count = p[2];
|
||||
p += 3;
|
||||
|
||||
printk(KERN_INFO "%s: 21041 Media table, default media %4.4x (%s).\n",
|
||||
dev->name, media,
|
||||
media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned char media_block = *p++;
|
||||
int media_code = media_block & MEDIA_MASK;
|
||||
if (media_block & 0x40)
|
||||
p += 6;
|
||||
printk(KERN_INFO "%s: 21041 media #%d, %s.\n",
|
||||
dev->name, media_code, medianame[media_code]);
|
||||
}
|
||||
} else {
|
||||
unsigned char *p = (void *)ee_data + ee_data[27];
|
||||
unsigned char csr12dir = 0;
|
||||
int count, new_advertise = 0;
|
||||
struct mediatable *mtable;
|
||||
u16 media = get_u16(p);
|
||||
|
||||
p += 2;
|
||||
if (tp->flags & CSR12_IN_SROM)
|
||||
csr12dir = *p++;
|
||||
count = *p++;
|
||||
|
||||
/* there is no phy information, don't even try to build mtable */
|
||||
if (count == 0) {
|
||||
if (tulip_debug > 0)
|
||||
printk(KERN_WARNING "%s: no phy info, aborting mtable build\n", dev->name);
|
||||
return;
|
||||
}
|
||||
|
||||
mtable = (struct mediatable *)
|
||||
kmalloc(sizeof(struct mediatable) + count*sizeof(struct medialeaf),
|
||||
GFP_KERNEL);
|
||||
if (mtable == NULL)
|
||||
return; /* Horrible, impossible failure. */
|
||||
last_mediatable = tp->mtable = mtable;
|
||||
mtable->defaultmedia = media;
|
||||
mtable->leafcount = count;
|
||||
mtable->csr12dir = csr12dir;
|
||||
mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
|
||||
mtable->csr15dir = mtable->csr15val = 0;
|
||||
|
||||
printk(KERN_INFO "%s: EEPROM default media type %s.\n", dev->name,
|
||||
media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
|
||||
for (i = 0; i < count; i++) {
|
||||
struct medialeaf *leaf = &mtable->mleaf[i];
|
||||
|
||||
if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
|
||||
leaf->type = 0;
|
||||
leaf->media = p[0] & 0x3f;
|
||||
leaf->leafdata = p;
|
||||
if ((p[2] & 0x61) == 0x01) /* Bogus, but Znyx boards do it. */
|
||||
mtable->has_mii = 1;
|
||||
p += 4;
|
||||
} else {
|
||||
leaf->type = p[1];
|
||||
if (p[1] == 0x05) {
|
||||
mtable->has_reset = i;
|
||||
leaf->media = p[2] & 0x0f;
|
||||
} else if (tp->chip_id == DM910X && p[1] == 0x80) {
|
||||
/* Hack to ignore Davicom delay period block */
|
||||
mtable->leafcount--;
|
||||
count--;
|
||||
i--;
|
||||
leaf->leafdata = p + 2;
|
||||
p += (p[0] & 0x3f) + 1;
|
||||
continue;
|
||||
} else if (p[1] & 1) {
|
||||
int gpr_len, reset_len;
|
||||
|
||||
mtable->has_mii = 1;
|
||||
leaf->media = 11;
|
||||
gpr_len=p[3]*2;
|
||||
reset_len=p[4+gpr_len]*2;
|
||||
new_advertise |= get_u16(&p[7+gpr_len+reset_len]);
|
||||
} else {
|
||||
mtable->has_nonmii = 1;
|
||||
leaf->media = p[2] & MEDIA_MASK;
|
||||
/* Davicom's media number for 100BaseTX is strange */
|
||||
if (tp->chip_id == DM910X && leaf->media == 1)
|
||||
leaf->media = 3;
|
||||
switch (leaf->media) {
|
||||
case 0: new_advertise |= 0x0020; break;
|
||||
case 4: new_advertise |= 0x0040; break;
|
||||
case 3: new_advertise |= 0x0080; break;
|
||||
case 5: new_advertise |= 0x0100; break;
|
||||
case 6: new_advertise |= 0x0200; break;
|
||||
}
|
||||
if (p[1] == 2 && leaf->media == 0) {
|
||||
if (p[2] & 0x40) {
|
||||
u32 base15 = get_unaligned((u16*)&p[7]);
|
||||
mtable->csr15dir =
|
||||
(get_unaligned((u16*)&p[9])<<16) + base15;
|
||||
mtable->csr15val =
|
||||
(get_unaligned((u16*)&p[11])<<16) + base15;
|
||||
} else {
|
||||
mtable->csr15dir = get_unaligned((u16*)&p[3])<<16;
|
||||
mtable->csr15val = get_unaligned((u16*)&p[5])<<16;
|
||||
}
|
||||
}
|
||||
}
|
||||
leaf->leafdata = p + 2;
|
||||
p += (p[0] & 0x3f) + 1;
|
||||
}
|
||||
if (tulip_debug > 1 && leaf->media == 11) {
|
||||
unsigned char *bp = leaf->leafdata;
|
||||
printk(KERN_INFO "%s: MII interface PHY %d, setup/reset "
|
||||
"sequences %d/%d long, capabilities %2.2x %2.2x.\n",
|
||||
dev->name, bp[0], bp[1], bp[2 + bp[1]*2],
|
||||
bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
|
||||
}
|
||||
printk(KERN_INFO "%s: Index #%d - Media %s (#%d) described "
|
||||
"by a %s (%d) block.\n",
|
||||
dev->name, i, medianame[leaf->media & 15], leaf->media,
|
||||
leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>",
|
||||
leaf->type);
|
||||
}
|
||||
if (new_advertise)
|
||||
tp->sym_advertise = new_advertise;
|
||||
}
|
||||
}
|
||||
/* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/
|
||||
|
||||
/* EEPROM_Ctrl bits. */
|
||||
#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
|
||||
#define EE_CS 0x01 /* EEPROM chip select. */
|
||||
#define EE_DATA_WRITE 0x04 /* Data from the Tulip to EEPROM. */
|
||||
#define EE_WRITE_0 0x01
|
||||
#define EE_WRITE_1 0x05
|
||||
#define EE_DATA_READ 0x08 /* Data from the EEPROM chip. */
|
||||
#define EE_ENB (0x4800 | EE_CS)
|
||||
|
||||
/* Delay between EEPROM clock transitions.
|
||||
Even at 33Mhz current PCI implementations don't overrun the EEPROM clock.
|
||||
We add a bus turn-around to insure that this remains true. */
|
||||
#define eeprom_delay() inl(ee_addr)
|
||||
|
||||
/* The EEPROM commands include the alway-set leading bit. */
|
||||
#define EE_READ_CMD (6)
|
||||
|
||||
/* Note: this routine returns extra data bits for size detection. */
|
||||
int __devinit tulip_read_eeprom(long ioaddr, int location, int addr_len)
|
||||
{
|
||||
int i;
|
||||
unsigned retval = 0;
|
||||
long ee_addr = ioaddr + CSR9;
|
||||
int read_cmd = location | (EE_READ_CMD << addr_len);
|
||||
|
||||
outl(EE_ENB & ~EE_CS, ee_addr);
|
||||
outl(EE_ENB, ee_addr);
|
||||
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 4 + addr_len; i >= 0; i--) {
|
||||
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
|
||||
outl(EE_ENB | dataval, ee_addr);
|
||||
eeprom_delay();
|
||||
outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
||||
eeprom_delay();
|
||||
retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
|
||||
}
|
||||
outl(EE_ENB, ee_addr);
|
||||
eeprom_delay();
|
||||
|
||||
for (i = 16; i > 0; i--) {
|
||||
outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
|
||||
eeprom_delay();
|
||||
retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
|
||||
outl(EE_ENB, ee_addr);
|
||||
eeprom_delay();
|
||||
}
|
||||
|
||||
/* Terminate the EEPROM access. */
|
||||
outl(EE_ENB & ~EE_CS, ee_addr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1,560 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/interrupt.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
#include "tulip.h"
|
||||
#include <linux/config.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
|
||||
int tulip_rx_copybreak;
|
||||
unsigned int tulip_max_interrupt_work;
|
||||
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
|
||||
#define MIT_SIZE 15
|
||||
unsigned int mit_table[MIT_SIZE+1] =
|
||||
{
|
||||
/* CRS11 21143 hardware Mitigation Control Interrupt
|
||||
We use only RX mitigation we other techniques for
|
||||
TX intr. mitigation.
|
||||
|
||||
31 Cycle Size (timer control)
|
||||
30:27 TX timer in 16 * Cycle size
|
||||
26:24 TX No pkts before Int.
|
||||
23:20 RX timer in Cycle size
|
||||
19:17 RX No pkts before Int.
|
||||
16 Continues Mode (CM)
|
||||
*/
|
||||
|
||||
0x0, /* IM disabled */
|
||||
0x80150000, /* RX time = 1, RX pkts = 2, CM = 1 */
|
||||
0x80150000,
|
||||
0x80270000,
|
||||
0x80370000,
|
||||
0x80490000,
|
||||
0x80590000,
|
||||
0x80690000,
|
||||
0x807B0000,
|
||||
0x808B0000,
|
||||
0x809D0000,
|
||||
0x80AD0000,
|
||||
0x80BD0000,
|
||||
0x80CF0000,
|
||||
0x80DF0000,
|
||||
// 0x80FF0000 /* RX time = 16, RX pkts = 7, CM = 1 */
|
||||
0x80F10000 /* RX time = 16, RX pkts = 0, CM = 1 */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
int tulip_refill_rx(struct net_device *dev)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
int entry;
|
||||
int refilled = 0;
|
||||
|
||||
/* Refill the Rx ring buffers. */
|
||||
for (; tp->cur_rx - tp->dirty_rx > 0; tp->dirty_rx++) {
|
||||
entry = tp->dirty_rx % RX_RING_SIZE;
|
||||
if (tp->rx_buffers[entry].skb == NULL) {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t mapping;
|
||||
|
||||
skb = tp->rx_buffers[entry].skb = dev_alloc_skb(PKT_BUF_SZ);
|
||||
if (skb == NULL)
|
||||
break;
|
||||
|
||||
mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
tp->rx_buffers[entry].mapping = mapping;
|
||||
|
||||
skb->dev = dev; /* Mark as being used by this device. */
|
||||
tp->rx_ring[entry].buffer1 = cpu_to_le32(mapping);
|
||||
refilled++;
|
||||
}
|
||||
tp->rx_ring[entry].status = cpu_to_le32(DescOwned);
|
||||
}
|
||||
if(tp->chip_id == LC82C168) {
|
||||
if(((inl(dev->base_addr + CSR5)>>17)&0x07) == 4) {
|
||||
/* Rx stopped due to out of buffers,
|
||||
* restart it
|
||||
*/
|
||||
outl(0x01, dev->base_addr + CSR2);
|
||||
}
|
||||
}
|
||||
return refilled;
|
||||
}
|
||||
|
||||
|
||||
static int tulip_rx(struct net_device *dev)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
int entry = tp->cur_rx % RX_RING_SIZE;
|
||||
int rx_work_limit = tp->dirty_rx + RX_RING_SIZE - tp->cur_rx;
|
||||
int received = 0;
|
||||
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
int drop = 0, mit_sel = 0;
|
||||
|
||||
/* that one buffer is needed for mit activation; or might be a
|
||||
bug in the ring buffer code; check later -- JHS*/
|
||||
|
||||
if (rx_work_limit >=RX_RING_SIZE) rx_work_limit--;
|
||||
#endif
|
||||
|
||||
if (tulip_debug > 4)
|
||||
printk(KERN_DEBUG " In tulip_rx(), entry %d %8.8x.\n", entry,
|
||||
tp->rx_ring[entry].status);
|
||||
/* If we own the next entry, it is a new packet. Send it up. */
|
||||
while ( ! (tp->rx_ring[entry].status & cpu_to_le32(DescOwned))) {
|
||||
s32 status = le32_to_cpu(tp->rx_ring[entry].status);
|
||||
|
||||
if (tulip_debug > 5)
|
||||
printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %8.8x.\n",
|
||||
dev->name, entry, status);
|
||||
if (--rx_work_limit < 0)
|
||||
break;
|
||||
if ((status & 0x38008300) != 0x0300) {
|
||||
if ((status & 0x38000300) != 0x0300) {
|
||||
/* Ingore earlier buffers. */
|
||||
if ((status & 0xffff) != 0x7fff) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_WARNING "%s: Oversized Ethernet frame "
|
||||
"spanned multiple buffers, status %8.8x!\n",
|
||||
dev->name, status);
|
||||
tp->stats.rx_length_errors++;
|
||||
}
|
||||
} else if (status & RxDescFatalErr) {
|
||||
/* There was a fatal error. */
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Receive error, Rx status %8.8x.\n",
|
||||
dev->name, status);
|
||||
tp->stats.rx_errors++; /* end of a packet.*/
|
||||
if (status & 0x0890) tp->stats.rx_length_errors++;
|
||||
if (status & 0x0004) tp->stats.rx_frame_errors++;
|
||||
if (status & 0x0002) tp->stats.rx_crc_errors++;
|
||||
if (status & 0x0001) tp->stats.rx_fifo_errors++;
|
||||
}
|
||||
} else {
|
||||
/* Omit the four octet CRC from the length. */
|
||||
short pkt_len = ((status >> 16) & 0x7ff) - 4;
|
||||
struct sk_buff *skb;
|
||||
|
||||
#ifndef final_version
|
||||
if (pkt_len > 1518) {
|
||||
printk(KERN_WARNING "%s: Bogus packet size of %d (%#x).\n",
|
||||
dev->name, pkt_len, pkt_len);
|
||||
pkt_len = 1518;
|
||||
tp->stats.rx_length_errors++;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
drop = atomic_read(&netdev_dropping);
|
||||
if (drop)
|
||||
goto throttle;
|
||||
#endif
|
||||
/* Check if the packet is long enough to accept without copying
|
||||
to a minimally-sized skbuff. */
|
||||
if (pkt_len < tulip_rx_copybreak
|
||||
&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
|
||||
//if (0) {
|
||||
skb->dev = dev;
|
||||
skb_reserve(skb, 2); /* 16 byte align the IP header */
|
||||
pci_dma_sync_single(tp->pdev,
|
||||
tp->rx_buffers[entry].mapping,
|
||||
pkt_len, PCI_DMA_FROMDEVICE);
|
||||
#if ! defined(__alpha__)
|
||||
eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail,
|
||||
pkt_len, 0);
|
||||
skb_put(skb, pkt_len);
|
||||
#else
|
||||
memcpy(skb_put(skb, pkt_len),
|
||||
tp->rx_buffers[entry].skb->tail,
|
||||
pkt_len);
|
||||
#endif
|
||||
} else { /* Pass up the skb already on the Rx ring. */
|
||||
char *temp = skb_put(skb = tp->rx_buffers[entry].skb,
|
||||
pkt_len);
|
||||
|
||||
#ifndef final_version
|
||||
if (tp->rx_buffers[entry].mapping !=
|
||||
le32_to_cpu(tp->rx_ring[entry].buffer1)) {
|
||||
printk(KERN_ERR "%s: Internal fault: The skbuff addresses "
|
||||
"do not match in tulip_rx: %08x vs. %08x %p / %p.\n",
|
||||
dev->name,
|
||||
le32_to_cpu(tp->rx_ring[entry].buffer1),
|
||||
tp->rx_buffers[entry].mapping,
|
||||
skb->head, temp);
|
||||
}
|
||||
#endif
|
||||
|
||||
pci_unmap_single(tp->pdev, tp->rx_buffers[entry].mapping,
|
||||
PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
|
||||
|
||||
tp->rx_buffers[entry].skb = NULL;
|
||||
tp->rx_buffers[entry].mapping = 0;
|
||||
}
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
mit_sel =
|
||||
#endif
|
||||
netif_rx(skb);
|
||||
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
switch (mit_sel) {
|
||||
case NET_RX_SUCCESS:
|
||||
case NET_RX_CN_LOW:
|
||||
case NET_RX_CN_MOD:
|
||||
break;
|
||||
|
||||
case NET_RX_CN_HIGH:
|
||||
rx_work_limit -= NET_RX_CN_HIGH; /* additional*/
|
||||
break;
|
||||
case NET_RX_DROP:
|
||||
rx_work_limit = -1;
|
||||
break;
|
||||
default:
|
||||
printk("unknown feedback return code %d\n", mit_sel);
|
||||
break;
|
||||
}
|
||||
|
||||
drop = atomic_read(&netdev_dropping);
|
||||
if (drop) {
|
||||
throttle:
|
||||
rx_work_limit = -1;
|
||||
mit_sel = NET_RX_DROP;
|
||||
|
||||
if (tp->fc_bit) {
|
||||
long ioaddr = dev->base_addr;
|
||||
|
||||
/* disable Rx & RxNoBuf ints. */
|
||||
outl(tulip_tbl[tp->chip_id].valid_intrs&RX_A_NBF_STOP, ioaddr + CSR7);
|
||||
set_bit(tp->fc_bit, &netdev_fc_xoff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
dev->last_rx = jiffies;
|
||||
tp->stats.rx_packets++;
|
||||
tp->stats.rx_bytes += pkt_len;
|
||||
}
|
||||
received++;
|
||||
entry = (++tp->cur_rx) % RX_RING_SIZE;
|
||||
}
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
|
||||
/* We use this simplistic scheme for IM. It's proven by
|
||||
real life installations. We can have IM enabled
|
||||
continuesly but this would cause unnecessary latency.
|
||||
Unfortunely we can't use all the NET_RX_* feedback here.
|
||||
This would turn on IM for devices that is not contributing
|
||||
to backlog congestion with unnecessary latency.
|
||||
|
||||
We monitor the the device RX-ring and have:
|
||||
|
||||
HW Interrupt Mitigation either ON or OFF.
|
||||
|
||||
ON: More then 1 pkt received (per intr.) OR we are dropping
|
||||
OFF: Only 1 pkt received
|
||||
|
||||
Note. We only use min and max (0, 15) settings from mit_table */
|
||||
|
||||
|
||||
if( tp->flags & HAS_INTR_MITIGATION) {
|
||||
if((received > 1 || mit_sel == NET_RX_DROP)
|
||||
&& tp->mit_sel != 15 ) {
|
||||
tp->mit_sel = 15;
|
||||
tp->mit_change = 1; /* Force IM change */
|
||||
}
|
||||
if((received <= 1 && mit_sel != NET_RX_DROP) && tp->mit_sel != 0 ) {
|
||||
tp->mit_sel = 0;
|
||||
tp->mit_change = 1; /* Force IM change */
|
||||
}
|
||||
}
|
||||
|
||||
return RX_RING_SIZE+1; /* maxrx+1 */
|
||||
#else
|
||||
return received;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* The interrupt handler does all of the Rx thread work and cleans up
|
||||
after the Tx thread. */
|
||||
void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_instance;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int csr5;
|
||||
int entry;
|
||||
int missed;
|
||||
int rx = 0;
|
||||
int tx = 0;
|
||||
int oi = 0;
|
||||
int maxrx = RX_RING_SIZE;
|
||||
int maxtx = TX_RING_SIZE;
|
||||
int maxoi = TX_RING_SIZE;
|
||||
unsigned int work_count = tulip_max_interrupt_work;
|
||||
|
||||
/* Let's see whether the interrupt really is for us */
|
||||
csr5 = inl(ioaddr + CSR5);
|
||||
|
||||
if ((csr5 & (NormalIntr|AbnormalIntr)) == 0)
|
||||
return;
|
||||
|
||||
tp->nir++;
|
||||
|
||||
do {
|
||||
/* Acknowledge all of the current interrupt sources ASAP. */
|
||||
outl(csr5 & 0x0001ffff, ioaddr + CSR5);
|
||||
|
||||
if (tulip_debug > 4)
|
||||
printk(KERN_DEBUG "%s: interrupt csr5=%#8.8x new csr5=%#8.8x.\n",
|
||||
dev->name, csr5, inl(dev->base_addr + CSR5));
|
||||
|
||||
if (csr5 & (RxIntr | RxNoBuf)) {
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
if ((!tp->fc_bit) ||
|
||||
(!test_bit(tp->fc_bit, &netdev_fc_xoff)))
|
||||
#endif
|
||||
rx += tulip_rx(dev);
|
||||
tulip_refill_rx(dev);
|
||||
}
|
||||
|
||||
if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
|
||||
unsigned int dirty_tx;
|
||||
|
||||
spin_lock(&tp->lock);
|
||||
|
||||
for (dirty_tx = tp->dirty_tx; tp->cur_tx - dirty_tx > 0;
|
||||
dirty_tx++) {
|
||||
int entry = dirty_tx % TX_RING_SIZE;
|
||||
int status = le32_to_cpu(tp->tx_ring[entry].status);
|
||||
|
||||
if (status < 0)
|
||||
break; /* It still has not been Txed */
|
||||
|
||||
/* Check for Rx filter setup frames. */
|
||||
if (tp->tx_buffers[entry].skb == NULL) {
|
||||
/* test because dummy frames not mapped */
|
||||
if (tp->tx_buffers[entry].mapping)
|
||||
pci_unmap_single(tp->pdev,
|
||||
tp->tx_buffers[entry].mapping,
|
||||
sizeof(tp->setup_frame),
|
||||
PCI_DMA_TODEVICE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (status & 0x8000) {
|
||||
/* There was an major error, log it. */
|
||||
#ifndef final_version
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
|
||||
dev->name, status);
|
||||
#endif
|
||||
tp->stats.tx_errors++;
|
||||
if (status & 0x4104) tp->stats.tx_aborted_errors++;
|
||||
if (status & 0x0C00) tp->stats.tx_carrier_errors++;
|
||||
if (status & 0x0200) tp->stats.tx_window_errors++;
|
||||
if (status & 0x0002) tp->stats.tx_fifo_errors++;
|
||||
if ((status & 0x0080) && tp->full_duplex == 0)
|
||||
tp->stats.tx_heartbeat_errors++;
|
||||
} else {
|
||||
tp->stats.tx_bytes +=
|
||||
tp->tx_buffers[entry].skb->len;
|
||||
tp->stats.collisions += (status >> 3) & 15;
|
||||
tp->stats.tx_packets++;
|
||||
}
|
||||
|
||||
pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping,
|
||||
tp->tx_buffers[entry].skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
||||
/* Free the original skb. */
|
||||
dev_kfree_skb_irq(tp->tx_buffers[entry].skb);
|
||||
tp->tx_buffers[entry].skb = NULL;
|
||||
tp->tx_buffers[entry].mapping = 0;
|
||||
tx++;
|
||||
}
|
||||
|
||||
#ifndef final_version
|
||||
if (tp->cur_tx - dirty_tx > TX_RING_SIZE) {
|
||||
printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d.\n",
|
||||
dev->name, dirty_tx, tp->cur_tx);
|
||||
dirty_tx += TX_RING_SIZE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tp->cur_tx - dirty_tx < TX_RING_SIZE - 2)
|
||||
netif_wake_queue(dev);
|
||||
|
||||
tp->dirty_tx = dirty_tx;
|
||||
if (csr5 & TxDied) {
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_WARNING "%s: The transmitter stopped."
|
||||
" CSR5 is %x, CSR6 %x, new CSR6 %x.\n",
|
||||
dev->name, csr5, inl(ioaddr + CSR6), tp->csr6);
|
||||
tulip_restart_rxtx(tp);
|
||||
}
|
||||
spin_unlock(&tp->lock);
|
||||
}
|
||||
|
||||
/* Log errors. */
|
||||
if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */
|
||||
if (csr5 == 0xffffffff)
|
||||
break;
|
||||
if (csr5 & TxJabber) tp->stats.tx_errors++;
|
||||
if (csr5 & TxFIFOUnderflow) {
|
||||
if ((tp->csr6 & 0xC000) != 0xC000)
|
||||
tp->csr6 += 0x4000; /* Bump up the Tx threshold */
|
||||
else
|
||||
tp->csr6 |= 0x00200000; /* Store-n-forward. */
|
||||
/* Restart the transmit process. */
|
||||
tulip_restart_rxtx(tp);
|
||||
outl(0, ioaddr + CSR1);
|
||||
}
|
||||
if (csr5 & (RxDied | RxNoBuf)) {
|
||||
if (tp->flags & COMET_MAC_ADDR) {
|
||||
outl(tp->mc_filter[0], ioaddr + 0xAC);
|
||||
outl(tp->mc_filter[1], ioaddr + 0xB0);
|
||||
}
|
||||
}
|
||||
if (csr5 & RxDied) { /* Missed a Rx frame. */
|
||||
tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
if (tp->fc_bit && !test_bit(tp->fc_bit, &netdev_fc_xoff)) {
|
||||
tp->stats.rx_errors++;
|
||||
tulip_start_rxtx(tp);
|
||||
}
|
||||
#else
|
||||
tp->stats.rx_errors++;
|
||||
tulip_start_rxtx(tp);
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* NB: t21142_lnk_change() does a del_timer_sync(), so be careful if this
|
||||
* call is ever done under the spinlock
|
||||
*/
|
||||
if (csr5 & (TPLnkPass | TPLnkFail | 0x08000000)) {
|
||||
if (tp->link_change)
|
||||
(tp->link_change)(dev, csr5);
|
||||
}
|
||||
if (csr5 & SytemError) {
|
||||
int error = (csr5 >> 23) & 7;
|
||||
/* oops, we hit a PCI error. The code produced corresponds
|
||||
* to the reason:
|
||||
* 0 - parity error
|
||||
* 1 - master abort
|
||||
* 2 - target abort
|
||||
* Note that on parity error, we should do a software reset
|
||||
* of the chip to get it back into a sane state (according
|
||||
* to the 21142/3 docs that is).
|
||||
* -- rmk
|
||||
*/
|
||||
printk(KERN_ERR "%s: (%lu) System Error occured (%d)\n",
|
||||
dev->name, tp->nir, error);
|
||||
}
|
||||
/* Clear all error sources, included undocumented ones! */
|
||||
outl(0x0800f7ba, ioaddr + CSR5);
|
||||
oi++;
|
||||
}
|
||||
if (csr5 & TimerInt) {
|
||||
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_ERR "%s: Re-enabling interrupts, %8.8x.\n",
|
||||
dev->name, csr5);
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
if (tp->fc_bit && (test_bit(tp->fc_bit, &netdev_fc_xoff)))
|
||||
if (net_ratelimit()) printk("BUG!! enabling interupt when FC off (timerintr.) \n");
|
||||
#endif
|
||||
outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
|
||||
tp->ttimer = 0;
|
||||
oi++;
|
||||
}
|
||||
if (tx > maxtx || rx > maxrx || oi > maxoi) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_WARNING "%s: Too much work during an interrupt, "
|
||||
"csr5=0x%8.8x. (%lu) (%d,%d,%d)\n", dev->name, csr5, tp->nir, tx, rx, oi);
|
||||
|
||||
/* Acknowledge all interrupt sources. */
|
||||
outl(0x8001ffff, ioaddr + CSR5);
|
||||
if (tp->flags & HAS_INTR_MITIGATION) {
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
if(tp->mit_change) {
|
||||
outl(mit_table[tp->mit_sel], ioaddr + CSR11);
|
||||
tp->mit_change = 0;
|
||||
}
|
||||
#else
|
||||
/* Josip Loncaric at ICASE did extensive experimentation
|
||||
to develop a good interrupt mitigation setting.*/
|
||||
outl(0x8b240000, ioaddr + CSR11);
|
||||
#endif
|
||||
} else if (tp->chip_id == LC82C168) {
|
||||
/* the LC82C168 doesn't have a hw timer.*/
|
||||
outl(0x00, ioaddr + CSR7);
|
||||
mod_timer(&tp->timer, RUN_AT(HZ/50));
|
||||
} else {
|
||||
/* Mask all interrupting sources, set timer to
|
||||
re-enable. */
|
||||
#ifndef CONFIG_NET_HW_FLOWCONTROL
|
||||
outl(((~csr5) & 0x0001ebef) | AbnormalIntr | TimerInt, ioaddr + CSR7);
|
||||
outl(0x0012, ioaddr + CSR11);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
work_count--;
|
||||
if (work_count == 0)
|
||||
break;
|
||||
|
||||
csr5 = inl(ioaddr + CSR5);
|
||||
} while ((csr5 & (NormalIntr|AbnormalIntr)) != 0);
|
||||
|
||||
tulip_refill_rx(dev);
|
||||
|
||||
/* check if the card is in suspend mode */
|
||||
entry = tp->dirty_rx % RX_RING_SIZE;
|
||||
if (tp->rx_buffers[entry].skb == NULL) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_WARNING "%s: in rx suspend mode: (%lu) (tp->cur_rx = %u, ttimer = %d, rx = %d) go/stay in suspend mode\n", dev->name, tp->nir, tp->cur_rx, tp->ttimer, rx);
|
||||
if (tp->chip_id == LC82C168) {
|
||||
outl(0x00, ioaddr + CSR7);
|
||||
mod_timer(&tp->timer, RUN_AT(HZ/50));
|
||||
} else {
|
||||
if (tp->ttimer == 0 || (inl(ioaddr + CSR11) & 0xffff) == 0) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_WARNING "%s: in rx suspend mode: (%lu) set timer\n", dev->name, tp->nir);
|
||||
outl(tulip_tbl[tp->chip_id].valid_intrs | TimerInt,
|
||||
ioaddr + CSR7);
|
||||
outl(TimerInt, ioaddr + CSR5);
|
||||
outl(12, ioaddr + CSR11);
|
||||
tp->ttimer = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((missed = inl(ioaddr + CSR8) & 0x1ffff)) {
|
||||
tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed;
|
||||
}
|
||||
|
||||
if (tulip_debug > 4)
|
||||
printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#4.4x.\n",
|
||||
dev->name, inl(ioaddr + CSR5));
|
||||
|
||||
}
|
||||
@@ -1,563 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/media.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
//#include <linux/kernel.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include "tulip.h"
|
||||
|
||||
|
||||
/* This is a mysterious value that can be written to CSR11 in the 21040 (only)
|
||||
to support a pre-NWay full-duplex signaling mechanism using short frames.
|
||||
No one knows what it should be, but if left at its default value some
|
||||
10base2(!) packets trigger a full-duplex-request interrupt. */
|
||||
#define FULL_DUPLEX_MAGIC 0x6969
|
||||
|
||||
/* The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
|
||||
met by back-to-back PCI I/O cycles, but we insert a delay to avoid
|
||||
"overclocking" issues or future 66Mhz PCI. */
|
||||
#define mdio_delay() inl(mdio_addr)
|
||||
|
||||
/* Read and write the MII registers using software-generated serial
|
||||
MDIO protocol. It is just different enough from the EEPROM protocol
|
||||
to not share code. The maxium data clock rate is 2.5 Mhz. */
|
||||
#define MDIO_SHIFT_CLK 0x10000
|
||||
#define MDIO_DATA_WRITE0 0x00000
|
||||
#define MDIO_DATA_WRITE1 0x20000
|
||||
#define MDIO_ENB 0x00000 /* Ignore the 0x02000 databook setting. */
|
||||
#define MDIO_ENB_IN 0x40000
|
||||
#define MDIO_DATA_READ 0x80000
|
||||
|
||||
static const unsigned char comet_miireg2offset[32] = {
|
||||
0xB4, 0xB8, 0xBC, 0xC0, 0xC4, 0xC8, 0xCC, 0, 0,0,0,0, 0,0,0,0,
|
||||
0,0xD0,0,0, 0,0,0,0, 0,0,0,0, 0, 0xD4, 0xD8, 0xDC, };
|
||||
|
||||
|
||||
/* MII transceiver control section.
|
||||
Read and write the MII registers using software-generated serial
|
||||
MDIO protocol. See the MII specifications or DP83840A data sheet
|
||||
for details. */
|
||||
|
||||
int tulip_mdio_read(struct net_device *dev, int phy_id, int location)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
int i;
|
||||
int read_cmd = (0xf6 << 10) | ((phy_id & 0x1f) << 5) | location;
|
||||
int retval = 0;
|
||||
long ioaddr = dev->base_addr;
|
||||
long mdio_addr = ioaddr + CSR9;
|
||||
unsigned long flags;
|
||||
|
||||
if (location & ~0x1f)
|
||||
return 0xffff;
|
||||
|
||||
if (tp->chip_id == COMET && phy_id == 30) {
|
||||
if (comet_miireg2offset[location])
|
||||
return inl(ioaddr + comet_miireg2offset[location]);
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&tp->mii_lock, flags);
|
||||
if (tp->chip_id == LC82C168) {
|
||||
int i = 1000;
|
||||
outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
|
||||
inl(ioaddr + 0xA0);
|
||||
inl(ioaddr + 0xA0);
|
||||
while (--i > 0) {
|
||||
barrier();
|
||||
if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&tp->mii_lock, flags);
|
||||
return retval & 0xffff;
|
||||
}
|
||||
|
||||
/* Establish sync by sending at least 32 logic ones. */
|
||||
for (i = 32; i >= 0; i--) {
|
||||
outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
|
||||
mdio_delay();
|
||||
outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
|
||||
mdio_delay();
|
||||
}
|
||||
/* Shift the read command bits out. */
|
||||
for (i = 15; i >= 0; i--) {
|
||||
int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
|
||||
|
||||
outl(MDIO_ENB | dataval, mdio_addr);
|
||||
mdio_delay();
|
||||
outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
|
||||
mdio_delay();
|
||||
}
|
||||
/* Read the two transition, 16 data, and wire-idle bits. */
|
||||
for (i = 19; i > 0; i--) {
|
||||
outl(MDIO_ENB_IN, mdio_addr);
|
||||
mdio_delay();
|
||||
retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
|
||||
outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
|
||||
mdio_delay();
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&tp->mii_lock, flags);
|
||||
return (retval>>1) & 0xffff;
|
||||
}
|
||||
|
||||
void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
int i;
|
||||
int cmd = (0x5002 << 16) | ((phy_id & 0x1f) << 23) | (location<<18) | (val & 0xffff);
|
||||
long ioaddr = dev->base_addr;
|
||||
long mdio_addr = ioaddr + CSR9;
|
||||
unsigned long flags;
|
||||
|
||||
if (location & ~0x1f)
|
||||
return;
|
||||
|
||||
if (tp->chip_id == COMET && phy_id == 30) {
|
||||
if (comet_miireg2offset[location])
|
||||
outl(val, ioaddr + comet_miireg2offset[location]);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&tp->mii_lock, flags);
|
||||
if (tp->chip_id == LC82C168) {
|
||||
int i = 1000;
|
||||
outl(cmd, ioaddr + 0xA0);
|
||||
do {
|
||||
barrier();
|
||||
if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
|
||||
break;
|
||||
} while (--i > 0);
|
||||
spin_unlock_irqrestore(&tp->mii_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Establish sync by sending 32 logic ones. */
|
||||
for (i = 32; i >= 0; i--) {
|
||||
outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
|
||||
mdio_delay();
|
||||
outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
|
||||
mdio_delay();
|
||||
}
|
||||
/* Shift the command bits out. */
|
||||
for (i = 31; i >= 0; i--) {
|
||||
int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
|
||||
outl(MDIO_ENB | dataval, mdio_addr);
|
||||
mdio_delay();
|
||||
outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
|
||||
mdio_delay();
|
||||
}
|
||||
/* Clear out extra bits. */
|
||||
for (i = 2; i > 0; i--) {
|
||||
outl(MDIO_ENB_IN, mdio_addr);
|
||||
mdio_delay();
|
||||
outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
|
||||
mdio_delay();
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&tp->mii_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
/* Set up the transceiver control registers for the selected media type. */
|
||||
void tulip_select_media(struct net_device *dev, int startup)
|
||||
{
|
||||
long ioaddr = dev->base_addr;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
struct mediatable *mtable = tp->mtable;
|
||||
u32 new_csr6;
|
||||
int i;
|
||||
|
||||
if (mtable) {
|
||||
struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
|
||||
unsigned char *p = mleaf->leafdata;
|
||||
switch (mleaf->type) {
|
||||
case 0: /* 21140 non-MII xcvr. */
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Using a 21140 non-MII transceiver"
|
||||
" with control setting %2.2x.\n",
|
||||
dev->name, p[1]);
|
||||
dev->if_port = p[0];
|
||||
if (startup)
|
||||
outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
|
||||
outl(p[1], ioaddr + CSR12);
|
||||
new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
|
||||
break;
|
||||
case 2: case 4: {
|
||||
u16 setup[5];
|
||||
u32 csr13val, csr14val, csr15dir, csr15val;
|
||||
for (i = 0; i < 5; i++)
|
||||
setup[i] = get_u16(&p[i*2 + 1]);
|
||||
|
||||
dev->if_port = p[0] & MEDIA_MASK;
|
||||
if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
|
||||
tp->full_duplex = 1;
|
||||
|
||||
if (startup && mtable->has_reset) {
|
||||
struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
|
||||
unsigned char *rst = rleaf->leafdata;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
|
||||
dev->name);
|
||||
for (i = 0; i < rst[0]; i++)
|
||||
outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
|
||||
}
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: 21143 non-MII %s transceiver control "
|
||||
"%4.4x/%4.4x.\n",
|
||||
dev->name, medianame[dev->if_port], setup[0], setup[1]);
|
||||
if (p[0] & 0x40) { /* SIA (CSR13-15) setup values are provided. */
|
||||
csr13val = setup[0];
|
||||
csr14val = setup[1];
|
||||
csr15dir = (setup[3]<<16) | setup[2];
|
||||
csr15val = (setup[4]<<16) | setup[2];
|
||||
outl(0, ioaddr + CSR13);
|
||||
outl(csr14val, ioaddr + CSR14);
|
||||
outl(csr15dir, ioaddr + CSR15); /* Direction */
|
||||
outl(csr15val, ioaddr + CSR15); /* Data */
|
||||
outl(csr13val, ioaddr + CSR13);
|
||||
} else {
|
||||
csr13val = 1;
|
||||
csr14val = 0;
|
||||
csr15dir = (setup[0]<<16) | 0x0008;
|
||||
csr15val = (setup[1]<<16) | 0x0008;
|
||||
if (dev->if_port <= 4)
|
||||
csr14val = t21142_csr14[dev->if_port];
|
||||
if (startup) {
|
||||
outl(0, ioaddr + CSR13);
|
||||
outl(csr14val, ioaddr + CSR14);
|
||||
}
|
||||
outl(csr15dir, ioaddr + CSR15); /* Direction */
|
||||
outl(csr15val, ioaddr + CSR15); /* Data */
|
||||
if (startup) outl(csr13val, ioaddr + CSR13);
|
||||
}
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Setting CSR15 to %8.8x/%8.8x.\n",
|
||||
dev->name, csr15dir, csr15val);
|
||||
if (mleaf->type == 4)
|
||||
new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
|
||||
else
|
||||
new_csr6 = 0x82420000;
|
||||
break;
|
||||
}
|
||||
case 1: case 3: {
|
||||
int phy_num = p[0];
|
||||
int init_length = p[1];
|
||||
u16 *misc_info, tmp_info;
|
||||
|
||||
dev->if_port = 11;
|
||||
new_csr6 = 0x020E0000;
|
||||
if (mleaf->type == 3) { /* 21142 */
|
||||
u16 *init_sequence = (u16*)(p+2);
|
||||
u16 *reset_sequence = &((u16*)(p+3))[init_length];
|
||||
int reset_length = p[2 + init_length*2];
|
||||
misc_info = reset_sequence + reset_length;
|
||||
if (startup)
|
||||
for (i = 0; i < reset_length; i++)
|
||||
outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
|
||||
for (i = 0; i < init_length; i++)
|
||||
outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
|
||||
} else {
|
||||
u8 *init_sequence = p + 2;
|
||||
u8 *reset_sequence = p + 3 + init_length;
|
||||
int reset_length = p[2 + init_length];
|
||||
misc_info = (u16*)(reset_sequence + reset_length);
|
||||
if (startup) {
|
||||
outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
|
||||
for (i = 0; i < reset_length; i++)
|
||||
outl(reset_sequence[i], ioaddr + CSR12);
|
||||
}
|
||||
for (i = 0; i < init_length; i++)
|
||||
outl(init_sequence[i], ioaddr + CSR12);
|
||||
}
|
||||
tmp_info = get_u16(&misc_info[1]);
|
||||
if (tmp_info)
|
||||
tp->advertising[phy_num] = tmp_info | 1;
|
||||
if (tmp_info && startup < 2) {
|
||||
if (tp->mii_advertise == 0)
|
||||
tp->mii_advertise = tp->advertising[phy_num];
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Advertising %4.4x on MII %d.\n",
|
||||
dev->name, tp->mii_advertise, tp->phys[phy_num]);
|
||||
tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5: case 6: {
|
||||
u16 setup[5];
|
||||
|
||||
new_csr6 = 0; /* FIXME */
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
setup[i] = get_u16(&p[i*2 + 1]);
|
||||
|
||||
if (startup && mtable->has_reset) {
|
||||
struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
|
||||
unsigned char *rst = rleaf->leafdata;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Resetting the transceiver.\n",
|
||||
dev->name);
|
||||
for (i = 0; i < rst[0]; i++)
|
||||
outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: Invalid media table selection %d.\n",
|
||||
dev->name, mleaf->type);
|
||||
new_csr6 = 0x020E0000;
|
||||
}
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %2.2x.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
inl(ioaddr + CSR12) & 0xff);
|
||||
} else if (tp->chip_id == DC21041) {
|
||||
int port = dev->if_port <= 4 ? dev->if_port : 0;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: 21041 using media %s, CSR12 is %4.4x.\n",
|
||||
dev->name, medianame[port == 3 ? 12: port],
|
||||
inl(ioaddr + CSR12));
|
||||
outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
|
||||
outl(t21041_csr14[port], ioaddr + CSR14);
|
||||
outl(t21041_csr15[port], ioaddr + CSR15);
|
||||
outl(t21041_csr13[port], ioaddr + CSR13);
|
||||
new_csr6 = 0x80020000;
|
||||
} else if (tp->chip_id == LC82C168) {
|
||||
if (startup && ! tp->medialock)
|
||||
dev->if_port = tp->mii_cnt ? 11 : 0;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: PNIC PHY status is %3.3x, media %s.\n",
|
||||
dev->name, inl(ioaddr + 0xB8), medianame[dev->if_port]);
|
||||
if (tp->mii_cnt) {
|
||||
new_csr6 = 0x810C0000;
|
||||
outl(0x0001, ioaddr + CSR15);
|
||||
outl(0x0201B07A, ioaddr + 0xB8);
|
||||
} else if (startup) {
|
||||
/* Start with 10mbps to do autonegotiation. */
|
||||
outl(0x32, ioaddr + CSR12);
|
||||
new_csr6 = 0x00420000;
|
||||
outl(0x0001B078, ioaddr + 0xB8);
|
||||
outl(0x0201B078, ioaddr + 0xB8);
|
||||
} else if (dev->if_port == 3 || dev->if_port == 5) {
|
||||
outl(0x33, ioaddr + CSR12);
|
||||
new_csr6 = 0x01860000;
|
||||
/* Trigger autonegotiation. */
|
||||
outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
|
||||
} else {
|
||||
outl(0x32, ioaddr + CSR12);
|
||||
new_csr6 = 0x00420000;
|
||||
outl(0x1F078, ioaddr + 0xB8);
|
||||
}
|
||||
} else if (tp->chip_id == DC21040) { /* 21040 */
|
||||
/* Turn on the xcvr interface. */
|
||||
int csr12 = inl(ioaddr + CSR12);
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: 21040 media type is %s, CSR12 is %2.2x.\n",
|
||||
dev->name, medianame[dev->if_port], csr12);
|
||||
if (tulip_media_cap[dev->if_port] & MediaAlwaysFD)
|
||||
tp->full_duplex = 1;
|
||||
new_csr6 = 0x20000;
|
||||
/* Set the full duplux match frame. */
|
||||
outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11);
|
||||
outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
|
||||
if (t21040_csr13[dev->if_port] & 8) {
|
||||
outl(0x0705, ioaddr + CSR14);
|
||||
outl(0x0006, ioaddr + CSR15);
|
||||
} else {
|
||||
outl(0xffff, ioaddr + CSR14);
|
||||
outl(0x0000, ioaddr + CSR15);
|
||||
}
|
||||
outl(0x8f01 | t21040_csr13[dev->if_port], ioaddr + CSR13);
|
||||
} else { /* Unknown chip type with no media table. */
|
||||
if (tp->default_port == 0)
|
||||
dev->if_port = tp->mii_cnt ? 11 : 3;
|
||||
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
|
||||
new_csr6 = 0x020E0000;
|
||||
} else if (tulip_media_cap[dev->if_port] & MediaIsFx) {
|
||||
new_csr6 = 0x028600000;
|
||||
} else
|
||||
new_csr6 = 0x038600000;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: No media description table, assuming "
|
||||
"%s transceiver, CSR12 %2.2x.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
inl(ioaddr + CSR12));
|
||||
}
|
||||
|
||||
tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Check the MII negotiated duplex and change the CSR6 setting if
|
||||
required.
|
||||
Return 0 if everything is OK.
|
||||
Return < 0 if the transceiver is missing or has no link beat.
|
||||
*/
|
||||
int tulip_check_duplex(struct net_device *dev)
|
||||
{
|
||||
struct tulip_private *tp = dev->priv;
|
||||
unsigned int bmsr, lpa, negotiated, new_csr6;
|
||||
|
||||
bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
|
||||
lpa = tulip_mdio_read(dev, tp->phys[0], MII_LPA);
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO "%s: MII status %4.4x, Link partner report "
|
||||
"%4.4x.\n", dev->name, bmsr, lpa);
|
||||
if (bmsr == 0xffff)
|
||||
return -2;
|
||||
if ((bmsr & BMSR_LSTATUS) == 0) {
|
||||
int new_bmsr = tulip_mdio_read(dev, tp->phys[0], MII_BMSR);
|
||||
if ((new_bmsr & BMSR_LSTATUS) == 0) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO "%s: No link beat on the MII interface,"
|
||||
" status %4.4x.\n", dev->name, new_bmsr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
negotiated = lpa & tp->advertising[0];
|
||||
tp->full_duplex = mii_duplex(tp->full_duplex_lock, negotiated);
|
||||
|
||||
new_csr6 = tp->csr6;
|
||||
|
||||
if (negotiated & LPA_100) new_csr6 &= ~TxThreshold;
|
||||
else new_csr6 |= TxThreshold;
|
||||
if (tp->full_duplex) new_csr6 |= FullDuplex;
|
||||
else new_csr6 &= ~FullDuplex;
|
||||
|
||||
if (new_csr6 != tp->csr6) {
|
||||
tp->csr6 = new_csr6;
|
||||
tulip_restart_rxtx(tp);
|
||||
|
||||
if (tulip_debug > 0)
|
||||
printk(KERN_INFO "%s: Setting %s-duplex based on MII"
|
||||
"#%d link partner capability of %4.4x.\n",
|
||||
dev->name, tp->full_duplex ? "full" : "half",
|
||||
tp->phys[0], lpa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __devinit tulip_find_mii (struct net_device *dev, int board_idx)
|
||||
{
|
||||
struct tulip_private *tp = dev->priv;
|
||||
int phyn, phy_idx = 0;
|
||||
int mii_reg0;
|
||||
int mii_advert;
|
||||
unsigned int to_advert, new_bmcr, ane_switch;
|
||||
|
||||
/* Find the connected MII xcvrs.
|
||||
Doing this in open() would allow detecting external xcvrs later,
|
||||
but takes much time. */
|
||||
for (phyn = 1; phyn <= 32 && phy_idx < sizeof (tp->phys); phyn++) {
|
||||
int phy = phyn & 0x1f;
|
||||
int mii_status = tulip_mdio_read (dev, phy, MII_BMSR);
|
||||
if ((mii_status & 0x8301) == 0x8001 ||
|
||||
((mii_status & BMSR_100BASE4) == 0
|
||||
&& (mii_status & 0x7800) != 0)) {
|
||||
/* preserve Becker logic, gain indentation level */
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
mii_reg0 = tulip_mdio_read (dev, phy, MII_BMCR);
|
||||
mii_advert = tulip_mdio_read (dev, phy, MII_ADVERTISE);
|
||||
ane_switch = 0;
|
||||
|
||||
/* if not advertising at all, gen an
|
||||
* advertising value from the capability
|
||||
* bits in BMSR
|
||||
*/
|
||||
if ((mii_advert & ADVERTISE_ALL) == 0) {
|
||||
unsigned int tmpadv = tulip_mdio_read (dev, phy, MII_BMSR);
|
||||
mii_advert = ((tmpadv >> 6) & 0x3e0) | 1;
|
||||
}
|
||||
|
||||
if (tp->mii_advertise) {
|
||||
tp->advertising[phy_idx] =
|
||||
to_advert = tp->mii_advertise;
|
||||
} else if (tp->advertising[phy_idx]) {
|
||||
to_advert = tp->advertising[phy_idx];
|
||||
} else {
|
||||
tp->advertising[phy_idx] =
|
||||
tp->mii_advertise =
|
||||
to_advert = mii_advert;
|
||||
}
|
||||
|
||||
tp->phys[phy_idx++] = phy;
|
||||
|
||||
printk (KERN_INFO "tulip%d: MII transceiver #%d "
|
||||
"config %4.4x status %4.4x advertising %4.4x.\n",
|
||||
board_idx, phy, mii_reg0, mii_status, mii_advert);
|
||||
|
||||
/* Fixup for DLink with miswired PHY. */
|
||||
if (mii_advert != to_advert) {
|
||||
printk (KERN_DEBUG "tulip%d: Advertising %4.4x on PHY %d,"
|
||||
" previously advertising %4.4x.\n",
|
||||
board_idx, to_advert, phy, mii_advert);
|
||||
tulip_mdio_write (dev, phy, 4, to_advert);
|
||||
}
|
||||
|
||||
/* Enable autonegotiation: some boards default to off. */
|
||||
if (tp->default_port == 0) {
|
||||
new_bmcr = mii_reg0 | BMCR_ANENABLE;
|
||||
if (new_bmcr != mii_reg0) {
|
||||
new_bmcr |= BMCR_ANRESTART;
|
||||
ane_switch = 1;
|
||||
}
|
||||
}
|
||||
/* ...or disable nway, if forcing media */
|
||||
else {
|
||||
new_bmcr = mii_reg0 & ~BMCR_ANENABLE;
|
||||
if (new_bmcr != mii_reg0)
|
||||
ane_switch = 1;
|
||||
}
|
||||
|
||||
/* clear out bits we never want at this point */
|
||||
new_bmcr &= ~(BMCR_CTST | BMCR_FULLDPLX | BMCR_ISOLATE |
|
||||
BMCR_PDOWN | BMCR_SPEED100 | BMCR_LOOPBACK |
|
||||
BMCR_RESET);
|
||||
|
||||
if (tp->full_duplex)
|
||||
new_bmcr |= BMCR_FULLDPLX;
|
||||
if (tulip_media_cap[tp->default_port] & MediaIs100)
|
||||
new_bmcr |= BMCR_SPEED100;
|
||||
|
||||
if (new_bmcr != mii_reg0) {
|
||||
/* some phys need the ANE switch to
|
||||
* happen before forced media settings
|
||||
* will "take." However, we write the
|
||||
* same value twice in order not to
|
||||
* confuse the sane phys.
|
||||
*/
|
||||
if (ane_switch) {
|
||||
tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr);
|
||||
udelay (10);
|
||||
}
|
||||
tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr);
|
||||
}
|
||||
}
|
||||
tp->mii_cnt = phy_idx;
|
||||
if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) {
|
||||
printk (KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n",
|
||||
board_idx);
|
||||
tp->phys[0] = 1;
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/pnic.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
//#include <linux/kernel.h>
|
||||
#include "tulip.h"
|
||||
|
||||
|
||||
void pnic_do_nway(struct net_device *dev)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
u32 phy_reg = inl(ioaddr + 0xB8);
|
||||
u32 new_csr6 = tp->csr6 & ~0x40C40200;
|
||||
|
||||
if (phy_reg & 0x78000000) { /* Ignore baseT4 */
|
||||
if (phy_reg & 0x20000000) dev->if_port = 5;
|
||||
else if (phy_reg & 0x40000000) dev->if_port = 3;
|
||||
else if (phy_reg & 0x10000000) dev->if_port = 4;
|
||||
else if (phy_reg & 0x08000000) dev->if_port = 0;
|
||||
tp->nwayset = 1;
|
||||
new_csr6 = (dev->if_port & 1) ? 0x01860000 : 0x00420000;
|
||||
outl(0x32 | (dev->if_port & 1), ioaddr + CSR12);
|
||||
if (dev->if_port & 1)
|
||||
outl(0x1F868, ioaddr + 0xB8);
|
||||
if (phy_reg & 0x30000000) {
|
||||
tp->full_duplex = 1;
|
||||
new_csr6 |= 0x00000200;
|
||||
}
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: PNIC autonegotiated status %8.8x, %s.\n",
|
||||
dev->name, phy_reg, medianame[dev->if_port]);
|
||||
if (tp->csr6 != new_csr6) {
|
||||
tp->csr6 = new_csr6;
|
||||
/* Restart Tx */
|
||||
tulip_restart_rxtx(tp);
|
||||
dev->trans_start = jiffies;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pnic_lnk_change(struct net_device *dev, int csr5)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int phy_reg = inl(ioaddr + 0xB8);
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: PNIC link changed state %8.8x, CSR5 %8.8x.\n",
|
||||
dev->name, phy_reg, csr5);
|
||||
if (inl(ioaddr + CSR5) & TPLnkFail) {
|
||||
outl((inl(ioaddr + CSR7) & ~TPLnkFail) | TPLnkPass, ioaddr + CSR7);
|
||||
/* If we use an external MII, then we mustn't use the
|
||||
* internal negotiation.
|
||||
*/
|
||||
if (tulip_media_cap[dev->if_port] & MediaIsMII)
|
||||
return;
|
||||
if (! tp->nwayset || jiffies - dev->trans_start > 1*HZ) {
|
||||
tp->csr6 = 0x00420000 | (tp->csr6 & 0x0000fdff);
|
||||
outl(tp->csr6, ioaddr + CSR6);
|
||||
outl(0x30, ioaddr + CSR12);
|
||||
outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
|
||||
dev->trans_start = jiffies;
|
||||
}
|
||||
} else if (inl(ioaddr + CSR5) & TPLnkPass) {
|
||||
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
|
||||
spin_lock(&tp->lock);
|
||||
tulip_check_duplex(dev);
|
||||
spin_unlock(&tp->lock);
|
||||
} else {
|
||||
pnic_do_nway(dev);
|
||||
}
|
||||
outl((inl(ioaddr + CSR7) & ~TPLnkPass) | TPLnkFail, ioaddr + CSR7);
|
||||
}
|
||||
}
|
||||
|
||||
void pnic_timer(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int next_tick = 60*HZ;
|
||||
|
||||
if(!inl(ioaddr + CSR7)) {
|
||||
/* the timer was called due to a work overflow
|
||||
* in the interrupt handler. Skip the connection
|
||||
* checks, the nic is definitively speaking with
|
||||
* his link partner.
|
||||
*/
|
||||
goto too_good_connection;
|
||||
}
|
||||
|
||||
if (tulip_media_cap[dev->if_port] & MediaIsMII) {
|
||||
spin_lock_irq(&tp->lock);
|
||||
if (tulip_check_duplex(dev) > 0)
|
||||
next_tick = 3*HZ;
|
||||
spin_unlock_irq(&tp->lock);
|
||||
} else {
|
||||
int csr12 = inl(ioaddr + CSR12);
|
||||
int new_csr6 = tp->csr6 & ~0x40C40200;
|
||||
int phy_reg = inl(ioaddr + 0xB8);
|
||||
int csr5 = inl(ioaddr + CSR5);
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: PNIC timer PHY status %8.8x, %s "
|
||||
"CSR5 %8.8x.\n",
|
||||
dev->name, phy_reg, medianame[dev->if_port], csr5);
|
||||
if (phy_reg & 0x04000000) { /* Remote link fault */
|
||||
outl(0x0201F078, ioaddr + 0xB8);
|
||||
next_tick = 1*HZ;
|
||||
tp->nwayset = 0;
|
||||
} else if (phy_reg & 0x78000000) { /* Ignore baseT4 */
|
||||
pnic_do_nway(dev);
|
||||
next_tick = 60*HZ;
|
||||
} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: %s link beat failed, CSR12 %4.4x, "
|
||||
"CSR5 %8.8x, PHY %3.3x.\n",
|
||||
dev->name, medianame[dev->if_port], csr12,
|
||||
inl(ioaddr + CSR5), inl(ioaddr + 0xB8));
|
||||
next_tick = 3*HZ;
|
||||
if (tp->medialock) {
|
||||
} else if (tp->nwayset && (dev->if_port & 1)) {
|
||||
next_tick = 1*HZ;
|
||||
} else if (dev->if_port == 0) {
|
||||
dev->if_port = 3;
|
||||
outl(0x33, ioaddr + CSR12);
|
||||
new_csr6 = 0x01860000;
|
||||
outl(0x1F868, ioaddr + 0xB8);
|
||||
} else {
|
||||
dev->if_port = 0;
|
||||
outl(0x32, ioaddr + CSR12);
|
||||
new_csr6 = 0x00420000;
|
||||
outl(0x1F078, ioaddr + 0xB8);
|
||||
}
|
||||
if (tp->csr6 != new_csr6) {
|
||||
tp->csr6 = new_csr6;
|
||||
/* Restart Tx */
|
||||
tulip_restart_rxtx(tp);
|
||||
dev->trans_start = jiffies;
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO "%s: Changing PNIC configuration to %s "
|
||||
"%s-duplex, CSR6 %8.8x.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
tp->full_duplex ? "full" : "half", new_csr6);
|
||||
}
|
||||
}
|
||||
}
|
||||
too_good_connection:
|
||||
mod_timer(&tp->timer, RUN_AT(next_tick));
|
||||
if(!inl(ioaddr + CSR7)) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO "%s: sw timer wakeup.\n", dev->name);
|
||||
disable_irq(dev->irq);
|
||||
tulip_refill_rx(dev);
|
||||
enable_irq(dev->irq);
|
||||
outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
|
||||
}
|
||||
}
|
||||
@@ -1,407 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/pnic2.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
Modified to hep support PNIC_II by Kevin B. Hendricks
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* Understanding the PNIC_II - everything is this file is based
|
||||
* on the PNIC_II_PDF datasheet which is sorely lacking in detail
|
||||
*
|
||||
* As I understand things, here are the registers and bits that
|
||||
* explain the masks and constants used in this file that are
|
||||
* either different from the 21142/3 or important for basic operation.
|
||||
*
|
||||
*
|
||||
* CSR 6 (mask = 0xfe3bd1fd of bits not to change)
|
||||
* -----
|
||||
* Bit 24 - SCR
|
||||
* Bit 23 - PCS
|
||||
* Bit 22 - TTM (Trasmit Threshold Mode)
|
||||
* Bit 18 - Port Select
|
||||
* Bit 13 - Start - 1, Stop - 0 Transmissions
|
||||
* Bit 11:10 - Loop Back Operation Mode
|
||||
* Bit 9 - Full Duplex mode (Advertise 10BaseT-FD is CSR14<7> is set)
|
||||
* Bit 1 - Start - 1, Stop - 0 Receive
|
||||
*
|
||||
*
|
||||
* CSR 14 (mask = 0xfff0ee39 of bits not to change)
|
||||
* ------
|
||||
* Bit 19 - PAUSE-Pause
|
||||
* Bit 18 - Advertise T4
|
||||
* Bit 17 - Advertise 100baseTx-FD
|
||||
* Bit 16 - Advertise 100baseTx-HD
|
||||
* Bit 12 - LTE - Link Test Enable
|
||||
* Bit 7 - ANE - Auto Negotiate Enable
|
||||
* Bit 6 - HDE - Advertise 10baseT-HD
|
||||
* Bit 2 - Reset to Power down - kept as 1 for normal operation
|
||||
* Bit 1 - Loop Back enable for 10baseT MCC
|
||||
*
|
||||
*
|
||||
* CSR 12
|
||||
* ------
|
||||
* Bit 25 - Partner can do T4
|
||||
* Bit 24 - Partner can do 100baseTx-FD
|
||||
* Bit 23 - Partner can do 100baseTx-HD
|
||||
* Bit 22 - Partner can do 10baseT-FD
|
||||
* Bit 21 - Partner can do 10baseT-HD
|
||||
* Bit 15 - LPN is 1 if all above bits are valid other wise 0
|
||||
* Bit 14:12 - autonegotiation state (write 001 to start autonegotiate)
|
||||
* Bit 3 - Autopolarity state
|
||||
* Bit 2 - LS10B - link state of 10baseT 0 - good, 1 - failed
|
||||
* Bit 1 - LS100B - link state of 100baseT 0 - good, 1- faild
|
||||
*
|
||||
*
|
||||
* Data Port Selection Info
|
||||
*-------------------------
|
||||
*
|
||||
* CSR14<7> CSR6<18> CSR6<22> CSR6<23> CSR6<24> MODE/PORT
|
||||
* 1 0 0 (X) 0 (X) 1 NWAY
|
||||
* 0 0 1 0 (X) 0 10baseT
|
||||
* 0 1 0 1 1 (X) 100baseT
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "tulip.h"
|
||||
#include <linux/pci.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
|
||||
void pnic2_timer(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int next_tick = 60*HZ;
|
||||
|
||||
if (tulip_debug > 3)
|
||||
printk(KERN_INFO"%s: PNIC2 negotiation status %8.8x.\n",
|
||||
dev->name,inl(ioaddr + CSR12));
|
||||
|
||||
if (next_tick) {
|
||||
mod_timer(&tp->timer, RUN_AT(next_tick));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pnic2_start_nway(struct net_device *dev)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int csr14;
|
||||
int csr12;
|
||||
|
||||
/* set up what to advertise during the negotiation */
|
||||
|
||||
/* load in csr14 and mask off bits not to touch
|
||||
* comment at top of file explains mask value
|
||||
*/
|
||||
csr14 = (inl(ioaddr + CSR14) & 0xfff0ee39);
|
||||
|
||||
/* bit 17 - advetise 100baseTx-FD */
|
||||
if (tp->sym_advertise & 0x0100) csr14 |= 0x00020000;
|
||||
|
||||
/* bit 16 - advertise 100baseTx-HD */
|
||||
if (tp->sym_advertise & 0x0080) csr14 |= 0x00010000;
|
||||
|
||||
/* bit 6 - advertise 10baseT-HD */
|
||||
if (tp->sym_advertise & 0x0020) csr14 |= 0x00000040;
|
||||
|
||||
/* Now set bit 12 Link Test Enable, Bit 7 Autonegotiation Enable
|
||||
* and bit 0 Don't PowerDown 10baseT
|
||||
*/
|
||||
csr14 |= 0x00001184;
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Restarting PNIC2 autonegotiation, "
|
||||
"csr14=%8.8x.\n", dev->name, csr14);
|
||||
|
||||
/* tell pnic2_lnk_change we are doing an nway negotiation */
|
||||
dev->if_port = 0;
|
||||
tp->nway = tp->mediasense = 1;
|
||||
tp->nwayset = tp->lpar = 0;
|
||||
|
||||
/* now we have to set up csr6 for NWAY state */
|
||||
|
||||
tp->csr6 = inl(ioaddr + CSR6);
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: On Entry to Nway, "
|
||||
"csr6=%8.8x.\n", dev->name, tp->csr6);
|
||||
|
||||
/* mask off any bits not to touch
|
||||
* comment at top of file explains mask value
|
||||
*/
|
||||
tp->csr6 = tp->csr6 & 0xfe3bd1fd;
|
||||
|
||||
/* don't forget that bit 9 is also used for advertising */
|
||||
/* advertise 10baseT-FD for the negotiation (bit 9) */
|
||||
if (tp->sym_advertise & 0x0040) tp->csr6 |= 0x00000200;
|
||||
|
||||
/* set bit 24 for nway negotiation mode ...
|
||||
* see Data Port Selection comment at top of file
|
||||
* and "Stop" - reset both Transmit (bit 13) and Receive (bit 1)
|
||||
*/
|
||||
tp->csr6 |= 0x01000000;
|
||||
outl(csr14, ioaddr + CSR14);
|
||||
outl(tp->csr6, ioaddr + CSR6);
|
||||
udelay(100);
|
||||
|
||||
/* all set up so now force the negotiation to begin */
|
||||
|
||||
/* read in current values and mask off all but the
|
||||
* Autonegotiation bits 14:12. Writing a 001 to those bits
|
||||
* should start the autonegotiation
|
||||
*/
|
||||
csr12 = (inl(ioaddr + CSR12) & 0xffff8fff);
|
||||
csr12 |= 0x1000;
|
||||
outl(csr12, ioaddr + CSR12);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pnic2_lnk_change(struct net_device *dev, int csr5)
|
||||
{
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int csr14;
|
||||
|
||||
/* read the staus register to find out what is up */
|
||||
int csr12 = inl(ioaddr + CSR12);
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: PNIC2 link status interrupt %8.8x, "
|
||||
" CSR5 %x, %8.8x.\n", dev->name, csr12,
|
||||
csr5, inl(ioaddr + CSR14));
|
||||
|
||||
/* If NWay finished and we have a negotiated partner capability.
|
||||
* check bits 14:12 for bit pattern 101 - all is good
|
||||
*/
|
||||
if (tp->nway && !tp->nwayset) {
|
||||
|
||||
/* we did an auto negotiation */
|
||||
|
||||
if ((csr12 & 0x7000) == 0x5000) {
|
||||
|
||||
/* negotiation ended successfully */
|
||||
|
||||
/* get the link partners reply and mask out all but
|
||||
* bits 24-21 which show the partners capabilites
|
||||
* and match those to what we advertised
|
||||
*
|
||||
* then begin to interpret the results of the negotiation.
|
||||
* Always go in this order : (we are ignoring T4 for now)
|
||||
* 100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD
|
||||
*/
|
||||
|
||||
int negotiated = ((csr12 >> 16) & 0x01E0) & tp->sym_advertise;
|
||||
tp->lpar = (csr12 >> 16);
|
||||
tp->nwayset = 1;
|
||||
|
||||
if (negotiated & 0x0100) dev->if_port = 5;
|
||||
else if (negotiated & 0x0080) dev->if_port = 3;
|
||||
else if (negotiated & 0x0040) dev->if_port = 4;
|
||||
else if (negotiated & 0x0020) dev->if_port = 0;
|
||||
else {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO "%s: funny autonegotiate result "
|
||||
"csr12 %8.8x advertising %4.4x\n",
|
||||
dev->name, csr12, tp->sym_advertise);
|
||||
tp->nwayset = 0;
|
||||
/* so check if 100baseTx link state is okay */
|
||||
if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180))
|
||||
dev->if_port = 3;
|
||||
}
|
||||
|
||||
/* now record the duplex that was negotiated */
|
||||
tp->full_duplex = 0;
|
||||
if ((dev->if_port == 4) || (dev->if_port == 5))
|
||||
tp->full_duplex = 1;
|
||||
|
||||
if (tulip_debug > 1) {
|
||||
if (tp->nwayset)
|
||||
printk(KERN_INFO "%s: Switching to %s based on link "
|
||||
"negotiation %4.4x & %4.4x = %4.4x.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
tp->sym_advertise, tp->lpar, negotiated);
|
||||
}
|
||||
|
||||
/* remember to turn off bit 7 - autonegotiate
|
||||
* enable so we can properly end nway mode and
|
||||
* set duplex (ie. use csr6<9> again)
|
||||
*/
|
||||
csr14 = (inl(ioaddr + CSR14) & 0xffffff7f);
|
||||
outl(csr14,ioaddr + CSR14);
|
||||
|
||||
|
||||
/* now set the data port and operating mode
|
||||
* (see the Data Port Selection comments at
|
||||
* the top of the file
|
||||
*/
|
||||
|
||||
/* get current csr6 and mask off bits not to touch */
|
||||
/* see comment at top of file */
|
||||
|
||||
tp->csr6 = (inl(ioaddr + CSR6) & 0xfe3bd1fd);
|
||||
|
||||
/* so if using if_port 3 or 5 then select the 100baseT
|
||||
* port else select the 10baseT port.
|
||||
* See the Data Port Selection table at the top
|
||||
* of the file which was taken from the PNIC_II.PDF
|
||||
* datasheet
|
||||
*/
|
||||
if (dev->if_port & 1) tp->csr6 |= 0x01840000;
|
||||
else tp->csr6 |= 0x00400000;
|
||||
|
||||
/* now set the full duplex bit appropriately */
|
||||
if (tp->full_duplex) tp->csr6 |= 0x00000200;
|
||||
|
||||
outl(1, ioaddr + CSR13);
|
||||
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Setting CSR6 %8.8x/%x CSR12 "
|
||||
"%8.8x.\n", dev->name, tp->csr6,
|
||||
inl(ioaddr + CSR6), inl(ioaddr + CSR12));
|
||||
|
||||
/* now the following actually writes out the
|
||||
* new csr6 values
|
||||
*/
|
||||
tulip_start_rxtx(tp);
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
printk(KERN_INFO "%s: Autonegotiation failed, "
|
||||
"using %s, link beat status %4.4x.\n",
|
||||
dev->name, medianame[dev->if_port], csr12);
|
||||
|
||||
/* remember to turn off bit 7 - autonegotiate
|
||||
* enable so we don't forget
|
||||
*/
|
||||
csr14 = (inl(ioaddr + CSR14) & 0xffffff7f);
|
||||
outl(csr14,ioaddr + CSR14);
|
||||
|
||||
/* what should we do when autonegotiate fails?
|
||||
* should we try again or default to baseline
|
||||
* case. I just don't know.
|
||||
*
|
||||
* for now default to some baseline case
|
||||
*/
|
||||
|
||||
dev->if_port = 0;
|
||||
tp->nway = 0;
|
||||
tp->nwayset = 1;
|
||||
|
||||
/* set to 10baseTx-HD - see Data Port Selection
|
||||
* comment given at the top of the file
|
||||
*/
|
||||
tp->csr6 = (inl(ioaddr + CSR6) & 0xfe3bd1fd);
|
||||
tp->csr6 |= 0x00400000;
|
||||
|
||||
tulip_restart_rxtx(tp);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((tp->nwayset && (csr5 & 0x08000000)
|
||||
&& (dev->if_port == 3 || dev->if_port == 5)
|
||||
&& (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) {
|
||||
|
||||
/* Link blew? Maybe restart NWay. */
|
||||
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Ugh! Link blew?\n", dev->name);
|
||||
|
||||
del_timer_sync(&tp->timer);
|
||||
pnic2_start_nway(dev);
|
||||
tp->timer.expires = RUN_AT(3*HZ);
|
||||
add_timer(&tp->timer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (dev->if_port == 3 || dev->if_port == 5) {
|
||||
|
||||
/* we are at 100mb and a potential link change occurred */
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: PNIC2 %s link beat %s.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
(csr12 & 2) ? "failed" : "good");
|
||||
|
||||
/* check 100 link beat */
|
||||
|
||||
tp->nway = 0;
|
||||
tp->nwayset = 1;
|
||||
|
||||
/* if failed then try doing an nway to get in sync */
|
||||
if ((csr12 & 2) && ! tp->medialock) {
|
||||
del_timer_sync(&tp->timer);
|
||||
pnic2_start_nway(dev);
|
||||
tp->timer.expires = RUN_AT(3*HZ);
|
||||
add_timer(&tp->timer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->if_port == 0 || dev->if_port == 4) {
|
||||
|
||||
/* we are at 10mb and a potential link change occurred */
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: PNIC2 %s link beat %s.\n",
|
||||
dev->name, medianame[dev->if_port],
|
||||
(csr12 & 4) ? "failed" : "good");
|
||||
|
||||
|
||||
tp->nway = 0;
|
||||
tp->nwayset = 1;
|
||||
|
||||
/* if failed, try doing an nway to get in sync */
|
||||
if ((csr12 & 4) && ! tp->medialock) {
|
||||
del_timer_sync(&tp->timer);
|
||||
pnic2_start_nway(dev);
|
||||
tp->timer.expires = RUN_AT(3*HZ);
|
||||
add_timer(&tp->timer);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_INFO"%s: PNIC2 Link Change Default?\n",dev->name);
|
||||
|
||||
/* if all else fails default to trying 10baseT-HD */
|
||||
dev->if_port = 0;
|
||||
|
||||
/* make sure autonegotiate enable is off */
|
||||
csr14 = (inl(ioaddr + CSR14) & 0xffffff7f);
|
||||
outl(csr14,ioaddr + CSR14);
|
||||
|
||||
/* set to 10baseTx-HD - see Data Port Selection
|
||||
* comment given at the top of the file
|
||||
*/
|
||||
tp->csr6 = (inl(ioaddr + CSR6) & 0xfe3bd1fd);
|
||||
tp->csr6 |= 0x00400000;
|
||||
|
||||
tulip_restart_rxtx(tp);
|
||||
}
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/timer.c
|
||||
|
||||
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
#include "tulip.h"
|
||||
|
||||
|
||||
void tulip_timer(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
u32 csr12 = inl(ioaddr + CSR12);
|
||||
int next_tick = 2*HZ;
|
||||
|
||||
if (tulip_debug > 2) {
|
||||
printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
|
||||
" %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n",
|
||||
dev->name, medianame[dev->if_port], inl(ioaddr + CSR5),
|
||||
inl(ioaddr + CSR6), csr12, inl(ioaddr + CSR13),
|
||||
inl(ioaddr + CSR14), inl(ioaddr + CSR15));
|
||||
}
|
||||
switch (tp->chip_id) {
|
||||
case DC21040:
|
||||
if (!tp->medialock && csr12 & 0x0002) { /* Network error */
|
||||
printk(KERN_INFO "%s: No link beat found.\n",
|
||||
dev->name);
|
||||
dev->if_port = (dev->if_port == 2 ? 0 : 2);
|
||||
tulip_select_media(dev, 0);
|
||||
dev->trans_start = jiffies;
|
||||
}
|
||||
break;
|
||||
case DC21041:
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: 21041 media tick CSR12 %8.8x.\n",
|
||||
dev->name, csr12);
|
||||
if (tp->medialock) break;
|
||||
switch (dev->if_port) {
|
||||
case 0: case 3: case 4:
|
||||
if (csr12 & 0x0004) { /*LnkFail */
|
||||
/* 10baseT is dead. Check for activity on alternate port. */
|
||||
tp->mediasense = 1;
|
||||
if (csr12 & 0x0200)
|
||||
dev->if_port = 2;
|
||||
else
|
||||
dev->if_port = 1;
|
||||
printk(KERN_INFO "%s: No 21041 10baseT link beat, Media switched to %s.\n",
|
||||
dev->name, medianame[dev->if_port]);
|
||||
outl(0, ioaddr + CSR13); /* Reset */
|
||||
outl(t21041_csr14[dev->if_port], ioaddr + CSR14);
|
||||
outl(t21041_csr15[dev->if_port], ioaddr + CSR15);
|
||||
outl(t21041_csr13[dev->if_port], ioaddr + CSR13);
|
||||
next_tick = 10*HZ; /* 2.4 sec. */
|
||||
} else
|
||||
next_tick = 30*HZ;
|
||||
break;
|
||||
case 1: /* 10base2 */
|
||||
case 2: /* AUI */
|
||||
if (csr12 & 0x0100) {
|
||||
next_tick = (30*HZ); /* 30 sec. */
|
||||
tp->mediasense = 0;
|
||||
} else if ((csr12 & 0x0004) == 0) {
|
||||
printk(KERN_INFO "%s: 21041 media switched to 10baseT.\n",
|
||||
dev->name);
|
||||
dev->if_port = 0;
|
||||
tulip_select_media(dev, 0);
|
||||
next_tick = (24*HZ)/10; /* 2.4 sec. */
|
||||
} else if (tp->mediasense || (csr12 & 0x0002)) {
|
||||
dev->if_port = 3 - dev->if_port; /* Swap ports. */
|
||||
tulip_select_media(dev, 0);
|
||||
next_tick = 20*HZ;
|
||||
} else {
|
||||
next_tick = 20*HZ;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DC21140:
|
||||
case DC21142:
|
||||
case MX98713:
|
||||
case COMPEX9881:
|
||||
case DM910X:
|
||||
default: {
|
||||
struct medialeaf *mleaf;
|
||||
unsigned char *p;
|
||||
if (tp->mtable == NULL) { /* No EEPROM info, use generic code. */
|
||||
/* Not much that can be done.
|
||||
Assume this a generic MII or SYM transceiver. */
|
||||
next_tick = 60*HZ;
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
|
||||
"CSR12 0x%2.2x.\n",
|
||||
dev->name, inl(ioaddr + CSR6), csr12 & 0xff);
|
||||
break;
|
||||
}
|
||||
mleaf = &tp->mtable->mleaf[tp->cur_index];
|
||||
p = mleaf->leafdata;
|
||||
switch (mleaf->type) {
|
||||
case 0: case 4: {
|
||||
/* Type 0 serial or 4 SYM transceiver. Check the link beat bit. */
|
||||
int offset = mleaf->type == 4 ? 5 : 2;
|
||||
s8 bitnum = p[offset];
|
||||
if (p[offset+1] & 0x80) {
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG"%s: Transceiver monitor tick "
|
||||
"CSR12=%#2.2x, no media sense.\n",
|
||||
dev->name, csr12);
|
||||
if (mleaf->type == 4) {
|
||||
if (mleaf->media == 3 && (csr12 & 0x02))
|
||||
goto select_next_media;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"
|
||||
" bit %d is %d, expecting %d.\n",
|
||||
dev->name, csr12, (bitnum >> 1) & 7,
|
||||
(csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
|
||||
(bitnum >= 0));
|
||||
/* Check that the specified bit has the proper value. */
|
||||
if ((bitnum < 0) !=
|
||||
((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
|
||||
if (tulip_debug > 2)
|
||||
printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
|
||||
medianame[mleaf->media & MEDIA_MASK]);
|
||||
if ((p[2] & 0x61) == 0x01) /* Bogus Znyx board. */
|
||||
goto actually_mii;
|
||||
/* netif_carrier_on(dev); */
|
||||
break;
|
||||
}
|
||||
/* netif_carrier_off(dev); */
|
||||
if (tp->medialock)
|
||||
break;
|
||||
select_next_media:
|
||||
if (--tp->cur_index < 0) {
|
||||
/* We start again, but should instead look for default. */
|
||||
tp->cur_index = tp->mtable->leafcount - 1;
|
||||
}
|
||||
dev->if_port = tp->mtable->mleaf[tp->cur_index].media;
|
||||
if (tulip_media_cap[dev->if_port] & MediaIsFD)
|
||||
goto select_next_media; /* Skip FD entries. */
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: No link beat on media %s,"
|
||||
" trying transceiver type %s.\n",
|
||||
dev->name, medianame[mleaf->media & MEDIA_MASK],
|
||||
medianame[tp->mtable->mleaf[tp->cur_index].media]);
|
||||
tulip_select_media(dev, 0);
|
||||
/* Restart the transmit process. */
|
||||
tulip_restart_rxtx(tp);
|
||||
next_tick = (24*HZ)/10;
|
||||
break;
|
||||
}
|
||||
case 1: case 3: /* 21140, 21142 MII */
|
||||
actually_mii:
|
||||
if (tulip_check_duplex(dev) < 0)
|
||||
{ /* netif_carrier_off(dev); */ }
|
||||
else
|
||||
{ /* netif_carrier_on(dev); */ }
|
||||
next_tick = 60*HZ;
|
||||
break;
|
||||
case 2: /* 21142 serial block has no link beat. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* mod_timer synchronizes us with potential add_timer calls
|
||||
* from interrupts.
|
||||
*/
|
||||
mod_timer(&tp->timer, RUN_AT(next_tick));
|
||||
}
|
||||
|
||||
|
||||
void mxic_timer(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int next_tick = 60*HZ;
|
||||
|
||||
if (tulip_debug > 3) {
|
||||
printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
|
||||
inl(ioaddr + CSR12));
|
||||
}
|
||||
if (next_tick) {
|
||||
mod_timer(&tp->timer, RUN_AT(next_tick));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void comet_timer(unsigned long data)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)data;
|
||||
struct tulip_private *tp = (struct tulip_private *)dev->priv;
|
||||
long ioaddr = dev->base_addr;
|
||||
int next_tick = 60*HZ;
|
||||
|
||||
if (tulip_debug > 1)
|
||||
printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
|
||||
"%4.4x.\n",
|
||||
dev->name, inl(ioaddr + 0xB8), inl(ioaddr + 0xC8));
|
||||
/* mod_timer synchronizes us with potential add_timer calls
|
||||
* from interrupts.
|
||||
*/
|
||||
mod_timer(&tp->timer, RUN_AT(next_tick));
|
||||
}
|
||||
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
drivers/net/tulip/tulip.h
|
||||
|
||||
Copyright 2000,2001 The Linux Kernel Team
|
||||
Written/copyright 1994-2001 by Donald Becker.
|
||||
|
||||
This software may be used and distributed according to the terms
|
||||
of the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Please refer to Documentation/DocBook/tulip.{pdf,ps,html}
|
||||
for more information on this driver, or visit the project
|
||||
Web page at http://sourceforge.net/projects/tulip/
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NET_TULIP_H__
|
||||
#define __NET_TULIP_H__
|
||||
|
||||
#include <linux/config.h>
|
||||
//#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
|
||||
|
||||
/* undefine, or define to various debugging levels (>4 == obscene levels) */
|
||||
#define TULIP_DEBUG 1
|
||||
|
||||
/* undefine USE_IO_OPS for MMIO, define for PIO */
|
||||
#ifdef CONFIG_TULIP_MMIO
|
||||
# undef USE_IO_OPS
|
||||
#else
|
||||
# define USE_IO_OPS 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
struct tulip_chip_table {
|
||||
char *chip_name;
|
||||
int io_size;
|
||||
int valid_intrs; /* CSR7 interrupt enable settings */
|
||||
int flags;
|
||||
void (*media_timer) (unsigned long data);
|
||||
};
|
||||
|
||||
|
||||
enum tbl_flag {
|
||||
HAS_MII = 0x0001,
|
||||
HAS_MEDIA_TABLE = 0x0002,
|
||||
CSR12_IN_SROM = 0x0004,
|
||||
ALWAYS_CHECK_MII = 0x0008,
|
||||
HAS_ACPI = 0x0010,
|
||||
MC_HASH_ONLY = 0x0020, /* Hash-only multicast filter. */
|
||||
HAS_PNICNWAY = 0x0080,
|
||||
HAS_NWAY = 0x0040, /* Uses internal NWay xcvr. */
|
||||
HAS_INTR_MITIGATION = 0x0100,
|
||||
IS_ASIX = 0x0200,
|
||||
HAS_8023X = 0x0400,
|
||||
COMET_MAC_ADDR = 0x0800,
|
||||
HAS_PCI_MWI = 0x1000,
|
||||
};
|
||||
|
||||
|
||||
/* chip types. careful! order is VERY IMPORTANT here, as these
|
||||
* are used throughout the driver as indices into arrays */
|
||||
/* Note 21142 == 21143. */
|
||||
enum chips {
|
||||
DC21040 = 0,
|
||||
DC21041 = 1,
|
||||
DC21140 = 2,
|
||||
DC21142 = 3, DC21143 = 3,
|
||||
LC82C168,
|
||||
MX98713,
|
||||
MX98715,
|
||||
MX98725,
|
||||
AX88140,
|
||||
PNIC2,
|
||||
COMET,
|
||||
COMPEX9881,
|
||||
I21145,
|
||||
DM910X,
|
||||
};
|
||||
|
||||
|
||||
enum MediaIs {
|
||||
MediaIsFD = 1,
|
||||
MediaAlwaysFD = 2,
|
||||
MediaIsMII = 4,
|
||||
MediaIsFx = 8,
|
||||
MediaIs100 = 16
|
||||
};
|
||||
|
||||
|
||||
/* Offsets to the Command and Status Registers, "CSRs". All accesses
|
||||
must be longword instructions and quadword aligned. */
|
||||
enum tulip_offsets {
|
||||
CSR0 = 0,
|
||||
CSR1 = 0x08,
|
||||
CSR2 = 0x10,
|
||||
CSR3 = 0x18,
|
||||
CSR4 = 0x20,
|
||||
CSR5 = 0x28,
|
||||
CSR6 = 0x30,
|
||||
CSR7 = 0x38,
|
||||
CSR8 = 0x40,
|
||||
CSR9 = 0x48,
|
||||
CSR10 = 0x50,
|
||||
CSR11 = 0x58,
|
||||
CSR12 = 0x60,
|
||||
CSR13 = 0x68,
|
||||
CSR14 = 0x70,
|
||||
CSR15 = 0x78,
|
||||
};
|
||||
|
||||
/* register offset and bits for CFDD PCI config reg */
|
||||
enum pci_cfg_driver_reg {
|
||||
CFDD = 0x40,
|
||||
CFDD_Sleep = (1 << 31),
|
||||
CFDD_Snooze = (1 << 30),
|
||||
};
|
||||
|
||||
|
||||
/* The bits in the CSR5 status registers, mostly interrupt sources. */
|
||||
enum status_bits {
|
||||
TimerInt = 0x800,
|
||||
SytemError = 0x2000,
|
||||
TPLnkFail = 0x1000,
|
||||
TPLnkPass = 0x10,
|
||||
NormalIntr = 0x10000,
|
||||
AbnormalIntr = 0x8000,
|
||||
RxJabber = 0x200,
|
||||
RxDied = 0x100,
|
||||
RxNoBuf = 0x80,
|
||||
RxIntr = 0x40,
|
||||
TxFIFOUnderflow = 0x20,
|
||||
TxJabber = 0x08,
|
||||
TxNoBuf = 0x04,
|
||||
TxDied = 0x02,
|
||||
TxIntr = 0x01,
|
||||
};
|
||||
|
||||
|
||||
enum tulip_mode_bits {
|
||||
TxThreshold = (1 << 22),
|
||||
FullDuplex = (1 << 9),
|
||||
TxOn = 0x2000,
|
||||
AcceptBroadcast = 0x0100,
|
||||
AcceptAllMulticast = 0x0080,
|
||||
AcceptAllPhys = 0x0040,
|
||||
AcceptRunt = 0x0008,
|
||||
RxOn = 0x0002,
|
||||
RxTx = (TxOn | RxOn),
|
||||
};
|
||||
|
||||
|
||||
enum tulip_busconfig_bits {
|
||||
MWI = (1 << 24),
|
||||
MRL = (1 << 23),
|
||||
MRM = (1 << 21),
|
||||
CALShift = 14,
|
||||
BurstLenShift = 8,
|
||||
};
|
||||
|
||||
|
||||
/* The Tulip Rx and Tx buffer descriptors. */
|
||||
struct tulip_rx_desc {
|
||||
s32 status;
|
||||
s32 length;
|
||||
u32 buffer1;
|
||||
u32 buffer2;
|
||||
};
|
||||
|
||||
|
||||
struct tulip_tx_desc {
|
||||
s32 status;
|
||||
s32 length;
|
||||
u32 buffer1;
|
||||
u32 buffer2; /* We use only buffer 1. */
|
||||
};
|
||||
|
||||
|
||||
enum desc_status_bits {
|
||||
DescOwned = 0x80000000,
|
||||
RxDescFatalErr = 0x8000,
|
||||
RxWholePkt = 0x0300,
|
||||
};
|
||||
|
||||
|
||||
enum t21041_csr13_bits {
|
||||
csr13_eng = (0xEF0<<4), /* for eng. purposes only, hardcode at EF0h */
|
||||
csr13_aui = (1<<3), /* clear to force 10bT, set to force AUI/BNC */
|
||||
csr13_cac = (1<<2), /* CSR13/14/15 autoconfiguration */
|
||||
csr13_srl = (1<<0), /* When reset, resets all SIA functions, machines */
|
||||
|
||||
csr13_mask_auibnc = (csr13_eng | csr13_aui | csr13_srl),
|
||||
csr13_mask_10bt = (csr13_eng | csr13_srl),
|
||||
};
|
||||
|
||||
enum t21143_csr6_bits {
|
||||
csr6_sc = (1<<31),
|
||||
csr6_ra = (1<<30),
|
||||
csr6_ign_dest_msb = (1<<26),
|
||||
csr6_mbo = (1<<25),
|
||||
csr6_scr = (1<<24), /* scramble mode flag: can't be set */
|
||||
csr6_pcs = (1<<23), /* Enables PCS functions (symbol mode requires csr6_ps be set) default is set */
|
||||
csr6_ttm = (1<<22), /* Transmit Threshold Mode, set for 10baseT, 0 for 100BaseTX */
|
||||
csr6_sf = (1<<21), /* Store and forward. If set ignores TR bits */
|
||||
csr6_hbd = (1<<19), /* Heart beat disable. Disables SQE function in 10baseT */
|
||||
csr6_ps = (1<<18), /* Port Select. 0 (defualt) = 10baseT, 1 = 100baseTX: can't be set */
|
||||
csr6_ca = (1<<17), /* Collision Offset Enable. If set uses special algorithm in low collision situations */
|
||||
csr6_trh = (1<<15), /* Transmit Threshold high bit */
|
||||
csr6_trl = (1<<14), /* Transmit Threshold low bit */
|
||||
|
||||
/***************************************************************
|
||||
* This table shows transmit threshold values based on media *
|
||||
* and these two registers (from PNIC1 & 2 docs) Note: this is *
|
||||
* all meaningless if sf is set. *
|
||||
***************************************************************/
|
||||
|
||||
/***********************************
|
||||
* (trh,trl) * 100BaseTX * 10BaseT *
|
||||
***********************************
|
||||
* (0,0) * 128 * 72 *
|
||||
* (0,1) * 256 * 96 *
|
||||
* (1,0) * 512 * 128 *
|
||||
* (1,1) * 1024 * 160 *
|
||||
***********************************/
|
||||
|
||||
csr6_fc = (1<<12), /* Forces a collision in next transmission (for testing in loopback mode) */
|
||||
csr6_om_int_loop = (1<<10), /* internal (FIFO) loopback flag */
|
||||
csr6_om_ext_loop = (1<<11), /* external (PMD) loopback flag */
|
||||
/* set both and you get (PHY) loopback */
|
||||
csr6_fd = (1<<9), /* Full duplex mode, disables hearbeat, no loopback */
|
||||
csr6_pm = (1<<7), /* Pass All Multicast */
|
||||
csr6_pr = (1<<6), /* Promiscuous mode */
|
||||
csr6_sb = (1<<5), /* Start(1)/Stop(0) backoff counter */
|
||||
csr6_if = (1<<4), /* Inverse Filtering, rejects only addresses in address table: can't be set */
|
||||
csr6_pb = (1<<3), /* Pass Bad Frames, (1) causes even bad frames to be passed on */
|
||||
csr6_ho = (1<<2), /* Hash-only filtering mode: can't be set */
|
||||
csr6_hp = (1<<0), /* Hash/Perfect Receive Filtering Mode: can't be set */
|
||||
|
||||
csr6_mask_capture = (csr6_sc | csr6_ca),
|
||||
csr6_mask_defstate = (csr6_mask_capture | csr6_mbo),
|
||||
csr6_mask_hdcap = (csr6_mask_defstate | csr6_hbd | csr6_ps),
|
||||
csr6_mask_hdcaptt = (csr6_mask_hdcap | csr6_trh | csr6_trl),
|
||||
csr6_mask_fullcap = (csr6_mask_hdcaptt | csr6_fd),
|
||||
csr6_mask_fullpromisc = (csr6_pr | csr6_pm),
|
||||
csr6_mask_filters = (csr6_hp | csr6_ho | csr6_if),
|
||||
csr6_mask_100bt = (csr6_scr | csr6_pcs | csr6_hbd),
|
||||
};
|
||||
|
||||
|
||||
/* Keep the ring sizes a power of two for efficiency.
|
||||
Making the Tx ring too large decreases the effectiveness of channel
|
||||
bonding and packet priority.
|
||||
There are no ill effects from too-large receive rings. */
|
||||
#undef TX_RING_SIZE
|
||||
#undef RX_RING_SIZE
|
||||
#define TX_RING_SIZE 16
|
||||
#define RX_RING_SIZE 32
|
||||
|
||||
#define MEDIA_MASK 31
|
||||
|
||||
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */
|
||||
|
||||
#define TULIP_MIN_CACHE_LINE 8 /* in units of 32-bit words */
|
||||
|
||||
#if defined(__sparc__) || defined(__hppa__)
|
||||
/* The UltraSparc PCI controllers will disconnect at every 64-byte
|
||||
* crossing anyways so it makes no sense to tell Tulip to burst
|
||||
* any more than that.
|
||||
*/
|
||||
#define TULIP_MAX_CACHE_LINE 16 /* in units of 32-bit words */
|
||||
#else
|
||||
#define TULIP_MAX_CACHE_LINE 32 /* in units of 32-bit words */
|
||||
#endif
|
||||
|
||||
|
||||
/* Ring-wrap flag in length field, use for last ring entry.
|
||||
0x01000000 means chain on buffer2 address,
|
||||
0x02000000 means use the ring start address in CSR2/3.
|
||||
Note: Some work-alike chips do not function correctly in chained mode.
|
||||
The ASIX chip works only in chained mode.
|
||||
Thus we indicates ring mode, but always write the 'next' field for
|
||||
chained mode as well.
|
||||
*/
|
||||
#define DESC_RING_WRAP 0x02000000
|
||||
|
||||
|
||||
#define EEPROM_SIZE 128 /* 2 << EEPROM_ADDRLEN */
|
||||
|
||||
|
||||
#define RUN_AT(x) (jiffies + (x))
|
||||
|
||||
#if defined(__i386__) /* AKA get_unaligned() */
|
||||
#define get_u16(ptr) (*(u16 *)(ptr))
|
||||
#else
|
||||
#define get_u16(ptr) (((u8*)(ptr))[0] + (((u8*)(ptr))[1]<<8))
|
||||
#endif
|
||||
|
||||
struct medialeaf {
|
||||
u8 type;
|
||||
u8 media;
|
||||
unsigned char *leafdata;
|
||||
};
|
||||
|
||||
|
||||
struct mediatable {
|
||||
u16 defaultmedia;
|
||||
u8 leafcount;
|
||||
u8 csr12dir; /* General purpose pin directions. */
|
||||
unsigned has_mii:1;
|
||||
unsigned has_nonmii:1;
|
||||
unsigned has_reset:6;
|
||||
u32 csr15dir;
|
||||
u32 csr15val; /* 21143 NWay setting. */
|
||||
struct medialeaf mleaf[0];
|
||||
};
|
||||
|
||||
|
||||
struct mediainfo {
|
||||
struct mediainfo *next;
|
||||
int info_type;
|
||||
int index;
|
||||
unsigned char *info;
|
||||
};
|
||||
|
||||
struct ring_info {
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t mapping;
|
||||
};
|
||||
|
||||
|
||||
struct tulip_private {
|
||||
const char *product_name;
|
||||
struct net_device *next_module;
|
||||
struct tulip_rx_desc *rx_ring;
|
||||
struct tulip_tx_desc *tx_ring;
|
||||
dma_addr_t rx_ring_dma;
|
||||
dma_addr_t tx_ring_dma;
|
||||
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
|
||||
struct ring_info tx_buffers[TX_RING_SIZE];
|
||||
/* The addresses of receive-in-place skbuffs. */
|
||||
struct ring_info rx_buffers[RX_RING_SIZE];
|
||||
u16 setup_frame[96]; /* Pseudo-Tx frame to init address table. */
|
||||
int chip_id;
|
||||
int revision;
|
||||
int flags;
|
||||
struct net_device_stats stats;
|
||||
struct timer_list timer; /* Media selection timer. */
|
||||
u32 mc_filter[2];
|
||||
spinlock_t lock;
|
||||
spinlock_t mii_lock;
|
||||
unsigned int cur_rx, cur_tx; /* The next free ring entry */
|
||||
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
|
||||
|
||||
#ifdef CONFIG_NET_HW_FLOWCONTROL
|
||||
#define RX_A_NBF_STOP 0xffffff3f /* To disable RX and RX-NOBUF ints. */
|
||||
int fc_bit;
|
||||
int mit_sel;
|
||||
int mit_change; /* Signal for Interrupt Mitigtion */
|
||||
#endif
|
||||
unsigned int full_duplex:1; /* Full-duplex operation requested. */
|
||||
unsigned int full_duplex_lock:1;
|
||||
unsigned int fake_addr:1; /* Multiport board faked address. */
|
||||
unsigned int default_port:4; /* Last dev->if_port value. */
|
||||
unsigned int media2:4; /* Secondary monitored media port. */
|
||||
unsigned int medialock:1; /* Don't sense media type. */
|
||||
unsigned int mediasense:1; /* Media sensing in progress. */
|
||||
unsigned int nway:1, nwayset:1; /* 21143 internal NWay. */
|
||||
unsigned int csr0; /* CSR0 setting. */
|
||||
unsigned int csr6; /* Current CSR6 control settings. */
|
||||
unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */
|
||||
void (*link_change) (struct net_device * dev, int csr5);
|
||||
u16 sym_advertise, mii_advertise; /* NWay capabilities advertised. */
|
||||
u16 lpar; /* 21143 Link partner ability. */
|
||||
u16 advertising[4];
|
||||
signed char phys[4], mii_cnt; /* MII device addresses. */
|
||||
struct mediatable *mtable;
|
||||
int cur_index; /* Current media index. */
|
||||
int saved_if_port;
|
||||
struct pci_dev *pdev;
|
||||
int ttimer;
|
||||
int susp_rx;
|
||||
unsigned long nir;
|
||||
unsigned long base_addr;
|
||||
int pad0, pad1; /* Used for 8-byte alignment */
|
||||
};
|
||||
|
||||
|
||||
struct eeprom_fixup {
|
||||
char *name;
|
||||
unsigned char addr0;
|
||||
unsigned char addr1;
|
||||
unsigned char addr2;
|
||||
u16 newtable[32]; /* Max length below. */
|
||||
};
|
||||
|
||||
|
||||
/* 21142.c */
|
||||
extern u16 t21142_csr14[];
|
||||
void t21142_timer(unsigned long data);
|
||||
void t21142_start_nway(struct net_device *dev);
|
||||
void t21142_lnk_change(struct net_device *dev, int csr5);
|
||||
|
||||
|
||||
/* PNIC2.c */
|
||||
void pnic2_lnk_change(struct net_device *dev, int csr5);
|
||||
void pnic2_timer(unsigned long data);
|
||||
void pnic2_start_nway(struct net_device *dev);
|
||||
void pnic2_lnk_change(struct net_device *dev, int csr5);
|
||||
|
||||
/* eeprom.c */
|
||||
void tulip_parse_eeprom(struct net_device *dev);
|
||||
int tulip_read_eeprom(long ioaddr, int location, int addr_len);
|
||||
|
||||
/* interrupt.c */
|
||||
extern unsigned int tulip_max_interrupt_work;
|
||||
extern int tulip_rx_copybreak;
|
||||
void tulip_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
|
||||
int tulip_refill_rx(struct net_device *dev);
|
||||
|
||||
/* media.c */
|
||||
int tulip_mdio_read(struct net_device *dev, int phy_id, int location);
|
||||
void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value);
|
||||
void tulip_select_media(struct net_device *dev, int startup);
|
||||
int tulip_check_duplex(struct net_device *dev);
|
||||
void tulip_find_mii (struct net_device *dev, int board_idx);
|
||||
|
||||
/* pnic.c */
|
||||
void pnic_do_nway(struct net_device *dev);
|
||||
void pnic_lnk_change(struct net_device *dev, int csr5);
|
||||
void pnic_timer(unsigned long data);
|
||||
|
||||
/* timer.c */
|
||||
void tulip_timer(unsigned long data);
|
||||
void mxic_timer(unsigned long data);
|
||||
void comet_timer(unsigned long data);
|
||||
|
||||
/* tulip_core.c */
|
||||
extern int tulip_debug;
|
||||
extern const char * const medianame[];
|
||||
extern const char tulip_media_cap[];
|
||||
extern struct tulip_chip_table tulip_tbl[];
|
||||
extern u8 t21040_csr13[];
|
||||
extern u16 t21041_csr13[];
|
||||
extern u16 t21041_csr14[];
|
||||
extern u16 t21041_csr15[];
|
||||
|
||||
#ifndef USE_IO_OPS
|
||||
#undef inb
|
||||
#undef inw
|
||||
#undef inl
|
||||
#undef outb
|
||||
#undef outw
|
||||
#undef outl
|
||||
#define inb(addr) readb((void*)(addr))
|
||||
#define inw(addr) readw((void*)(addr))
|
||||
#define inl(addr) readl((void*)(addr))
|
||||
#define outb(val,addr) writeb((val), (void*)(addr))
|
||||
#define outw(val,addr) writew((val), (void*)(addr))
|
||||
#define outl(val,addr) writel((val), (void*)(addr))
|
||||
#endif /* !USE_IO_OPS */
|
||||
|
||||
|
||||
|
||||
static inline void tulip_start_rxtx(struct tulip_private *tp)
|
||||
{
|
||||
long ioaddr = tp->base_addr;
|
||||
outl(tp->csr6 | RxTx, ioaddr + CSR6);
|
||||
barrier();
|
||||
(void) inl(ioaddr + CSR6); /* mmio sync */
|
||||
}
|
||||
|
||||
static inline void tulip_stop_rxtx(struct tulip_private *tp)
|
||||
{
|
||||
long ioaddr = tp->base_addr;
|
||||
u32 csr6 = inl(ioaddr + CSR6);
|
||||
|
||||
if (csr6 & RxTx) {
|
||||
outl(csr6 & ~RxTx, ioaddr + CSR6);
|
||||
barrier();
|
||||
(void) inl(ioaddr + CSR6); /* mmio sync */
|
||||
}
|
||||
}
|
||||
|
||||
static inline void tulip_restart_rxtx(struct tulip_private *tp)
|
||||
{
|
||||
tulip_stop_rxtx(tp);
|
||||
udelay(5);
|
||||
tulip_start_rxtx(tp);
|
||||
}
|
||||
|
||||
#endif /* __NET_TULIP_H__ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -13,9 +13,7 @@
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#define TARGET_CPUS cpu_online_map
|
||||
#define INT_DELIVERY_MODE 1 /* logical delivery broadcast to all procs */
|
||||
#else
|
||||
#define INT_DELIVERY_MODE 1 /* logical delivery */
|
||||
#define TARGET_CPUS 0x01
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2043,12 +2043,13 @@ long do_net_update(void)
|
||||
|
||||
for ( j = 0; j < current->num_net_vifs; j++)
|
||||
{
|
||||
current_vif = current->net_vif_list[j];
|
||||
net_ring = current_vif->net_ring;
|
||||
int target;
|
||||
u8 *g_data;
|
||||
unsigned short protocol;
|
||||
|
||||
current_vif = current->net_vif_list[j];
|
||||
net_ring = current_vif->net_ring;
|
||||
|
||||
/* First, we send out pending TX descriptors if they exist on this ring.
|
||||
*/
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#define TX_RING_ADD(_i,_j) (((_i)+(_j)) & (TX_RING_SIZE-1))
|
||||
#define RX_RING_ADD(_i,_j) (((_i)+(_j)) & (RX_RING_SIZE-1))
|
||||
|
||||
#define RX_BUF_SIZE 2049 /* (was 1600) Ethernet MTU + plenty of slack! */
|
||||
#define RX_BUF_SIZE ((PAGE_SIZE/2)+1) /* Fool the slab allocator :-) */
|
||||
|
||||
static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs);
|
||||
static void network_tx_int(int irq, void *dev_id, struct pt_regs *ptregs);
|
||||
@@ -92,9 +92,9 @@ static int network_open(struct net_device *dev)
|
||||
np->rx_skb_ring = kmalloc(RX_RING_SIZE * sizeof(struct sk_buff *),
|
||||
GFP_KERNEL);
|
||||
np->net_ring->tx_ring = kmalloc(TX_RING_SIZE * sizeof(tx_entry_t),
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
np->net_ring->rx_ring = kmalloc(RX_RING_SIZE * sizeof(rx_entry_t),
|
||||
GFP_KERNEL);
|
||||
GFP_KERNEL);
|
||||
if ( (np->tx_skb_ring == NULL) || (np->rx_skb_ring == NULL) ||
|
||||
(np->net_ring->tx_ring == NULL) || (np->net_ring->rx_ring == NULL) )
|
||||
{
|
||||
@@ -106,7 +106,7 @@ static int network_open(struct net_device *dev)
|
||||
network_alloc_rx_buffers(dev);
|
||||
|
||||
error = request_irq(NET_RX_IRQ, network_rx_int, 0,
|
||||
"net-rx", dev);
|
||||
"net-rx", dev);
|
||||
if ( error )
|
||||
{
|
||||
printk(KERN_WARNING "%s: Could not allocate receive interrupt\n",
|
||||
@@ -115,7 +115,7 @@ static int network_open(struct net_device *dev)
|
||||
}
|
||||
|
||||
error = request_irq(NET_TX_IRQ, network_tx_int, 0,
|
||||
"net-tx", dev);
|
||||
"net-tx", dev);
|
||||
if ( error )
|
||||
{
|
||||
printk(KERN_WARNING "%s: Could not allocate transmit interrupt\n",
|
||||
@@ -171,20 +171,20 @@ static void network_tx_buf_gc(struct net_device *dev)
|
||||
|
||||
inline unsigned long get_ppte(unsigned long addr)
|
||||
{
|
||||
unsigned long ppte = 0xdeadbeef;
|
||||
pgd_t *pgd; pmd_t *pmd; pte_t *ptep;
|
||||
pgd = pgd_offset_k(addr);
|
||||
unsigned long ppte = 0xdeadbeef;
|
||||
pgd_t *pgd; pmd_t *pmd; pte_t *ptep;
|
||||
pgd = pgd_offset_k(addr);
|
||||
|
||||
if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG();
|
||||
if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG();
|
||||
|
||||
pmd = pmd_offset(pgd, addr);
|
||||
if (pmd_none(*pmd)) BUG();
|
||||
if (pmd_bad(*pmd)) BUG();
|
||||
pmd = pmd_offset(pgd, addr);
|
||||
if (pmd_none(*pmd)) BUG();
|
||||
if (pmd_bad(*pmd)) BUG();
|
||||
|
||||
ptep = pte_offset(pmd, addr);
|
||||
ppte = (unsigned long)phys_to_machine(virt_to_phys(ptep));
|
||||
ptep = pte_offset(pmd, addr);
|
||||
ppte = (unsigned long)phys_to_machine(virt_to_phys(ptep));
|
||||
|
||||
return ppte;
|
||||
return ppte;
|
||||
}
|
||||
|
||||
static void network_alloc_rx_buffers(struct net_device *dev)
|
||||
@@ -250,8 +250,8 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
np->tx_skb_ring[i] = skb;
|
||||
np->net_ring->tx_ring[i].addr
|
||||
= (unsigned long)phys_to_machine(virt_to_phys(skb->data));
|
||||
np->net_ring->tx_ring[i].addr =
|
||||
(unsigned long)phys_to_machine(virt_to_phys(skb->data));
|
||||
np->net_ring->tx_ring[i].size = skb->len;
|
||||
np->net_ring->tx_prod = TX_RING_INC(i);
|
||||
atomic_inc(&np->tx_entries);
|
||||
@@ -264,8 +264,8 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
np->tx_full = 1;
|
||||
netif_stop_queue(dev);
|
||||
np->net_ring->tx_event = TX_RING_ADD(np->tx_idx,
|
||||
atomic_read(&np->tx_entries) >> 1);
|
||||
np->net_ring->tx_event =
|
||||
TX_RING_ADD(np->tx_idx, atomic_read(&np->tx_entries) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -295,23 +295,24 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
|
||||
{
|
||||
if (np->net_ring->rx_ring[i].status != RING_STATUS_OK)
|
||||
{
|
||||
printk("bad buffer on RX ring!(%d)\n",
|
||||
np->net_ring->rx_ring[i].status);
|
||||
continue;
|
||||
printk("bad buffer on RX ring!(%d)\n",
|
||||
np->net_ring->rx_ring[i].status);
|
||||
continue;
|
||||
}
|
||||
skb = np->rx_skb_ring[i];
|
||||
|
||||
phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] =
|
||||
(*(unsigned long *)phys_to_virt(
|
||||
machine_to_phys(np->net_ring->rx_ring[i].addr))
|
||||
) >> PAGE_SHIFT;
|
||||
machine_to_phys(np->net_ring->rx_ring[i].addr))
|
||||
) >> PAGE_SHIFT;
|
||||
|
||||
skb_put(skb, np->net_ring->rx_ring[i].size);
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
|
||||
/* Set up shinfo -- from alloc_skb
|
||||
* This was particularily nasty: the shared info is hidden at the back of the data area
|
||||
* (presumably so it can be shared), but on page flip it gets very spunked.
|
||||
/*
|
||||
* Set up shinfo -- from alloc_skb This was particularily nasty: the
|
||||
* shared info is hidden at the back of the data area (presumably so
|
||||
* it can be shared), but on page flip it gets very spunked.
|
||||
*/
|
||||
|
||||
atomic_set(&(skb_shinfo(skb)->dataref), 1);
|
||||
@@ -331,9 +332,7 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
|
||||
|
||||
/* Deal with hypervisor racing our resetting of rx_event. */
|
||||
smp_mb();
|
||||
if ( np->net_ring->rx_cons != i ) {
|
||||
goto again;
|
||||
}
|
||||
if ( np->net_ring->rx_cons != i ) goto again;
|
||||
}
|
||||
|
||||
|
||||
|
||||