[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-tr] LAA for 2.2.9 ibmtr driver



Courtesy Rogier Wolff....

--- Begin Message ---


Hi everyone,

Thanks to Paul Norton, I found the IBM shared RAM token ring card docs
on the IBM website:

  http://www.s390.ibm.com/bookmgr-cgi/bookmgr.cmd/BOOKS/BK8R1001/CCONTENTS

Those do come in handy when things don't work at first :-)

Thanks to Henrik Stoerner for the userinterface and the LAA parsing
code.


Locally Administrated Addresses are useful for some people because
that can simplify routing tables in large networks enormously.

At insmod time, you specify "laa=aa.bb.cc.dd.ee.ff" to set the LAA to
the value specified. (LAA's start with 0x40-0x7f, so "aa" is invalid,
and will be rejected). Of course everybody but me puts this in
/etc/conf.modules .

As I was interested in the code that read the hardware address from
the Adapter Identification Prom (AIP), I studied that code. At first I
misunderstood that code. I tried rewriting it in a way that it is no
longer so hard-to-read. It is now also much shorter. 

Paul, you're mentioned as the Maintainer. Are you agreed with me with
these changes? Will you submit them to Linus, or do you want me to do
this? 

Uwe, do you need this backported to 2.0, or will this 2.2 patch
suffice? (I promised you I'd do that, so you have every right to
ask me to produce that patch too... :-)

Regards,

	Roger Wolff.

------------------------------------------------------------------------

diff -ur linux-2.2.9.clean/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- linux-2.2.9.clean/drivers/net/ibmtr.c	Mon May 17 07:49:55 1999
+++ linux/drivers/net/ibmtr.c	Wed Jun  2 20:57:24 1999
@@ -79,6 +79,10 @@
  *
  *	Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) :
  *	+ added spinlocks for SMP sanity (10 March 1999)
+ *
+ *	Changes by Roger E. Wolff (R.E.Wolff@BitWizard.nl) :
+ *	+ added support for Locally Administrated Adresses (May 30, 1999)
+ *
  */
 
 /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value 
@@ -187,6 +191,8 @@
 #endif
 
 #if !TR_NEWFORMAT
+/* Tip: Declare this variable as a module parameter, makes changing the 
+   debug options much easier. -- REW */
 unsigned char ibmtr_debug_trace=1;  /*  Patch or otherwise alter to
                                          control tokenring tracing.  */
 #else
@@ -216,6 +222,7 @@
 void		ibmtr_readlog(struct device *dev);
 void		ibmtr_reset_timer(struct timer_list *tmr, struct device *dev);
 int             ibmtr_change_mtu(struct device *dev, int mtu);
+static char *   get_laa (struct device *dev);
 
 static unsigned int ibmtr_portlist[] __initdata = {
 	0xa20, 0xa24, 0
@@ -297,12 +304,13 @@
 
 __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
 {
-	unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK,temp=0;
+	unsigned char segment=0, intr=0, irq=0, i=0, j=0, cardpresent=NOTOK;
 	__u32 t_mmio=0;
 	struct tok_info *ti=0;
 	__u32 cd_chanid;
 	unsigned char *tchanid, ctemp;
 	unsigned long timeout;
+	char *laa;
 
 #ifndef MODULE
 #ifndef PCMCIA
@@ -473,33 +481,60 @@
 	if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
 		DPRINTK("irq=%d",irq);
 		if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
-			DPRINTK(", ti->mmio=%08X",ti->mmio);
+			printk(", ti->mmio=%08X",ti->mmio);
 			printk(", segment=%02X",segment);
 		}
 		printk(".\n");
 	}
 
-	/* Get hw address of token ring card */
+	dev->dev_addr[0] = 0;
+	laa =  get_laa (dev);
+	if (laa && strlen (laa) > 0) {
+		char *p = laa;
+		char *newp;
+		int j;
+		u8 laa_mac[6];
+	  
+		for (j=0; (*p && (j<6)); j++) {
+			laa_mac[j] = simple_strtoul(p, &newp, 16);
+			if (*newp == '.') p=++newp; 
+			else {
+				if (j < 5) laa_mac[0] = 0; /* Not enough numbers */
+				break;
+			}
+		}
+	  
+		if ((laa_mac[0] >= 0x40) && (laa_mac[0] <= 0x7f)) {
+			/* Valid LAA, use it */
+			printk(KERN_DEBUG "%s: Using locally administered address %x.%x.%x.%x.%x.%x\n",
+			       dev->name, laa_mac[0],laa_mac[1],laa_mac[2],
+			       laa_mac[3], laa_mac[4],laa_mac[5]);
+
+			for (j=0; j < 6;j++) 
+				dev->dev_addr[j] = laa_mac[j];
+		} else 
+			printk(KERN_WARNING "%s: Invalid locally administered address %s\n", dev->name, laa);
+	} 
+	if (!dev->dev_addr[0]) {
+		/* Get hw address of token ring card */
 #if !TR_NEWFORMAT
-	DPRINTK("hw address: ");
+		DPRINTK("hw address: ");
 #endif
-	j=0;
-	for (i=0; i<0x18; i=i+2) 
-	{
-		/* technical reference states to do this */
-		temp = readb(ti->mmio + AIP + i) & 0x0f;
-#if !TR_NEWFORMAT
-		printk("%1X",ti->hw_address[j]=temp);
-#else
-		ti->hw_address[j]=temp;
+		/* I misunderstood this piece of code first time I read it. 
+		   I hope it is clearer now. In any case it is shorter now. -- REW */
+		for (j=0;j<6;j++) {
+			/* technical reference states that the upper 4 bits are 
+			   undefined. They are usually zero though. -- REW */
+			dev->dev_addr[j] = ((readb(ti->mmio + AIP + j*4) & 0x0f) << 4) |
+			                    (readb(ti->mmio + AIP + j*4 + 2) & 0x0f);
+#ifndef TR_NEWFORMAT
+			printk("%02x", dev->dev_addr[j]);
 #endif
-		if(j&1)
-			dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
-		++j;
-	}
+		}
 #ifndef TR_NEWFORMAT
-	printk("\n");
+		printk("\n");
 #endif
+	}
 
 	/* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
 	ti->adapter_type = readb(ti->mmio + AIPADAPTYPE);
@@ -1368,6 +1403,9 @@
 	       ti->init_srb + offsetof(struct dir_open_adapter, command));
 	writew(htons(OPEN_PASS_BCON_MAC),
 	       ti->init_srb + offsetof(struct dir_open_adapter, open_options));
+	for (i=0;i<6;i++) 
+	  writeb (dev->dev_addr[i], 
+		  ti->init_srb + offsetof(struct dir_open_adapter, node_address) + i);
 	if (ti->ring_speed == 16) {
 		writew(htons(ti->dhb_size16mb),
 		       ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
@@ -1714,10 +1752,13 @@
 static int io[IBMTR_MAX_ADAPTERS] = {0xa20,0xa24};
 static int irq[IBMTR_MAX_ADAPTERS] = {0,0};
 static int mem[IBMTR_MAX_ADAPTERS] = {0,0};
+static char *laa[IBMTR_MAX_ADAPTERS] = {NULL, };   /* LAA parameter string */
+
 
 MODULE_PARM(io, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
 MODULE_PARM(irq, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
 MODULE_PARM(mem, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "i");
+MODULE_PARM(laa, "1-" __MODULE_STRING(IBMTR_MAX_ADAPTERS) "s");
 
 int init_module(void)
 {
@@ -1763,4 +1804,26 @@
 			 dev_ibmtr[i] = NULL;
                 }
 }
+
+
+char *get_laa (struct device *dev)
+{
+  int i;
+
+  for (i=0;i< IBMTR_MAX_ADAPTERS; i++)
+    if (dev == dev_ibmtr[i]) {
+      return laa[i];
+    }
+  printk (KERN_WARNING "ibmtr: Unexpected situation: Dev is not from dev_ibmtr.\n");
+  return NULL;
+}
+
+#else
+
+/* Not module: laa not supported. */
+char *get_laa (struct device *dev)
+{
+  return NULL;
+}
+
 #endif /* MODULE */


-- 
** R.E.Wolff@BitWizard.nl ** http://www.BitWizard.nl/ ** +31-15-2137555 **
*-- BitWizard writes Linux device drivers for any device you may have! --*
------ Microsoft SELLS you Windows, Linux GIVES you the whole house ------
--- End Message ---