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

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