2 * olympic.c (c) 1999 Peter De Schrijver All Rights Reserved
3 * 1999 Mike Phillips (phillim@amtrak.com)
5 * Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic
8 * Base Driver Skeleton:
9 * Written 1993-94 by Donald Becker.
11 * Copyright 1993 United States Government as represented by the
12 * Director, National Security Agency.
14 * Thanks to Erik De Cock, Adrian Bridgett and Frank Fiene for their
15 * assistance and perserverance with the testing of this driver.
17 * This software may be used and distributed according to the terms
18 * of the GNU Public License, incorporated herein by reference.
20 * 4/27/99 - Alpha Release 0.1.0
21 * First release to the public
23 * 6/8/99 - Official Release 0.2.0
24 * Merged into the kernel code
25 * 8/18/99 - Updated driver for 2.3.13 kernel to use new pci
26 * resource. Driver also reports the card name returned by
28 * 1/11/00 - Added spinlocks for smp
29 * 2/23/00 - Updated to dev_kfree_irq
30 * 3/10/00 - Fixed FDX enable which triggered other bugs also
32 * 5/20/00 - Changes to handle Olympic on LinuxPPC. Endian changes.
33 * The odd thing about the changes is that the fix for
34 * endian issues with the big-endian data in the arb, asb...
35 * was to always swab() the bytes, no matter what CPU.
36 * That's because the read[wl]() functions always swap the
37 * bytes on the way in on PPC.
38 * Fixing the hardware descriptors was another matter,
39 * because they weren't going through read[wl](), there all
40 * the results had to be in memory in le32 values. kdaaker
45 * If Problems do Occur
46 * Most problems can be rectified by either closing and opening the interface
47 * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult
48 * if compiled into the kernel).
51 /* Change OLYMPIC_DEBUG to 1 to get verbose, and I mean really verbose, messages */
53 #define OLYMPIC_DEBUG 0
55 /* Change OLYMPIC_NETWORK_MONITOR to receive mac frames through the arb channel.
56 * Will also create a /proc/net/olympic_tr entry if proc_fs is compiled into the
58 * Intended to be used to create a ring-error reporting network module
59 * i.e. it will give you the source address of beaconers on the ring
62 #define OLYMPIC_NETWORK_MONITOR 0
64 #include <linux/config.h>
65 #include <linux/module.h>
67 #include <linux/kernel.h>
68 #include <linux/sched.h>
69 #include <linux/errno.h>
70 #include <linux/timer.h>
72 #include <linux/ioport.h>
73 #include <linux/string.h>
74 #include <linux/proc_fs.h>
75 #include <linux/ptrace.h>
76 #include <linux/skbuff.h>
77 #include <linux/interrupt.h>
78 #include <linux/delay.h>
79 #include <linux/netdevice.h>
80 #include <linux/trdevice.h>
81 #include <linux/stddef.h>
82 #include <linux/init.h>
83 #include <linux/pci.h>
84 #include <linux/spinlock.h>
85 #include <net/checksum.h>
88 #include <asm/system.h>
89 #include <asm/bitops.h>
93 /* I've got to put some intelligence into the version number so that Peter and I know
94 * which version of the code somebody has got.
95 * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author.
96 * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike
98 * Official releases will only have an a.b.c version number format.
101 static char *version
=
102 "Olympic.c v0.5.0 3/10/00 - Peter De Schrijver & Mike Phillips" ;
104 static char *open_maj_error
[] = {"No error", "Lobe Media Test", "Physical Insertion",
105 "Address Verification", "Neighbor Notification (Ring Poll)",
106 "Request Parameters","FDX Registration Request",
107 "FDX Duplicate Address Check", "Station registration Query Wait",
110 static char *open_min_error
[] = {"No error", "Function Failure", "Signal Lost", "Wire Fault",
111 "Ring Speed Mismatch", "Timeout","Ring Failure","Ring Beaconing",
112 "Duplicate Node Address","Request Parameters","Remove Received",
113 "Reserved", "Reserved", "No Monitor Detected for RPL",
114 "Monitor Contention failer for RPL", "FDX Protocol Error"};
116 /* Module paramters */
118 /* Ring Speed 0,4,16,100
120 * 4,16 = Selected speed only, no autosense
121 * This allows the card to be the first on the ring
122 * and become the active monitor.
123 * 100 = Nothing at present, 100mbps is autodetected
124 * if FDX is turned on. May be implemented in the future to
125 * fail if 100mpbs is not detected.
127 * WARNING: Some hubs will allow you to insert
131 static int ringspeed
[OLYMPIC_MAX_ADAPTERS
] = {0,} ;
133 MODULE_PARM(ringspeed
, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS
) "i");
135 /* Packet buffer size */
137 static int pkt_buf_sz
[OLYMPIC_MAX_ADAPTERS
] = {0,} ;
139 MODULE_PARM(pkt_buf_sz
, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS
) "i") ;
143 static int message_level
[OLYMPIC_MAX_ADAPTERS
] = {0,} ;
145 MODULE_PARM(message_level
, "1-" __MODULE_STRING(OLYMPIC_MAX_ADAPTERS
) "i") ;
147 static int olympic_scan(struct net_device
*dev
);
148 static int olympic_init(struct net_device
*dev
);
149 static int olympic_open(struct net_device
*dev
);
150 static int olympic_xmit(struct sk_buff
*skb
, struct net_device
*dev
);
151 static int olympic_close(struct net_device
*dev
);
152 static void olympic_set_rx_mode(struct net_device
*dev
);
153 static void olympic_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
);
154 static struct net_device_stats
* olympic_get_stats(struct net_device
*dev
);
155 static int olympic_set_mac_address(struct net_device
*dev
, void *addr
) ;
156 static void olympic_arb_cmd(struct net_device
*dev
);
157 static int olympic_change_mtu(struct net_device
*dev
, int mtu
);
158 static void olympic_srb_bh(struct net_device
*dev
) ;
159 static void olympic_asb_bh(struct net_device
*dev
) ;
160 #if OLYMPIC_NETWORK_MONITOR
161 #ifdef CONFIG_PROC_FS
162 static int sprintf_info(char *buffer
, struct net_device
*dev
) ;
166 int __init
olympic_probe(struct net_device
*dev
)
170 cards_found
=olympic_scan(dev
);
171 return cards_found
? 0 : -ENODEV
;
174 static int __init
olympic_scan(struct net_device
*dev
)
176 struct pci_dev
*pci_device
= NULL
;
177 struct olympic_private
*olympic_priv
;
181 while((pci_device
=pci_find_device(PCI_VENDOR_ID_IBM
, PCI_DEVICE_ID_IBM_TR_WAKE
, pci_device
))) {
184 if (pci_enable_device(pci_device
))
187 /* These lines are needed by the PowerPC, it appears
189 * are not being set properly for the PPC, this may
191 * the new PCI code */
192 pci_read_config_word(pci_device
, PCI_COMMAND
, &pci_command
);
193 pci_command
|= PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
;
194 pci_write_config_word(pci_device
, PCI_COMMAND
,pci_command
);
195 pci_set_master(pci_device
);
197 /* Check to see if io has been allocated, if so, we've already done this card,
198 so continue on the card discovery loop */
200 if (check_region(pci_resource_start(pci_device
, 0), OLYMPIC_IO_SPACE
)) {
205 olympic_priv
=kmalloc(sizeof (struct olympic_private
), GFP_KERNEL
);
206 memset(olympic_priv
, 0, sizeof(struct olympic_private
));
207 init_waitqueue_head(&olympic_priv
->srb_wait
);
208 init_waitqueue_head(&olympic_priv
->trb_wait
);
210 dev
=init_trdev(dev
, 0);
212 dev
->priv
=(void *)olympic_priv
;
214 printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device
, dev
, dev
->priv
);
216 dev
->irq
=pci_device
->irq
;
217 dev
->base_addr
=pci_resource_start(pci_device
, 0);
218 dev
->init
=&olympic_init
;
219 olympic_priv
->olympic_card_name
= (char *)pci_device
->resource
[0].name
;
220 olympic_priv
->olympic_mmio
=
221 ioremap(pci_resource_start(pci_device
,1),256);
222 olympic_priv
->olympic_lap
=
223 ioremap(pci_resource_start(pci_device
,2),2048);
225 if ((pkt_buf_sz
[card_no
] < 100) || (pkt_buf_sz
[card_no
] > 18000) )
226 olympic_priv
->pkt_buf_sz
= PKT_BUF_SZ
;
228 olympic_priv
->pkt_buf_sz
= pkt_buf_sz
[card_no
] ;
230 olympic_priv
->olympic_ring_speed
= ringspeed
[card_no
] ;
231 olympic_priv
->olympic_message_level
= message_level
[card_no
] ;
233 if(olympic_init(dev
)==-1) {
234 unregister_netdevice(dev
);
239 dev
->open
=&olympic_open
;
240 dev
->hard_start_xmit
=&olympic_xmit
;
241 dev
->change_mtu
=&olympic_change_mtu
;
243 dev
->stop
=&olympic_close
;
245 dev
->set_multicast_list
=&olympic_set_rx_mode
;
246 dev
->get_stats
=&olympic_get_stats
;
247 dev
->set_mac_address
=&olympic_set_mac_address
;
255 static int __init
olympic_init(struct net_device
*dev
)
257 struct olympic_private
*olympic_priv
;
258 __u8
*olympic_mmio
, *init_srb
,*adapter_addr
;
260 unsigned int uaa_addr
;
262 olympic_priv
=(struct olympic_private
*)dev
->priv
;
263 olympic_mmio
=olympic_priv
->olympic_mmio
;
265 printk("%s \n", version
);
266 printk("%s: %s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n",dev
->name
, olympic_priv
->olympic_card_name
, (unsigned int) dev
->base_addr
,olympic_priv
->olympic_mmio
, olympic_priv
->olympic_lap
, dev
->irq
);
268 request_region(dev
->base_addr
, OLYMPIC_IO_SPACE
, "olympic");
269 writel(readl(olympic_mmio
+BCTL
) | BCTL_SOFTRESET
,olympic_mmio
+BCTL
);
271 while((readl(olympic_priv
->olympic_mmio
+BCTL
)) & BCTL_SOFTRESET
) {
273 if(jiffies
-t
> 40*HZ
) {
274 printk(KERN_ERR
"IBM PCI tokenring card not responding.\n");
275 release_region(dev
->base_addr
, OLYMPIC_IO_SPACE
) ;
280 spin_lock_init(&olympic_priv
->olympic_lock
) ;
283 printk("BCTL: %x\n",readl(olympic_mmio
+BCTL
));
284 printk("GPR: %x\n",readw(olympic_mmio
+GPR
));
285 printk("SISRMASK: %x\n",readl(olympic_mmio
+SISR_MASK
));
287 /* Aaaahhh, You have got to be real careful setting GPR, the card
288 holds the previous values from flash memory, including autosense
291 writel(readl(olympic_mmio
+BCTL
)|BCTL_MIMREB
,olympic_mmio
+BCTL
);
293 if (olympic_priv
->olympic_ring_speed
== 0) { /* Autosense */
294 writel(readl(olympic_mmio
+GPR
)|GPR_AUTOSENSE
,olympic_mmio
+GPR
);
295 if (olympic_priv
->olympic_message_level
)
296 printk(KERN_INFO
"%s: Ringspeed autosense mode on\n",dev
->name
);
297 } else if (olympic_priv
->olympic_ring_speed
== 16) {
298 if (olympic_priv
->olympic_message_level
)
299 printk(KERN_INFO
"%s: Trying to open at 16 Mbps as requested\n", dev
->name
);
300 writel(GPR_16MBPS
, olympic_mmio
+GPR
);
301 } else if (olympic_priv
->olympic_ring_speed
== 4) {
302 if (olympic_priv
->olympic_message_level
)
303 printk(KERN_INFO
"%s: Trying to open at 4 Mbps as requested\n", dev
->name
) ;
304 writel(0, olympic_mmio
+GPR
);
307 writel(readl(olympic_mmio
+GPR
)|GPR_NEPTUNE_BF
,olympic_mmio
+GPR
);
310 printk("GPR = %x\n",readw(olympic_mmio
+ GPR
) ) ;
312 /* start solo init */
313 writel((1<<15),olympic_mmio
+SISR_MASK_SUM
);
316 while(!((readl(olympic_mmio
+SISR_RR
)) & SISR_SRB_REPLY
)) {
318 if(jiffies
-t
> 40*HZ
) {
319 printk(KERN_ERR
"IBM PCI tokenring card not responding.\n");
320 release_region(dev
->base_addr
, OLYMPIC_IO_SPACE
);
325 writel(readl(olympic_mmio
+LAPWWO
),olympic_mmio
+LAPA
);
328 printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio
+LAPWWO
), readl(olympic_mmio
+LAPA
));
331 init_srb
=olympic_priv
->olympic_lap
+ ((readl(olympic_mmio
+LAPWWO
)) & (~0xf800));
336 printk("init_srb(%p): ",init_srb
);
338 printk("%x ",readb(init_srb
+i
));
342 if(readw(init_srb
+6)) {
343 printk(KERN_INFO
"tokenring card intialization failed. errorcode : %x\n",readw(init_srb
+6));
344 release_region(dev
->base_addr
, OLYMPIC_IO_SPACE
);
348 if (olympic_priv
->olympic_message_level
) {
349 if ( readb(init_srb
+2) & 0x40) {
350 printk(KERN_INFO
"Olympic: Adapter is FDX capable.\n") ;
352 printk(KERN_INFO
"Olympic: Adapter cannot do FDX.\n");
356 uaa_addr
=swab16(readw(init_srb
+8));
359 printk("UAA resides at %x\n",uaa_addr
);
362 writel(uaa_addr
,olympic_mmio
+LAPA
);
363 adapter_addr
=olympic_priv
->olympic_lap
+ (uaa_addr
& (~0xf800));
366 printk("adapter address: %02x:%02x:%02x:%02x:%02x:%02x\n",
367 readb(adapter_addr
), readb(adapter_addr
+1),readb(adapter_addr
+2),
368 readb(adapter_addr
+3),readb(adapter_addr
+4),readb(adapter_addr
+5));
371 memcpy_fromio(&dev
->dev_addr
[0], adapter_addr
,6);
373 olympic_priv
->olympic_addr_table_addr
= swab16(readw(init_srb
+ 12));
374 olympic_priv
->olympic_parms_addr
= swab16(readw(init_srb
+ 14));
380 static int olympic_open(struct net_device
*dev
)
382 struct olympic_private
*olympic_priv
=(struct olympic_private
*)dev
->priv
;
383 __u8
*olympic_mmio
=olympic_priv
->olympic_mmio
,*init_srb
;
385 char open_error
[255] ;
386 int i
, open_finished
= 1 ;
388 #if OLYMPIC_NETWORK_MONITOR
393 if(request_irq(dev
->irq
, &olympic_interrupt
, SA_SHIRQ
, "olympic", dev
)) {
398 printk("BMCTL: %x\n",readl(olympic_mmio
+BMCTL_SUM
));
399 printk("pending ints: %x\n",readl(olympic_mmio
+SISR_RR
));
402 writel(SISR_MI
,olympic_mmio
+SISR_MASK_SUM
);
404 writel(SISR_MI
| SISR_SRB_REPLY
, olympic_mmio
+SISR_MASK
); /* more ints later, doesn't stop arb cmd interrupt */
406 writel(LISR_LIE
,olympic_mmio
+LISR
); /* more ints later */
408 /* adapter is closed, so SRB is pointed to by LAPWWO */
410 writel(readl(olympic_mmio
+LAPWWO
),olympic_mmio
+LAPA
);
411 init_srb
=olympic_priv
->olympic_lap
+ ((readl(olympic_mmio
+LAPWWO
)) & (~0xf800));
414 printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio
+LAPWWO
), readl(olympic_mmio
+LAPA
));
415 printk("SISR Mask = %04x\n", readl(olympic_mmio
+SISR_MASK
));
416 printk("Before the open command \n");
423 for(i
=0;i
<SRB_COMMAND_SIZE
;i
+=4)
424 writel(0,init_srb
+i
);
425 if(SRB_COMMAND_SIZE
& 2)
426 writew(0,init_srb
+(SRB_COMMAND_SIZE
& ~3));
427 if(SRB_COMMAND_SIZE
& 1)
428 writeb(0,init_srb
+(SRB_COMMAND_SIZE
& ~1));
430 writeb(SRB_OPEN_ADAPTER
,init_srb
) ; /* open */
431 writeb(OLYMPIC_CLEAR_RET_CODE
,init_srb
+2);
433 /* If Network Monitor, instruct card to copy MAC frames through the ARB */
435 #if OLYMPIC_NETWORK_MONITOR
436 writew(swab16(OPEN_ADAPTER_ENABLE_FDX
| OPEN_ADAPTER_PASS_ADC_MAC
| OPEN_ADAPTER_PASS_ATT_MAC
| OPEN_ADAPTER_PASS_BEACON
), init_srb
+8);
438 writew(swab16(OPEN_ADAPTER_ENABLE_FDX
), init_srb
+8);
441 if (olympic_priv
->olympic_laa
[0]) {
442 writeb(olympic_priv
->olympic_laa
[0],init_srb
+12);
443 writeb(olympic_priv
->olympic_laa
[1],init_srb
+13);
444 writeb(olympic_priv
->olympic_laa
[2],init_srb
+14);
445 writeb(olympic_priv
->olympic_laa
[3],init_srb
+15);
446 writeb(olympic_priv
->olympic_laa
[4],init_srb
+16);
447 writeb(olympic_priv
->olympic_laa
[5],init_srb
+17);
448 memcpy(dev
->dev_addr
,olympic_priv
->olympic_laa
,dev
->addr_len
) ;
450 writeb(1,init_srb
+30);
452 olympic_priv
->srb_queued
=1;
454 writel(LISR_SRB_CMD
,olympic_mmio
+LISR_SUM
);
456 while(olympic_priv
->srb_queued
) {
457 interruptible_sleep_on_timeout(&olympic_priv
->srb_wait
, 60*HZ
);
458 if(signal_pending(current
)) {
459 printk(KERN_WARNING
"%s: SRB timed out.\n",
461 printk(KERN_WARNING
"SISR=%x MISR=%x\n",
462 readl(olympic_mmio
+SISR
),
463 readl(olympic_mmio
+LISR
));
464 olympic_priv
->srb_queued
=0;
468 restore_flags(flags
);
470 printk("init_srb(%p): ",init_srb
);
472 printk("%02x ",readb(init_srb
+i
));
476 /* If we get the same return response as we set, the interrupt wasn't raised and the open
480 if(readb(init_srb
+2)== OLYMPIC_CLEAR_RET_CODE
) {
481 printk(KERN_WARNING
"%s: Adapter Open time out or error.\n", dev
->name
) ;
485 if(readb(init_srb
+2)!=0) {
486 if (readb(init_srb
+2) == 0x07) {
487 if (!olympic_priv
->olympic_ring_speed
&& open_finished
) { /* Autosense , first time around */
488 printk(KERN_WARNING
"%s: Retrying at different ring speed \n", dev
->name
);
492 strcpy(open_error
, open_maj_error
[(readb(init_srb
+7) & 0xf0) >> 4]) ;
493 strcat(open_error
," - ") ;
494 strcat(open_error
, open_min_error
[(readb(init_srb
+7) & 0x0f)]) ;
496 if (!olympic_priv
->olympic_ring_speed
&& ((readb(init_srb
+7) & 0x0f) == 0x0d)) {
497 printk(KERN_WARNING
"%s: Tried to autosense ring speed with no monitors present\n",dev
->name
);
498 printk(KERN_WARNING
"%s: Please try again with a specified ring speed \n",dev
->name
);
499 free_irq(dev
->irq
, dev
);
503 printk(KERN_WARNING
"%s: %s\n",dev
->name
,open_error
);
504 free_irq(dev
->irq
,dev
) ;
507 } /* if autosense && open_finished */
509 printk(KERN_WARNING
"%s: Bad OPEN response: %x\n", dev
->name
,init_srb
[2]);
510 free_irq(dev
->irq
, dev
);
515 } while (!(open_finished
)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */
517 if (readb(init_srb
+18) & (1<<3))
518 if (olympic_priv
->olympic_message_level
)
519 printk(KERN_INFO
"%s: Opened in FDX Mode\n",dev
->name
);
521 if (readb(init_srb
+18) & (1<<1))
522 olympic_priv
->olympic_ring_speed
= 100 ;
523 else if (readb(init_srb
+18) & 1)
524 olympic_priv
->olympic_ring_speed
= 16 ;
526 olympic_priv
->olympic_ring_speed
= 4 ;
528 if (olympic_priv
->olympic_message_level
)
529 printk(KERN_INFO
"%s: Opened in %d Mbps mode\n",dev
->name
, olympic_priv
->olympic_ring_speed
);
531 olympic_priv
->asb
= swab16(readw(init_srb
+8));
532 olympic_priv
->srb
= swab16(readw(init_srb
+10));
533 olympic_priv
->arb
= swab16(readw(init_srb
+12));
534 olympic_priv
->trb
= swab16(readw(init_srb
+16));
536 olympic_priv
->olympic_receive_options
= 0x01 ;
537 olympic_priv
->olympic_copy_all_options
= 0 ;
541 writel((3<<16),olympic_mmio
+BMCTL_RWM
); /* Ensure end of frame generated interrupts */
543 writel(BMCTL_RX_DIS
|3,olympic_mmio
+BMCTL_RWM
); /* Yes, this the enables RX channel */
545 for(i
=0;i
<OLYMPIC_RX_RING_SIZE
;i
++) {
549 skb
=dev_alloc_skb(olympic_priv
->pkt_buf_sz
);
555 olympic_priv
->olympic_rx_ring
[i
].buffer
= cpu_to_le32(virt_to_bus(skb
->data
));
556 olympic_priv
->olympic_rx_ring
[i
].res_length
= cpu_to_le32(olympic_priv
->pkt_buf_sz
);
557 olympic_priv
->rx_ring_skb
[i
]=skb
;
561 printk(KERN_WARNING
"%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev
->name
);
562 free_irq(dev
->irq
, dev
);
566 writel(virt_to_bus(&olympic_priv
->olympic_rx_ring
[0]), olympic_mmio
+RXDESCQ
);
567 writel(virt_to_bus(&olympic_priv
->olympic_rx_ring
[0]), olympic_mmio
+RXCDA
);
568 writew(i
, olympic_mmio
+RXDESCQCNT
);
570 writel(virt_to_bus(&olympic_priv
->olympic_rx_status_ring
[0]), olympic_mmio
+RXSTATQ
);
571 writel(virt_to_bus(&olympic_priv
->olympic_rx_status_ring
[0]), olympic_mmio
+RXCSA
);
573 olympic_priv
->rx_ring_last_received
= OLYMPIC_RX_RING_SIZE
- 1; /* last processed rx status */
574 olympic_priv
->rx_status_last_received
= OLYMPIC_RX_RING_SIZE
- 1;
576 writew(i
, olympic_mmio
+RXSTATQCNT
);
579 printk("# of rx buffers: %d, RXENQ: %x\n",i
, readw(olympic_mmio
+RXENQ
));
580 printk("RXCSA: %x, rx_status_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio
+RXCSA
)),&olympic_priv
->olympic_rx_status_ring
[0]);
581 printk(" stat_ring[1]: %p, stat_ring[2]: %p, stat_ring[3]: %p\n", &(olympic_priv
->olympic_rx_status_ring
[1]), &(olympic_priv
->olympic_rx_status_ring
[2]), &(olympic_priv
->olympic_rx_status_ring
[3]) );
582 printk(" stat_ring[4]: %p, stat_ring[5]: %p, stat_ring[6]: %p\n", &(olympic_priv
->olympic_rx_status_ring
[4]), &(olympic_priv
->olympic_rx_status_ring
[5]), &(olympic_priv
->olympic_rx_status_ring
[6]) );
583 printk(" stat_ring[7]: %p\n", &(olympic_priv
->olympic_rx_status_ring
[7]) );
585 printk("RXCDA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio
+RXCDA
)),&olympic_priv
->olympic_rx_ring
[0]);
588 writew((((readw(olympic_mmio
+RXENQ
)) & 0x8000) ^ 0x8000) | i
,olympic_mmio
+RXENQ
);
591 printk("# of rx buffers: %d, RXENQ: %x\n",i
, readw(olympic_mmio
+RXENQ
));
592 printk("RXCSA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio
+RXCSA
)),&olympic_priv
->olympic_rx_status_ring
[0]);
593 printk("RXCDA: %x, rx_ring[0]: %p\n",bus_to_virt(readl(olympic_mmio
+RXCDA
)),&olympic_priv
->olympic_rx_ring
[0]);
596 writel(SISR_RX_STATUS
| SISR_RX_NOBUF
,olympic_mmio
+SISR_MASK_SUM
);
600 writel(BMCTL_TX1_DIS
,olympic_mmio
+BMCTL_RWM
); /* Yes, this enables TX channel 1 */
601 for(i
=0;i
<OLYMPIC_TX_RING_SIZE
;i
++)
602 olympic_priv
->olympic_tx_ring
[i
].buffer
=0xdeadbeef;
604 olympic_priv
->free_tx_ring_entries
=OLYMPIC_TX_RING_SIZE
;
605 writel(virt_to_bus(&olympic_priv
->olympic_tx_ring
[0]), olympic_mmio
+TXDESCQ_1
);
606 writel(virt_to_bus(&olympic_priv
->olympic_tx_ring
[0]), olympic_mmio
+TXCDA_1
);
607 writew(OLYMPIC_TX_RING_SIZE
, olympic_mmio
+TXDESCQCNT_1
);
609 writel(virt_to_bus(&olympic_priv
->olympic_tx_status_ring
[0]),olympic_mmio
+TXSTATQ_1
);
610 writel(virt_to_bus(&olympic_priv
->olympic_tx_status_ring
[0]),olympic_mmio
+TXCSA_1
);
611 writew(OLYMPIC_TX_RING_SIZE
,olympic_mmio
+TXSTATQCNT_1
);
613 olympic_priv
->tx_ring_free
=0; /* next entry in tx ring to use */
614 olympic_priv
->tx_ring_last_status
=OLYMPIC_TX_RING_SIZE
-1; /* last processed tx status */
616 writel(SISR_TX1_EOF
| SISR_ADAPTER_CHECK
| SISR_ARB_CMD
| SISR_TRB_REPLY
| SISR_ASB_FREE
,olympic_mmio
+SISR_MASK_SUM
);
619 printk("BMCTL: %x\n",readl(olympic_mmio
+BMCTL_SUM
));
620 printk("SISR MASK: %x\n",readl(olympic_mmio
+SISR_MASK
));
623 #if OLYMPIC_NETWORK_MONITOR
624 oat
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->olympic_addr_table_addr
) ;
625 opt
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->olympic_parms_addr
) ;
627 printk("%s: Node Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev
->name
,
628 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)),
629 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+1),
630 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+2),
631 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+3),
632 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+4),
633 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+5));
634 printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev
->name
,
635 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)),
636 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)+1),
637 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)+2),
638 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)+3));
640 printk("%s: NAUN Address: %02x:%02x:%02x:%02x:%02x:%02x\n",dev
->name
,
641 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)),
642 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+1),
643 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+2),
644 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+3),
645 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+4),
646 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+5));
651 netif_start_queue(dev
);
658 * When we enter the rx routine we do not know how many frames have been
659 * queued on the rx channel. Therefore we start at the next rx status
660 * position and travel around the receive ring until we have completed
663 * This means that we may process the frame before we receive the end
664 * of frame interrupt. This is why we always test the status instead
665 * of blindly processing the next frame.
668 static void olympic_rx(struct net_device
*dev
)
670 struct olympic_private
*olympic_priv
=(struct olympic_private
*)dev
->priv
;
671 __u8
*olympic_mmio
=olympic_priv
->olympic_mmio
;
672 struct olympic_rx_status
*rx_status
;
673 struct olympic_rx_desc
*rx_desc
;
674 int rx_ring_last_received
,length
, buffer_cnt
, cpy_length
, frag_len
;
675 struct sk_buff
*skb
, *skb2
;
678 rx_status
=&(olympic_priv
->olympic_rx_status_ring
[(olympic_priv
->rx_status_last_received
+ 1) & (OLYMPIC_RX_RING_SIZE
- 1)]) ;
680 while (rx_status
->status_buffercnt
) {
681 __u32 l_status_buffercnt
;
683 olympic_priv
->rx_status_last_received
++ ;
684 olympic_priv
->rx_status_last_received
&= (OLYMPIC_RX_RING_SIZE
-1);
686 printk(" stat_ring addr: %x \n", &(olympic_priv
->olympic_rx_status_ring
[olympic_priv
->rx_status_last_received
]) );
687 printk("rx status: %x rx len: %x \n", le32_to_cpu(rx_status
->status_buffercnt
), le32_to_cpu(rx_status
->fragmentcnt_framelen
));
689 length
= le32_to_cpu(rx_status
->fragmentcnt_framelen
) & 0xffff;
690 buffer_cnt
= le32_to_cpu(rx_status
->status_buffercnt
) & 0xffff;
691 i
= buffer_cnt
; /* Need buffer_cnt later for rxenq update */
692 frag_len
= le32_to_cpu(rx_status
->fragmentcnt_framelen
) >> 16;
695 printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length
, frag_len
, buffer_cnt
);
697 l_status_buffercnt
= le32_to_cpu(rx_status
->status_buffercnt
);
698 if(l_status_buffercnt
& 0xC0000000) {
699 if (l_status_buffercnt
& 0x3B000000) {
700 if (olympic_priv
->olympic_message_level
) {
701 if (l_status_buffercnt
& (1<<29)) /* Rx Frame Truncated */
702 printk(KERN_WARNING
"%s: Rx Frame Truncated \n",dev
->name
);
703 if (l_status_buffercnt
& (1<<28)) /*Rx receive overrun */
704 printk(KERN_WARNING
"%s: Rx Frame Receive overrun \n",dev
->name
);
705 if (l_status_buffercnt
& (1<<27)) /* No receive buffers */
706 printk(KERN_WARNING
"%s: No receive buffers \n",dev
->name
);
707 if (l_status_buffercnt
& (1<<25)) /* Receive frame error detect */
708 printk(KERN_WARNING
"%s: Receive frame error detect \n",dev
->name
);
709 if (l_status_buffercnt
& (1<<24)) /* Received Error Detect */
710 printk(KERN_WARNING
"%s: Received Error Detect \n",dev
->name
);
712 olympic_priv
->rx_ring_last_received
+= i
;
713 olympic_priv
->rx_ring_last_received
&= (OLYMPIC_RX_RING_SIZE
-1) ;
714 olympic_priv
->olympic_stats
.rx_errors
++;
717 if (buffer_cnt
== 1) {
718 skb
= dev_alloc_skb(olympic_priv
->pkt_buf_sz
) ;
720 skb
= dev_alloc_skb(length
) ;
724 printk(KERN_WARNING
"%s: Not enough memory to copy packet to upper layers. \n",dev
->name
) ;
725 olympic_priv
->olympic_stats
.rx_dropped
++ ;
726 /* Update counters even though we don't transfer the frame */
727 olympic_priv
->rx_ring_last_received
+= i
;
728 olympic_priv
->rx_ring_last_received
&= (OLYMPIC_RX_RING_SIZE
-1) ;
732 /* Optimise based upon number of buffers used.
733 If only one buffer is used we can simply swap the buffers around.
734 If more than one then we must use the new buffer and copy the information
735 first. Ideally all frames would be in a single buffer, this can be tuned by
736 altering the buffer size. */
739 olympic_priv
->rx_ring_last_received
++ ;
740 olympic_priv
->rx_ring_last_received
&= (OLYMPIC_RX_RING_SIZE
-1);
741 rx_ring_last_received
= olympic_priv
->rx_ring_last_received
;
742 skb2
=olympic_priv
->rx_ring_skb
[rx_ring_last_received
] ;
743 skb_put(skb2
,length
);
744 skb2
->protocol
= tr_type_trans(skb2
,dev
);
745 olympic_priv
->olympic_rx_ring
[rx_ring_last_received
].buffer
= cpu_to_le32(virt_to_bus(skb
->data
));
746 olympic_priv
->olympic_rx_ring
[rx_ring_last_received
].res_length
= cpu_to_le32(olympic_priv
->pkt_buf_sz
);
747 olympic_priv
->rx_ring_skb
[rx_ring_last_received
] = skb
;
750 do { /* Walk the buffers */
751 olympic_priv
->rx_ring_last_received
++ ;
752 olympic_priv
->rx_ring_last_received
&= (OLYMPIC_RX_RING_SIZE
-1);
753 rx_ring_last_received
= olympic_priv
->rx_ring_last_received
;
754 rx_desc
= &(olympic_priv
->olympic_rx_ring
[rx_ring_last_received
]);
755 cpy_length
= (i
== 1 ? frag_len
: le32_to_cpu(rx_desc
->res_length
));
756 memcpy(skb_put(skb
, cpy_length
), bus_to_virt(le32_to_cpu(rx_desc
->buffer
)), cpy_length
) ;
759 skb
->protocol
= tr_type_trans(skb
,dev
);
762 olympic_priv
->olympic_stats
.rx_packets
++ ;
763 olympic_priv
->olympic_stats
.rx_bytes
+= length
;
764 } /* if skb == null */
765 } /* If status & 0x3b */
767 } else { /*if buffercnt & 0xC */
768 olympic_priv
->rx_ring_last_received
+= i
;
769 olympic_priv
->rx_ring_last_received
&= (OLYMPIC_RX_RING_SIZE
- 1) ;
772 rx_status
->fragmentcnt_framelen
= 0 ;
773 rx_status
->status_buffercnt
= 0 ;
774 rx_status
= &(olympic_priv
->olympic_rx_status_ring
[(olympic_priv
->rx_status_last_received
+1) & (OLYMPIC_RX_RING_SIZE
-1) ]);
776 writew((((readw(olympic_mmio
+RXENQ
)) & 0x8000) ^ 0x8000) | buffer_cnt
, olympic_mmio
+RXENQ
);
781 static void olympic_interrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
783 struct net_device
*dev
= (struct net_device
*)dev_id
;
784 struct olympic_private
*olympic_priv
=(struct olympic_private
*)dev
->priv
;
785 __u8
*olympic_mmio
=olympic_priv
->olympic_mmio
;
787 __u8
*adapter_check_area
;
789 sisr
=readl(olympic_mmio
+SISR_RR
) ; /* Reset sisr */
791 if (!(sisr
& SISR_MI
)) /* Interrupt isn't for us */
794 spin_lock(&olympic_priv
->olympic_lock
);
796 if (sisr
& (SISR_SRB_REPLY
| SISR_TX1_EOF
| SISR_RX_STATUS
| SISR_ADAPTER_CHECK
|
797 SISR_ASB_FREE
| SISR_ARB_CMD
| SISR_TRB_REPLY
| SISR_RX_NOBUF
)) {
799 if(sisr
& SISR_SRB_REPLY
) {
800 if(olympic_priv
->srb_queued
==1) {
801 wake_up_interruptible(&olympic_priv
->srb_wait
);
802 } else if (olympic_priv
->srb_queued
==2) {
803 olympic_srb_bh(dev
) ;
805 olympic_priv
->srb_queued
=0;
806 } /* SISR_SRB_REPLY */
808 if (sisr
& SISR_TX1_EOF
) {
809 olympic_priv
->tx_ring_last_status
++;
810 olympic_priv
->tx_ring_last_status
&= (OLYMPIC_TX_RING_SIZE
-1);
811 olympic_priv
->free_tx_ring_entries
++;
812 olympic_priv
->olympic_stats
.tx_bytes
+= olympic_priv
->tx_ring_skb
[olympic_priv
->tx_ring_last_status
]->len
;
813 olympic_priv
->olympic_stats
.tx_packets
++ ;
814 dev_kfree_skb_irq(olympic_priv
->tx_ring_skb
[olympic_priv
->tx_ring_last_status
]);
815 olympic_priv
->olympic_tx_ring
[olympic_priv
->tx_ring_last_status
].buffer
=0xdeadbeef;
816 olympic_priv
->olympic_tx_status_ring
[olympic_priv
->tx_ring_last_status
].status
=0;
817 netif_wake_queue(dev
);
820 if (sisr
& SISR_RX_STATUS
) {
822 } /* SISR_RX_STATUS */
824 if (sisr
& SISR_ADAPTER_CHECK
) {
825 printk(KERN_WARNING
"%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev
->name
);
826 writel(readl(olympic_mmio
+LAPWWO
),olympic_mmio
+LAPA
);
827 adapter_check_area
= (__u8
*)(olympic_mmio
+LAPWWO
) ;
828 printk(KERN_WARNING
"%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev
->name
, readb(adapter_check_area
+0), readb(adapter_check_area
+1), readb(adapter_check_area
+2), readb(adapter_check_area
+3), readb(adapter_check_area
+4), readb(adapter_check_area
+5), readb(adapter_check_area
+6), readb(adapter_check_area
+7)) ;
829 free_irq(dev
->irq
, dev
) ;
831 } /* SISR_ADAPTER_CHECK */
833 if (sisr
& SISR_ASB_FREE
) {
834 /* Wake up anything that is waiting for the asb response */
835 if (olympic_priv
->asb_queued
) {
836 olympic_asb_bh(dev
) ;
838 } /* SISR_ASB_FREE */
840 if (sisr
& SISR_ARB_CMD
) {
841 olympic_arb_cmd(dev
) ;
844 if (sisr
& SISR_TRB_REPLY
) {
845 /* Wake up anything that is waiting for the trb response */
846 if (olympic_priv
->trb_queued
) {
847 wake_up_interruptible(&olympic_priv
->trb_wait
);
849 olympic_priv
->trb_queued
= 0 ;
850 } /* SISR_TRB_REPLY */
852 if (sisr
& SISR_RX_NOBUF
) {
853 /* According to the documentation, we don't have to do anything, but trapping it keeps it out of
854 /var/log/messages. */
855 } /* SISR_RX_NOBUF */
857 printk(KERN_WARNING
"%s: Unexpected interrupt: %x\n",dev
->name
, sisr
);
858 printk(KERN_WARNING
"%s: SISR_MASK: %x\n",dev
->name
, readl(olympic_mmio
+SISR_MASK
)) ;
859 } /* One if the interrupts we want */
861 writel(SISR_MI
,olympic_mmio
+SISR_MASK_SUM
);
863 spin_unlock(&olympic_priv
->olympic_lock
) ;
866 static int olympic_xmit(struct sk_buff
*skb
, struct net_device
*dev
)
868 struct olympic_private
*olympic_priv
=(struct olympic_private
*)dev
->priv
;
869 __u8
*olympic_mmio
=olympic_priv
->olympic_mmio
;
870 unsigned long flags
;
872 spin_lock_irqsave(&olympic_priv
->olympic_lock
, flags
);
874 netif_stop_queue(dev
);
876 if(olympic_priv
->free_tx_ring_entries
) {
877 olympic_priv
->olympic_tx_ring
[olympic_priv
->tx_ring_free
].buffer
= cpu_to_le32(virt_to_bus(skb
->data
));
878 olympic_priv
->olympic_tx_ring
[olympic_priv
->tx_ring_free
].status_length
= cpu_to_le32(skb
->len
| (0x80000000));
879 olympic_priv
->tx_ring_skb
[olympic_priv
->tx_ring_free
]=skb
;
880 olympic_priv
->free_tx_ring_entries
--;
882 olympic_priv
->tx_ring_free
++;
883 olympic_priv
->tx_ring_free
&= (OLYMPIC_TX_RING_SIZE
-1);
886 writew((((readw(olympic_mmio
+TXENQ_1
)) & 0x8000) ^ 0x8000) | 1,olympic_mmio
+TXENQ_1
);
888 netif_wake_queue(dev
);
889 spin_unlock_irqrestore(&olympic_priv
->olympic_lock
,flags
);
892 spin_unlock_irqrestore(&olympic_priv
->olympic_lock
,flags
);
899 static int olympic_close(struct net_device
*dev
)
901 struct olympic_private
*olympic_priv
=(struct olympic_private
*)dev
->priv
;
902 __u8
*olympic_mmio
=olympic_priv
->olympic_mmio
,*srb
;
906 netif_stop_queue(dev
);
908 writel(olympic_priv
->srb
,olympic_mmio
+LAPA
);
909 srb
=olympic_priv
->olympic_lap
+ (olympic_priv
->srb
& (~0xf800));
911 writeb(SRB_CLOSE_ADAPTER
,srb
+0);
913 writeb(OLYMPIC_CLEAR_RET_CODE
,srb
+2);
918 olympic_priv
->srb_queued
=1;
920 writel(LISR_SRB_CMD
,olympic_mmio
+LISR_SUM
);
922 while(olympic_priv
->srb_queued
) {
923 interruptible_sleep_on_timeout(&olympic_priv
->srb_wait
, jiffies
+60*HZ
);
924 if(signal_pending(current
)) {
925 printk(KERN_WARNING
"%s: SRB timed out.\n",
927 printk(KERN_WARNING
"SISR=%x MISR=%x\n",
928 readl(olympic_mmio
+SISR
),
929 readl(olympic_mmio
+LISR
));
930 olympic_priv
->srb_queued
=0;
935 restore_flags(flags
) ;
936 olympic_priv
->rx_status_last_received
++;
937 olympic_priv
->rx_status_last_received
&=OLYMPIC_RX_RING_SIZE
-1;
939 for(i
=0;i
<OLYMPIC_RX_RING_SIZE
;i
++) {
940 dev_kfree_skb(olympic_priv
->rx_ring_skb
[olympic_priv
->rx_status_last_received
]);
941 olympic_priv
->rx_status_last_received
++;
942 olympic_priv
->rx_status_last_received
&=OLYMPIC_RX_RING_SIZE
-1;
945 /* reset tx/rx fifo's and busmaster logic */
947 writel(readl(olympic_mmio
+BCTL
)|(3<<13),olympic_mmio
+BCTL
);
949 writel(readl(olympic_mmio
+BCTL
)&~(3<<13),olympic_mmio
+BCTL
);
952 printk("srb(%p): ",srb
);
954 printk("%x ",readb(srb
+i
));
957 free_irq(dev
->irq
,dev
);
964 static void olympic_set_rx_mode(struct net_device
*dev
)
966 struct olympic_private
*olympic_priv
= (struct olympic_private
*) dev
->priv
;
967 __u8
*olympic_mmio
= olympic_priv
->olympic_mmio
;
970 struct dev_mc_list
*dmi
;
971 unsigned char dev_mc_address
[4] ;
974 writel(olympic_priv
->srb
,olympic_mmio
+LAPA
);
975 srb
=olympic_priv
->olympic_lap
+ (olympic_priv
->srb
& (~0xf800));
976 options
= olympic_priv
->olympic_copy_all_options
;
978 if (dev
->flags
&IFF_PROMISC
)
983 /* Only issue the srb if there is a change in options */
985 if ((options
^ olympic_priv
->olympic_copy_all_options
)) {
987 /* Now to issue the srb command to alter the copy.all.options */
989 writeb(SRB_MODIFY_RECEIVE_OPTIONS
,srb
);
991 writeb(OLYMPIC_CLEAR_RET_CODE
,srb
+2);
993 writeb(olympic_priv
->olympic_receive_options
,srb
+4);
994 writeb(options
,srb
+5);
996 olympic_priv
->srb_queued
=2; /* Can't sleep, use srb_bh */
998 writel(LISR_SRB_CMD
,olympic_mmio
+LISR_SUM
);
1000 olympic_priv
->olympic_copy_all_options
= options
;
1005 /* Set the functional addresses we need for multicast */
1007 dev_mc_address
[0] = dev_mc_address
[1] = dev_mc_address
[2] = dev_mc_address
[3] = 0 ;
1009 for (i
=0,dmi
=dev
->mc_list
;i
< dev
->mc_count
; i
++,dmi
= dmi
->next
) {
1010 dev_mc_address
[0] |= dmi
->dmi_addr
[2] ;
1011 dev_mc_address
[1] |= dmi
->dmi_addr
[3] ;
1012 dev_mc_address
[2] |= dmi
->dmi_addr
[4] ;
1013 dev_mc_address
[3] |= dmi
->dmi_addr
[5] ;
1016 writeb(SRB_SET_FUNC_ADDRESS
,srb
+0);
1018 writeb(OLYMPIC_CLEAR_RET_CODE
,srb
+2);
1022 writeb(dev_mc_address
[0],srb
+6);
1023 writeb(dev_mc_address
[1],srb
+7);
1024 writeb(dev_mc_address
[2],srb
+8);
1025 writeb(dev_mc_address
[3],srb
+9);
1027 olympic_priv
->srb_queued
= 2 ;
1028 writel(LISR_SRB_CMD
,olympic_mmio
+LISR_SUM
);
1032 static void olympic_srb_bh(struct net_device
*dev
)
1034 struct olympic_private
*olympic_priv
= (struct olympic_private
*) dev
->priv
;
1035 __u8
*olympic_mmio
= olympic_priv
->olympic_mmio
;
1038 writel(olympic_priv
->srb
,olympic_mmio
+LAPA
);
1039 srb
=olympic_priv
->olympic_lap
+ (olympic_priv
->srb
& (~0xf800));
1041 switch (readb(srb
)) {
1043 /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous)
1044 * At some point we should do something if we get an error, such as
1045 * resetting the IFF_PROMISC flag in dev
1048 case SRB_MODIFY_RECEIVE_OPTIONS
:
1049 switch (readb(srb
+2)) {
1051 printk(KERN_WARNING
"%s: Unrecognized srb command\n",dev
->name
) ;
1054 printk(KERN_WARNING
"%s: Adapter must be open for this operation, doh!!\n",dev
->name
);
1057 if (olympic_priv
->olympic_message_level
)
1058 printk(KERN_WARNING
"%s: Receive Options Modified to %x,%x\n",dev
->name
,olympic_priv
->olympic_copy_all_options
, olympic_priv
->olympic_receive_options
) ;
1060 } /* switch srb[2] */
1063 /* SRB_SET_GROUP_ADDRESS - Multicast group setting
1066 case SRB_SET_GROUP_ADDRESS
:
1067 switch (readb(srb
+2)) {
1071 printk(KERN_WARNING
"%s: Unrecognized srb command \n",dev
->name
) ;
1074 printk(KERN_WARNING
"%s: Adapter must be open for this operation, doh!!\n",dev
->name
);
1077 printk(KERN_WARNING
"%s: Group/Functional address indicator bits not set correctly\n",dev
->name
) ;
1079 case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */
1080 printk(KERN_WARNING
"%s: Group address registers full\n",dev
->name
) ;
1083 printk(KERN_INFO
"%s: Group Address already set.\n",dev
->name
) ;
1087 } /* switch srb[2] */
1090 /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list
1093 case SRB_RESET_GROUP_ADDRESS
:
1094 switch (readb(srb
+2)) {
1098 printk(KERN_WARNING
"%s: Unrecognized srb command \n",dev
->name
) ;
1101 printk(KERN_WARNING
"%s: Adapter must be open for this operation, doh!!\n",dev
->name
) ;
1103 case 0x39: /* Must deal with this if individual multicast addresses used */
1104 printk(KERN_INFO
"%s: Group address not found \n",dev
->name
);
1108 } /* switch srb[2] */
1112 /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode
1115 case SRB_SET_FUNC_ADDRESS
:
1116 switch (readb(srb
+2)) {
1118 if (olympic_priv
->olympic_message_level
)
1119 printk(KERN_INFO
"%s: Functional Address Mask Set \n",dev
->name
) ;
1122 printk(KERN_WARNING
"%s: Unrecognized srb command \n",dev
->name
) ;
1125 printk(KERN_WARNING
"%s: Adapter must be open for this operation, doh!!\n",dev
->name
) ;
1129 } /* switch srb[2] */
1132 /* SRB_READ_LOG - Read and reset the adapter error counters
1136 switch (readb(srb
+2)) {
1138 if (olympic_priv
->olympic_message_level
)
1139 printk(KERN_INFO
"%s: Read Log issued\n",dev
->name
) ;
1142 printk(KERN_WARNING
"%s: Unrecognized srb command \n",dev
->name
) ;
1145 printk(KERN_WARNING
"%s: Adapter must be open for this operation, doh!!\n",dev
->name
) ;
1148 } /* switch srb[2] */
1151 /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */
1153 case SRB_READ_SR_COUNTERS
:
1154 switch (readb(srb
+2)) {
1156 if (olympic_priv
->olympic_message_level
)
1157 printk(KERN_INFO
"%s: Read Source Routing Counters issued\n",dev
->name
) ;
1160 printk(KERN_WARNING
"%s: Unrecognized srb command \n",dev
->name
) ;
1163 printk(KERN_WARNING
"%s: Adapter must be open for this operation, doh!!\n",dev
->name
) ;
1167 } /* switch srb[2] */
1171 printk(KERN_WARNING
"%s: Unrecognized srb bh return value.\n",dev
->name
);
1173 } /* switch srb[0] */
1177 static struct net_device_stats
* olympic_get_stats(struct net_device
*dev
)
1179 struct olympic_private
*olympic_priv
;
1180 olympic_priv
=(struct olympic_private
*) dev
->priv
;
1181 return (struct net_device_stats
*) &olympic_priv
->olympic_stats
;
1184 static int olympic_set_mac_address (struct net_device
*dev
, void *addr
)
1186 struct sockaddr
*saddr
= addr
;
1187 struct olympic_private
*olympic_priv
= (struct olympic_private
*)dev
->priv
;
1189 if (netif_running(dev
)) {
1190 printk(KERN_WARNING
"%s: Cannot set mac/laa address while card is open\n", dev
->name
) ;
1194 memcpy(olympic_priv
->olympic_laa
, saddr
->sa_data
,dev
->addr_len
) ;
1196 if (olympic_priv
->olympic_message_level
) {
1197 printk(KERN_INFO
"%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev
->name
, olympic_priv
->olympic_laa
[0],
1198 olympic_priv
->olympic_laa
[1], olympic_priv
->olympic_laa
[2],
1199 olympic_priv
->olympic_laa
[3], olympic_priv
->olympic_laa
[4],
1200 olympic_priv
->olympic_laa
[5]);
1206 static void olympic_arb_cmd(struct net_device
*dev
)
1208 struct olympic_private
*olympic_priv
= (struct olympic_private
*) dev
->priv
;
1209 __u8
*olympic_mmio
=olympic_priv
->olympic_mmio
;
1210 __u8
*arb_block
, *asb_block
, *srb
;
1212 __u16 frame_len
, buffer_len
;
1213 struct sk_buff
*mac_frame
;
1217 __u16 lan_status
= 0, lan_status_diff
; /* Initialize to stop compiler warning */
1218 __u8 fdx_prot_error
;
1221 #if OLYMPIC_NETWORK_MONITOR
1222 struct trh_hdr
*mac_hdr
;
1225 arb_block
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->arb
) ;
1226 asb_block
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->asb
) ;
1227 srb
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->srb
) ;
1228 writel(readl(olympic_mmio
+LAPA
),olympic_mmio
+LAPWWO
);
1230 if (readb(arb_block
+0) == ARB_RECEIVE_DATA
) { /* Receive.data, MAC frames */
1232 header_len
= readb(arb_block
+8) ; /* 802.5 Token-Ring Header Length */
1233 frame_len
= swab16(readw(arb_block
+ 10)) ;
1235 buff_off
= swab16(readw(arb_block
+ 6)) ;
1237 buf_ptr
= olympic_priv
->olympic_lap
+ buff_off
;
1242 frame_data
= buf_ptr
+offsetof(struct mac_receive_buffer
,frame_data
) ;
1244 for (i
=0 ; i
< 14 ; i
++) {
1245 printk("Loc %d = %02x\n",i
,readb(frame_data
+ i
));
1248 printk("next %04x, fs %02x, len %04x \n",readw(buf_ptr
+offsetof(struct mac_receive_buffer
,next
)), readb(buf_ptr
+offsetof(struct mac_receive_buffer
,frame_status
)), readw(buf_ptr
+offsetof(struct mac_receive_buffer
,buffer_length
)));
1251 mac_frame
= dev_alloc_skb(frame_len
) ;
1253 /* Walk the buffer chain, creating the frame */
1256 frame_data
= buf_ptr
+offsetof(struct mac_receive_buffer
,frame_data
) ;
1257 buffer_len
= swab16(readw(buf_ptr
+offsetof(struct mac_receive_buffer
,buffer_length
)));
1258 memcpy_fromio(skb_put(mac_frame
, buffer_len
), frame_data
, buffer_len
) ;
1259 next_ptr
=readw(buf_ptr
+offsetof(struct mac_receive_buffer
,next
));
1261 } while (next_ptr
&& (buf_ptr
=olympic_priv
->olympic_lap
+ ntohs(next_ptr
)));
1263 #if OLYMPIC_NETWORK_MONITOR
1264 printk(KERN_WARNING
"%s: Received MAC Frame, details: \n",dev
->name
) ;
1265 mac_hdr
= (struct trh_hdr
*)mac_frame
->data
;
1266 printk(KERN_WARNING
"%s: MAC Frame Dest. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev
->name
, mac_hdr
->daddr
[0], mac_hdr
->daddr
[1], mac_hdr
->daddr
[2], mac_hdr
->daddr
[3], mac_hdr
->daddr
[4], mac_hdr
->daddr
[5]) ;
1267 printk(KERN_WARNING
"%s: MAC Frame Srce. Addr: %02x:%02x:%02x:%02x:%02x:%02x \n", dev
->name
, mac_hdr
->saddr
[0], mac_hdr
->saddr
[1], mac_hdr
->saddr
[2], mac_hdr
->saddr
[3], mac_hdr
->saddr
[4], mac_hdr
->saddr
[5]) ;
1269 mac_frame
->dev
= dev
;
1270 mac_frame
->protocol
= tr_type_trans(mac_frame
,dev
);
1271 netif_rx(mac_frame
) ;
1273 /* Now tell the card we have dealt with the received frame */
1275 /* Set LISR Bit 1 */
1276 writel(LISR_ARB_FREE
,olympic_priv
->olympic_lap
+ LISR_SUM
);
1278 /* Is the ASB free ? */
1280 if (readb(asb_block
+ 2) != 0xff) {
1281 olympic_priv
->asb_queued
= 1 ;
1282 writel(LISR_ASB_FREE_REQ
,olympic_priv
->olympic_mmio
+LISR_SUM
);
1284 /* Drop out and wait for the bottom half to be run */
1287 writeb(ASB_RECEIVE_DATA
,asb_block
); /* Receive data */
1288 writeb(OLYMPIC_CLEAR_RET_CODE
,asb_block
+2); /* Necessary ?? */
1289 writeb(readb(arb_block
+6),asb_block
+6); /* Must send the address back to the adapter */
1290 writeb(readb(arb_block
+7),asb_block
+7); /* To let it know we have dealt with the data */
1292 writel(LISR_ASB_REPLY
| LISR_ASB_FREE_REQ
,olympic_priv
->olympic_mmio
+LISR_SUM
);
1294 olympic_priv
->asb_queued
= 2 ;
1298 } else if (readb(arb_block
) == ARB_LAN_CHANGE_STATUS
) { /* Lan.change.status */
1299 lan_status
= swab16(readw(arb_block
+6));
1300 fdx_prot_error
= readb(arb_block
+8) ;
1302 /* Issue ARB Free */
1303 writel(LISR_ARB_FREE
,olympic_priv
->olympic_mmio
+LISR_SUM
);
1305 lan_status_diff
= olympic_priv
->olympic_lan_status
^ lan_status
;
1307 if (lan_status_diff
& (LSC_LWF
| LSC_ARW
| LSC_FPE
| LSC_RR
) ) {
1308 if (lan_status_diff
& LSC_LWF
)
1309 printk(KERN_WARNING
"%s: Short circuit detected on the lobe\n",dev
->name
);
1310 if (lan_status_diff
& LSC_ARW
)
1311 printk(KERN_WARNING
"%s: Auto removal error\n",dev
->name
);
1312 if (lan_status_diff
& LSC_FPE
)
1313 printk(KERN_WARNING
"%s: FDX Protocol Error\n",dev
->name
);
1314 if (lan_status_diff
& LSC_RR
)
1315 printk(KERN_WARNING
"%s: Force remove MAC frame received\n",dev
->name
);
1317 /* Adapter has been closed by the hardware */
1319 /* reset tx/rx fifo's and busmaster logic */
1321 writel(readl(olympic_mmio
+BCTL
)|(3<<13),olympic_mmio
+BCTL
);
1323 writel(readl(olympic_mmio
+BCTL
)&~(3<<13),olympic_mmio
+BCTL
);
1324 netif_stop_queue(dev
);
1325 olympic_priv
->srb
= readw(olympic_priv
->olympic_lap
+ LAPWWO
) ;
1327 olympic_priv
->rx_status_last_received
++;
1328 olympic_priv
->rx_status_last_received
&=OLYMPIC_RX_RING_SIZE
-1;
1329 for(i
=0;i
<OLYMPIC_RX_RING_SIZE
;i
++) {
1330 dev_kfree_skb(olympic_priv
->rx_ring_skb
[olympic_priv
->rx_status_last_received
]);
1331 olympic_priv
->rx_status_last_received
++;
1332 olympic_priv
->rx_status_last_received
&=OLYMPIC_RX_RING_SIZE
-1;
1335 free_irq(dev
->irq
,dev
);
1337 printk(KERN_WARNING
"%s: Adapter has been closed \n", dev
->name
) ;
1339 } /* If serious error */
1341 if (olympic_priv
->olympic_message_level
) {
1342 if (lan_status_diff
& LSC_SIG_LOSS
)
1343 printk(KERN_WARNING
"%s: No receive signal detected \n", dev
->name
) ;
1344 if (lan_status_diff
& LSC_HARD_ERR
)
1345 printk(KERN_INFO
"%s: Beaconing \n",dev
->name
);
1346 if (lan_status_diff
& LSC_SOFT_ERR
)
1347 printk(KERN_WARNING
"%s: Adapter transmitted Soft Error Report Mac Frame \n",dev
->name
);
1348 if (lan_status_diff
& LSC_TRAN_BCN
)
1349 printk(KERN_INFO
"%s: We are tranmitting the beacon, aaah\n",dev
->name
);
1350 if (lan_status_diff
& LSC_SS
)
1351 printk(KERN_INFO
"%s: Single Station on the ring \n", dev
->name
);
1352 if (lan_status_diff
& LSC_RING_REC
)
1353 printk(KERN_INFO
"%s: Ring recovery ongoing\n",dev
->name
);
1354 if (lan_status_diff
& LSC_FDX_MODE
)
1355 printk(KERN_INFO
"%s: Operating in FDX mode\n",dev
->name
);
1358 if (lan_status_diff
& LSC_CO
) {
1360 if (olympic_priv
->olympic_message_level
)
1361 printk(KERN_INFO
"%s: Counter Overflow \n", dev
->name
);
1363 /* Issue READ.LOG command */
1365 writeb(SRB_READ_LOG
, srb
);
1367 writeb(OLYMPIC_CLEAR_RET_CODE
,srb
+2);
1372 olympic_priv
->srb_queued
=2; /* Can't sleep, use srb_bh */
1374 writel(LISR_SRB_CMD
,olympic_mmio
+LISR_SUM
);
1378 if (lan_status_diff
& LSC_SR_CO
) {
1380 if (olympic_priv
->olympic_message_level
)
1381 printk(KERN_INFO
"%s: Source routing counters overflow\n", dev
->name
);
1383 /* Issue a READ.SR.COUNTERS */
1385 writeb(SRB_READ_SR_COUNTERS
,srb
);
1387 writeb(OLYMPIC_CLEAR_RET_CODE
,srb
+2);
1390 olympic_priv
->srb_queued
=2; /* Can't sleep, use srb_bh */
1392 writel(LISR_SRB_CMD
,olympic_mmio
+LISR_SUM
);
1396 olympic_priv
->olympic_lan_status
= lan_status
;
1398 } /* Lan.change.status */
1400 printk(KERN_WARNING
"%s: Unknown arb command \n", dev
->name
);
1403 static void olympic_asb_bh(struct net_device
*dev
)
1405 struct olympic_private
*olympic_priv
= (struct olympic_private
*) dev
->priv
;
1406 __u8
*arb_block
, *asb_block
;
1408 arb_block
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->arb
) ;
1409 asb_block
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->asb
) ;
1411 if (olympic_priv
->asb_queued
== 1) { /* Dropped through the first time */
1413 writeb(ASB_RECEIVE_DATA
,asb_block
); /* Receive data */
1414 writeb(OLYMPIC_CLEAR_RET_CODE
,asb_block
+2); /* Necessary ?? */
1415 writeb(readb(arb_block
+6),asb_block
+6); /* Must send the address back to the adapter */
1416 writeb(readb(arb_block
+7),asb_block
+7); /* To let it know we have dealt with the data */
1418 writel(LISR_ASB_REPLY
| LISR_ASB_FREE_REQ
,olympic_priv
->olympic_mmio
+LISR_SUM
);
1419 olympic_priv
->asb_queued
= 2 ;
1424 if (olympic_priv
->asb_queued
== 2) {
1425 switch (readb(asb_block
+2)) {
1427 printk(KERN_WARNING
"%s: Unrecognized command code \n", dev
->name
);
1430 printk(KERN_WARNING
"%s: Unrecognized buffer address \n", dev
->name
);
1433 /* Valid response, everything should be ok again */
1436 printk(KERN_WARNING
"%s: Invalid return code in asb\n",dev
->name
);
1440 olympic_priv
->asb_queued
= 0 ;
1443 static int olympic_change_mtu(struct net_device
*dev
, int mtu
)
1445 struct olympic_private
*olympic_priv
= (struct olympic_private
*) dev
->priv
;
1448 if (olympic_priv
->olympic_ring_speed
== 4)
1459 olympic_priv
->pkt_buf_sz
= mtu
+ TR_HLEN
;
1464 #if OLYMPIC_NETWORK_MONITOR
1465 #ifdef CONFIG_PROC_FS
1466 static int olympic_proc_info(char *buffer
, char **start
, off_t offset
, int length
, int *eof
, void *data
)
1468 struct pci_dev
*pci_device
= NULL
;
1474 struct net_device
*dev
;
1477 size
= sprintf(buffer
,
1478 "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapters\n");
1484 while((pci_device
=pci_find_device(PCI_VENDOR_ID_IBM
, PCI_DEVICE_ID_IBM_TR_WAKE
, pci_device
))) {
1486 for (dev
= dev_base
; dev
!= NULL
; dev
= dev
->next
)
1488 if (dev
->base_addr
== pci_device
->resource
[0].start
) { /* Yep, an Olympic device */
1489 size
= sprintf_info(buffer
+len
, dev
);
1498 if(pos
>offset
+length
)
1504 *start
=buffer
+(offset
-begin
); /* Start of wanted data */
1505 len
-=(offset
-begin
); /* Start slop */
1507 len
=length
; /* Ending slop */
1511 static int sprintf_info(char *buffer
, struct net_device
*dev
)
1513 struct olympic_private
*olympic_priv
=(struct olympic_private
*)dev
->priv
;
1514 __u8
*oat
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->olympic_addr_table_addr
) ;
1515 __u8
*opt
= (__u8
*)(olympic_priv
->olympic_lap
+ olympic_priv
->olympic_parms_addr
) ;
1518 size
= sprintf(buffer
, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
1521 size
+= sprintf(buffer
+size
, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n",
1529 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)),
1530 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+1),
1531 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+2),
1532 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+3),
1533 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+4),
1534 readb(oat
+offsetof(struct olympic_adapter_addr_table
,node_addr
)+5),
1535 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)),
1536 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)+1),
1537 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)+2),
1538 readb(oat
+offsetof(struct olympic_adapter_addr_table
,func_addr
)+3));
1540 size
+= sprintf(buffer
+size
, "\n%6s: Token Ring Parameters Table:\n", dev
->name
);
1542 size
+= sprintf(buffer
+size
, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n",
1545 size
+= sprintf(buffer
+size
, "%6s: %02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x :\n",
1547 readb(opt
+offsetof(struct olympic_parameters_table
, phys_addr
)),
1548 readb(opt
+offsetof(struct olympic_parameters_table
, phys_addr
)+1),
1549 readb(opt
+offsetof(struct olympic_parameters_table
, phys_addr
)+2),
1550 readb(opt
+offsetof(struct olympic_parameters_table
, phys_addr
)+3),
1551 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)),
1552 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+1),
1553 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+2),
1554 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+3),
1555 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+4),
1556 readb(opt
+offsetof(struct olympic_parameters_table
, up_node_addr
)+5),
1557 readb(opt
+offsetof(struct olympic_parameters_table
, poll_addr
)),
1558 readb(opt
+offsetof(struct olympic_parameters_table
, poll_addr
)+1),
1559 readb(opt
+offsetof(struct olympic_parameters_table
, poll_addr
)+2),
1560 readb(opt
+offsetof(struct olympic_parameters_table
, poll_addr
)+3),
1561 readb(opt
+offsetof(struct olympic_parameters_table
, poll_addr
)+4),
1562 readb(opt
+offsetof(struct olympic_parameters_table
, poll_addr
)+5),
1563 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, acc_priority
))),
1564 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, auth_source_class
))),
1565 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, att_code
))));
1567 size
+= sprintf(buffer
+size
, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
1570 size
+= sprintf(buffer
+size
, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x : %04x : %04x : %04x : \n",
1572 readb(opt
+offsetof(struct olympic_parameters_table
, source_addr
)),
1573 readb(opt
+offsetof(struct olympic_parameters_table
, source_addr
)+1),
1574 readb(opt
+offsetof(struct olympic_parameters_table
, source_addr
)+2),
1575 readb(opt
+offsetof(struct olympic_parameters_table
, source_addr
)+3),
1576 readb(opt
+offsetof(struct olympic_parameters_table
, source_addr
)+4),
1577 readb(opt
+offsetof(struct olympic_parameters_table
, source_addr
)+5),
1578 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, beacon_type
))),
1579 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, major_vector
))),
1580 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, lan_status
))),
1581 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, local_ring
))),
1582 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, mon_error
))),
1583 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, frame_correl
))));
1585 size
+= sprintf(buffer
+size
, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
1588 size
+= sprintf(buffer
+size
, "%6s: : %02x : %02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x : \n",
1590 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, beacon_transmit
))),
1591 swab16(readw(opt
+offsetof(struct olympic_parameters_table
, beacon_receive
))),
1592 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_naun
)),
1593 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_naun
)+1),
1594 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_naun
)+2),
1595 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_naun
)+3),
1596 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_naun
)+4),
1597 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_naun
)+5),
1598 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_phys
)),
1599 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_phys
)+1),
1600 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_phys
)+2),
1601 readb(opt
+offsetof(struct olympic_parameters_table
, beacon_phys
)+3));
1611 static struct net_device
* dev_olympic
[OLYMPIC_MAX_ADAPTERS
];
1613 int init_module(void)
1617 #if OLYMPIC_NETWORK_MONITOR
1618 #ifdef CONFIG_PROC_FS
1619 create_proc_read_entry("net/olympic_tr",0,0,olympic_proc_info
,NULL
);
1622 for (i
= 0; (i
<OLYMPIC_MAX_ADAPTERS
); i
++) {
1623 dev_olympic
[i
] = NULL
;
1624 dev_olympic
[i
] = init_trdev(dev_olympic
[i
], 0);
1625 if (dev_olympic
[i
] == NULL
)
1628 dev_olympic
[i
]->init
= &olympic_probe
;
1630 if (register_trdev(dev_olympic
[i
]) != 0) {
1631 kfree(dev_olympic
[i
]);
1632 dev_olympic
[i
] = NULL
;
1634 printk("Olympic: No IBM PCI Token Ring cards found in system.\n");
1637 printk("Olympic: %d IBM PCI Token Ring card(s) found in system.\n",i
) ;
1646 void cleanup_module(void)
1650 for (i
= 0; i
< OLYMPIC_MAX_ADAPTERS
; i
++)
1651 if (dev_olympic
[i
]) {
1652 unregister_trdev(dev_olympic
[i
]);
1653 release_region(dev_olympic
[i
]->base_addr
, OLYMPIC_IO_SPACE
);
1654 kfree(dev_olympic
[i
]->priv
);
1655 kfree(dev_olympic
[i
]);
1656 dev_olympic
[i
] = NULL
;
1659 #if OLYMPIC_NETWORK_MONITOR
1660 #ifdef CONFIG_PROC_FS
1661 remove_proc_entry("net/olympic_tr", NULL
) ;