Commit 386d0ce7 authored by Jeff Garzik's avatar Jeff Garzik

Merge mandrakesoft.com:/home/jgarzik/vanilla/linus-2.5

into mandrakesoft.com:/home/jgarzik/repo/net-drivers-2.5
parents afae6f7c 6502fb5d
...@@ -45,11 +45,13 @@ ...@@ -45,11 +45,13 @@
- Reviewed against 1.18 from scyld.com - Reviewed against 1.18 from scyld.com
v1.18a 17Nov2001 Jeff Garzik <jgarzik@mandrakesoft.com> v1.18a 17Nov2001 Jeff Garzik <jgarzik@mandrakesoft.com>
- ethtool support - ethtool support
v1.18b 1Mar2002 Zwane Mwaikambo <zwane@commfireservices.com>
- Power Management support
*/ */
#define DRV_NAME "3c509" #define DRV_NAME "3c509"
#define DRV_VERSION "1.18a" #define DRV_VERSION "1.18b"
#define DRV_RELDATE "17Nov2001" #define DRV_RELDATE "1Mar2002"
/* A few values that may be tweaked. */ /* A few values that may be tweaked. */
...@@ -82,8 +84,9 @@ static int max_interrupt_work = 10; ...@@ -82,8 +84,9 @@ static int max_interrupt_work = 10;
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <linux/pm.h>
static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "becker@scyld.com\n"; static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n"; static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n";
#ifdef EL3_DEBUG #ifdef EL3_DEBUG
...@@ -116,7 +119,8 @@ enum c509cmd { ...@@ -116,7 +119,8 @@ enum c509cmd {
FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
StatsDisable = 22<<11, StopCoax = 23<<11,}; StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11,
PowerDown = 28<<11, PowerAuto = 29<<11};
enum c509status { enum c509status {
IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
...@@ -152,6 +156,9 @@ struct el3_private { ...@@ -152,6 +156,9 @@ struct el3_private {
int head, size; int head, size;
struct sk_buff *queue[SKB_QUEUE_SIZE]; struct sk_buff *queue[SKB_QUEUE_SIZE];
char mca_slot; char mca_slot;
#ifdef CONFIG_PM
struct pm_dev *pmdev;
#endif
}; };
static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/ static int id_port __initdata = 0x110; /* Start with 0x110 to avoid new sound cards.*/
static struct net_device *el3_root_dev; static struct net_device *el3_root_dev;
...@@ -168,6 +175,13 @@ static int el3_close(struct net_device *dev); ...@@ -168,6 +175,13 @@ static int el3_close(struct net_device *dev);
static void set_multicast_list(struct net_device *dev); static void set_multicast_list(struct net_device *dev);
static void el3_tx_timeout (struct net_device *dev); static void el3_tx_timeout (struct net_device *dev);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static void el3_down(struct net_device *dev);
static void el3_up(struct net_device *dev);
#ifdef CONFIG_PM
static int el3_suspend(struct pm_dev *pdev);
static int el3_resume(struct pm_dev *pdev);
static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
#endif
#ifdef CONFIG_MCA #ifdef CONFIG_MCA
struct el3_mca_adapters_struct { struct el3_mca_adapters_struct {
...@@ -219,7 +233,7 @@ static u16 el3_isapnp_phys_addr[8][3]; ...@@ -219,7 +233,7 @@ static u16 el3_isapnp_phys_addr[8][3];
#endif /* __ISAPNP__ */ #endif /* __ISAPNP__ */
static int nopnp; static int nopnp;
int __init el3_probe(struct net_device *dev) int __init el3_probe(struct net_device *dev, int card_idx)
{ {
struct el3_private *lp; struct el3_private *lp;
short lrs_state = 0xff, i; short lrs_state = 0xff, i;
...@@ -525,6 +539,16 @@ int __init el3_probe(struct net_device *dev) ...@@ -525,6 +539,16 @@ int __init el3_probe(struct net_device *dev)
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl; dev->do_ioctl = netdev_ioctl;
#ifdef CONFIG_PM
/* register power management */
lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
if (lp->pmdev) {
struct pm_dev *p;
p = lp->pmdev;
p->data = (struct net_device *)dev;
}
#endif
/* Fill in the generic fields of the device structure. */ /* Fill in the generic fields of the device structure. */
ether_setup(dev); ether_setup(dev);
return 0; return 0;
...@@ -581,53 +605,7 @@ el3_open(struct net_device *dev) ...@@ -581,53 +605,7 @@ el3_open(struct net_device *dev)
printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name, printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS)); dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
/* Activate board: this is probably unnecessary. */ el3_up(dev);
outw(0x0001, ioaddr + 4);
/* Set the IRQ line. */
outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
/* Set the station address in window 2 each time opened. */
EL3WINDOW(2);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i);
if (dev->if_port == 3)
/* Start the thinnet transceiver. We should really wait 50ms...*/
outw(StartCoax, ioaddr + EL3_CMD);
else if (dev->if_port == 0) {
/* 10baseT interface, enabled link beat and jabber check. */
EL3WINDOW(4);
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
}
/* Switch to the stats window, and clear all stats by reading. */
outw(StatsDisable, ioaddr + EL3_CMD);
EL3WINDOW(6);
for (i = 0; i < 9; i++)
inb(ioaddr + i);
inw(ioaddr + 10);
inw(ioaddr + 12);
/* Switch to register set 1 for normal use. */
EL3WINDOW(1);
/* Accept b-case and phys addr only. */
outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
netif_start_queue(dev);
outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
/* Allow status bits to be seen. */
outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
/* Ack all pending events, and set active indicator mask. */
outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
ioaddr + EL3_CMD);
outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
ioaddr + EL3_CMD);
if (el3_debug > 3) if (el3_debug > 3)
printk("%s: Opened 3c509 IRQ %d status %4.4x.\n", printk("%s: Opened 3c509 IRQ %d status %4.4x.\n",
...@@ -986,23 +964,7 @@ el3_close(struct net_device *dev) ...@@ -986,23 +964,7 @@ el3_close(struct net_device *dev)
if (el3_debug > 2) if (el3_debug > 2)
printk("%s: Shutting down ethercard.\n", dev->name); printk("%s: Shutting down ethercard.\n", dev->name);
netif_stop_queue(dev); el3_down(dev);
/* Turn off statistics ASAP. We update lp->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);
/* Disable the receiver and transmitter. */
outw(RxDisable, ioaddr + EL3_CMD);
outw(TxDisable, ioaddr + EL3_CMD);
if (dev->if_port == 3)
/* Turn off thinnet power. Green! */
outw(StopCoax, ioaddr + EL3_CMD);
else if (dev->if_port == 0) {
/* Disable link beat and jabber, if_port may change ere next open(). */
EL3WINDOW(4);
outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
}
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
/* Switching back to window 0 disables the IRQ. */ /* Switching back to window 0 disables the IRQ. */
...@@ -1010,7 +972,6 @@ el3_close(struct net_device *dev) ...@@ -1010,7 +972,6 @@ el3_close(struct net_device *dev)
/* But we explicitly zero the IRQ line select anyway. */ /* But we explicitly zero the IRQ line select anyway. */
outw(0x0f00, ioaddr + WN0_IRQ); outw(0x0f00, ioaddr + WN0_IRQ);
update_stats(dev);
return 0; return 0;
} }
...@@ -1093,6 +1054,156 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1093,6 +1054,156 @@ static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
return rc; return rc;
} }
static void el3_down(struct net_device *dev)
{
int ioaddr = dev->base_addr;
netif_stop_queue(dev);
/* Turn off statistics ASAP. We update lp->stats below. */
outw(StatsDisable, ioaddr + EL3_CMD);
/* Disable the receiver and transmitter. */
outw(RxDisable, ioaddr + EL3_CMD);
outw(TxDisable, ioaddr + EL3_CMD);
if (dev->if_port == 3)
/* Turn off thinnet power. Green! */
outw(StopCoax, ioaddr + EL3_CMD);
else if (dev->if_port == 0) {
/* Disable link beat and jabber, if_port may change ere next open(). */
EL3WINDOW(4);
outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
}
outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
update_stats(dev);
}
static void el3_up(struct net_device *dev)
{
int i;
int ioaddr = dev->base_addr;
/* Activating the board required and does no harm otherwise */
outw(0x0001, ioaddr + 4);
/* Set the IRQ line. */
outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
/* Set the station address in window 2 each time opened. */
EL3WINDOW(2);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i);
if (dev->if_port == 3)
/* Start the thinnet transceiver. We should really wait 50ms...*/
outw(StartCoax, ioaddr + EL3_CMD);
else if (dev->if_port == 0) {
/* 10baseT interface, enabled link beat and jabber check. */
EL3WINDOW(4);
outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
}
/* Switch to the stats window, and clear all stats by reading. */
outw(StatsDisable, ioaddr + EL3_CMD);
EL3WINDOW(6);
for (i = 0; i < 9; i++)
inb(ioaddr + i);
inw(ioaddr + 10);
inw(ioaddr + 12);
/* Switch to register set 1 for normal use. */
EL3WINDOW(1);
/* Accept b-case and phys addr only. */
outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
/* Allow status bits to be seen. */
outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
/* Ack all pending events, and set active indicator mask. */
outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
ioaddr + EL3_CMD);
outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
ioaddr + EL3_CMD);
netif_start_queue(dev);
}
/* Power Management support functions */
#ifdef CONFIG_PM
static int el3_suspend(struct pm_dev *pdev)
{
unsigned long flags;
struct net_device *dev;
struct el3_private *lp;
int ioaddr;
if (!pdev && !pdev->data)
return -EINVAL;
dev = (struct net_device *)pdev->data;
lp = (struct el3_private *)dev->priv;
ioaddr = dev->base_addr;
spin_lock_irqsave(&lp->lock, flags);
if (netif_running(dev))
netif_device_detach(dev);
el3_down(dev);
outw(PowerDown, ioaddr + EL3_CMD);
spin_unlock_irqrestore(&lp->lock, flags);
return 0;
}
static int el3_resume(struct pm_dev *pdev)
{
unsigned long flags;
struct net_device *dev;
struct el3_private *lp;
int ioaddr;
if (!pdev && !pdev->data)
return -EINVAL;
dev = (struct net_device *)pdev->data;
lp = (struct el3_private *)dev->priv;
ioaddr = dev->base_addr;
spin_lock_irqsave(&lp->lock, flags);
outw(PowerUp, ioaddr + EL3_CMD);
el3_up(dev);
if (netif_running(dev))
netif_device_attach(dev);
spin_unlock_irqrestore(&lp->lock, flags);
return 0;
}
static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
{
switch (rqst) {
case PM_SUSPEND:
return el3_suspend(pdev);
case PM_RESUME:
return el3_resume(pdev);
}
return 0;
}
#endif /* CONFIG_PM */
#ifdef MODULE #ifdef MODULE
/* Parameters that may be passed into the module. */ /* Parameters that may be passed into the module. */
static int debug = -1; static int debug = -1;
...@@ -1122,7 +1233,7 @@ init_module(void) ...@@ -1122,7 +1233,7 @@ init_module(void)
el3_debug = debug; el3_debug = debug;
el3_root_dev = NULL; el3_root_dev = NULL;
while (el3_probe(0) == 0) { while (el3_probe(0, el3_cards) == 0) {
if (irq[el3_cards] > 1) if (irq[el3_cards] > 1)
el3_root_dev->irq = irq[el3_cards]; el3_root_dev->irq = irq[el3_cards];
if (xcvr[el3_cards] >= 0) if (xcvr[el3_cards] >= 0)
...@@ -1145,6 +1256,11 @@ cleanup_module(void) ...@@ -1145,6 +1256,11 @@ cleanup_module(void)
if(lp->mca_slot!=-1) if(lp->mca_slot!=-1)
mca_mark_as_unused(lp->mca_slot); mca_mark_as_unused(lp->mca_slot);
#endif #endif
#ifdef CONFIG_PM
if (lp->pmdev)
pm_unregister(lp->pmdev);
#endif
next_dev = lp->next_dev; next_dev = lp->next_dev;
unregister_netdev(el3_root_dev); unregister_netdev(el3_root_dev);
release_region(el3_root_dev->base_addr, EL3_IO_EXTENT); release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
......
...@@ -54,19 +54,19 @@ ...@@ -54,19 +54,19 @@
#define NE_BASE (dev->base_addr) #define NE_BASE (dev->base_addr)
#define NE_CMD 0x00 #define NE_CMD 0x00
#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */
#define NE_RESET 0x1f+GAYLE_ODD /* Issue a read to reset, a write to clear. */ #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */
#define NE_IO_EXTENT 0x20 #define NE_IO_EXTENT 0x20
#define NE_EN0_ISR 0x07+GAYLE_ODD #define NE_EN0_ISR 0x07
#define NE_EN0_DCFG 0x0e #define NE_EN0_DCFG 0x0e
#define NE_EN0_RSARLO 0x08 #define NE_EN0_RSARLO 0x08
#define NE_EN0_RSARHI 0x09+GAYLE_ODD #define NE_EN0_RSARHI 0x09
#define NE_EN0_RCNTLO 0x0a #define NE_EN0_RCNTLO 0x0a
#define NE_EN0_RXCR 0x0c #define NE_EN0_RXCR 0x0c
#define NE_EN0_TXCR 0x0d+GAYLE_ODD #define NE_EN0_TXCR 0x0d
#define NE_EN0_RCNTHI 0x0b+GAYLE_ODD #define NE_EN0_RCNTHI 0x0b
#define NE_EN0_IMR 0x0f+GAYLE_ODD #define NE_EN0_IMR 0x0f
#define NE1SM_START_PG 0x20 /* First page of TX buffer */ #define NE1SM_START_PG 0x20 /* First page of TX buffer */
#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
...@@ -157,7 +157,7 @@ int __init apne_probe(struct net_device *dev) ...@@ -157,7 +157,7 @@ int __init apne_probe(struct net_device *dev)
printk("ethernet PCMCIA card inserted\n"); printk("ethernet PCMCIA card inserted\n");
if (init_pcmcia()) if (init_pcmcia())
return apne_probe1(dev, IOBASE+GAYLE_IO); return apne_probe1(dev, IOBASE);
else else
return (-ENODEV); return (-ENODEV);
...@@ -174,11 +174,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) ...@@ -174,11 +174,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
int neX000, ctron; int neX000, ctron;
#endif #endif
static unsigned version_printed; static unsigned version_printed;
static u32 pcmcia_offsets[16]={
0, 1+GAYLE_ODD, 2, 3+GAYLE_ODD,
4, 5+GAYLE_ODD, 6, 7+GAYLE_ODD,
8, 9+GAYLE_ODD, 0xa, 0xb+GAYLE_ODD,
0xc, 0xd+GAYLE_ODD, 0xe, 0xf+GAYLE_ODD };
if (ei_debug && version_printed++ == 0) if (ei_debug && version_printed++ == 0)
printk(version); printk(version);
...@@ -188,15 +183,15 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) ...@@ -188,15 +183,15 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
/* Reset card. Who knows what dain-bramaged state it was left in. */ /* Reset card. Who knows what dain-bramaged state it was left in. */
{ unsigned long reset_start_time = jiffies; { unsigned long reset_start_time = jiffies;
writeb(readb(ioaddr + NE_RESET), ioaddr + NE_RESET); outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
while ((readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
if (jiffies - reset_start_time > 2*HZ/100) { if (jiffies - reset_start_time > 2*HZ/100) {
printk(" not found (no reset ack).\n"); printk(" not found (no reset ack).\n");
return -ENODEV; return -ENODEV;
} }
writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ outb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */
} }
#ifndef MANUAL_HWADDR0 #ifndef MANUAL_HWADDR0
...@@ -222,13 +217,13 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) ...@@ -222,13 +217,13 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
{E8390_RREAD+E8390_START, NE_CMD}, {E8390_RREAD+E8390_START, NE_CMD},
}; };
for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) { for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
writeb(program_seq[i].value, ioaddr + program_seq[i].offset); outb(program_seq[i].value, ioaddr + program_seq[i].offset);
} }
} }
for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
SA_prom[i] = readb(ioaddr + NE_DATAPORT); SA_prom[i] = inb(ioaddr + NE_DATAPORT);
SA_prom[i+1] = readb(ioaddr + NE_DATAPORT); SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
if (SA_prom[i] != SA_prom[i+1]) if (SA_prom[i] != SA_prom[i+1])
wordlength = 1; wordlength = 1;
} }
...@@ -244,7 +239,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) ...@@ -244,7 +239,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
if (wordlength == 2) { if (wordlength == 2) {
/* We must set the 8390 for word mode. */ /* We must set the 8390 for word mode. */
writeb(0x49, ioaddr + NE_EN0_DCFG); outb(0x49, ioaddr + NE_EN0_DCFG);
start_page = NESM_START_PG; start_page = NESM_START_PG;
stop_page = NESM_STOP_PG; stop_page = NESM_STOP_PG;
} else { } else {
...@@ -271,7 +266,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) ...@@ -271,7 +266,7 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
#else #else
wordlength = 2; wordlength = 2;
/* We must set the 8390 for word mode. */ /* We must set the 8390 for word mode. */
writeb(0x49, ioaddr + NE_EN0_DCFG); outb(0x49, ioaddr + NE_EN0_DCFG);
start_page = NESM_START_PG; start_page = NESM_START_PG;
stop_page = NESM_STOP_PG; stop_page = NESM_STOP_PG;
...@@ -314,7 +309,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr) ...@@ -314,7 +309,6 @@ static int __init apne_probe1(struct net_device *dev, int ioaddr)
ei_status.block_input = &apne_block_input; ei_status.block_input = &apne_block_input;
ei_status.block_output = &apne_block_output; ei_status.block_output = &apne_block_output;
ei_status.get_8390_hdr = &apne_get_8390_hdr; ei_status.get_8390_hdr = &apne_get_8390_hdr;
ei_status.reg_offset = pcmcia_offsets;
dev->open = &apne_open; dev->open = &apne_open;
dev->stop = &apne_close; dev->stop = &apne_close;
NS8390_init(dev, 0); NS8390_init(dev, 0);
...@@ -354,18 +348,18 @@ apne_reset_8390(struct net_device *dev) ...@@ -354,18 +348,18 @@ apne_reset_8390(struct net_device *dev)
if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies); if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
writeb(readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
ei_status.txing = 0; ei_status.txing = 0;
ei_status.dmaing = 0; ei_status.dmaing = 0;
/* This check _should_not_ be necessary, omit eventually. */ /* This check _should_not_ be necessary, omit eventually. */
while ((readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
if (jiffies - reset_start_time > 2*HZ/100) { if (jiffies - reset_start_time > 2*HZ/100) {
printk("%s: ne_reset_8390() did not complete.\n", dev->name); printk("%s: ne_reset_8390() did not complete.\n", dev->name);
break; break;
} }
writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */ outb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */
} }
/* Grab the 8390 specific header. Similar to the block_input routine, but /* Grab the 8390 specific header. Similar to the block_input routine, but
...@@ -390,25 +384,25 @@ apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pa ...@@ -390,25 +384,25 @@ apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pa
} }
ei_status.dmaing |= 0x01; ei_status.dmaing |= 0x01;
writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
writeb(ENISR_RDC, nic_base + NE_EN0_ISR); outb(ENISR_RDC, nic_base + NE_EN0_ISR);
writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
writeb(0, nic_base + NE_EN0_RCNTHI); outb(0, nic_base + NE_EN0_RCNTHI);
writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ outb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */
writeb(ring_page, nic_base + NE_EN0_RSARHI); outb(ring_page, nic_base + NE_EN0_RSARHI);
writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
if (ei_status.word16) { if (ei_status.word16) {
ptrs = (short*)hdr; ptrs = (short*)hdr;
for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++) for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
*ptrs++ = readw(NE_BASE + NE_DATAPORT); *ptrs++ = inw(NE_BASE + NE_DATAPORT);
} else { } else {
ptrc = (char*)hdr; ptrc = (char*)hdr;
for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++) for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++)
*ptrc++ = readb(NE_BASE + NE_DATAPORT); *ptrc++ = inb(NE_BASE + NE_DATAPORT);
} }
writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
hdr->count = WORDSWAP(hdr->count); hdr->count = WORDSWAP(hdr->count);
...@@ -418,7 +412,7 @@ apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pa ...@@ -418,7 +412,7 @@ apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pa
/* Block input and output, similar to the Crynwr packet driver. If you /* Block input and output, similar to the Crynwr packet driver. If you
are porting to a new ethercard, look at the packet driver source for hints. are porting to a new ethercard, look at the packet driver source for hints.
The NEx000 doesn't share the on-board packet memory -- you have to put The NEx000 doesn't share the on-board packet memory -- you have to put
the packet out through the "remote DMA" dataport using writeb. */ the packet out through the "remote DMA" dataport using outb. */
static void static void
apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
...@@ -437,27 +431,27 @@ apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int rin ...@@ -437,27 +431,27 @@ apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int rin
return; return;
} }
ei_status.dmaing |= 0x01; ei_status.dmaing |= 0x01;
writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
writeb(ENISR_RDC, nic_base + NE_EN0_ISR); outb(ENISR_RDC, nic_base + NE_EN0_ISR);
writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
writeb(count >> 8, nic_base + NE_EN0_RCNTHI); outb(count >> 8, nic_base + NE_EN0_RCNTHI);
writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
if (ei_status.word16) { if (ei_status.word16) {
ptrs = (short*)buf; ptrs = (short*)buf;
for (cnt = 0; cnt < (count>>1); cnt++) for (cnt = 0; cnt < (count>>1); cnt++)
*ptrs++ = readw(NE_BASE + NE_DATAPORT); *ptrs++ = inw(NE_BASE + NE_DATAPORT);
if (count & 0x01) { if (count & 0x01) {
buf[count-1] = readb(NE_BASE + NE_DATAPORT); buf[count-1] = inb(NE_BASE + NE_DATAPORT);
} }
} else { } else {
ptrc = (char*)buf; ptrc = (char*)buf;
for (cnt = 0; cnt < count; cnt++) for (cnt = 0; cnt < count; cnt++)
*ptrc++ = readb(NE_BASE + NE_DATAPORT); *ptrc++ = inb(NE_BASE + NE_DATAPORT);
} }
writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01; ei_status.dmaing &= ~0x01;
} }
...@@ -486,30 +480,30 @@ apne_block_output(struct net_device *dev, int count, ...@@ -486,30 +480,30 @@ apne_block_output(struct net_device *dev, int count,
} }
ei_status.dmaing |= 0x01; ei_status.dmaing |= 0x01;
/* We should already be in page 0, but to be safe... */ /* We should already be in page 0, but to be safe... */
writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
writeb(ENISR_RDC, nic_base + NE_EN0_ISR); outb(ENISR_RDC, nic_base + NE_EN0_ISR);
/* Now the normal output. */ /* Now the normal output. */
writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); outb(count & 0xff, nic_base + NE_EN0_RCNTLO);
writeb(count >> 8, nic_base + NE_EN0_RCNTHI); outb(count >> 8, nic_base + NE_EN0_RCNTHI);
writeb(0x00, nic_base + NE_EN0_RSARLO); outb(0x00, nic_base + NE_EN0_RSARLO);
writeb(start_page, nic_base + NE_EN0_RSARHI); outb(start_page, nic_base + NE_EN0_RSARHI);
writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
if (ei_status.word16) { if (ei_status.word16) {
ptrs = (short*)buf; ptrs = (short*)buf;
for (cnt = 0; cnt < count>>1; cnt++) for (cnt = 0; cnt < count>>1; cnt++)
writew(*ptrs++, NE_BASE+NE_DATAPORT); outw(*ptrs++, NE_BASE+NE_DATAPORT);
} else { } else {
ptrc = (char*)buf; ptrc = (char*)buf;
for (cnt = 0; cnt < count; cnt++) for (cnt = 0; cnt < count; cnt++)
writeb(*ptrc++, NE_BASE + NE_DATAPORT); outb(*ptrc++, NE_BASE + NE_DATAPORT);
} }
dma_start = jiffies; dma_start = jiffies;
while ((readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
if (jiffies - dma_start > 2*HZ/100) { /* 20ms */ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
printk("%s: timeout waiting for Tx RDC.\n", dev->name); printk("%s: timeout waiting for Tx RDC.\n", dev->name);
apne_reset_8390(dev); apne_reset_8390(dev);
...@@ -517,7 +511,7 @@ apne_block_output(struct net_device *dev, int count, ...@@ -517,7 +511,7 @@ apne_block_output(struct net_device *dev, int count,
break; break;
} }
writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
ei_status.dmaing &= ~0x01; ei_status.dmaing &= ~0x01;
return; return;
} }
...@@ -611,7 +605,9 @@ static int init_pcmcia(void) ...@@ -611,7 +605,9 @@ static int init_pcmcia(void)
} }
#endif #endif
writeb(config, GAYLE_ATTRIBUTE+offset); out_8(GAYLE_ATTRIBUTE+offset, config);
return 1; return 1;
} }
MODULE_LICENSE("GPL");
...@@ -1153,9 +1153,7 @@ dgrs_probe1(struct net_device *dev) ...@@ -1153,9 +1153,7 @@ dgrs_probe1(struct net_device *dev)
*/ */
rc = dgrs_download(dev); rc = dgrs_download(dev);
if (rc) if (rc)
{ goto err_out;
return rc;
}
/* /*
* Get ether address of board * Get ether address of board
...@@ -1169,7 +1167,8 @@ dgrs_probe1(struct net_device *dev) ...@@ -1169,7 +1167,8 @@ dgrs_probe1(struct net_device *dev)
if (dev->dev_addr[0] & 1) if (dev->dev_addr[0] & 1)
{ {
printk("%s: Illegal Ethernet Address\n", dev->name); printk("%s: Illegal Ethernet Address\n", dev->name);
return (-ENXIO); rc = -ENXIO;
goto err_out;
} }
/* /*
...@@ -1178,9 +1177,10 @@ dgrs_probe1(struct net_device *dev) ...@@ -1178,9 +1177,10 @@ dgrs_probe1(struct net_device *dev)
*/ */
if (priv->plxreg) if (priv->plxreg)
OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1); OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1);
rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev); rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev);
if (rc) if (rc)
return (rc); goto err_out;
priv->intrcnt = 0; priv->intrcnt = 0;
for (i = jiffies + 2*HZ + HZ/2; time_after(i, jiffies); ) for (i = jiffies + 2*HZ + HZ/2; time_after(i, jiffies); )
...@@ -1191,15 +1191,21 @@ dgrs_probe1(struct net_device *dev) ...@@ -1191,15 +1191,21 @@ dgrs_probe1(struct net_device *dev)
} }
if (priv->intrcnt < 2) if (priv->intrcnt < 2)
{ {
printk("%s: Not interrupting on IRQ %d (%d)\n", printk(KERN_ERR "%s: Not interrupting on IRQ %d (%d)\n",
dev->name, dev->irq, priv->intrcnt); dev->name, dev->irq, priv->intrcnt);
return (-ENXIO); rc = -ENXIO;
goto err_free_irq;
} }
/* /*
* Register the /proc/ioports information... * Register the /proc/ioports information...
*/ */
request_region(dev->base_addr, 256, "RightSwitch"); if (!request_region(dev->base_addr, 256, "RightSwitch")) {
printk(KERN_ERR "%s: io 0x%3lX, which is busy.\n", dev->name,
dev->base_addr);
rc = -EBUSY;
goto err_free_irq;
}
/* /*
* Entry points... * Entry points...
...@@ -1211,7 +1217,12 @@ dgrs_probe1(struct net_device *dev) ...@@ -1211,7 +1217,12 @@ dgrs_probe1(struct net_device *dev)
dev->set_multicast_list = &dgrs_set_multicast_list; dev->set_multicast_list = &dgrs_set_multicast_list;
dev->do_ioctl = &dgrs_ioctl; dev->do_ioctl = &dgrs_ioctl;
return (0); return rc;
err_free_irq:
free_irq(dev->irq, dev);
err_out:
return rc;
} }
int __init int __init
......
...@@ -75,13 +75,13 @@ static inline void netif_start_queue(struct net_device *dev) ...@@ -75,13 +75,13 @@ static inline void netif_start_queue(struct net_device *dev)
#define rr_mark_net_bh(foo) mark_bh(foo) #define rr_mark_net_bh(foo) mark_bh(foo)
#define rr_if_busy(dev) dev->tbusy #define rr_if_busy(dev) dev->tbusy
#define rr_if_running(dev) dev->start /* Currently unused. */ #define rr_if_running(dev) dev->start /* Currently unused. */
#define rr_if_down(dev) {do{dev->start = 0;}while (0);} #define rr_if_down(dev) do { dev->start = 0; } while (0)
#else #else
#define NET_BH 0 #define NET_BH 0
#define rr_mark_net_bh(foo) {do{} while(0);} #define rr_mark_net_bh(foo) do { } while(0)
#define rr_if_busy(dev) netif_queue_stopped(dev) #define rr_if_busy(dev) netif_queue_stopped(dev)
#define rr_if_running(dev) netif_running(dev) #define rr_if_running(dev) netif_running(dev)
#define rr_if_down(dev) {do{} while(0);} #define rr_if_down(dev) do { } while(0)
#endif #endif
#include "rrunner.h" #include "rrunner.h"
......
/* $Id: sgiseeq.c,v 1.17 2000/03/27 23:02:57 ralf Exp $ /*
*
* sgiseeq.c: Seeq8003 ethernet driver for SGI machines. * sgiseeq.c: Seeq8003 ethernet driver for SGI machines.
* *
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -450,20 +450,22 @@ static int sgiseeq_open(struct net_device *dev) ...@@ -450,20 +450,22 @@ static int sgiseeq_open(struct net_device *dev)
unsigned long flags; unsigned long flags;
int err; int err;
save_flags(flags); cli(); __save_and_cli(flags);
if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, (void *) dev)) {
err = -EAGAIN;
if (request_irq(dev->irq, sgiseeq_interrupt, 0, sgiseeqstr, dev)) {
printk("Seeq8003: Can't get irq %d\n", dev->irq); printk("Seeq8003: Can't get irq %d\n", dev->irq);
restore_flags(flags); goto out;
return -EAGAIN;
} }
err = init_seeq(dev, sp, sregs); err = init_seeq(dev, sp, sregs);
if (err) if (err)
return err; goto out;
netif_start_queue(dev); netif_start_queue(dev);
restore_flags(flags);
return 0; out:
__restore_flags(flags);
return err;
} }
static int sgiseeq_close(struct net_device *dev) static int sgiseeq_close(struct net_device *dev)
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
*/ */
static char *version = "sun3lance.c: v1.1 11/17/1999 Sam Creasey (sammy@oh.verio.com)\n"; static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.net)\n";
#include <linux/module.h> #include <linux/module.h>
...@@ -35,16 +35,24 @@ static char *version = "sun3lance.c: v1.1 11/17/1999 Sam Creasey (sammy@oh.veri ...@@ -35,16 +35,24 @@ static char *version = "sun3lance.c: v1.1 11/17/1999 Sam Creasey (sammy@oh.veri
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/delay.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/idprom.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/sun3mmu.h> #include <asm/pgalloc.h>
#include <asm/dvma.h> #include <asm/dvma.h>
#include <asm/idprom.h>
#include <asm/machines.h>
#ifdef CONFIG_SUN3
#include <asm/sun3mmu.h>
#else
#include <asm/sun3xprom.h>
#endif
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
...@@ -62,7 +70,7 @@ static char *version = "sun3lance.c: v1.1 11/17/1999 Sam Creasey (sammy@oh.veri ...@@ -62,7 +70,7 @@ static char *version = "sun3lance.c: v1.1 11/17/1999 Sam Creasey (sammy@oh.veri
* 3 = debug, print even more debug infos (packet data) * 3 = debug, print even more debug infos (packet data)
*/ */
#define LANCE_DEBUG 1 #define LANCE_DEBUG 0
#ifdef LANCE_DEBUG #ifdef LANCE_DEBUG
static int lance_debug = LANCE_DEBUG; static int lance_debug = LANCE_DEBUG;
...@@ -139,7 +147,7 @@ struct lance_memory { ...@@ -139,7 +147,7 @@ struct lance_memory {
struct lance_tx_head tx_head[TX_RING_SIZE]; struct lance_tx_head tx_head[TX_RING_SIZE];
struct lance_rx_head rx_head[RX_RING_SIZE]; struct lance_rx_head rx_head[RX_RING_SIZE];
char rx_data[RX_RING_SIZE][PKT_BUF_SZ]; char rx_data[RX_RING_SIZE][PKT_BUF_SZ];
char tx_data[RX_RING_SIZE][PKT_BUF_SZ]; char tx_data[TX_RING_SIZE][PKT_BUF_SZ];
}; };
/* The driver's private device structure */ /* The driver's private device structure */
...@@ -247,15 +255,27 @@ int __init sun3lance_probe( struct net_device *dev ) ...@@ -247,15 +255,27 @@ int __init sun3lance_probe( struct net_device *dev )
{ {
static int found; static int found;
/* check that this machine has an onboard lance */
switch(idprom->id_machtype) {
case SM_SUN3|SM_3_50:
case SM_SUN3|SM_3_60:
case SM_SUN3X|SM_3_80:
/* these machines have lance */
break;
default:
return(-ENODEV);
}
if(found) if(found)
return(ENODEV); return(-ENODEV);
if (lance_probe(dev)) { if (lance_probe(dev)) {
found = 1; found = 1;
return( 0 ); return( 0 );
} }
return( ENODEV ); return( -ENODEV );
} }
static int __init lance_probe( struct net_device *dev) static int __init lance_probe( struct net_device *dev)
...@@ -269,6 +289,7 @@ static int __init lance_probe( struct net_device *dev) ...@@ -269,6 +289,7 @@ static int __init lance_probe( struct net_device *dev)
volatile unsigned short *ioaddr_probe; volatile unsigned short *ioaddr_probe;
unsigned short tmp1, tmp2; unsigned short tmp1, tmp2;
#ifdef CONFIG_SUN3
/* LANCE_OBIO can be found within the IO pmeg with some effort */ /* LANCE_OBIO can be found within the IO pmeg with some effort */
for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 + for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 +
SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) { SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) {
...@@ -286,6 +307,9 @@ static int __init lance_probe( struct net_device *dev) ...@@ -286,6 +307,9 @@ static int __init lance_probe( struct net_device *dev)
if(!found) if(!found)
return 0; return 0;
#else
ioaddr = SUN3X_LANCE;
#endif
/* test to see if there's really a lance here */ /* test to see if there's really a lance here */
/* (CSRO_INIT shouldn't be readable) */ /* (CSRO_INIT shouldn't be readable) */
...@@ -311,8 +335,9 @@ static int __init lance_probe( struct net_device *dev) ...@@ -311,8 +335,9 @@ static int __init lance_probe( struct net_device *dev)
return 0; return 0;
} }
lp = (struct lance_private *)dev->priv; lp = (struct lance_private *)dev->priv;
MEM = (struct lance_memory *)sun3_dvma_malloc(sizeof(struct
lance_memory)); MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
lp->iobase = (volatile unsigned short *)ioaddr; lp->iobase = (volatile unsigned short *)ioaddr;
dev->base_addr = (unsigned long)ioaddr; /* informational only */ dev->base_addr = (unsigned long)ioaddr; /* informational only */
...@@ -346,20 +371,19 @@ static int __init lance_probe( struct net_device *dev) ...@@ -346,20 +371,19 @@ static int __init lance_probe( struct net_device *dev)
MEM->init.mode = 0x0000; MEM->init.mode = 0x0000;
MEM->init.filter[0] = 0x00000000; MEM->init.filter[0] = 0x00000000;
MEM->init.filter[1] = 0x00000000; MEM->init.filter[1] = 0x00000000;
MEM->init.rdra = sun3_dvma_vtop(MEM->rx_head); MEM->init.rdra = dvma_vtob(MEM->rx_head);
MEM->init.rlen = (RX_LOG_RING_SIZE << 13) | MEM->init.rlen = (RX_LOG_RING_SIZE << 13) |
(sun3_dvma_vtop(MEM->rx_head) >> 16); (dvma_vtob(MEM->rx_head) >> 16);
MEM->init.tdra = sun3_dvma_vtop(MEM->tx_head); MEM->init.tdra = dvma_vtob(MEM->tx_head);
MEM->init.tlen = (TX_LOG_RING_SIZE << 13) | MEM->init.tlen = (TX_LOG_RING_SIZE << 13) |
(sun3_dvma_vtop(MEM->tx_head) >> 16); (dvma_vtob(MEM->tx_head) >> 16);
DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n", DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
sun3_dvma_vtop(&(MEM->init)), sun3_dvma_vtop(MEM->rx_head), dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
(sun3_dvma_vtop(MEM->tx_head)))); (dvma_vtob(MEM->tx_head))));
if (did_version++ == 0) if (did_version++ == 0)
DPRINTK( 1, ( version )); printk( version );
/* The LANCE-specific entries in the device structure. */ /* The LANCE-specific entries in the device structure. */
dev->open = &lance_open; dev->open = &lance_open;
...@@ -386,16 +410,8 @@ static int lance_open( struct net_device *dev ) ...@@ -386,16 +410,8 @@ static int lance_open( struct net_device *dev )
REGA(CSR0) = CSR0_STOP; REGA(CSR0) = CSR0_STOP;
/* tell the lance the address of its init block */
REGA(CSR1) = sun3_dvma_vtop(&(MEM->init));
REGA(CSR2) = sun3_dvma_vtop(&(MEM->init)) >> 16;
lance_init_ring(dev); lance_init_ring(dev);
/* Re-initialize the LANCE, and start it when done. */
REGA(CSR3) = CSR3_BSWP;
/* From now on, AREG is kept to point to CSR0 */ /* From now on, AREG is kept to point to CSR0 */
REGA(CSR0) = CSR0_INIT; REGA(CSR0) = CSR0_INIT;
...@@ -434,23 +450,52 @@ static void lance_init_ring( struct net_device *dev ) ...@@ -434,23 +450,52 @@ static void lance_init_ring( struct net_device *dev )
lp->old_rx = lp->old_tx = 0; lp->old_rx = lp->old_tx = 0;
for( i = 0; i < TX_RING_SIZE; i++ ) { for( i = 0; i < TX_RING_SIZE; i++ ) {
MEM->tx_head[i].base = sun3_dvma_vtop(MEM->tx_data[i]); MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
MEM->tx_head[i].flag = 0; MEM->tx_head[i].flag = 0;
MEM->tx_head[i].base_hi = MEM->tx_head[i].base_hi =
(sun3_dvma_vtop(MEM->tx_data[i])) >>16; (dvma_vtob(MEM->tx_data[i])) >>16;
MEM->tx_head[i].length = 0; MEM->tx_head[i].length = 0;
MEM->tx_head[i].misc = 0; MEM->tx_head[i].misc = 0;
} }
for( i = 0; i < RX_RING_SIZE; i++ ) { for( i = 0; i < RX_RING_SIZE; i++ ) {
MEM->rx_head[i].base = sun3_dvma_vtop(MEM->rx_data[i]); MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]);
MEM->rx_head[i].flag = TMD1_OWN_CHIP; MEM->rx_head[i].flag = RMD1_OWN_CHIP;
MEM->rx_head[i].base_hi = MEM->rx_head[i].base_hi =
(sun3_dvma_vtop(MEM->rx_data[i])) >> 16; (dvma_vtob(MEM->rx_data[i])) >> 16;
MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000; MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
MEM->rx_head[i].msg_length = 0; MEM->rx_head[i].msg_length = 0;
} }
/* tell the card it's ether address, bytes swapped */
MEM->init.hwaddr[0] = dev->dev_addr[1];
MEM->init.hwaddr[1] = dev->dev_addr[0];
MEM->init.hwaddr[2] = dev->dev_addr[3];
MEM->init.hwaddr[3] = dev->dev_addr[2];
MEM->init.hwaddr[4] = dev->dev_addr[5];
MEM->init.hwaddr[5] = dev->dev_addr[4];
MEM->init.mode = 0x0000;
MEM->init.filter[0] = 0x00000000;
MEM->init.filter[1] = 0x00000000;
MEM->init.rdra = dvma_vtob(MEM->rx_head);
MEM->init.rlen = (RX_LOG_RING_SIZE << 13) |
(dvma_vtob(MEM->rx_head) >> 16);
MEM->init.tdra = dvma_vtob(MEM->tx_head);
MEM->init.tlen = (TX_LOG_RING_SIZE << 13) |
(dvma_vtob(MEM->tx_head) >> 16);
/* tell the lance the address of its init block */
REGA(CSR1) = dvma_vtob(&(MEM->init));
REGA(CSR2) = dvma_vtob(&(MEM->init)) >> 16;
#ifdef CONFIG_SUN3X
REGA(CSR3) = CSR3_BSWP | CSR3_ACON | CSR3_BCON;
#else
REGA(CSR3) = CSR3_BSWP;
#endif
} }
...@@ -520,13 +565,22 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) ...@@ -520,13 +565,22 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
} }
AREG = CSR0; AREG = CSR0;
// DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n", DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
// dev->name, DREG )); dev->name, DREG ));
#ifdef CONFIG_SUN3X
/* this weirdness doesn't appear on sun3... */
if(!(DREG & CSR0_INIT)) {
DPRINTK( 1, ("INIT not set, reinitializing...\n"));
REGA( CSR0 ) = CSR0_STOP;
lance_init_ring(dev);
REGA( CSR0 ) = CSR0_INIT | CSR0_STRT;
}
#endif
/* Fill in a Tx ring entry */ /* Fill in a Tx ring entry */
#if 0 #if 0
if (lance_debug >= 3) { if (lance_debug >= 2) {
u_char *p; u_char *p;
int i; int i;
printk( "%s: TX pkt %d type 0x%04x from ", dev->name, printk( "%s: TX pkt %d type 0x%04x from ", dev->name,
...@@ -566,7 +620,10 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev ) ...@@ -566,7 +620,10 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
lp->stats.tx_bytes += skb->len; lp->stats.tx_bytes += skb->len;
/* Trigger an immediate send poll. */ /* Trigger an immediate send poll. */
REGA(CSR0) = CSR0_INEA | CSR0_TDMD; REGA(CSR0) = CSR0_INEA | CSR0_TDMD | CSR0_STRT;
AREG = CSR0;
DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
dev->name, DREG ));
dev->trans_start = jiffies; dev->trans_start = jiffies;
dev_kfree_skb( skb ); dev_kfree_skb( skb );
...@@ -599,12 +656,13 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp) ...@@ -599,12 +656,13 @@ static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
in_interrupt = 1; in_interrupt = 1;
still_more: still_more:
flush_cache_all();
AREG = CSR0; AREG = CSR0;
csr0 = DREG; csr0 = DREG;
/* ack interrupts */ /* ack interrupts */
DREG = csr0 & (CSR0_TINT | CSR0_RINT); DREG = csr0 & (CSR0_TINT | CSR0_RINT | CSR0_IDON);
/* clear errors */ /* clear errors */
if(csr0 & CSR0_ERR) if(csr0 & CSR0_ERR)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment