OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [ibmtr.c] - Blame information for rev 1626

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.