patch-2.2.15 linux/drivers/net/olympic.c

Next file: linux/drivers/net/olympic.h
Previous file: linux/drivers/net/lmc/lmc_ver.h
Back to the patch index
Back to the overall index

diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/net/olympic.c linux/drivers/net/olympic.c
@@ -22,10 +22,10 @@
  *
  *  6/8/99  - Official Release 0.2.0   
  *            Merged into the kernel code 
- *  
- *  To Do:
  *
- *  Sanitize for smp
+ *  3/10/00 - Enabled FDX and fixed bugs produced thereafter.
+ *  	      Put in smp code 
+ *  To Do:
  *
  *  If Problems do Occur
  *  Most problems can be rectified by either closing and opening the interface
@@ -71,6 +71,7 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
+#include <asm/spinlock.h>
 
 #include "olympic.h"
 
@@ -83,7 +84,7 @@
  */
 
 static char *version = 
-"Olympic.c v0.2.0 6/8/99 - Peter De Schrijver & Mike Phillips" ; 
+"Olympic.c v0.4.0 3/10/00 - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
 				   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -245,6 +246,8 @@
 		}
 	}
 
+	spin_lock_init(&olympic_priv->olympic_lock) ; 
+
 #if OLYMPIC_DEBUG
 	printk("BCTL: %x\n",readl(olympic_mmio+BCTL));
 	printk("GPR: %x\n",readw(olympic_mmio+GPR));
@@ -393,7 +396,7 @@
 #if OLYMPIC_NETWORK_MONITOR
 		writew(ntohs(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON),init_srb+8);
 #else
-		writew(OPEN_ADAPTER_ENABLE_FDX,init_srb+8);
+		writew(ntohs(OPEN_ADAPTER_ENABLE_FDX),init_srb+8);
 #endif		
 
 		if (olympic_priv->olympic_laa[0]) {
@@ -751,6 +754,8 @@
 	if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ 
 		return ;
 
+	spin_lock(&olympic_priv->olympic_lock);
+
 	if (dev->interrupt) 
 		printk(KERN_WARNING "%s: Re-entering interrupt \n",dev->name) ; 
 
@@ -830,17 +835,22 @@
 
 	writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
 
+	spin_unlock(&olympic_priv->olympic_lock) ; 
+
 }	
 
 static int olympic_xmit(struct sk_buff *skb, struct device *dev) 
 {
 	struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv;
-    __u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	__u8 *olympic_mmio=olympic_priv->olympic_mmio;
+	unsigned long flags ; 
 
 	if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
 		return 1;
 	}
 
+	spin_lock_irqsave(&olympic_priv->olympic_lock, flags) ; 
+
 	if(olympic_priv->free_tx_ring_entries) {
 		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer=virt_to_bus(skb->data);
 		olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length=skb->len | (0x80000000);
@@ -854,11 +864,12 @@
 		writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
 
 		dev->tbusy=0;		
-
+		spin_unlock_irqrestore(&olympic_priv->olympic_lock, flags) ; 
 		return 0;
-	} else 
+	} else {
+		spin_unlock_irqrestore(&olympic_priv->olympic_lock, flags) ; 
 		return 1;
-
+	}	
 }
 	
 
@@ -939,9 +950,9 @@
 	options = olympic_priv->olympic_copy_all_options; 
 
 	if (dev->flags&IFF_PROMISC)  
-		options |= (3<<5) ; /* All LLC and MAC frames, all through the main rx channel */  
+		options |= 0x61 ; 
 	else
-		options &= ~(3<<5) ; 
+		options &= ~0x61 ; 
 
 	if (dev->mc_count) {  
 		set_mc_list = 1 ; 
@@ -1216,7 +1227,7 @@
 	__u16 lan_status = 0, lan_status_diff  ; /* Initialize to stop compiler warning */
 	__u8 fdx_prot_error ; 
 	__u16 next_ptr;
-
+	int i ; 
 #if OLYMPIC_NETWORK_MONITOR
 	struct trh_hdr *mac_hdr ; 
 #endif
@@ -1276,7 +1287,7 @@
 
 		/* Is the ASB free ? */ 	
 		
-		if (!(readl(olympic_priv->olympic_mmio + SISR) & SISR_ASB_FREE)) {
+		if (readb(asb_block + 2) != 0xff) { 
 			olympic_priv->asb_queued = 1 ; 
 			writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); 
 			return ; 	
@@ -1295,7 +1306,7 @@
 		return ; 	
 		
 	} else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */
-		lan_status = readw(arb_block+6);
+		lan_status = ntohs(readw(arb_block+6)) ;
 		fdx_prot_error = readb(arb_block+8) ; 
 		
 		/* Issue ARB Free */
@@ -1323,11 +1334,20 @@
 			dev->tbusy = 1 ;
 			dev->interrupt = 1 ; 
 			dev->start = 0 ; 
+	
 			olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; 
+			olympic_priv->rx_status_last_received++;
+			olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
+			for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
+				dev_kfree_skb(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+				olympic_priv->rx_status_last_received++;
+				olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
+			}
+
 			free_irq(dev->irq,dev);
 			
 			printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; 
-	
+			MOD_DEC_USE_COUNT ; 
 		} /* If serious error */
 		
 		if (olympic_priv->olympic_message_level) { 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)