1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80#define OLYMPIC_DEBUG 0
81
82
83#include <linux/module.h>
84#include <linux/kernel.h>
85#include <linux/errno.h>
86#include <linux/timer.h>
87#include <linux/in.h>
88#include <linux/ioport.h>
89#include <linux/string.h>
90#include <linux/proc_fs.h>
91#include <linux/ptrace.h>
92#include <linux/skbuff.h>
93#include <linux/interrupt.h>
94#include <linux/delay.h>
95#include <linux/netdevice.h>
96#include <linux/trdevice.h>
97#include <linux/stddef.h>
98#include <linux/init.h>
99#include <linux/pci.h>
100#include <linux/spinlock.h>
101#include <linux/bitops.h>
102#include <linux/jiffies.h>
103
104#include <net/checksum.h>
105#include <net/net_namespace.h>
106
107#include <asm/io.h>
108#include <asm/system.h>
109
110#include "olympic.h"
111
112
113
114
115
116
117
118
119
120static char version[] =
121"Olympic.c v1.0.5 6/04/02 - Peter De Schrijver & Mike Phillips" ;
122
123static char *open_maj_error[] = {"No error", "Lobe Media Test", "Physical Insertion",
124 "Address Verification", "Neighbor Notification (Ring Poll)",
125 "Request Parameters","FDX Registration Request",
126 "FDX Duplicate Address Check", "Station registration Query Wait",
127 "Unknown stage"};
128
129static char *open_min_error[] = {"No error", "Function Failure", "Signal Lost", "Wire Fault",
130 "Ring Speed Mismatch", "Timeout","Ring Failure","Ring Beaconing",
131 "Duplicate Node Address","Request Parameters","Remove Received",
132 "Reserved", "Reserved", "No Monitor Detected for RPL",
133 "Monitor Contention failer for RPL", "FDX Protocol Error"};
134
135
136
137MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
138MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ;
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ;
154module_param_array(ringspeed, int, NULL, 0);
155
156
157
158static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ;
159module_param_array(pkt_buf_sz, int, NULL, 0) ;
160
161
162
163static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ;
164module_param_array(message_level, int, NULL, 0) ;
165
166
167
168
169
170
171
172static int network_monitor[OLYMPIC_MAX_ADAPTERS] = {0,};
173module_param_array(network_monitor, int, NULL, 0);
174
175static struct pci_device_id olympic_pci_tbl[] = {
176 {PCI_VENDOR_ID_IBM,PCI_DEVICE_ID_IBM_TR_WAKE,PCI_ANY_ID,PCI_ANY_ID,},
177 { }
178};
179MODULE_DEVICE_TABLE(pci,olympic_pci_tbl) ;
180
181
182static int olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
183static int olympic_init(struct net_device *dev);
184static int olympic_open(struct net_device *dev);
185static netdev_tx_t olympic_xmit(struct sk_buff *skb,
186 struct net_device *dev);
187static int olympic_close(struct net_device *dev);
188static void olympic_set_rx_mode(struct net_device *dev);
189static void olympic_freemem(struct net_device *dev) ;
190static irqreturn_t olympic_interrupt(int irq, void *dev_id);
191static int olympic_set_mac_address(struct net_device *dev, void *addr) ;
192static void olympic_arb_cmd(struct net_device *dev);
193static int olympic_change_mtu(struct net_device *dev, int mtu);
194static void olympic_srb_bh(struct net_device *dev) ;
195static void olympic_asb_bh(struct net_device *dev) ;
196static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ;
197
198static const struct net_device_ops olympic_netdev_ops = {
199 .ndo_open = olympic_open,
200 .ndo_stop = olympic_close,
201 .ndo_start_xmit = olympic_xmit,
202 .ndo_change_mtu = olympic_change_mtu,
203 .ndo_set_multicast_list = olympic_set_rx_mode,
204 .ndo_set_mac_address = olympic_set_mac_address,
205};
206
207static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
208{
209 struct net_device *dev ;
210 struct olympic_private *olympic_priv;
211 static int card_no = -1 ;
212 int i ;
213
214 card_no++ ;
215
216 if ((i = pci_enable_device(pdev))) {
217 return i ;
218 }
219
220 pci_set_master(pdev);
221
222 if ((i = pci_request_regions(pdev,"olympic"))) {
223 goto op_disable_dev;
224 }
225
226 dev = alloc_trdev(sizeof(struct olympic_private)) ;
227 if (!dev) {
228 i = -ENOMEM;
229 goto op_release_dev;
230 }
231
232 olympic_priv = netdev_priv(dev) ;
233
234 spin_lock_init(&olympic_priv->olympic_lock) ;
235
236 init_waitqueue_head(&olympic_priv->srb_wait);
237 init_waitqueue_head(&olympic_priv->trb_wait);
238#if OLYMPIC_DEBUG
239 printk(KERN_INFO "pci_device: %p, dev:%p, dev->priv: %p\n", pdev, dev, netdev_priv(dev));
240#endif
241 dev->irq=pdev->irq;
242 dev->base_addr=pci_resource_start(pdev, 0);
243 olympic_priv->olympic_card_name = pci_name(pdev);
244 olympic_priv->pdev = pdev;
245 olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
246 olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
247 if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) {
248 goto op_free_iomap;
249 }
250
251 if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
252 olympic_priv->pkt_buf_sz = PKT_BUF_SZ ;
253 else
254 olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ;
255
256 dev->mtu = olympic_priv->pkt_buf_sz - TR_HLEN ;
257 olympic_priv->olympic_ring_speed = ringspeed[card_no] ;
258 olympic_priv->olympic_message_level = message_level[card_no] ;
259 olympic_priv->olympic_network_monitor = network_monitor[card_no];
260
261 if ((i = olympic_init(dev))) {
262 goto op_free_iomap;
263 }
264
265 dev->netdev_ops = &olympic_netdev_ops;
266 SET_NETDEV_DEV(dev, &pdev->dev);
267
268 pci_set_drvdata(pdev,dev) ;
269 register_netdev(dev) ;
270 printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name);
271 if (olympic_priv->olympic_network_monitor) {
272 char proc_name[20] ;
273 strcpy(proc_name,"olympic_") ;
274 strcat(proc_name,dev->name) ;
275 create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ;
276 printk("Olympic: Network Monitor information: /proc/%s\n",proc_name);
277 }
278 return 0 ;
279
280op_free_iomap:
281 if (olympic_priv->olympic_mmio)
282 iounmap(olympic_priv->olympic_mmio);
283 if (olympic_priv->olympic_lap)
284 iounmap(olympic_priv->olympic_lap);
285
286 free_netdev(dev);
287op_release_dev:
288 pci_release_regions(pdev);
289
290op_disable_dev:
291 pci_disable_device(pdev);
292 return i;
293}
294
295static int olympic_init(struct net_device *dev)
296{
297 struct olympic_private *olympic_priv;
298 u8 __iomem *olympic_mmio, *init_srb,*adapter_addr;
299 unsigned long t;
300 unsigned int uaa_addr;
301
302 olympic_priv=netdev_priv(dev);
303 olympic_mmio=olympic_priv->olympic_mmio;
304
305 printk("%s \n", version);
306 printk("%s. I/O at %hx, MMIO at %p, LAP at %p, using irq %d\n", olympic_priv->olympic_card_name, (unsigned int) dev->base_addr,olympic_priv->olympic_mmio, olympic_priv->olympic_lap, dev->irq);
307
308 writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL);
309 t=jiffies;
310 while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
311 schedule();
312 if(time_after(jiffies, t + 40*HZ)) {
313 printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
314 return -ENODEV;
315 }
316 }
317
318
319
320 if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
321 writel(readl(olympic_priv->olympic_mmio+FERMASK)|FERMASK_INT_BIT, olympic_mmio+FERMASK);
322 }
323
324#if OLYMPIC_DEBUG
325 printk("BCTL: %x\n",readl(olympic_mmio+BCTL));
326 printk("GPR: %x\n",readw(olympic_mmio+GPR));
327 printk("SISRMASK: %x\n",readl(olympic_mmio+SISR_MASK));
328#endif
329
330
331
332
333 writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL);
334
335 if (olympic_priv->olympic_ring_speed == 0) {
336 writew(readw(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
337 if (olympic_priv->olympic_message_level)
338 printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name);
339 } else if (olympic_priv->olympic_ring_speed == 16) {
340 if (olympic_priv->olympic_message_level)
341 printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name);
342 writew(GPR_16MBPS, olympic_mmio+GPR);
343 } else if (olympic_priv->olympic_ring_speed == 4) {
344 if (olympic_priv->olympic_message_level)
345 printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ;
346 writew(0, olympic_mmio+GPR);
347 }
348
349 writew(readw(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR);
350
351#if OLYMPIC_DEBUG
352 printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ;
353#endif
354
355
356
357
358
359
360 if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
361 t=jiffies;
362 while (!(readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE)) {
363 schedule() ;
364 if(time_after(jiffies, t + 2*HZ)) {
365 printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ;
366 return -ENODEV;
367 }
368 }
369 writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ;
370 }
371
372
373 writel((1<<15),olympic_mmio+SISR_MASK_SUM);
374
375 t=jiffies;
376 while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {
377 schedule();
378 if(time_after(jiffies, t + 15*HZ)) {
379 printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
380 return -ENODEV;
381 }
382 }
383
384 writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
385
386#if OLYMPIC_DEBUG
387 printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
388#endif
389
390 init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
391
392#if OLYMPIC_DEBUG
393{
394 int i;
395 printk("init_srb(%p): ",init_srb);
396 for(i=0;i<20;i++)
397 printk("%x ",readb(init_srb+i));
398 printk("\n");
399}
400#endif
401 if(readw(init_srb+6)) {
402 printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",readw(init_srb+6));
403 return -ENODEV;
404 }
405
406 if (olympic_priv->olympic_message_level) {
407 if ( readb(init_srb +2) & 0x40) {
408 printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ;
409 } else {
410 printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n");
411 }
412 }
413
414 uaa_addr=swab16(readw(init_srb+8));
415
416#if OLYMPIC_DEBUG
417 printk("UAA resides at %x\n",uaa_addr);
418#endif
419
420 writel(uaa_addr,olympic_mmio+LAPA);
421 adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800));
422
423 memcpy_fromio(&dev->dev_addr[0], adapter_addr,6);
424
425#if OLYMPIC_DEBUG
426 printk("adapter address: %pM\n", dev->dev_addr);
427#endif
428
429 olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12));
430 olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14));
431
432 return 0;
433
434}
435
436static int olympic_open(struct net_device *dev)
437{
438 struct olympic_private *olympic_priv=netdev_priv(dev);
439 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
440 unsigned long flags, t;
441 int i, open_finished = 1 ;
442 u8 resp, err;
443
444 DECLARE_WAITQUEUE(wait,current) ;
445
446 olympic_init(dev);
447
448 if(request_irq(dev->irq, &olympic_interrupt, IRQF_SHARED , "olympic", dev)) {
449 return -EAGAIN;
450 }
451
452#if OLYMPIC_DEBUG
453 printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
454 printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR));
455#endif
456
457 writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
458
459 writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK);
460
461 writel(LISR_LIE,olympic_mmio+LISR);
462
463
464
465 writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
466 init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
467
468#if OLYMPIC_DEBUG
469 printk("LAPWWO: %x, LAPA: %x\n",readw(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
470 printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK));
471 printk("Before the open command \n");
472#endif
473 do {
474 memset_io(init_srb,0,SRB_COMMAND_SIZE);
475
476 writeb(SRB_OPEN_ADAPTER,init_srb) ;
477 writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2);
478
479
480 if (olympic_priv->olympic_network_monitor)
481 writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);
482 else
483 writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
484
485
486
487
488
489 if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) {
490 writeb(olympic_priv->olympic_laa[0],init_srb+12);
491 writeb(olympic_priv->olympic_laa[1],init_srb+13);
492 writeb(olympic_priv->olympic_laa[2],init_srb+14);
493 writeb(olympic_priv->olympic_laa[3],init_srb+15);
494 writeb(olympic_priv->olympic_laa[4],init_srb+16);
495 writeb(olympic_priv->olympic_laa[5],init_srb+17);
496 memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;
497 }
498 writeb(1,init_srb+30);
499
500 spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
501 olympic_priv->srb_queued=1;
502
503 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
504 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
505
506 t = jiffies ;
507
508 add_wait_queue(&olympic_priv->srb_wait,&wait) ;
509 set_current_state(TASK_INTERRUPTIBLE) ;
510
511 while(olympic_priv->srb_queued) {
512 schedule() ;
513 if(signal_pending(current)) {
514 printk(KERN_WARNING "%s: Signal received in open.\n",
515 dev->name);
516 printk(KERN_WARNING "SISR=%x LISR=%x\n",
517 readl(olympic_mmio+SISR),
518 readl(olympic_mmio+LISR));
519 olympic_priv->srb_queued=0;
520 break;
521 }
522 if (time_after(jiffies, t + 10*HZ)) {
523 printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ;
524 olympic_priv->srb_queued=0;
525 break ;
526 }
527 set_current_state(TASK_INTERRUPTIBLE) ;
528 }
529 remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
530 set_current_state(TASK_RUNNING) ;
531 olympic_priv->srb_queued = 0 ;
532#if OLYMPIC_DEBUG
533 printk("init_srb(%p): ",init_srb);
534 for(i=0;i<20;i++)
535 printk("%02x ",readb(init_srb+i));
536 printk("\n");
537#endif
538
539
540
541
542
543 switch (resp = readb(init_srb+2)) {
544 case OLYMPIC_CLEAR_RET_CODE:
545 printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ;
546 goto out;
547 case 0:
548 open_finished = 1;
549 break;
550 case 0x07:
551 if (!olympic_priv->olympic_ring_speed && open_finished) {
552 printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name);
553 open_finished = 0 ;
554 continue;
555 }
556
557 err = readb(init_srb+7);
558
559 if (!olympic_priv->olympic_ring_speed && ((err & 0x0f) == 0x0d)) {
560 printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);
561 printk(KERN_WARNING "%s: Please try again with a specified ring speed \n",dev->name);
562 } else {
563 printk(KERN_WARNING "%s: %s - %s\n", dev->name,
564 open_maj_error[(err & 0xf0) >> 4],
565 open_min_error[(err & 0x0f)]);
566 }
567 goto out;
568
569 case 0x32:
570 printk(KERN_WARNING "%s: Invalid LAA: %pM\n",
571 dev->name, olympic_priv->olympic_laa);
572 goto out;
573
574 default:
575 printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp);
576 goto out;
577
578 }
579 } while (!(open_finished)) ;
580
581 if (readb(init_srb+18) & (1<<3))
582 if (olympic_priv->olympic_message_level)
583 printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name);
584
585 if (readb(init_srb+18) & (1<<1))
586 olympic_priv->olympic_ring_speed = 100 ;
587 else if (readb(init_srb+18) & 1)
588 olympic_priv->olympic_ring_speed = 16 ;
589 else
590 olympic_priv->olympic_ring_speed = 4 ;
591
592 if (olympic_priv->olympic_message_level)
593 printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed);
594
595 olympic_priv->asb = swab16(readw(init_srb+8));
596 olympic_priv->srb = swab16(readw(init_srb+10));
597 olympic_priv->arb = swab16(readw(init_srb+12));
598 olympic_priv->trb = swab16(readw(init_srb+16));
599
600 olympic_priv->olympic_receive_options = 0x01 ;
601 olympic_priv->olympic_copy_all_options = 0 ;
602
603
604
605 writel((3<<16),olympic_mmio+BMCTL_RWM);
606
607 writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM);
608
609 for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
610
611 struct sk_buff *skb;
612
613 skb=dev_alloc_skb(olympic_priv->pkt_buf_sz);
614 if(skb == NULL)
615 break;
616
617 skb->dev = dev;
618
619 olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev,
620 skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ;
621 olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz);
622 olympic_priv->rx_ring_skb[i]=skb;
623 }
624
625 if (i==0) {
626 printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
627 goto out;
628 }
629
630 olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring,
631 sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
632 writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ);
633 writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA);
634 writew(i, olympic_mmio+RXDESCQCNT);
635
636 olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring,
637 sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
638 writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ);
639 writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA);
640
641 olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1;
642 olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1;
643
644 writew(i, olympic_mmio+RXSTATQCNT);
645
646#if OLYMPIC_DEBUG
647 printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
648 printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
649 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]) );
650 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]) );
651 printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7]) );
652
653 printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
654 printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",
655 olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ;
656#endif
657
658 writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
659
660#if OLYMPIC_DEBUG
661 printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
662 printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
663 printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
664#endif
665
666 writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);
667
668
669
670 writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM);
671 for(i=0;i<OLYMPIC_TX_RING_SIZE;i++)
672 olympic_priv->olympic_tx_ring[i].buffer=cpu_to_le32(0xdeadbeef);
673
674 olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;
675 olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,
676 sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ;
677 writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1);
678 writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1);
679 writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1);
680
681 olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring,
682 sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
683 writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1);
684 writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1);
685 writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1);
686
687 olympic_priv->tx_ring_free=0;
688 olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1;
689
690 writel(0xffffffff, olympic_mmio+EISR_RWM) ;
691 writel(0,olympic_mmio+EISR) ;
692 writel(EISR_MASK_OPTIONS,olympic_mmio+EISR_MASK) ;
693 writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE | SISR_ERR,olympic_mmio+SISR_MASK_SUM);
694
695#if OLYMPIC_DEBUG
696 printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
697 printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));
698#endif
699
700 if (olympic_priv->olympic_network_monitor) {
701 u8 __iomem *oat;
702 u8 __iomem *opt;
703 u8 addr[6];
704 oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
705 opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
706
707 for (i = 0; i < 6; i++)
708 addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i);
709 printk("%s: Node Address: %pM\n", dev->name, addr);
710 printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name,
711 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
712 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
713 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
714 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
715
716 for (i = 0; i < 6; i++)
717 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i);
718 printk("%s: NAUN Address: %pM\n", dev->name, addr);
719 }
720
721 netif_start_queue(dev);
722 return 0;
723
724out:
725 free_irq(dev->irq, dev);
726 return -EIO;
727}
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744static void olympic_rx(struct net_device *dev)
745{
746 struct olympic_private *olympic_priv=netdev_priv(dev);
747 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
748 struct olympic_rx_status *rx_status;
749 struct olympic_rx_desc *rx_desc ;
750 int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len;
751 struct sk_buff *skb, *skb2;
752 int i;
753
754 rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ;
755
756 while (rx_status->status_buffercnt) {
757 u32 l_status_buffercnt;
758
759 olympic_priv->rx_status_last_received++ ;
760 olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1);
761#if OLYMPIC_DEBUG
762 printk("rx status: %x rx len: %x \n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen));
763#endif
764 length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff;
765 buffer_cnt = le32_to_cpu(rx_status->status_buffercnt) & 0xffff;
766 i = buffer_cnt ;
767 frag_len = le32_to_cpu(rx_status->fragmentcnt_framelen) >> 16;
768
769#if OLYMPIC_DEBUG
770 printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt);
771#endif
772 l_status_buffercnt = le32_to_cpu(rx_status->status_buffercnt);
773 if(l_status_buffercnt & 0xC0000000) {
774 if (l_status_buffercnt & 0x3B000000) {
775 if (olympic_priv->olympic_message_level) {
776 if (l_status_buffercnt & (1<<29))
777 printk(KERN_WARNING "%s: Rx Frame Truncated \n",dev->name);
778 if (l_status_buffercnt & (1<<28))
779 printk(KERN_WARNING "%s: Rx Frame Receive overrun \n",dev->name);
780 if (l_status_buffercnt & (1<<27))
781 printk(KERN_WARNING "%s: No receive buffers \n",dev->name);
782 if (l_status_buffercnt & (1<<25))
783 printk(KERN_WARNING "%s: Receive frame error detect \n",dev->name);
784 if (l_status_buffercnt & (1<<24))
785 printk(KERN_WARNING "%s: Received Error Detect \n",dev->name);
786 }
787 olympic_priv->rx_ring_last_received += i ;
788 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
789 dev->stats.rx_errors++;
790 } else {
791
792 if (buffer_cnt == 1) {
793 skb = dev_alloc_skb(max_t(int, olympic_priv->pkt_buf_sz,length)) ;
794 } else {
795 skb = dev_alloc_skb(length) ;
796 }
797
798 if (skb == NULL) {
799 printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",dev->name) ;
800 dev->stats.rx_dropped++;
801
802 olympic_priv->rx_ring_last_received += i ;
803 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
804 } else {
805
806
807
808
809
810
811
812
813 if (buffer_cnt==1) {
814 olympic_priv->rx_ring_last_received++ ;
815 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
816 rx_ring_last_received = olympic_priv->rx_ring_last_received ;
817 if (length > 1500) {
818 skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ;
819
820 pci_unmap_single(olympic_priv->pdev,
821 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
822 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
823 skb_put(skb2,length-4);
824 skb2->protocol = tr_type_trans(skb2,dev);
825 olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer =
826 cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data,
827 olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
828 olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length =
829 cpu_to_le32(olympic_priv->pkt_buf_sz);
830 olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ;
831 netif_rx(skb2) ;
832 } else {
833 pci_dma_sync_single_for_cpu(olympic_priv->pdev,
834 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
835 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
836 skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
837 skb_put(skb,length - 4),
838 length - 4);
839 pci_dma_sync_single_for_device(olympic_priv->pdev,
840 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
841 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
842 skb->protocol = tr_type_trans(skb,dev) ;
843 netif_rx(skb) ;
844 }
845 } else {
846 do {
847 olympic_priv->rx_ring_last_received++ ;
848 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
849 rx_ring_last_received = olympic_priv->rx_ring_last_received ;
850 pci_dma_sync_single_for_cpu(olympic_priv->pdev,
851 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
852 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
853 rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]);
854 cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length));
855 skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
856 skb_put(skb, cpy_length),
857 cpy_length);
858 pci_dma_sync_single_for_device(olympic_priv->pdev,
859 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
860 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
861 } while (--i) ;
862 skb_trim(skb,skb->len-4) ;
863 skb->protocol = tr_type_trans(skb,dev);
864 netif_rx(skb) ;
865 }
866 dev->stats.rx_packets++ ;
867 dev->stats.rx_bytes += length ;
868 }
869 }
870
871 } else {
872 olympic_priv->rx_ring_last_received += i ;
873 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE - 1) ;
874 }
875
876 rx_status->fragmentcnt_framelen = 0 ;
877 rx_status->status_buffercnt = 0 ;
878 rx_status = &(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received+1) & (OLYMPIC_RX_RING_SIZE -1) ]);
879
880 writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | buffer_cnt , olympic_mmio+RXENQ);
881 }
882
883}
884
885static void olympic_freemem(struct net_device *dev)
886{
887 struct olympic_private *olympic_priv=netdev_priv(dev);
888 int i;
889
890 for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
891 if (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] != NULL) {
892 dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
893 olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL;
894 }
895 if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != cpu_to_le32(0xdeadbeef)) {
896 pci_unmap_single(olympic_priv->pdev,
897 le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
898 olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
899 }
900 olympic_priv->rx_status_last_received++;
901 olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
902 }
903
904 pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr,
905 sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
906 pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
907 sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
908
909 pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr,
910 sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
911 pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr,
912 sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
913
914 return ;
915}
916
917static irqreturn_t olympic_interrupt(int irq, void *dev_id)
918{
919 struct net_device *dev= (struct net_device *)dev_id;
920 struct olympic_private *olympic_priv=netdev_priv(dev);
921 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
922 u32 sisr;
923 u8 __iomem *adapter_check_area ;
924
925
926
927
928
929
930 sisr=readl(olympic_mmio+SISR) ;
931 if (!(sisr & SISR_MI))
932 return IRQ_NONE;
933 sisr=readl(olympic_mmio+SISR_RR) ;
934
935 spin_lock(&olympic_priv->olympic_lock);
936
937
938 if (sisr == 0xffffffff) {
939 printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ;
940 spin_unlock(&olympic_priv->olympic_lock) ;
941 return IRQ_NONE;
942 }
943
944 if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK |
945 SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF | SISR_ERR)) {
946
947
948
949 if((sisr & SISR_ERR) && (readl(olympic_mmio+EISR) & EISR_MASK_OPTIONS)) {
950 printk(KERN_ERR "Olympic: EISR Error, EISR=%08x\n",readl(olympic_mmio+EISR)) ;
951 printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ;
952 printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ;
953 printk(KERN_ERR "or the linux-tr mailing list.\n") ;
954 wake_up_interruptible(&olympic_priv->srb_wait);
955 spin_unlock(&olympic_priv->olympic_lock) ;
956 return IRQ_HANDLED;
957 }
958
959 if(sisr & SISR_SRB_REPLY) {
960 if(olympic_priv->srb_queued==1) {
961 wake_up_interruptible(&olympic_priv->srb_wait);
962 } else if (olympic_priv->srb_queued==2) {
963 olympic_srb_bh(dev) ;
964 }
965 olympic_priv->srb_queued=0;
966 }
967
968
969
970 if (sisr & SISR_TX1_EOF) {
971 while(olympic_priv->olympic_tx_status_ring[(olympic_priv->tx_ring_last_status + 1) & (OLYMPIC_TX_RING_SIZE-1)].status) {
972 olympic_priv->tx_ring_last_status++;
973 olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
974 olympic_priv->free_tx_ring_entries++;
975 dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
976 dev->stats.tx_packets++ ;
977 pci_unmap_single(olympic_priv->pdev,
978 le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer),
979 olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
980 dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
981 olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32(0xdeadbeef);
982 olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
983 }
984 netif_wake_queue(dev);
985 }
986
987 if (sisr & SISR_RX_STATUS) {
988 olympic_rx(dev);
989 }
990
991 if (sisr & SISR_ADAPTER_CHECK) {
992 netif_stop_queue(dev);
993 printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
994 writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA);
995 adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ;
996 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)) ;
997 spin_unlock(&olympic_priv->olympic_lock) ;
998 return IRQ_HANDLED;
999 }
1000
1001 if (sisr & SISR_ASB_FREE) {
1002
1003 if (olympic_priv->asb_queued) {
1004 olympic_asb_bh(dev) ;
1005 }
1006 }
1007
1008 if (sisr & SISR_ARB_CMD) {
1009 olympic_arb_cmd(dev) ;
1010 }
1011
1012 if (sisr & SISR_TRB_REPLY) {
1013
1014 if (olympic_priv->trb_queued) {
1015 wake_up_interruptible(&olympic_priv->trb_wait);
1016 }
1017 olympic_priv->trb_queued = 0 ;
1018 }
1019
1020 if (sisr & SISR_RX_NOBUF) {
1021
1022
1023 }
1024 } else {
1025 printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",dev->name, sisr);
1026 printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ;
1027 }
1028 writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
1029
1030 spin_unlock(&olympic_priv->olympic_lock) ;
1031 return IRQ_HANDLED;
1032}
1033
1034static netdev_tx_t olympic_xmit(struct sk_buff *skb,
1035 struct net_device *dev)
1036{
1037 struct olympic_private *olympic_priv=netdev_priv(dev);
1038 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
1039 unsigned long flags ;
1040
1041 spin_lock_irqsave(&olympic_priv->olympic_lock, flags);
1042
1043 netif_stop_queue(dev);
1044
1045 if(olympic_priv->free_tx_ring_entries) {
1046 olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer =
1047 cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE));
1048 olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000));
1049 olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb;
1050 olympic_priv->free_tx_ring_entries--;
1051
1052 olympic_priv->tx_ring_free++;
1053 olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1);
1054 writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
1055 netif_wake_queue(dev);
1056 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
1057 return NETDEV_TX_OK;
1058 } else {
1059 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
1060 return NETDEV_TX_BUSY;
1061 }
1062
1063}
1064
1065
1066static int olympic_close(struct net_device *dev)
1067{
1068 struct olympic_private *olympic_priv=netdev_priv(dev);
1069 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*srb;
1070 unsigned long t,flags;
1071
1072 DECLARE_WAITQUEUE(wait,current) ;
1073
1074 netif_stop_queue(dev);
1075
1076 writel(olympic_priv->srb,olympic_mmio+LAPA);
1077 srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
1078
1079 writeb(SRB_CLOSE_ADAPTER,srb+0);
1080 writeb(0,srb+1);
1081 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1082
1083 add_wait_queue(&olympic_priv->srb_wait,&wait) ;
1084 set_current_state(TASK_INTERRUPTIBLE) ;
1085
1086 spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
1087 olympic_priv->srb_queued=1;
1088
1089 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1090 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
1091
1092 while(olympic_priv->srb_queued) {
1093
1094 t = schedule_timeout_interruptible(60*HZ);
1095
1096 if(signal_pending(current)) {
1097 printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
1098 printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
1099 olympic_priv->srb_queued=0;
1100 break;
1101 }
1102
1103 if (t == 0) {
1104 printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ;
1105 }
1106 olympic_priv->srb_queued=0;
1107 }
1108 remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
1109
1110 olympic_priv->rx_status_last_received++;
1111 olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
1112
1113 olympic_freemem(dev) ;
1114
1115
1116
1117 writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
1118 udelay(1);
1119 writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
1120
1121#if OLYMPIC_DEBUG
1122 {
1123 int i ;
1124 printk("srb(%p): ",srb);
1125 for(i=0;i<4;i++)
1126 printk("%x ",readb(srb+i));
1127 printk("\n");
1128 }
1129#endif
1130 free_irq(dev->irq,dev);
1131
1132 return 0;
1133
1134}
1135
1136static void olympic_set_rx_mode(struct net_device *dev)
1137{
1138 struct olympic_private *olympic_priv = netdev_priv(dev);
1139 u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ;
1140 u8 options = 0;
1141 u8 __iomem *srb;
1142 struct dev_mc_list *dmi ;
1143 unsigned char dev_mc_address[4] ;
1144 int i ;
1145
1146 writel(olympic_priv->srb,olympic_mmio+LAPA);
1147 srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
1148 options = olympic_priv->olympic_copy_all_options;
1149
1150 if (dev->flags&IFF_PROMISC)
1151 options |= 0x61 ;
1152 else
1153 options &= ~0x61 ;
1154
1155
1156
1157 if ((options ^ olympic_priv->olympic_copy_all_options)) {
1158
1159
1160
1161 writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb);
1162 writeb(0,srb+1);
1163 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1164 writeb(0,srb+3);
1165 writeb(olympic_priv->olympic_receive_options,srb+4);
1166 writeb(options,srb+5);
1167
1168 olympic_priv->srb_queued=2;
1169
1170 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1171
1172 olympic_priv->olympic_copy_all_options = options ;
1173
1174 return ;
1175 }
1176
1177
1178
1179 dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
1180
1181 for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) {
1182 dev_mc_address[0] |= dmi->dmi_addr[2] ;
1183 dev_mc_address[1] |= dmi->dmi_addr[3] ;
1184 dev_mc_address[2] |= dmi->dmi_addr[4] ;
1185 dev_mc_address[3] |= dmi->dmi_addr[5] ;
1186 }
1187
1188 writeb(SRB_SET_FUNC_ADDRESS,srb+0);
1189 writeb(0,srb+1);
1190 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1191 writeb(0,srb+3);
1192 writeb(0,srb+4);
1193 writeb(0,srb+5);
1194 writeb(dev_mc_address[0],srb+6);
1195 writeb(dev_mc_address[1],srb+7);
1196 writeb(dev_mc_address[2],srb+8);
1197 writeb(dev_mc_address[3],srb+9);
1198
1199 olympic_priv->srb_queued = 2 ;
1200 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1201
1202}
1203
1204static void olympic_srb_bh(struct net_device *dev)
1205{
1206 struct olympic_private *olympic_priv = netdev_priv(dev);
1207 u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ;
1208 u8 __iomem *srb;
1209
1210 writel(olympic_priv->srb,olympic_mmio+LAPA);
1211 srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
1212
1213 switch (readb(srb)) {
1214
1215
1216
1217
1218
1219
1220 case SRB_MODIFY_RECEIVE_OPTIONS:
1221 switch (readb(srb+2)) {
1222 case 0x01:
1223 printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ;
1224 break ;
1225 case 0x04:
1226 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
1227 break ;
1228 default:
1229 if (olympic_priv->olympic_message_level)
1230 printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ;
1231 break ;
1232 }
1233 break ;
1234
1235
1236
1237
1238 case SRB_SET_GROUP_ADDRESS:
1239 switch (readb(srb+2)) {
1240 case 0x00:
1241 break ;
1242 case 0x01:
1243 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1244 break ;
1245 case 0x04:
1246 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
1247 break ;
1248 case 0x3c:
1249 printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ;
1250 break ;
1251 case 0x3e:
1252 printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ;
1253 break ;
1254 case 0x55:
1255 printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ;
1256 break ;
1257 default:
1258 break ;
1259 }
1260 break ;
1261
1262
1263
1264
1265 case SRB_RESET_GROUP_ADDRESS:
1266 switch (readb(srb+2)) {
1267 case 0x00:
1268 break ;
1269 case 0x01:
1270 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1271 break ;
1272 case 0x04:
1273 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1274 break ;
1275 case 0x39:
1276 printk(KERN_INFO "%s: Group address not found \n",dev->name);
1277 break ;
1278 default:
1279 break ;
1280 }
1281 break ;
1282
1283
1284
1285
1286
1287 case SRB_SET_FUNC_ADDRESS:
1288 switch (readb(srb+2)) {
1289 case 0x00:
1290 if (olympic_priv->olympic_message_level)
1291 printk(KERN_INFO "%s: Functional Address Mask Set \n",dev->name) ;
1292 break ;
1293 case 0x01:
1294 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1295 break ;
1296 case 0x04:
1297 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1298 break ;
1299 default:
1300 break ;
1301 }
1302 break ;
1303
1304
1305
1306
1307 case SRB_READ_LOG:
1308 switch (readb(srb+2)) {
1309 case 0x00:
1310 if (olympic_priv->olympic_message_level)
1311 printk(KERN_INFO "%s: Read Log issued\n",dev->name) ;
1312 break ;
1313 case 0x01:
1314 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1315 break ;
1316 case 0x04:
1317 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1318 break ;
1319
1320 }
1321 break ;
1322
1323
1324
1325 case SRB_READ_SR_COUNTERS:
1326 switch (readb(srb+2)) {
1327 case 0x00:
1328 if (olympic_priv->olympic_message_level)
1329 printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ;
1330 break ;
1331 case 0x01:
1332 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1333 break ;
1334 case 0x04:
1335 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1336 break ;
1337 default:
1338 break ;
1339 }
1340 break ;
1341
1342 default:
1343 printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name);
1344 break ;
1345 }
1346
1347}
1348
1349static int olympic_set_mac_address (struct net_device *dev, void *addr)
1350{
1351 struct sockaddr *saddr = addr ;
1352 struct olympic_private *olympic_priv = netdev_priv(dev);
1353
1354 if (netif_running(dev)) {
1355 printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ;
1356 return -EIO ;
1357 }
1358
1359 memcpy(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ;
1360
1361 if (olympic_priv->olympic_message_level) {
1362 printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0],
1363 olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2],
1364 olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4],
1365 olympic_priv->olympic_laa[5]);
1366 }
1367
1368 return 0 ;
1369}
1370
1371static void olympic_arb_cmd(struct net_device *dev)
1372{
1373 struct olympic_private *olympic_priv = netdev_priv(dev);
1374 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
1375 u8 __iomem *arb_block, *asb_block, *srb ;
1376 u8 header_len ;
1377 u16 frame_len, buffer_len ;
1378 struct sk_buff *mac_frame ;
1379 u8 __iomem *buf_ptr ;
1380 u8 __iomem *frame_data ;
1381 u16 buff_off ;
1382 u16 lan_status = 0, lan_status_diff ;
1383 u8 fdx_prot_error ;
1384 u16 next_ptr;
1385
1386 arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ;
1387 asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ;
1388 srb = (olympic_priv->olympic_lap + olympic_priv->srb) ;
1389
1390 if (readb(arb_block+0) == ARB_RECEIVE_DATA) {
1391
1392 header_len = readb(arb_block+8) ;
1393 frame_len = swab16(readw(arb_block + 10)) ;
1394
1395 buff_off = swab16(readw(arb_block + 6)) ;
1396
1397 buf_ptr = olympic_priv->olympic_lap + buff_off ;
1398
1399#if OLYMPIC_DEBUG
1400{
1401 int i;
1402 frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ;
1403
1404 for (i=0 ; i < 14 ; i++) {
1405 printk("Loc %d = %02x\n",i,readb(frame_data + i));
1406 }
1407
1408 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)));
1409}
1410#endif
1411 mac_frame = dev_alloc_skb(frame_len) ;
1412 if (!mac_frame) {
1413 printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name);
1414 goto drop_frame;
1415 }
1416
1417
1418
1419 do {
1420 frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ;
1421 buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length)));
1422 memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ;
1423 next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next));
1424 } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + swab16(next_ptr)));
1425
1426 mac_frame->protocol = tr_type_trans(mac_frame, dev);
1427
1428 if (olympic_priv->olympic_network_monitor) {
1429 struct trh_hdr *mac_hdr;
1430 printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name);
1431 mac_hdr = tr_hdr(mac_frame);
1432 printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %pM\n",
1433 dev->name, mac_hdr->daddr);
1434 printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %pM\n",
1435 dev->name, mac_hdr->saddr);
1436 }
1437 netif_rx(mac_frame);
1438
1439drop_frame:
1440
1441
1442
1443 writel(LISR_ARB_FREE,olympic_priv->olympic_mmio + LISR_SUM);
1444
1445
1446
1447 if (readb(asb_block + 2) != 0xff) {
1448 olympic_priv->asb_queued = 1 ;
1449 writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
1450 return ;
1451
1452 }
1453
1454 writeb(ASB_RECEIVE_DATA,asb_block);
1455 writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2);
1456 writeb(readb(arb_block+6),asb_block+6);
1457 writeb(readb(arb_block+7),asb_block+7);
1458
1459 writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
1460
1461 olympic_priv->asb_queued = 2 ;
1462
1463 return ;
1464
1465 } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) {
1466 lan_status = swab16(readw(arb_block+6));
1467 fdx_prot_error = readb(arb_block+8) ;
1468
1469
1470 writel(LISR_ARB_FREE,olympic_priv->olympic_mmio+LISR_SUM);
1471
1472 lan_status_diff = olympic_priv->olympic_lan_status ^ lan_status ;
1473
1474 if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) {
1475 if (lan_status_diff & LSC_LWF)
1476 printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);
1477 if (lan_status_diff & LSC_ARW)
1478 printk(KERN_WARNING "%s: Auto removal error\n",dev->name);
1479 if (lan_status_diff & LSC_FPE)
1480 printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);
1481 if (lan_status_diff & LSC_RR)
1482 printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);
1483
1484
1485
1486
1487
1488 writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
1489 udelay(1);
1490 writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
1491 netif_stop_queue(dev);
1492 olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ;
1493 printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ;
1494 }
1495
1496 if (olympic_priv->olympic_message_level) {
1497 if (lan_status_diff & LSC_SIG_LOSS)
1498 printk(KERN_WARNING "%s: No receive signal detected \n", dev->name) ;
1499 if (lan_status_diff & LSC_HARD_ERR)
1500 printk(KERN_INFO "%s: Beaconing \n",dev->name);
1501 if (lan_status_diff & LSC_SOFT_ERR)
1502 printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n",dev->name);
1503 if (lan_status_diff & LSC_TRAN_BCN)
1504 printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name);
1505 if (lan_status_diff & LSC_SS)
1506 printk(KERN_INFO "%s: Single Station on the ring \n", dev->name);
1507 if (lan_status_diff & LSC_RING_REC)
1508 printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);
1509 if (lan_status_diff & LSC_FDX_MODE)
1510 printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);
1511 }
1512
1513 if (lan_status_diff & LSC_CO) {
1514
1515 if (olympic_priv->olympic_message_level)
1516 printk(KERN_INFO "%s: Counter Overflow \n", dev->name);
1517
1518
1519
1520 writeb(SRB_READ_LOG, srb);
1521 writeb(0,srb+1);
1522 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1523 writeb(0,srb+3);
1524 writeb(0,srb+4);
1525 writeb(0,srb+5);
1526
1527 olympic_priv->srb_queued=2;
1528
1529 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1530
1531 }
1532
1533 if (lan_status_diff & LSC_SR_CO) {
1534
1535 if (olympic_priv->olympic_message_level)
1536 printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
1537
1538
1539
1540 writeb(SRB_READ_SR_COUNTERS,srb);
1541 writeb(0,srb+1);
1542 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1543 writeb(0,srb+3);
1544
1545 olympic_priv->srb_queued=2;
1546
1547 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1548
1549 }
1550
1551 olympic_priv->olympic_lan_status = lan_status ;
1552
1553 }
1554 else
1555 printk(KERN_WARNING "%s: Unknown arb command \n", dev->name);
1556}
1557
1558static void olympic_asb_bh(struct net_device *dev)
1559{
1560 struct olympic_private *olympic_priv = netdev_priv(dev);
1561 u8 __iomem *arb_block, *asb_block ;
1562
1563 arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ;
1564 asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ;
1565
1566 if (olympic_priv->asb_queued == 1) {
1567
1568 writeb(ASB_RECEIVE_DATA,asb_block);
1569 writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2);
1570 writeb(readb(arb_block+6),asb_block+6);
1571 writeb(readb(arb_block+7),asb_block+7);
1572
1573 writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
1574 olympic_priv->asb_queued = 2 ;
1575
1576 return ;
1577 }
1578
1579 if (olympic_priv->asb_queued == 2) {
1580 switch (readb(asb_block+2)) {
1581 case 0x01:
1582 printk(KERN_WARNING "%s: Unrecognized command code \n", dev->name);
1583 break ;
1584 case 0x26:
1585 printk(KERN_WARNING "%s: Unrecognized buffer address \n", dev->name);
1586 break ;
1587 case 0xFF:
1588
1589 break ;
1590 default:
1591 printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name);
1592 break ;
1593 }
1594 }
1595 olympic_priv->asb_queued = 0 ;
1596}
1597
1598static int olympic_change_mtu(struct net_device *dev, int mtu)
1599{
1600 struct olympic_private *olympic_priv = netdev_priv(dev);
1601 u16 max_mtu ;
1602
1603 if (olympic_priv->olympic_ring_speed == 4)
1604 max_mtu = 4500 ;
1605 else
1606 max_mtu = 18000 ;
1607
1608 if (mtu > max_mtu)
1609 return -EINVAL ;
1610 if (mtu < 100)
1611 return -EINVAL ;
1612
1613 dev->mtu = mtu ;
1614 olympic_priv->pkt_buf_sz = mtu + TR_HLEN ;
1615
1616 return 0 ;
1617}
1618
1619static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
1620{
1621 struct net_device *dev = (struct net_device *)data ;
1622 struct olympic_private *olympic_priv=netdev_priv(dev);
1623 u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ;
1624 u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ;
1625 int size = 0 ;
1626 int len=0;
1627 off_t begin=0;
1628 off_t pos=0;
1629 u8 addr[6];
1630 u8 addr2[6];
1631 int i;
1632
1633 size = sprintf(buffer,
1634 "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
1635 size += sprintf(buffer+size, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
1636 dev->name);
1637
1638 for (i = 0 ; i < 6 ; i++)
1639 addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i);
1640
1641 size += sprintf(buffer+size, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
1642 dev->name,
1643 dev->dev_addr, addr,
1644 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
1645 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
1646 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
1647 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
1648
1649 size += sprintf(buffer+size, "\n%6s: Token Ring Parameters Table:\n", dev->name);
1650
1651 size += sprintf(buffer+size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n",
1652 dev->name) ;
1653
1654 for (i = 0 ; i < 6 ; i++)
1655 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr) + i);
1656 for (i = 0 ; i < 6 ; i++)
1657 addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i);
1658
1659 size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n",
1660 dev->name,
1661 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)),
1662 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1),
1663 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2),
1664 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3),
1665 addr, addr2,
1666 swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))),
1667 swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))),
1668 swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code))));
1669
1670 size += sprintf(buffer+size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
1671 dev->name) ;
1672
1673 for (i = 0 ; i < 6 ; i++)
1674 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i);
1675 size += sprintf(buffer+size, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n",
1676 dev->name, addr,
1677 swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))),
1678 swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))),
1679 swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))),
1680 swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))),
1681 swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))),
1682 swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl))));
1683
1684 size += sprintf(buffer+size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
1685 dev->name) ;
1686
1687 for (i = 0 ; i < 6 ; i++)
1688 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i);
1689 size += sprintf(buffer+size, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n",
1690 dev->name,
1691 swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))),
1692 swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))),
1693 addr,
1694 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)),
1695 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1),
1696 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
1697 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3));
1698
1699 len=size;
1700 pos=begin+size;
1701 if (pos<offset) {
1702 len=0;
1703 begin=pos;
1704 }
1705 *start=buffer+(offset-begin);
1706 len-=(offset-begin);
1707 if(len>length)
1708 len=length;
1709 return len;
1710}
1711
1712static void __devexit olympic_remove_one(struct pci_dev *pdev)
1713{
1714 struct net_device *dev = pci_get_drvdata(pdev) ;
1715 struct olympic_private *olympic_priv=netdev_priv(dev);
1716
1717 if (olympic_priv->olympic_network_monitor) {
1718 char proc_name[20] ;
1719 strcpy(proc_name,"olympic_") ;
1720 strcat(proc_name,dev->name) ;
1721 remove_proc_entry(proc_name,init_net.proc_net);
1722 }
1723 unregister_netdev(dev) ;
1724 iounmap(olympic_priv->olympic_mmio) ;
1725 iounmap(olympic_priv->olympic_lap) ;
1726 pci_release_regions(pdev) ;
1727 pci_set_drvdata(pdev,NULL) ;
1728 free_netdev(dev) ;
1729}
1730
1731static struct pci_driver olympic_driver = {
1732 .name = "olympic",
1733 .id_table = olympic_pci_tbl,
1734 .probe = olympic_probe,
1735 .remove = __devexit_p(olympic_remove_one),
1736};
1737
1738static int __init olympic_pci_init(void)
1739{
1740 return pci_register_driver(&olympic_driver) ;
1741}
1742
1743static void __exit olympic_pci_cleanup(void)
1744{
1745 pci_unregister_driver(&olympic_driver) ;
1746}
1747
1748
1749module_init(olympic_pci_init) ;
1750module_exit(olympic_pci_cleanup) ;
1751
1752MODULE_LICENSE("GPL");
1753