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

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

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