root/drivers/net/ibmtr.c

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

DEFINITIONS

This source file includes following definitions.
  1. adapter_def
  2. DummyCall
  3. PrtChanID
  4. tok_probe
  5. get_sram_size
  6. tok_open
  7. tok_close
  8. tok_interrupt
  9. initial_tok_int
  10. tok_init_card
  11. open_sap
  12. tok_open_adapter
  13. tr_tx
  14. tr_rx
  15. tok_send_packet
  16. tok_get_stats
  17. init_module
  18. cleanup_module

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

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