blob: 71fed1e202238a36c320647d4d55c3ee158a116c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * olympic.c (c) 1999 Peter De Schrijver All Rights Reserved
3 * 1999/2000 Mike Phillips (mikep@linuxtr.net)
4 *
5 * Linux driver for IBM PCI tokenring cards based on the Pit/Pit-Phy/Olympic
6 * chipset.
7 *
8 * Base Driver Skeleton:
9 * Written 1993-94 by Donald Becker.
10 *
11 * Copyright 1993 United States Government as represented by the
12 * Director, National Security Agency.
13 *
14 * Thanks to Erik De Cock, Adrian Bridgett and Frank Fiene for their
15 * assistance and perserverance with the testing of this driver.
16 *
17 * This software may be used and distributed according to the terms
18 * of the GNU General Public License, incorporated herein by reference.
19 *
20 * 4/27/99 - Alpha Release 0.1.0
21 * First release to the public
22 *
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
41 *
42 * 12/23/00 - Added minimal Cardbus support (Thanks Donald).
43 *
44 * 03/09/01 - Add new pci api, dev_base_lock, general clean up.
45 *
46 * 03/27/01 - Add new dma pci (Thanks to Kyle Lucke) and alloc_trdev
47 * Change proc_fs behaviour, now one entry per adapter.
48 *
49 * 04/09/01 - Couple of bug fixes to the dma unmaps and ejecting the
50 * adapter when live does not take the system down with it.
51 *
52 * 06/02/01 - Clean up, copy skb for small packets
53 *
54 * 06/22/01 - Add EISR error handling routines
55 *
56 * 07/19/01 - Improve bad LAA reporting, strip out freemem
57 * into a separate function, its called from 3
58 * different places now.
59 * 02/09/02 - Replaced sleep_on.
60 * 03/01/02 - Replace access to several registers from 32 bit to
61 * 16 bit. Fixes alignment errors on PPC 64 bit machines.
62 * Thanks to Al Trautman for this one.
63 * 03/10/02 - Fix BUG in arb_cmd. Bug was there all along but was
64 * silently ignored until the error checking code
65 * went into version 1.0.0
66 * 06/04/02 - Add correct start up sequence for the cardbus adapters.
67 * Required for strict compliance with pci power mgmt specs.
68 * To Do:
69 *
70 * Wake on lan
71 *
72 * If Problems do Occur
73 * Most problems can be rectified by either closing and opening the interface
74 * (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult
75 * if compiled into the kernel).
76 */
77
78/* Change OLYMPIC_DEBUG to 1 to get verbose, and I mean really verbose, messages */
79
80#define OLYMPIC_DEBUG 0
81
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083#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>
Marcelo Feitoza Parisiff5688a2006-01-09 18:37:15 -0800102#include <linux/jiffies.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104#include <net/checksum.h>
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200105#include <net/net_namespace.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106
107#include <asm/io.h>
108#include <asm/system.h>
109
110#include "olympic.h"
111
112/* I've got to put some intelligence into the version number so that Peter and I know
113 * which version of the code somebody has got.
114 * Version Number = a.b.c.d where a.b.c is the level of code and d is the latest author.
115 * So 0.0.1.pds = Peter, 0.0.1.mlp = Mike
116 *
117 * Official releases will only have an a.b.c version number format.
118 */
119
Adrian Bunke28e3a62008-03-31 01:40:04 +0300120static char version[] =
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121"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/* Module paramters */
136
137MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
138MODULE_DESCRIPTION("Olympic PCI/Cardbus Chipset Driver") ;
139
140/* Ring Speed 0,4,16,100
141 * 0 = Autosense
142 * 4,16 = Selected speed only, no autosense
143 * This allows the card to be the first on the ring
144 * and become the active monitor.
145 * 100 = Nothing at present, 100mbps is autodetected
146 * if FDX is turned on. May be implemented in the future to
147 * fail if 100mpbs is not detected.
148 *
149 * WARNING: Some hubs will allow you to insert
150 * at the wrong speed
151 */
152
153static int ringspeed[OLYMPIC_MAX_ADAPTERS] = {0,} ;
154module_param_array(ringspeed, int, NULL, 0);
155
156/* Packet buffer size */
157
158static int pkt_buf_sz[OLYMPIC_MAX_ADAPTERS] = {0,} ;
159module_param_array(pkt_buf_sz, int, NULL, 0) ;
160
161/* Message Level */
162
163static int message_level[OLYMPIC_MAX_ADAPTERS] = {0,} ;
164module_param_array(message_level, int, NULL, 0) ;
165
166/* Change network_monitor to receive mac frames through the arb channel.
167 * Will also create a /proc/net/olympic_tr%d entry, where %d is the tr
168 * device, i.e. tr0, tr1 etc.
169 * Intended to be used to create a ring-error reporting network module
170 * i.e. it will give you the source address of beaconers on the ring
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 { } /* Terminating Entry */
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 int olympic_xmit(struct sk_buff *skb, struct net_device *dev);
186static int olympic_close(struct net_device *dev);
187static void olympic_set_rx_mode(struct net_device *dev);
188static void olympic_freemem(struct net_device *dev) ;
David Howells7d12e782006-10-05 14:55:46 +0100189static irqreturn_t olympic_interrupt(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190static int olympic_set_mac_address(struct net_device *dev, void *addr) ;
191static void olympic_arb_cmd(struct net_device *dev);
192static int olympic_change_mtu(struct net_device *dev, int mtu);
193static void olympic_srb_bh(struct net_device *dev) ;
194static void olympic_asb_bh(struct net_device *dev) ;
195static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ;
196
197static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
198{
199 struct net_device *dev ;
200 struct olympic_private *olympic_priv;
201 static int card_no = -1 ;
202 int i ;
203
204 card_no++ ;
205
206 if ((i = pci_enable_device(pdev))) {
207 return i ;
208 }
209
210 pci_set_master(pdev);
211
212 if ((i = pci_request_regions(pdev,"olympic"))) {
213 goto op_disable_dev;
214 }
215
216 dev = alloc_trdev(sizeof(struct olympic_private)) ;
217 if (!dev) {
218 i = -ENOMEM;
Eric Sesterhenn6d56ab92006-06-21 16:17:17 +0200219 goto op_release_dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 }
221
Yoann Padioleaueda10532007-07-23 15:18:21 +0200222 olympic_priv = netdev_priv(dev) ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223
224 spin_lock_init(&olympic_priv->olympic_lock) ;
225
226 init_waitqueue_head(&olympic_priv->srb_wait);
227 init_waitqueue_head(&olympic_priv->trb_wait);
228#if OLYMPIC_DEBUG
Yoann Padioleaueda10532007-07-23 15:18:21 +0200229 printk(KERN_INFO "pci_device: %p, dev:%p, dev->priv: %p\n", pdev, dev, netdev_priv(dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230#endif
231 dev->irq=pdev->irq;
232 dev->base_addr=pci_resource_start(pdev, 0);
233 olympic_priv->olympic_card_name = pci_name(pdev);
234 olympic_priv->pdev = pdev;
235 olympic_priv->olympic_mmio = ioremap(pci_resource_start(pdev,1),256);
236 olympic_priv->olympic_lap = ioremap(pci_resource_start(pdev,2),2048);
237 if (!olympic_priv->olympic_mmio || !olympic_priv->olympic_lap) {
238 goto op_free_iomap;
239 }
240
241 if ((pkt_buf_sz[card_no] < 100) || (pkt_buf_sz[card_no] > 18000) )
242 olympic_priv->pkt_buf_sz = PKT_BUF_SZ ;
243 else
244 olympic_priv->pkt_buf_sz = pkt_buf_sz[card_no] ;
245
246 dev->mtu = olympic_priv->pkt_buf_sz - TR_HLEN ;
247 olympic_priv->olympic_ring_speed = ringspeed[card_no] ;
248 olympic_priv->olympic_message_level = message_level[card_no] ;
249 olympic_priv->olympic_network_monitor = network_monitor[card_no];
250
251 if ((i = olympic_init(dev))) {
252 goto op_free_iomap;
253 }
254
255 dev->open=&olympic_open;
256 dev->hard_start_xmit=&olympic_xmit;
257 dev->change_mtu=&olympic_change_mtu;
258 dev->stop=&olympic_close;
259 dev->do_ioctl=NULL;
260 dev->set_multicast_list=&olympic_set_rx_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 dev->set_mac_address=&olympic_set_mac_address ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 SET_NETDEV_DEV(dev, &pdev->dev);
263
264 pci_set_drvdata(pdev,dev) ;
265 register_netdev(dev) ;
266 printk("Olympic: %s registered as: %s\n",olympic_priv->olympic_card_name,dev->name);
267 if (olympic_priv->olympic_network_monitor) { /* Must go after register_netdev as we need the device name */
268 char proc_name[20] ;
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200269 strcpy(proc_name,"olympic_") ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700270 strcat(proc_name,dev->name) ;
Eric W. Biederman457c4cb2007-09-12 12:01:34 +0200271 create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272 printk("Olympic: Network Monitor information: /proc/%s\n",proc_name);
273 }
274 return 0 ;
275
276op_free_iomap:
277 if (olympic_priv->olympic_mmio)
278 iounmap(olympic_priv->olympic_mmio);
279 if (olympic_priv->olympic_lap)
280 iounmap(olympic_priv->olympic_lap);
281
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 free_netdev(dev);
Eric Sesterhenn6d56ab92006-06-21 16:17:17 +0200283op_release_dev:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284 pci_release_regions(pdev);
285
286op_disable_dev:
287 pci_disable_device(pdev);
288 return i;
289}
290
Adrian Bunke28e3a62008-03-31 01:40:04 +0300291static int olympic_init(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292{
293 struct olympic_private *olympic_priv;
294 u8 __iomem *olympic_mmio, *init_srb,*adapter_addr;
295 unsigned long t;
296 unsigned int uaa_addr;
297
Yoann Padioleaueda10532007-07-23 15:18:21 +0200298 olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 olympic_mmio=olympic_priv->olympic_mmio;
300
301 printk("%s \n", version);
302 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);
303
304 writel(readl(olympic_mmio+BCTL) | BCTL_SOFTRESET,olympic_mmio+BCTL);
305 t=jiffies;
306 while((readl(olympic_mmio+BCTL)) & BCTL_SOFTRESET) {
307 schedule();
Marcelo Feitoza Parisiff5688a2006-01-09 18:37:15 -0800308 if(time_after(jiffies, t + 40*HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700309 printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
310 return -ENODEV;
311 }
312 }
313
314
315 /* Needed for cardbus */
316 if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
317 writel(readl(olympic_priv->olympic_mmio+FERMASK)|FERMASK_INT_BIT, olympic_mmio+FERMASK);
318 }
319
320#if OLYMPIC_DEBUG
321 printk("BCTL: %x\n",readl(olympic_mmio+BCTL));
322 printk("GPR: %x\n",readw(olympic_mmio+GPR));
323 printk("SISRMASK: %x\n",readl(olympic_mmio+SISR_MASK));
324#endif
325 /* Aaaahhh, You have got to be real careful setting GPR, the card
326 holds the previous values from flash memory, including autosense
327 and ring speed */
328
329 writel(readl(olympic_mmio+BCTL)|BCTL_MIMREB,olympic_mmio+BCTL);
330
331 if (olympic_priv->olympic_ring_speed == 0) { /* Autosense */
332 writew(readw(olympic_mmio+GPR)|GPR_AUTOSENSE,olympic_mmio+GPR);
333 if (olympic_priv->olympic_message_level)
334 printk(KERN_INFO "%s: Ringspeed autosense mode on\n",olympic_priv->olympic_card_name);
335 } else if (olympic_priv->olympic_ring_speed == 16) {
336 if (olympic_priv->olympic_message_level)
337 printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", olympic_priv->olympic_card_name);
338 writew(GPR_16MBPS, olympic_mmio+GPR);
339 } else if (olympic_priv->olympic_ring_speed == 4) {
340 if (olympic_priv->olympic_message_level)
341 printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", olympic_priv->olympic_card_name) ;
342 writew(0, olympic_mmio+GPR);
343 }
344
345 writew(readw(olympic_mmio+GPR)|GPR_NEPTUNE_BF,olympic_mmio+GPR);
346
347#if OLYMPIC_DEBUG
348 printk("GPR = %x\n",readw(olympic_mmio + GPR) ) ;
349#endif
350 /* Solo has been paused to meet the Cardbus power
351 * specs if the adapter is cardbus. Check to
352 * see its been paused and then restart solo. The
353 * adapter should set the pause bit within 1 second.
354 */
355
356 if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
357 t=jiffies;
Al Virob710b432007-12-16 20:53:36 +0000358 while (!(readl(olympic_mmio+CLKCTL) & CLKCTL_PAUSE)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 schedule() ;
Marcelo Feitoza Parisiff5688a2006-01-09 18:37:15 -0800360 if(time_after(jiffies, t + 2*HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 printk(KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n") ;
362 return -ENODEV;
363 }
364 }
365 writel(readl(olympic_mmio+CLKCTL) & ~CLKCTL_PAUSE, olympic_mmio+CLKCTL) ;
366 }
367
368 /* start solo init */
369 writel((1<<15),olympic_mmio+SISR_MASK_SUM);
370
371 t=jiffies;
372 while(!((readl(olympic_mmio+SISR_RR)) & SISR_SRB_REPLY)) {
373 schedule();
Marcelo Feitoza Parisiff5688a2006-01-09 18:37:15 -0800374 if(time_after(jiffies, t + 15*HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 printk(KERN_ERR "IBM PCI tokenring card not responding.\n");
376 return -ENODEV;
377 }
378 }
379
380 writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
381
382#if OLYMPIC_DEBUG
383 printk("LAPWWO: %x, LAPA: %x\n",readl(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
384#endif
385
386 init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
387
388#if OLYMPIC_DEBUG
389{
390 int i;
391 printk("init_srb(%p): ",init_srb);
392 for(i=0;i<20;i++)
393 printk("%x ",readb(init_srb+i));
394 printk("\n");
395}
396#endif
397 if(readw(init_srb+6)) {
398 printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n",readw(init_srb+6));
399 return -ENODEV;
400 }
401
402 if (olympic_priv->olympic_message_level) {
403 if ( readb(init_srb +2) & 0x40) {
404 printk(KERN_INFO "Olympic: Adapter is FDX capable.\n") ;
405 } else {
406 printk(KERN_INFO "Olympic: Adapter cannot do FDX.\n");
407 }
408 }
409
410 uaa_addr=swab16(readw(init_srb+8));
411
412#if OLYMPIC_DEBUG
413 printk("UAA resides at %x\n",uaa_addr);
414#endif
415
416 writel(uaa_addr,olympic_mmio+LAPA);
417 adapter_addr=olympic_priv->olympic_lap + (uaa_addr & (~0xf800));
418
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 memcpy_fromio(&dev->dev_addr[0], adapter_addr,6);
420
Joe Perches0795af52007-10-03 17:59:30 -0700421#if OLYMPIC_DEBUG
Johannes Berge1749612008-10-27 15:59:26 -0700422 printk("adapter address: %pM\n", dev->dev_addr);
Joe Perches0795af52007-10-03 17:59:30 -0700423#endif
424
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 olympic_priv->olympic_addr_table_addr = swab16(readw(init_srb + 12));
426 olympic_priv->olympic_parms_addr = swab16(readw(init_srb + 14));
427
428 return 0;
429
430}
431
Adrian Bunke28e3a62008-03-31 01:40:04 +0300432static int olympic_open(struct net_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433{
Yoann Padioleaueda10532007-07-23 15:18:21 +0200434 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*init_srb;
436 unsigned long flags, t;
437 int i, open_finished = 1 ;
438 u8 resp, err;
439
440 DECLARE_WAITQUEUE(wait,current) ;
441
442 olympic_init(dev);
443
Thomas Gleixner1fb9df52006-07-01 19:29:39 -0700444 if(request_irq(dev->irq, &olympic_interrupt, IRQF_SHARED , "olympic", dev)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 return -EAGAIN;
446 }
447
448#if OLYMPIC_DEBUG
449 printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
450 printk("pending ints: %x\n",readl(olympic_mmio+SISR_RR));
451#endif
452
453 writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
454
455 writel(SISR_MI | SISR_SRB_REPLY, olympic_mmio+SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */
456
457 writel(LISR_LIE,olympic_mmio+LISR); /* more ints later */
458
459 /* adapter is closed, so SRB is pointed to by LAPWWO */
460
461 writel(readw(olympic_mmio+LAPWWO),olympic_mmio+LAPA);
462 init_srb=olympic_priv->olympic_lap + ((readw(olympic_mmio+LAPWWO)) & (~0xf800));
463
464#if OLYMPIC_DEBUG
465 printk("LAPWWO: %x, LAPA: %x\n",readw(olympic_mmio+LAPWWO), readl(olympic_mmio+LAPA));
466 printk("SISR Mask = %04x\n", readl(olympic_mmio+SISR_MASK));
467 printk("Before the open command \n");
468#endif
469 do {
470 memset_io(init_srb,0,SRB_COMMAND_SIZE);
471
472 writeb(SRB_OPEN_ADAPTER,init_srb) ; /* open */
473 writeb(OLYMPIC_CLEAR_RET_CODE,init_srb+2);
474
475 /* If Network Monitor, instruct card to copy MAC frames through the ARB */
476 if (olympic_priv->olympic_network_monitor)
477 writew(swab16(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), init_srb+8);
478 else
479 writew(swab16(OPEN_ADAPTER_ENABLE_FDX), init_srb+8);
480
481 /* Test OR of first 3 bytes as its totally possible for
482 * someone to set the first 2 bytes to be zero, although this
483 * is an error, the first byte must have bit 6 set to 1 */
484
485 if (olympic_priv->olympic_laa[0] | olympic_priv->olympic_laa[1] | olympic_priv->olympic_laa[2]) {
486 writeb(olympic_priv->olympic_laa[0],init_srb+12);
487 writeb(olympic_priv->olympic_laa[1],init_srb+13);
488 writeb(olympic_priv->olympic_laa[2],init_srb+14);
489 writeb(olympic_priv->olympic_laa[3],init_srb+15);
490 writeb(olympic_priv->olympic_laa[4],init_srb+16);
491 writeb(olympic_priv->olympic_laa[5],init_srb+17);
492 memcpy(dev->dev_addr,olympic_priv->olympic_laa,dev->addr_len) ;
493 }
494 writeb(1,init_srb+30);
495
496 spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
497 olympic_priv->srb_queued=1;
498
499 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
500 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
501
502 t = jiffies ;
503
504 add_wait_queue(&olympic_priv->srb_wait,&wait) ;
505 set_current_state(TASK_INTERRUPTIBLE) ;
506
507 while(olympic_priv->srb_queued) {
508 schedule() ;
509 if(signal_pending(current)) {
510 printk(KERN_WARNING "%s: Signal received in open.\n",
511 dev->name);
512 printk(KERN_WARNING "SISR=%x LISR=%x\n",
513 readl(olympic_mmio+SISR),
514 readl(olympic_mmio+LISR));
515 olympic_priv->srb_queued=0;
516 break;
517 }
Marcelo Feitoza Parisiff5688a2006-01-09 18:37:15 -0800518 if (time_after(jiffies, t + 10*HZ)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519 printk(KERN_WARNING "%s: SRB timed out. \n",dev->name) ;
520 olympic_priv->srb_queued=0;
521 break ;
522 }
523 set_current_state(TASK_INTERRUPTIBLE) ;
524 }
525 remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
526 set_current_state(TASK_RUNNING) ;
527 olympic_priv->srb_queued = 0 ;
528#if OLYMPIC_DEBUG
529 printk("init_srb(%p): ",init_srb);
530 for(i=0;i<20;i++)
531 printk("%02x ",readb(init_srb+i));
532 printk("\n");
533#endif
534
535 /* If we get the same return response as we set, the interrupt wasn't raised and the open
536 * timed out.
537 */
538
539 switch (resp = readb(init_srb+2)) {
540 case OLYMPIC_CLEAR_RET_CODE:
541 printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name) ;
542 goto out;
543 case 0:
544 open_finished = 1;
545 break;
546 case 0x07:
547 if (!olympic_priv->olympic_ring_speed && open_finished) { /* Autosense , first time around */
548 printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name);
549 open_finished = 0 ;
550 continue;
551 }
552
553 err = readb(init_srb+7);
554
555 if (!olympic_priv->olympic_ring_speed && ((err & 0x0f) == 0x0d)) {
556 printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n",dev->name);
557 printk(KERN_WARNING "%s: Please try again with a specified ring speed \n",dev->name);
558 } else {
559 printk(KERN_WARNING "%s: %s - %s\n", dev->name,
560 open_maj_error[(err & 0xf0) >> 4],
561 open_min_error[(err & 0x0f)]);
562 }
563 goto out;
564
565 case 0x32:
Johannes Berge1749612008-10-27 15:59:26 -0700566 printk(KERN_WARNING "%s: Invalid LAA: %pM\n",
567 dev->name, olympic_priv->olympic_laa);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 goto out;
569
570 default:
571 printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, resp);
572 goto out;
573
574 }
575 } while (!(open_finished)) ; /* Will only loop if ring speed mismatch re-open attempted && autosense is on */
576
577 if (readb(init_srb+18) & (1<<3))
578 if (olympic_priv->olympic_message_level)
579 printk(KERN_INFO "%s: Opened in FDX Mode\n",dev->name);
580
581 if (readb(init_srb+18) & (1<<1))
582 olympic_priv->olympic_ring_speed = 100 ;
583 else if (readb(init_srb+18) & 1)
584 olympic_priv->olympic_ring_speed = 16 ;
585 else
586 olympic_priv->olympic_ring_speed = 4 ;
587
588 if (olympic_priv->olympic_message_level)
589 printk(KERN_INFO "%s: Opened in %d Mbps mode\n",dev->name, olympic_priv->olympic_ring_speed);
590
591 olympic_priv->asb = swab16(readw(init_srb+8));
592 olympic_priv->srb = swab16(readw(init_srb+10));
593 olympic_priv->arb = swab16(readw(init_srb+12));
594 olympic_priv->trb = swab16(readw(init_srb+16));
595
596 olympic_priv->olympic_receive_options = 0x01 ;
597 olympic_priv->olympic_copy_all_options = 0 ;
598
599 /* setup rx ring */
600
601 writel((3<<16),olympic_mmio+BMCTL_RWM); /* Ensure end of frame generated interrupts */
602
603 writel(BMCTL_RX_DIS|3,olympic_mmio+BMCTL_RWM); /* Yes, this the enables RX channel */
604
605 for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
606
607 struct sk_buff *skb;
608
609 skb=dev_alloc_skb(olympic_priv->pkt_buf_sz);
610 if(skb == NULL)
611 break;
612
613 skb->dev = dev;
614
615 olympic_priv->olympic_rx_ring[i].buffer = cpu_to_le32(pci_map_single(olympic_priv->pdev,
616 skb->data,olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE)) ;
617 olympic_priv->olympic_rx_ring[i].res_length = cpu_to_le32(olympic_priv->pkt_buf_sz);
618 olympic_priv->rx_ring_skb[i]=skb;
619 }
620
621 if (i==0) {
622 printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers. Adapter disabled\n",dev->name);
623 goto out;
624 }
625
626 olympic_priv->rx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_rx_ring,
627 sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
628 writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXDESCQ);
629 writel(olympic_priv->rx_ring_dma_addr, olympic_mmio+RXCDA);
630 writew(i, olympic_mmio+RXDESCQCNT);
631
632 olympic_priv->rx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_rx_status_ring,
633 sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
634 writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXSTATQ);
635 writel(olympic_priv->rx_status_ring_dma_addr, olympic_mmio+RXCSA);
636
637 olympic_priv->rx_ring_last_received = OLYMPIC_RX_RING_SIZE - 1; /* last processed rx status */
638 olympic_priv->rx_status_last_received = OLYMPIC_RX_RING_SIZE - 1;
639
640 writew(i, olympic_mmio+RXSTATQCNT);
641
642#if OLYMPIC_DEBUG
643 printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
644 printk("RXCSA: %x, rx_status_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
645 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]) );
646 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]) );
647 printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7]) );
648
649 printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
650 printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",
651 olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ;
652#endif
653
654 writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
655
656#if OLYMPIC_DEBUG
657 printk("# of rx buffers: %d, RXENQ: %x\n",i, readw(olympic_mmio+RXENQ));
658 printk("RXCSA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCSA),&olympic_priv->olympic_rx_status_ring[0]);
659 printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
660#endif
661
662 writel(SISR_RX_STATUS | SISR_RX_NOBUF,olympic_mmio+SISR_MASK_SUM);
663
664 /* setup tx ring */
665
666 writel(BMCTL_TX1_DIS,olympic_mmio+BMCTL_RWM); /* Yes, this enables TX channel 1 */
667 for(i=0;i<OLYMPIC_TX_RING_SIZE;i++)
Al Virob710b432007-12-16 20:53:36 +0000668 olympic_priv->olympic_tx_ring[i].buffer=cpu_to_le32(0xdeadbeef);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669
670 olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE;
671 olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,
672 sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE,PCI_DMA_TODEVICE) ;
673 writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXDESCQ_1);
674 writel(olympic_priv->tx_ring_dma_addr, olympic_mmio+TXCDA_1);
675 writew(OLYMPIC_TX_RING_SIZE, olympic_mmio+TXDESCQCNT_1);
676
677 olympic_priv->tx_status_ring_dma_addr = pci_map_single(olympic_priv->pdev, olympic_priv->olympic_tx_status_ring,
678 sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
679 writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXSTATQ_1);
680 writel(olympic_priv->tx_status_ring_dma_addr,olympic_mmio+TXCSA_1);
681 writew(OLYMPIC_TX_RING_SIZE,olympic_mmio+TXSTATQCNT_1);
682
683 olympic_priv->tx_ring_free=0; /* next entry in tx ring to use */
684 olympic_priv->tx_ring_last_status=OLYMPIC_TX_RING_SIZE-1; /* last processed tx status */
685
686 writel(0xffffffff, olympic_mmio+EISR_RWM) ; /* clean the eisr */
687 writel(0,olympic_mmio+EISR) ;
688 writel(EISR_MASK_OPTIONS,olympic_mmio+EISR_MASK) ; /* enables most of the TX error interrupts */
689 writel(SISR_TX1_EOF | SISR_ADAPTER_CHECK | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_ASB_FREE | SISR_ERR,olympic_mmio+SISR_MASK_SUM);
690
691#if OLYMPIC_DEBUG
692 printk("BMCTL: %x\n",readl(olympic_mmio+BMCTL_SUM));
693 printk("SISR MASK: %x\n",readl(olympic_mmio+SISR_MASK));
694#endif
695
696 if (olympic_priv->olympic_network_monitor) {
Joe Perches0795af52007-10-03 17:59:30 -0700697 u8 __iomem *oat;
698 u8 __iomem *opt;
699 int i;
700 u8 addr[6];
Joe Perches0795af52007-10-03 17:59:30 -0700701 oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr);
702 opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703
Joe Perches0795af52007-10-03 17:59:30 -0700704 for (i = 0; i < 6; i++)
705 addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+i);
Johannes Berge1749612008-10-27 15:59:26 -0700706 printk("%s: Node Address: %pM\n", dev->name, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 printk("%s: Functional Address: %02x:%02x:%02x:%02x\n",dev->name,
708 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
709 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
710 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
711 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
Joe Perches0795af52007-10-03 17:59:30 -0700712
713 for (i = 0; i < 6; i++)
714 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+i);
Johannes Berge1749612008-10-27 15:59:26 -0700715 printk("%s: NAUN Address: %pM\n", dev->name, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 }
717
718 netif_start_queue(dev);
719 return 0;
720
721out:
722 free_irq(dev->irq, dev);
723 return -EIO;
724}
725
726/*
727 * When we enter the rx routine we do not know how many frames have been
728 * queued on the rx channel. Therefore we start at the next rx status
729 * position and travel around the receive ring until we have completed
730 * all the frames.
731 *
732 * This means that we may process the frame before we receive the end
733 * of frame interrupt. This is why we always test the status instead
734 * of blindly processing the next frame.
735 *
736 * We also remove the last 4 bytes from the packet as well, these are
737 * just token ring trailer info and upset protocols that don't check
738 * their own length, i.e. SNA.
739 *
740 */
741static void olympic_rx(struct net_device *dev)
742{
Yoann Padioleaueda10532007-07-23 15:18:21 +0200743 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
745 struct olympic_rx_status *rx_status;
746 struct olympic_rx_desc *rx_desc ;
747 int rx_ring_last_received,length, buffer_cnt, cpy_length, frag_len;
748 struct sk_buff *skb, *skb2;
749 int i;
750
751 rx_status=&(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received + 1) & (OLYMPIC_RX_RING_SIZE - 1)]) ;
752
753 while (rx_status->status_buffercnt) {
754 u32 l_status_buffercnt;
755
756 olympic_priv->rx_status_last_received++ ;
757 olympic_priv->rx_status_last_received &= (OLYMPIC_RX_RING_SIZE -1);
758#if OLYMPIC_DEBUG
759 printk("rx status: %x rx len: %x \n", le32_to_cpu(rx_status->status_buffercnt), le32_to_cpu(rx_status->fragmentcnt_framelen));
760#endif
761 length = le32_to_cpu(rx_status->fragmentcnt_framelen) & 0xffff;
762 buffer_cnt = le32_to_cpu(rx_status->status_buffercnt) & 0xffff;
763 i = buffer_cnt ; /* Need buffer_cnt later for rxenq update */
764 frag_len = le32_to_cpu(rx_status->fragmentcnt_framelen) >> 16;
765
766#if OLYMPIC_DEBUG
767 printk("length: %x, frag_len: %x, buffer_cnt: %x\n", length, frag_len, buffer_cnt);
768#endif
769 l_status_buffercnt = le32_to_cpu(rx_status->status_buffercnt);
770 if(l_status_buffercnt & 0xC0000000) {
771 if (l_status_buffercnt & 0x3B000000) {
772 if (olympic_priv->olympic_message_level) {
773 if (l_status_buffercnt & (1<<29)) /* Rx Frame Truncated */
774 printk(KERN_WARNING "%s: Rx Frame Truncated \n",dev->name);
775 if (l_status_buffercnt & (1<<28)) /*Rx receive overrun */
776 printk(KERN_WARNING "%s: Rx Frame Receive overrun \n",dev->name);
777 if (l_status_buffercnt & (1<<27)) /* No receive buffers */
778 printk(KERN_WARNING "%s: No receive buffers \n",dev->name);
779 if (l_status_buffercnt & (1<<25)) /* Receive frame error detect */
780 printk(KERN_WARNING "%s: Receive frame error detect \n",dev->name);
781 if (l_status_buffercnt & (1<<24)) /* Received Error Detect */
782 printk(KERN_WARNING "%s: Received Error Detect \n",dev->name);
783 }
784 olympic_priv->rx_ring_last_received += i ;
785 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
Stephen Hemmingerdcc59a92009-01-09 13:01:23 +0000786 dev->stats.rx_errors++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 } else {
788
789 if (buffer_cnt == 1) {
790 skb = dev_alloc_skb(max_t(int, olympic_priv->pkt_buf_sz,length)) ;
791 } else {
792 skb = dev_alloc_skb(length) ;
793 }
794
795 if (skb == NULL) {
796 printk(KERN_WARNING "%s: Not enough memory to copy packet to upper layers. \n",dev->name) ;
Stephen Hemmingerdcc59a92009-01-09 13:01:23 +0000797 dev->stats.rx_dropped++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798 /* Update counters even though we don't transfer the frame */
799 olympic_priv->rx_ring_last_received += i ;
800 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1) ;
801 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 /* Optimise based upon number of buffers used.
803 If only one buffer is used we can simply swap the buffers around.
804 If more than one then we must use the new buffer and copy the information
805 first. Ideally all frames would be in a single buffer, this can be tuned by
806 altering the buffer size. If the length of the packet is less than
807 1500 bytes we're going to copy it over anyway to stop packets getting
808 dropped from sockets with buffers smaller than our pkt_buf_sz. */
809
810 if (buffer_cnt==1) {
811 olympic_priv->rx_ring_last_received++ ;
812 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
813 rx_ring_last_received = olympic_priv->rx_ring_last_received ;
814 if (length > 1500) {
815 skb2=olympic_priv->rx_ring_skb[rx_ring_last_received] ;
816 /* unmap buffer */
817 pci_unmap_single(olympic_priv->pdev,
818 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
819 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
820 skb_put(skb2,length-4);
821 skb2->protocol = tr_type_trans(skb2,dev);
822 olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer =
823 cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data,
824 olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE));
825 olympic_priv->olympic_rx_ring[rx_ring_last_received].res_length =
826 cpu_to_le32(olympic_priv->pkt_buf_sz);
827 olympic_priv->rx_ring_skb[rx_ring_last_received] = skb ;
828 netif_rx(skb2) ;
829 } else {
830 pci_dma_sync_single_for_cpu(olympic_priv->pdev,
831 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
832 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -0300833 skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
834 skb_put(skb,length - 4),
835 length - 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 pci_dma_sync_single_for_device(olympic_priv->pdev,
837 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
838 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
839 skb->protocol = tr_type_trans(skb,dev) ;
840 netif_rx(skb) ;
841 }
842 } else {
843 do { /* Walk the buffers */
844 olympic_priv->rx_ring_last_received++ ;
845 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE -1);
846 rx_ring_last_received = olympic_priv->rx_ring_last_received ;
847 pci_dma_sync_single_for_cpu(olympic_priv->pdev,
848 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
849 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
850 rx_desc = &(olympic_priv->olympic_rx_ring[rx_ring_last_received]);
851 cpy_length = (i == 1 ? frag_len : le32_to_cpu(rx_desc->res_length));
Arnaldo Carvalho de Melod626f622007-03-27 18:55:52 -0300852 skb_copy_from_linear_data(olympic_priv->rx_ring_skb[rx_ring_last_received],
853 skb_put(skb, cpy_length),
854 cpy_length);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 pci_dma_sync_single_for_device(olympic_priv->pdev,
856 le32_to_cpu(olympic_priv->olympic_rx_ring[rx_ring_last_received].buffer),
857 olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE) ;
858 } while (--i) ;
859 skb_trim(skb,skb->len-4) ;
860 skb->protocol = tr_type_trans(skb,dev);
861 netif_rx(skb) ;
862 }
Stephen Hemmingerdcc59a92009-01-09 13:01:23 +0000863 dev->stats.rx_packets++ ;
864 dev->stats.rx_bytes += length ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865 } /* if skb == null */
866 } /* If status & 0x3b */
867
868 } else { /*if buffercnt & 0xC */
869 olympic_priv->rx_ring_last_received += i ;
870 olympic_priv->rx_ring_last_received &= (OLYMPIC_RX_RING_SIZE - 1) ;
871 }
872
873 rx_status->fragmentcnt_framelen = 0 ;
874 rx_status->status_buffercnt = 0 ;
875 rx_status = &(olympic_priv->olympic_rx_status_ring[(olympic_priv->rx_status_last_received+1) & (OLYMPIC_RX_RING_SIZE -1) ]);
876
877 writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | buffer_cnt , olympic_mmio+RXENQ);
878 } /* while */
879
880}
881
882static void olympic_freemem(struct net_device *dev)
883{
Yoann Padioleaueda10532007-07-23 15:18:21 +0200884 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 int i;
886
887 for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
888 if (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] != NULL) {
889 dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
890 olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL;
891 }
Al Virob710b432007-12-16 20:53:36 +0000892 if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != cpu_to_le32(0xdeadbeef)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 pci_unmap_single(olympic_priv->pdev,
894 le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
895 olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
896 }
897 olympic_priv->rx_status_last_received++;
898 olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
899 }
900 /* unmap rings */
901 pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr,
902 sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
903 pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
904 sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
905
906 pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr,
907 sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
908 pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr,
909 sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
910
911 return ;
912}
913
David Howells7d12e782006-10-05 14:55:46 +0100914static irqreturn_t olympic_interrupt(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915{
916 struct net_device *dev= (struct net_device *)dev_id;
Yoann Padioleaueda10532007-07-23 15:18:21 +0200917 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
919 u32 sisr;
920 u8 __iomem *adapter_check_area ;
921
922 /*
923 * Read sisr but don't reset it yet.
924 * The indication bit may have been set but the interrupt latch
925 * bit may not be set, so we'd lose the interrupt later.
926 */
927 sisr=readl(olympic_mmio+SISR) ;
928 if (!(sisr & SISR_MI)) /* Interrupt isn't for us */
929 return IRQ_NONE;
930 sisr=readl(olympic_mmio+SISR_RR) ; /* Read & Reset sisr */
931
932 spin_lock(&olympic_priv->olympic_lock);
933
934 /* Hotswap gives us this on removal */
935 if (sisr == 0xffffffff) {
936 printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ;
937 spin_unlock(&olympic_priv->olympic_lock) ;
938 return IRQ_NONE;
939 }
940
941 if (sisr & (SISR_SRB_REPLY | SISR_TX1_EOF | SISR_RX_STATUS | SISR_ADAPTER_CHECK |
942 SISR_ASB_FREE | SISR_ARB_CMD | SISR_TRB_REPLY | SISR_RX_NOBUF | SISR_ERR)) {
943
944 /* If we ever get this the adapter is seriously dead. Only a reset is going to
945 * bring it back to life. We're talking pci bus errors and such like :( */
946 if((sisr & SISR_ERR) && (readl(olympic_mmio+EISR) & EISR_MASK_OPTIONS)) {
947 printk(KERN_ERR "Olympic: EISR Error, EISR=%08x\n",readl(olympic_mmio+EISR)) ;
948 printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ;
949 printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ;
950 printk(KERN_ERR "or the linux-tr mailing list.\n") ;
951 wake_up_interruptible(&olympic_priv->srb_wait);
952 spin_unlock(&olympic_priv->olympic_lock) ;
953 return IRQ_HANDLED;
954 } /* SISR_ERR */
955
956 if(sisr & SISR_SRB_REPLY) {
957 if(olympic_priv->srb_queued==1) {
958 wake_up_interruptible(&olympic_priv->srb_wait);
959 } else if (olympic_priv->srb_queued==2) {
960 olympic_srb_bh(dev) ;
961 }
962 olympic_priv->srb_queued=0;
963 } /* SISR_SRB_REPLY */
964
965 /* We shouldn't ever miss the Tx interrupt, but the you never know, hence the loop to ensure
966 we get all tx completions. */
967 if (sisr & SISR_TX1_EOF) {
968 while(olympic_priv->olympic_tx_status_ring[(olympic_priv->tx_ring_last_status + 1) & (OLYMPIC_TX_RING_SIZE-1)].status) {
969 olympic_priv->tx_ring_last_status++;
970 olympic_priv->tx_ring_last_status &= (OLYMPIC_TX_RING_SIZE-1);
971 olympic_priv->free_tx_ring_entries++;
Stephen Hemmingerdcc59a92009-01-09 13:01:23 +0000972 dev->stats.tx_bytes += olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len;
973 dev->stats.tx_packets++ ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 pci_unmap_single(olympic_priv->pdev,
975 le32_to_cpu(olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer),
976 olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);
977 dev_kfree_skb_irq(olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]);
Al Virob710b432007-12-16 20:53:36 +0000978 olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32(0xdeadbeef);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979 olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0;
980 }
981 netif_wake_queue(dev);
982 } /* SISR_TX1_EOF */
983
984 if (sisr & SISR_RX_STATUS) {
985 olympic_rx(dev);
986 } /* SISR_RX_STATUS */
987
988 if (sisr & SISR_ADAPTER_CHECK) {
989 netif_stop_queue(dev);
990 printk(KERN_WARNING "%s: Adapter Check Interrupt Raised, 8 bytes of information follow:\n", dev->name);
991 writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA);
992 adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ;
993 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)) ;
994 spin_unlock(&olympic_priv->olympic_lock) ;
995 return IRQ_HANDLED;
996 } /* SISR_ADAPTER_CHECK */
997
998 if (sisr & SISR_ASB_FREE) {
999 /* Wake up anything that is waiting for the asb response */
1000 if (olympic_priv->asb_queued) {
1001 olympic_asb_bh(dev) ;
1002 }
1003 } /* SISR_ASB_FREE */
1004
1005 if (sisr & SISR_ARB_CMD) {
1006 olympic_arb_cmd(dev) ;
1007 } /* SISR_ARB_CMD */
1008
1009 if (sisr & SISR_TRB_REPLY) {
1010 /* Wake up anything that is waiting for the trb response */
1011 if (olympic_priv->trb_queued) {
1012 wake_up_interruptible(&olympic_priv->trb_wait);
1013 }
1014 olympic_priv->trb_queued = 0 ;
1015 } /* SISR_TRB_REPLY */
1016
1017 if (sisr & SISR_RX_NOBUF) {
1018 /* According to the documentation, we don't have to do anything, but trapping it keeps it out of
1019 /var/log/messages. */
1020 } /* SISR_RX_NOBUF */
1021 } else {
1022 printk(KERN_WARNING "%s: Unexpected interrupt: %x\n",dev->name, sisr);
1023 printk(KERN_WARNING "%s: SISR_MASK: %x\n",dev->name, readl(olympic_mmio+SISR_MASK)) ;
1024 } /* One if the interrupts we want */
1025 writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
1026
1027 spin_unlock(&olympic_priv->olympic_lock) ;
1028 return IRQ_HANDLED;
1029}
1030
1031static int olympic_xmit(struct sk_buff *skb, struct net_device *dev)
1032{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001033 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001034 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
1035 unsigned long flags ;
1036
1037 spin_lock_irqsave(&olympic_priv->olympic_lock, flags);
1038
1039 netif_stop_queue(dev);
1040
1041 if(olympic_priv->free_tx_ring_entries) {
1042 olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer =
1043 cpu_to_le32(pci_map_single(olympic_priv->pdev, skb->data, skb->len,PCI_DMA_TODEVICE));
1044 olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length = cpu_to_le32(skb->len | (0x80000000));
1045 olympic_priv->tx_ring_skb[olympic_priv->tx_ring_free]=skb;
1046 olympic_priv->free_tx_ring_entries--;
1047
1048 olympic_priv->tx_ring_free++;
1049 olympic_priv->tx_ring_free &= (OLYMPIC_TX_RING_SIZE-1);
1050 writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
1051 netif_wake_queue(dev);
1052 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
1053 return 0;
1054 } else {
1055 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
1056 return 1;
1057 }
1058
1059}
1060
1061
1062static int olympic_close(struct net_device *dev)
1063{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001064 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio,*srb;
1066 unsigned long t,flags;
1067
1068 DECLARE_WAITQUEUE(wait,current) ;
1069
1070 netif_stop_queue(dev);
1071
1072 writel(olympic_priv->srb,olympic_mmio+LAPA);
1073 srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
1074
1075 writeb(SRB_CLOSE_ADAPTER,srb+0);
1076 writeb(0,srb+1);
1077 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1078
1079 add_wait_queue(&olympic_priv->srb_wait,&wait) ;
1080 set_current_state(TASK_INTERRUPTIBLE) ;
1081
1082 spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
1083 olympic_priv->srb_queued=1;
1084
1085 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1086 spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
1087
1088 while(olympic_priv->srb_queued) {
1089
Nishanth Aravamudan3173c892005-09-11 02:09:55 -07001090 t = schedule_timeout_interruptible(60*HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091
1092 if(signal_pending(current)) {
1093 printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
1094 printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
1095 olympic_priv->srb_queued=0;
1096 break;
1097 }
1098
1099 if (t == 0) {
1100 printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ;
1101 }
1102 olympic_priv->srb_queued=0;
1103 }
1104 remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
1105
1106 olympic_priv->rx_status_last_received++;
1107 olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
1108
1109 olympic_freemem(dev) ;
1110
1111 /* reset tx/rx fifo's and busmaster logic */
1112
1113 writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
1114 udelay(1);
1115 writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
1116
1117#if OLYMPIC_DEBUG
1118 {
1119 int i ;
1120 printk("srb(%p): ",srb);
1121 for(i=0;i<4;i++)
1122 printk("%x ",readb(srb+i));
1123 printk("\n");
1124 }
1125#endif
1126 free_irq(dev->irq,dev);
1127
1128 return 0;
1129
1130}
1131
1132static void olympic_set_rx_mode(struct net_device *dev)
1133{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001134 struct olympic_private *olympic_priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ;
1136 u8 options = 0;
1137 u8 __iomem *srb;
1138 struct dev_mc_list *dmi ;
1139 unsigned char dev_mc_address[4] ;
1140 int i ;
1141
1142 writel(olympic_priv->srb,olympic_mmio+LAPA);
1143 srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
1144 options = olympic_priv->olympic_copy_all_options;
1145
1146 if (dev->flags&IFF_PROMISC)
1147 options |= 0x61 ;
1148 else
1149 options &= ~0x61 ;
1150
1151 /* Only issue the srb if there is a change in options */
1152
1153 if ((options ^ olympic_priv->olympic_copy_all_options)) {
1154
1155 /* Now to issue the srb command to alter the copy.all.options */
1156
1157 writeb(SRB_MODIFY_RECEIVE_OPTIONS,srb);
1158 writeb(0,srb+1);
1159 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1160 writeb(0,srb+3);
1161 writeb(olympic_priv->olympic_receive_options,srb+4);
1162 writeb(options,srb+5);
1163
1164 olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */
1165
1166 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1167
1168 olympic_priv->olympic_copy_all_options = options ;
1169
1170 return ;
1171 }
1172
1173 /* Set the functional addresses we need for multicast */
1174
1175 dev_mc_address[0] = dev_mc_address[1] = dev_mc_address[2] = dev_mc_address[3] = 0 ;
1176
1177 for (i=0,dmi=dev->mc_list;i < dev->mc_count; i++,dmi = dmi->next) {
1178 dev_mc_address[0] |= dmi->dmi_addr[2] ;
1179 dev_mc_address[1] |= dmi->dmi_addr[3] ;
1180 dev_mc_address[2] |= dmi->dmi_addr[4] ;
1181 dev_mc_address[3] |= dmi->dmi_addr[5] ;
1182 }
1183
1184 writeb(SRB_SET_FUNC_ADDRESS,srb+0);
1185 writeb(0,srb+1);
1186 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1187 writeb(0,srb+3);
1188 writeb(0,srb+4);
1189 writeb(0,srb+5);
1190 writeb(dev_mc_address[0],srb+6);
1191 writeb(dev_mc_address[1],srb+7);
1192 writeb(dev_mc_address[2],srb+8);
1193 writeb(dev_mc_address[3],srb+9);
1194
1195 olympic_priv->srb_queued = 2 ;
1196 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1197
1198}
1199
1200static void olympic_srb_bh(struct net_device *dev)
1201{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001202 struct olympic_private *olympic_priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203 u8 __iomem *olympic_mmio = olympic_priv->olympic_mmio ;
1204 u8 __iomem *srb;
1205
1206 writel(olympic_priv->srb,olympic_mmio+LAPA);
1207 srb=olympic_priv->olympic_lap + (olympic_priv->srb & (~0xf800));
1208
1209 switch (readb(srb)) {
1210
1211 /* SRB_MODIFY_RECEIVE_OPTIONS i.e. set_multicast_list options (promiscuous)
1212 * At some point we should do something if we get an error, such as
1213 * resetting the IFF_PROMISC flag in dev
1214 */
1215
1216 case SRB_MODIFY_RECEIVE_OPTIONS:
1217 switch (readb(srb+2)) {
1218 case 0x01:
1219 printk(KERN_WARNING "%s: Unrecognized srb command\n",dev->name) ;
1220 break ;
1221 case 0x04:
1222 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
1223 break ;
1224 default:
1225 if (olympic_priv->olympic_message_level)
1226 printk(KERN_WARNING "%s: Receive Options Modified to %x,%x\n",dev->name,olympic_priv->olympic_copy_all_options, olympic_priv->olympic_receive_options) ;
1227 break ;
1228 } /* switch srb[2] */
1229 break ;
1230
1231 /* SRB_SET_GROUP_ADDRESS - Multicast group setting
1232 */
1233
1234 case SRB_SET_GROUP_ADDRESS:
1235 switch (readb(srb+2)) {
1236 case 0x00:
1237 break ;
1238 case 0x01:
1239 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1240 break ;
1241 case 0x04:
1242 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name);
1243 break ;
1244 case 0x3c:
1245 printk(KERN_WARNING "%s: Group/Functional address indicator bits not set correctly\n",dev->name) ;
1246 break ;
1247 case 0x3e: /* If we ever implement individual multicast addresses, will need to deal with this */
1248 printk(KERN_WARNING "%s: Group address registers full\n",dev->name) ;
1249 break ;
1250 case 0x55:
1251 printk(KERN_INFO "%s: Group Address already set.\n",dev->name) ;
1252 break ;
1253 default:
1254 break ;
1255 } /* switch srb[2] */
1256 break ;
1257
1258 /* SRB_RESET_GROUP_ADDRESS - Remove a multicast address from group list
1259 */
1260
1261 case SRB_RESET_GROUP_ADDRESS:
1262 switch (readb(srb+2)) {
1263 case 0x00:
1264 break ;
1265 case 0x01:
1266 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1267 break ;
1268 case 0x04:
1269 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1270 break ;
1271 case 0x39: /* Must deal with this if individual multicast addresses used */
1272 printk(KERN_INFO "%s: Group address not found \n",dev->name);
1273 break ;
1274 default:
1275 break ;
1276 } /* switch srb[2] */
1277 break ;
1278
1279
1280 /* SRB_SET_FUNC_ADDRESS - Called by the set_rx_mode
1281 */
1282
1283 case SRB_SET_FUNC_ADDRESS:
1284 switch (readb(srb+2)) {
1285 case 0x00:
1286 if (olympic_priv->olympic_message_level)
1287 printk(KERN_INFO "%s: Functional Address Mask Set \n",dev->name) ;
1288 break ;
1289 case 0x01:
1290 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1291 break ;
1292 case 0x04:
1293 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1294 break ;
1295 default:
1296 break ;
1297 } /* switch srb[2] */
1298 break ;
1299
1300 /* SRB_READ_LOG - Read and reset the adapter error counters
1301 */
1302
1303 case SRB_READ_LOG:
1304 switch (readb(srb+2)) {
1305 case 0x00:
1306 if (olympic_priv->olympic_message_level)
1307 printk(KERN_INFO "%s: Read Log issued\n",dev->name) ;
1308 break ;
1309 case 0x01:
1310 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1311 break ;
1312 case 0x04:
1313 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1314 break ;
1315
1316 } /* switch srb[2] */
1317 break ;
1318
1319 /* SRB_READ_SR_COUNTERS - Read and reset the source routing bridge related counters */
1320
1321 case SRB_READ_SR_COUNTERS:
1322 switch (readb(srb+2)) {
1323 case 0x00:
1324 if (olympic_priv->olympic_message_level)
1325 printk(KERN_INFO "%s: Read Source Routing Counters issued\n",dev->name) ;
1326 break ;
1327 case 0x01:
1328 printk(KERN_WARNING "%s: Unrecognized srb command \n",dev->name) ;
1329 break ;
1330 case 0x04:
1331 printk(KERN_WARNING "%s: Adapter must be open for this operation, doh!!\n",dev->name) ;
1332 break ;
1333 default:
1334 break ;
1335 } /* switch srb[2] */
1336 break ;
1337
1338 default:
1339 printk(KERN_WARNING "%s: Unrecognized srb bh return value.\n",dev->name);
1340 break ;
1341 } /* switch srb[0] */
1342
1343}
1344
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345static int olympic_set_mac_address (struct net_device *dev, void *addr)
1346{
1347 struct sockaddr *saddr = addr ;
Yoann Padioleaueda10532007-07-23 15:18:21 +02001348 struct olympic_private *olympic_priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349
1350 if (netif_running(dev)) {
1351 printk(KERN_WARNING "%s: Cannot set mac/laa address while card is open\n", dev->name) ;
1352 return -EIO ;
1353 }
1354
1355 memcpy(olympic_priv->olympic_laa, saddr->sa_data,dev->addr_len) ;
1356
1357 if (olympic_priv->olympic_message_level) {
1358 printk(KERN_INFO "%s: MAC/LAA Set to = %x.%x.%x.%x.%x.%x\n",dev->name, olympic_priv->olympic_laa[0],
1359 olympic_priv->olympic_laa[1], olympic_priv->olympic_laa[2],
1360 olympic_priv->olympic_laa[3], olympic_priv->olympic_laa[4],
1361 olympic_priv->olympic_laa[5]);
1362 }
1363
1364 return 0 ;
1365}
1366
1367static void olympic_arb_cmd(struct net_device *dev)
1368{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001369 struct olympic_private *olympic_priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 u8 __iomem *olympic_mmio=olympic_priv->olympic_mmio;
1371 u8 __iomem *arb_block, *asb_block, *srb ;
1372 u8 header_len ;
1373 u16 frame_len, buffer_len ;
1374 struct sk_buff *mac_frame ;
1375 u8 __iomem *buf_ptr ;
1376 u8 __iomem *frame_data ;
1377 u16 buff_off ;
1378 u16 lan_status = 0, lan_status_diff ; /* Initialize to stop compiler warning */
1379 u8 fdx_prot_error ;
1380 u16 next_ptr;
1381
1382 arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ;
1383 asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ;
1384 srb = (olympic_priv->olympic_lap + olympic_priv->srb) ;
1385
1386 if (readb(arb_block+0) == ARB_RECEIVE_DATA) { /* Receive.data, MAC frames */
1387
1388 header_len = readb(arb_block+8) ; /* 802.5 Token-Ring Header Length */
1389 frame_len = swab16(readw(arb_block + 10)) ;
1390
1391 buff_off = swab16(readw(arb_block + 6)) ;
1392
1393 buf_ptr = olympic_priv->olympic_lap + buff_off ;
1394
1395#if OLYMPIC_DEBUG
1396{
1397 int i;
1398 frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ;
1399
1400 for (i=0 ; i < 14 ; i++) {
1401 printk("Loc %d = %02x\n",i,readb(frame_data + i));
1402 }
1403
1404 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)));
1405}
1406#endif
1407 mac_frame = dev_alloc_skb(frame_len) ;
1408 if (!mac_frame) {
1409 printk(KERN_WARNING "%s: Memory squeeze, dropping frame.\n", dev->name);
1410 goto drop_frame;
1411 }
1412
1413 /* Walk the buffer chain, creating the frame */
1414
1415 do {
1416 frame_data = buf_ptr+offsetof(struct mac_receive_buffer,frame_data) ;
1417 buffer_len = swab16(readw(buf_ptr+offsetof(struct mac_receive_buffer,buffer_length)));
1418 memcpy_fromio(skb_put(mac_frame, buffer_len), frame_data , buffer_len ) ;
1419 next_ptr=readw(buf_ptr+offsetof(struct mac_receive_buffer,next));
Al Virob710b432007-12-16 20:53:36 +00001420 } while (next_ptr && (buf_ptr=olympic_priv->olympic_lap + swab16(next_ptr)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Arnaldo Carvalho de Meloc1a4b862007-03-19 15:27:07 -07001422 mac_frame->protocol = tr_type_trans(mac_frame, dev);
1423
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 if (olympic_priv->olympic_network_monitor) {
Joe Perches0795af52007-10-03 17:59:30 -07001425 struct trh_hdr *mac_hdr;
Joe Perches0795af52007-10-03 17:59:30 -07001426 printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name);
Arnaldo Carvalho de Meloc1a4b862007-03-19 15:27:07 -07001427 mac_hdr = tr_hdr(mac_frame);
Johannes Berge1749612008-10-27 15:59:26 -07001428 printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %pM\n",
1429 dev->name, mac_hdr->daddr);
1430 printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %pM\n",
1431 dev->name, mac_hdr->saddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 }
Arnaldo Carvalho de Meloc1a4b862007-03-19 15:27:07 -07001433 netif_rx(mac_frame);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
1435drop_frame:
1436 /* Now tell the card we have dealt with the received frame */
1437
1438 /* Set LISR Bit 1 */
1439 writel(LISR_ARB_FREE,olympic_priv->olympic_mmio + LISR_SUM);
1440
1441 /* Is the ASB free ? */
1442
1443 if (readb(asb_block + 2) != 0xff) {
1444 olympic_priv->asb_queued = 1 ;
1445 writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
1446 return ;
1447 /* Drop out and wait for the bottom half to be run */
1448 }
1449
1450 writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */
1451 writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */
1452 writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */
1453 writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */
1454
1455 writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
1456
1457 olympic_priv->asb_queued = 2 ;
1458
1459 return ;
1460
1461 } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */
1462 lan_status = swab16(readw(arb_block+6));
1463 fdx_prot_error = readb(arb_block+8) ;
1464
1465 /* Issue ARB Free */
1466 writel(LISR_ARB_FREE,olympic_priv->olympic_mmio+LISR_SUM);
1467
1468 lan_status_diff = olympic_priv->olympic_lan_status ^ lan_status ;
1469
1470 if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) {
1471 if (lan_status_diff & LSC_LWF)
1472 printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name);
1473 if (lan_status_diff & LSC_ARW)
1474 printk(KERN_WARNING "%s: Auto removal error\n",dev->name);
1475 if (lan_status_diff & LSC_FPE)
1476 printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name);
1477 if (lan_status_diff & LSC_RR)
1478 printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name);
1479
1480 /* Adapter has been closed by the hardware */
1481
1482 /* reset tx/rx fifo's and busmaster logic */
1483
1484 writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL);
1485 udelay(1);
1486 writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
1487 netif_stop_queue(dev);
1488 olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ;
1489 printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ;
1490 } /* If serious error */
1491
1492 if (olympic_priv->olympic_message_level) {
1493 if (lan_status_diff & LSC_SIG_LOSS)
1494 printk(KERN_WARNING "%s: No receive signal detected \n", dev->name) ;
1495 if (lan_status_diff & LSC_HARD_ERR)
1496 printk(KERN_INFO "%s: Beaconing \n",dev->name);
1497 if (lan_status_diff & LSC_SOFT_ERR)
1498 printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n",dev->name);
1499 if (lan_status_diff & LSC_TRAN_BCN)
1500 printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name);
1501 if (lan_status_diff & LSC_SS)
1502 printk(KERN_INFO "%s: Single Station on the ring \n", dev->name);
1503 if (lan_status_diff & LSC_RING_REC)
1504 printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name);
1505 if (lan_status_diff & LSC_FDX_MODE)
1506 printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name);
1507 }
1508
1509 if (lan_status_diff & LSC_CO) {
1510
1511 if (olympic_priv->olympic_message_level)
1512 printk(KERN_INFO "%s: Counter Overflow \n", dev->name);
1513
1514 /* Issue READ.LOG command */
1515
1516 writeb(SRB_READ_LOG, srb);
1517 writeb(0,srb+1);
1518 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1519 writeb(0,srb+3);
1520 writeb(0,srb+4);
1521 writeb(0,srb+5);
1522
1523 olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */
1524
1525 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1526
1527 }
1528
1529 if (lan_status_diff & LSC_SR_CO) {
1530
1531 if (olympic_priv->olympic_message_level)
1532 printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name);
1533
1534 /* Issue a READ.SR.COUNTERS */
1535
1536 writeb(SRB_READ_SR_COUNTERS,srb);
1537 writeb(0,srb+1);
1538 writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
1539 writeb(0,srb+3);
1540
1541 olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */
1542
1543 writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
1544
1545 }
1546
1547 olympic_priv->olympic_lan_status = lan_status ;
1548
1549 } /* Lan.change.status */
1550 else
1551 printk(KERN_WARNING "%s: Unknown arb command \n", dev->name);
1552}
1553
1554static void olympic_asb_bh(struct net_device *dev)
1555{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001556 struct olympic_private *olympic_priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 u8 __iomem *arb_block, *asb_block ;
1558
1559 arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ;
1560 asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ;
1561
1562 if (olympic_priv->asb_queued == 1) { /* Dropped through the first time */
1563
1564 writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */
1565 writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */
1566 writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */
1567 writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */
1568
1569 writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM);
1570 olympic_priv->asb_queued = 2 ;
1571
1572 return ;
1573 }
1574
1575 if (olympic_priv->asb_queued == 2) {
1576 switch (readb(asb_block+2)) {
1577 case 0x01:
1578 printk(KERN_WARNING "%s: Unrecognized command code \n", dev->name);
1579 break ;
1580 case 0x26:
1581 printk(KERN_WARNING "%s: Unrecognized buffer address \n", dev->name);
1582 break ;
1583 case 0xFF:
1584 /* Valid response, everything should be ok again */
1585 break ;
1586 default:
1587 printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name);
1588 break ;
1589 }
1590 }
1591 olympic_priv->asb_queued = 0 ;
1592}
1593
1594static int olympic_change_mtu(struct net_device *dev, int mtu)
1595{
Yoann Padioleaueda10532007-07-23 15:18:21 +02001596 struct olympic_private *olympic_priv = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 u16 max_mtu ;
1598
1599 if (olympic_priv->olympic_ring_speed == 4)
1600 max_mtu = 4500 ;
1601 else
1602 max_mtu = 18000 ;
1603
1604 if (mtu > max_mtu)
1605 return -EINVAL ;
1606 if (mtu < 100)
1607 return -EINVAL ;
1608
1609 dev->mtu = mtu ;
1610 olympic_priv->pkt_buf_sz = mtu + TR_HLEN ;
1611
1612 return 0 ;
1613}
1614
1615static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
1616{
1617 struct net_device *dev = (struct net_device *)data ;
Yoann Padioleaueda10532007-07-23 15:18:21 +02001618 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ;
1620 u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ;
1621 int size = 0 ;
1622 int len=0;
1623 off_t begin=0;
1624 off_t pos=0;
Joe Perches0795af52007-10-03 17:59:30 -07001625 u8 addr[6];
1626 u8 addr2[6];
1627 int i;
Joe Perches0795af52007-10-03 17:59:30 -07001628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 size = sprintf(buffer,
1630 "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
1631 size += sprintf(buffer+size, "\n%6s: Adapter Address : Node Address : Functional Addr\n",
1632 dev->name);
1633
Joe Perches0795af52007-10-03 17:59:30 -07001634 for (i = 0 ; i < 6 ; i++)
1635 addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i);
1636
Johannes Berge1749612008-10-27 15:59:26 -07001637 size += sprintf(buffer+size, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 dev->name,
Johannes Berge1749612008-10-27 15:59:26 -07001639 dev->dev_addr, addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)),
1641 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1),
1642 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
1643 readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
1644
1645 size += sprintf(buffer+size, "\n%6s: Token Ring Parameters Table:\n", dev->name);
1646
1647 size += sprintf(buffer+size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n",
1648 dev->name) ;
Joe Perches0795af52007-10-03 17:59:30 -07001649
1650 for (i = 0 ; i < 6 ; i++)
1651 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, up_node_addr) + i);
1652 for (i = 0 ; i < 6 ; i++)
1653 addr2[i] = readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i);
1654
Johannes Berge1749612008-10-27 15:59:26 -07001655 size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x : %pM : %pM : %04x : %04x : %04x :\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 dev->name,
1657 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)),
1658 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1),
1659 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2),
1660 readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3),
Johannes Berge1749612008-10-27 15:59:26 -07001661 addr, addr2,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))),
1663 swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))),
1664 swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code))));
1665
1666 size += sprintf(buffer+size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
1667 dev->name) ;
1668
Joe Perches0795af52007-10-03 17:59:30 -07001669 for (i = 0 ; i < 6 ; i++)
1670 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i);
Johannes Berge1749612008-10-27 15:59:26 -07001671 size += sprintf(buffer+size, "%6s: %pM : %04x : %04x : %04x : %04x : %04x : %04x : \n",
1672 dev->name, addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))),
1674 swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))),
1675 swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))),
1676 swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))),
1677 swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))),
1678 swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl))));
1679
1680 size += sprintf(buffer+size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n",
1681 dev->name) ;
1682
Joe Perches0795af52007-10-03 17:59:30 -07001683 for (i = 0 ; i < 6 ; i++)
1684 addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i);
Johannes Berge1749612008-10-27 15:59:26 -07001685 size += sprintf(buffer+size, "%6s: : %02x : %02x : %pM : %02x:%02x:%02x:%02x : \n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 dev->name,
1687 swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))),
1688 swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))),
Johannes Berge1749612008-10-27 15:59:26 -07001689 addr,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)),
1691 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1),
1692 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
1693 readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3));
1694
1695 len=size;
1696 pos=begin+size;
1697 if (pos<offset) {
1698 len=0;
1699 begin=pos;
1700 }
1701 *start=buffer+(offset-begin); /* Start of wanted data */
1702 len-=(offset-begin); /* Start slop */
1703 if(len>length)
1704 len=length; /* Ending slop */
1705 return len;
1706}
1707
1708static void __devexit olympic_remove_one(struct pci_dev *pdev)
1709{
1710 struct net_device *dev = pci_get_drvdata(pdev) ;
Yoann Padioleaueda10532007-07-23 15:18:21 +02001711 struct olympic_private *olympic_priv=netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 if (olympic_priv->olympic_network_monitor) {
1714 char proc_name[20] ;
Eric W. Biederman457c4cb2007-09-12 12:01:34 +02001715 strcpy(proc_name,"olympic_") ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 strcat(proc_name,dev->name) ;
Eric W. Biederman457c4cb2007-09-12 12:01:34 +02001717 remove_proc_entry(proc_name,init_net.proc_net);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 }
1719 unregister_netdev(dev) ;
1720 iounmap(olympic_priv->olympic_mmio) ;
1721 iounmap(olympic_priv->olympic_lap) ;
1722 pci_release_regions(pdev) ;
1723 pci_set_drvdata(pdev,NULL) ;
1724 free_netdev(dev) ;
1725}
1726
1727static struct pci_driver olympic_driver = {
1728 .name = "olympic",
1729 .id_table = olympic_pci_tbl,
1730 .probe = olympic_probe,
1731 .remove = __devexit_p(olympic_remove_one),
1732};
1733
1734static int __init olympic_pci_init(void)
1735{
Henrik Kretzschmar83717cf2006-10-10 14:33:29 -07001736 return pci_register_driver(&olympic_driver) ;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737}
1738
1739static void __exit olympic_pci_cleanup(void)
1740{
1741 pci_unregister_driver(&olympic_driver) ;
1742}
1743
1744
1745module_init(olympic_pci_init) ;
1746module_exit(olympic_pci_cleanup) ;
1747
1748MODULE_LICENSE("GPL");