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

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