linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: phillim2@comcast.net
To: linux-kernel@vger.kernel.org, jgarzik@mandrakesoft.com,
	alan@lxorguk.ukuu.org.uk, marcelo@conectiva.com.br
Subject: [PATCH] Olympic driver
Date: Mon, 30 Sep 2002 19:30:54 -0400	[thread overview]
Message-ID: <20020930233053.GB669@cg436716-a.adubn1.nj.home.com> (raw)

A small update to the olympic driver. 

This fixes a bug introduced in the last update that will panic the
kernel if the wrong options are chosen, corrects some read/write
alignments for 64bit ppc and adds code to start up the cardbus adapters
correctly.

The patch applies cleanly to 2.5.39 as well.

Mike Phillips
Linux Token Ring Project
http://www.linuxtr.net


diff -urN -X dontdiff linux-2.4.20-pre7-ac3.orig/drivers/net/tokenring/olympic.c linux-2.4.20-pre7-ac3/drivers/net/tokenring/olympic.c
--- linux-2.4.20-pre7-ac3.orig/drivers/net/tokenring/olympic.c	2002-09-22 17:10:00.000000000 -0500
+++ linux-2.4.20-pre7-ac3/drivers/net/tokenring/olympic.c	2002-09-22 14:12:56.000000000 -0500
@@ -56,8 +56,15 @@
  * 07/19/01 - Improve bad LAA reporting, strip out freemem
  *	      into a separate function, its called from 3 
  *	      different places now. 
- * 02/09/01 - Replaced sleep_on. 
- *
+ * 02/09/02 - Replaced sleep_on. 
+ * 03/01/02 - Replace access to several registers from 32 bit to 
+ * 	      16 bit. Fixes alignment errors on PPC 64 bit machines.
+ * 	      Thanks to Al Trautman for this one.
+ * 03/10/02 - Fix BUG in arb_cmd. Bug was there all along but was
+ * 	      silently ignored until the error checking code 
+ * 	      went into version 1.0.0 
+ * 06/04/02 - Add correct start up sequence for the cardbus adapters.
+ * 	      Required for strict compliance with pci power mgmt specs.
  *  To Do:
  *
  *	     Wake on lan	
@@ -111,7 +118,7 @@
  */
 
 static char version[] __devinitdata = 
-"Olympic.c v1.0.0 2/9/02  - Peter De Schrijver & Mike Phillips" ; 
+"Olympic.c v1.0.5 6/04/02 - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
 				   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -296,9 +303,10 @@
 	spin_lock_init(&olympic_priv->olympic_lock) ; 
 
 	/* Needed for cardbus */
-	if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR))
+	if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
 		writel(readl(olympic_priv->olympic_mmio+FERMASK)|FERMASK_INT_BIT, olympic_mmio+FERMASK);
-
+	}
+	
 #if OLYMPIC_DEBUG
 	printk("BCTL: %x\n",readl(olympic_mmio+BCTL));
 	printk("GPR: %x\n",readw(olympic_mmio+GPR));
@@ -311,24 +319,42 @@
 	writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL);
 	
 	if (olympic_priv->olympic_ring_speed  == 0) { /* Autosense */
-		writel(readl(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
+		writew(readw(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
 		if (olympic_priv->olympic_message_level) 
 			printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name);
 	} else if (olympic_priv->olympic_ring_speed == 16) {
 		if (olympic_priv->olympic_message_level) 
 			printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name);
-		writel(GPR_16MBPS, olympic_mmio+GPR);
+		writew(GPR_16MBPS, olympic_mmio+GPR);
 	} else if (olympic_priv->olympic_ring_speed == 4) {
 		if (olympic_priv->olympic_message_level) 
 			printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ; 
-		writel(0, olympic_mmio+GPR);
+		writew(0, olympic_mmio+GPR);
 	} 
 	
-	writel(readl(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR);
+	writew(readw(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR);
 
 #if OLYMPIC_DEBUG
 	printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ; 
 #endif
+	/* Solo has been paused to meet the Cardbus power
+	 * specs if the adapter is cardbus. Check to 
+	 * see its been paused and then restart solo. The
+	 * adapter should set the pause bit within 1 second.
+	 */
+
+	if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { 
+		t=jiffies;
+		while (!readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE) { 
+			schedule() ; 
+			if(jiffies-t > 2*HZ) { 
+				printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ; 
+				return -ENODEV;
+			}
+		}
+		writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ; 
+	}
+	
 	/* start solo init */
 	writel((1<<15),olympic_mmio+SISR_MASK_SUM);
 
@@ -341,13 +367,13 @@
 		}
 	}
 	
-	writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
+	writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
 
 #if OLYMPIC_DEBUG
 	printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
 #endif
 
-	init_srb=olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWO)) & (~0xf800));
+	init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
 
 #if OLYMPIC_DEBUG		
 {
@@ -422,11 +448,11 @@
 
 	/* adapter is closed, so SRB is pointed to by LAPWWO */
 
-	writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
-	init_srb=olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWO)) & (~0xf800));
+	writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
+	init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
 	
 #if OLYMPIC_DEBUG
-	printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
+	printk("LAPWWO: %x, LAPA: %x\n",readw(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
 	printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK));
 	printk("Before the open command \n");
 #endif	
@@ -486,7 +512,7 @@
             			olympic_priv->srb_queued=0;
             			break;
         		}
-			if ((jiffies-t) > 60*HZ) { 
+			if ((jiffies-t) > 10*HZ) { 
 				printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ; 
 				olympic_priv->srb_queued=0;
 				break ; 
@@ -495,7 +521,7 @@
     		}
 		remove_wait_queue(&olympic_priv->srb_wait,&wait) ; 
 		set_current_state(TASK_RUNNING) ; 
-
+		olympic_priv->srb_queued = 0 ; 
 #if OLYMPIC_DEBUG
 		printk("init_srb(%p): ",init_srb);
 		for(i=0;i<20;i++)
@@ -629,7 +655,8 @@
 	printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7])  );
 
 	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
-	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
+	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr =
+%08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
 #endif
 
 	writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
@@ -790,7 +817,7 @@
 			   	   	   first. Ideally all frames would be in a single buffer, this can be tuned by
                                	   	   altering the buffer size. If the length of the packet is less than
 					   1500 bytes we're going to copy it over anyway to stop packets getting
-					   dropped from sockets with buffers small than our pkt_buf_sz. */
+					   dropped from sockets with buffers smaller than our pkt_buf_sz. */
 				
  					if (buffer_cnt==1) {
 						olympic_priv->rx_ring_last_received++ ; 
@@ -1097,10 +1124,13 @@
 	writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
 
 #if OLYMPIC_DEBUG
+	{
+	int i ; 
 	printk("srb(%p): ",srb);
 	for(i=0;i<4;i++)
 		printk("%x ",readb(srb+i));
 	printk("\n");
+	}
 #endif
 	free_irq(dev->irq,dev);
 
@@ -1369,8 +1399,7 @@
 	arb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; 
 	asb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; 
 	srb = (u8 *)(olympic_priv->olympic_lap + olympic_priv->srb) ; 
-	writel(readl(olympic_mmio+LAPA),olympic_mmio+LAPWWO);
-
+	
 	if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */
 
 		header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */	
@@ -1423,7 +1452,7 @@
 		/* Now tell the card we have dealt with the received frame */
 
 		/* Set LISR Bit 1 */
-		writel(LISR_ARB_FREE,olympic_priv->olympic_lap + LISR_SUM);
+		writel(LISR_ARB_FREE,olympic_priv->olympic_mmio + LISR_SUM);
 
 		/* Is the ASB free ? */ 	
 		
diff -urN -X dontdiff linux-2.4.20-pre7-ac3.orig/drivers/net/tokenring/olympic.h linux-2.4.20-pre7-ac3/drivers/net/tokenring/olympic.h
--- linux-2.4.20-pre7-ac3.orig/drivers/net/tokenring/olympic.h	2002-08-02 19:39:44.000000000 -0500
+++ linux-2.4.20-pre7-ac3/drivers/net/tokenring/olympic.h	2002-09-22 14:12:56.000000000 -0500
@@ -91,6 +91,7 @@
 #define TIMER 0x50
 
 #define CLKCTL 0x74
+#define CLKCTL_PAUSE (1<<15) 
 
 #define PM_CON 0x4
 

                 reply	other threads:[~2002-10-01  0:58 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020930233053.GB669@cg436716-a.adubn1.nj.home.com \
    --to=phillim2@comcast.net \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=jgarzik@mandrakesoft.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo@conectiva.com.br \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).