]> git.pld-linux.org Git - packages/kernel.git/blob - atm-21-fore200e-0.3.patch
- obsolete
[packages/kernel.git] / atm-21-fore200e-0.3.patch
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.101658 seconds and 3 git commands to generate.