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:
kaf24@labyrinth.cl.cam.ac.uk committed 2003-02-14 17:31:12 +00:00
1 parent f834467529
commit 9a224b7822
21 files changed
+33 -10807

No files matched your search

-15
View File
@@ -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
+1 -3
View File
@@ -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
-58
View File
@@ -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 \
-239
View File
@@ -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);
}
}
-520
View File
@@ -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.
-8
View File
@@ -1,8 +0,0 @@
include $(BASEDIR)/Rules.mk
default: $(OBJS)
$(LD) -r -o tulip.o $(OBJS)
clean:
rm -f *.o *~ core
-320
View File
@@ -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;
}
-560
View File
@@ -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));
}
-563
View File
@@ -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;
}
}
-171
View File
@@ -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);
}
}
-407
View File
@@ -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);
}
-220
View File
@@ -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));
}
-499
View File
@@ -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
-2
View File
@@ -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
+3 -2
View File
@@ -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;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.