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    Chagnes 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 definately 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-existant 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         dev->open=tok_open;
 547         dev->stop=tok_close;
 548         dev->hard_start_xmit=tok_send_packet;
 549         dev->get_stats = NULL;
 550         dev->get_stats = tok_get_stats;
 551         dev->set_multicast_list = NULL;
 552         tr_setup(dev);
 553         tok_init_card((unsigned long)dev);
 554         
 555         return 0;  /* Return 0 to indicate we have found a Token Ring card. */
 556 }
 557 
 558 /* query the adapter for the size of shared RAM  */
 559 
 560 unsigned char get_sram_size(struct tok_info *adapt_info)
 561 {
 562                 
 563         unsigned char avail_sram_code;
 564         static unsigned char size_code[]={ 0,16,32,64,127,128 };
 565         
 566         /* Adapter gives
 567            'F' -- use RRR bits 3,2
 568            'E' -- 8kb   'D' -- 16kb
 569            'C' -- 32kb  'A' -- 64KB
 570            'B' - 64KB less 512 bytes at top
 571            (WARNING ... must zero top bytes in INIT */
 572 
 573         avail_sram_code=0xf-readb(adapt_info->mmio + AIPAVAILSHRAM);
 574         if (avail_sram_code) 
 575                 return size_code[avail_sram_code];
 576         else  /* for code 'F', must compute size from RRR(3,2) bits */
 577                 return 1<<((readb(adapt_info->mmio+ ACA_OFFSET + ACA_RW + RRR_ODD)>>2)+4);
 578 }
 579 
 580 static int tok_open(struct device *dev) 
 581 {
 582         struct tok_info *ti=(struct tok_info *)dev->priv;
 583         
 584         if (ti->open_status==CLOSED) tok_init_card((unsigned long)dev);
 585         
 586         if (ti->open_status==IN_PROGRESS) sleep_on(&ti->wait_for_reset);
 587         
 588         if (ti->open_status==SUCCES) {
 589                 dev->tbusy=0;
 590                 dev->interrupt=0;
 591                 dev->start=1;
 592                 /* NEED to see smem size *AND* reset high 512 bytes if needed */
 593                 
 594                 MOD_INC_USE_COUNT;
 595                 
 596                 return 0;
 597         } else return -EAGAIN;
 598         
 599 }
 600 
 601 static int tok_close(struct device *dev) 
 602 {
 603         
 604         struct tok_info *ti=(struct tok_info *) dev->priv;
 605         
 606         writeb(DIR_CLOSE_ADAPTER, 
 607                ti->srb + offsetof(struct srb_close_adapter, command));
 608         writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 609         
 610         ti->open_status=CLOSED;
 611         
 612         sleep_on(&ti->wait_for_tok_int);                
 613         
 614         if (readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)))
 615                 DPRINTK("close adapter failed: %02X\n",
 616                         (int)readb(ti->srb + offsetof(struct srb_close_adapter, ret_code)));
 617                 
 618         MOD_DEC_USE_COUNT;
 619         
 620         return 0;
 621 }
 622 
 623 void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 624 {
 625         unsigned char status;
 626         struct tok_info *ti;
 627         struct device *dev = (struct device *)(irq2dev_map[irq]);
 628         
 629 #if TR_VERBOSE
 630         DPRINTK("Int from tok_driver, dev : %p\n",dev);
 631 #endif
 632         
 633         ti=(struct tok_info *) dev->priv;
 634         
 635         switch (ti->do_tok_int) {
 636                 
 637               case NOT_FIRST:
 638                 
 639                 /*  Begin the regular interrupt handler HERE inline to avoid
 640                     the extra levels of logic and call depth for the
 641                     original solution.   */
 642                 
 643                 dev->interrupt=1;
 644                 
 645                 /* Disable interrupts till processing is finished */
 646                 writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 647 
 648                 /* Reset interrupt for ISA boards */
 649                 if (ti->global_int_enable)
 650                         outb(0, ti->global_int_enable);
 651                 
 652                 status=readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD);
 653                 
 654                 if (status & ADAP_CHK_INT) {
 655                         
 656                         int i;
 657                         __u32 check_reason;
 658 
 659                         check_reason=ti->mmio + ntohs(readw(ti->mmio + ACA_OFFSET + ACA_RW +WWCR_EVEN));
 660                         
 661                         DPRINTK("Adapter check interrupt\n");
 662                         DPRINTK("8 reason bytes follow: ");
 663                         for(i=0; i<8; i++, check_reason++)
 664                                 printk("%02X ", (int)readb(check_reason));      
 665                         printk("\n");
 666                         
 667                         writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 668                         writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
 669                         dev->interrupt=0;
 670                         
 671                 }       else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)
 672                                  & (TCR_INT | ERR_INT | ACCESS_INT)) {
 673                         
 674                         DPRINTK("adapter error: ISRP_EVEN : %02x\n", 
 675                                 (int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));
 676                         writeb(~(TCR_INT | ERR_INT | ACCESS_INT),
 677                                ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 678                         writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);
 679                         dev->interrupt=0;
 680 
 681                 } else if (status 
 682                            & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {
 683                         /* SRB, ASB, ARB or SSB response */
 684                         
 685                         if (status & SRB_RESP_INT) { /* SRB response */
 686                                 
 687                                 switch(readb(ti->srb)) { /* SRB command check */
 688                                         
 689                                       case XMIT_DIR_FRAME: {
 690                                               unsigned char xmit_ret_code;
 691                                               
 692                                               xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
 693                                               if (xmit_ret_code != 0xff) {
 694                                                       DPRINTK("error on xmit_dir_frame request: %02X\n", 
 695                                                               xmit_ret_code);
 696                                                       if (ti->current_skb) {
 697                                                               dev_kfree_skb(ti->current_skb, FREE_WRITE);
 698                                                               ti->current_skb=NULL;
 699                                                       }
 700                                                       dev->tbusy=0;
 701                                               }
 702                                       }
 703                                       break;
 704                                       
 705                                       case XMIT_UI_FRAME: {
 706                                               unsigned char xmit_ret_code;
 707                                               
 708                                               xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));
 709                                               if (xmit_ret_code != 0xff) {
 710                                                       DPRINTK("error on xmit_ui_frame request: %02X\n",
 711                                                               xmit_ret_code);
 712                                                       if (ti->current_skb) {
 713                                                               dev_kfree_skb(ti->current_skb, FREE_WRITE);
 714                                                               ti->current_skb=NULL;
 715                                                       }
 716                                                       dev->tbusy=0;
 717                                               }
 718                                       }
 719                                       break;
 720                                       
 721                                       case DIR_OPEN_ADAPTER: {
 722                                               unsigned char open_ret_code;
 723                                               __u16 open_error_code;
 724                                               
 725                                               ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));
 726                                               ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));
 727                                               ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));
 728                                               ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));
 729                                               ti->current_skb=NULL;
 730                                               
 731                                               open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
 732                                               open_error_code = readw(ti->init_srb +offsetof(struct srb_open_response, error_code));
 733 
 734                                               if (open_ret_code==7) {
 735                                                       
 736                                                       if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {
 737                                                               DPRINTK("open failed: Adapter speed must match ring "
 738                                                                       "speed if Automatic Ring Speed Save is disabled\n");
 739                                                               ti->open_status=FAILURE;
 740                                                               wake_up(&ti->wait_for_reset);
 741                                                       } else if (open_error_code==0x24)
 742                                                               DPRINTK("retrying open to adjust to ring speed\n");
 743                                                       else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
 744                                                               DPRINTK("No signal detected for Auto Speed Detection\n");
 745                                                       else DPRINTK("Unrecoverable error: error code = %02X\n", 
 746                                                                    open_error_code);
 747                                                       
 748                                               } else if (!open_ret_code) {
 749 #if !TR_NEWFORMAT
 750                                                       DPRINTK("board opened...\n");
 751 #else
 752                                                       DPRINTK("Adapter initialized and opened.\n");
 753 #endif
 754                                                       writeb(~(SRB_RESP_INT), 
 755                                                              ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 756                                                       writeb(~(CMD_IN_SRB), 
 757                                                              ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
 758                                                       open_sap(EXTENDED_SAP,dev);
 759                                                       
 760                                                       /* YdW probably hates me */
 761                                                       goto skip_reset;
 762                                               } else
 763                                                       DPRINTK("open failed: ret_code = %02X, retrying\n",
 764                                                               open_ret_code);
 765                                               
 766                                               if (ti->open_status != FAILURE) {
 767                                                       tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 768                                                       tr_timer.data=(unsigned long)dev;
 769                                                       tr_timer.next=tr_timer.prev=NULL;
 770                                                       add_timer(&tr_timer);
 771                                               }
 772                                               
 773                                       }
 774                                       break;
 775                                       
 776                                       case DIR_CLOSE_ADAPTER:
 777                                         wake_up(&ti->wait_for_tok_int);
 778                                         break;
 779                                         
 780                                       case DLC_OPEN_SAP:
 781                                         if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {
 782                                                 DPRINTK("open_sap failed: ret_code = %02X,retrying\n",
 783                                                         (int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));
 784                                                 tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 785                                                 tr_timer.data=(unsigned long)dev;
 786                                                 tr_timer.next=tr_timer.prev=NULL;
 787                                                 add_timer(&tr_timer);
 788                                         } else {
 789                                                 ti->exsap_station_id=
 790                                                         readw(ti->srb+offsetof(struct dlc_open_sap, station_id));
 791                                                 ti->open_status=SUCCES; /* TR adapter is now available */
 792                                                 wake_up(&ti->wait_for_reset);
 793                                         }
 794                                         break;
 795                                         
 796                                       case DIR_INTERRUPT:
 797                                       case DIR_MOD_OPEN_PARAMS: 
 798                                       case DIR_SET_GRP_ADDR:
 799                                       case DIR_SET_FUNC_ADDR:
 800                                       case DLC_CLOSE_SAP:
 801                                         if (readb(ti->srb+offsetof(struct srb_interrupt, ret_code)))
 802                                                 DPRINTK("error on %02X: %02X\n",
 803                                                         (int)readb(ti->srb+offsetof(struct srb_interrupt, command)),
 804                                                         (int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));
 805                                         break;
 806                                         
 807                                       case DIR_READ_LOG:
 808                                         if (readb(ti->srb+offsetof(struct srb_read_log, ret_code)))
 809                                                 DPRINTK("error on dir_read_log: %02X\n",
 810                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, ret_code)));
 811                                         else
 812                                                 DPRINTK(
 813                                                         "Line errors %02X, Internal errors %02X, Burst errors %02X\n"
 814                                                         "A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"
 815                                                         "Receive congestion count %02X, Frame copied errors %02X\n"
 816                                                         "Frequency errors %02X, Token errors %02X\n",
 817                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 818                                                                                     line_errors)),
 819                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 820                                                                                     internal_errors)),
 821                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 822                                                                                     burst_errors)),
 823                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),
 824                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 825                                                                                     abort_delimiters)),
 826                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 827                                                                                     lost_frames)),
 828                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 829                                                                                                     recv_congest_count)),
 830                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 831                                                                                     frame_copied_errors)),
 832                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 833                                                                                     frequency_errors)),
 834                                                         (int)readb(ti->srb+offsetof(struct srb_read_log, 
 835                                                                                                     token_errors)));
 836                                         dev->tbusy=0;
 837                                         break;
 838                                         
 839                                       default:
 840                                         DPRINTK("Unknown command %02X encountered\n",
 841                                                 (int)readb(ti->srb));
 842                                         
 843                                 } /* SRB command check */
 844                                 
 845                                 writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
 846                                 writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 847                                 
 848                           skip_reset:
 849                         } /* SRB response */
 850                         
 851                         if (status & ASB_FREE_INT) { /* ASB response */
 852                                 
 853                                 switch(readb(ti->asb)) { /* ASB command check */
 854                                         
 855                                       case REC_DATA:
 856                                       case XMIT_UI_FRAME:
 857                                       case XMIT_DIR_FRAME:
 858                                         if (readb(ti->asb+2)!=0xff) /* checks ret_code */
 859                                                 DPRINTK("ASB error %02X in cmd %02X\n", 
 860                                                         (int)readb(ti->asb+2), 
 861                                                                         (int)readb(ti->asb));
 862                                         break;
 863                                         
 864                                       default:
 865                                         DPRINTK("unknown command in asb %02X\n",
 866                                                 (int)readb(ti->asb));
 867                                         
 868                                 } /* ASB command check */
 869                                 
 870                                 writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 871                                 
 872                         } /* ASB response */
 873                         
 874                         if (status & ARB_CMD_INT) { /* ARB response */
 875                                 
 876                                 switch (readb(ti->arb)) { /* ARB command check */
 877                                         
 878                                       case DLC_STATUS:
 879                                         DPRINTK("DLC_STATUS new status: %02X on station %02X\n", 
 880                                                 ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),
 881                                                 ntohs(readw(ti->arb 
 882                                                                             +offsetof(struct arb_dlc_status, station_id))));
 883                                         break;
 884                                         
 885                                       case REC_DATA:
 886                                         tr_rx(dev);
 887                                         break;
 888                                         
 889                                       case RING_STAT_CHANGE: {
 890                                               unsigned short ring_status;
 891                                               
 892                                               ring_status=ntohs(readw(ti->arb
 893                                                                       +offsetof(struct arb_ring_stat_change, ring_status)));
 894                                               
 895                                               if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {
 896                                                       
 897                                                       DPRINTK("Signal loss/Lobe fault\n");
 898                                                       DPRINTK("We try to reopen the adapter.\n");       
 899                                                       tr_timer.expires=jiffies+TR_RETRY_INTERVAL;
 900                                                       tr_timer.data=(unsigned long)dev;
 901                                                       tr_timer.next=tr_timer.prev=NULL;
 902                                                       add_timer(&tr_timer);
 903                                                       
 904                                               } else if (ring_status & (HARD_ERROR | XMIT_BEACON 
 905                                                                                         | AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))
 906                                                       DPRINTK("New ring status: %02X\n", ring_status);
 907                                               
 908                                               if (ring_status & LOG_OVERFLOW) {
 909                                                       
 910                                                       writeb(DIR_READ_LOG, ti->srb);
 911                                                       writeb(INT_ENABLE, 
 912                                                              ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
 913                                                       writeb(CMD_IN_SRB, 
 914                                                              ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 915                                                       dev->tbusy=1; /* really srb busy... */
 916                                                       
 917                                               }
 918                                       }
 919                                       break;
 920                                       
 921                                       case XMIT_DATA_REQ:
 922                                         tr_tx(dev);
 923                                         break;
 924                                         
 925                                       default:
 926                                         DPRINTK("Unknown command %02X in arb\n", 
 927                                                 (int)readb(ti->arb));
 928                                         break;
 929                                         
 930                                 } /* ARB command check */
 931                                 
 932                                 writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 933                                 writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 934                                 
 935                         } /* ARB response */
 936                         
 937                         if (status & SSB_RESP_INT) { /* SSB response */
 938                                                 
 939                                 switch (readb(ti->ssb)) { /* SSB command check */
 940                                         
 941                                       case XMIT_DIR_FRAME:
 942                                       case XMIT_UI_FRAME:
 943                                         if (readb(ti->ssb+2)) /* checks ret_code */
 944                                                 DPRINTK("xmit ret_code: %02X xmit error code: %02X\n", 
 945                                                         (int)readb(ti->ssb+2), (int)readb(ti->ssb+6));          
 946                                         else ti->tr_stats.tx_packets++;
 947                                         break;
 948                                         
 949                                       case XMIT_XID_CMD:
 950                                         DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2));
 951                                         
 952                                       default:
 953                                         DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb));
 954                                         
 955                                 } /* SSB command check */
 956                                 
 957                                 writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 958                                 writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 959                                 
 960                         } /* SSB response */
 961                         
 962                 }        /* SRB, ARB, ASB or SSB response */
 963                 
 964                 dev->interrupt=0;
 965                 writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
 966                 break;
 967 
 968               case FIRST_INT:
 969                 initial_tok_int(dev);
 970                 break;
 971                 
 972               default:
 973                 DPRINTK("Unexpected interrupt from tr adapter\n");
 974 
 975         }
 976 }
 977 
 978 static void initial_tok_int(struct device *dev) 
 979 {
 980 
 981         __u32 encoded_addr;
 982         __u32 hw_encoded_addr;
 983         struct tok_info *ti;
 984         
 985         ti=(struct tok_info *) dev->priv;
 986         
 987         writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 988         
 989         /* Reset interrupt for ISA boards */
 990         if (ti->global_int_enable) outb(0,ti->global_int_enable);
 991         
 992         ti->do_tok_int=NOT_FIRST;
 993         
 994 #ifndef TR_NEWFORMAT
 995         DPRINTK("Initial tok int received\n");
 996 #endif
 997 
 998         /* we assign the address for ISA devices; set RRR even to D000 for 
 999            shared RAM address */
1000         if(!ti->sram) {
1001                 writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
1002                 ti->sram=((__u32)ti->sram_base << 12);
1003         }
1004         ti->init_srb=ti->sram
1005                 +ntohs((unsigned short)readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN));
1006         SET_PAGE(ntohs((unsigned short)readw(ti->mmio+ACA_OFFSET + WRBR_EVEN)));
1007         
1008 #if TR_VERBOSE
1009         {
1010                 int i;
1011                 DPRINTK("init_srb(%p):", ti->init_srb);
1012                 for (i=0;i<17;i++) printk("%02X ", (int)readb(ti->init_srb+i));
1013                 printk("\n");
1014         }
1015 #endif
1016         
1017         hw_encoded_addr = readw(ti->init_srb 
1018                                 + offsetof(struct srb_init_response, encoded_address));
1019         
1020 #if !TR_NEWFORMAT               
1021         DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);
1022         DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",
1023                 ntohs(hw_encoded_addr));
1024 #endif
1025         
1026         encoded_addr=(ti->sram + ntohs(hw_encoded_addr));
1027         
1028 #if !TR_NEWFORMAT
1029         DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr, 
1030                 ntohs(hw_encoded_addr), encoded_addr);
1031 #else
1032         DPRINTK("Initial interrupt : shared RAM located at %08X.\n", encoded_addr);
1033 #endif  
1034         
1035         ti->auto_ringspeedsave=readb(ti->init_srb
1036                                      +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;
1037         
1038 #if !TR_NEWFORMAT
1039         for(i=0;i<TR_ALEN;i++) {
1040                 dev->dev_addr[i]=readb(encoded_addr + i);
1041                 printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" );
1042         }
1043         printk("\n");
1044 #endif
1045         
1046         tok_open_adapter((unsigned long)dev);
1047 }
1048 
1049 static void tok_init_card(unsigned long dev_addr) 
1050 {
1051         struct tok_info *ti;
1052         short PIOaddr;
1053         int i;
1054         struct device *dev=(struct device *)dev_addr;
1055         PIOaddr = dev->base_addr;
1056         ti=(struct tok_info *) dev->priv;
1057         
1058         /* Special processing for first interrupt after reset */
1059         ti->do_tok_int=FIRST_INT;
1060         
1061         /* Reset adapter */
1062         dev->tbusy=1; /* nothing can be done before reset and open completed */
1063         
1064 #ifdef ENABLE_PAGING
1065         if(ti->page_mask)
1066                 writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);
1067 #endif
1068         
1069         writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
1070         
1071 #if !TR_NEWFORMAT
1072         DPRINTK("resetting card\n");
1073 #endif
1074         
1075         outb(0, PIOaddr+ADAPTRESET);
1076         for (i=jiffies+TR_RESET_INTERVAL; jiffies<=i;); /* wait 50ms */
1077         outb(0,PIOaddr+ADAPTRESETREL);
1078         
1079 #if !TR_NEWFORMAT
1080         DPRINTK("card reset\n");
1081 #endif
1082         
1083         ti->open_status=IN_PROGRESS;
1084         writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
1085                 
1086 }
1087 
1088 static void open_sap(unsigned char type,struct device *dev) 
1089 {
1090         int i;
1091         struct tok_info *ti=(struct tok_info *) dev->priv;
1092         
1093         SET_PAGE(ti->srb);
1094         for (i=0; i<sizeof(struct dlc_open_sap); i++)
1095                 writeb(0, ti->srb+i);
1096         
1097         writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));
1098         writew(htons(MAX_I_FIELD), 
1099                ti->srb + offsetof(struct dlc_open_sap, max_i_field));
1100         writeb(SAP_OPEN_IND_SAP | SAP_OPEN_PRIORITY, 
1101                ti->srb + offsetof(struct dlc_open_sap, sap_options));
1102         writeb(SAP_OPEN_STATION_CNT, 
1103                ti->srb + offsetof(struct dlc_open_sap, station_count));
1104         writeb(type, ti->srb + offsetof(struct dlc_open_sap, sap_value));
1105         
1106         writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1107 
1108 }
1109 
1110 void tok_open_adapter(unsigned long dev_addr) 
1111 {
1112         
1113         struct device *dev=(struct device *)dev_addr;
1114         struct tok_info *ti;
1115         int i;
1116         
1117         ti=(struct tok_info *) dev->priv;
1118         
1119 #if !TR_NEWFORMAT
1120         DPRINTK("now opening the board...\n");
1121 #endif
1122         
1123         writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
1124         writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);
1125         
1126         for (i=0; i<sizeof(struct dir_open_adapter); i++)
1127                 writeb(0, ti->init_srb+i);
1128         
1129         writeb(DIR_OPEN_ADAPTER, 
1130                ti->init_srb + offsetof(struct dir_open_adapter, command));
1131         writew(htons(OPEN_PASS_BCON_MAC), 
1132                ti->init_srb + offsetof(struct dir_open_adapter, open_options));
1133         writew(htons(NUM_RCV_BUF), 
1134                ti->init_srb + offsetof(struct dir_open_adapter, num_rcv_buf));
1135         writew(htons(RCV_BUF_LEN), 
1136                ti->init_srb + offsetof(struct dir_open_adapter, rcv_buf_len));
1137         writew(htons(DHB_LENGTH), 
1138                ti->init_srb + offsetof(struct dir_open_adapter, dhb_length));
1139         writeb(NUM_DHB, 
1140                ti->init_srb + offsetof(struct dir_open_adapter, num_dhb));
1141         writeb(DLC_MAX_SAP, 
1142                ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sap));
1143         writeb(DLC_MAX_STA, 
1144                ti->init_srb + offsetof(struct dir_open_adapter, dlc_max_sta));
1145         
1146         ti->srb=ti->init_srb; /* We use this one in the interrupt handler */
1147         
1148         writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
1149         writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1150         
1151 }
1152 
1153 static void tr_tx(struct device *dev) 
1154 {
1155         struct tok_info *ti=(struct tok_info *) dev->priv;
1156         struct trh_hdr *trhdr=(struct trh_hdr *)ti->current_skb->data;
1157         unsigned int hdr_len;
1158         __u32 dhb;
1159         unsigned char xmit_command;
1160         int i;
1161         
1162         if (readb(ti->asb + offsetof(struct asb_xmit_resp, ret_code))!=0xFF)
1163                 DPRINTK("ASB not free !!!\n");
1164         
1165         /* in providing the transmit interrupts,
1166            is telling us it is ready for data and
1167            providing a shared memory address for us
1168            to stuff with data.  Here we compute the
1169            effective address where we will place data.*/
1170         dhb=ti->sram 
1171                 +ntohs(readw(ti->arb + offsetof(struct arb_xmit_req, dhb_address)));
1172         
1173         xmit_command = readb(ti->srb + offsetof(struct srb_xmit, command));
1174         
1175         writeb(xmit_command, ti->asb + offsetof(struct asb_xmit_resp, command));
1176         writew(readb(ti->srb + offsetof(struct srb_xmit, station_id)),
1177                ti->asb + offsetof(struct asb_xmit_resp, station_id));
1178         writeb(EXTENDED_SAP, ti->asb + offsetof(struct asb_xmit_resp, rsap_value));
1179         writeb(readb(ti->srb + offsetof(struct srb_xmit, cmd_corr)),
1180                ti->asb + offsetof(struct asb_xmit_resp, cmd_corr));
1181         writeb(0, ti->asb + offsetof(struct asb_xmit_resp, ret_code));
1182         
1183         if ((xmit_command==XMIT_XID_CMD) || (xmit_command==XMIT_TEST_CMD)) {
1184                 
1185                 writew(htons(0x11), 
1186                        ti->asb + offsetof(struct asb_xmit_resp, frame_length));
1187                 writeb(0x0e, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
1188                 writeb(AC, dhb);
1189                 writeb(LLC_FRAME, dhb+1);
1190                 
1191                 for (i=0; i<TR_ALEN; i++) writeb((int)0x0FF, dhb+i+2);
1192                 for (i=0; i<TR_ALEN; i++) writeb(0, dhb+i+TR_ALEN+2);
1193                 
1194                 writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1195                 return;
1196                 
1197         }
1198         
1199         /* the token ring packet is copied from sk_buff to the adapter
1200            buffer identified in the command data received with the
1201            interrupt.  The sk_buff area was set up with a maximum
1202            sized route information field so here we must compress
1203            out the extra (all) rif fields.   */
1204         /* nb/dwm .... I re-arranged code here to avoid copy of extra
1205            bytes, ended up with fewer statements as well. */
1206         
1207         /* TR arch. identifies if RIF present by high bit of source
1208            address.  So here we check if RIF present */
1209 
1210         if (!(trhdr->saddr[0] & 0x80)) { /* RIF present : preserve it */
1211                 hdr_len=sizeof(struct trh_hdr)-18;
1212                 
1213 #if TR_VERBOSE
1214                 DPRINTK("hdr_length: %d, frame length: %ld\n", hdr_len,
1215                         ti->current_skb->len-18);
1216 #endif
1217         } else hdr_len=((ntohs(trhdr->rcf) & TR_RCF_LEN_MASK)>>8)
1218                   +sizeof(struct trh_hdr)-18;
1219         
1220         /* header length including rif is computed above, now move the data
1221            and set fields appropriately. */
1222         for (i=0; i<hdr_len; i++)
1223                 writeb(*(unsigned char *)(ti->current_skb->data +i), dhb++);
1224         
1225         writeb(hdr_len, ti->asb + offsetof(struct asb_xmit_resp, hdr_length));
1226         writew(htons(ti->current_skb->len-sizeof(struct trh_hdr)+hdr_len),
1227                ti->asb + offsetof(struct asb_xmit_resp, frame_length));
1228         
1229         /*  now copy the actual packet data next to hdr */
1230         for (i=0; i<ti->current_skb->len-sizeof(struct trh_hdr); i++)
1231                 writeb(*(unsigned char *)(ti->current_skb->data +sizeof(struct trh_hdr)+i),
1232                        dhb+i);
1233         
1234         writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1235         dev->tbusy=0;
1236         dev_kfree_skb(ti->current_skb,FREE_WRITE);
1237         ti->current_skb=NULL;
1238         mark_bh(NET_BH);
1239 }
1240 
1241 static void tr_rx(struct device *dev) 
1242 {
1243         int i;
1244         struct tok_info *ti=(struct tok_info *) dev->priv;
1245         __u32 rbuffer;  
1246         __u32 llc;
1247         unsigned char *data;
1248         unsigned int rbuffer_len, lan_hdr_len;
1249         unsigned int arb_frame_len;
1250         struct sk_buff *skb;
1251         
1252         rbuffer=(ti->sram
1253                  +ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))));
1254         
1255         if(readb(ti->asb + offsetof(struct asb_rec, ret_code))!=0xFF)
1256                 DPRINTK("ASB not free !!!\n");
1257         
1258         writeb(REC_DATA, 
1259                ti->asb + offsetof(struct asb_rec, command));
1260         writew(readw(ti->arb + offsetof(struct arb_rec_req, station_id)),
1261                ti->asb + offsetof(struct asb_rec, station_id));
1262         writew(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr)),
1263                ti->asb + offsetof(struct asb_rec, rec_buf_addr));
1264         
1265         lan_hdr_len=readb(ti->arb + offsetof(struct arb_rec_req, lan_hdr_len));
1266         
1267         llc=(rbuffer+offsetof(struct rec_buf, data) + lan_hdr_len);
1268         
1269 #if TR_VERBOSE
1270         DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
1271                 (unsigned int)offsetof(struct rec_buf,data), (unsigned int)lan_hdr_len);
1272         DPRINTK("llc: %08X rec_buf_addr: %04X ti->sram: %p\n", llc,
1273                 ntohs(readw(ti->arb + offsetof(struct arb_rec_req, rec_buf_addr))), 
1274                 ti->sram);
1275         DPRINTK("dsap: %02X, ssap: %02X, llc: %02X, protid: %02X%02X%02X, "
1276                 "ethertype: %04X\n",
1277                 (int)readb(llc + offsetof(struct trllc, dsap)),
1278                 (int)readb(llc + offsetof(struct trllc, ssap)),
1279                 (int)readb(llc + offsetof(struct trllc, protid)),
1280                 (int)readb(llc + offsetof(struct trllc, protid)+1),
1281                 (int)readb(llc + offsetof(struct trllc, protid)+2),
1282                 (int)readw(llc + offsetof(struct trllc, ethertype)));
1283 #endif
1284         
1285         if (readb(llc + offsetof(struct trllc, llc))!=UI_CMD) {
1286 #if !TR_FILTERNONUI             
1287                 DPRINTK("non-UI frame arrived. dropped. llc= %02X\n",
1288                         (int)readb(llc + offsetof(struct trllc, llc))
1289 #endif
1290                         writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
1291                         ti->tr_stats.rx_dropped++;
1292                         writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1293                         return;
1294                         }
1295                 
1296 #if TR_VERBOSE
1297                 if ((readb(llc + offsetof(struct trllc, dsap))!=0xAA) ||
1298                     (readb(llc + offsetof(struct trllc, ssap))!=0xAA)) {
1299                         
1300                         __u32 trhhdr;
1301                         
1302                         trhhdr=(rbuffer+offsetof(struct rec_buf,data));
1303                         
1304                         DPRINTK("Probably non-IP frame received.\n");
1305                         DPRINTK("ssap: %02X dsap: %02X saddr: %02X:%02X:%02X:%02X:%02X:%02X "
1306                                 "daddr: %02X:%02X:%02X:%02X:%02X:%02X\n",
1307                                 (int)readb(llc + offsetof(struct trllc, ssap)),
1308                                 (int)readb(llc + offsetof(struct trllc, dsap)),
1309                                 (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)),
1310                                 (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+1),
1311                                 (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+2),
1312                                 (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+3),
1313                                 (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+4),
1314                                 (int)readb(trhhdr + offsetof(struct trh_hdr, saddr)+5),
1315                                 (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)),
1316                                 (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+1),
1317                                 (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+2),
1318                                 (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+3),
1319                                 (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+4),
1320                                 (int)readb(trhhdr + offsetof(struct trh_hdr, daddr)+5));
1321                 }
1322 #endif
1323                 
1324                 arb_frame_len=ntohs(readw(ti->arb+offsetof(struct arb_rec_req, frame_len)));
1325                 
1326                 if (!(skb=dev_alloc_skb(arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr)))) {
1327                         DPRINTK("out of memory. frame dropped.\n");     
1328                         ti->tr_stats.rx_dropped++;
1329                         writeb(DATA_LOST, ti->asb + offsetof(struct asb_rec, ret_code));
1330                         writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1331                         return;
1332                 }
1333                 
1334                 skb_put(skb, arb_frame_len-lan_hdr_len+sizeof(struct trh_hdr));
1335                 skb->dev=dev;
1336                 
1337                 data=skb->data;
1338                 for (i=0; i<lan_hdr_len; i++) 
1339                         data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
1340                 
1341                 if (lan_hdr_len<sizeof(struct trh_hdr))
1342                         memset(data+lan_hdr_len, 0, sizeof(struct trh_hdr)-lan_hdr_len);
1343                 
1344                 data+=sizeof(struct trh_hdr);
1345                 rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)))
1346                         -lan_hdr_len;
1347                 
1348 #if TR_VERBOSE
1349                 DPRINTK("rbuffer_len: %d, data: %p\n", rbuffer_len, data);
1350 #endif
1351                 
1352                 for (i=0; i<rbuffer_len; i++)
1353                         data[i]=readb(rbuffer+ offsetof(struct rec_buf, data)+lan_hdr_len+i);
1354                 data+=rbuffer_len;
1355                 
1356                 while (readw(rbuffer + offsetof(struct rec_buf, buf_ptr))) {
1357                         rbuffer=(ti->sram
1358                                  +ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_ptr)))-2);
1359                         rbuffer_len=ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
1360                         for (i=0; i<rbuffer_len; i++)
1361                                 data[i]=readb(rbuffer + offsetof(struct rec_buf, data)+i);
1362                         data+=rbuffer_len;
1363                         
1364 #if TR_VERBOSE
1365                         DPRINTK("buf_ptr: %d, data =%p\n", 
1366                                 ntohs((rbuffer + offsetof(struct rec_buf, buf_ptr))), data);
1367 #endif
1368                 } 
1369                 
1370                 writeb(0, ti->asb + offsetof(struct asb_rec, ret_code));
1371                 
1372                 writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
1373                 
1374                 ti->tr_stats.rx_packets++;
1375                 
1376                 skb->protocol=tr_type_trans(skb,dev);
1377                 netif_rx(skb);
1378                 
1379         }
1380 
1381 static int tok_send_packet(struct sk_buff *skb, struct device *dev) 
1382 {
1383         struct tok_info *ti;
1384         ti=(struct tok_info *) dev->priv;
1385         
1386         if (dev->tbusy) {
1387                 int ticks_waited;
1388                 
1389                 ticks_waited=jiffies - dev->trans_start;
1390                 if (ticks_waited<TR_BUSY_INTERVAL) return 1;
1391                 
1392                 DPRINTK("Arrg. Transmitter busy for more than 50 msec. "
1393                         "Donald resets adapter, but resetting\n"
1394                         "the IBM tokenring adapter takes a long time."
1395                         " It might not even help when the\n"
1396                         "ring is very busy, so we just wait a little longer "
1397                         "and hope for the best.\n");            
1398                 dev->trans_start+=5; /* we fake the transmission start time... */
1399                 return 1;
1400         }
1401         
1402         /* Donald does this, so we do too. */
1403         if (skb==NULL) {
1404                 dev_tint(dev);
1405                 return 0;
1406         }
1407         
1408         if (set_bit(0,(void *)&dev->tbusy)!=0)
1409                 DPRINTK("Transmitter access conflict\n");
1410         else {
1411                 /* Save skb; we'll need it when the adapter asks for the data */
1412                 ti->current_skb=skb; 
1413                 writeb(XMIT_UI_FRAME, ti->srb + offsetof(struct srb_xmit, command));
1414                 writew(ti->exsap_station_id, ti->srb 
1415                        +offsetof(struct srb_xmit, station_id));
1416                 writeb(CMD_IN_SRB, (ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD));
1417                 dev->trans_start=jiffies;
1418         }
1419         
1420         return 0;
1421 }       
1422 
1423 /* tok_get_stats():  Basically a scaffold routine which will return
1424    the address of the tr_statistics structure associated with
1425    this device -- the tr.... structure is a ethnet look-alike
1426    so at least for this iteration may suffice.   */
1427 
1428 static struct enet_statistics * tok_get_stats(struct device *dev) {
1429 
1430         struct tok_info *toki;
1431         toki=(struct tok_info *) dev->priv;
1432         return (struct enet_statistics *) &toki->tr_stats;
1433 }
1434 
1435 #ifdef MODULE
1436 
1437 
1438 static char devicename[9] = { 0, };
1439 static struct device dev_ibmtr = {
1440         devicename, /* device name is inserted by linux/drivers/net/net_init.c */
1441         0, 0, 0, 0,
1442         0, 0,
1443         0, 0, 0, NULL, tok_probe };
1444 
1445 static int io = 0xa20;
1446 
1447 int init_module(void)
1448 {
1449         if (io == 0) 
1450                 printk("ibmtr: You should not use auto-probing with insmod!\n");
1451         dev_ibmtr.base_addr = io;
1452         dev_ibmtr.irq       = 0;
1453         
1454         if (register_netdev(&dev_ibmtr) != 0) {
1455                 printk("ibmtr: register_netdev() returned non-zero.\n");
1456                 return -EIO;
1457         }
1458         return 0;
1459 }
1460 
1461 void cleanup_module(void)
1462 {
1463         unregister_netdev(&dev_ibmtr);
1464         
1465         /* If we don't do this, we can't re-insmod it later. */
1466         free_irq(dev_ibmtr.irq, NULL);
1467         irq2dev_map[dev_ibmtr.irq] = NULL;
1468         release_region(dev_ibmtr.base_addr, TR_IO_EXTENT);
1469 }
1470 #endif /* MODULE */

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