patch-2.3.45 linux/drivers/net/smc9194.c
Next file: linux/drivers/net/strip.c
Previous file: linux/drivers/net/smc-mca.c
Back to the patch index
Back to the overall index
- Lines: 529
- Date:
Sat Feb 12 15:45:05 2000
- Orig file:
v2.3.44/linux/drivers/net/smc9194.c
- Orig date:
Wed Aug 18 11:36:42 1999
diff -u --recursive --new-file v2.3.44/linux/drivers/net/smc9194.c linux/drivers/net/smc9194.c
@@ -50,11 +50,8 @@
static const char *version =
"smc9194.c:v0.12 03/06/96 by Erik Stahlman (erik@vt.edu)\n";
-#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
-#endif
-
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
@@ -82,22 +79,6 @@
-------------------------------------------------------------------------*/
/*
- . this is for kernels > 1.2.70
-*/
-#define REALLY_NEW_KERNEL
-#ifndef REALLY_NEW_KERNEL
-#define free_irq( x, y ) free_irq( x )
-#define request_irq( x, y, z, u, v ) request_irq( x, y, z, u )
-#endif
-
-/*
- . Do you want to use this with old kernels.
- . WARNING: this is not well tested.
-#define SUPPORT_OLD_KERNEL
-*/
-
-
-/*
. Do you want to use 32 bit xfers? This should work on all chips, as
. the chipset is designed to accommodate them.
*/
@@ -108,9 +89,10 @@
.for a slightly different card, you can add it to the array. Keep in
.mind that the array must end in zero.
*/
-static unsigned int smc_portlist[] __initdata =
- { 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
- 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0};
+static unsigned int smc_portlist[] __initdata = {
+ 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
+ 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0
+};
/*
. Wait time for memory to be free. This probably shouldn't be
@@ -149,12 +131,6 @@
#endif
-/* the older versions of the kernel cannot support autoprobing */
-#ifdef SUPPORT_OLD_KERNEL
-#define NO_AUTOPROBE
-#endif
-
-
/*------------------------------------------------------------------------
.
. The internal workings of the driver. If you are changing anything
@@ -164,9 +140,6 @@
-------------------------------------------------------------------------*/
#define CARDNAME "SMC9194"
-#ifdef SUPPORT_OLD_KERNEL
-char kernel_version[] = UTS_RELEASE;
-#endif
/* store this information for the driver.. */
struct smc_local {
@@ -217,6 +190,11 @@
static int smc_open(struct net_device *dev);
/*
+ . Our watchdog timed out. Called by the networking layer
+*/
+static void smc_timeout(struct net_device *dev);
+
+/*
. This is called by the kernel to send a packet out into the net. it's
. responsible for doing a best-effort send, but if it's simply not possible
. to send it, the packet gets dropped.
@@ -240,12 +218,12 @@
. Finally, a call to set promiscuous mode ( for TCPDUMP and related
. programs ) and multicast modes.
*/
-#ifdef SUPPORT_OLD_KERNEL
-static void smc_set_multicast_list(struct net_device *dev, int num_addrs,
- void *addrs);
-#else
static void smc_set_multicast_list(struct net_device *dev);
-#endif
+
+/*
+ . CRC compute
+ */
+static int crc32( char * s, int length );
/*---------------------------------------------------------------
.
@@ -256,11 +234,7 @@
/*
. Handles the actual interrupt
*/
-#ifdef REALLY_NEW_KERNEL
static void smc_interrupt(int irq, void *, struct pt_regs *regs);
-#else
-static void smc_interrupt(int irq, struct pt_regs *regs);
-#endif
/*
. This is a separate procedure to handle the receipt of a packet, to
. leave the interrupt code looking slightly cleaner
@@ -321,25 +295,9 @@
/* this puts the device in an inactive state */
static void smc_shutdown( int ioaddr );
-#ifndef NO_AUTOPROBE
/* This routine will find the IRQ of the driver if one is not
. specified in the input to the device. */
static int smc_findirq( int ioaddr );
-#endif
-
-/*
- this routine will set the hardware multicast table to the specified
- values given it by the higher level routines
-*/
-#ifndef SUPPORT_OLD_KERNEL
-static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * );
-static int crc32( char *, int );
-#endif
-
-#ifdef SUPPORT_OLD_KERNEL
-extern struct net_device *init_etherdev(struct net_device *dev, int sizeof_private,
- unsigned long *mem_startp );
-#endif
/*
. Function: smc_reset( int ioaddr )
@@ -442,7 +400,6 @@
}
-#ifndef SUPPORT_OLD_KERNEL
/*
. Function: smc_setmulticast( int ioaddr, int count, dev_mc_list * adds )
. Purpose:
@@ -525,8 +482,6 @@
return crc_value;
}
-#endif
-
/*
. Function: smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * )
@@ -575,6 +530,7 @@
dev_kfree_skb (skb);
lp->saved_skb = NULL;
/* this IS an error, but, i don't want the skb saved */
+ netif_wake_queue(dev);
return 0;
}
/* either way, a packet is waiting now */
@@ -616,7 +572,7 @@
}
/* or YES! I can send the packet now.. */
smc_hardware_send_packet(dev);
-
+ netif_wake_queue(dev);
return 0;
}
@@ -663,7 +619,7 @@
printk(KERN_DEBUG CARDNAME": Memory allocation failed. \n");
kfree(skb);
lp->saved_skb = NULL;
- dev->tbusy = 0;
+ netif_wake_queue(dev);
return;
}
@@ -729,8 +685,7 @@
dev->trans_start = jiffies;
/* we can send another packet */
- dev->tbusy = 0;
-
+ netif_wake_queue(dev);
return;
}
@@ -787,7 +742,6 @@
return -ENODEV;
}
-#ifndef NO_AUTOPROBE
/*----------------------------------------------------------------------
. smc_findirq
.
@@ -860,7 +814,6 @@
/* and return what I found */
return autoirq_report( 0 );
}
-#endif
/*----------------------------------------------------------------------
. Function: smc_probe( int ioaddr )
@@ -962,14 +915,7 @@
/* see if I need to initialize the ethernet card structure */
if (dev == NULL) {
-#ifdef SUPPORT_OLD_KERNEL
-#ifndef MODULE
-/* note: the old module interface does not support this call */
- dev = init_etherdev( 0, sizeof( struct smc_local ), 0 );
-#endif
-#else
dev = init_etherdev(0, 0);
-#endif
if (dev == NULL)
return -ENOMEM;
}
@@ -1043,7 +989,6 @@
. what (s)he is doing. No checking is done!!!!
.
*/
-#ifndef NO_AUTOPROBE
if ( dev->irq < 2 ) {
int trials;
@@ -1060,13 +1005,6 @@
printk(CARDNAME": Couldn't autodetect your IRQ. Use irq=xx.\n");
return -ENODEV;
}
-#else
- if (dev->irq == 0 ) {
- printk(CARDNAME
- ": Autoprobing IRQs is not supported for old kernels.\n");
- return -ENODEV;
- }
-#endif
if (dev->irq == 2) {
/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
* or don't know which one to set.
@@ -1114,10 +1052,10 @@
dev->open = smc_open;
dev->stop = smc_close;
dev->hard_start_xmit = smc_send_packet;
+ dev->tx_timeout = smc_timeout;
+ dev->watchdog_timeo = HZ/20;
dev->get_stats = smc_query_statistics;
-#ifdef HAVE_MULTICAST
- dev->set_multicast_list = &smc_set_multicast_list;
-#endif
+ dev->set_multicast_list = smc_set_multicast_list;
return 0;
}
@@ -1174,12 +1112,7 @@
/* clear out all the junk that was put here before... */
memset(dev->priv, 0, sizeof(struct smc_local));
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-#ifdef MODULE
MOD_INC_USE_COUNT;
-#endif
/* reset the hardware */
@@ -1211,6 +1144,8 @@
address |= dev->dev_addr[ i ];
outw( address, ioaddr + ADDR0 + i );
}
+
+ netif_start_queue(dev);
return 0;
}
@@ -1220,38 +1155,29 @@
. skeleton.c, from Becker.
.--------------------------------------------------------
*/
+
+static void smc_timeout(struct net_device *dev)
+{
+ /* If we get here, some higher level has decided we are broken.
+ There should really be a "kick me" function call instead. */
+ printk(KERN_WARNING CARDNAME": transmit timed out, %s?\n",
+ tx_done(dev) ? "IRQ conflict" :
+ "network cable problem");
+ /* "kick" the adaptor */
+ smc_reset( dev->base_addr );
+ smc_enable( dev->base_addr );
+ dev->trans_start = jiffies;
+ /* clear anything saved */
+ ((struct smc_local *)dev->priv)->saved_skb = NULL;
+ netif_wake_queue(dev);
+}
+
static int smc_send_packet(struct sk_buff *skb, struct net_device *dev)
{
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- printk(KERN_WARNING CARDNAME": transmit timed out, %s?\n",
- tx_done(dev) ? "IRQ conflict" :
- "network cable problem");
- /* "kick" the adaptor */
- smc_reset( dev->base_addr );
- smc_enable( dev->base_addr );
-
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- /* clear anything saved */
- ((struct smc_local *)dev->priv)->saved_skb = NULL;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- printk(KERN_WARNING CARDNAME": Transmitter access conflict.\n");
- dev_kfree_skb (skb);
- } else {
- /* Well, I want to send the packet.. but I don't know
- if I can send it right now... */
- return smc_wait_to_send_packet( skb, dev );
- }
- return 0;
+ netif_stop_queue(dev);
+ /* Well, I want to send the packet.. but I don't know
+ if I can send it right now... */
+ return smc_wait_to_send_packet( skb, dev );
}
/*--------------------------------------------------------------------
@@ -1266,11 +1192,8 @@
. and finally restore state.
.
---------------------------------------------------------------------*/
-#ifdef REALLY_NEW_KERNEL
+
static void smc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
-#else
-static void smc_interrupt(int irq, struct pt_regs * regs)
-#endif
{
struct net_device *dev = dev_id;
int ioaddr = dev->base_addr;
@@ -1288,20 +1211,6 @@
PRINTK3((CARDNAME": SMC interrupt started \n"));
- if (dev == NULL) {
- printk(KERN_WARNING CARDNAME": irq %d for unknown device.\n",
- irq);
- return;
- }
-
-/* will Linux let this happen ?? If not, this costs some speed */
- if ( dev->interrupt ) {
- printk(KERN_WARNING CARDNAME": interrupt inside interrupt.\n");
- return;
- }
-
- dev->interrupt = 1;
-
saved_bank = inw( ioaddr + BANK_SELECT );
SMC_SELECT_BANK(2);
@@ -1346,12 +1255,7 @@
lp->stats.collisions += card_stats & 0xF;
/* these are for when linux supports these statistics */
-#if 0
- card_stats >>= 4;
- /* deferred */
- card_stats >>= 4;
- /* excess deferred */
-#endif
+
SMC_SELECT_BANK( 2 );
PRINTK2((KERN_WARNING CARDNAME
": TX_BUFFER_EMPTY handled\n"));
@@ -1372,8 +1276,8 @@
mask |= ( IM_TX_EMPTY_INT | IM_TX_INT );
/* and let the card send more packets to me */
- mark_bh( NET_BH );
-
+ netif_wake_queue(dev);
+
PRINTK2((CARDNAME": Handoff done successfully.\n"));
} else if (status & IM_RX_OVRN_INT ) {
lp->stats.rx_errors++;
@@ -1397,7 +1301,6 @@
SMC_SELECT_BANK( saved_bank );
- dev->interrupt = 0;
PRINTK3((CARDNAME ": Interrupt done\n"));
return;
}
@@ -1462,11 +1365,7 @@
if ( status & RS_MULTICAST )
lp->stats.multicast++;
-#ifdef SUPPORT_OLD_KERNEL
- skb = alloc_skb( packet_length + 5, GFP_ATOMIC );
-#else
skb = dev_alloc_skb( packet_length + 5);
-#endif
if ( skb == NULL ) {
printk(KERN_NOTICE CARDNAME
@@ -1478,18 +1377,12 @@
! This should work without alignment, but it could be
! in the worse case
*/
-#ifndef SUPPORT_OLD_KERNEL
- /* TODO: Should I use 32bit alignment here ? */
+
skb_reserve( skb, 2 ); /* 16 bit alignment */
-#endif
skb->dev = dev;
-#ifdef SUPPORT_OLD_KERNEL
- skb->len = packet_length;
- data = skb->data;
-#else
data = skb_put( skb, packet_length);
-#endif
+
#ifdef USE_32_BIT
/* QUESTION: Like in the TX routine, do I want
to send the DWORDs or the bytes first, or some
@@ -1516,9 +1409,7 @@
print_packet( data, packet_length );
#endif
-#ifndef SUPPORT_OLD_KERNEL
skb->protocol = eth_type_trans(skb, dev );
-#endif
netif_rx(skb);
lp->stats.rx_packets++;
} else {
@@ -1616,17 +1507,12 @@
-----------------------------------------------------*/
static int smc_close(struct net_device *dev)
{
- dev->tbusy = 1;
- dev->start = 0;
-
+ netif_stop_queue(dev);
/* clear everything */
smc_shutdown( dev->base_addr );
/* Update the statistics here. */
-#ifdef MODULE
MOD_DEC_USE_COUNT;
-#endif
-
return 0;
}
@@ -1648,21 +1534,12 @@
. promiscuous mode ( for TCPDUMP and cousins ) or accept
. a select set of multicast packets
*/
-#ifdef SUPPORT_OLD_KERNEL
-static void smc_set_multicast_list( struct net_device * dev,
- int num_addrs, void * addrs )
-#else
static void smc_set_multicast_list(struct net_device *dev)
-#endif
{
short ioaddr = dev->base_addr;
SMC_SELECT_BANK(0);
-#ifdef SUPPORT_OLD_KERNEL
- if ( num_addrs < 0 )
-#else
if ( dev->flags & IFF_PROMISC )
-#endif
outw( inw(ioaddr + RCR ) | RCR_PROMISC, ioaddr + RCR );
/* BUG? I never disable promiscuous mode if multicasting was turned on.
@@ -1674,27 +1551,12 @@
I don't need to zero the multicast table, because the flag is
checked before the table is
*/
-#ifdef SUPPORT_OLD_KERNEL
- else if ( num_addrs > 20 ) /* arbitrary constant */
-#else
else if (dev->flags & IFF_ALLMULTI)
-#endif
outw( inw(ioaddr + RCR ) | RCR_ALMUL, ioaddr + RCR );
/* We just get all multicast packets even if we only want them
. from one source. This will be changed at some future
. point. */
-#ifdef SUPPORT_OLD_KERNEL
- else if (num_addrs > 0 ) {
-/* the old kernel support will not have hardware multicast support. It would
- involve more kludges, and make the multicast setting code even worse.
- Instead, just use the ALMUL method. This is reasonable, considering that
- it is seldom used
-*/
- outw( inw( ioaddr + RCR ) & ~RCR_PROMISC, ioaddr + RCR );
- outw( inw( ioadddr + RCR ) | RCR_ALMUL, ioadddr + RCR );
- }
-#else
else if (dev->mc_count ) {
/* support hardware multicasting */
@@ -1705,7 +1567,6 @@
last thing called. The bank is set to zero at the top */
smc_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
}
-#endif
else {
outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
ioaddr + RCR );
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)