]> git.pld-linux.org Git - packages/kernel.git/blame - atm-21-fore200e-0.3.patch
- replaced by linux-2.4-sfq.patch
[packages/kernel.git] / atm-21-fore200e-0.3.patch
CommitLineData
b5a39c4d
JR
1--- linux-2.4.0-test9-orig/drivers/atm/fore200e.c
2+++ linux-2.4.0-test9/drivers/atm/fore200e.c Fri Dec 1 16:18:31 2000
3@@ -2,7 +2,7 @@
4 $Id$
5
6 A FORE Systems 200E-series driver for ATM on Linux.
7- Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2000.
8+ Christophe Lizzi (lizzi@cnam.fr), October 1999-December 2000.
9
10 Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
11
12@@ -34,6 +34,8 @@
13 #include <linux/sched.h>
14 #include <linux/interrupt.h>
15 #include <linux/bitops.h>
16+#include <linux/pci.h>
17+#include <linux/module.h>
18 #include <linux/atmdev.h>
19 #include <linux/sonet.h>
20 #include <linux/atm_suni.h>
21@@ -46,7 +48,6 @@
22 #include <asm/byteorder.h>
23 #include <asm/uaccess.h>
24 #include <asm/atomic.h>
25-#include <linux/pci.h>
26
27 #ifdef CONFIG_ATM_FORE200E_SBA
28 #include <asm/idprom.h>
29@@ -56,25 +57,31 @@
30 #include <asm/pgtable.h>
31 #endif
32
33-#include <linux/module.h>
34
35-#include "fore200e.h"
36-#include "suni.h"
37+#if 0 /* defer intr work to a tasklet */
38+#define FORE200E_USE_TASKLET
39+#endif
40+
41+#if 0 /* enable the debugging code of the buffer supply queues */
42+#define FORE200E_BSQ_DEBUG
43+#endif
44
45 #if 1 /* ensure correct handling of 52-byte AAL0 SDUs used by atmdump-like apps */
46 #define FORE200E_52BYTE_AAL0_SDU
47 #endif
48
49-#define FORE200E_VERSION "0.2d"
50+#include "fore200e.h"
51+#include "suni.h"
52
53+#define FORE200E_VERSION "0.3"
54
55 #define FORE200E "fore200e: "
56
57 #if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
58 #define DPRINTK(level, format, args...) do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
59- printk(FORE200E format, ##args); } while(0)
60+ printk(FORE200E format, ##args); } while (0)
61 #else
62-#define DPRINTK(level, format, args...) while(0)
63+#define DPRINTK(level, format, args...) do {} while (0)
64 #endif
65
66
67@@ -503,6 +510,7 @@
68 {
69 #if defined(__sparc_v9__)
70 /* returned chunks are page-aligned */
71+ chunk->alloc_size = size * nbr;
72 chunk->alloc_addr = pci_alloc_consistent((struct pci_dev*)fore200e->bus_dev,
73 chunk->alloc_size,
74 &chunk->dma_addr);
75@@ -589,7 +597,7 @@
76 {
77 DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
78
79- /* XXX iounmap() does nothing on PowerPC (at least in 2.2.12 and 2.3.41),
80+ /* XXX iounmap() does nothing on PowerPC (at least in 2.2.x and 2.3.x),
81 this leads to a kernel panic if the module is loaded and unloaded several times */
82 if (fore200e->virt_base != NULL)
83 iounmap(fore200e->virt_base);
84@@ -989,44 +997,89 @@
85 static void
86 fore200e_irq_tx(struct fore200e* fore200e)
87 {
88+ struct host_txq* txq = &fore200e->host_txq;
89 struct host_txq_entry* entry;
90- int i;
91-
92- entry = fore200e->host_txq.host_entry;
93
94- for (i = 0; i < QUEUE_SIZE_TX; i++) {
95+ for (;;) {
96
97- if (*entry->status & STATUS_COMPLETE) {
98+ entry = &txq->host_entry[ txq->tail ];
99
100- DPRINTK(3, "TX COMPLETED: entry = %p, vcc = %p, skb = %p\n", entry, entry->vcc, entry->skb);
101+ if (!(*entry->status & STATUS_COMPLETE)) {
102+ break;
103+ }
104
105- /* free copy of misaligned data */
106- if (entry->data)
107- kfree(entry->data);
108+ DPRINTK(3, "TX COMPLETED: entry = %p [tail = %d], vcc = %p, skb = %p\n",
109+ entry, txq->tail, entry->vcc, entry->skb);
110
111- /* remove DMA mapping */
112- fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
113- FORE200E_DMA_TODEVICE);
114+ /* free copy of misaligned data */
115+ if (entry->data)
116+ kfree(entry->data);
117+
118+ /* remove DMA mapping */
119+ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
120+ FORE200E_DMA_TODEVICE);
121+
122+ /* notify tx completion */
123+ if (entry->vcc->pop)
124+ entry->vcc->pop(entry->vcc, entry->skb);
125+ else
126+ dev_kfree_skb_irq(entry->skb);
127+
128+ /* check error condition */
129+ if (*entry->status & STATUS_ERROR)
130+ atomic_inc(&entry->vcc->stats->tx_err);
131+ else
132+ atomic_inc(&entry->vcc->stats->tx);
133+
134+ *entry->status = STATUS_FREE;
135+
136+ fore200e->host_txq.txing--;
137
138- /* notify tx completion */
139- if (entry->vcc->pop)
140- entry->vcc->pop(entry->vcc, entry->skb);
141- else
142- dev_kfree_skb_irq(entry->skb);
143+ FORE200E_NEXT_ENTRY(txq->tail, QUEUE_SIZE_TX);
144+ }
145+}
146
147- /* check error condition */
148- if (*entry->status & STATUS_ERROR)
149- atomic_inc(&entry->vcc->stats->tx_err);
150- else
151- atomic_inc(&entry->vcc->stats->tx);
152
153- *entry->status = STATUS_FREE;
154-
155- fore200e->host_txq.txing--;
156+#ifdef FORE200E_BSQ_DEBUG
157+int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn) /* FFF */
158+{
159+ struct buffer* buffer;
160+ int count = 0;
161+
162+ buffer = bsq->freebuf;
163+ while (buffer) {
164+
165+ if (buffer->supplied) {
166+ printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld supplied but in free list!\n",
167+ where, scheme, magn, buffer->index);
168 }
169- entry++;
170+
171+ if (buffer->magn != magn) {
172+ printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected magn = %d\n",
173+ where, scheme, magn, buffer->index, buffer->magn);
174+ }
175+
176+ if (buffer->scheme != scheme) {
177+ printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected scheme = %d\n",
178+ where, scheme, magn, buffer->index, buffer->scheme);
179+ }
180+
181+ if (buffer->index < 0 || buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ]) {
182+ printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
183+ where, scheme, magn, buffer->index);
184+ }
185+
186+ count++;
187+ buffer = buffer->next;
188+ }
189+
190+ if (count != bsq->freebuf_count) {
191+ printk(FORE200E "bsq_audit(%d): queue %d.%d, %d bufs in free list, but freebuf_count = %d\n",
192+ where, scheme, magn, count, bsq->freebuf_count);
193 }
194+ return 0;
195 }
196+#endif
197
198
199 static void
200@@ -1043,28 +1096,44 @@
201
202 bsq = &fore200e->host_bsq[ scheme ][ magn ];
203
204- if (fore200e_rx_buf_nbr[ scheme ][ magn ] - bsq->count > RBD_BLK_SIZE) {
205+#ifdef FORE200E_BSQ_DEBUG
206+ bsq_audit(1, bsq, scheme, magn);
207+#endif
208
209- DPRINTK(2, "supplying rx buffers to queue %d / %d, count = %d\n",
210- scheme, magn, bsq->count);
211+ while (bsq->freebuf_count >= RBD_BLK_SIZE) {
212+
213+ DPRINTK(2, "supplying %d rx buffers to queue %d / %d, freebuf_count = %d\n",
214+ RBD_BLK_SIZE, scheme, magn, bsq->freebuf_count);
215
216 entry = &bsq->host_entry[ bsq->head ];
217-
218- FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
219
220 for (i = 0; i < RBD_BLK_SIZE; i++) {
221
222- buffer = &bsq->buffer[ bsq->free ];
223-
224- FORE200E_NEXT_ENTRY(bsq->free, fore200e_rx_buf_nbr[ scheme ][ magn ]);
225+ /* take the first buffer in the free buffer list */
226+ buffer = bsq->freebuf;
227+ if (!buffer) {
228+ printk(FORE200E "no more free bufs in queue %d.%d, but freebuf_count = %d\n",
229+ scheme, magn, bsq->freebuf_count);
230+ return;
231+ }
232+ bsq->freebuf = buffer->next;
233
234+#ifdef FORE200E_BSQ_DEBUG
235+ if (buffer->supplied)
236+ printk(FORE200E "queue %d.%d, buffer %lu already supplied\n",
237+ scheme, magn, buffer->index);
238+ buffer->supplied = 1;
239+#endif
240+
241 entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
242 entry->rbd_block->rbd[ i ].handle = FORE200E_BUF2HDL(buffer);
243 }
244
245- /* increase the number of supplied rx buffers */
246- bsq->count += RBD_BLK_SIZE;
247-
248+ FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
249+
250+ /* decrease accordingly the number of free rx buffers */
251+ bsq->freebuf_count -= RBD_BLK_SIZE;
252+
253 *entry->status = STATUS_PENDING;
254 fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
255 }
256@@ -1073,7 +1142,6 @@
257 }
258
259
260-
261 static struct atm_vcc*
262 fore200e_find_vcc(struct fore200e* fore200e, struct rpd* rpd)
263 {
264@@ -1089,7 +1157,7 @@
265 }
266
267
268-static void
269+static int
270 fore200e_push_rpd(struct fore200e* fore200e, struct rpd* rpd)
271 {
272 struct atm_vcc* vcc;
273@@ -1103,10 +1171,15 @@
274
275 vcc = fore200e_find_vcc(fore200e, rpd);
276 if (vcc == NULL) {
277-
278- printk(FORE200E "no vcc found for PDU received on %d.%d.%d\n",
279- fore200e->atm_dev->number, rpd->atm_header.vpi, rpd->atm_header.vci);
280- return;
281+ DPRINTK(1, "no vcc found for PDU received on %d.%d.%d\n",
282+ fore200e->atm_dev->number, rpd->atm_header.vpi, rpd->atm_header.vci);
283+ return -EINVAL;
284+ }
285+
286+
287+ if (!test_bit(ATM_VF_READY, &vcc->flags)) {
288+ DPRINTK(1, "vcc %d.%d.%d not ready for rx\n", vcc->itf, vcc->vpi, vcc->vpi);
289+ return -EINVAL;
290 }
291
292 fore200e_vcc = FORE200E_VCC(vcc);
293@@ -1129,10 +1202,9 @@
294
295 skb = alloc_skb(pdu_len, GFP_ATOMIC);
296 if (skb == NULL) {
297-
298 printk(FORE200E "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
299 atomic_inc(&vcc->stats->rx_drop);
300- return;
301+ return -ENOMEM;
302 }
303
304 do_gettimeofday(&skb->stamp);
305@@ -1169,11 +1241,13 @@
306 vcc->itf, vcc->vpi, vcc->vci);
307
308 dev_kfree_skb_irq(skb);
309- return;
310+ return -ENOMEM;
311 }
312
313 vcc->push(vcc, skb);
314 atomic_inc(&vcc->stats->rx);
315+
316+ return 0;
317 }
318
319
320@@ -1183,13 +1257,31 @@
321 struct buffer* buffer;
322 int i;
323
324+ struct host_bsq* bsq;
325+
326+
327 for (i = 0; i < rpd->nseg; i++) {
328
329 /* rebuild rx buffer address from rsd handle */
330 buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
331
332- /* decrease the number of supplied rx buffers */
333- fore200e->host_bsq[ buffer->scheme ][ buffer->magn ].count--;
334+ bsq = &fore200e->host_bsq[ buffer->scheme ][ buffer->magn ];
335+
336+#ifdef FORE200E_BSQ_DEBUG
337+ bsq_audit(2, bsq, buffer->scheme, buffer->magn);
338+
339+ if (buffer->supplied == 0)
340+ printk(FORE200E "queue %d.%d, buffer %ld was not supplied\n",
341+ buffer->scheme, buffer->magn, buffer->index);
342+ buffer->supplied = 0;
343+#endif
344+
345+ /* re-insert the buffer into the free buffer list */
346+ buffer->next = bsq->freebuf;
347+ bsq->freebuf = buffer;
348+
349+ /* then increment the number of free rx buffers */
350+ bsq->freebuf_count++;
351 }
352 }
353
354@@ -1208,8 +1300,6 @@
355 if ((*entry->status & STATUS_COMPLETE) == 0)
356 break;
357
358- FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
359-
360 if ((*entry->status & STATUS_ERROR) == 0) {
361
362 fore200e_push_rpd(fore200e, entry->rpd);
363@@ -1219,6 +1309,8 @@
364 fore200e->atm_dev->number, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
365 }
366
367+ FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
368+
369 fore200e_collect_rpd(fore200e, entry->rpd);
370
371 fore200e_supply(fore200e);
372@@ -1230,6 +1322,23 @@
373 }
374
375
376+static void
377+fore200e_irq(struct fore200e* fore200e)
378+{
379+ fore200e_irq_rx(fore200e);
380+
381+ if (fore200e->host_txq.txing) {
382+
383+ /* give up if someone else is playing with the tx queue */
384+ if (test_bit(0, &fore200e->tx_bit))
385+ return;
386+
387+ fore200e_irq_tx(fore200e);
388+ }
389+}
390+
391+
392+
393 static void
394 fore200e_interrupt(int irq, void* dev, struct pt_regs* regs)
395 {
396@@ -1242,23 +1351,25 @@
397 }
398 DPRINTK(3, "valid interrupt on device %c\n", fore200e->name[9]);
399
400+#ifdef FORE200E_USE_TASKLET
401 tasklet_schedule(&fore200e->tasklet);
402+#else
403+ fore200e_irq(fore200e);
404+#endif
405
406 fore200e->bus->irq_ack(fore200e);
407 }
408
409
410+#ifdef FORE200E_USE_TASKLET
411 static void
412 fore200e_tasklet(unsigned long data)
413 {
414- struct fore200e* fore200e = (struct fore200e*) data;
415+ DPRINTK(3, "tasklet scheduled for device %c\n", fore200e->name[9]);
416
417- fore200e_irq_rx(fore200e);
418-
419- if (fore200e->host_txq.txing)
420- fore200e_irq_tx(fore200e);
421+ fore200e_irq((struct fore200e*) data);
422 }
423-
424+#endif
425
426
427 static int
428@@ -1268,7 +1379,7 @@
429
430 #if 1
431 /* fairly balance VCs over (identical) buffer schemes */
432- scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
433+ scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
434 #else
435 /* bit 7 of VPI magically selects the second buffer scheme */
436 if (vcc->vpi & (1<<7)) {
437@@ -1419,7 +1530,7 @@
438 return 0;
439
440 set_bit(ATM_VF_ADDR, &vcc->flags);
441- vcc->itf = vcc->dev->number;
442+ vcc->itf = vcc->dev->number;
443
444 DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
445 "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
446@@ -1438,7 +1549,7 @@
447 }
448 /* reserving the pseudo-CBR bandwidth at this point grants us
449 to reduce the length of the critical section protected
450- by 'rate_sf'. in counterpart, we have to reset the available
451+ by 'rate_sf'. in counterpart, we have to restore the available
452 bandwidth if we later encounter an error */
453
454 fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
455@@ -1490,6 +1601,8 @@
456
457 DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
458
459+ clear_bit(ATM_VF_READY, &vcc->flags);
460+
461 fore200e_activate_vcin(fore200e, 0, vcc, 0);
462
463 kfree(FORE200E_VCC(vcc));
464@@ -1499,8 +1610,6 @@
465 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
466 up(&fore200e->rate_sf);
467 }
468-
469- clear_bit(ATM_VF_READY, &vcc->flags);
470 }
471
472
473@@ -1518,7 +1627,6 @@
474 struct host_txq_entry* entry;
475 struct tpd* tpd;
476 struct tpd_haddr tpd_haddr;
477- //unsigned long flags;
478 int retry = CONFIG_ATM_FORE200E_TX_RETRY;
479 int tx_copy = 0;
480 int tx_len = skb->len;
481@@ -1526,6 +1634,11 @@
482 unsigned char* skb_data;
483 int skb_len;
484
485+ if (!test_bit(ATM_VF_READY, &vcc->flags)) {
486+ DPRINTK(1, "vcc %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
487+ return -EINVAL;
488+ }
489+
490 #ifdef FORE200E_52BYTE_AAL0_SDU
491 if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
492 cell_header = (u32*) skb->data;
493@@ -1543,18 +1656,18 @@
494
495 retry_here:
496
497- tasklet_disable(&fore200e->tasklet);
498+ set_bit(0, &fore200e->tx_bit);
499
500 entry = &txq->host_entry[ txq->head ];
501
502- if (*entry->status != STATUS_FREE) {
503+ if ((*entry->status != STATUS_FREE) || (txq->txing >= QUEUE_SIZE_TX - 2)) {
504
505 /* try to free completed tx queue entries */
506 fore200e_irq_tx(fore200e);
507
508 if (*entry->status != STATUS_FREE) {
509
510- tasklet_enable(&fore200e->tasklet);
511+ clear_bit(0, &fore200e->tx_bit);
512
513 /* retry once again? */
514 if(--retry > 0)
515@@ -1562,13 +1675,16 @@
516
517 atomic_inc(&vcc->stats->tx_err);
518
519- printk(FORE200E "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
520+ fore200e->tx_sat++;
521+ DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
522 fore200e->name, fore200e->cp_queues->heartbeat);
523 if (vcc->pop)
524 vcc->pop(vcc, skb);
525 else
526 dev_kfree_skb(skb);
527- return -EIO;
528+
529+ clear_bit(0, &fore200e->tx_bit);
530+ return -ENOBUFS;
531 }
532 }
533
534@@ -1594,7 +1710,8 @@
535 entry->data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA);
536 if (entry->data == NULL) {
537
538- tasklet_enable(&fore200e->tasklet);
539+ clear_bit(0, &fore200e->tx_bit);
540+
541 if (vcc->pop)
542 vcc->pop(vcc, skb);
543 else
544@@ -1618,7 +1735,7 @@
545 FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
546 txq->txing++;
547
548- tasklet_enable(&fore200e->tasklet);
549+ clear_bit(0, &fore200e->tx_bit);
550
551 /* ensure DMA synchronisation */
552 fore200e->bus->dma_sync(fore200e, tpd->tsd[ 0 ].buffer, tpd->tsd[ 0 ].length, FORE200E_DMA_TODEVICE);
553@@ -1959,6 +2076,11 @@
554 struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
555 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
556
557+ if (!test_bit(ATM_VF_READY, &vcc->flags)) {
558+ DPRINTK(1, "vcc %d.%d.%d not ready for QoS change\n", vcc->itf, vcc->vpi, vcc->vpi);
559+ return -EINVAL;
560+ }
561+
562 DPRINTK(2, "change_qos %d.%d.%d, "
563 "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
564 "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
565@@ -2008,7 +2130,9 @@
566 printk(FORE200E "IRQ %s reserved for device %s\n",
567 fore200e_irq_itoa(fore200e->irq), fore200e->name);
568
569+#ifdef FORE200E_USE_TASKLET
570 tasklet_init(&fore200e->tasklet, fore200e_tasklet, (unsigned long)fore200e);
571+#endif
572
573 fore200e->state = FORE200E_STATE_IRQ;
574 return 0;
575@@ -2070,10 +2194,16 @@
576 if (buffer == NULL)
577 return -ENOMEM;
578
579+ bsq->freebuf = NULL;
580+
581 for (i = 0; i < nbr; i++) {
582
583 buffer[ i ].scheme = scheme;
584 buffer[ i ].magn = magn;
585+#ifdef FORE200E_BSQ_DEBUG
586+ buffer[ i ].index = i;
587+ buffer[ i ].supplied = 0;
588+#endif
589
590 /* allocate the receive buffer body */
591 if (fore200e_chunk_alloc(fore200e,
592@@ -2086,9 +2216,17 @@
593
594 return -ENOMEM;
595 }
596+
597+ /* insert the buffer into the free buffer list */
598+ buffer[ i ].next = bsq->freebuf;
599+ bsq->freebuf = &buffer[ i ];
600 }
601- /* set next free buffer index */
602- bsq->free = 0;
603+ /* all the buffers are free, initially */
604+ bsq->freebuf_count = nbr;
605+
606+#ifdef FORE200E_BDQ_DEBUG
607+ bsq_audit(3, bsq, scheme, magn);
608+#endif
609 }
610 }
611
612@@ -2145,9 +2283,9 @@
613 FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
614 bsq->host_entry[ i ].rbd_block_dma =
615 FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
616- bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
617+ bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
618
619- *bsq->host_entry[ i ].status = STATUS_FREE;
620+ *bsq->host_entry[ i ].status = STATUS_FREE;
621
622 fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i),
623 &cp_entry[ i ].status_haddr);
624@@ -2276,8 +2414,9 @@
625 operation to detect that a new pdu has been submitted for tx */
626 }
627
628- /* set the head entry of the queue */
629+ /* set the head and tail entries of the queue */
630 txq->head = 0;
631+ txq->tail = 0;
632
633 fore200e->state = FORE200E_STATE_INIT_TXQ;
634 return 0;
635@@ -2591,7 +2730,7 @@
636 struct fore200e* fore200e;
637 int index, link;
638
639- printk(FORE200E "FORE Systems 200E-series driver - version " FORE200E_VERSION "\n");
640+ printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
641
642 /* for each configured bus interface */
643 for (link = 0, bus = fore200e_bus; bus->model_name; bus++) {
644@@ -2674,14 +2817,15 @@
645
646 if (!left--)
647 return sprintf(page,
648- " supplied small bufs (1):\t%d\n"
649- " supplied large bufs (1):\t%d\n"
650- " supplied small bufs (2):\t%d\n"
651- " supplied large bufs (2):\t%d\n",
652- fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].count,
653- fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].count,
654- fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].count,
655- fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].count);
656+ " free small bufs, scheme 1:\t%d\n"
657+ " free large bufs, scheme 1:\t%d\n"
658+ " free small bufs, scheme 2:\t%d\n"
659+ " free large bufs, scheme 2:\t%d\n",
660+ fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].freebuf_count,
661+ fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].freebuf_count,
662+ fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].freebuf_count,
663+ fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].freebuf_count);
664+
665 if (!left--) {
666 u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
667
668@@ -2867,13 +3011,15 @@
669 " large b1:\t\t\t%10u\n"
670 " small b2:\t\t\t%10u\n"
671 " large b2:\t\t\t%10u\n"
672- " RX PDUs:\t\t\t%10u\n",
673+ " RX PDUs:\t\t\t%10u\n"
674+ " TX PDUs:\t\t\t%10lu\n",
675 fore200e_swap(fore200e->stats->aux.small_b1_failed),
676 fore200e_swap(fore200e->stats->aux.large_b1_failed),
677 fore200e_swap(fore200e->stats->aux.small_b2_failed),
678 fore200e_swap(fore200e->stats->aux.large_b2_failed),
679- fore200e_swap(fore200e->stats->aux.rpd_alloc_failed));
680-
681+ fore200e_swap(fore200e->stats->aux.rpd_alloc_failed),
682+ fore200e->tx_sat);
683+
684 if (!left--)
685 return sprintf(page,"\n"
686 " receive carrier:\t\t\t%s\n",
687--- linux-2.4.0-test9-orig/drivers/atm/fore200e.h
688+++ linux-2.4.0-test9/drivers/atm/fore200e.h Fri Dec 1 16:27:20 2000
689@@ -11,7 +11,7 @@
690 #define LARGE_BUFFER_SIZE 4032 /* size of large buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
691
692
693-#define RBD_BLK_SIZE 32 /* nbr of supplied rx buffers per rbd */
694+#define RBD_BLK_SIZE 16 /* nbr of supplied rx buffers per rbd */
695
696
697 #define MAX_PDU_SIZE 65535 /* maximum PDU size supported by AALs */
698@@ -23,17 +23,17 @@
699 #define BUFFER_S2_SIZE SMALL_BUFFER_SIZE /* size of small buffers, scheme 2 */
700 #define BUFFER_L2_SIZE LARGE_BUFFER_SIZE /* size of large buffers, scheme 2 */
701
702-#define BUFFER_S1_NBR (RBD_BLK_SIZE * 2)
703-#define BUFFER_L1_NBR (RBD_BLK_SIZE * 2)
704+#define BUFFER_S1_NBR (RBD_BLK_SIZE * 6)
705+#define BUFFER_L1_NBR (RBD_BLK_SIZE * 4)
706
707-#define BUFFER_S2_NBR (RBD_BLK_SIZE * 2)
708-#define BUFFER_L2_NBR (RBD_BLK_SIZE * 2)
709+#define BUFFER_S2_NBR (RBD_BLK_SIZE * 6)
710+#define BUFFER_L2_NBR (RBD_BLK_SIZE * 4)
711
712
713 #define QUEUE_SIZE_CMD 16 /* command queue capacity */
714 #define QUEUE_SIZE_RX 64 /* receive queue capacity */
715 #define QUEUE_SIZE_TX 256 /* transmit queue capacity */
716-#define QUEUE_SIZE_BS 16 /* buffer supply queue capacity */
717+#define QUEUE_SIZE_BS 32 /* buffer supply queue capacity */
718
719 #define NBR_CONNECT 1024 /* number of ATM connections */
720
721@@ -576,6 +576,10 @@
722 enum buffer_scheme scheme; /* buffer scheme */
723 enum buffer_magn magn; /* buffer magnitude */
724 struct chunk data; /* data buffer */
725+#ifdef FORE200E_BSQ_DEBUG
726+ unsigned long index; /* buffer # in queue */
727+ int supplied; /* 'buffer supplied' flag */
728+#endif
729 } buffer_t;
730
731
732@@ -602,6 +606,7 @@
733 typedef struct host_txq {
734 struct host_txq_entry host_entry[ QUEUE_SIZE_TX ]; /* host resident tx queue entries */
735 int head; /* head of tx queue */
736+ int tail; /* tail of tx queue */
737 struct chunk tpd; /* array of tpds */
738 struct chunk status; /* arry of completion status */
739 int txing; /* number of pending PDUs in tx queue */
740@@ -626,8 +631,8 @@
741 struct chunk rbd_block; /* array of rbds */
742 struct chunk status; /* array of completion status */
743 struct buffer* buffer; /* array of rx buffers */
744- int free; /* index of first free rx buffer */
745- volatile int count; /* count of supplied rx buffers */
746+ struct buffer* freebuf; /* list of free rx buffers */
747+ volatile int freebuf_count; /* count of free rx buffers */
748 } host_bsq_t;
749
750
751@@ -879,8 +884,11 @@
752 struct stats* stats; /* last snapshot of the stats */
753
754 struct semaphore rate_sf; /* protects rate reservation ops */
755+#ifdef FORE200E_USE_TASKLET
756 struct tasklet_struct tasklet; /* performs interrupt work */
757-
758+#endif
759+ volatile int tx_bit; /* 'in tx code' flag */
760+ unsigned long tx_sat; /* tx queue saturation count */
761 } fore200e_t;
762
763
764--- /dev/null Thu Jan 1 01:00:00 1970
765+++ linux-2.4.20/drivers/atm/fore200e.CHANGES Mon Dec 4 14:34:31 2000
766@@ -0,0 +1,207 @@
767+Version 0.3 (December, 1, 2000)
768+-------------------------------
769+
770+ this version should fix some of the bugs introduced
771+ in the preceding releases (and thus should introduce new ones :-)
772+
773+ - fix the bug in the sparc64-specific part of
774+ fore200e_pca_dma_chunk_alloc(): chunk->alloc_size was
775+ left uninitialized.
776+ - rewrite the management of the buffer supply queues:
777+ now use per-queue linked-lists of free buffers.
778+ - the debugging code that audits the sanity of the free buffers
779+ lists can be enabled by the FORE200E_BSQ_DEBUG define.
780+ - check that a VCC is ready before playing with it.
781+ - fix bugs in the management of the tx queue. note that ENOBUFS is
782+ now returned in case of tx queue saturation: this prevent
783+ ttcp_atm to give up immediately if this event occurs.
784+ - count of tx queue saturation occurrences appended to the
785+ auxiliary statistics.
786+ - minor cosmetic changes.
787+
788+
789+Version 0.2g (July, 16, 2000)
790+-----------------------------
791+
792+ this release includes some experimental changes to
793+ the tx/interrupt code. It's an attempt to improve
794+ the schedulability of the driver and its performances.
795+
796+ - interrupts are no longer disabled to protect the
797+ critical section of the tx code. As a consequence,
798+ the rx processing may no longer be delayed by the
799+ tx processing.
800+ - handling of completed tx entries is improved
801+ thanks to a tail queue pointer.
802+ - interrupt work can be performed by the intr handler
803+ or can be deferred to a tasklet according to the
804+ FORE200E_USE_TASKLET define.
805+
806+
807+Version 0.2f (May, 21, 2000)
808+----------------------------
809+
810+ this is just the 'official' release of the preceding version.
811+ It also fixes a buglet spotted by Mitchell Blank Jr.
812+
813+ - the driver no longer mess with vcc->timestamp.
814+
815+
816+Version 0.2e (May, 8, 2000)
817+---------------------------
818+
819+ this is an experimental version, intended as a first attempt
820+ to fix the lockup problems encountered by a few users
821+ under heavy loads/SMP (probably introduced with the tasklet
822+ code).
823+
824+ - use the spin_lock_bh() machinery to guard the
825+ critical section of the tx code.
826+ - minor fix to the Makefile test that tells the target
827+ endianess from <asm/byteorder.h>.
828+
829+
830+Version 0.2d (Mar, 28, 2000)
831+----------------------------
832+
833+ - fix fatal bug in fore200e_open(): the ATM_VF_READY flag
834+ should be set, not cleared!
835+ - fix SBUS DMA direction flags.
836+ - move interrupt handler work to tasklet.
837+ - the compile no longer fails when the driver is compiled
838+ without any hardware support (i.e. with both PCA and SBA
839+ support disabled) (spotted by Arjan van de Ven). Also display
840+ a message to warn the user.
841+
842+
843+Version 0.2c (Mar, 23, 2000)
844+----------------------------
845+
846+ this is a minor interim release. It does not provide significant
847+ improvement to the driver code.
848+
849+ - initiate transition to the new-style PCI driver support.
850+ - minor cosmetic changes.
851+ - fix typos in Documentation/networking/fore200e.txt.
852+
853+
854+Version 0.2b (Feb, 23, 2000)
855+----------------------------
856+
857+ - update of PCI and SBUS DVMA code to 2.3.47-7 (DVMA functions
858+ now have a 'direction' argument).
859+
860+
861+Version 0.2a (Feb, 11, 2000)
862+----------------------------
863+
864+ this release completes the transition of the driver to the new
865+ DVMA interface. Many thanks to Marconi Networks (formerly FORE
866+ Systems) for having placed their binary firmware images under GPL.
867+
868+ - switch to the new PCI interface (requires 2.3.42+).
869+ - minor code cleanup.
870+ - add FORE firmware copyright notice.
871+
872+
873+Version 0.2 (Jan, 22, 2000)
874+---------------------------
875+
876+ as the driver is now shipped with the regular linux-atm
877+ distributions, it is now released as a diff against the latest
878+ linux-atm code.
879+
880+ - drop support of 2.2.x and pre-2.3.36 kernels.
881+ - switch to the new SBUS interface.
882+
883+
884+Version 0.1f (Jan, 22, 2000)
885+----------------------------
886+
887+ this is an interim release that makes the driver ready for the
888+ important 2.3.35+ transition. Significant parts of the driver
889+ have been rewritten to comply to the principles of the new SBUS
890+ interface introduced by the latest 2.3 kernels.
891+
892+ - clean code.
893+ - rewrite memory management routines.
894+ - rewrite DMA/DVMA management routines.
895+ - rewrite I/O management routines (and fix design weakness).
896+ - fix a bug in the initialization of the buffer supply queue.
897+ - cmd polling now gives up immediately if an error condition
898+ is detected.
899+
900+ note that the driver remains useable with 2.2 and earlier 2.3 kernels,
901+ but future releases will drop support of pre-2.3.36 kernels.
902+
903+
904+Version 0.1e (Dec, 23, 1999)
905+----------------------------
906+
907+ - support of S/UNI hardware loopback modes via SUNI_GETLOOP/SUNI_SETLOOP
908+ ioctls.
909+ - add the related ioctl entries in arch/sparc64/kernel/ioctl32.c.
910+ - add a simple 'sunimode' utility to get/set the S/UNI loopback mode
911+ (should also work with all the drivers that use suni.c/suni.h).
912+ - fix handling of 52-byte AAL0 SDUs used by atmdump-like applications:
913+ * if qos.txtp.max_sdu == 52, the following tx SDU format is expected
914+ by the driver:
915+ <4-byte cell header><48-byte AAL0 payload>[<48-byte AAL0 payload>...]
916+ i.e.
917+ <--- 52-byte AAL0 SDU used by atmdump --->[<- opt. extra payloads ->]
918+ otherwise, the following tx SDU format is assumed:
919+ <48-byte AAL0 payload>[<48-byte AAL0 payload>...]
920+ * if qos.txtp.max_sdu == 52, the rx SDUs are delivered as follows:
921+ <4-byte cell header><48-byte AAL0 payload>
922+ i.e.
923+ <- 52-byte AAL0 SDU expected by atmdump ->
924+ otherwise, the SDUs are delivered as: <48-byte AAL0 payload>
925+
926+
927+Version 0.1d (Dec, 16, 1999)
928+----------------------------
929+
930+ - add a retry mechanism so that the driver does not immediately give up
931+ if the tx queue is saturated. Saturation of the transmit queue may occur
932+ under extreme conditions, when a fast host continuously submits very
933+ small frames or raw AAL0 cells.
934+ - add a new config option to tune the retry mecanism.
935+ - improve AAL0 support. Attempting to transmit incomplete cell payloads
936+ over an AAL0 VC simply used to nuke the PCA board.
937+
938+
939+Version 0.1c (Nov, 22, 1999)
940+----------------------------
941+
942+ - endian-dependent code no longer depends on arch-specific definitions
943+ (e.g. __powerpc__ or __sparc_v9__) but on __BIG_ENDIAN/__LITTLE_ENDIAN
944+ - the right PCA-200E firmware is no longer selected according to
945+ a list of well-known archs in Config.in, but is guessed from
946+ <asm/byteorder.h> in Makefile.
947+ - rbd/rsd handles now use the FORE200E_BUF2HDL() and FORE200E_HDL2BUF()
948+ macros.
949+ - minor cosmetic changes.
950+ - spend some time playing with AAL0. Seems to work with MTU = 48 bytes.
951+
952+
953+Version 0.1b (Nov, 16, 1999)
954+----------------------------
955+
956+ - improve the configuration process in order to avoid confusion
957+ caused by the firmware stuff.
958+ - update accordingly the build process and the help file.
959+
960+ (note that the driver code is unchanged)
961+
962+
963+Version 0.1a (Nov, 2, 1999)
964+---------------------------
965+
966+ - use new mutex initializer in 2.3.1+ kernels.
967+ - add CHANGES file.
968+
969+
970+Version 0.1 (Oct, 25, 1999)
971+---------------------------
972+
973+ - first public release
974--- /dev/null Thu Jan 1 01:00:00 1970
975+++ linux-2.4.20/drivers/atm/fore200e.README Mon Dec 4 14:34:31 2000
976@@ -0,0 +1,79 @@
977+
978+linux-2.4.0-test9-fore200e-0.3.tar
979+----------------------------------
980+
981+This package updates the support of the FORE Systems 200E-series ATM
982+adapters by the Linux operating system. Note that the driver itself is
983+now distributed with the regular Linux kernel distribution.
984+
985+It is based on the earlier PCA-200E driver written by Uwe Dannowski.
986+
987+This device driver simultaneously supports PCA-200E and SBA-200E adapters on
988+i386, alpha (untested), powerpc, sparc and sparc64 hosts.
989+
990+The intent is to enable the use of different models of FORE adapters at the
991+same time, by servers that have several bus interfaces (such as PCI+SBUS,
992+PCI+MCA or PCI+EISA).
993+Only PCI and SBUS devices are currently supported by the driver, but support
994+for other bus interfaces such as EISA should not be too hard to add (this may
995+be more tricky for the MCA bus, though, as FORE made some MCA-specific
996+modifications to the adapter's AALI interface).
997+
998+The driver is shipped with firmware data being uploaded to the ATM adapters
999+at system boot time or at module loading time. The supplied firmware images
1000+should work with all adapters.
1001+
1002+However, if you encounter problems (the firmware doesn't start or the driver
1003+is unable to read the PROM data), you may consider trying another firmware
1004+version. Alternative binary firmware images can be found somewhere on the
1005+ForeThough CD-ROM supplied with your adapter by FORE Systems.
1006+
1007+You can also get the latest firmware images from FORE Systems at
1008+http://www.fore.com. Register TACTics Online and go to
1009+the 'software updates' pages. The firmware binaries are part of
1010+the various ForeThough software distributions.
1011+
1012+Notice that different versions of the PCA-200E firmware exist, depending
1013+on the endianess of the host architecture. The driver is shipped with
1014+both little and big endian PCA firmware images.
1015+
1016+Name and location of the alternative firmware images can be set at kernel
1017+configuration time. See the INSTALL file for details.
1018+
1019+Also note that the firmware binaries are the intellectual property
1020+of FORE Systems, Inc. Please read the fore200e_firmware_copyright file.
1021+
1022+
1023+
1024+Driver features summary
1025+-----------------------
1026+
1027+ - simultaneously supports PCA-200E and SBA-200E adapters;
1028+ - works on i386, powerpc, SBUS-based sparc and
1029+ SBUS or PCI-based sparc64 architectures;
1030+ - now targeted to 2.4.0-test9 kernels;
1031+ - uses new DVMA PCI and SBUS interfaces;
1032+ - useable as a removable kernel module;
1033+ - supports FORE pseudo-CBR rate control;
1034+ - the reserved CBR rate can be changed after VC setup;
1035+ - supports AAL0, AAL3/4 and AAL5;
1036+ - supports S/UNI hardware loopback modes;
1037+ - internal design focuses on portability and extensibility.
1038+
1039+
1040+Restrictions / Known bugs
1041+-------------------------
1042+
1043+ - only VP=0 is supported;
1044+ - 'insmod' coredumps when attempting to load the driver on sparc64
1045+ hosts (at least using the old Ultrapenguin 1.1.9 distribution);
1046+ - some memory resources cannot be freed on sparc, sparc64 and powerpc,
1047+ because the required support is still missing in 2.2 and 2.3 kernels.
1048+ You shouldn't try to unload the module driver on these platforms.
1049+
1050+
1051+Feedback
1052+--------
1053+
1054+Feedback is welcome. Please send success stories/bug reports/
1055+patches/improvement/comments/flames to <lizzi@cnam.fr>.
This page took 0.246484 seconds and 4 git commands to generate.