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