OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [yellowfin.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* yellowfin.c: A Packet Engines G-NIC ethernet driver for linux. */
2
/*
3
        Written 1997-1998 by Donald Becker.
4
 
5
        This software may be used and distributed according to the terms
6
        of the GNU Public License, incorporated herein by reference.
7
 
8
        This driver is for the Packet Engines G-NIC PCI Gigabit Ethernet adapter.
9
        It also supports the Symbios Logic version of the same chip core.
10
 
11
        The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
12
        Center of Excellence in Space Data and Information Sciences
13
           Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
14
 
15
        Support and updates available at
16
        http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html
17
*/
18
 
19
static const char *version = "yellowfin.c:v0.99A 4/7/98 becker@cesdis.gsfc.nasa.gov\n";
20
 
21
/* A few user-configurable values. */
22
 
23
static int max_interrupt_work = 20;
24
static int min_pci_latency = 64;
25
static int mtu = 0;
26
#ifdef YF_PROTOTYPE                     /* Support for prototype hardware errata. */
27
/* System-wide count of bogus-rx frames. */
28
static int bogus_rx = 0;
29
static int dma_ctrl = 0x004A0263;                       /* Constrained by errata */
30
static int fifo_cfg = 0x0020;                           /* Bypass external Tx FIFO. */
31
#elif YF_NEW                                    /* A future perfect board :->.  */
32
static int dma_ctrl = 0x00CAC277;                       /* Override when loading module! */
33
static int fifo_cfg = 0x0028;
34
#else
35
static int dma_ctrl = 0x004A0263;                       /* Constrained by errata */
36
static int fifo_cfg = 0x0020;                           /* Bypass external Tx FIFO. */
37
#endif
38
 
39
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
40
   Setting to > 1518 effectively disables this feature. */
41
static const int rx_copybreak = 100;
42
 
43
/* Keep the ring sizes a power of two for efficiency.
44
   Making the Tx ring too large decreases the effectiveness of channel
45
   bonding and packet priority.
46
   There are no ill effects from too-large receive rings. */
47
#define TX_RING_SIZE    16
48
#define RX_RING_SIZE    32
49
 
50
/* Operational parameters that usually are not changed. */
51
/* Time in jiffies before concluding the transmitter is hung. */
52
#define TX_TIMEOUT  ((2000*HZ)/1000)
53
 
54
#include <linux/config.h>
55
#ifdef MODULE
56
#ifdef MODVERSIONS
57
#include <linux/modversions.h>
58
#endif
59
#include <linux/module.h>
60
#include <linux/version.h>
61
#else
62
#define MOD_INC_USE_COUNT
63
#define MOD_DEC_USE_COUNT
64
#endif
65
 
66
#include <linux/kernel.h>
67
#include <linux/sched.h>
68
#include <linux/string.h>
69
#include <linux/timer.h>
70
#include <linux/ptrace.h>
71
#include <linux/errno.h>
72
#include <linux/ioport.h>
73
#include <linux/malloc.h>
74
#include <linux/interrupt.h>
75
#include <linux/pci.h>
76
#include <linux/bios32.h>
77
#include <asm/processor.h>              /* Processor type for cache alignment. */
78
#include <asm/bitops.h>
79
#include <asm/io.h>
80
 
81
#include <linux/netdevice.h>
82
#include <linux/etherdevice.h>
83
#include <linux/skbuff.h>
84
 
85
/* Kernel compatibility defines, common to David Hind's PCMCIA package.
86
   This is only in the support-all-kernels source code. */
87
#include <linux/version.h>              /* Evil, but neccessary */
88
 
89
#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10300
90
#define RUN_AT(x) (x)                   /* What to put in timer->expires.  */
91
#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC)
92
#define virt_to_bus(addr)  ((unsigned long)addr)
93
#define bus_to_virt(addr) ((void*)addr)
94
 
95
#else  /* 1.3.0 and later */
96
#define RUN_AT(x) (jiffies + (x))
97
#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
98
#endif
99
 
100
#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10338
101
#ifdef MODULE
102
#if !defined(CONFIG_MODVERSIONS) && !defined(__NO_VERSION__)
103
char kernel_version[] = UTS_RELEASE;
104
#endif
105
#else
106
#undef MOD_INC_USE_COUNT
107
#define MOD_INC_USE_COUNT
108
#undef MOD_DEC_USE_COUNT
109
#define MOD_DEC_USE_COUNT
110
#endif
111
#endif /* 1.3.38 */
112
 
113
#if (LINUX_VERSION_CODE >= 0x10344)
114
#define NEW_MULTICAST
115
#include <linux/delay.h>
116
#endif
117
#if (LINUX_VERSION_CODE >= 0x20100)
118
char kernel_version[] = UTS_RELEASE;
119
#endif
120
#ifdef SA_SHIRQ
121
#define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs)
122
#else
123
#define IRQ(irq, dev_id, pt_regs) (irq, pt_regs)
124
#endif
125
#if (LINUX_VERSION_CODE < 0x20123)
126
#define test_and_set_bit(val, addr) set_bit(val, addr)
127
#endif
128
 
129
static const char *card_name = "Yellowfin G-NIC Gbit Ethernet";
130
 
131
/* The PCI I/O space extent. */
132
#define YELLOWFIN_TOTAL_SIZE 0x100
133
 
134
#ifdef HAVE_DEVLIST
135
struct netdev_entry yellowfin_drv =
136
{card_name, yellowfin_pci_probe, YELLOWFIN_TOTAL_SIZE, NULL};
137
#endif
138
 
139
#ifdef YELLOWFIN_DEBUG
140
int yellowfin_debug = YELLOWFIN_DEBUG;
141
#else
142
int yellowfin_debug = 1;
143
#endif
144
 
145
/*
146
                                Theory of Operation
147
 
148
I. Board Compatibility
149
 
150
This device driver is designed for the Packet Engines "Yellowfin" Gigabit
151
Ethernet adapter.  The only PCA currently supported is the G-NIC 64-bit
152
PCI card.
153
 
154
II. Board-specific settings
155
 
156
PCI bus devices are configured by the system at boot time, so no jumpers
157
need to be set on the board.  The system BIOS preferably should assign the
158
PCI INTA signal to an otherwise unused system IRQ line.
159
Note: Kernel versions earlier than 1.3.73 do not support shared PCI
160
interrupt lines.
161
 
162
III. Driver operation
163
 
164
IIIa. Ring buffers
165
 
166
The Yellowfin uses the Descriptor Based DMA Architecture specified by Apple.
167
This is a descriptor list scheme similar to that used by the EEPro100 and
168
Tulip.  This driver uses two statically allocated fixed-size descriptor lists
169
formed into rings by a branch from the final descriptor to the beginning of
170
the list.  The ring sizes are set at compile time by RX/TX_RING_SIZE.
171
 
172
The driver allocates full frame size skbuffs for the Rx ring buffers at
173
open() time and passes the skb->data field to the Yellowfin as receive data
174
buffers.  When an incoming frame is less than RX_COPYBREAK bytes long,
175
a fresh skbuff is allocated and the frame is copied to the new skbuff.
176
When the incoming frame is larger, the skbuff is passed directly up the
177
protocol stack and replaced by a newly allocated skbuff.
178
 
179
The RX_COPYBREAK value is chosen to trade-off the memory wasted by
180
using a full-sized skbuff for small frames vs. the copying costs of larger
181
frames.  For small frames the copying cost is negligible (esp. considering
182
that we are pre-loading the cache with immediately useful header
183
information).  For large frames the copying cost is non-trivial, and the
184
larger copy might flush the cache of useful data.
185
 
186
IIIC. Synchronization
187
 
188
The driver runs as two independent, single-threaded flows of control.  One
189
is the send-packet routine, which enforces single-threaded use by the
190
dev->tbusy flag.  The other thread is the interrupt handler, which is single
191
threaded by the hardware and other software.
192
 
193
The send packet thread has partial control over the Tx ring and 'dev->tbusy'
194
flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
195
queue slot is empty, it clears the tbusy flag when finished otherwise it sets
196
the 'yp->tx_full' flag.
197
 
198
The interrupt handler has exclusive control over the Rx ring and records stats
199
from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
200
empty by incrementing the dirty_tx mark. Iff the 'yp->tx_full' flag is set, it
201
clears both the tx_full and tbusy flags.
202
 
203
IV. Notes
204
 
205
Thanks to Kim Stearns of Packet Engines for providing a pair of G-NIC boards.
206
 
207
IVb. References
208
 
209
Yellowfin Engineering Design Specification, 4/23/97 Preliminary/Confidential
210
http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
211
 
212
IVc. Errata
213
 
214
See Packet Engines confidential appendix.
215
 
216
*/
217
 
218
/* A few values that may be tweaked. */
219
#define PKT_BUF_SZ              1536                    /* Size of each temporary Rx buffer.*/
220
 
221
#ifndef PCI_VENDOR_ID_PKT_ENG           /* To be defined in linux/pci.h */
222
#define PCI_VENDOR_ID_PKT_ENG                   0x1000 /* Hmm, likely number.. */
223
#define PCI_DEVICE_ID_YELLOWFIN                 0x0702
224
#endif
225
 
226
/* The rest of these values should never change. */
227
 
228
static void yellowfin_timer(unsigned long data);
229
 
230
/* Offsets to the Yellowfin registers.  Various sizes and alignments. */
231
enum yellowfin_offsets {
232
        TxCtrl=0x00, TxStatus=0x04, TxPtr=0x0C,
233
        TxIntrSel=0x10, TxBranchSel=0x14, TxWaitSel=0x18,
234
        RxCtrl=0x40, RxStatus=0x44, RxPtr=0x4C,
235
        RxIntrSel=0x50, RxBranchSel=0x54, RxWaitSel=0x58,
236
        EventStatus=0x80, IntrEnb=0x82, IntrClear=0x84, IntrStatus=0x86,
237
        ChipRev=0x8C, DMACtrl=0x90, Cnfg=0xA0, RxDepth=0xB8, FlowCtrl=0xBC,
238
        AddrMode=0xD0, StnAddr=0xD2, HashTbl=0xD8, FIFOcfg=0xF8,
239
};
240
 
241
/* The Yellowfin Rx and Tx buffer descriptors. */
242
struct yellowfin_desc {
243
        u16 request_cnt;
244
        u16 cmd;
245
        u32 addr;
246
        u32 branch_addr;
247
        u16 result_cnt;
248
        u16 status;
249
};
250
 
251
struct tx_status_words {
252
        u16 tx_cnt;
253
        u16 tx_errs;
254
        u16 total_tx_cnt;
255
        u16 paused;
256
};
257
 
258
/* Bits in yellowfin_desc.cmd */
259
enum desc_cmd_bits {
260
        CMD_TX_PKT=0x1000, CMD_RX_BUF=0x2000, CMD_TXSTATUS=0x3000,
261
        CMD_NOP=0x6000, CMD_STOP=0x7000,
262
        BRANCH_ALWAYS=0x0C, INTR_ALWAYS=0x30, WAIT_ALWAYS=0x03,
263
        BRANCH_IFTRUE=0x04,
264
};
265
 
266
/* Bits in yellowfin_desc.status */
267
enum desc_status_bits { RX_EOP=0x0040, };
268
 
269
/* Bits in the interrupt status/mask registers. */
270
enum intr_status_bits {
271
        IntrRxDone=0x01, IntrRxInvalid=0x02, IntrRxPCIFault=0x04,IntrRxPCIErr=0x08,
272
        IntrTxDone=0x10, IntrTxInvalid=0x20, IntrTxPCIFault=0x40,IntrTxPCIErr=0x80,
273
        IntrEarlyRx=0x100, IntrWakeup=0x200, };
274
 
275
struct yellowfin_private {
276
        /* Descriptor rings first for alignment.  Tx requires a second descriptor
277
           for status. */
278
        struct yellowfin_desc rx_ring[RX_RING_SIZE];
279
        struct yellowfin_desc tx_ring[TX_RING_SIZE*2];
280
        const char *product_name;
281
        struct device *next_module;
282
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
283
        struct sk_buff* tx_skbuff[TX_RING_SIZE];
284
        struct tx_status_words tx_status[TX_RING_SIZE];
285
        /* The addresses of receive-in-place skbuffs. */
286
        struct sk_buff* rx_skbuff[RX_RING_SIZE];
287
        int chip_id;
288
        struct enet_statistics stats;
289
        struct timer_list timer;        /* Media selection timer. */
290
        int in_interrupt;
291
        unsigned int cur_rx, cur_tx;            /* The next free ring entry */
292
        unsigned int dirty_rx, dirty_tx;        /* The ring entries to be free()ed. */
293
        unsigned int tx_full:1;                         /* The Tx queue is full. */
294
        unsigned int full_duplex:1;                     /* Full-duplex operation requested. */
295
        unsigned int medialock:1;                       /* Do not sense media. */
296
        unsigned int default_port:4;            /* Last dev->if_port value. */
297
        u32 pad[4];                                                     /* Used for 32-byte alignment */
298
};
299
 
300
#ifdef MODULE
301
/* Used to pass the media type, etc. */
302
#define MAX_UNITS 8                             /* More are supported, limit only on options */
303
static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
304
 
305
#if LINUX_VERSION_CODE > 0x20115
306
MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
307
MODULE_DESCRIPTION("Packet Engines Yellowfin G-NIC Gigabit Ethernet driver");
308
MODULE_PARM(max_interrupt_work, "i");
309
MODULE_PARM(min_pci_latency, "i");
310
MODULE_PARM(mtu, "i");
311
MODULE_PARM(debug, "i");
312
MODULE_PARM(rx_copybreak, "i");
313
MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
314
#endif
315
 
316
#endif
317
 
318
static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq,
319
                                                                   int chip_id, int options);
320
static int yellowfin_open(struct device *dev);
321
static void yellowfin_timer(unsigned long data);
322
static void yellowfin_tx_timeout(struct device *dev);
323
static void yellowfin_init_ring(struct device *dev);
324
static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev);
325
static int yellowfin_rx(struct device *dev);
326
static void yellowfin_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs);
327
static int yellowfin_close(struct device *dev);
328
static struct enet_statistics *yellowfin_get_stats(struct device *dev);
329
#ifdef NEW_MULTICAST
330
static void set_rx_mode(struct device *dev);
331
#else
332
static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
333
#endif
334
 
335
 
336
 
337
#ifdef MODULE
338
/* A list of all installed Yellowfin devices, for removing the driver module. */
339
static struct device *root_yellowfin_dev = NULL;
340
#endif
341
 
342
int yellowfin_probe(struct device *dev)
343
{
344
        int cards_found = 0;
345
        static int pci_index = 0;        /* Static, for multiple probe calls. */
346
 
347
        /* Ideally we would detect all network cards in slot order.  That would
348
           be best done a central PCI probe dispatch, which wouldn't work
349
           well with the current structure.  So instead we detect just the
350
           Yellowfin cards in slot order. */
351
 
352
        if (pcibios_present()) {
353
                unsigned char pci_bus, pci_device_fn;
354
 
355
                for (;pci_index < 0xff; pci_index++) {
356
                        u8 pci_irq_line, pci_latency;
357
                        u16 pci_command, vendor, device;
358
                        u32 pci_ioaddr, chip_idx = 0;
359
 
360
#ifdef REVERSE_PROBE_ORDER
361
                        if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
362
                                                                        0xfe - pci_index,
363
                                                                        &pci_bus, &pci_device_fn)
364
                                != PCIBIOS_SUCCESSFUL)
365
                                continue;
366
#else
367
                        if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
368
                                                                        pci_index,
369
                                                                        &pci_bus, &pci_device_fn)
370
                                != PCIBIOS_SUCCESSFUL)
371
                                break;
372
#endif
373
                        pcibios_read_config_word(pci_bus, pci_device_fn,
374
                                                                         PCI_VENDOR_ID, &vendor);
375
                        pcibios_read_config_word(pci_bus, pci_device_fn,
376
                                                                         PCI_DEVICE_ID, &device);
377
                        pcibios_read_config_byte(pci_bus, pci_device_fn,
378
                                                                         PCI_INTERRUPT_LINE, &pci_irq_line);
379
                        pcibios_read_config_dword(pci_bus, pci_device_fn,
380
                                                                          PCI_BASE_ADDRESS_0, &pci_ioaddr);
381
                        /* Remove I/O space marker in bit 0. */
382
                        pci_ioaddr &= ~3;
383
 
384
                        if (vendor != PCI_VENDOR_ID_PKT_ENG)
385
                                continue;
386
 
387
                        if (device != PCI_DEVICE_ID_YELLOWFIN)
388
                                continue;
389
 
390
                        if (yellowfin_debug > 2)
391
                                printk("Found Packet Engines Yellowfin G-NIC at I/O %#x, IRQ %d.\n",
392
                                           pci_ioaddr, pci_irq_line);
393
 
394
                        if (check_region(pci_ioaddr, YELLOWFIN_TOTAL_SIZE))
395
                                continue;
396
 
397
#ifdef MODULE
398
                        dev = yellowfin_probe1(dev, pci_ioaddr, pci_irq_line, chip_idx,
399
                                                 cards_found < MAX_UNITS ? options[cards_found] : 0);
400
#else
401
                        dev = yellowfin_probe1(dev, pci_ioaddr, pci_irq_line, chip_idx,
402
                                                 dev ? dev->mem_start : 0);
403
#endif
404
 
405
                        if (dev) {
406
                          /* Get and check the bus-master and latency values. */
407
                          pcibios_read_config_word(pci_bus, pci_device_fn,
408
                                                                           PCI_COMMAND, &pci_command);
409
                          if ( ! (pci_command & PCI_COMMAND_MASTER)) {
410
                                printk("  PCI Master Bit has not been set! Setting...\n");
411
                                pci_command |= PCI_COMMAND_MASTER;
412
                                pcibios_write_config_word(pci_bus, pci_device_fn,
413
                                                                                  PCI_COMMAND, pci_command);
414
                          }
415
                          pcibios_read_config_byte(pci_bus, pci_device_fn,
416
                                                                           PCI_LATENCY_TIMER, &pci_latency);
417
                          if (pci_latency < min_pci_latency) {
418
                                printk("  PCI latency timer (CFLT) is unreasonably low at %d."
419
                                           "  Setting to %d clocks.\n",
420
                                           pci_latency, min_pci_latency);
421
                                pcibios_write_config_byte(pci_bus, pci_device_fn,
422
                                                                                  PCI_LATENCY_TIMER, min_pci_latency);
423
                          } else if (yellowfin_debug > 1)
424
                                printk("  PCI latency timer (CFLT) is %#x.\n", pci_latency);
425
                          dev = 0;
426
                          cards_found++;
427
                        }
428
                }
429
        }
430
 
431
#if defined (MODULE)
432
        return cards_found;
433
#else
434
        return 0;
435
#endif
436
}
437
 
438
static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq,
439
                                                                   int chip_id, int options)
440
{
441
        static int did_version = 0;                      /* Already printed version info. */
442
        struct yellowfin_private *yp;
443
        int i;
444
 
445
        if (yellowfin_debug > 0  &&  did_version++ == 0)
446
                printk(version);
447
 
448
        dev = init_etherdev(dev, sizeof(struct yellowfin_private));
449
 
450
        printk("%s: P-E Yellowfin type %8x at %#3x, ",
451
                   dev->name, inl(ioaddr + ChipRev), ioaddr);
452
 
453
        for (i = 0; i < 5; i++)
454
                printk("%2.2x:", inb(ioaddr + StnAddr + i));
455
        printk("%2.2x, IRQ %d.\n", inb(ioaddr + StnAddr + i), irq);
456
        for (i = 0; i < 6; i++)
457
                dev->dev_addr[i] = inb(ioaddr + StnAddr + i);
458
 
459
        /* Reset the chip. */
460
        outl(0x80000000, ioaddr + DMACtrl);
461
 
462
 
463
        /* We do a request_region() only to register /proc/ioports info. */
464
        request_region(ioaddr, YELLOWFIN_TOTAL_SIZE, card_name);
465
 
466
        dev->base_addr = ioaddr;
467
        dev->irq = irq;
468
 
469
        /* Make certain the descriptor lists are aligned. */
470
        yp = (void *)(((long)kmalloc(sizeof(*yp), GFP_KERNEL) + 31) & ~31);
471
        memset(yp, 0, sizeof(*yp));
472
        dev->priv = yp;
473
 
474
#ifdef MODULE
475
        yp->next_module = root_yellowfin_dev;
476
        root_yellowfin_dev = dev;
477
#endif
478
 
479
        yp->chip_id = chip_id;
480
 
481
        yp->full_duplex = 1;
482
#ifdef YELLOWFIN_DEFAULT_MEDIA
483
        yp->default_port = YELLOWFIN_DEFAULT_MEDIA;
484
#endif
485
#ifdef YELLOWFIN_NO_MEDIA_SWITCH
486
        yp->medialock = 1;
487
#endif
488
 
489
        /* The lower four bits are the media type. */
490
        if (options > 0) {
491
                yp->full_duplex = (options & 16) ? 1 : 0;
492
                yp->default_port = options & 15;
493
                if (yp->default_port)
494
                        yp->medialock = 1;
495
        }
496
 
497
        /* The Yellowfin-specific entries in the device structure. */
498
        dev->open = &yellowfin_open;
499
        dev->hard_start_xmit = &yellowfin_start_xmit;
500
        dev->stop = &yellowfin_close;
501
        dev->get_stats = &yellowfin_get_stats;
502
        dev->set_multicast_list = &set_rx_mode;
503
        if (mtu)
504
                dev->mtu = mtu;
505
 
506
        /* todo: Reset the xcvr interface and turn on heartbeat. */
507
 
508
        return dev;
509
}
510
 
511
 
512
static int
513
yellowfin_open(struct device *dev)
514
{
515
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
516
        int ioaddr = dev->base_addr;
517
 
518
        /* Reset the chip. */
519
        outl(0x80000000, ioaddr + DMACtrl);
520
 
521
#ifdef SA_SHIRQ
522
        if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ,
523
                                        card_name, dev)) {
524
                return -EAGAIN;
525
        }
526
#else
527
        if (irq2dev_map[dev->irq] != NULL
528
                || (irq2dev_map[dev->irq] = dev) == NULL
529
                || dev->irq == 0
530
                || request_irq(dev->irq, &yellowfin_interrupt, 0, card_name)) {
531
                return -EAGAIN;
532
        }
533
#endif
534
 
535
        if (yellowfin_debug > 1)
536
                printk("%s: yellowfin_open() irq %d.\n", dev->name, dev->irq);
537
 
538
        MOD_INC_USE_COUNT;
539
 
540
        yellowfin_init_ring(dev);
541
 
542
        outl(virt_to_bus(yp->rx_ring), ioaddr + RxPtr);
543
        outl(virt_to_bus(yp->tx_ring), ioaddr + TxPtr);
544
 
545
        /* Set up various condition 'select' registers.
546
           There are no options here. */
547
        outl(0x00800080, ioaddr + TxIntrSel);   /* Interrupt on Tx abort */
548
        outl(0x00800080, ioaddr + TxBranchSel); /* Branch on Tx abort */
549
        outl(0x00400040, ioaddr + TxWaitSel);   /* Wait on Tx status */
550
        outl(0x00400040, ioaddr + RxIntrSel);   /* Interrupt on Rx done */
551
        outl(0x00400040, ioaddr + RxBranchSel); /* Branch on Rx error */
552
        outl(0x00400040, ioaddr + RxWaitSel);   /* Wait on Rx done */
553
 
554
        /* Initialize other registers: with so many this eventually this will
555
           converted to an offset/value list. */
556
        outl(dma_ctrl, ioaddr + DMACtrl);
557
        outw(fifo_cfg, ioaddr + FIFOcfg);
558
        /* Enable automatic generation of flow control frames, period 0xffff. */
559
        outl(0x0030FFFF, ioaddr + FlowCtrl);
560
 
561
        if (dev->if_port == 0)
562
                dev->if_port = yp->default_port;
563
 
564
        dev->tbusy = 0;
565
        dev->interrupt = 0;
566
        yp->in_interrupt = 0;
567
 
568
        /* We are always in full-duplex mode with the current chip! */
569
        yp->full_duplex = 1;
570
 
571
        /* Setting the Rx mode will start the Rx process. */
572
        outw(0x01CD | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
573
#ifdef NEW_MULTICAST
574
        set_rx_mode(dev);
575
#else
576
        set_rx_mode(dev, 0, 0);
577
#endif
578
 
579
        dev->start = 1;
580
 
581
        /* Enable interrupts by setting the interrupt mask. */
582
        outw(0x81ff, ioaddr + IntrEnb);                 /* See enum intr_status_bits */
583
        outw(0x0000, ioaddr + EventStatus);             /* Clear non-interrupting events */
584
        outl(0x80008000, ioaddr + RxCtrl);              /* Start Rx and Tx channels. */
585
        outl(0x80008000, ioaddr + TxCtrl);
586
 
587
        if (yellowfin_debug > 2) {
588
                printk("%s: Done yellowfin_open().\n",
589
                           dev->name);
590
        }
591
        /* Set the timer to check for link beat. */
592
        init_timer(&yp->timer);
593
        yp->timer.expires = RUN_AT((24*HZ)/10);                 /* 2.4 sec. */
594
        yp->timer.data = (unsigned long)dev;
595
        yp->timer.function = &yellowfin_timer;                          /* timer handler */
596
        add_timer(&yp->timer);
597
 
598
        return 0;
599
}
600
 
601
static void yellowfin_timer(unsigned long data)
602
{
603
        struct device *dev = (struct device *)data;
604
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
605
        int ioaddr = dev->base_addr;
606
        int next_tick = 0;
607
 
608
        if (yellowfin_debug > 3) {
609
                printk("%s: Yellowfin timer tick, status %8.8x.\n",
610
                           dev->name, inl(ioaddr + IntrStatus));
611
        }
612
        if (next_tick) {
613
                yp->timer.expires = RUN_AT(next_tick);
614
                add_timer(&yp->timer);
615
        }
616
}
617
 
618
static void yellowfin_tx_timeout(struct device *dev)
619
{
620
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
621
        int ioaddr = dev->base_addr;
622
 
623
        printk("%s: Yellowfin transmit timed out, status %8.8x, resetting...\n",
624
                   dev->name, inl(ioaddr));
625
 
626
#ifndef __alpha__
627
        {
628
                int i;
629
                printk("  Rx ring %8.8x: ", (int)yp->rx_ring);
630
                for (i = 0; i < RX_RING_SIZE; i++)
631
                        printk(" %8.8x", (unsigned int)yp->rx_ring[i].status);
632
                printk("\n  Tx ring %8.8x: ", (int)yp->tx_ring);
633
                for (i = 0; i < TX_RING_SIZE; i++)
634
                        printk(" %4.4x /%4.4x", yp->tx_status[i].tx_errs, yp->tx_ring[i].status);
635
                printk("\n");
636
        }
637
#endif
638
 
639
  /* Perhaps we should reinitialize the hardware here. */
640
  dev->if_port = 0;
641
  /* Stop and restart the chip's Tx processes . */
642
 
643
  /* Trigger an immediate transmit demand. */
644
 
645
  dev->trans_start = jiffies;
646
  yp->stats.tx_errors++;
647
  return;
648
}
649
 
650
 
651
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
652
static void
653
yellowfin_init_ring(struct device *dev)
654
{
655
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
656
        int i;
657
 
658
        yp->tx_full = 0;
659
        yp->cur_rx = yp->cur_tx = 0;
660
        yp->dirty_rx = yp->dirty_tx = 0;
661
 
662
        for (i = 0; i < RX_RING_SIZE; i++) {
663
                struct sk_buff *skb;
664
                int pkt_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
665
 
666
                yp->rx_ring[i].request_cnt = pkt_buf_sz;
667
                yp->rx_ring[i].cmd = CMD_RX_BUF | INTR_ALWAYS;
668
 
669
                skb = DEV_ALLOC_SKB(pkt_buf_sz);
670
                skb_reserve(skb, 2);    /* 16 byte align the IP header. */
671
                yp->rx_skbuff[i] = skb;
672
                if (skb == NULL)
673
                        break;                  /* Bad news!  */
674
                skb->dev = dev;                 /* Mark as being used by this device. */
675
#if LINUX_VERSION_CODE > 0x10300
676
                yp->rx_ring[i].addr = virt_to_bus(skb->tail);
677
#else
678
                yp->rx_ring[i].addr = virt_to_bus(skb->data);
679
#endif
680
                yp->rx_ring[i].branch_addr = virt_to_bus(&yp->rx_ring[i+1]);
681
        }
682
        /* Mark the last entry as wrapping the ring. */
683
        yp->rx_ring[i-1].cmd = CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS;
684
        yp->rx_ring[i-1].branch_addr = virt_to_bus(&yp->rx_ring[0]);
685
 
686
/*#define NO_TXSTATS*/
687
#ifdef NO_TXSTATS
688
        /* In this mode the Tx ring needs only a single descriptor. */
689
        for (i = 0; i < TX_RING_SIZE; i++) {
690
                yp->tx_skbuff[i] = 0;
691
                yp->tx_ring[i].cmd = CMD_STOP;
692
                yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]);
693
        }
694
        yp->tx_ring[--i].cmd = CMD_STOP | BRANCH_ALWAYS; /* Wrap ring */
695
        yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[0]);
696
#else
697
        /* Tx ring needs a pair of descriptors, the second for the status. */
698
        for (i = 0; i < TX_RING_SIZE*2; i++) {
699
                yp->tx_skbuff[i/2] = 0;
700
                yp->tx_ring[i].cmd = CMD_STOP; /* Branch on Tx error. */
701
                yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]);
702
                i++;
703
                yp->tx_ring[i].cmd = CMD_TXSTATUS; /* Interrupt, no wait. */
704
                yp->tx_ring[i].request_cnt = sizeof(yp->tx_status[i]);
705
                yp->tx_ring[i].addr = virt_to_bus(&yp->tx_status[i/2]);
706
                yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]);
707
        }
708
        /* Wrap ring */
709
        yp->tx_ring[--i].cmd = CMD_TXSTATUS | BRANCH_ALWAYS | INTR_ALWAYS;
710
        yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[0]);
711
#endif
712
}
713
 
714
static int
715
yellowfin_start_xmit(struct sk_buff *skb, struct device *dev)
716
{
717
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
718
        unsigned entry;
719
 
720
        /* Block a timer-based transmit from overlapping.  This could better be
721
           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
722
        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
723
                if (jiffies - dev->trans_start < TX_TIMEOUT)
724
                        return 1;
725
                yellowfin_tx_timeout(dev);
726
                return 1;
727
        }
728
 
729
        /* Caution: the write order is important here, set the base address
730
           with the "ownership" bits last. */
731
 
732
        /* Calculate the next Tx descriptor entry. */
733
        entry = yp->cur_tx % TX_RING_SIZE;
734
 
735
        yp->tx_skbuff[entry] = skb;
736
 
737
#ifdef NO_TXSTATS
738
        yp->tx_ring[entry].request_cnt = skb->len;
739
        yp->tx_ring[entry].addr = virt_to_bus(skb->data);
740
        yp->tx_ring[entry].status = 0;
741
        if (entry >= TX_RING_SIZE-1) {
742
                yp->tx_ring[0].cmd = CMD_STOP; /* New stop command. */
743
                yp->tx_ring[TX_RING_SIZE-1].cmd = CMD_TX_PKT | BRANCH_ALWAYS;
744
        } else {
745
                yp->tx_ring[entry+1].cmd = CMD_STOP; /* New stop command. */
746
                yp->tx_ring[entry].cmd = CMD_TX_PKT | BRANCH_IFTRUE;
747
        }
748
        yp->cur_tx++;
749
#else
750
        yp->tx_ring[entry<<1].request_cnt = skb->len;
751
        yp->tx_ring[entry<<1].addr = virt_to_bus(skb->data);
752
        /* The input_last (status-write) command is constant, but we must rewrite
753
           the subsequent 'stop' command. */
754
 
755
        yp->cur_tx++;
756
        {
757
                unsigned next_entry = yp->cur_tx % TX_RING_SIZE;
758
                yp->tx_ring[next_entry<<1].cmd = CMD_STOP;
759
        }
760
        /* Final step -- overwrite the old 'stop' command. */
761
 
762
        yp->tx_ring[entry<<1].cmd =
763
                (entry % 6) == 0 ? CMD_TX_PKT | INTR_ALWAYS | BRANCH_IFTRUE :
764
                CMD_TX_PKT | BRANCH_IFTRUE;
765
#endif
766
 
767
        /* Todo: explicitly flush cache lines here. */
768
 
769
        /* Wake the potentially-idle transmit channel. */
770
        outl(0x10001000, dev->base_addr + TxCtrl);
771
 
772
        if (yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 1)
773
                clear_bit(0, (void*)&dev->tbusy);                /* Typical path */
774
        else
775
                yp->tx_full = 1;
776
        dev->trans_start = jiffies;
777
 
778
        if (yellowfin_debug > 4) {
779
                printk("%s: Yellowfin transmit frame #%d queued in slot %d.\n",
780
                           dev->name, yp->cur_tx, entry);
781
        }
782
        return 0;
783
}
784
 
785
/* The interrupt handler does all of the Rx thread work and cleans up
786
   after the Tx thread. */
787
static void yellowfin_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs)
788
{
789
#ifdef SA_SHIRQ         /* Use the now-standard shared IRQ implementation. */
790
        struct device *dev = (struct device *)dev_instance;
791
#else
792
        struct device *dev = (struct device *)(irq2dev_map[irq]);
793
#endif
794
 
795
        struct yellowfin_private *lp;
796
        int ioaddr, boguscnt = max_interrupt_work;
797
 
798
        if (dev == NULL) {
799
                printk ("yellowfin_interrupt(): irq %d for unknown device.\n", irq);
800
                return;
801
        }
802
 
803
        ioaddr = dev->base_addr;
804
        lp = (struct yellowfin_private *)dev->priv;
805
        if (test_and_set_bit(0, (void*)&lp->in_interrupt)) {
806
                dev->interrupt = 1;
807
                printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
808
                return;
809
        }
810
 
811
        do {
812
                u16 intr_status = inw(ioaddr + IntrClear);
813
                unsigned dirty_tx = lp->dirty_tx;
814
 
815
                if (yellowfin_debug > 4)
816
                        printk("%s: Yellowfin interrupt, status %4.4x.\n",
817
                                   dev->name, intr_status);
818
 
819
                if (intr_status == 0)
820
                        break;
821
 
822
                if (intr_status & (IntrRxDone | IntrEarlyRx))
823
                        yellowfin_rx(dev);
824
 
825
#ifdef NO_TXSTATS
826
                for (; lp->cur_tx - dirty_tx > 0; dirty_tx++) {
827
                        int entry = dirty_tx % TX_RING_SIZE;
828
                        if (lp->tx_ring[entry].status == 0)
829
                                break;
830
                        /* Free the original skb. */
831
                        dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE);
832
                        lp->tx_skbuff[entry] = 0;
833
                        lp->stats.tx_packets++;
834
                }
835
                if (lp->tx_full && dev->tbusy
836
                        && lp->cur_tx - dirty_tx < TX_RING_SIZE - 4) {
837
                        /* The ring is no longer full, clear tbusy. */
838
                        lp->tx_full = 0;
839
                        clear_bit(0, (void*)&dev->tbusy);
840
                        mark_bh(NET_BH);
841
                }
842
                lp->dirty_tx = dirty_tx;
843
#else
844
                if (intr_status & IntrTxDone
845
                        || lp->tx_status[dirty_tx % TX_RING_SIZE].tx_errs) {
846
 
847
                        for (dirty_tx = lp->dirty_tx; lp->cur_tx - dirty_tx > 0;
848
                                 dirty_tx++) {
849
                                /* Todo: optimize this. */
850
                                int entry = dirty_tx % TX_RING_SIZE;
851
                                u16 tx_errs = lp->tx_status[entry].tx_errs;
852
 
853
                                if (tx_errs == 0)
854
                                        break;                  /* It still hasn't been Txed */
855
                                if (tx_errs & 0xF8100000) {
856
                                        /* There was an major error, log it. */
857
#ifndef final_version
858
                                        if (yellowfin_debug > 1)
859
                                                printk("%s: Transmit error, Tx status %4.4x.\n",
860
                                                           dev->name, tx_errs);
861
#endif
862
                                        lp->stats.tx_errors++;
863
                                        if (tx_errs & 0xF800) lp->stats.tx_aborted_errors++;
864
                                        if (tx_errs & 0x0800) lp->stats.tx_carrier_errors++;
865
                                        if (tx_errs & 0x2000) lp->stats.tx_window_errors++;
866
                                        if (tx_errs & 0x8000) lp->stats.tx_fifo_errors++;
867
#ifdef ETHER_STATS
868
                                        if (tx_errs & 0x1000) lp->stats.collisions16++;
869
#endif
870
                                } else {
871
#ifdef ETHER_STATS
872
                                        if (status & 0x0400) lp->stats.tx_deferred++;
873
#endif
874
                                        lp->stats.collisions += tx_errs & 15;
875
                                        lp->stats.tx_packets++;
876
                                }
877
 
878
                                /* Free the original skb. */
879
                                dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE);
880
                                lp->tx_skbuff[entry] = 0;
881
                                /* Mark status as empty. */
882
                                lp->tx_status[entry].tx_errs = 0;
883
                        }
884
 
885
#ifndef final_version
886
                        if (lp->cur_tx - dirty_tx > TX_RING_SIZE) {
887
                                printk("%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
888
                                           dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
889
                                dirty_tx += TX_RING_SIZE;
890
                        }
891
#endif
892
 
893
                        if (lp->tx_full && dev->tbusy
894
                                && lp->cur_tx - dirty_tx < TX_RING_SIZE - 2) {
895
                                /* The ring is no longer full, clear tbusy. */
896
                                lp->tx_full = 0;
897
                                clear_bit(0, (void*)&dev->tbusy);
898
                                mark_bh(NET_BH);
899
                        }
900
 
901
                        lp->dirty_tx = dirty_tx;
902
                }
903
#endif
904
 
905
                /* Log errors and other events. */
906
                if (intr_status & 0x2ee) {      /* Abnormal error summary. */
907
                        printk("%s: Something Wicked happened! %4.4x.\n",
908
                                   dev->name, intr_status);
909
                        /* Hmmmmm, it's not clear what to do here. */
910
                        if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
911
                                lp->stats.tx_errors++;
912
                        if (intr_status & (IntrRxPCIErr | IntrRxPCIFault))
913
                                lp->stats.rx_errors++;
914
                }
915
                if (--boguscnt < 0) {
916
                        printk("%s: Too much work at interrupt, status=0x%4.4x.\n",
917
                                   dev->name, intr_status);
918
                        break;
919
                }
920
        } while (1);
921
 
922
        if (yellowfin_debug > 3)
923
                printk("%s: exiting interrupt, status=%#4.4x.\n",
924
                           dev->name, inw(ioaddr + IntrStatus));
925
 
926
        /* Code that should never be run!  Perhaps remove after testing.. */
927
        {
928
                static int stopit = 10;
929
                if (dev->start == 0  &&  --stopit < 0) {
930
                        printk("%s: Emergency stop, looping startup interrupt.\n",
931
                                   dev->name);
932
#ifdef SA_SHIRQ
933
                        free_irq(irq, dev);
934
#else
935
                        free_irq(irq);
936
#endif
937
                }
938
        }
939
 
940
        dev->interrupt = 0;
941
        clear_bit(0, (void*)&lp->in_interrupt);
942
        return;
943
}
944
 
945
/* This routine is logically part of the interrupt handler, but separated
946
   for clarity and better register allocation. */
947
static int
948
yellowfin_rx(struct device *dev)
949
{
950
        struct yellowfin_private *lp = (struct yellowfin_private *)dev->priv;
951
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
952
        int entry = lp->cur_rx % RX_RING_SIZE;
953
        int boguscnt = 20;
954
 
955
        if (yellowfin_debug > 4) {
956
                printk(" In yellowfin_rx(), entry %d status %4.4x.\n", entry,
957
                           yp->rx_ring[entry].status);
958
                printk("   #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x.\n",
959
                           entry, yp->rx_ring[entry].cmd,
960
                           yp->rx_ring[entry].request_cnt, yp->rx_ring[entry].addr,
961
                           yp->rx_ring[entry].result_cnt, yp->rx_ring[entry].status);
962
        }
963
 
964
 
965
        /* If EOP is set on the next entry, it's a new packet. Send it up. */
966
        while (yp->rx_ring[entry].status) {
967
                /* Todo: optimize this mess. */
968
                u16 desc_status = yp->rx_ring[entry].status;
969
                struct yellowfin_desc *desc = &lp->rx_ring[entry];
970
                int frm_size = desc->request_cnt - desc->result_cnt;
971
                u8 *buf_addr = bus_to_virt(lp->rx_ring[entry].addr);
972
                s16 frame_status = *(s16*)&(buf_addr[frm_size - 2]);
973
 
974
                if (yellowfin_debug > 4)
975
                        printk("  yellowfin_rx() status was %4.4x.\n", frame_status);
976
                if (--boguscnt < 0)
977
                        break;
978
                if ( ! (desc_status & RX_EOP)) {
979
                        printk("%s: Oversized Ethernet frame spanned multiple buffers,"
980
                                   " status %4.4x!\n", dev->name, desc_status);
981
                          lp->stats.rx_length_errors++;
982
                } else if (frame_status & 0x0038) {
983
                        /* There was a error. */
984
                        if (yellowfin_debug > 3)
985
                                printk("  yellowfin_rx() Rx error was %4.4x.\n", frame_status);
986
                        lp->stats.rx_errors++;
987
                        if (frame_status & 0x0060) lp->stats.rx_length_errors++;
988
                        if (frame_status & 0x0008) lp->stats.rx_frame_errors++;
989
                        if (frame_status & 0x0010) lp->stats.rx_crc_errors++;
990
                        if (frame_status < 0) lp->stats.rx_dropped++;
991
#ifdef YF_PROTOTYPE                     /* Support for prototype hardware errata. */
992
                } else if (memcmp(bus_to_virt(lp->rx_ring[entry].addr),
993
                                                  dev->dev_addr, 6) != 0
994
                                   && memcmp(bus_to_virt(lp->rx_ring[entry].addr),
995
                                                         "\377\377\377\377\377\377", 6) != 0) {
996
                        printk("%s: Bad frame to %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
997
                                   dev->name,
998
                                   ((char *)bus_to_virt(lp->rx_ring[entry].addr))[0],
999
                                   ((char *)bus_to_virt(lp->rx_ring[entry].addr))[1],
1000
                                   ((char *)bus_to_virt(lp->rx_ring[entry].addr))[2],
1001
                                   ((char *)bus_to_virt(lp->rx_ring[entry].addr))[3],
1002
                                   ((char *)bus_to_virt(lp->rx_ring[entry].addr))[4],
1003
                                   ((char *)bus_to_virt(lp->rx_ring[entry].addr))[5]);
1004
                        bogus_rx++;
1005
#endif
1006
                } else {
1007
                        u8 bogus_cnt = buf_addr[frm_size - 8];
1008
                        int pkt_len = frm_size - 8 - bogus_cnt;
1009
                        struct sk_buff *skb;
1010
                        int rx_in_place = 0;
1011
 
1012
                        /* Check if the packet is long enough to just accept without
1013
                           copying to a properly sized skbuff. */
1014
                        if (pkt_len > rx_copybreak) {
1015
                                struct sk_buff *newskb;
1016
                                char *temp;
1017
 
1018
                                /* Get a fresh skbuff to replace the filled one. */
1019
                                newskb = DEV_ALLOC_SKB(dev->mtu <= 1500 ? PKT_BUF_SZ
1020
                                                                           : dev->mtu + 32);
1021
                                if (newskb == NULL) {
1022
                                        skb = 0;         /* No memory, drop the packet. */
1023
                                        goto memory_squeeze;
1024
                                }
1025
                                /* Pass up the skb already on the Rx ring. */
1026
                                skb = lp->rx_skbuff[entry];
1027
                                temp = skb_put(skb, pkt_len);
1028
                                if (bus_to_virt(lp->rx_ring[entry].addr) != temp)
1029
                                        printk("%s: Warning -- the skbuff addresses do not match"
1030
                                                   " in yellowfin_rx: %p vs. %p / %p.\n", dev->name,
1031
                                                   bus_to_virt(lp->rx_ring[entry].addr),
1032
                                                   skb->head, temp);
1033
                                rx_in_place = 1;
1034
                                lp->rx_skbuff[entry] = newskb;
1035
                                newskb->dev = dev;
1036
                                skb_reserve(newskb, 2); /* 16 byte align IP header */
1037
                                lp->rx_ring[entry].addr = virt_to_bus(newskb->tail);
1038
                        } else
1039
                                skb = DEV_ALLOC_SKB(pkt_len + 2);
1040
                        memory_squeeze:
1041
                        if (skb == NULL) {
1042
                                printk("%s: Memory squeeze, deferring packet.\n", dev->name);
1043
                                /* todo: Check that at least two ring entries are free.
1044
                                   If not, free one and mark stats->rx_dropped++. */
1045
                                break;
1046
                        }
1047
                        skb->dev = dev;
1048
                        if (! rx_in_place) {
1049
                                skb_reserve(skb, 2);    /* 16 byte align the data fields */
1050
                                memcpy(skb_put(skb, pkt_len),
1051
                                           bus_to_virt(lp->rx_ring[entry].addr), pkt_len);
1052
                        }
1053
#if LINUX_VERSION_CODE > 0x10300
1054
                        skb->protocol = eth_type_trans(skb, dev);
1055
#else
1056
                        skb->len = pkt_len;
1057
#endif
1058
                        netif_rx(skb);
1059
                        lp->stats.rx_packets++;
1060
                }
1061
 
1062
                /* Mark this entry as being the end-of-list, and the prior entry
1063
                   as now valid. */
1064
                lp->rx_ring[entry].cmd = CMD_STOP;
1065
                yp->rx_ring[entry].status = 0;
1066
                {
1067
                        int prev_entry = entry - 1;
1068
                        if (prev_entry < 0)
1069
                                lp->rx_ring[RX_RING_SIZE - 1].cmd =
1070
                                        CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS;
1071
                        else
1072
                                lp->rx_ring[prev_entry].cmd = CMD_RX_BUF | INTR_ALWAYS;
1073
                }
1074
                entry = (++lp->cur_rx) % RX_RING_SIZE;
1075
        }
1076
        /* todo: restart Rx engine if stopped.  For now we just make the Rx ring
1077
           large enough to avoid this. */
1078
 
1079
        return 0;
1080
}
1081
 
1082
static int
1083
yellowfin_close(struct device *dev)
1084
{
1085
        int ioaddr = dev->base_addr;
1086
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
1087
        int i;
1088
 
1089
        dev->start = 0;
1090
        dev->tbusy = 1;
1091
 
1092
        if (yellowfin_debug > 1) {
1093
                printk("%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n",
1094
                           dev->name, inw(ioaddr + TxStatus),
1095
                           inw(ioaddr + RxStatus), inl(ioaddr + IntrStatus));
1096
                printk("%s: Queue pointers were Tx %d / %d,  Rx %d / %d.\n",
1097
                           dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx);
1098
        }
1099
 
1100
        /* Disable interrupts by clearing the interrupt mask. */
1101
        outw(0x0000, ioaddr + IntrEnb);
1102
 
1103
        /* Stop the chip's Tx and Rx processes. */
1104
        outl(0x80000000, ioaddr + RxCtrl);
1105
        outl(0x80000000, ioaddr + TxCtrl);
1106
 
1107
        del_timer(&yp->timer);
1108
 
1109
#ifdef __i386__
1110
        if (yellowfin_debug > 2) {
1111
                printk("\n  Tx ring at %8.8x:\n", (int)virt_to_bus(yp->tx_ring));
1112
                for (i = 0; i < TX_RING_SIZE*2; i++)
1113
                        printk(" %c #%d desc. %4.4x %4.4x %8.8x %8.8x %4.4x %4.4x.\n",
1114
                                   inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
1115
                                   i, yp->tx_ring[i].cmd,
1116
                                   yp->tx_ring[i].request_cnt, yp->tx_ring[i].addr,
1117
                                   yp->tx_ring[i].branch_addr,
1118
                                   yp->tx_ring[i].result_cnt, yp->tx_ring[i].status);
1119
                printk("  Tx status %p:\n", yp->tx_status);
1120
                for (i = 0; i < TX_RING_SIZE; i++)
1121
                        printk("   #%d status %4.4x %4.4x %4.4x %4.4x.\n",
1122
                                   i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs,
1123
                                   yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused);
1124
 
1125
                printk("\n  Rx ring %8.8x:\n", (int)virt_to_bus(yp->rx_ring));
1126
                for (i = 0; i < RX_RING_SIZE; i++) {
1127
                        printk(" %c #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x\n",
1128
                                   inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ',
1129
                                   i, yp->rx_ring[i].cmd,
1130
                                   yp->rx_ring[i].request_cnt, yp->rx_ring[i].addr,
1131
                                   yp->rx_ring[i].result_cnt, yp->rx_ring[i].status);
1132
                        if (yellowfin_debug > 5) {
1133
                                if (*(u8*)yp->rx_ring[i].addr != 0x69) {
1134
                                        int j;
1135
                                        for (j = 0; j < 0x50; j++)
1136
                                                printk(" %4.4x", ((u16*)yp->rx_ring[i].addr)[j]);
1137
                                        printk("\n");
1138
                                }
1139
                        }
1140
                }
1141
        }
1142
#endif /* __i386__ debugging only */
1143
 
1144
#ifdef SA_SHIRQ
1145
        free_irq(dev->irq, dev);
1146
#else
1147
        free_irq(dev->irq);
1148
        irq2dev_map[dev->irq] = 0;
1149
#endif
1150
 
1151
        /* Free all the skbuffs in the Rx queue. */
1152
        for (i = 0; i < RX_RING_SIZE; i++) {
1153
                yp->rx_ring[i].cmd = CMD_STOP;
1154
                yp->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
1155
                if (yp->rx_skbuff[i]) {
1156
#if LINUX_VERSION_CODE < 0x20100
1157
                        yp->rx_skbuff[i]->free = 1;
1158
#endif
1159
                        dev_kfree_skb(yp->rx_skbuff[i], FREE_WRITE);
1160
                }
1161
                yp->rx_skbuff[i] = 0;
1162
        }
1163
        for (i = 0; i < TX_RING_SIZE; i++) {
1164
                if (yp->tx_skbuff[i])
1165
                        dev_kfree_skb(yp->tx_skbuff[i], FREE_WRITE);
1166
                yp->tx_skbuff[i] = 0;
1167
        }
1168
 
1169
#ifdef YF_PROTOTYPE                     /* Support for prototype hardware errata. */
1170
        if (yellowfin_debug > 0) {
1171
                printk("%s: Received %d frames that we should not have.\n",
1172
                           dev->name, bogus_rx);
1173
        }
1174
#endif
1175
        MOD_DEC_USE_COUNT;
1176
 
1177
        return 0;
1178
}
1179
 
1180
static struct enet_statistics *
1181
yellowfin_get_stats(struct device *dev)
1182
{
1183
        struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
1184
        return &yp->stats;
1185
}
1186
 
1187
/* Set or clear the multicast filter for this adaptor. */
1188
 
1189
/* The little-endian AUTODIN32 ethernet CRC calculation.
1190
   N.B. Do not use for bulk data, use a table-based routine instead.
1191
   This is common code and should be moved to net/core/crc.c */
1192
static unsigned const ethernet_polynomial_le = 0xedb88320U;
1193
static inline unsigned ether_crc_le(int length, unsigned char *data)
1194
{
1195
        unsigned int crc = 0xffffffff;  /* Initial value. */
1196
        while(--length >= 0) {
1197
                unsigned char current_octet = *data++;
1198
                int bit;
1199
                for (bit = 8; --bit >= 0; current_octet >>= 1) {
1200
                        if ((crc ^ current_octet) & 1) {
1201
                                crc >>= 1;
1202
                                crc ^= ethernet_polynomial_le;
1203
                        } else
1204
                                crc >>= 1;
1205
                }
1206
        }
1207
        return crc;
1208
}
1209
 
1210
 
1211
#ifdef NEW_MULTICAST
1212
static void set_rx_mode(struct device *dev)
1213
#else
1214
static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
1215
#endif
1216
{
1217
        int ioaddr = dev->base_addr;
1218
        u16 cfg_value = inw(ioaddr + Cnfg);
1219
 
1220
        /* Stop the Rx process to change any value. */
1221
        outw(cfg_value & ~0x1000, ioaddr + Cnfg);
1222
        if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
1223
                /* Unconditionally log net taps. */
1224
                printk("%s: Promiscuous mode enabled.\n", dev->name);
1225
                outw(0x000F, ioaddr + AddrMode);
1226
        } else if ((dev->mc_count > 64)  ||  (dev->flags & IFF_ALLMULTI)) {
1227
                /* Too many to filter well, or accept all multicasts. */
1228
                outw(0x000B, ioaddr + AddrMode);
1229
        } else if (dev->mc_count > 0) { /* Must use the multicast hash table. */
1230
                struct dev_mc_list *mclist;
1231
                u16 hash_table[4];
1232
                int i;
1233
                memset(hash_table, 0, sizeof(hash_table));
1234
                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
1235
                         i++, mclist = mclist->next) {
1236
                        /* Due to a bug in the early chip versions, multiple filter
1237
                           slots must be set for each address. */
1238
                        set_bit((ether_crc_le(3, mclist->dmi_addr) >> 3) & 0x3f,
1239
                                        hash_table);
1240
                        set_bit((ether_crc_le(4, mclist->dmi_addr) >> 3) & 0x3f,
1241
                                        hash_table);
1242
                        set_bit((ether_crc_le(5, mclist->dmi_addr) >> 3) & 0x3f,
1243
                                        hash_table);
1244
                        set_bit((ether_crc_le(6, mclist->dmi_addr) >> 3) & 0x3f,
1245
                                        hash_table);
1246
                }
1247
                /* Copy the hash table to the chip. */
1248
                for (i = 0; i < 4; i++)
1249
                        outw(hash_table[i], ioaddr + HashTbl + i*2);
1250
                outw(0x0003, ioaddr + AddrMode);
1251
        } else {                                        /* Normal, unicast/broadcast-only mode. */
1252
                outw(0x0001, ioaddr + AddrMode);
1253
        }
1254
        /* Restart the Rx process. */
1255
        outw(cfg_value | 0x1000, ioaddr + Cnfg);
1256
}
1257
 
1258
#ifdef MODULE
1259
 
1260
/* An additional parameter that may be passed in... */
1261
static int debug = -1;
1262
 
1263
int
1264
init_module(void)
1265
{
1266
        int cards_found;
1267
 
1268
        if (debug >= 0)
1269
                yellowfin_debug = debug;
1270
 
1271
        root_yellowfin_dev = NULL;
1272
        cards_found = yellowfin_probe(0);
1273
 
1274
        return cards_found ? 0 : -ENODEV;
1275
}
1276
 
1277
void
1278
cleanup_module(void)
1279
{
1280
        struct device *next_dev;
1281
 
1282
        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
1283
        while (root_yellowfin_dev) {
1284
                next_dev = ((struct yellowfin_private *)root_yellowfin_dev->priv)->next_module;
1285
                unregister_netdev(root_yellowfin_dev);
1286
                release_region(root_yellowfin_dev->base_addr, YELLOWFIN_TOTAL_SIZE);
1287
                kfree(root_yellowfin_dev);
1288
                root_yellowfin_dev = next_dev;
1289
        }
1290
}
1291
 
1292
#endif  /* MODULE */
1293
 
1294
/*
1295
 * Local variables:
1296
 *  compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
1297
 *  SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
1298
 *  c-indent-level: 4
1299
 *  c-basic-offset: 4
1300
 *  tab-width: 4
1301
 * End:
1302
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.