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#define DRV_NAME "3c515"
26#define DRV_VERSION "0.99t-ac"
27#define DRV_RELDATE "28-Oct-2002"
28
29static char *version =
30DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " becker@scyld.com and others\n";
31
32#define CORKSCREW 1
33
34
35
36
37static const int rx_copybreak = 200;
38
39
40static const int mtu = 1500;
41
42
43static int max_interrupt_work = 20;
44
45
46#define AUTOMEDIA 1
47
48
49
50
51
52#define VORTEX_BUS_MASTER
53
54
55
56#define TX_RING_SIZE 16
57#define RX_RING_SIZE 16
58#define PKT_BUF_SZ 1536
59
60#include <linux/config.h>
61#include <linux/module.h>
62#include <linux/isapnp.h>
63#include <linux/kernel.h>
64#include <linux/netdevice.h>
65#include <linux/string.h>
66#include <linux/errno.h>
67#include <linux/in.h>
68#include <linux/ioport.h>
69#include <linux/slab.h>
70#include <linux/skbuff.h>
71#include <linux/etherdevice.h>
72#include <linux/interrupt.h>
73#include <linux/timer.h>
74#include <linux/ethtool.h>
75
76#include <asm/uaccess.h>
77#include <asm/bitops.h>
78#include <asm/io.h>
79#include <asm/dma.h>
80
81#define NEW_MULTICAST
82#include <linux/delay.h>
83
84#define MAX_UNITS 8
85
86MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
87MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
88MODULE_LICENSE("GPL");
89
90MODULE_PARM(debug, "i");
91MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
92MODULE_PARM(rx_copybreak, "i");
93MODULE_PARM(max_interrupt_work, "i");
94MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
95MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
96MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
97MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
98
99
100
101#define DRIVER_DEBUG 1
102
103
104static int rx_nocopy, rx_copy, queued_packet;
105
106
107
108#define WAIT_TX_AVAIL 200
109
110
111#define TX_TIMEOUT 40
112
113
114
115
116#define CORKSCREW_TOTAL_SIZE 0x20
117
118#ifdef DRIVER_DEBUG
119static int corkscrew_debug = DRIVER_DEBUG;
120#else
121static int corkscrew_debug = 1;
122#endif
123
124#define CORKSCREW_ID 10
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
186#define EL3_CMD 0x0e
187#define EL3_STATUS 0x0e
188
189
190
191
192
193
194
195enum corkscrew_cmd {
196 TotalReset = 0 << 11, SelectWindow = 1 << 11, StartCoax = 2 << 11,
197 RxDisable = 3 << 11, RxEnable = 4 << 11, RxReset = 5 << 11,
198 UpStall = 6 << 11, UpUnstall = (6 << 11) + 1, DownStall = (6 << 11) + 2,
199 DownUnstall = (6 << 11) + 3, RxDiscard = 8 << 11, TxEnable = 9 << 11,
200 TxDisable = 10 << 11, TxReset = 11 << 11, FakeIntr = 12 << 11,
201 AckIntr = 13 << 11, SetIntrEnb = 14 << 11, SetStatusEnb = 15 << 11,
202 SetRxFilter = 16 << 11, SetRxThreshold = 17 << 11,
203 SetTxThreshold = 18 << 11, SetTxStart = 19 << 11, StartDMAUp = 20 << 11,
204 StartDMADown = (20 << 11) + 1, StatsEnable = 21 << 11,
205 StatsDisable = 22 << 11, StopCoax = 23 << 11,
206};
207
208
209enum RxFilter {
210 RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
211};
212
213
214enum corkscrew_status {
215 IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
216 TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
217 IntReq = 0x0040, StatsFull = 0x0080,
218 DMADone = 1 << 8, DownComplete = 1 << 9, UpComplete = 1 << 10,
219 DMAInProgress = 1 << 11,
220 CmdInProgress = 1 << 12,
221};
222
223
224
225enum Window1 {
226 TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
227 RxStatus = 0x18, Timer = 0x1A, TxStatus = 0x1B,
228 TxFree = 0x1C,
229};
230enum Window0 {
231 Wn0IRQ = 0x08,
232#if defined(CORKSCREW)
233 Wn0EepromCmd = 0x200A,
234 Wn0EepromData = 0x200C,
235#else
236 Wn0EepromCmd = 10,
237 Wn0EepromData = 12,
238#endif
239};
240enum Win0_EEPROM_bits {
241 EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
242 EEPROM_EWENB = 0x30,
243 EEPROM_EWDIS = 0x00,
244};
245
246
247enum eeprom_offset {
248 PhysAddr01 = 0, PhysAddr23 = 1, PhysAddr45 = 2, ModelID = 3,
249 EtherLink3ID = 7,
250};
251
252enum Window3 {
253 Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
254};
255union wn3_config {
256 int i;
257 struct w3_config_fields {
258 unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
259 int pad8:8;
260 unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
261 int pad24:7;
262 } u;
263};
264
265enum Window4 {
266 Wn4_NetDiag = 6, Wn4_Media = 10,
267};
268enum Win4_Media_bits {
269 Media_SQE = 0x0008,
270 Media_10TP = 0x00C0,
271 Media_Lnk = 0x0080,
272 Media_LnkBeat = 0x0800,
273};
274enum Window7 {
275 Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
276};
277
278
279enum MasterCtrl {
280 PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen =
281 0x40c,
282 TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418,
283};
284
285
286
287
288struct boom_rx_desc {
289 u32 next;
290 s32 status;
291 u32 addr;
292 s32 length;
293};
294
295
296enum rx_desc_status {
297 RxDComplete = 0x00008000, RxDError = 0x4000,
298
299};
300
301struct boom_tx_desc {
302 u32 next;
303 s32 status;
304 u32 addr;
305 s32 length;
306};
307
308struct corkscrew_private {
309 const char *product_name;
310 struct net_device *next_module;
311
312 struct boom_rx_desc rx_ring[RX_RING_SIZE];
313 struct boom_tx_desc tx_ring[TX_RING_SIZE];
314
315 struct sk_buff *rx_skbuff[RX_RING_SIZE];
316 struct sk_buff *tx_skbuff[TX_RING_SIZE];
317 unsigned int cur_rx, cur_tx;
318 unsigned int dirty_rx, dirty_tx;
319 struct net_device_stats stats;
320 struct sk_buff *tx_skb;
321 struct timer_list timer;
322 int capabilities ;
323 int options;
324 int last_rx_packets;
325 unsigned int available_media:8,
326 media_override:3,
327 default_media:3,
328 full_duplex:1, autoselect:1, bus_master:1,
329 full_bus_master_tx:1, full_bus_master_rx:1,
330 tx_full:1;
331 spinlock_t lock;
332};
333
334
335
336
337enum xcvr_types {
338 XCVR_10baseT = 0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
339 XCVR_100baseFx, XCVR_MII = 6, XCVR_Default = 8,
340};
341
342static struct media_table {
343 char *name;
344 unsigned int media_bits:16,
345 mask:8,
346 next:8;
347 short wait;
348} media_tbl[] = {
349 { "10baseT", Media_10TP, 0x08, XCVR_10base2, (14 * HZ) / 10 },
350 { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1 * HZ) / 10},
351 { "undefined", 0, 0x80, XCVR_10baseT, 10000},
352 { "10base2", 0, 0x10, XCVR_AUI, (1 * HZ) / 10},
353 { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14 * HZ) / 10},
354 { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14 * HZ) / 10},
355 { "MII", 0, 0x40, XCVR_10baseT, 3 * HZ},
356 { "undefined", 0, 0x01, XCVR_10baseT, 10000},
357 { "Default", 0, 0xFF, XCVR_10baseT, 10000},
358};
359
360#ifdef __ISAPNP__
361static struct isapnp_device_id corkscrew_isapnp_adapters[] = {
362 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
363 ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051),
364 (long) "3Com Fast EtherLink ISA" },
365 { }
366};
367
368MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
369
370static int corkscrew_isapnp_phys_addr[3];
371
372static int nopnp;
373#endif
374
375static int corkscrew_scan(struct net_device *dev);
376static struct net_device *corkscrew_found_device(struct net_device *dev,
377 int ioaddr, int irq,
378 int product_index,
379 int options);
380static int corkscrew_probe1(struct net_device *dev);
381static int corkscrew_open(struct net_device *dev);
382static void corkscrew_timer(unsigned long arg);
383static int corkscrew_start_xmit(struct sk_buff *skb,
384 struct net_device *dev);
385static int corkscrew_rx(struct net_device *dev);
386static void corkscrew_timeout(struct net_device *dev);
387static int boomerang_rx(struct net_device *dev);
388static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
389 struct pt_regs *regs);
390static int corkscrew_close(struct net_device *dev);
391static void update_stats(int addr, struct net_device *dev);
392static struct net_device_stats *corkscrew_get_stats(struct net_device *dev);
393static void set_rx_mode(struct net_device *dev);
394static struct ethtool_ops netdev_ethtool_ops;
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
412
413#ifdef MODULE
414static int debug = -1;
415
416static struct net_device *root_corkscrew_dev;
417
418int init_module(void)
419{
420 int cards_found;
421
422 if (debug >= 0)
423 corkscrew_debug = debug;
424 if (corkscrew_debug)
425 printk(version);
426
427 root_corkscrew_dev = NULL;
428 cards_found = corkscrew_scan(NULL);
429 return cards_found ? 0 : -ENODEV;
430}
431
432#else
433int tc515_probe(struct net_device *dev)
434{
435 int cards_found = 0;
436
437 SET_MODULE_OWNER(dev);
438
439 cards_found = corkscrew_scan(dev);
440
441 if (corkscrew_debug > 0 && cards_found)
442 printk(version);
443
444 return cards_found ? 0 : -ENODEV;
445}
446#endif
447
448static int corkscrew_scan(struct net_device *dev)
449{
450 int cards_found = 0;
451 static int ioaddr;
452#ifdef __ISAPNP__
453 short i;
454 static int pnp_cards;
455#endif
456
457#ifdef __ISAPNP__
458 if(nopnp == 1)
459 goto no_pnp;
460 for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) {
461 struct pnp_dev *idev = NULL;
462 int irq;
463 while((idev = pnp_find_dev(NULL,
464 corkscrew_isapnp_adapters[i].vendor,
465 corkscrew_isapnp_adapters[i].function,
466 idev))) {
467
468 if (pnp_device_attach(idev) < 0)
469 continue;
470 if (pnp_activate_dev(idev) < 0) {
471 printk("pnp activate failed (out of resources?)\n");
472 pnp_device_detach(idev);
473 return -ENOMEM;
474 }
475 if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
476 pnp_device_detach(idev);
477 continue;
478 }
479 ioaddr = pnp_port_start(idev, 0);
480 irq = pnp_irq(idev, 0);
481 if(corkscrew_debug)
482 printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
483 (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
484
485 if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
486 pnp_device_detach(idev);
487 continue;
488 }
489
490 {
491 int timer;
492 outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
493
494 for (timer = 4; timer >= 0; timer--) {
495 udelay(162);
496 if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
497 == 0)
498 break;
499 }
500 if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
501 pnp_device_detach(idev);
502 continue;
503 }
504 }
505 printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
506 inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
507
508 corkscrew_isapnp_phys_addr[pnp_cards] = ioaddr;
509 corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev
510 && dev->mem_start ? dev->
511 mem_start : options[cards_found]);
512 dev = 0;
513 pnp_cards++;
514 cards_found++;
515 }
516 }
517no_pnp:
518#endif
519
520
521 for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
522 int irq;
523#ifdef __ISAPNP__
524
525 if(ioaddr == corkscrew_isapnp_phys_addr[0]) continue;
526 if(ioaddr == corkscrew_isapnp_phys_addr[1]) continue;
527 if(ioaddr == corkscrew_isapnp_phys_addr[2]) continue;
528#endif
529 if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE))
530 continue;
531
532 if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0))
533 continue;
534
535 {
536 int timer;
537 outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
538
539 for (timer = 4; timer >= 0; timer--) {
540 udelay(162);
541 if ((inw(ioaddr + Wn0EepromCmd) & 0x0200)
542 == 0)
543 break;
544 }
545 if (inw(ioaddr + Wn0EepromData) != 0x6d50)
546 continue;
547 }
548 printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
549 inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
550 irq = inw(ioaddr + 0x2002) & 15;
551 corkscrew_found_device(dev, ioaddr, irq, CORKSCREW_ID,
552 dev && dev->mem_start ? dev->mem_start :
553 (cards_found >= MAX_UNITS ? -1 :
554 options[cards_found]));
555 dev = 0;
556 cards_found++;
557 }
558 if (corkscrew_debug)
559 printk(KERN_INFO "%d 3c515 cards found.\n", cards_found);
560 return cards_found;
561}
562
563static struct net_device *corkscrew_found_device(struct net_device *dev,
564 int ioaddr, int irq,
565 int product_index,
566 int options)
567{
568 struct corkscrew_private *vp;
569
570#ifdef MODULE
571
572 int dev_size = sizeof(struct net_device) + sizeof(struct corkscrew_private) + 15;
573
574 dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
575 if (!dev)
576 return NULL;
577 memset(dev, 0, dev_size);
578
579 dev->priv = (void *) (((long) dev + sizeof(struct net_device) + 15) & ~15);
580 vp = (struct corkscrew_private *) dev->priv;
581 dev->base_addr = ioaddr;
582 dev->irq = irq;
583 dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
584 dev->init = corkscrew_probe1;
585 vp->product_name = "3c515";
586 vp->options = options;
587 if (options >= 0) {
588 vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
589 vp->full_duplex = (options & 8) ? 1 : 0;
590 vp->bus_master = (options & 16) ? 1 : 0;
591 } else {
592 vp->media_override = 7;
593 vp->full_duplex = 0;
594 vp->bus_master = 0;
595 }
596 ether_setup(dev);
597 vp->next_module = root_corkscrew_dev;
598 root_corkscrew_dev = dev;
599 SET_MODULE_OWNER(dev);
600 if (register_netdev(dev) != 0) {
601 kfree(dev);
602 return NULL;
603 }
604#else
605
606 dev->priv = kmalloc(sizeof(struct corkscrew_private), GFP_KERNEL);
607 if (!dev->priv)
608 return NULL;
609 memset(dev->priv, 0, sizeof(struct corkscrew_private));
610 dev = init_etherdev(dev, sizeof(struct corkscrew_private));
611 dev->base_addr = ioaddr;
612 dev->irq = irq;
613 dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
614 vp = (struct corkscrew_private *) dev->priv;
615 vp->product_name = "3c515";
616 vp->options = options;
617 if (options >= 0) {
618 vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
619 vp->full_duplex = (options & 8) ? 1 : 0;
620 vp->bus_master = (options & 16) ? 1 : 0;
621 } else {
622 vp->media_override = 7;
623 vp->full_duplex = 0;
624 vp->bus_master = 0;
625 }
626
627 corkscrew_probe1(dev);
628#endif
629 return dev;
630}
631
632static int corkscrew_probe1(struct net_device *dev)
633{
634 int ioaddr = dev->base_addr;
635 struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
636 unsigned int eeprom[0x40], checksum = 0;
637 int i;
638
639 printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
640
641 spin_lock_init(&vp->lock);
642
643
644 EL3WINDOW(0);
645 for (i = 0; i < 0x18; i++) {
646 short *phys_addr = (short *) dev->dev_addr;
647 int timer;
648 outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
649
650 for (timer = 4; timer >= 0; timer--) {
651 udelay(162);
652 if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
653 break;
654 }
655 eeprom[i] = inw(ioaddr + Wn0EepromData);
656 checksum ^= eeprom[i];
657 if (i < 3)
658 phys_addr[i] = htons(eeprom[i]);
659 }
660 checksum = (checksum ^ (checksum >> 8)) & 0xff;
661 if (checksum != 0x00)
662 printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
663 for (i = 0; i < 6; i++)
664 printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
665 if (eeprom[16] == 0x11c7) {
666 if (request_dma(dev->dma, "3c515")) {
667 printk(", DMA %d allocation failed", dev->dma);
668 dev->dma = 0;
669 } else
670 printk(", DMA %d", dev->dma);
671 }
672 printk(", IRQ %d\n", dev->irq);
673
674 if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
675 printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
676
677 {
678 char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
679 union wn3_config config;
680 EL3WINDOW(3);
681 vp->available_media = inw(ioaddr + Wn3_Options);
682 config.i = inl(ioaddr + Wn3_Config);
683 if (corkscrew_debug > 1)
684 printk(KERN_INFO " Internal config register is %4.4x, transceivers %#x.\n",
685 config.i, inw(ioaddr + Wn3_Options));
686 printk(KERN_INFO " %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
687 8 << config.u.ram_size,
688 config.u.ram_width ? "word" : "byte",
689 ram_split[config.u.ram_split],
690 config.u.autoselect ? "autoselect/" : "",
691 media_tbl[config.u.xcvr].name);
692 dev->if_port = config.u.xcvr;
693 vp->default_media = config.u.xcvr;
694 vp->autoselect = config.u.autoselect;
695 }
696 if (vp->media_override != 7) {
697 printk(KERN_INFO " Media override to transceiver type %d (%s).\n",
698 vp->media_override,
699 media_tbl[vp->media_override].name);
700 dev->if_port = vp->media_override;
701 }
702
703 vp->capabilities = eeprom[16];
704 vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0;
705
706
707 vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
708
709
710 request_region(ioaddr, CORKSCREW_TOTAL_SIZE, vp->product_name);
711
712
713 dev->open = &corkscrew_open;
714 dev->hard_start_xmit = &corkscrew_start_xmit;
715 dev->tx_timeout = &corkscrew_timeout;
716 dev->watchdog_timeo = (400 * HZ) / 1000;
717 dev->stop = &corkscrew_close;
718 dev->get_stats = &corkscrew_get_stats;
719 dev->set_multicast_list = &set_rx_mode;
720 dev->ethtool_ops = &netdev_ethtool_ops;
721
722 return 0;
723}
724
725
726static int corkscrew_open(struct net_device *dev)
727{
728 int ioaddr = dev->base_addr;
729 struct corkscrew_private *vp =
730 (struct corkscrew_private *) dev->priv;
731 union wn3_config config;
732 int i;
733
734
735 EL3WINDOW(3);
736 if (vp->full_duplex)
737 outb(0x20, ioaddr + Wn3_MAC_Ctrl);
738 config.i = inl(ioaddr + Wn3_Config);
739
740 if (vp->media_override != 7) {
741 if (corkscrew_debug > 1)
742 printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
743 dev->name, vp->media_override,
744 media_tbl[vp->media_override].name);
745 dev->if_port = vp->media_override;
746 } else if (vp->autoselect) {
747
748 dev->if_port = 4;
749 while (!(vp->available_media & media_tbl[dev->if_port].mask))
750 dev->if_port = media_tbl[dev->if_port].next;
751
752 if (corkscrew_debug > 1)
753 printk("%s: Initial media type %s.\n",
754 dev->name, media_tbl[dev->if_port].name);
755
756 init_timer(&vp->timer);
757 vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
758 vp->timer.data = (unsigned long) dev;
759 vp->timer.function = &corkscrew_timer;
760 add_timer(&vp->timer);
761 } else
762 dev->if_port = vp->default_media;
763
764 config.u.xcvr = dev->if_port;
765 outl(config.i, ioaddr + Wn3_Config);
766
767 if (corkscrew_debug > 1) {
768 printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
769 dev->name, config.i);
770 }
771
772 outw(TxReset, ioaddr + EL3_CMD);
773 for (i = 20; i >= 0; i--)
774 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
775 break;
776
777 outw(RxReset, ioaddr + EL3_CMD);
778
779 for (i = 20; i >= 0; i--)
780 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
781 break;
782
783 outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
784
785
786 if (vp->capabilities == 0x11c7) {
787
788 if (dev->irq == 0
789 || dev->dma == 0
790 || request_irq(dev->irq, &corkscrew_interrupt, 0,
791 vp->product_name, dev)) return -EAGAIN;
792 enable_dma(dev->dma);
793 set_dma_mode(dev->dma, DMA_MODE_CASCADE);
794 } else if (request_irq(dev->irq, &corkscrew_interrupt, SA_SHIRQ,
795 vp->product_name, dev)) {
796 return -EAGAIN;
797 }
798
799 if (corkscrew_debug > 1) {
800 EL3WINDOW(4);
801 printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
802 dev->name, dev->irq, inw(ioaddr + Wn4_Media));
803 }
804
805
806 EL3WINDOW(2);
807 for (i = 0; i < 6; i++)
808 outb(dev->dev_addr[i], ioaddr + i);
809 for (; i < 12; i += 2)
810 outw(0, ioaddr + i);
811
812 if (dev->if_port == 3)
813
814 outw(StartCoax, ioaddr + EL3_CMD);
815 EL3WINDOW(4);
816 outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP | Media_SQE)) |
817 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
818
819
820 outw(StatsDisable, ioaddr + EL3_CMD);
821 EL3WINDOW(6);
822 for (i = 0; i < 10; i++)
823 inb(ioaddr + i);
824 inw(ioaddr + 10);
825 inw(ioaddr + 12);
826
827 EL3WINDOW(4);
828 inb(ioaddr + 12);
829
830 outw(0x0040, ioaddr + Wn4_NetDiag);
831
832
833 EL3WINDOW(7);
834
835 if (vp->full_bus_master_rx) {
836 vp->cur_rx = vp->dirty_rx = 0;
837 if (corkscrew_debug > 2)
838 printk("%s: Filling in the Rx ring.\n",
839 dev->name);
840 for (i = 0; i < RX_RING_SIZE; i++) {
841 struct sk_buff *skb;
842 if (i < (RX_RING_SIZE - 1))
843 vp->rx_ring[i].next =
844 isa_virt_to_bus(&vp->rx_ring[i + 1]);
845 else
846 vp->rx_ring[i].next = 0;
847 vp->rx_ring[i].status = 0;
848 vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
849 skb = dev_alloc_skb(PKT_BUF_SZ);
850 vp->rx_skbuff[i] = skb;
851 if (skb == NULL)
852 break;
853 skb->dev = dev;
854 skb_reserve(skb, 2);
855 vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
856 }
857 vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]);
858 outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
859 }
860 if (vp->full_bus_master_tx) {
861 vp->cur_tx = vp->dirty_tx = 0;
862 outb(PKT_BUF_SZ >> 8, ioaddr + TxFreeThreshold);
863
864 for (i = 0; i < TX_RING_SIZE; i++)
865 vp->tx_skbuff[i] = 0;
866 outl(0, ioaddr + DownListPtr);
867 }
868
869 set_rx_mode(dev);
870 outw(StatsEnable, ioaddr + EL3_CMD);
871
872 netif_start_queue(dev);
873
874 outw(RxEnable, ioaddr + EL3_CMD);
875 outw(TxEnable, ioaddr + EL3_CMD);
876
877 outw(SetStatusEnb | AdapterFailure | IntReq | StatsFull |
878 (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
879 (vp->full_bus_master_rx ? UpComplete : RxComplete) |
880 (vp->bus_master ? DMADone : 0), ioaddr + EL3_CMD);
881
882 outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
883 ioaddr + EL3_CMD);
884 outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
885 | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete,
886 ioaddr + EL3_CMD);
887
888 return 0;
889}
890
891static void corkscrew_timer(unsigned long data)
892{
893#ifdef AUTOMEDIA
894 struct net_device *dev = (struct net_device *) data;
895 struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
896 int ioaddr = dev->base_addr;
897 unsigned long flags;
898 int ok = 0;
899
900 if (corkscrew_debug > 1)
901 printk("%s: Media selection timer tick happened, %s.\n",
902 dev->name, media_tbl[dev->if_port].name);
903
904 spin_lock_irqsave(&vp->lock, flags);
905
906 {
907 int old_window = inw(ioaddr + EL3_CMD) >> 13;
908 int media_status;
909 EL3WINDOW(4);
910 media_status = inw(ioaddr + Wn4_Media);
911 switch (dev->if_port) {
912 case 0:
913 case 4:
914 case 5:
915 if (media_status & Media_LnkBeat) {
916 ok = 1;
917 if (corkscrew_debug > 1)
918 printk("%s: Media %s has link beat, %x.\n",
919 dev->name,
920 media_tbl[dev->if_port].name,
921 media_status);
922 } else if (corkscrew_debug > 1)
923 printk("%s: Media %s is has no link beat, %x.\n",
924 dev->name,
925 media_tbl[dev->if_port].name,
926 media_status);
927
928 break;
929 default:
930 if (corkscrew_debug > 1)
931 printk("%s: Media %s is has no indication, %x.\n",
932 dev->name,
933 media_tbl[dev->if_port].name,
934 media_status);
935 ok = 1;
936 }
937 if (!ok) {
938 union wn3_config config;
939
940 do {
941 dev->if_port =
942 media_tbl[dev->if_port].next;
943 }
944 while (!(vp->available_media & media_tbl[dev->if_port].mask));
945
946 if (dev->if_port == 8) {
947 dev->if_port = vp->default_media;
948 if (corkscrew_debug > 1)
949 printk("%s: Media selection failing, using default %s port.\n",
950 dev->name,
951 media_tbl[dev->if_port].name);
952 } else {
953 if (corkscrew_debug > 1)
954 printk("%s: Media selection failed, now trying %s port.\n",
955 dev->name,
956 media_tbl[dev->if_port].name);
957 vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
958 add_timer(&vp->timer);
959 }
960 outw((media_status & ~(Media_10TP | Media_SQE)) |
961 media_tbl[dev->if_port].media_bits,
962 ioaddr + Wn4_Media);
963
964 EL3WINDOW(3);
965 config.i = inl(ioaddr + Wn3_Config);
966 config.u.xcvr = dev->if_port;
967 outl(config.i, ioaddr + Wn3_Config);
968
969 outw(dev->if_port == 3 ? StartCoax : StopCoax,
970 ioaddr + EL3_CMD);
971 }
972 EL3WINDOW(old_window);
973 }
974
975 spin_unlock_irqrestore(&vp->lock, flags);
976 if (corkscrew_debug > 1)
977 printk("%s: Media selection timer finished, %s.\n",
978 dev->name, media_tbl[dev->if_port].name);
979
980#endif
981 return;
982}
983
984static void corkscrew_timeout(struct net_device *dev)
985{
986 int i;
987 struct corkscrew_private *vp =
988 (struct corkscrew_private *) dev->priv;
989 int ioaddr = dev->base_addr;
990
991 printk(KERN_WARNING
992 "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
993 dev->name, inb(ioaddr + TxStatus),
994 inw(ioaddr + EL3_STATUS));
995
996 if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
997 printk(KERN_WARNING
998 "%s: Transmitter encountered 16 collisions -- network"
999 " network cable problem?\n", dev->name);
1000#ifndef final_version
1001 printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
1002 vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
1003 vp->cur_tx);
1004 printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
1005 &vp->tx_ring[0]);
1006 for (i = 0; i < TX_RING_SIZE; i++) {
1007 printk(" %d: %p length %8.8x status %8.8x\n", i,
1008 &vp->tx_ring[i],
1009 vp->tx_ring[i].length, vp->tx_ring[i].status);
1010 }
1011#endif
1012
1013 outw(TxReset, ioaddr + EL3_CMD);
1014 for (i = 20; i >= 0; i--)
1015 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1016 break;
1017 outw(TxEnable, ioaddr + EL3_CMD);
1018 dev->trans_start = jiffies;
1019 vp->stats.tx_errors++;
1020 vp->stats.tx_dropped++;
1021 netif_wake_queue(dev);
1022}
1023
1024static int corkscrew_start_xmit(struct sk_buff *skb,
1025 struct net_device *dev)
1026{
1027 struct corkscrew_private *vp =
1028 (struct corkscrew_private *) dev->priv;
1029 int ioaddr = dev->base_addr;
1030
1031
1032
1033 netif_stop_queue(dev);
1034
1035 if (vp->full_bus_master_tx) {
1036
1037 int entry = vp->cur_tx % TX_RING_SIZE;
1038 struct boom_tx_desc *prev_entry;
1039 unsigned long flags, i;
1040
1041 if (vp->tx_full)
1042 return 1;
1043 if (vp->cur_tx != 0)
1044 prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
1045 else
1046 prev_entry = NULL;
1047 if (corkscrew_debug > 3)
1048 printk("%s: Trying to send a packet, Tx index %d.\n",
1049 dev->name, vp->cur_tx);
1050
1051 vp->tx_skbuff[entry] = skb;
1052 vp->tx_ring[entry].next = 0;
1053 vp->tx_ring[entry].addr = isa_virt_to_bus(skb->data);
1054 vp->tx_ring[entry].length = skb->len | 0x80000000;
1055 vp->tx_ring[entry].status = skb->len | 0x80000000;
1056
1057 spin_lock_irqsave(&vp->lock, flags);
1058 outw(DownStall, ioaddr + EL3_CMD);
1059
1060 for (i = 20; i >= 0; i--)
1061 if ((inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0)
1062 break;
1063 if (prev_entry)
1064 prev_entry->next = isa_virt_to_bus(&vp->tx_ring[entry]);
1065 if (inl(ioaddr + DownListPtr) == 0) {
1066 outl(isa_virt_to_bus(&vp->tx_ring[entry]),
1067 ioaddr + DownListPtr);
1068 queued_packet++;
1069 }
1070 outw(DownUnstall, ioaddr + EL3_CMD);
1071 spin_unlock_irqrestore(&vp->lock, flags);
1072
1073 vp->cur_tx++;
1074 if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)
1075 vp->tx_full = 1;
1076 else {
1077 if (prev_entry)
1078 prev_entry->status &= ~0x80000000;
1079 netif_wake_queue(dev);
1080 }
1081 dev->trans_start = jiffies;
1082 return 0;
1083 }
1084
1085 outl(skb->len, ioaddr + TX_FIFO);
1086 vp->stats.tx_bytes += skb->len;
1087#ifdef VORTEX_BUS_MASTER
1088 if (vp->bus_master) {
1089
1090 outl((int) (skb->data), ioaddr + Wn7_MasterAddr);
1091 outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
1092 vp->tx_skb = skb;
1093 outw(StartDMADown, ioaddr + EL3_CMD);
1094
1095 } else {
1096
1097 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
1098 dev_kfree_skb(skb);
1099 if (inw(ioaddr + TxFree) > 1536) {
1100 netif_wake_queue(dev);
1101 } else
1102
1103 outw(SetTxThreshold + (1536 >> 2),
1104 ioaddr + EL3_CMD);
1105 }
1106#else
1107
1108 outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
1109 dev_kfree_skb(skb);
1110 if (inw(ioaddr + TxFree) > 1536) {
1111 netif_wake_queue(dev);
1112 } else
1113
1114 outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
1115#endif
1116
1117 dev->trans_start = jiffies;
1118
1119
1120 {
1121 short tx_status;
1122 int i = 4;
1123
1124 while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
1125 if (tx_status & 0x3C) {
1126 if (corkscrew_debug > 2)
1127 printk("%s: Tx error, status %2.2x.\n",
1128 dev->name, tx_status);
1129 if (tx_status & 0x04)
1130 vp->stats.tx_fifo_errors++;
1131 if (tx_status & 0x38)
1132 vp->stats.tx_aborted_errors++;
1133 if (tx_status & 0x30) {
1134 int j;
1135 outw(TxReset, ioaddr + EL3_CMD);
1136 for (j = 20; j >= 0; j--)
1137 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1138 break;
1139 }
1140 outw(TxEnable, ioaddr + EL3_CMD);
1141 }
1142 outb(0x00, ioaddr + TxStatus);
1143 }
1144 }
1145 return 0;
1146}
1147
1148
1149
1150
1151static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
1152 struct pt_regs *regs)
1153{
1154
1155 struct net_device *dev = dev_id;
1156 struct corkscrew_private *lp;
1157 int ioaddr, status;
1158 int latency;
1159 int i = max_interrupt_work;
1160
1161 ioaddr = dev->base_addr;
1162 latency = inb(ioaddr + Timer);
1163 lp = (struct corkscrew_private *) dev->priv;
1164
1165 spin_lock(&lp->lock);
1166
1167 status = inw(ioaddr + EL3_STATUS);
1168
1169 if (corkscrew_debug > 4)
1170 printk("%s: interrupt, status %4.4x, timer %d.\n",
1171 dev->name, status, latency);
1172 if ((status & 0xE000) != 0xE000) {
1173 static int donedidthis;
1174
1175
1176
1177 if (donedidthis++ > 100) {
1178 printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
1179 dev->name, status, netif_running(dev));
1180 free_irq(dev->irq, dev);
1181 dev->irq = -1;
1182 }
1183 }
1184
1185 do {
1186 if (corkscrew_debug > 5)
1187 printk("%s: In interrupt loop, status %4.4x.\n",
1188 dev->name, status);
1189 if (status & RxComplete)
1190 corkscrew_rx(dev);
1191
1192 if (status & TxAvailable) {
1193 if (corkscrew_debug > 5)
1194 printk(" TX room bit was handled.\n");
1195
1196 outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
1197 netif_wake_queue(dev);
1198 }
1199 if (status & DownComplete) {
1200 unsigned int dirty_tx = lp->dirty_tx;
1201
1202 while (lp->cur_tx - dirty_tx > 0) {
1203 int entry = dirty_tx % TX_RING_SIZE;
1204 if (inl(ioaddr + DownListPtr) == isa_virt_to_bus(&lp->tx_ring[entry]))
1205 break;
1206 if (lp->tx_skbuff[entry]) {
1207 dev_kfree_skb_irq(lp->tx_skbuff[entry]);
1208 lp->tx_skbuff[entry] = 0;
1209 }
1210 dirty_tx++;
1211 }
1212 lp->dirty_tx = dirty_tx;
1213 outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
1214 if (lp->tx_full && (lp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
1215 lp->tx_full = 0;
1216 netif_wake_queue(dev);
1217 }
1218 }
1219#ifdef VORTEX_BUS_MASTER
1220 if (status & DMADone) {
1221 outw(0x1000, ioaddr + Wn7_MasterStatus);
1222 dev_kfree_skb_irq(lp->tx_skb);
1223 netif_wake_queue(dev);
1224 }
1225#endif
1226 if (status & UpComplete) {
1227 boomerang_rx(dev);
1228 outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
1229 }
1230 if (status & (AdapterFailure | RxEarly | StatsFull)) {
1231
1232 if (status & RxEarly) {
1233 corkscrew_rx(dev);
1234 outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
1235 }
1236 if (status & StatsFull) {
1237 static int DoneDidThat;
1238 if (corkscrew_debug > 4)
1239 printk("%s: Updating stats.\n", dev->name);
1240 update_stats(ioaddr, dev);
1241
1242
1243 if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
1244 int win, reg;
1245 printk("%s: Updating stats failed, disabling stats as an"
1246 " interrupt source.\n", dev->name);
1247 for (win = 0; win < 8; win++) {
1248 EL3WINDOW(win);
1249 printk("\n Vortex window %d:", win);
1250 for (reg = 0; reg < 16; reg++)
1251 printk(" %2.2x", inb(ioaddr + reg));
1252 }
1253 EL3WINDOW(7);
1254 outw(SetIntrEnb | TxAvailable |
1255 RxComplete | AdapterFailure |
1256 UpComplete | DownComplete |
1257 TxComplete, ioaddr + EL3_CMD);
1258 DoneDidThat++;
1259 }
1260 }
1261 if (status & AdapterFailure) {
1262
1263 outw(RxReset, ioaddr + EL3_CMD);
1264
1265 set_rx_mode(dev);
1266 outw(RxEnable, ioaddr + EL3_CMD);
1267 outw(AckIntr | AdapterFailure,
1268 ioaddr + EL3_CMD);
1269 }
1270 }
1271
1272 if (--i < 0) {
1273 printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x. "
1274 "Disabling functions (%4.4x).\n", dev->name,
1275 status, SetStatusEnb | ((~status) & 0x7FE));
1276
1277 outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
1278 outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
1279 break;
1280 }
1281
1282 outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
1283
1284 } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
1285
1286 spin_unlock(&lp->lock);
1287
1288 if (corkscrew_debug > 4)
1289 printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
1290 return IRQ_HANDLED;
1291}
1292
1293static int corkscrew_rx(struct net_device *dev)
1294{
1295 struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
1296 int ioaddr = dev->base_addr;
1297 int i;
1298 short rx_status;
1299
1300 if (corkscrew_debug > 5)
1301 printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
1302 inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
1303 while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
1304 if (rx_status & 0x4000) {
1305 unsigned char rx_error = inb(ioaddr + RxErrors);
1306 if (corkscrew_debug > 2)
1307 printk(" Rx error: status %2.2x.\n",
1308 rx_error);
1309 vp->stats.rx_errors++;
1310 if (rx_error & 0x01)
1311 vp->stats.rx_over_errors++;
1312 if (rx_error & 0x02)
1313 vp->stats.rx_length_errors++;
1314 if (rx_error & 0x04)
1315 vp->stats.rx_frame_errors++;
1316 if (rx_error & 0x08)
1317 vp->stats.rx_crc_errors++;
1318 if (rx_error & 0x10)
1319 vp->stats.rx_length_errors++;
1320 } else {
1321
1322 short pkt_len = rx_status & 0x1fff;
1323 struct sk_buff *skb;
1324
1325 skb = dev_alloc_skb(pkt_len + 5 + 2);
1326 if (corkscrew_debug > 4)
1327 printk("Receiving packet size %d status %4.4x.\n",
1328 pkt_len, rx_status);
1329 if (skb != NULL) {
1330 skb->dev = dev;
1331 skb_reserve(skb, 2);
1332
1333 insl(ioaddr + RX_FIFO,
1334 skb_put(skb, pkt_len),
1335 (pkt_len + 3) >> 2);
1336 outw(RxDiscard, ioaddr + EL3_CMD);
1337 skb->protocol = eth_type_trans(skb, dev);
1338 netif_rx(skb);
1339 dev->last_rx = jiffies;
1340 vp->stats.rx_packets++;
1341 vp->stats.rx_bytes += pkt_len;
1342
1343 for (i = 200; i >= 0; i--)
1344 if (! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
1345 break;
1346 continue;
1347 } else if (corkscrew_debug)
1348 printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
1349 }
1350 outw(RxDiscard, ioaddr + EL3_CMD);
1351 vp->stats.rx_dropped++;
1352
1353 for (i = 200; i >= 0; i--)
1354 if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
1355 break;
1356 }
1357 return 0;
1358}
1359
1360static int boomerang_rx(struct net_device *dev)
1361{
1362 struct corkscrew_private *vp =
1363 (struct corkscrew_private *) dev->priv;
1364 int entry = vp->cur_rx % RX_RING_SIZE;
1365 int ioaddr = dev->base_addr;
1366 int rx_status;
1367
1368 if (corkscrew_debug > 5)
1369 printk(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
1370 inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
1371 while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
1372 if (rx_status & RxDError) {
1373 unsigned char rx_error = rx_status >> 16;
1374 if (corkscrew_debug > 2)
1375 printk(" Rx error: status %2.2x.\n",
1376 rx_error);
1377 vp->stats.rx_errors++;
1378 if (rx_error & 0x01)
1379 vp->stats.rx_over_errors++;
1380 if (rx_error & 0x02)
1381 vp->stats.rx_length_errors++;
1382 if (rx_error & 0x04)
1383 vp->stats.rx_frame_errors++;
1384 if (rx_error & 0x08)
1385 vp->stats.rx_crc_errors++;
1386 if (rx_error & 0x10)
1387 vp->stats.rx_length_errors++;
1388 } else {
1389
1390 short pkt_len = rx_status & 0x1fff;
1391 struct sk_buff *skb;
1392
1393 vp->stats.rx_bytes += pkt_len;
1394 if (corkscrew_debug > 4)
1395 printk("Receiving packet size %d status %4.4x.\n",
1396 pkt_len, rx_status);
1397
1398
1399
1400 if (pkt_len < rx_copybreak
1401 && (skb = dev_alloc_skb(pkt_len + 4)) != 0) {
1402 skb->dev = dev;
1403 skb_reserve(skb, 2);
1404
1405 memcpy(skb_put(skb, pkt_len),
1406 isa_bus_to_virt(vp->rx_ring[entry].
1407 addr), pkt_len);
1408 rx_copy++;
1409 } else {
1410 void *temp;
1411
1412 skb = vp->rx_skbuff[entry];
1413 vp->rx_skbuff[entry] = NULL;
1414 temp = skb_put(skb, pkt_len);
1415
1416 if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
1417 printk("%s: Warning -- the skbuff addresses do not match"
1418 " in boomerang_rx: %p vs. %p / %p.\n",
1419 dev->name,
1420 isa_bus_to_virt(vp->
1421 rx_ring[entry].
1422 addr), skb->head,
1423 temp);
1424 rx_nocopy++;
1425 }
1426 skb->protocol = eth_type_trans(skb, dev);
1427 netif_rx(skb);
1428 dev->last_rx = jiffies;
1429 vp->stats.rx_packets++;
1430 }
1431 entry = (++vp->cur_rx) % RX_RING_SIZE;
1432 }
1433
1434 for (; vp->cur_rx - vp->dirty_rx > 0; vp->dirty_rx++) {
1435 struct sk_buff *skb;
1436 entry = vp->dirty_rx % RX_RING_SIZE;
1437 if (vp->rx_skbuff[entry] == NULL) {
1438 skb = dev_alloc_skb(PKT_BUF_SZ);
1439 if (skb == NULL)
1440 break;
1441 skb->dev = dev;
1442 skb_reserve(skb, 2);
1443 vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
1444 vp->rx_skbuff[entry] = skb;
1445 }
1446 vp->rx_ring[entry].status = 0;
1447 }
1448 return 0;
1449}
1450
1451static int corkscrew_close(struct net_device *dev)
1452{
1453 struct corkscrew_private *vp =
1454 (struct corkscrew_private *) dev->priv;
1455 int ioaddr = dev->base_addr;
1456 int i;
1457
1458 netif_stop_queue(dev);
1459
1460 if (corkscrew_debug > 1) {
1461 printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
1462 dev->name, inw(ioaddr + EL3_STATUS),
1463 inb(ioaddr + TxStatus));
1464 printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
1465 " tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
1466 queued_packet);
1467 }
1468
1469 del_timer(&vp->timer);
1470
1471
1472 outw(StatsDisable, ioaddr + EL3_CMD);
1473
1474
1475 outw(RxDisable, ioaddr + EL3_CMD);
1476 outw(TxDisable, ioaddr + EL3_CMD);
1477
1478 if (dev->if_port == XCVR_10base2)
1479
1480 outw(StopCoax, ioaddr + EL3_CMD);
1481
1482 free_irq(dev->irq, dev);
1483
1484 outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
1485
1486 update_stats(ioaddr, dev);
1487 if (vp->full_bus_master_rx) {
1488 outl(0, ioaddr + UpListPtr);
1489 for (i = 0; i < RX_RING_SIZE; i++)
1490 if (vp->rx_skbuff[i]) {
1491 dev_kfree_skb(vp->rx_skbuff[i]);
1492 vp->rx_skbuff[i] = 0;
1493 }
1494 }
1495 if (vp->full_bus_master_tx) {
1496 outl(0, ioaddr + DownListPtr);
1497 for (i = 0; i < TX_RING_SIZE; i++)
1498 if (vp->tx_skbuff[i]) {
1499 dev_kfree_skb(vp->tx_skbuff[i]);
1500 vp->tx_skbuff[i] = 0;
1501 }
1502 }
1503
1504 return 0;
1505}
1506
1507static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
1508{
1509 struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
1510 unsigned long flags;
1511
1512 if (netif_running(dev)) {
1513 spin_lock_irqsave(&vp->lock, flags);
1514 update_stats(dev->base_addr, dev);
1515 spin_unlock_irqrestore(&vp->lock, flags);
1516 }
1517 return &vp->stats;
1518}
1519
1520
1521
1522
1523
1524
1525
1526
1527static void update_stats(int ioaddr, struct net_device *dev)
1528{
1529 struct corkscrew_private *vp =
1530 (struct corkscrew_private *) dev->priv;
1531
1532
1533
1534 EL3WINDOW(6);
1535 vp->stats.tx_carrier_errors += inb(ioaddr + 0);
1536 vp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
1537 inb(ioaddr + 2);
1538 vp->stats.collisions += inb(ioaddr + 3);
1539 vp->stats.tx_window_errors += inb(ioaddr + 4);
1540 vp->stats.rx_fifo_errors += inb(ioaddr + 5);
1541 vp->stats.tx_packets += inb(ioaddr + 6);
1542 vp->stats.tx_packets += (inb(ioaddr + 9) & 0x30) << 4;
1543 inb(ioaddr + 7);
1544
1545 inb(ioaddr + 8);
1546
1547
1548
1549 inw(ioaddr + 10);
1550 inw(ioaddr + 12);
1551
1552 EL3WINDOW(4);
1553 inb(ioaddr + 12);
1554
1555
1556 EL3WINDOW(7);
1557 return;
1558}
1559
1560
1561
1562
1563
1564static void set_rx_mode(struct net_device *dev)
1565{
1566 int ioaddr = dev->base_addr;
1567 short new_mode;
1568
1569 if (dev->flags & IFF_PROMISC) {
1570 if (corkscrew_debug > 3)
1571 printk("%s: Setting promiscuous mode.\n",
1572 dev->name);
1573 new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
1574 } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
1575 new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
1576 } else
1577 new_mode = SetRxFilter | RxStation | RxBroadcast;
1578
1579 outw(new_mode, ioaddr + EL3_CMD);
1580}
1581
1582static void netdev_get_drvinfo(struct net_device *dev,
1583 struct ethtool_drvinfo *info)
1584{
1585 strcpy(info->driver, DRV_NAME);
1586 strcpy(info->version, DRV_VERSION);
1587 sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
1588}
1589
1590static u32 netdev_get_msglevel(struct net_device *dev)
1591{
1592 return corkscrew_debug;
1593}
1594
1595static void netdev_set_msglevel(struct net_device *dev, u32 level)
1596{
1597 corkscrew_debug = level;
1598}
1599
1600static struct ethtool_ops netdev_ethtool_ops = {
1601 .get_drvinfo = netdev_get_drvinfo,
1602 .get_msglevel = netdev_get_msglevel,
1603 .set_msglevel = netdev_set_msglevel,
1604};
1605
1606
1607#ifdef MODULE
1608void cleanup_module(void)
1609{
1610 struct net_device *next_dev;
1611
1612 while (root_corkscrew_dev) {
1613 next_dev =
1614 ((struct corkscrew_private *) root_corkscrew_dev->
1615 priv)->next_module;
1616 if (root_corkscrew_dev->dma)
1617 free_dma(root_corkscrew_dev->dma);
1618 unregister_netdev(root_corkscrew_dev);
1619 outw(TotalReset, root_corkscrew_dev->base_addr + EL3_CMD);
1620 release_region(root_corkscrew_dev->base_addr,
1621 CORKSCREW_TOTAL_SIZE);
1622 free_netdev(root_corkscrew_dev);
1623 root_corkscrew_dev = next_dev;
1624 }
1625}
1626#endif
1627
1628
1629
1630
1631
1632
1633
1634
1635