Merge with Linux 2.4.0-test5-pre3.
[linux-2.6/linux-mips.git] / drivers / net / tokenring / olympic.c
blobb8784bb29feb34a14a612be10e95a2ac5870895e
1 /*
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
6 * chipset.
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
27 * the pci resource.
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
31 * squashed.
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
43 * To Do:
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
57 * kernel.
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>
71 #include <linux/in.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>
87 #include <asm/io.h>
88 #include <asm/system.h>
89 #include <asm/bitops.h>
91 #include "olympic.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",
108 "Unknown stage"};
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
119 * 0 = Autosense
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
128 * at the wrong speed
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") ;
141 /* Message Level */
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) ;
163 #endif
164 #endif
166 int __init olympic_probe(struct net_device *dev)
168 int cards_found;
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;
178 int card_no = 0 ;
179 if (pci_present()) {
181 while((pci_device=pci_find_device(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_TR_WAKE, pci_device))) {
182 __u16 pci_command ;
184 if (pci_enable_device(pci_device))
185 continue;
187 /* These lines are needed by the PowerPC, it appears
188 that these flags
189 * are not being set properly for the PPC, this may
190 well be fixed with
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)) {
201 card_no++ ;
202 continue ;
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);
209 #ifndef MODULE
210 dev=init_trdev(dev, 0);
211 #endif
212 dev->priv=(void *)olympic_priv;
213 #if OLYMPIC_DEBUG
214 printk("pci_device: %p, dev:%p, dev->priv: %p\n", pci_device, dev, dev->priv);
215 #endif
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 ;
227 else
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);
235 kfree(dev->priv);
236 return 0;
239 dev->open=&olympic_open;
240 dev->hard_start_xmit=&olympic_xmit;
241 dev->change_mtu=&olympic_change_mtu;
243 dev->stop=&olympic_close;
244 dev->do_ioctl=NULL;
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 ;
248 return 1;
251 return 0 ;
255 static int __init olympic_init(struct net_device *dev)
257 struct olympic_private *olympic_priv;
258 __u8 *olympic_mmio, *init_srb,*adapter_addr;
259 unsigned long t;
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);
270 t=jiffies;
271 while((readl(olympic_priv->olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
272 schedule();
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) ;
276 return -1;
280 spin_lock_init(&olympic_priv->olympic_lock) ;
282 #if OLYMPIC_DEBUG
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));
286 #endif
287 /* Aaaahhh, You have got to be real careful setting GPR, the card
288 holds the previous values from flash memory, including autosense
289 and ring speed */
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);
309 #if OLYMPIC_DEBUG
310 printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ;
311 #endif
312 /* start solo init */
313 writel((1<<15),olympic_mmio+SISR_MASK_SUM);
315 t=jiffies;
316 while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {
317 schedule();
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);
321 return -1;
325 writel(readl(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
327 #if OLYMPIC_DEBUG
328 printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
329 #endif
331 init_srb=olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWO)) & (~0xf800));
333 #if OLYMPIC_DEBUG
335 int i;
336 printk("init_srb(%p): ",init_srb);
337 for(i=0;i<20;i++)
338 printk("%x ",readb(init_srb+i));
339 printk("\n");
341 #endif
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);
345 return -1;
348 if (olympic_priv->olympic_message_level) {
349 if ( readb(init_srb +2) & 0x40) {
350 printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ;
351 } else {
352 printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n");
356 uaa_addr=swab16(readw(init_srb+8));
358 #if OLYMPIC_DEBUG
359 printk("UAA resides at %x\n",uaa_addr);
360 #endif
362 writel(uaa_addr,olympic_mmio+LAPA);
363 adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800));
365 #if OLYMPIC_DEBUG
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));
369 #endif
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));
376 return 0;
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;
384 unsigned long flags;
385 char open_error[255] ;
386 int i, open_finished = 1 ;
388 #if OLYMPIC_NETWORK_MONITOR
389 __u8 *oat ;
390 __u8 *opt ;
391 #endif
393 if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {
394 return -EAGAIN;
397 #if OLYMPIC_DEBUG
398 printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
399 printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR));
400 #endif
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));
413 #if OLYMPIC_DEBUG
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");
417 #endif
418 do {
419 int i;
421 save_flags(flags);
422 cli();
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);
437 #else
438 writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
439 #endif
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",
460 dev->name);
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;
465 break;
468 restore_flags(flags);
469 #if OLYMPIC_DEBUG
470 printk("init_srb(%p): ",init_srb);
471 for(i=0;i<20;i++)
472 printk("%02x ",readb(init_srb+i));
473 printk("\n");
474 #endif
476 /* If we get the same return response as we set, the interrupt wasn't raised and the open
477 * timed out.
480 if(readb(init_srb+2)== OLYMPIC_CLEAR_RET_CODE) {
481 printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ;
482 return -EIO ;
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);
489 open_finished = 0 ;
490 } else {
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);
500 return -EIO ;
503 printk(KERN_WARNING "%s: %s\n",dev->name,open_error);
504 free_irq(dev->irq,dev) ;
505 return -EIO ;
507 } /* if autosense && open_finished */
508 } else {
509 printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name,init_srb[2]);
510 free_irq(dev->irq, dev);
511 return -EIO;
513 } else
514 open_finished = 1 ;
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 ;
525 else
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 ;
539 /* setup rx ring */
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++) {
547 struct sk_buff *skb;
549 skb=dev_alloc_skb(olympic_priv->pkt_buf_sz);
550 if(skb == NULL)
551 break;
553 skb->dev = dev;
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;
560 if (i==0) {
561 printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
562 free_irq(dev->irq, dev);
563 return -EIO;
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);
578 #if OLYMPIC_DEBUG
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]);
586 #endif
588 writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
590 #if OLYMPIC_DEBUG
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]);
594 #endif
596 writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);
598 /* setup tx ring */
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);
618 #if OLYMPIC_DEBUG
619 printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
620 printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));
621 #endif
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));
649 #endif
651 netif_start_queue(dev);
652 MOD_INC_USE_COUNT ;
653 return 0;
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
661 * all the frames.
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;
676 int i;
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);
685 #if OLYMPIC_DEBUG
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));
688 #endif
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;
694 #if OLYMPIC_DEBUG
695 printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt);
696 #endif
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++;
715 } else {
717 if (buffer_cnt == 1) {
718 skb = dev_alloc_skb(olympic_priv->pkt_buf_sz) ;
719 } else {
720 skb = dev_alloc_skb(length) ;
723 if (skb == NULL) {
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) ;
729 } else {
730 skb->dev = dev ;
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. */
738 if (buffer_cnt==1) {
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 ;
748 netif_rx(skb2) ;
749 } else {
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) ;
757 } while (--i) ;
759 skb->protocol = tr_type_trans(skb,dev);
760 netif_rx(skb) ;
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);
777 } /* while */
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;
786 __u32 sisr;
787 __u8 *adapter_check_area ;
789 sisr=readl(olympic_mmio+SISR_RR) ; /* Reset sisr */
791 if (!(sisr & SISR_MI)) /* Interrupt isn't for us */
792 return ;
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);
818 } /* SISR_TX1_EOF */
820 if (sisr & SISR_RX_STATUS) {
821 olympic_rx(dev);
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) ;
842 } /* SISR_ARB_CMD */
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 */
856 } else {
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);
890 return 0;
891 } else {
892 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
893 return 1;
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;
903 unsigned long flags;
904 int i;
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);
912 writeb(0,srb+1);
913 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
915 save_flags(flags);
916 cli();
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",
926 dev->name);
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;
931 break;
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);
948 udelay(1);
949 writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
951 #if OLYMPIC_DEBUG
952 printk("srb(%p): ",srb);
953 for(i=0;i<4;i++)
954 printk("%x ",readb(srb+i));
955 printk("\n");
956 #endif
957 free_irq(dev->irq,dev);
959 MOD_DEC_USE_COUNT ;
960 return 0;
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 ;
968 __u8 options = 0;
969 __u8 *srb;
970 struct dev_mc_list *dmi ;
971 unsigned char dev_mc_address[4] ;
972 int i ;
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)
979 options |= 0x61 ;
980 else
981 options &= ~0x61 ;
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);
990 writeb(0,srb+1);
991 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
992 writeb(0,srb+3);
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 ;
1002 return ;
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);
1017 writeb(0,srb+1);
1018 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1019 writeb(0,srb+3);
1020 writeb(0,srb+4);
1021 writeb(0,srb+5);
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 ;
1036 __u8 *srb;
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)) {
1050 case 0x01:
1051 printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ;
1052 break ;
1053 case 0x04:
1054 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
1055 break ;
1056 default:
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) ;
1059 break ;
1060 } /* switch srb[2] */
1061 break ;
1063 /* SRB_SET_GROUP_ADDRESS - Multicast group setting
1066 case SRB_SET_GROUP_ADDRESS:
1067 switch (readb(srb+2)) {
1068 case 0x00:
1069 break ;
1070 case 0x01:
1071 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1072 break ;
1073 case 0x04:
1074 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
1075 break ;
1076 case 0x3c:
1077 printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ;
1078 break ;
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) ;
1081 break ;
1082 case 0x55:
1083 printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ;
1084 break ;
1085 default:
1086 break ;
1087 } /* switch srb[2] */
1088 break ;
1090 /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list
1093 case SRB_RESET_GROUP_ADDRESS:
1094 switch (readb(srb+2)) {
1095 case 0x00:
1096 break ;
1097 case 0x01:
1098 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1099 break ;
1100 case 0x04:
1101 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1102 break ;
1103 case 0x39: /* Must deal with this if individual multicast addresses used */
1104 printk(KERN_INFO "%s: Group address not found \n",dev->name);
1105 break ;
1106 default:
1107 break ;
1108 } /* switch srb[2] */
1109 break ;
1112 /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode
1115 case SRB_SET_FUNC_ADDRESS:
1116 switch (readb(srb+2)) {
1117 case 0x00:
1118 if (olympic_priv->olympic_message_level)
1119 printk(KERN_INFO "%s: Functional Address Mask Set \n",dev->name) ;
1120 break ;
1121 case 0x01:
1122 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1123 break ;
1124 case 0x04:
1125 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1126 break ;
1127 default:
1128 break ;
1129 } /* switch srb[2] */
1130 break ;
1132 /* SRB_READ_LOG - Read and reset the adapter error counters
1135 case SRB_READ_LOG:
1136 switch (readb(srb+2)) {
1137 case 0x00:
1138 if (olympic_priv->olympic_message_level)
1139 printk(KERN_INFO "%s: Read Log issued\n",dev->name) ;
1140 break ;
1141 case 0x01:
1142 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1143 break ;
1144 case 0x04:
1145 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1146 break ;
1148 } /* switch srb[2] */
1149 break ;
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)) {
1155 case 0x00:
1156 if (olympic_priv->olympic_message_level)
1157 printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ;
1158 break ;
1159 case 0x01:
1160 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1161 break ;
1162 case 0x04:
1163 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1164 break ;
1165 default:
1166 break ;
1167 } /* switch srb[2] */
1168 break ;
1170 default:
1171 printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name);
1172 break ;
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) ;
1191 return -EIO ;
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]);
1203 return 0 ;
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 ;
1211 __u8 header_len ;
1212 __u16 frame_len, buffer_len ;
1213 struct sk_buff *mac_frame ;
1214 __u8 *buf_ptr ;
1215 __u8 *frame_data ;
1216 __u16 buff_off ;
1217 __u16 lan_status = 0, lan_status_diff ; /* Initialize to stop compiler warning */
1218 __u8 fdx_prot_error ;
1219 __u16 next_ptr;
1220 int i ;
1221 #if OLYMPIC_NETWORK_MONITOR
1222 struct trh_hdr *mac_hdr ;
1223 #endif
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 ;
1239 #if OLYMPIC_DEBUG
1241 int i;
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)));
1250 #endif
1251 mac_frame = dev_alloc_skb(frame_len) ;
1253 /* Walk the buffer chain, creating the frame */
1255 do {
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]) ;
1268 #endif
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);
1283 return ;
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 ;
1296 return ;
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);
1322 udelay(1);
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) ;
1338 MOD_DEC_USE_COUNT ;
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);
1366 writeb(0,srb+1);
1367 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1368 writeb(0,srb+3);
1369 writeb(0,srb+4);
1370 writeb(0,srb+5);
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);
1386 writeb(0,srb+1);
1387 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1388 writeb(0,srb+3);
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 */
1399 else
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 ;
1421 return ;
1424 if (olympic_priv->asb_queued == 2) {
1425 switch (readb(asb_block+2)) {
1426 case 0x01:
1427 printk(KERN_WARNING "%s: Unrecognized command code \n", dev->name);
1428 break ;
1429 case 0x26:
1430 printk(KERN_WARNING "%s: Unrecognized buffer address \n", dev->name);
1431 break ;
1432 case 0xFF:
1433 /* Valid response, everything should be ok again */
1434 break ;
1435 default:
1436 printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name);
1437 break ;
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;
1446 __u16 max_mtu ;
1448 if (olympic_priv->olympic_ring_speed == 4)
1449 max_mtu = 4500 ;
1450 else
1451 max_mtu = 18000 ;
1453 if (mtu > max_mtu)
1454 return -EINVAL ;
1455 if (mtu < 100)
1456 return -EINVAL ;
1458 dev->mtu = mtu ;
1459 olympic_priv->pkt_buf_sz = mtu + TR_HLEN ;
1461 return 0 ;
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 ;
1469 int len=0;
1470 off_t begin=0;
1471 off_t pos=0;
1472 int size;
1474 struct net_device *dev;
1477 size = sprintf(buffer,
1478 "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapters\n");
1480 pos+=size;
1481 len+=size;
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);
1490 len+=size;
1491 pos=begin+len;
1493 if(pos<offset)
1495 len=0;
1496 begin=pos;
1498 if(pos>offset+length)
1499 break;
1500 } /* if */
1501 } /* for */
1502 } /* While */
1504 *start=buffer+(offset-begin); /* Start of wanted data */
1505 len-=(offset-begin); /* Start slop */
1506 if(len>length)
1507 len=length; /* Ending slop */
1508 return len;
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) ;
1516 int size = 0 ;
1518 size = sprintf(buffer, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
1519 dev->name);
1521 size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n",
1522 dev->name,
1523 dev->dev_addr[0],
1524 dev->dev_addr[1],
1525 dev->dev_addr[2],
1526 dev->dev_addr[3],
1527 dev->dev_addr[4],
1528 dev->dev_addr[5],
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",
1543 dev->name) ;
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",
1546 dev->name,
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",
1568 dev->name) ;
1570 size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x : %04x : %04x : %04x : \n",
1571 dev->name,
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",
1586 dev->name) ;
1588 size += sprintf(buffer+size, "%6s: : %02x : %02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x : \n",
1589 dev->name,
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));
1604 return size;
1606 #endif
1607 #endif
1609 #ifdef MODULE
1611 static struct net_device* dev_olympic[OLYMPIC_MAX_ADAPTERS];
1613 int init_module(void)
1615 int i;
1617 #if OLYMPIC_NETWORK_MONITOR
1618 #ifdef CONFIG_PROC_FS
1619 create_proc_read_entry("net/olympic_tr",0,0,olympic_proc_info,NULL);
1620 #endif
1621 #endif
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)
1626 return -ENOMEM;
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;
1633 if (i == 0) {
1634 printk("Olympic: No IBM PCI Token Ring cards found in system.\n");
1635 return -EIO;
1636 } else {
1637 printk("Olympic: %d IBM PCI Token Ring card(s) found in system.\n",i) ;
1638 return 0;
1643 return 0;
1646 void cleanup_module(void)
1648 int i;
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) ;
1662 #endif
1663 #endif
1665 #endif /* MODULE */