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

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)