root/drivers/net/ibmtr.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. adapter_def
  2. DummyCall
  3. PrtChanID
  4. tok_probe
  5. get_sram_size
  6. tok_open
  7. tok_close
  8. tok_interrupt
  9. initial_tok_int
  10. tok_init_card
  11. open_sap
  12. tok_open_adapter
  13. tr_tx
  14. tr_rx
  15. tok_send_packet
  16. tok_get_stats
  17. init_module
  18. cleanup_module

   1 /* ibmtr.c:  A shared-memory IBM Token Ring 16/4 driver for linux */
   2 /*
   3         Written 1993 by Mark Swanson and Peter De Schrijver.
   4         This software may be used and distributed according to the terms
   5         of the GNU Public License, incorporated herein by reference.
   6 
   7         This device driver should work with Any IBM Token Ring Card that does
   8    not use DMA.
   9 
  10         I used Donald Becker's (becker@super.org) device driver work
  11         as a base for most of my initial work.
  12 */
  13 
  14 /*
  15    Changes by Peter De Schrijver (Peter.Deschrijver@linux.cc.kuleuven.ac.be) :
  16         
  17         + changed name to ibmtr.c in anticipation of other tr boards.
  18         + changed reset code and adapter open code.
  19         + added SAP open code.
  20         + a first attempt to write interrupt, transmit and receive routines.
  21 
  22    Changes by David W. Morris (dwm@shell.portal.com) :
  23      941003 dwm: - Restructure tok_probe for multiple adapters, devices
  24                  - Add comments, misc reorg for clarity
  25                  - Flatten interrupt handler levels
  26 
  27    Changes by Farzad Farid (farzy@zen.via.ecp.fr)
  28    and Pascal Andre (andre@chimay.via.ecp.fr) (March 9 1995) :
  29         - multi ring support clean up
  30         - RFC1042 compliance enhanced
  31 
  32    Changes by Pascal Andre (andre@chimay.via.ecp.fr) (September 7 1995) :
  33         - bug correction in tr_tx
  34         - removed redundant information display
  35         - some code reworking
  36 
  37    Warnings !!!!!!!!!!!!!!
  38       This driver is only partially sanitized for support of multiple
  39       adapters.  It will almost definately fail if more than one
  40       active adapter is identified.
  41 */
  42         
  43 #ifdef MODULE
  44 #include <linux/module.h>
  45 #include <linux/version.h>
  46 #endif
  47 
  48 #define NO_AUTODETECT 1
  49 #undef NO_AUTODETECT
  50 #undef ENABLE_PAGING
  51 
  52 #define FALSE 0
  53 #define TRUE (!FALSE)
  54 
  55 /* changes the output format of driver initialisation */
  56 #define TR_NEWFORMAT    1
  57 
  58 /* some 95 OS send many non UI frame; this allow removing the warning */
  59 #define TR_FILTERNONUI  1
  60 
  61 /* version and credits */
  62 static const char *version = "ibmtr.c: v1.3.24 8/7/94 Peter De Schrijver and Mark Swanson\n"
  63 "   modified 10/3/94 DW Morris, 3/9/95 F Farid and P Andre, 9/7/95 P Andre\n";
  64 
  65 static char pcchannelid[]={0x05, 0x00, 0x04, 0x09,
  66                          0x04, 0x03, 0x04, 0x0f,
  67                          0x03, 0x06, 0x03, 0x01,
  68                          0x03, 0x01, 0x03, 0x00,
  69                          0x03, 0x09, 0x03, 0x09,
  70                          0x03, 0x00, 0x02, 0x00};
  71 static char mcchannelid[]={0x04, 0x0d, 0x04, 0x01,
  72                          0x05, 0x02, 0x05, 0x03,
  73                          0x03, 0x06, 0x03, 0x03,
  74                          0x05, 0x08, 0x03, 0x04,
  75                          0x03, 0x05, 0x03, 0x01,
  76                          0x03, 0x08, 0x02, 0x00};
  77 
  78 #include <linux/config.h>
  79 #include <linux/kernel.h>
  80 #include <linux/sched.h>
  81 #include <linux/errno.h>
  82 #include <linux/sched.h>
  83 #include <linux/timer.h>
  84 #include <linux/in.h>
  85 #include <asm/io.h>
  86 #include <asm/system.h>
  87 #include <asm/bitops.h>
  88 #include <linux/ioport.h>
  89 #include <linux/errno.h>
  90 #include <linux/string.h>
  91 #include <linux/skbuff.h>
  92 #include <linux/interrupt.h>
  93 #include <linux/netdevice.h>
  94 #include <linux/trdevice.h>
  95 #include <stddef.h>
  96 #include "ibmtr.h"
  97 
  98 
  99 #define DPRINTK(format, args...) printk("%s: " format, dev->name , ## args)
 100 #define DPRINTD(format, args...) DummyCall("%s: " format, dev->name , ## args)
 101 
 102 #ifdef TR_NEWFORMAT
 103 /* this allows displaying full adapter information */
 104 const char *channel_def[] = { "ISA", "MCA", "ISA P&P" };
 105 char *adapter_def(char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107        switch (type)
 108        {
 109                case 'f':
 110                case 'F' : return "Adapter/A";
 111                case 'e':
 112                case 'E' : return "16/4 Adapter/II";
 113                default :
 114                        printk("Unknow adapter %c\n", type);
 115                        return "adapter";
 116        };
 117 };
 118 #endif
 119 
 120 #if 0
 121 struct tok_info tok_info1;   /*  WARNING: this area must be replicated
 122                                  or 'malloced' to support > 1 adapter */
 123 
 124 static struct wait_queue *wait_for_tok_int=NULL, *wait_for_reset;
 125 void (*do_tok_int)(struct device *dev)=NULL;
 126 #endif
 127 
 128 #ifndef TR_NEWFORMAT
 129 unsigned char ibmtr_debug_trace=1;  /*  Patch or otherwise alter to
 130                                          control tokenring tracing.  */
 131 #else
 132 unsigned char ibmtr_debug_trace=0;
 133 #endif
 134 #define TRC_INIT 0x01              /*  Trace initialization & PROBEs */
 135 #define TRC_INITV 0x02             /*  verbose init trace points     */
 136 
 137 static short TokBaseAddrs[]={MMIOStartLocP, /* Addr-s to scan */
 138                              MMIOStartLocA};
 139 
 140 
 141 int tok_probe(struct device *dev);
 142 unsigned char get_sram_size(struct tok_info *adapt_info);
 143 
 144 static void tok_init_card(unsigned long dev_addr);
 145 static void tok_interrupt(int irq, struct pt_regs *regs);
 146 
 147 static void initial_tok_int(struct device *dev);
 148 
 149 static void open_sap(unsigned char type,struct device *dev);
 150 void tok_open_adapter(unsigned long dev_addr);
 151 static void tr_rx(struct device *dev);
 152 static void tr_tx(struct device *dev);
 153 
 154 static int tok_open(struct device *dev);
 155 static int tok_close(struct device *dev);
 156 static int tok_send_packet(struct sk_buff *skb, struct device *dev);
 157 static struct enet_statistics * tok_get_stats(struct device *dev);
 158 
 159 static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter};
 160 
 161 int DummyCallCount=0;
 162 
 163 /*  This routine combined with the #DEFINE DPRINTD serves
 164     to workaround the gcc apparent bug.   in tr_tx() */
 165 
 166 static void DummyCall(const char * fmt,...) {DummyCallCount++;return;}
     /* [previous][next][first][last][top][bottom][index][help] */
 167 
 168 static void PrtChanID(char *pcid, short stride) {
     /* [previous][next][first][last][top][bottom][index][help] */
 169   short i, j;
 170   for (i=0,j=0;i<24;i++,j=j+stride) printk("%1x",((int) pcid[j])&0x0f);
 171   printk("\n");
 172 }
 173 
 174 /* tok_probe():  Routine specified in the network device structure
 175           to probe for an IBM Token Ring Adapter.  Routine outline:
 176           I.  Interrogate hardware to determine if an adapter exists
 177               and what the speeds and feeds are
 178          II.  Setup data structures to control execution based upon
 179               adapter characteristics.
 180          III. Initialize adapter operation
 181      We expect tok_probe to be called once for each device entry
 182      which references it.
 183  */
 184 
 185 int tok_probe(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187 
 188   unsigned char segment=0, intr=0, irq=0, i=0, j=0,
 189                 cardpresent=NOTOK,temp=0;
 190   unsigned char *t_mmio=0;
 191   short PIOaddr=0, iAddr;
 192   struct tok_info *ti=0;
 193   static struct tok_info *badti=0;  /* if fail after kmalloc, reuse */
 194 
 195   static unsigned char Shared_Ram_Base = IBMTR_SHARED_RAM_BASE;
 196 
 197   /*  this is the major adapter probe loop.  For each call to tok_probe,
 198       we try each remaining entry in TokBaseAddrs[] as a possible
 199       adapter.  Once an entry is rejected or assigned, we zero it to
 200       avoid duplicate use or worthless trial for the tok probe call*/
 201 
 202   for (iAddr=0;
 203        iAddr < (sizeof(TokBaseAddrs)/sizeof(short))&&PIOaddr==0;
 204        iAddr++) { char *tchanid, *cd_chanid, ctemp;
 205     PIOaddr=TokBaseAddrs[iAddr];  /* address to try           */
 206     TokBaseAddrs[iAddr] = 0;      /* (and marked already used */
 207     if (PIOaddr == 0) continue;   /* already tried this addr */
 208     if ( check_region(PIOaddr,TR_IO_EXTENT) ) { /* Make sure PIO address not
 209                                                    already assigned elsewhere
 210                                                    before we muck with I/O
 211                                                    addresses */
 212       if (ibmtr_debug_trace & TRC_INIT)
 213         DPRINTK("check_region(%4hx,%d) failed.\n",PIOaddr, TR_IO_EXTENT);
 214       PIOaddr = 0; continue; /* clear to flag fail and try next */
 215     }
 216            /*  Query the adapter PIO base port which will return
 217                indication of where MMIO was placed (per tech ref
 218                this assignment is done by BIOS - what is rational for
 219                where it is?).  We also have a coded interrupt address.*/
 220 
 221     segment = inb(PIOaddr);
 222     if (segment < 0x40 || segment > 0xe0) { /* out of range values
 223                             so we will assume non-existant IO dev */
 224       PIOaddr = 0; continue; /* clear to flag fail and try next */
 225     }
 226 
 227                  /*  Compute the linear base address of the MMIO area
 228                      as LINUX doesn't care about segments          */
 229     t_mmio=(char *) (((segment & 0xfc) << 11) + 0x80000);
 230     intr = segment & 0x03;   /* low bits is coded interrupt # */
 231     if (ibmtr_debug_trace & TRC_INIT)
 232       DPRINTK("PIOaddr: %4hx seg/intr: %2x mmio base: %p intr: %d\n",
 233               PIOaddr, (int) segment,t_mmio,(int) intr);
 234     /*  Now we will compare expected 'channelid' strings with
 235         what we is there to learn of ISA/MCA or not TR card */
 236         /*  !!!WARNING:!!!! It seems pretty silly to blunder ahead
 237             w/o verification that the mmio address we have found
 238             is valid storage -- perhaps this is tolerable for current
 239             hardware state??? */
 240     cd_chanid = (char *)(CHANNEL_ID + t_mmio);  /* for efficiency */
 241     tchanid=pcchannelid; cardpresent=TR_ISA;  /* try ISA ? */
 242                        /* suboptimize knowing first byte different */
 243     ctemp = (* cd_chanid) & 0x0f;
 244     if (  ctemp != *tchanid) { /* NOT ISA card, try MCA */
 245       tchanid=mcchannelid; cardpresent=TR_MCA;
 246       if (  ctemp != *tchanid)  /* Neither ISA nor MCA */
 247         cardpresent=NOTOK;
 248     }
 249     if (cardpresent != NOTOK) { /* know presumed type, try rest of ID */
 250       for (i=2,j=1; i<=46; i=i+2,j++) {
 251         if ( (cd_chanid[i] & 0x0f) != tchanid[j]) {
 252           cardpresent=NOTOK;   /* match failed, not TR card */
 253           break;
 254         }
 255       }
 256     }
 257 
 258     /* If we have an ISA board check for the ISA P&P version, as it has
 259        different IRQ settings */
 260     if (cardpresent == TR_ISA && (*(AIPFID + t_mmio)==0x0e))
 261         cardpresent=TR_ISAPNP;
 262 
 263     if (cardpresent == NOTOK) { /* "channel_id" did not match, report */
 264       if (ibmtr_debug_trace & TRC_INIT) {
 265         DPRINTK("Channel ID string not found for PIOaddr: %4hx\n",
 266                 PIOaddr);
 267         DPRINTK("Expected for ISA: ");  PrtChanID(pcchannelid,1);
 268         DPRINTK("           found: ");  PrtChanID(cd_chanid,2);
 269         DPRINTK("Expected for MCA: ");  PrtChanID(mcchannelid,1);
 270       }
 271       PIOaddr = 0;  /* all to know not found yet */
 272       continue;
 273     }
 274 
 275    /* !!!! we could tighten validation by checking the HW Address
 276       against the 1-s complement..  Move the get HW logic to here */
 277 
 278   }
 279 
 280   /*   The search loop has either completed with a presumed TR adapter
 281        or none found.  Check situation ... march on if possible */
 282 
 283   if (PIOaddr == 0) { /* failed to find a valid TR adapter */
 284     if (ibmtr_debug_trace & TRC_INIT)
 285          DPRINTK("Unable to assign adapter to device.\n");
 286     return ENODEV;
 287   }
 288 
 289   /*?? Now, allocate some of the pl0 buffers for this driver.. */
 290 
 291   if (!badti) {
 292     ti = (struct tok_info *)kmalloc(sizeof(struct tok_info), GFP_KERNEL);
 293     if (ti == NULL)
 294           return -ENOMEM;
 295   } else {
 296     ti = badti; badti = NULL;
 297   }/*?? dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL); */
 298 
 299   memset(ti,0,sizeof(struct tok_info));
 300 
 301   ti->mmio= t_mmio;
 302 
 303   dev->priv = ti;     /* this seems like the logical use of the
 304                          field ... lets try some empirical tests
 305                          using the token-info structure -- that
 306                          should fit with out future hope of multiple
 307                          adapter support as well /dwm   */
 308 
 309   switch (cardpresent) {
 310     case TR_ISA:
 311       if (intr==0) irq=9; /* irq2 really is irq9 */
 312       if (intr==1) irq=3;
 313       if (intr==2) irq=6;
 314       if (intr==3) irq=7;
 315       ti->global_int_enable=GLOBAL_INT_ENABLE+((irq==9) ? 2 : irq);
 316       ti->sram=NULL;
 317 #ifndef TR_NEWFORMAT
 318       DPRINTK("ti->global_int_enable: %04X\n",ti->global_int_enable);
 319 #endif
 320       break;
 321     case TR_MCA:
 322       if (intr==0) irq=9;
 323       if (intr==1) irq=3;
 324       if (intr==2) irq=10;
 325       if (intr==3) irq=11;
 326       ti->global_int_enable=0;
 327       ti->sram=(unsigned char *)((inb(PIOaddr+ADAPTRESETREL) & 0xfe)
 328                                   << 12);
 329       break;
 330     case TR_ISAPNP:
 331       if (intr==0) irq=9;
 332       if (intr==1) irq=3;
 333       if (intr==2) irq=10;
 334       if (intr==3) irq=11;
 335       while(!(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN));
 336       ti->sram=(unsigned char *)((unsigned long)(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN) <<12);
 337       ti->global_int_enable=PIOaddr+ADAPTINTREL;
 338       break;
 339       
 340   }
 341 
 342   if (ibmtr_debug_trace & TRC_INIT) { /* just report int */
 343     DPRINTK("irq=%d",irq);
 344     if (ibmtr_debug_trace & TRC_INITV) { /* full chat in verbose only */
 345       DPRINTK(", ti->mmio=%p",ti->mmio);
 346       printk(", segment=%02X",segment);
 347     }
 348     printk(".\n");
 349   }
 350 
 351   /* Get hw address of token ring card */
 352 #ifndef TR_NEWFORMAT 
 353   DPRINTK("hw address: ");
 354 #endif
 355   j=0;
 356   for (i=0; i<0x18; i=i+2) {
 357     temp = *(char *)((ulong)AIP + (ulong)i + ti->mmio) & 0x0f; /* Tech ref states must do this */
 358 #ifndef TR_NEWFORMAT
 359     printk("%1X",ti->hw_address[j]=temp);
 360 #else
 361     ti->hw_address[j]=temp;
 362 #endif
 363     if(j&1)
 364       dev->dev_addr[(j/2)]=ti->hw_address[j]+(ti->hw_address[j-1]<<4);
 365     ++j;
 366   }
 367 #ifndef TR_NEWFORMAT
 368   printk("\n");
 369 #endif
 370 
 371 
 372   /* get Adapter type:  'F' = Adapter/A, 'E' = 16/4 Adapter II,...*/
 373   ti->adapter_type = *(char *)(ti->mmio + AIPADAPTYPE);
 374 
 375   /* get Data Rate:  F=4Mb, E=16Mb, D=4Mb & 16Mb ?? */
 376   ti->data_rate = *(char *)(ti->mmio + AIPDATARATE);
 377 
 378   /* Get Early Token Release support?: F=no, E=4Mb, D=16Mb, C=4&16Mb */
 379   ti->token_release = *(char *)(ti->mmio + AIPEARLYTOKEN);
 380 
 381   /* How much shared RAM is on adapter ? */
 382   ti->avail_shared_ram = get_sram_size(ti);
 383 
 384   /* We need to set or do a bunch of work here based on previous results.. */
 385   /* Support paging?  What sizes?:  F=no, E=16k, D=32k, C=16 & 32k */
 386   ti->shared_ram_paging = *(char *)(ti->mmio + AIPSHRAMPAGE);
 387 
 388   /* Available DHB  4Mb size:   F=2048, E=4096, D=4464 */
 389   ti->dhb_size4mb = *(char *) (ti->mmio + AIP4MBDHB);
 390 
 391   /* Available DHB 16Mb size:  F=2048, E=4096, D=8192, C=16384, B=17960 */
 392   ti->dhb_size16mb = *(char *)(ti->mmio + AIP16MBDHB);
 393 
 394 #ifndef TR_NEWFORMAT
 395   DPRINTK("atype=%x, drate=%x, trel=%x, asram=%dK, srp=%x, dhb(4mb=%x, 16mb=%x)\n",ti->adapter_type,
 396           ti->data_rate, ti->token_release, ti->avail_shared_ram/2, ti->shared_ram_paging,
 397           ti->dhb_size4mb, ti->dhb_size16mb);
 398 #endif
 399 
 400   /* We must figure out how much shared memory space this adapter
 401      will occupy so that if there are two adapters we can fit both
 402      in.  Given a choice, we will limit this adapter to 32K.  The
 403      maximum space will will use for two adapters is 64K so if the
 404      adapter we are working on demands 64K (it also doesn't support
 405      paging), then only one adapter can be supported.  */
 406 
 407   /* determine how much of total RAM is mapped into PC space */
 408   ti->mapped_ram_size=1<<(((*(unsigned char *)
 409                        (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
 410   ti->page_mask=0;
 411   if (ti->shared_ram_paging == 0xf) { /* No paging in adapter */
 412     ti->mapped_ram_size = ti->avail_shared_ram;
 413   } else {
 414 #ifdef ENABLE_PAGING
 415     unsigned char pg_size;
 416 #endif
 417 
 418 #ifndef TR_NEWFORMAT
 419     DPRINTK("shared ram page size: %dK\n",ti->mapped_ram_size/2);
 420 #endif
 421 #ifdef ENABLE_PAGING
 422     switch(ti->shared_ram_paging) {
 423       case 0xf:
 424         break;
 425       case 0xe:
 426         ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
 427         pg_size=32;   /* 16KB page size */
 428         break;
 429       case 0xd:
 430         ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
 431         pg_size=64;   /* 32KB page size */
 432         break;
 433       case 0xc:
 434         ti->page_mask=(ti->mapped_ram_size==32) ? 0xc0 : 0;
 435         ti->page_mask=(ti->mapped_ram_size==64) ? 0x80 : 0;
 436         DPRINTK("Dual size shared RAM page (code=0xC), don't support it!\n");
 437         /* nb/dwm: I did this because RRR (3,2) bits are documented as
 438          * R/O and I can't find how to select which page size
 439          * Also, the above conditional statement sequence is invalid
 440          *       as page_mask will always be set by the second stmt
 441          */
 442         badti=ti;
 443         break;
 444       default:
 445         DPRINTK("Unknown shared ram paging info %01X\n",ti->shared_ram_paging);
 446         badti=ti;    /* bail out if bad code */
 447         break;
 448     }
 449     if(ti->page_mask) {
 450       if(pg_size > ti->mapped_ram_size) {
 451         DPRINTK("Page size (%d) > mapped ram window (%d), can't page.\n",
 452                 pg_size, ti->mapped_ram_size);
 453         ti->page_mask = 0;    /* reset paging */
 454       } else {
 455         ti->mapped_ram_size=ti->avail_shared_ram; /****** ?????????? *******/
 456         DPRINTK("Shared RAM paging enabled. Page size : %uK\n",((ti->page_mask^ 0xff)+1)>>2);
 457       }
 458     }
 459 #else
 460 #endif
 461   }
 462 
 463   if (cardpresent==TR_ISA) { /* finish figuring the shared RAM address */
 464     static unsigned char ram_bndry_mask[]={0xfe, 0xfc, 0xf8, 0xf0};
 465     unsigned char new_base, rrr_32, chk_base, rbm;
 466     rrr_32 = (*(unsigned char *)
 467                        (ti->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2;
 468     rbm = ram_bndry_mask[rrr_32];
 469     new_base = (Shared_Ram_Base + (~rbm)) & rbm; /* up to boundary */
 470     chk_base = new_base + (ti->mapped_ram_size>>3);
 471     if (chk_base > (IBMTR_SHARED_RAM_BASE+IBMTR_SHARED_RAM_SIZE)) {
 472       DPRINTK("Shared RAM for this adapter (%05x) exceeds driver"
 473               " limit (%05x), adapter not started.\n",
 474               chk_base<<12, (IBMTR_SHARED_RAM_BASE+
 475                               IBMTR_SHARED_RAM_SIZE)<<12);
 476       badti=ti;
 477     } else {  /* seems cool, record what we have figured out */
 478       ti->sram_base = new_base;
 479       Shared_Ram_Base = new_base;
 480     }
 481   }
 482 
 483   /* dwm: irq and other final setup moved here so if we find other
 484         unrecognized values OR shared ram conflicts, we can still
 485         bail out in a rather benign fashion.    */
 486 
 487   if (badti) return ENODEV;
 488 #ifndef TR_NEWFORMAT
 489   DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
 490 #endif
 491 
 492   if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR") != 0) {
 493     DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
 494     badti = ti;    /*  keep track of unused tok_info */
 495     return ENODEV;
 496   }
 497   irq2dev_map[irq]=dev;
 498 
 499   /*?? Now, allocate some of the PIO PORTs for this driver.. */
 500   request_region(PIOaddr,TR_IO_EXTENT,"ibmtr");  /* record PIOaddr range
 501                                                     as busy */
 502 #ifndef TR_NEWFORMAT
 503    DPRINTK("%s",version); /* As we have passed card identification,
 504                              let the world know we're here! */
 505 #else
 506   printk("%s",version);
 507   DPRINTK("%s %s found using irq %d, PIOaddr %4hx, %dK shared RAM.\n",
 508        channel_def[cardpresent-1], adapter_def(ti->adapter_type), irq,
 509         PIOaddr, ti->mapped_ram_size/2);
 510   DPRINTK("Hardware address : %02X:%02X:%02X:%02X:%02X:%02X\n",
 511        dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 512         dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 513 #endif
 514 
 515   dev->base_addr=PIOaddr; /* set the value for device */
 516 
 517   dev->open=tok_open;
 518   dev->stop=tok_close;
 519   dev->hard_start_xmit=tok_send_packet;
 520   dev->get_stats = NULL;
 521   dev->get_stats = tok_get_stats;
 522   dev->set_multicast_list = NULL;
 523   tr_setup(dev);
 524   tok_init_card((unsigned long)dev);
 525 
 526   return 0;  /* Return 0 to indicate we have found a Token Ring card. */
 527 }
 528 
 529 /* query the adapter for the size of shared RAM  */
 530 
 531 unsigned char get_sram_size(struct tok_info *adapt_info) {
     /* [previous][next][first][last][top][bottom][index][help] */
 532 
 533         unsigned char avail_sram_code;
 534         static unsigned char size_code[]={ 0,16,32,64,127,128 };
 535 
 536            /*  Adapter gives
 537                 'F' -- use RRR bits 3,2
 538                 'E' -- 8kb   'D' -- 16kb
 539                 'C' -- 32kb  'A' -- 64KB
 540                 'B' - 64KB less 512 bytes at top
 541                       (WARNING ... must zero top bytes in INIT */
 542 
 543         avail_sram_code=0xf-*(adapt_info->mmio + AIPAVAILSHRAM);
 544         if(avail_sram_code)
 545                 return size_code[avail_sram_code];
 546         else  /* for code 'F', must compute size from RRR(3,2) bits */
 547 
 548                 return 1<<(((*(unsigned char *)
 549               (adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD))>>2)+4);
 550 }
 551 
 552 static int tok_open(struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
 553 
 554    struct tok_info *ti=(struct tok_info *)dev->priv;
 555 
 556    if(ti->open_status==CLOSED) {
 557       tok_init_card((unsigned long)dev);
 558    }
 559 
 560         if(ti->open_status==IN_PROGRESS) {
 561       sleep_on(&ti->wait_for_reset);
 562         }
 563         
 564    if(ti->open_status==SUCCES) {
 565       dev->tbusy=0;
 566       dev->interrupt=0;
 567       dev->start=1;
 568       /*  NEED to see smem size *AND* reset high 512 bytes if
 569           needed */
 570 
 571 #ifdef MODULE
 572         MOD_INC_USE_COUNT;
 573 #endif
 574 
 575       return 0;
 576    }
 577         else 
 578       return -EAGAIN;
 579 
 580 }
 581 
 582 static int tok_close(struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
 583 
 584   struct tok_info *ti=(struct tok_info *) dev->priv;
 585 
 586         struct srb_close_adapter *close_adapter=(struct srb_close_adapter *)ti->srb;
 587 
 588         close_adapter->command=DIR_CLOSE_ADAPTER;
 589         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
 590 
 591    ti->open_status=CLOSED;
 592 
 593         sleep_on(&ti->wait_for_tok_int);                
 594 
 595         if(close_adapter->ret_code)
 596                 DPRINTK("close adapter failed: %02X\n",close_adapter->ret_code);
 597 
 598 #ifdef MODULE
 599         MOD_DEC_USE_COUNT;
 600 #endif
 601         
 602         return 0;
 603 }
 604 
 605 static void tok_interrupt (int irq, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 606 {
 607 
 608         unsigned char status;
 609   struct tok_info *ti;
 610 /*   int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2); */
 611    struct device *dev = (struct device *)(irq2dev_map[irq]);
 612 #if 0
 613    DPRINTK("Int from tok_driver, dev : %p\n",dev);
 614 #endif
 615   ti=(struct tok_info *) dev->priv;
 616 
 617   switch (ti->do_tok_int) {
 618     case NOT_FIRST:
 619 
 620         /*  Begin the regular interrupt handler HERE inline to avoid
 621             the extra levels of logic and call depth for the
 622             original solution.   */
 623 
 624 
 625         dev->interrupt=1;
 626 
 627         /* Disable interrupts till processing is finished */
 628         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
 629 
 630         /* Reset interrupt for ISA boards */
 631         if(ti->global_int_enable)
 632                 outb(0,ti->global_int_enable);
 633         
 634         status=*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
 635 
 636         if(status & ADAP_CHK_INT) {
 637                 int i;
 638                 unsigned char *check_reason=ti->mmio + ntohs(*(unsigned short *)(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
 639 
 640                 DPRINTK("adapter check interrupt\n");
 641 
 642                 DPRINTK("8 reason bytes follow: ");
 643                 for(i=0;i<      8;i++,check_reason++)
 644                         printk("%02X ",*check_reason);  
 645                 printk("\n");
 646 
 647                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=(~ADAP_CHK_INT);
 648                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN)=INT_ENABLE;
 649                 dev->interrupt=0;
 650         }       
 651 
 652         else if((*(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)) & (TCR_INT + ERR_INT + ACCESS_INT)) {
 653 
 654                 DPRINTK("adapter error: ISRP_EVEN : %02x\n",
 655                                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
 656                                 
 657                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(TCR_INT + ERR_INT + ACCESS_INT);
 658                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN)=INT_ENABLE;
 659                 dev->interrupt=0;
 660         }
 661                                         
 662         else if(status & (SRB_RESP_INT + ASB_FREE_INT + ARB_CMD_INT + SSB_RESP_INT)) {
 663 
 664                 if(status & SRB_RESP_INT) {
 665                         switch(*ti->srb) {
 666                                 case XMIT_DIR_FRAME: {
 667                                         struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
 668                                         if(xmit->ret_code!=0xff) {
 669                                                 DPRINTK("error on xmit_dir_frame request: %02X\n",xmit->ret_code);
 670                                                 if(ti->current_skb) {
 671                                                         dev_kfree_skb(ti->current_skb, FREE_WRITE);
 672                                                         ti->current_skb=NULL;
 673                                                 }
 674                                                 dev->tbusy=0;
 675                                         }                                                                                               
 676                                 }
 677                                 break;
 678                                 
 679                                 case XMIT_UI_FRAME: {
 680                                         struct srb_xmit *xmit=(struct srb_xmit *)(ti->srb);
 681                                         if(xmit->ret_code!=0xff) {
 682                                                 DPRINTK("error on xmit_ui_frame request: %02X\n",xmit->ret_code);
 683                                                 if(ti->current_skb) {
 684                                                         dev_kfree_skb(ti->current_skb, FREE_WRITE);
 685                                                         ti->current_skb=NULL;
 686                                                 }
 687                                                 dev->tbusy=0;
 688                                         }                                                                                               
 689                                 }
 690                                 break;
 691         
 692                                 case DIR_OPEN_ADAPTER: {
 693                                         struct srb_open_response *open_response=(struct srb_open_response *)(ti->init_srb);
 694 
 695                                         ti->srb=ti->sram+ntohs(open_response->srb_addr);
 696                                         ti->ssb=ti->sram+ntohs(open_response->ssb_addr);
 697                                         ti->arb=ti->sram+ntohs(open_response->arb_addr);
 698                                         ti->asb=ti->sram+ntohs(open_response->asb_addr);
 699                                         ti->current_skb=NULL;
 700 
 701                                         if(open_response->ret_code==7) {
 702                                                 if(!ti->auto_ringspeedsave && (open_response->error_code==0x24)) {
 703                                                         DPRINTK("open failed: Adapter speed must match ring speed if Automatic Ring Speed Save is disabled\n");
 704                                                         ti->open_status=FAILURE;
 705                                                         wake_up(&ti->wait_for_reset);
 706                                                 }
 707                                                 else if(open_response->error_code==0x24) 
 708                                                         DPRINTK("retrying open to adjust to ring speed\n");
 709 
 710                                                 else if((open_response->error_code==0x2d) && ti->auto_ringspeedsave)
 711                                                         DPRINTK("No signal detected for Auto Speed Detection\n");
 712                                                 else DPRINTK("Unrecoverable error: error code = %02X\n",open_response->error_code);
 713                                         }
 714                                         else if(!open_response->ret_code) {
 715 #ifndef TR_NEWFORMAT
 716                                                 DPRINTK("board opened...\n");
 717 #else
 718                                                 DPRINTK("Adapter initialized and opened.\n");
 719 #endif
 720                                                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
 721                                                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
 722                                                 open_sap(EXTENDED_SAP,dev);
 723 /* YdW probably hates me */
 724                                                 goto skip_reset;
 725                                         }
 726                                         else {  
 727                                                 DPRINTK("open failed: ret_code = %02X, retrying\n",open_response->ret_code);
 728                                         }
 729                                         if(ti->open_status!=FAILURE) {
 730                                                 tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 731                                                 tr_timer.data=(unsigned long)dev;
 732                                                 tr_timer.next=tr_timer.prev=NULL;
 733                                                 add_timer(&tr_timer);
 734                                         }
 735                                 }
 736                                 break;
 737 
 738                                 case DIR_CLOSE_ADAPTER:
 739                                         wake_up(&ti->wait_for_tok_int);
 740                                         break;
 741                                 case DLC_OPEN_SAP: {
 742                                         struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
 743                                         if(open_sap->ret_code) {
 744                                                 DPRINTK("open_sap failed: ret_code = %02X,retrying\n",open_sap->ret_code);
 745                                                 tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 746                                                 tr_timer.data=(unsigned long)dev;
 747                                                 tr_timer.next=tr_timer.prev=NULL;
 748                                                 add_timer(&tr_timer);
 749                                         }
 750                                         else {
 751                                                 ti->exsap_station_id=open_sap->station_id;
 752                                                 ti->open_status=SUCCES; /* TR adapter is now available */
 753                                                 wake_up(&ti->wait_for_reset);
 754                                         }
 755                                 }
 756                                 break;
 757 
 758                                 case DIR_INTERRUPT:
 759                                 case DIR_MOD_OPEN_PARAMS:       
 760                                 case DIR_SET_GRP_ADDR:
 761                                 case DIR_SET_FUNC_ADDR:
 762                                 case DLC_CLOSE_SAP: {
 763                                         struct srb_interrupt *intr=(struct srb_interrupt *)(ti->srb);
 764                                         if(intr->ret_code)
 765                                                 DPRINTK("error on %02X: %02X\n",intr->command,intr->ret_code);  
 766                                 }
 767                                 break;
 768 
 769                                 case DIR_READ_LOG: {
 770                                         struct srb_read_log *read_log=(struct srb_read_log *)(ti->srb);
 771                                         if(read_log->ret_code)
 772                                                 DPRINTK("error on dir_read_log: %02X\n",read_log->ret_code);
 773                                         else {
 774                                                 DPRINTK("Line errors %02X, Internal errors %02X, Burst errors %02X\n",
 775                           read_log->line_errors,read_log->internal_errors,read_log->burst_errors);
 776                                                 DPRINTK("A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n",
 777                           read_log->A_C_errors,read_log->abort_delimiters,read_log->lost_frames);
 778                                                 DPRINTK("Receive congestion count %02X, Frame copied errors %02X, Frequency errors %02X\n",
 779                           read_log->recv_congest_count,read_log->frame_copied_errors,read_log->frequency_errors);
 780                                                 DPRINTK("Token errors %02X\n",read_log->token_errors);
 781                                         }
 782                                         dev->tbusy=0;
 783                                 }
 784                                 break;
 785 
 786                                 default:
 787                                         DPRINTK("Unknown command %02X encountered\n",*(ti->srb));
 788                         }
 789                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
 790                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
 791 skip_reset:
 792                 }
 793 
 794                 if(status & ASB_FREE_INT) {
 795                         switch(*ti->asb) {
 796                                 case REC_DATA:
 797                                 case XMIT_UI_FRAME:
 798                                 case XMIT_DIR_FRAME:
 799                                         if(*(ti->asb+2)!=0xff)
 800                                                 DPRINTK("ASB error %02X in cmd %02X\n", *(ti->asb+2),*(ti->asb));
 801                                         break;
 802                                 default:
 803                                         DPRINTK("unknown command in asb %02X\n",*ti->asb);
 804                         }
 805                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ASB_FREE_INT);
 806                 }
 807 
 808                 if(status & ARB_CMD_INT) {
 809                         switch(*ti->arb) {
 810                                 case DLC_STATUS: {
 811                                         struct arb_dlc_status *dlc_status=(struct arb_dlc_status *)(ti->arb);                   
 812                                         DPRINTK("DLC_STATUS new status: %02X on station %02X\n",ntohs(dlc_status->status),ntohs(dlc_status->station_id));
 813                                 }
 814                                 break;
 815 
 816                                 case REC_DATA:
 817                                         tr_rx(dev);
 818                                         break;
 819 
 820                                 case RING_STAT_CHANGE: {
 821                                         struct arb_ring_stat_change *ring_stat_change=(struct arb_ring_stat_change *)(ti->arb);
 822                                         unsigned short ring_status=ntohs(ring_stat_change->ring_status);
 823 
 824                                         if(ring_status & (SIGNAL_LOSS + LOBE_FAULT)) {
 825                                                 DPRINTK("Signal loss/Lobe fault\n");
 826                                                 DPRINTK("We try to reopen the adapter.\n");     
 827                                                 tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 828                                                 tr_timer.data=(unsigned long)dev;
 829                                                 tr_timer.next=tr_timer.prev=NULL;
 830                                                 add_timer(&tr_timer);
 831                                         } else if (ring_status & (HARD_ERROR + XMIT_BEACON +
 832                                                                   AUTO_REMOVAL + REMOVE_RECV + RING_RECOVER))
 833                                                 DPRINTK("New ring status: %02X\n",ring_status);
 834 
 835                                         if(ring_status & LOG_OVERFLOW) {
 836                                                 *(ti->srb)=DIR_READ_LOG;
 837                                                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
 838                                                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
 839                                                 dev->tbusy=1; /* really srb busy... */
 840                                         }
 841                                 }
 842                                 break;
 843 
 844                                 case XMIT_DATA_REQ:
 845                                         tr_tx(dev);
 846                                         break;
 847 
 848                                 default:
 849                                         DPRINTK("Unknown command %02X in arb\n",*(ti->arb));
 850                                         break;
 851                         }
 852                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(ARB_CMD_INT);
 853                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=ARB_FREE;
 854                 }
 855 
 856                 if(status & SSB_RESP_INT) {
 857                         switch(*ti->ssb) {
 858                                 case XMIT_DIR_FRAME:
 859                                 case XMIT_UI_FRAME:
 860                                         if(*(ti->ssb+2))
 861                                                 DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",*(ti->ssb+2),*(ti->ssb+6));               
 862                                         else
 863                                                 ti->tr_stats.tx_packets++;
 864                                         break;
 865                                 
 866                                 case XMIT_XID_CMD:
 867                                         DPRINTK("xmit xid ret_code: %02X\n",*(ti->ssb+2));
 868                                 
 869                                 default:
 870                                         DPRINTK("Unknown command %02X in ssb\n",*(ti->ssb));
 871                         }
 872                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SSB_RESP_INT);
 873                         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=SSB_FREE;
 874                 }
 875         }       
 876 
 877         dev->interrupt=0;
 878         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
 879 
 880         return;
 881 
 882       break;
 883     case FIRST_INT:
 884       initial_tok_int(dev);
 885       break;
 886     default:
 887       DPRINTK("Unexpected interrupt from tr adapter\n");
 888   }
 889 
 890 }
 891 
 892 static void initial_tok_int(struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
 893 
 894 #ifndef TR_NEWFORMAT
 895   int i;
 896 #endif
 897   unsigned char *encoded_addr;
 898   struct tok_info *ti;
 899 
 900   ti=(struct tok_info *) dev->priv;
 901 
 902         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=(~INT_ENABLE);
 903         
 904         /* Reset interrupt for ISA boards */
 905         if(ti->global_int_enable)
 906                 outb(0,ti->global_int_enable);
 907 
 908         ti->do_tok_int=NOT_FIRST;
 909 
 910 #ifndef TR_NEWFORMAT
 911         DPRINTK("Initial tok int received\n");
 912 #endif
 913 
 914         if(!ti->sram) {  /* we assign the address for ISA devices */
 915                         /* set RRR even to D000 for shared ram address */
 916                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN)=
 917                                        ti->sram_base;
 918                 ti->sram=(char *)(ti->sram_base << 12);
 919         }
 920         ti->init_srb=ti->sram+ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
 921         SET_PAGE(ntohs(*(unsigned short *)(ti->mmio+ ACA_OFFSET + WRBR_EVEN)));
 922 
 923 #if 0
 924         DPRINTK("init_srb(%p):",ti->init_srb);
 925         for(i=0;i<17;i++)
 926                 printk("%02X ",*(ti->init_srb+i));
 927         printk("\n");
 928 #endif
 929 
 930 #ifndef TR_NEWFORMAT            
 931         DPRINTK("srb_init_response->encoded_address: %04X\n",((struct srb_init_response *)ti->init_srb)->encoded_address);
 932         DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
 933 #endif
 934         encoded_addr=(unsigned char *)(ti->sram + ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address));
 935 
 936 #ifndef TR_NEWFORMAT
 937         DPRINTK("encoded addr (%04X,%04X,%p): ",
 938                         ((struct srb_init_response *)ti->init_srb)->encoded_address,
 939                         ntohs(((struct srb_init_response *)ti->init_srb)->encoded_address),     
 940                         encoded_addr);
 941 #else
 942        DPRINTK("Initial interrupt : shared RAM located at %p.\n", encoded_addr);
 943 #endif
 944         ti->auto_ringspeedsave=((struct srb_init_response *)ti->init_srb)->init_status_2 & 0x4 ? TRUE : FALSE;
 945 
 946 #ifndef TR_NEWFORMAT
 947         for(i=0;i<TR_ALEN;i++)
 948                 printk("%02X%s",dev->dev_addr[i]=encoded_addr[i],(i==TR_ALEN-1) ? "" : ":" );
 949         printk("\n");
 950 #endif
 951 
 952         tok_open_adapter((unsigned long)dev);
 953 
 954 }
 955 
 956 static void tok_init_card(unsigned long dev_addr) {
     /* [previous][next][first][last][top][bottom][index][help] */
 957 
 958    struct tok_info *ti;
 959         short PIOaddr;
 960         int i;
 961         struct  device *dev=(struct device *)dev_addr;
 962         PIOaddr = dev->base_addr;
 963         ti=(struct tok_info *) dev->priv;
 964 
 965       /* Special processing for first interrupt after reset */
 966         ti->do_tok_int=FIRST_INT;
 967 
 968         /* Reset adapter */
 969 
 970         dev->tbusy=1; /* nothing can be done before reset and open completed */
 971 
 972 #ifdef ENABLE_PAGING
 973         if(ti->page_mask) {
 974                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN)=SRPR_ENABLE_PAGING;
 975         }
 976 #endif
 977 
 978         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN)=~(INT_ENABLE);
 979 #ifndef TR_NEWFORMAT
 980         DPRINTK("resetting card\n");
 981 #endif
 982         outb(0,PIOaddr+ADAPTRESET);
 983         for(i=jiffies+5;jiffies<=i;); /* wait 50ms */
 984         outb(0,PIOaddr+ADAPTRESETREL);
 985 #ifndef TR_NEWFORMAT
 986         DPRINTK("card reset\n");
 987 #endif
 988 
 989         ti->open_status=IN_PROGRESS;
 990 
 991         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
 992 
 993 }
 994 
 995 static void open_sap(unsigned char type,struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
 996 
 997   struct tok_info *ti=(struct tok_info *) dev->priv;
 998         struct dlc_open_sap *open_sap=(struct dlc_open_sap *)ti->srb;
 999 
1000         SET_PAGE(ti->srb);
1001         memset(open_sap,0,sizeof(struct dlc_open_sap));
1002 
1003         open_sap->command=DLC_OPEN_SAP;
1004         open_sap->max_i_field=htons(MAX_I_FIELD);
1005         open_sap->sap_options=SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY;
1006         open_sap->station_count=SAP_OPEN_STATION_CNT;
1007         open_sap->sap_value=type;
1008 
1009         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
1010 
1011 }
1012 
1013 void tok_open_adapter(unsigned long dev_addr) {
     /* [previous][next][first][last][top][bottom][index][help] */
1014 
1015         struct device *dev=(struct device *)dev_addr;
1016         struct dir_open_adapter *open_adapter;
1017   struct tok_info *ti;
1018   ti=(struct tok_info *) dev->priv;
1019 
1020         DPRINTK("now opening the board...\n");
1021 
1022         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD)=~(SRB_RESP_INT);
1023         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD)=~(CMD_IN_SRB);
1024 
1025         open_adapter=(struct dir_open_adapter *)(ti->init_srb);
1026         memset(open_adapter,0,sizeof(struct dir_open_adapter));
1027 
1028         open_adapter->command=DIR_OPEN_ADAPTER;
1029         open_adapter->open_options=htons(OPEN_PASS_BCON_MAC);
1030         open_adapter->num_rcv_buf=htons(NUM_RCV_BUF);
1031         open_adapter->rcv_buf_len=htons(RCV_BUF_LEN);
1032         open_adapter->dhb_length=htons(DHB_LENGTH);
1033         open_adapter->num_dhb=NUM_DHB;
1034         open_adapter->dlc_max_sap=DLC_MAX_SAP;
1035         open_adapter->dlc_max_sta=DLC_MAX_STA;
1036 
1037         ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
1038 
1039         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN)=INT_ENABLE;
1040         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
1041 
1042 }
1043 
1044 static void tr_tx(struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
1045 
1046   struct tok_info *ti=(struct tok_info *) dev->priv;
1047         struct asb_xmit_resp *xmit_resp=(struct asb_xmit_resp *)ti->asb;
1048         struct arb_xmit_req *xmit_req=(struct arb_xmit_req *)ti->arb;
1049         struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
1050         struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
1051         unsigned int hdr_len;
1052         unsigned char *dhb;
1053 
1054 /* */
1055   DPRINTD("ti=%p asb=(%p,%p) arb=(%p,%p) srb=(%p,%p)\n",
1056        ti , ti->asb, xmit_resp, ti->arb, xmit_req, ti->srb, xmit);
1057 /* */
1058 
1059 #if 0
1060 DPRINTK("transmitting...\n");
1061 #endif
1062 
1063         if(xmit_resp->ret_code!=0xff)  DPRINTK("ASB not free !!!\n");
1064 
1065                      /*  in providing the transmit interrupts,
1066                          is telling us it is ready for data and
1067                          providing a shared memory address for us
1068                          to stuff with data.  Here we compute the
1069                          effective address where we will place data.*/
1070   dhb=ti->sram+ntohs(xmit_req->dhb_address);
1071 
1072         xmit_resp->command=xmit->command;
1073         xmit_resp->station_id=xmit_req->station_id;
1074         xmit_resp->rsap_value=EXTENDED_SAP;
1075         xmit_resp->cmd_corr=xmit_req->cmd_corr;
1076         xmit_resp->ret_code=0;
1077 
1078         if((xmit->command==XMIT_XID_CMD) || (xmit->command==XMIT_TEST_CMD)) {
1079                 xmit_resp->frame_length=htons(0x11);
1080                 xmit_resp->hdr_length=0x0e;
1081                 dhb[0]=AC;
1082                 dhb[1]=LLC_FRAME;
1083                 memset(dhb+2,(int)0x0ff,TR_ALEN);
1084                 memset(dhb+2+TR_ALEN,0,TR_ALEN);
1085                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET
1086                                                          + ISRA_ODD)=RESP_IN_ASB;
1087                 return;
1088         }
1089 
1090      /* the token ring packet is copied from sk_buff to the adapter
1091         buffer identified in the command data received with the
1092         interrupt.  The sk_buff area was set up with a maximum
1093         sized route information field so here we must compress
1094         out the extra (all) rif fields.   */
1095      /* nb/dwm .... I re-arranged code here to avoid copy of extra
1096         bytes, ended up with fewer statements as well             */
1097 
1098      /*  TR arch. identifies if RIF present by high bit of source
1099          address.  So here we check if RIF present */
1100   if(!(trhdr->saddr[0] & 0x80)) {
1101     hdr_len=sizeof(struct trh_hdr)-18;
1102 #if 0
1103 DPRINTK(("hdr_length: %d, frame length: %ld\n",hdr_len,
1104       ti->current_skb->len-18));
1105 #endif
1106   }   /*  TR packet includes RIF data ... preserve it */
1107   else {
1108     hdr_len=((ntohs(trhdr->rcf)
1109              & TR_RCF_LEN_MASK)>>8)+sizeof(struct trh_hdr)-18;
1110 #if 0
1111 /* rework the following if activated, hdr_len <> rif_len */
1112 DPRINTK("rcf: %02X rif_len: %d\n", trhdr->rcf,wrk_len);
1113 DPRINTK("hdr_length: %d, frame length: %ld\n",sizeof(struct trh_hdr)-18+hdr_len,
1114       ti->current_skb->len-18+hdr_len);
1115 #endif
1116   }
1117 
1118   /* header length including rif is computed above, now move the data
1119      and set fields appropriately.     */
1120 
1121   memcpy(dhb,ti->current_skb->data,hdr_len);
1122   dhb+=hdr_len;
1123   xmit_resp->hdr_length= hdr_len;
1124   xmit_resp->frame_length=htons(ti->current_skb->len
1125                                 -sizeof(struct trh_hdr)+hdr_len);
1126 
1127                   /*  now copy the actual packet data next to hdr */
1128   memcpy(dhb,ti->current_skb->data+sizeof(struct trh_hdr),
1129              ti->current_skb->len-sizeof(struct trh_hdr));
1130 
1131   *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)
1132              =RESP_IN_ASB;
1133   dev->tbusy=0;
1134   dev_kfree_skb(ti->current_skb,FREE_WRITE);
1135   ti->current_skb=NULL;
1136   mark_bh(NET_BH);
1137 }
1138 
1139 static void tr_rx(struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
1140 
1141   struct tok_info *ti=(struct tok_info *) dev->priv;
1142 
1143         struct arb_rec_req *rec_req=(struct arb_rec_req *)ti->arb;
1144         struct asb_rec *rec_resp=(struct asb_rec *)ti->asb;
1145         struct rec_buf *rbuffer;        
1146         struct trllc *llc;
1147         unsigned char *data;
1148         unsigned int rbuffer_len,lan_hdr_len;
1149         struct sk_buff *skb;
1150 
1151         rbuffer=(struct rec_buf *)(ti->sram+ntohs(rec_req->rec_buf_addr));
1152 
1153         if(rec_resp->ret_code!=0xff) DPRINTK("ASB not free !!!\n");
1154 
1155         rec_resp->command=REC_DATA;
1156         rec_resp->station_id=rec_req->station_id;
1157         rec_resp->rec_buf_addr=rec_req->rec_buf_addr;
1158 
1159         lan_hdr_len=rec_req->lan_hdr_len;
1160 
1161         llc=(struct trllc *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data)+lan_hdr_len);
1162 
1163 #if 0
1164 DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",offsetof(struct rec_buf,data),lan_hdr_len);
1165 DPRINTK("llc: %p rec_buf_addr: %04X ti->sram: %p\n",llc,ntohs(rec_req->rec_buf_addr),ti->sram);
1166 DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, ethertype: %04X\n",
1167                         llc->dsap,llc->ssap,llc->llc,llc->protid[0],llc->protid[1],llc->protid[2],llc->ethertype);
1168 #endif
1169 
1170         if(llc->llc!=UI_CMD) {
1171 #ifndef TR_FILTERNONUI          
1172                 DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",llc->llc);
1173 #endif
1174                 rec_resp->ret_code=DATA_LOST;
1175                 ti->tr_stats.rx_dropped++;
1176                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
1177                 return;
1178         }
1179 
1180 #if 0
1181         if((llc->dsap!=0xaa) || (llc->ssap!=0xaa)) {
1182 
1183         struct trh_hdr *trhdr=(struct trh_hdr *)((unsigned char *)rbuffer+offsetof(struct rec_buf,data));
1184 
1185 DPRINTK("Probably non-IP frame received.\n");
1186 DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
1187                         llc->ssap,llc->dsap,trhdr->saddr[0],trhdr->saddr[1],trhdr->saddr[2],trhdr->saddr[3],trhdr->saddr[4],trhdr->saddr[5],
1188                         trhdr->daddr[0],trhdr->daddr[1],trhdr->daddr[2],trhdr->daddr[3],trhdr->daddr[4],trhdr->daddr[5]);
1189         }
1190 #endif
1191 
1192 
1193         if(!(skb=dev_alloc_skb(ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr)))) {
1194                 DPRINTK("out of memory. frame dropped.\n");     
1195                 ti->tr_stats.rx_dropped++;
1196                 rec_resp->ret_code=DATA_LOST;
1197                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
1198                 return;
1199         }
1200 
1201         skb_put(skb,ntohs(rec_req->frame_len)-lan_hdr_len+sizeof(struct trh_hdr));
1202         skb->dev=dev;
1203 
1204 #if 0
1205 DPRINTK("Now copying data...\n");
1206 #endif
1207 
1208 
1209         data=skb->data;
1210         memcpy(data,&(rbuffer->data),lan_hdr_len);
1211 
1212 
1213         if(lan_hdr_len<sizeof(struct trh_hdr))
1214                 memset(data+lan_hdr_len,0,sizeof(struct trh_hdr)-lan_hdr_len);
1215 
1216         data+=sizeof(struct trh_hdr);
1217         rbuffer_len=ntohs(rbuffer->buf_len)-lan_hdr_len;
1218 #if 0
1219 DPRINTK("rbuffer_len: %d, data: %p\n",rbuffer_len,data);
1220 #endif
1221         memcpy(data,(unsigned char *)(&(rbuffer->data))+lan_hdr_len,rbuffer_len);
1222         data+=rbuffer_len;
1223 
1224 
1225         if(rbuffer->buf_ptr)
1226                 for(rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2);
1227                                 memcpy(data,&(rbuffer->data),rbuffer_len=ntohs(rbuffer->buf_len)),rbuffer->buf_ptr;
1228                                 data+=rbuffer_len,rbuffer=(struct rec_buf *)(ti->sram+ntohs(rbuffer->buf_ptr)-2))
1229 #if 0
1230         DPRINTK("buf_ptr: %d,data =%p\n",ntohs(rbuffer->buf_ptr),data);
1231 #endif
1232 
1233         rec_resp->ret_code=0;
1234 
1235         *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=RESP_IN_ASB;
1236 
1237         ti->tr_stats.rx_packets++;
1238 
1239         skb->protocol=tr_type_trans(skb,dev);
1240         netif_rx(skb);
1241 
1242         return;
1243 }
1244 
1245 static int tok_send_packet(struct sk_buff *skb, struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
1246 
1247   struct tok_info *ti=(struct tok_info *) dev->priv;
1248 
1249 #if 0
1250 DPRINTK("tada: sending packet...\n");
1251 #endif
1252 
1253         if (dev->tbusy) {
1254                 int ticks_waited=jiffies - dev->trans_start;
1255                 if(ticks_waited<5)
1256                         return 1;
1257                 DPRINTK("Arrg. Transmitter busy for more than 50 msec. Donald resets adapter, but resetting\n \
1258 the IBM tokenring adapter takes a long time. It might not even help when the\n \
1259 ring is very busy, so we just wait a little longer and hope for the best.\n");          
1260                 dev->trans_start+=5; /* we fake the transmission start time... */
1261                 return 1;
1262         }
1263 
1264         /* Donald does this, so we do too. */
1265 
1266         if(skb==NULL) {
1267                 dev_tint(dev);
1268                 return 0;
1269         }
1270 
1271         if(set_bit(0,(void *)&dev->tbusy)!=0)
1272                 DPRINTK("Transmitter access conflict\n");
1273         else {
1274                 struct srb_xmit *xmit=(struct srb_xmit *)ti->srb;
1275 
1276                 ti->current_skb=skb; /* save skb. We will need it when the adapter
1277                                   asks for the data */
1278                 xmit->command=XMIT_UI_FRAME;
1279                 xmit->station_id=ti->exsap_station_id;
1280                 *(unsigned char *)(ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD)=CMD_IN_SRB;
1281                 dev->trans_start=jiffies;
1282         }
1283 
1284         return 0;
1285 }       
1286 
1287 /* tok_get_stats():  Basically a scaffold routine which will return
1288          the address of the tr_statistics structure associated with
1289          this device -- the tr.... structure is a ethnet look-alike
1290          so at least for this iteration may suffice.   */
1291 
1292 static struct enet_statistics * tok_get_stats(struct device *dev) {
     /* [previous][next][first][last][top][bottom][index][help] */
1293 
1294   struct tok_info *toki;
1295   toki=(struct tok_info *) dev->priv;
1296   return (struct enet_statistics *) &toki->tr_stats;
1297 }
1298 
1299 #ifdef MODULE
1300 char kernel_version[] = UTS_RELEASE;
1301 static char devicename[9] = { 0, };
1302 static struct device dev_ibmtr = {
1303         devicename, /* device name is inserted by linux/drivers/net/net_init.c */
1304         0, 0, 0, 0,
1305         0, 0,
1306         0, 0, 0, NULL, tok_probe };
1307 
1308 int io = 0xa20;
1309 
1310 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1311 {
1312         if (io == 0)
1313                 printk("ibmtr: You should not use auto-probing with insmod!\n");
1314         dev_ibmtr.base_addr = io;
1315         dev_ibmtr.irq       = 0;
1316         if (register_netdev(&dev_ibmtr) != 0) {
1317                 printk("ibmtr: register_netdev() returned non-zero.\n");
1318                 return -EIO;
1319         }
1320         return 0;
1321 }
1322 
1323 void
1324 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1325 {
1326         if (MOD_IN_USE)
1327                 printk("ibmtr: device busy, remove delayed\n");
1328         else
1329         {
1330                 unregister_netdev(&dev_ibmtr);
1331 
1332                 /* If we don't do this, we can't re-insmod it later. */
1333                 free_irq(dev_ibmtr.irq);
1334                 irq2dev_map[dev_ibmtr.irq] = NULL;
1335                 release_region(dev_ibmtr.base_addr, TR_IO_EXTENT);
1336         }
1337 }
1338 #endif /* MODULE */

/* [previous][next][first][last][top][bottom][index][help] */