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. HWPrtChanID
  5. tok_probe

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

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