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

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