root/drivers/net/ibmtr.c

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

DEFINITIONS

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

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