blob: 4aeb3d062ff6d52630834147015e1c33c039e314 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 $Id: fore200e.c,v 1.5 2000/04/14 10:10:34 davem Exp $
3
4 A FORE Systems 200E-series driver for ATM on Linux.
5 Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2003.
6
7 Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
8
9 This driver simultaneously supports PCA-200E and SBA-200E adapters
10 on i386, alpha (untested), powerpc, sparc and sparc64 architectures.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/kernel.h>
29#include <linux/slab.h>
30#include <linux/init.h>
31#include <linux/capability.h>
32#include <linux/sched.h>
33#include <linux/interrupt.h>
34#include <linux/bitops.h>
35#include <linux/pci.h>
36#include <linux/module.h>
37#include <linux/atmdev.h>
38#include <linux/sonet.h>
39#include <linux/atm_suni.h>
40#include <linux/dma-mapping.h>
41#include <linux/delay.h>
42#include <asm/io.h>
43#include <asm/string.h>
44#include <asm/page.h>
45#include <asm/irq.h>
46#include <asm/dma.h>
47#include <asm/byteorder.h>
48#include <asm/uaccess.h>
49#include <asm/atomic.h>
50
51#ifdef CONFIG_ATM_FORE200E_SBA
52#include <asm/idprom.h>
53#include <asm/sbus.h>
54#include <asm/openprom.h>
55#include <asm/oplib.h>
56#include <asm/pgtable.h>
57#endif
58
59#if defined(CONFIG_ATM_FORE200E_USE_TASKLET) /* defer interrupt work to a tasklet */
60#define FORE200E_USE_TASKLET
61#endif
62
63#if 0 /* enable the debugging code of the buffer supply queues */
64#define FORE200E_BSQ_DEBUG
65#endif
66
67#if 1 /* ensure correct handling of 52-byte AAL0 SDUs expected by atmdump-like apps */
68#define FORE200E_52BYTE_AAL0_SDU
69#endif
70
71#include "fore200e.h"
72#include "suni.h"
73
74#define FORE200E_VERSION "0.3e"
75
76#define FORE200E "fore200e: "
77
78#if 0 /* override .config */
79#define CONFIG_ATM_FORE200E_DEBUG 1
80#endif
81#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
82#define DPRINTK(level, format, args...) do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
83 printk(FORE200E format, ##args); } while (0)
84#else
85#define DPRINTK(level, format, args...) do {} while (0)
86#endif
87
88
89#define FORE200E_ALIGN(addr, alignment) \
90 ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr))
91
92#define FORE200E_DMA_INDEX(dma_addr, type, index) ((dma_addr) + (index) * sizeof(type))
93
94#define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ])
95
96#define FORE200E_NEXT_ENTRY(index, modulo) (index = ++(index) % (modulo))
97
98#if 1
99#define ASSERT(expr) if (!(expr)) { \
100 printk(FORE200E "assertion failed! %s[%d]: %s\n", \
101 __FUNCTION__, __LINE__, #expr); \
102 panic(FORE200E "%s", __FUNCTION__); \
103 }
104#else
105#define ASSERT(expr) do {} while (0)
106#endif
107
108
109static const struct atmdev_ops fore200e_ops;
110static const struct fore200e_bus fore200e_bus[];
111
112static LIST_HEAD(fore200e_boards);
113
114
115MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
116MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION);
117MODULE_SUPPORTED_DEVICE("PCA-200E, SBA-200E");
118
119
120static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
121 { BUFFER_S1_NBR, BUFFER_L1_NBR },
122 { BUFFER_S2_NBR, BUFFER_L2_NBR }
123};
124
125static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
126 { BUFFER_S1_SIZE, BUFFER_L1_SIZE },
127 { BUFFER_S2_SIZE, BUFFER_L2_SIZE }
128};
129
130
131#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
132static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" };
133#endif
134
135
136#if 0 /* currently unused */
137static int
138fore200e_fore2atm_aal(enum fore200e_aal aal)
139{
140 switch(aal) {
141 case FORE200E_AAL0: return ATM_AAL0;
142 case FORE200E_AAL34: return ATM_AAL34;
143 case FORE200E_AAL5: return ATM_AAL5;
144 }
145
146 return -EINVAL;
147}
148#endif
149
150
151static enum fore200e_aal
152fore200e_atm2fore_aal(int aal)
153{
154 switch(aal) {
155 case ATM_AAL0: return FORE200E_AAL0;
156 case ATM_AAL34: return FORE200E_AAL34;
157 case ATM_AAL1:
158 case ATM_AAL2:
159 case ATM_AAL5: return FORE200E_AAL5;
160 }
161
162 return -EINVAL;
163}
164
165
166static char*
167fore200e_irq_itoa(int irq)
168{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169 static char str[8];
170 sprintf(str, "%d", irq);
171 return str;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172}
173
174
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175/* allocate and align a chunk of memory intended to hold the data behing exchanged
176 between the driver and the adapter (using streaming DVMA) */
177
178static int
179fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment, int direction)
180{
181 unsigned long offset = 0;
182
183 if (alignment <= sizeof(int))
184 alignment = 0;
185
186 chunk->alloc_size = size + alignment;
187 chunk->align_size = size;
188 chunk->direction = direction;
189
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -0800190 chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 if (chunk->alloc_addr == NULL)
192 return -ENOMEM;
193
194 if (alignment > 0)
195 offset = FORE200E_ALIGN(chunk->alloc_addr, alignment);
196
197 chunk->align_addr = chunk->alloc_addr + offset;
198
199 chunk->dma_addr = fore200e->bus->dma_map(fore200e, chunk->align_addr, chunk->align_size, direction);
200
201 return 0;
202}
203
204
205/* free a chunk of memory */
206
207static void
208fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
209{
210 fore200e->bus->dma_unmap(fore200e, chunk->dma_addr, chunk->dma_size, chunk->direction);
211
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -0800212 kfree(chunk->alloc_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213}
214
215
216static void
217fore200e_spin(int msecs)
218{
219 unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
220 while (time_before(jiffies, timeout));
221}
222
223
224static int
225fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
226{
227 unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
228 int ok;
229
230 mb();
231 do {
232 if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
233 break;
234
235 } while (time_before(jiffies, timeout));
236
237#if 1
238 if (!ok) {
239 printk(FORE200E "cmd polling failed, got status 0x%08x, expected 0x%08x\n",
240 *addr, val);
241 }
242#endif
243
244 return ok;
245}
246
247
248static int
249fore200e_io_poll(struct fore200e* fore200e, volatile u32 __iomem *addr, u32 val, int msecs)
250{
251 unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
252 int ok;
253
254 do {
255 if ((ok = (fore200e->bus->read(addr) == val)))
256 break;
257
258 } while (time_before(jiffies, timeout));
259
260#if 1
261 if (!ok) {
262 printk(FORE200E "I/O polling failed, got status 0x%08x, expected 0x%08x\n",
263 fore200e->bus->read(addr), val);
264 }
265#endif
266
267 return ok;
268}
269
270
271static void
272fore200e_free_rx_buf(struct fore200e* fore200e)
273{
274 int scheme, magn, nbr;
275 struct buffer* buffer;
276
277 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
278 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
279
280 if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) {
281
282 for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) {
283
284 struct chunk* data = &buffer[ nbr ].data;
285
286 if (data->alloc_addr != NULL)
287 fore200e_chunk_free(fore200e, data);
288 }
289 }
290 }
291 }
292}
293
294
295static void
296fore200e_uninit_bs_queue(struct fore200e* fore200e)
297{
298 int scheme, magn;
299
300 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
301 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
302
303 struct chunk* status = &fore200e->host_bsq[ scheme ][ magn ].status;
304 struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block;
305
306 if (status->alloc_addr)
307 fore200e->bus->dma_chunk_free(fore200e, status);
308
309 if (rbd_block->alloc_addr)
310 fore200e->bus->dma_chunk_free(fore200e, rbd_block);
311 }
312 }
313}
314
315
316static int
317fore200e_reset(struct fore200e* fore200e, int diag)
318{
319 int ok;
320
321 fore200e->cp_monitor = fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET;
322
323 fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat);
324
325 fore200e->bus->reset(fore200e);
326
327 if (diag) {
328 ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000);
329 if (ok == 0) {
330
331 printk(FORE200E "device %s self-test failed\n", fore200e->name);
332 return -ENODEV;
333 }
334
335 printk(FORE200E "device %s self-test passed\n", fore200e->name);
336
337 fore200e->state = FORE200E_STATE_RESET;
338 }
339
340 return 0;
341}
342
343
344static void
345fore200e_shutdown(struct fore200e* fore200e)
346{
347 printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n",
348 fore200e->name, fore200e->phys_base,
349 fore200e_irq_itoa(fore200e->irq));
350
351 if (fore200e->state > FORE200E_STATE_RESET) {
352 /* first, reset the board to prevent further interrupts or data transfers */
353 fore200e_reset(fore200e, 0);
354 }
355
356 /* then, release all allocated resources */
357 switch(fore200e->state) {
358
359 case FORE200E_STATE_COMPLETE:
Jesper Juhla2c1aa52005-06-02 13:04:07 -0700360 kfree(fore200e->stats);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
362 case FORE200E_STATE_IRQ:
363 free_irq(fore200e->irq, fore200e->atm_dev);
364
365 case FORE200E_STATE_ALLOC_BUF:
366 fore200e_free_rx_buf(fore200e);
367
368 case FORE200E_STATE_INIT_BSQ:
369 fore200e_uninit_bs_queue(fore200e);
370
371 case FORE200E_STATE_INIT_RXQ:
372 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.status);
373 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.rpd);
374
375 case FORE200E_STATE_INIT_TXQ:
376 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.status);
377 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.tpd);
378
379 case FORE200E_STATE_INIT_CMDQ:
380 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_cmdq.status);
381
382 case FORE200E_STATE_INITIALIZE:
383 /* nothing to do for that state */
384
385 case FORE200E_STATE_START_FW:
386 /* nothing to do for that state */
387
388 case FORE200E_STATE_LOAD_FW:
389 /* nothing to do for that state */
390
391 case FORE200E_STATE_RESET:
392 /* nothing to do for that state */
393
394 case FORE200E_STATE_MAP:
395 fore200e->bus->unmap(fore200e);
396
397 case FORE200E_STATE_CONFIGURE:
398 /* nothing to do for that state */
399
400 case FORE200E_STATE_REGISTER:
401 /* XXX shouldn't we *start* by deregistering the device? */
402 atm_dev_deregister(fore200e->atm_dev);
403
404 case FORE200E_STATE_BLANK:
405 /* nothing to do for that state */
406 break;
407 }
408}
409
410
411#ifdef CONFIG_ATM_FORE200E_PCA
412
413static u32 fore200e_pca_read(volatile u32 __iomem *addr)
414{
415 /* on big-endian hosts, the board is configured to convert
416 the endianess of slave RAM accesses */
417 return le32_to_cpu(readl(addr));
418}
419
420
421static void fore200e_pca_write(u32 val, volatile u32 __iomem *addr)
422{
423 /* on big-endian hosts, the board is configured to convert
424 the endianess of slave RAM accesses */
425 writel(cpu_to_le32(val), addr);
426}
427
428
429static u32
430fore200e_pca_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction)
431{
432 u32 dma_addr = pci_map_single((struct pci_dev*)fore200e->bus_dev, virt_addr, size, direction);
433
434 DPRINTK(3, "PCI DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d, --> dma_addr = 0x%08x\n",
435 virt_addr, size, direction, dma_addr);
436
437 return dma_addr;
438}
439
440
441static void
442fore200e_pca_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
443{
444 DPRINTK(3, "PCI DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d\n",
445 dma_addr, size, direction);
446
447 pci_unmap_single((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction);
448}
449
450
451static void
452fore200e_pca_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
453{
454 DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
455
456 pci_dma_sync_single_for_cpu((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction);
457}
458
459static void
460fore200e_pca_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
461{
462 DPRINTK(3, "PCI DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
463
464 pci_dma_sync_single_for_device((struct pci_dev*)fore200e->bus_dev, dma_addr, size, direction);
465}
466
467
468/* allocate a DMA consistent chunk of memory intended to act as a communication mechanism
469 (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
470
471static int
472fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk,
473 int size, int nbr, int alignment)
474{
475 /* returned chunks are page-aligned */
476 chunk->alloc_size = size * nbr;
477 chunk->alloc_addr = pci_alloc_consistent((struct pci_dev*)fore200e->bus_dev,
478 chunk->alloc_size,
479 &chunk->dma_addr);
480
481 if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
482 return -ENOMEM;
483
484 chunk->align_addr = chunk->alloc_addr;
485
486 return 0;
487}
488
489
490/* free a DMA consistent chunk of memory */
491
492static void
493fore200e_pca_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
494{
495 pci_free_consistent((struct pci_dev*)fore200e->bus_dev,
496 chunk->alloc_size,
497 chunk->alloc_addr,
498 chunk->dma_addr);
499}
500
501
502static int
503fore200e_pca_irq_check(struct fore200e* fore200e)
504{
505 /* this is a 1 bit register */
506 int irq_posted = readl(fore200e->regs.pca.psr);
507
508#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG == 2)
509 if (irq_posted && (readl(fore200e->regs.pca.hcr) & PCA200E_HCR_OUTFULL)) {
510 DPRINTK(2,"FIFO OUT full, device %d\n", fore200e->atm_dev->number);
511 }
512#endif
513
514 return irq_posted;
515}
516
517
518static void
519fore200e_pca_irq_ack(struct fore200e* fore200e)
520{
521 writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr);
522}
523
524
525static void
526fore200e_pca_reset(struct fore200e* fore200e)
527{
528 writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr);
529 fore200e_spin(10);
530 writel(0, fore200e->regs.pca.hcr);
531}
532
533
Sam Ravnborgc027f5f2006-03-03 17:50:37 -0800534static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535fore200e_pca_map(struct fore200e* fore200e)
536{
537 DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
538
539 fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH);
540
541 if (fore200e->virt_base == NULL) {
542 printk(FORE200E "can't map device %s\n", fore200e->name);
543 return -EFAULT;
544 }
545
546 DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
547
548 /* gain access to the PCA specific registers */
549 fore200e->regs.pca.hcr = fore200e->virt_base + PCA200E_HCR_OFFSET;
550 fore200e->regs.pca.imr = fore200e->virt_base + PCA200E_IMR_OFFSET;
551 fore200e->regs.pca.psr = fore200e->virt_base + PCA200E_PSR_OFFSET;
552
553 fore200e->state = FORE200E_STATE_MAP;
554 return 0;
555}
556
557
558static void
559fore200e_pca_unmap(struct fore200e* fore200e)
560{
561 DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
562
563 if (fore200e->virt_base != NULL)
564 iounmap(fore200e->virt_base);
565}
566
567
Sam Ravnborgc027f5f2006-03-03 17:50:37 -0800568static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569fore200e_pca_configure(struct fore200e* fore200e)
570{
571 struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev;
572 u8 master_ctrl, latency;
573
574 DPRINTK(2, "device %s being configured\n", fore200e->name);
575
576 if ((pci_dev->irq == 0) || (pci_dev->irq == 0xFF)) {
577 printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n");
578 return -EIO;
579 }
580
581 pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl);
582
583 master_ctrl = master_ctrl
584#if defined(__BIG_ENDIAN)
585 /* request the PCA board to convert the endianess of slave RAM accesses */
586 | PCA200E_CTRL_CONVERT_ENDIAN
587#endif
588#if 0
589 | PCA200E_CTRL_DIS_CACHE_RD
590 | PCA200E_CTRL_DIS_WRT_INVAL
591 | PCA200E_CTRL_ENA_CONT_REQ_MODE
592 | PCA200E_CTRL_2_CACHE_WRT_INVAL
593#endif
594 | PCA200E_CTRL_LARGE_PCI_BURSTS;
595
596 pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl);
597
598 /* raise latency from 32 (default) to 192, as this seems to prevent NIC
599 lockups (under heavy rx loads) due to continuous 'FIFO OUT full' condition.
600 this may impact the performances of other PCI devices on the same bus, though */
601 latency = 192;
602 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
603
604 fore200e->state = FORE200E_STATE_CONFIGURE;
605 return 0;
606}
607
608
609static int __init
610fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
611{
612 struct host_cmdq* cmdq = &fore200e->host_cmdq;
613 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
614 struct prom_opcode opcode;
615 int ok;
616 u32 prom_dma;
617
618 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
619
620 opcode.opcode = OPCODE_GET_PROM;
621 opcode.pad = 0;
622
623 prom_dma = fore200e->bus->dma_map(fore200e, prom, sizeof(struct prom_data), DMA_FROM_DEVICE);
624
625 fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
626
627 *entry->status = STATUS_PENDING;
628
629 fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.prom_block.opcode);
630
631 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
632
633 *entry->status = STATUS_FREE;
634
635 fore200e->bus->dma_unmap(fore200e, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
636
637 if (ok == 0) {
638 printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
639 return -EIO;
640 }
641
642#if defined(__BIG_ENDIAN)
643
644#define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) ))
645
646 /* MAC address is stored as little-endian */
647 swap_here(&prom->mac_addr[0]);
648 swap_here(&prom->mac_addr[4]);
649#endif
650
651 return 0;
652}
653
654
655static int
656fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
657{
658 struct pci_dev* pci_dev = (struct pci_dev*)fore200e->bus_dev;
659
660 return sprintf(page, " PCI bus/slot/function:\t%d/%d/%d\n",
661 pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
662}
663
664#endif /* CONFIG_ATM_FORE200E_PCA */
665
666
667#ifdef CONFIG_ATM_FORE200E_SBA
668
669static u32
670fore200e_sba_read(volatile u32 __iomem *addr)
671{
672 return sbus_readl(addr);
673}
674
675
676static void
677fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
678{
679 sbus_writel(val, addr);
680}
681
682
683static u32
684fore200e_sba_dma_map(struct fore200e* fore200e, void* virt_addr, int size, int direction)
685{
686 u32 dma_addr = sbus_map_single((struct sbus_dev*)fore200e->bus_dev, virt_addr, size, direction);
687
688 DPRINTK(3, "SBUS DVMA mapping: virt_addr = 0x%p, size = %d, direction = %d --> dma_addr = 0x%08x\n",
689 virt_addr, size, direction, dma_addr);
690
691 return dma_addr;
692}
693
694
695static void
696fore200e_sba_dma_unmap(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
697{
698 DPRINTK(3, "SBUS DVMA unmapping: dma_addr = 0x%08x, size = %d, direction = %d,\n",
699 dma_addr, size, direction);
700
701 sbus_unmap_single((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
702}
703
704
705static void
706fore200e_sba_dma_sync_for_cpu(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
707{
708 DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
709
710 sbus_dma_sync_single_for_cpu((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
711}
712
713static void
714fore200e_sba_dma_sync_for_device(struct fore200e* fore200e, u32 dma_addr, int size, int direction)
715{
716 DPRINTK(3, "SBUS DVMA sync: dma_addr = 0x%08x, size = %d, direction = %d\n", dma_addr, size, direction);
717
718 sbus_dma_sync_single_for_device((struct sbus_dev*)fore200e->bus_dev, dma_addr, size, direction);
719}
720
721
722/* allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
723 (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
724
725static int
726fore200e_sba_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk,
727 int size, int nbr, int alignment)
728{
729 chunk->alloc_size = chunk->align_size = size * nbr;
730
731 /* returned chunks are page-aligned */
732 chunk->alloc_addr = sbus_alloc_consistent((struct sbus_dev*)fore200e->bus_dev,
733 chunk->alloc_size,
734 &chunk->dma_addr);
735
736 if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
737 return -ENOMEM;
738
739 chunk->align_addr = chunk->alloc_addr;
740
741 return 0;
742}
743
744
745/* free a DVMA consistent chunk of memory */
746
747static void
748fore200e_sba_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
749{
750 sbus_free_consistent((struct sbus_dev*)fore200e->bus_dev,
751 chunk->alloc_size,
752 chunk->alloc_addr,
753 chunk->dma_addr);
754}
755
756
757static void
758fore200e_sba_irq_enable(struct fore200e* fore200e)
759{
760 u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
761 fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
762}
763
764
765static int
766fore200e_sba_irq_check(struct fore200e* fore200e)
767{
768 return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
769}
770
771
772static void
773fore200e_sba_irq_ack(struct fore200e* fore200e)
774{
775 u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
776 fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
777}
778
779
780static void
781fore200e_sba_reset(struct fore200e* fore200e)
782{
783 fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
784 fore200e_spin(10);
785 fore200e->bus->write(0, fore200e->regs.sba.hcr);
786}
787
788
789static int __init
790fore200e_sba_map(struct fore200e* fore200e)
791{
792 struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
793 unsigned int bursts;
794
795 /* gain access to the SBA specific registers */
796 fore200e->regs.sba.hcr = sbus_ioremap(&sbus_dev->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
797 fore200e->regs.sba.bsr = sbus_ioremap(&sbus_dev->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
798 fore200e->regs.sba.isr = sbus_ioremap(&sbus_dev->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
799 fore200e->virt_base = sbus_ioremap(&sbus_dev->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
800
801 if (fore200e->virt_base == NULL) {
802 printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
803 return -EFAULT;
804 }
805
806 DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
807
808 fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
809
810 /* get the supported DVMA burst sizes */
811 bursts = prom_getintdefault(sbus_dev->bus->prom_node, "burst-sizes", 0x00);
812
813 if (sbus_can_dma_64bit(sbus_dev))
814 sbus_set_sbus64(sbus_dev, bursts);
815
816 fore200e->state = FORE200E_STATE_MAP;
817 return 0;
818}
819
820
821static void
822fore200e_sba_unmap(struct fore200e* fore200e)
823{
824 sbus_iounmap(fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
825 sbus_iounmap(fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
826 sbus_iounmap(fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
827 sbus_iounmap(fore200e->virt_base, SBA200E_RAM_LENGTH);
828}
829
830
831static int __init
832fore200e_sba_configure(struct fore200e* fore200e)
833{
834 fore200e->state = FORE200E_STATE_CONFIGURE;
835 return 0;
836}
837
838
839static struct fore200e* __init
840fore200e_sba_detect(const struct fore200e_bus* bus, int index)
841{
842 struct fore200e* fore200e;
843 struct sbus_bus* sbus_bus;
844 struct sbus_dev* sbus_dev = NULL;
845
846 unsigned int count = 0;
847
848 for_each_sbus (sbus_bus) {
849 for_each_sbusdev (sbus_dev, sbus_bus) {
850 if (strcmp(sbus_dev->prom_name, SBA200E_PROM_NAME) == 0) {
851 if (count >= index)
852 goto found;
853 count++;
854 }
855 }
856 }
857 return NULL;
858
859 found:
860 if (sbus_dev->num_registers != 4) {
861 printk(FORE200E "this %s device has %d instead of 4 registers\n",
862 bus->model_name, sbus_dev->num_registers);
863 return NULL;
864 }
865
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -0800866 fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 if (fore200e == NULL)
868 return NULL;
869
870 fore200e->bus = bus;
871 fore200e->bus_dev = sbus_dev;
872 fore200e->irq = sbus_dev->irqs[ 0 ];
873
874 fore200e->phys_base = (unsigned long)sbus_dev;
875
876 sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
877
878 return fore200e;
879}
880
881
882static int __init
883fore200e_sba_prom_read(struct fore200e* fore200e, struct prom_data* prom)
884{
885 struct sbus_dev* sbus_dev = (struct sbus_dev*) fore200e->bus_dev;
886 int len;
887
888 len = prom_getproperty(sbus_dev->prom_node, "macaddrlo2", &prom->mac_addr[ 4 ], 4);
889 if (len < 0)
890 return -EBUSY;
891
892 len = prom_getproperty(sbus_dev->prom_node, "macaddrhi4", &prom->mac_addr[ 2 ], 4);
893 if (len < 0)
894 return -EBUSY;
895
896 prom_getproperty(sbus_dev->prom_node, "serialnumber",
897 (char*)&prom->serial_number, sizeof(prom->serial_number));
898
899 prom_getproperty(sbus_dev->prom_node, "promversion",
900 (char*)&prom->hw_revision, sizeof(prom->hw_revision));
901
902 return 0;
903}
904
905
906static int
907fore200e_sba_proc_read(struct fore200e* fore200e, char *page)
908{
909 struct sbus_dev* sbus_dev = (struct sbus_dev*)fore200e->bus_dev;
910
911 return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name);
912}
913#endif /* CONFIG_ATM_FORE200E_SBA */
914
915
916static void
917fore200e_tx_irq(struct fore200e* fore200e)
918{
919 struct host_txq* txq = &fore200e->host_txq;
920 struct host_txq_entry* entry;
921 struct atm_vcc* vcc;
922 struct fore200e_vc_map* vc_map;
923
924 if (fore200e->host_txq.txing == 0)
925 return;
926
927 for (;;) {
928
929 entry = &txq->host_entry[ txq->tail ];
930
931 if ((*entry->status & STATUS_COMPLETE) == 0) {
932 break;
933 }
934
935 DPRINTK(3, "TX COMPLETED: entry = %p [tail = %d], vc_map = %p, skb = %p\n",
936 entry, txq->tail, entry->vc_map, entry->skb);
937
938 /* free copy of misaligned data */
Jesper Juhla2c1aa52005-06-02 13:04:07 -0700939 kfree(entry->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940
941 /* remove DMA mapping */
942 fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
943 DMA_TO_DEVICE);
944
945 vc_map = entry->vc_map;
946
947 /* vcc closed since the time the entry was submitted for tx? */
948 if ((vc_map->vcc == NULL) ||
949 (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
950
951 DPRINTK(1, "no ready vcc found for PDU sent on device %d\n",
952 fore200e->atm_dev->number);
953
954 dev_kfree_skb_any(entry->skb);
955 }
956 else {
957 ASSERT(vc_map->vcc);
958
959 /* vcc closed then immediately re-opened? */
960 if (vc_map->incarn != entry->incarn) {
961
962 /* when a vcc is closed, some PDUs may be still pending in the tx queue.
963 if the same vcc is immediately re-opened, those pending PDUs must
964 not be popped after the completion of their emission, as they refer
965 to the prior incarnation of that vcc. otherwise, sk_atm(vcc)->sk_wmem_alloc
966 would be decremented by the size of the (unrelated) skb, possibly
967 leading to a negative sk->sk_wmem_alloc count, ultimately freezing the vcc.
968 we thus bind the tx entry to the current incarnation of the vcc
969 when the entry is submitted for tx. When the tx later completes,
970 if the incarnation number of the tx entry does not match the one
971 of the vcc, then this implies that the vcc has been closed then re-opened.
972 we thus just drop the skb here. */
973
974 DPRINTK(1, "vcc closed-then-re-opened; dropping PDU sent on device %d\n",
975 fore200e->atm_dev->number);
976
977 dev_kfree_skb_any(entry->skb);
978 }
979 else {
980 vcc = vc_map->vcc;
981 ASSERT(vcc);
982
983 /* notify tx completion */
984 if (vcc->pop) {
985 vcc->pop(vcc, entry->skb);
986 }
987 else {
988 dev_kfree_skb_any(entry->skb);
989 }
990#if 1
991 /* race fixed by the above incarnation mechanism, but... */
992 if (atomic_read(&sk_atm(vcc)->sk_wmem_alloc) < 0) {
993 atomic_set(&sk_atm(vcc)->sk_wmem_alloc, 0);
994 }
995#endif
996 /* check error condition */
997 if (*entry->status & STATUS_ERROR)
998 atomic_inc(&vcc->stats->tx_err);
999 else
1000 atomic_inc(&vcc->stats->tx);
1001 }
1002 }
1003
1004 *entry->status = STATUS_FREE;
1005
1006 fore200e->host_txq.txing--;
1007
1008 FORE200E_NEXT_ENTRY(txq->tail, QUEUE_SIZE_TX);
1009 }
1010}
1011
1012
1013#ifdef FORE200E_BSQ_DEBUG
1014int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn)
1015{
1016 struct buffer* buffer;
1017 int count = 0;
1018
1019 buffer = bsq->freebuf;
1020 while (buffer) {
1021
1022 if (buffer->supplied) {
1023 printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld supplied but in free list!\n",
1024 where, scheme, magn, buffer->index);
1025 }
1026
1027 if (buffer->magn != magn) {
1028 printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected magn = %d\n",
1029 where, scheme, magn, buffer->index, buffer->magn);
1030 }
1031
1032 if (buffer->scheme != scheme) {
1033 printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected scheme = %d\n",
1034 where, scheme, magn, buffer->index, buffer->scheme);
1035 }
1036
1037 if ((buffer->index < 0) || (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ])) {
1038 printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
1039 where, scheme, magn, buffer->index);
1040 }
1041
1042 count++;
1043 buffer = buffer->next;
1044 }
1045
1046 if (count != bsq->freebuf_count) {
1047 printk(FORE200E "bsq_audit(%d): queue %d.%d, %d bufs in free list, but freebuf_count = %d\n",
1048 where, scheme, magn, count, bsq->freebuf_count);
1049 }
1050 return 0;
1051}
1052#endif
1053
1054
1055static void
1056fore200e_supply(struct fore200e* fore200e)
1057{
1058 int scheme, magn, i;
1059
1060 struct host_bsq* bsq;
1061 struct host_bsq_entry* entry;
1062 struct buffer* buffer;
1063
1064 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
1065 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
1066
1067 bsq = &fore200e->host_bsq[ scheme ][ magn ];
1068
1069#ifdef FORE200E_BSQ_DEBUG
1070 bsq_audit(1, bsq, scheme, magn);
1071#endif
1072 while (bsq->freebuf_count >= RBD_BLK_SIZE) {
1073
1074 DPRINTK(2, "supplying %d rx buffers to queue %d / %d, freebuf_count = %d\n",
1075 RBD_BLK_SIZE, scheme, magn, bsq->freebuf_count);
1076
1077 entry = &bsq->host_entry[ bsq->head ];
1078
1079 for (i = 0; i < RBD_BLK_SIZE; i++) {
1080
1081 /* take the first buffer in the free buffer list */
1082 buffer = bsq->freebuf;
1083 if (!buffer) {
1084 printk(FORE200E "no more free bufs in queue %d.%d, but freebuf_count = %d\n",
1085 scheme, magn, bsq->freebuf_count);
1086 return;
1087 }
1088 bsq->freebuf = buffer->next;
1089
1090#ifdef FORE200E_BSQ_DEBUG
1091 if (buffer->supplied)
1092 printk(FORE200E "queue %d.%d, buffer %lu already supplied\n",
1093 scheme, magn, buffer->index);
1094 buffer->supplied = 1;
1095#endif
1096 entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
1097 entry->rbd_block->rbd[ i ].handle = FORE200E_BUF2HDL(buffer);
1098 }
1099
1100 FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
1101
1102 /* decrease accordingly the number of free rx buffers */
1103 bsq->freebuf_count -= RBD_BLK_SIZE;
1104
1105 *entry->status = STATUS_PENDING;
1106 fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
1107 }
1108 }
1109 }
1110}
1111
1112
1113static int
1114fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rpd)
1115{
1116 struct sk_buff* skb;
1117 struct buffer* buffer;
1118 struct fore200e_vcc* fore200e_vcc;
1119 int i, pdu_len = 0;
1120#ifdef FORE200E_52BYTE_AAL0_SDU
1121 u32 cell_header = 0;
1122#endif
1123
1124 ASSERT(vcc);
1125
1126 fore200e_vcc = FORE200E_VCC(vcc);
1127 ASSERT(fore200e_vcc);
1128
1129#ifdef FORE200E_52BYTE_AAL0_SDU
1130 if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) {
1131
1132 cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) |
1133 (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) |
1134 (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) |
1135 (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) |
1136 rpd->atm_header.clp;
1137 pdu_len = 4;
1138 }
1139#endif
1140
1141 /* compute total PDU length */
1142 for (i = 0; i < rpd->nseg; i++)
1143 pdu_len += rpd->rsd[ i ].length;
1144
1145 skb = alloc_skb(pdu_len, GFP_ATOMIC);
1146 if (skb == NULL) {
1147 DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
1148
1149 atomic_inc(&vcc->stats->rx_drop);
1150 return -ENOMEM;
1151 }
1152
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001153 __net_timestamp(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154
1155#ifdef FORE200E_52BYTE_AAL0_SDU
1156 if (cell_header) {
1157 *((u32*)skb_put(skb, 4)) = cell_header;
1158 }
1159#endif
1160
1161 /* reassemble segments */
1162 for (i = 0; i < rpd->nseg; i++) {
1163
1164 /* rebuild rx buffer address from rsd handle */
1165 buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
1166
1167 /* Make device DMA transfer visible to CPU. */
1168 fore200e->bus->dma_sync_for_cpu(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, DMA_FROM_DEVICE);
1169
1170 memcpy(skb_put(skb, rpd->rsd[ i ].length), buffer->data.align_addr, rpd->rsd[ i ].length);
1171
1172 /* Now let the device get at it again. */
1173 fore200e->bus->dma_sync_for_device(fore200e, buffer->data.dma_addr, rpd->rsd[ i ].length, DMA_FROM_DEVICE);
1174 }
1175
1176 DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
1177
1178 if (pdu_len < fore200e_vcc->rx_min_pdu)
1179 fore200e_vcc->rx_min_pdu = pdu_len;
1180 if (pdu_len > fore200e_vcc->rx_max_pdu)
1181 fore200e_vcc->rx_max_pdu = pdu_len;
1182 fore200e_vcc->rx_pdu++;
1183
1184 /* push PDU */
1185 if (atm_charge(vcc, skb->truesize) == 0) {
1186
1187 DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n",
1188 vcc->itf, vcc->vpi, vcc->vci);
1189
1190 dev_kfree_skb_any(skb);
1191
1192 atomic_inc(&vcc->stats->rx_drop);
1193 return -ENOMEM;
1194 }
1195
1196 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
1197
1198 vcc->push(vcc, skb);
1199 atomic_inc(&vcc->stats->rx);
1200
1201 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
1202
1203 return 0;
1204}
1205
1206
1207static void
1208fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd)
1209{
1210 struct host_bsq* bsq;
1211 struct buffer* buffer;
1212 int i;
1213
1214 for (i = 0; i < rpd->nseg; i++) {
1215
1216 /* rebuild rx buffer address from rsd handle */
1217 buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
1218
1219 bsq = &fore200e->host_bsq[ buffer->scheme ][ buffer->magn ];
1220
1221#ifdef FORE200E_BSQ_DEBUG
1222 bsq_audit(2, bsq, buffer->scheme, buffer->magn);
1223
1224 if (buffer->supplied == 0)
1225 printk(FORE200E "queue %d.%d, buffer %ld was not supplied\n",
1226 buffer->scheme, buffer->magn, buffer->index);
1227 buffer->supplied = 0;
1228#endif
1229
1230 /* re-insert the buffer into the free buffer list */
1231 buffer->next = bsq->freebuf;
1232 bsq->freebuf = buffer;
1233
1234 /* then increment the number of free rx buffers */
1235 bsq->freebuf_count++;
1236 }
1237}
1238
1239
1240static void
1241fore200e_rx_irq(struct fore200e* fore200e)
1242{
1243 struct host_rxq* rxq = &fore200e->host_rxq;
1244 struct host_rxq_entry* entry;
1245 struct atm_vcc* vcc;
1246 struct fore200e_vc_map* vc_map;
1247
1248 for (;;) {
1249
1250 entry = &rxq->host_entry[ rxq->head ];
1251
1252 /* no more received PDUs */
1253 if ((*entry->status & STATUS_COMPLETE) == 0)
1254 break;
1255
1256 vc_map = FORE200E_VC_MAP(fore200e, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
1257
1258 if ((vc_map->vcc == NULL) ||
1259 (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
1260
1261 DPRINTK(1, "no ready VC found for PDU received on %d.%d.%d\n",
1262 fore200e->atm_dev->number,
1263 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
1264 }
1265 else {
1266 vcc = vc_map->vcc;
1267 ASSERT(vcc);
1268
1269 if ((*entry->status & STATUS_ERROR) == 0) {
1270
1271 fore200e_push_rpd(fore200e, vcc, entry->rpd);
1272 }
1273 else {
1274 DPRINTK(2, "damaged PDU on %d.%d.%d\n",
1275 fore200e->atm_dev->number,
1276 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
1277 atomic_inc(&vcc->stats->rx_err);
1278 }
1279 }
1280
1281 FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
1282
1283 fore200e_collect_rpd(fore200e, entry->rpd);
1284
1285 /* rewrite the rpd address to ack the received PDU */
1286 fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr);
1287 *entry->status = STATUS_FREE;
1288
1289 fore200e_supply(fore200e);
1290 }
1291}
1292
1293
1294#ifndef FORE200E_USE_TASKLET
1295static void
1296fore200e_irq(struct fore200e* fore200e)
1297{
1298 unsigned long flags;
1299
1300 spin_lock_irqsave(&fore200e->q_lock, flags);
1301 fore200e_rx_irq(fore200e);
1302 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1303
1304 spin_lock_irqsave(&fore200e->q_lock, flags);
1305 fore200e_tx_irq(fore200e);
1306 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1307}
1308#endif
1309
1310
1311static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +01001312fore200e_interrupt(int irq, void* dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313{
1314 struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
1315
1316 if (fore200e->bus->irq_check(fore200e) == 0) {
1317
1318 DPRINTK(3, "interrupt NOT triggered by device %d\n", fore200e->atm_dev->number);
1319 return IRQ_NONE;
1320 }
1321 DPRINTK(3, "interrupt triggered by device %d\n", fore200e->atm_dev->number);
1322
1323#ifdef FORE200E_USE_TASKLET
1324 tasklet_schedule(&fore200e->tx_tasklet);
1325 tasklet_schedule(&fore200e->rx_tasklet);
1326#else
1327 fore200e_irq(fore200e);
1328#endif
1329
1330 fore200e->bus->irq_ack(fore200e);
1331 return IRQ_HANDLED;
1332}
1333
1334
1335#ifdef FORE200E_USE_TASKLET
1336static void
1337fore200e_tx_tasklet(unsigned long data)
1338{
1339 struct fore200e* fore200e = (struct fore200e*) data;
1340 unsigned long flags;
1341
1342 DPRINTK(3, "tx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
1343
1344 spin_lock_irqsave(&fore200e->q_lock, flags);
1345 fore200e_tx_irq(fore200e);
1346 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1347}
1348
1349
1350static void
1351fore200e_rx_tasklet(unsigned long data)
1352{
1353 struct fore200e* fore200e = (struct fore200e*) data;
1354 unsigned long flags;
1355
1356 DPRINTK(3, "rx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
1357
1358 spin_lock_irqsave(&fore200e->q_lock, flags);
1359 fore200e_rx_irq((struct fore200e*) data);
1360 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1361}
1362#endif
1363
1364
1365static int
1366fore200e_select_scheme(struct atm_vcc* vcc)
1367{
1368 /* fairly balance the VCs over (identical) buffer schemes */
1369 int scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
1370
1371 DPRINTK(1, "VC %d.%d.%d uses buffer scheme %d\n",
1372 vcc->itf, vcc->vpi, vcc->vci, scheme);
1373
1374 return scheme;
1375}
1376
1377
1378static int
1379fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu)
1380{
1381 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1382 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1383 struct activate_opcode activ_opcode;
1384 struct deactivate_opcode deactiv_opcode;
1385 struct vpvc vpvc;
1386 int ok;
1387 enum fore200e_aal aal = fore200e_atm2fore_aal(vcc->qos.aal);
1388
1389 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1390
1391 if (activate) {
1392 FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc);
1393
1394 activ_opcode.opcode = OPCODE_ACTIVATE_VCIN;
1395 activ_opcode.aal = aal;
1396 activ_opcode.scheme = FORE200E_VCC(vcc)->scheme;
1397 activ_opcode.pad = 0;
1398 }
1399 else {
1400 deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN;
1401 deactiv_opcode.pad = 0;
1402 }
1403
1404 vpvc.vci = vcc->vci;
1405 vpvc.vpi = vcc->vpi;
1406
1407 *entry->status = STATUS_PENDING;
1408
1409 if (activate) {
1410
1411#ifdef FORE200E_52BYTE_AAL0_SDU
1412 mtu = 48;
1413#endif
1414 /* the MTU is not used by the cp, except in the case of AAL0 */
1415 fore200e->bus->write(mtu, &entry->cp_entry->cmd.activate_block.mtu);
1416 fore200e->bus->write(*(u32*)&vpvc, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.vpvc);
1417 fore200e->bus->write(*(u32*)&activ_opcode, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.opcode);
1418 }
1419 else {
1420 fore200e->bus->write(*(u32*)&vpvc, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.vpvc);
1421 fore200e->bus->write(*(u32*)&deactiv_opcode, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.opcode);
1422 }
1423
1424 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1425
1426 *entry->status = STATUS_FREE;
1427
1428 if (ok == 0) {
1429 printk(FORE200E "unable to %s VC %d.%d.%d\n",
1430 activate ? "open" : "close", vcc->itf, vcc->vpi, vcc->vci);
1431 return -EIO;
1432 }
1433
1434 DPRINTK(1, "VC %d.%d.%d %sed\n", vcc->itf, vcc->vpi, vcc->vci,
1435 activate ? "open" : "clos");
1436
1437 return 0;
1438}
1439
1440
1441#define FORE200E_MAX_BACK2BACK_CELLS 255 /* XXX depends on CDVT */
1442
1443static void
1444fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
1445{
1446 if (qos->txtp.max_pcr < ATM_OC3_PCR) {
1447
1448 /* compute the data cells to idle cells ratio from the tx PCR */
1449 rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR;
1450 rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells;
1451 }
1452 else {
1453 /* disable rate control */
1454 rate->data_cells = rate->idle_cells = 0;
1455 }
1456}
1457
1458
1459static int
1460fore200e_open(struct atm_vcc *vcc)
1461{
1462 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1463 struct fore200e_vcc* fore200e_vcc;
1464 struct fore200e_vc_map* vc_map;
1465 unsigned long flags;
1466 int vci = vcc->vci;
1467 short vpi = vcc->vpi;
1468
1469 ASSERT((vpi >= 0) && (vpi < 1<<FORE200E_VPI_BITS));
1470 ASSERT((vci >= 0) && (vci < 1<<FORE200E_VCI_BITS));
1471
1472 spin_lock_irqsave(&fore200e->q_lock, flags);
1473
1474 vc_map = FORE200E_VC_MAP(fore200e, vpi, vci);
1475 if (vc_map->vcc) {
1476
1477 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1478
1479 printk(FORE200E "VC %d.%d.%d already in use\n",
1480 fore200e->atm_dev->number, vpi, vci);
1481
1482 return -EINVAL;
1483 }
1484
1485 vc_map->vcc = vcc;
1486
1487 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1488
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001489 fore200e_vcc = kzalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 if (fore200e_vcc == NULL) {
1491 vc_map->vcc = NULL;
1492 return -ENOMEM;
1493 }
1494
1495 DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
1496 "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
1497 vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
1498 fore200e_traffic_class[ vcc->qos.txtp.traffic_class ],
1499 vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu,
1500 fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ],
1501 vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu);
1502
1503 /* pseudo-CBR bandwidth requested? */
1504 if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
1505
1506 down(&fore200e->rate_sf);
1507 if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
1508 up(&fore200e->rate_sf);
1509
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001510 kfree(fore200e_vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 vc_map->vcc = NULL;
1512 return -EAGAIN;
1513 }
1514
1515 /* reserve bandwidth */
1516 fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
1517 up(&fore200e->rate_sf);
1518 }
1519
1520 vcc->itf = vcc->dev->number;
1521
1522 set_bit(ATM_VF_PARTIAL,&vcc->flags);
1523 set_bit(ATM_VF_ADDR, &vcc->flags);
1524
1525 vcc->dev_data = fore200e_vcc;
1526
1527 if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) {
1528
1529 vc_map->vcc = NULL;
1530
1531 clear_bit(ATM_VF_ADDR, &vcc->flags);
1532 clear_bit(ATM_VF_PARTIAL,&vcc->flags);
1533
1534 vcc->dev_data = NULL;
1535
1536 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
1537
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001538 kfree(fore200e_vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 return -EINVAL;
1540 }
1541
1542 /* compute rate control parameters */
1543 if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
1544
1545 fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate);
1546 set_bit(ATM_VF_HASQOS, &vcc->flags);
1547
1548 DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n",
1549 vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
1550 vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr,
1551 fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells);
1552 }
1553
1554 fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = MAX_PDU_SIZE + 1;
1555 fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
1556 fore200e_vcc->tx_pdu = fore200e_vcc->rx_pdu = 0;
1557
1558 /* new incarnation of the vcc */
1559 vc_map->incarn = ++fore200e->incarn_count;
1560
1561 /* VC unusable before this flag is set */
1562 set_bit(ATM_VF_READY, &vcc->flags);
1563
1564 return 0;
1565}
1566
1567
1568static void
1569fore200e_close(struct atm_vcc* vcc)
1570{
1571 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1572 struct fore200e_vcc* fore200e_vcc;
1573 struct fore200e_vc_map* vc_map;
1574 unsigned long flags;
1575
1576 ASSERT(vcc);
1577 ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<<FORE200E_VPI_BITS));
1578 ASSERT((vcc->vci >= 0) && (vcc->vci < 1<<FORE200E_VCI_BITS));
1579
1580 DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
1581
1582 clear_bit(ATM_VF_READY, &vcc->flags);
1583
1584 fore200e_activate_vcin(fore200e, 0, vcc, 0);
1585
1586 spin_lock_irqsave(&fore200e->q_lock, flags);
1587
1588 vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
1589
1590 /* the vc is no longer considered as "in use" by fore200e_open() */
1591 vc_map->vcc = NULL;
1592
1593 vcc->itf = vcc->vci = vcc->vpi = 0;
1594
1595 fore200e_vcc = FORE200E_VCC(vcc);
1596 vcc->dev_data = NULL;
1597
1598 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1599
1600 /* release reserved bandwidth, if any */
1601 if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
1602
1603 down(&fore200e->rate_sf);
1604 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
1605 up(&fore200e->rate_sf);
1606
1607 clear_bit(ATM_VF_HASQOS, &vcc->flags);
1608 }
1609
1610 clear_bit(ATM_VF_ADDR, &vcc->flags);
1611 clear_bit(ATM_VF_PARTIAL,&vcc->flags);
1612
1613 ASSERT(fore200e_vcc);
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001614 kfree(fore200e_vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615}
1616
1617
1618static int
1619fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
1620{
1621 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1622 struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
1623 struct fore200e_vc_map* vc_map;
1624 struct host_txq* txq = &fore200e->host_txq;
1625 struct host_txq_entry* entry;
1626 struct tpd* tpd;
1627 struct tpd_haddr tpd_haddr;
1628 int retry = CONFIG_ATM_FORE200E_TX_RETRY;
1629 int tx_copy = 0;
1630 int tx_len = skb->len;
1631 u32* cell_header = NULL;
1632 unsigned char* skb_data;
1633 int skb_len;
1634 unsigned char* data;
1635 unsigned long flags;
1636
1637 ASSERT(vcc);
1638 ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
1639 ASSERT(fore200e);
1640 ASSERT(fore200e_vcc);
1641
1642 if (!test_bit(ATM_VF_READY, &vcc->flags)) {
1643 DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
1644 dev_kfree_skb_any(skb);
1645 return -EINVAL;
1646 }
1647
1648#ifdef FORE200E_52BYTE_AAL0_SDU
1649 if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
1650 cell_header = (u32*) skb->data;
1651 skb_data = skb->data + 4; /* skip 4-byte cell header */
1652 skb_len = tx_len = skb->len - 4;
1653
1654 DPRINTK(3, "user-supplied cell header = 0x%08x\n", *cell_header);
1655 }
1656 else
1657#endif
1658 {
1659 skb_data = skb->data;
1660 skb_len = skb->len;
1661 }
1662
1663 if (((unsigned long)skb_data) & 0x3) {
1664
1665 DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name);
1666 tx_copy = 1;
1667 tx_len = skb_len;
1668 }
1669
1670 if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) {
1671
1672 /* this simply NUKES the PCA board */
1673 DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name);
1674 tx_copy = 1;
1675 tx_len = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD;
1676 }
1677
1678 if (tx_copy) {
1679 data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA);
1680 if (data == NULL) {
1681 if (vcc->pop) {
1682 vcc->pop(vcc, skb);
1683 }
1684 else {
1685 dev_kfree_skb_any(skb);
1686 }
1687 return -ENOMEM;
1688 }
1689
1690 memcpy(data, skb_data, skb_len);
1691 if (skb_len < tx_len)
1692 memset(data + skb_len, 0x00, tx_len - skb_len);
1693 }
1694 else {
1695 data = skb_data;
1696 }
1697
1698 vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
1699 ASSERT(vc_map->vcc == vcc);
1700
1701 retry_here:
1702
1703 spin_lock_irqsave(&fore200e->q_lock, flags);
1704
1705 entry = &txq->host_entry[ txq->head ];
1706
1707 if ((*entry->status != STATUS_FREE) || (txq->txing >= QUEUE_SIZE_TX - 2)) {
1708
1709 /* try to free completed tx queue entries */
1710 fore200e_tx_irq(fore200e);
1711
1712 if (*entry->status != STATUS_FREE) {
1713
1714 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1715
1716 /* retry once again? */
1717 if (--retry > 0) {
1718 udelay(50);
1719 goto retry_here;
1720 }
1721
1722 atomic_inc(&vcc->stats->tx_err);
1723
1724 fore200e->tx_sat++;
1725 DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
1726 fore200e->name, fore200e->cp_queues->heartbeat);
1727 if (vcc->pop) {
1728 vcc->pop(vcc, skb);
1729 }
1730 else {
1731 dev_kfree_skb_any(skb);
1732 }
1733
1734 if (tx_copy)
1735 kfree(data);
1736
1737 return -ENOBUFS;
1738 }
1739 }
1740
1741 entry->incarn = vc_map->incarn;
1742 entry->vc_map = vc_map;
1743 entry->skb = skb;
1744 entry->data = tx_copy ? data : NULL;
1745
1746 tpd = entry->tpd;
1747 tpd->tsd[ 0 ].buffer = fore200e->bus->dma_map(fore200e, data, tx_len, DMA_TO_DEVICE);
1748 tpd->tsd[ 0 ].length = tx_len;
1749
1750 FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
1751 txq->txing++;
1752
1753 /* The dma_map call above implies a dma_sync so the device can use it,
1754 * thus no explicit dma_sync call is necessary here.
1755 */
1756
1757 DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n",
1758 vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
1759 tpd->tsd[0].length, skb_len);
1760
1761 if (skb_len < fore200e_vcc->tx_min_pdu)
1762 fore200e_vcc->tx_min_pdu = skb_len;
1763 if (skb_len > fore200e_vcc->tx_max_pdu)
1764 fore200e_vcc->tx_max_pdu = skb_len;
1765 fore200e_vcc->tx_pdu++;
1766
1767 /* set tx rate control information */
1768 tpd->rate.data_cells = fore200e_vcc->rate.data_cells;
1769 tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells;
1770
1771 if (cell_header) {
1772 tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP);
1773 tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
1774 tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
1775 tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
1776 tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT;
1777 }
1778 else {
1779 /* set the ATM header, common to all cells conveying the PDU */
1780 tpd->atm_header.clp = 0;
1781 tpd->atm_header.plt = 0;
1782 tpd->atm_header.vci = vcc->vci;
1783 tpd->atm_header.vpi = vcc->vpi;
1784 tpd->atm_header.gfc = 0;
1785 }
1786
1787 tpd->spec.length = tx_len;
1788 tpd->spec.nseg = 1;
1789 tpd->spec.aal = fore200e_atm2fore_aal(vcc->qos.aal);
1790 tpd->spec.intr = 1;
1791
1792 tpd_haddr.size = sizeof(struct tpd) / (1<<TPD_HADDR_SHIFT); /* size is expressed in 32 byte blocks */
1793 tpd_haddr.pad = 0;
1794 tpd_haddr.haddr = entry->tpd_dma >> TPD_HADDR_SHIFT; /* shift the address, as we are in a bitfield */
1795
1796 *entry->status = STATUS_PENDING;
1797 fore200e->bus->write(*(u32*)&tpd_haddr, (u32 __iomem *)&entry->cp_entry->tpd_haddr);
1798
1799 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1800
1801 return 0;
1802}
1803
1804
1805static int
1806fore200e_getstats(struct fore200e* fore200e)
1807{
1808 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1809 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1810 struct stats_opcode opcode;
1811 int ok;
1812 u32 stats_dma_addr;
1813
1814 if (fore200e->stats == NULL) {
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001815 fore200e->stats = kzalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 if (fore200e->stats == NULL)
1817 return -ENOMEM;
1818 }
1819
1820 stats_dma_addr = fore200e->bus->dma_map(fore200e, fore200e->stats,
1821 sizeof(struct stats), DMA_FROM_DEVICE);
1822
1823 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1824
1825 opcode.opcode = OPCODE_GET_STATS;
1826 opcode.pad = 0;
1827
1828 fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr);
1829
1830 *entry->status = STATUS_PENDING;
1831
1832 fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.stats_block.opcode);
1833
1834 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1835
1836 *entry->status = STATUS_FREE;
1837
1838 fore200e->bus->dma_unmap(fore200e, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
1839
1840 if (ok == 0) {
1841 printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
1842 return -EIO;
1843 }
1844
1845 return 0;
1846}
1847
1848
1849static int
1850fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
1851{
1852 /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
1853
1854 DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
1855 vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
1856
1857 return -EINVAL;
1858}
1859
1860
1861static int
1862fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
1863{
1864 /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
1865
1866 DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
1867 vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
1868
1869 return -EINVAL;
1870}
1871
1872
1873#if 0 /* currently unused */
1874static int
1875fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
1876{
1877 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1878 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1879 struct oc3_opcode opcode;
1880 int ok;
1881 u32 oc3_regs_dma_addr;
1882
1883 oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
1884
1885 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1886
1887 opcode.opcode = OPCODE_GET_OC3;
1888 opcode.reg = 0;
1889 opcode.value = 0;
1890 opcode.mask = 0;
1891
1892 fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr);
1893
1894 *entry->status = STATUS_PENDING;
1895
1896 fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
1897
1898 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1899
1900 *entry->status = STATUS_FREE;
1901
1902 fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
1903
1904 if (ok == 0) {
1905 printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
1906 return -EIO;
1907 }
1908
1909 return 0;
1910}
1911#endif
1912
1913
1914static int
1915fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask)
1916{
1917 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1918 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1919 struct oc3_opcode opcode;
1920 int ok;
1921
1922 DPRINTK(2, "set OC-3 reg = 0x%02x, value = 0x%02x, mask = 0x%02x\n", reg, value, mask);
1923
1924 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1925
1926 opcode.opcode = OPCODE_SET_OC3;
1927 opcode.reg = reg;
1928 opcode.value = value;
1929 opcode.mask = mask;
1930
1931 fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr);
1932
1933 *entry->status = STATUS_PENDING;
1934
1935 fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.oc3_block.opcode);
1936
1937 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1938
1939 *entry->status = STATUS_FREE;
1940
1941 if (ok == 0) {
1942 printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name);
1943 return -EIO;
1944 }
1945
1946 return 0;
1947}
1948
1949
1950static int
1951fore200e_setloop(struct fore200e* fore200e, int loop_mode)
1952{
1953 u32 mct_value, mct_mask;
1954 int error;
1955
1956 if (!capable(CAP_NET_ADMIN))
1957 return -EPERM;
1958
1959 switch (loop_mode) {
1960
1961 case ATM_LM_NONE:
1962 mct_value = 0;
1963 mct_mask = SUNI_MCT_DLE | SUNI_MCT_LLE;
1964 break;
1965
1966 case ATM_LM_LOC_PHY:
1967 mct_value = mct_mask = SUNI_MCT_DLE;
1968 break;
1969
1970 case ATM_LM_RMT_PHY:
1971 mct_value = mct_mask = SUNI_MCT_LLE;
1972 break;
1973
1974 default:
1975 return -EINVAL;
1976 }
1977
1978 error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask);
1979 if (error == 0)
1980 fore200e->loop_mode = loop_mode;
1981
1982 return error;
1983}
1984
1985
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986static int
1987fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
1988{
1989 struct sonet_stats tmp;
1990
1991 if (fore200e_getstats(fore200e) < 0)
1992 return -EIO;
1993
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001994 tmp.section_bip = cpu_to_be32(fore200e->stats->oc3.section_bip8_errors);
1995 tmp.line_bip = cpu_to_be32(fore200e->stats->oc3.line_bip24_errors);
1996 tmp.path_bip = cpu_to_be32(fore200e->stats->oc3.path_bip8_errors);
1997 tmp.line_febe = cpu_to_be32(fore200e->stats->oc3.line_febe_errors);
1998 tmp.path_febe = cpu_to_be32(fore200e->stats->oc3.path_febe_errors);
1999 tmp.corr_hcs = cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors);
2000 tmp.uncorr_hcs = cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors);
2001 tmp.tx_cells = cpu_to_be32(fore200e->stats->aal0.cells_transmitted) +
2002 cpu_to_be32(fore200e->stats->aal34.cells_transmitted) +
2003 cpu_to_be32(fore200e->stats->aal5.cells_transmitted);
2004 tmp.rx_cells = cpu_to_be32(fore200e->stats->aal0.cells_received) +
2005 cpu_to_be32(fore200e->stats->aal34.cells_received) +
2006 cpu_to_be32(fore200e->stats->aal5.cells_received);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007
2008 if (arg)
2009 return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;
2010
2011 return 0;
2012}
2013
2014
2015static int
2016fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
2017{
2018 struct fore200e* fore200e = FORE200E_DEV(dev);
2019
2020 DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg);
2021
2022 switch (cmd) {
2023
2024 case SONET_GETSTAT:
2025 return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
2026
2027 case SONET_GETDIAG:
2028 return put_user(0, (int __user *)arg) ? -EFAULT : 0;
2029
2030 case ATM_SETLOOP:
2031 return fore200e_setloop(fore200e, (int)(unsigned long)arg);
2032
2033 case ATM_GETLOOP:
2034 return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
2035
2036 case ATM_QUERYLOOP:
2037 return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
2038 }
2039
2040 return -ENOSYS; /* not implemented */
2041}
2042
2043
2044static int
2045fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
2046{
2047 struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
2048 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
2049
2050 if (!test_bit(ATM_VF_READY, &vcc->flags)) {
2051 DPRINTK(1, "VC %d.%d.%d not ready for QoS change\n", vcc->itf, vcc->vpi, vcc->vpi);
2052 return -EINVAL;
2053 }
2054
2055 DPRINTK(2, "change_qos %d.%d.%d, "
2056 "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
2057 "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
2058 "available_cell_rate = %u",
2059 vcc->itf, vcc->vpi, vcc->vci,
2060 fore200e_traffic_class[ qos->txtp.traffic_class ],
2061 qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu,
2062 fore200e_traffic_class[ qos->rxtp.traffic_class ],
2063 qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu,
2064 flags, fore200e->available_cell_rate);
2065
2066 if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
2067
2068 down(&fore200e->rate_sf);
2069 if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
2070 up(&fore200e->rate_sf);
2071 return -EAGAIN;
2072 }
2073
2074 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
2075 fore200e->available_cell_rate -= qos->txtp.max_pcr;
2076
2077 up(&fore200e->rate_sf);
2078
2079 memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
2080
2081 /* update rate control parameters */
2082 fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
2083
2084 set_bit(ATM_VF_HASQOS, &vcc->flags);
2085
2086 return 0;
2087 }
2088
2089 return -EINVAL;
2090}
2091
2092
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002093static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002094fore200e_irq_request(struct fore200e* fore200e)
2095{
Thomas Gleixnerdace1452006-07-01 19:29:38 -07002096 if (request_irq(fore200e->irq, fore200e_interrupt, IRQF_SHARED, fore200e->name, fore200e->atm_dev) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097
2098 printk(FORE200E "unable to reserve IRQ %s for device %s\n",
2099 fore200e_irq_itoa(fore200e->irq), fore200e->name);
2100 return -EBUSY;
2101 }
2102
2103 printk(FORE200E "IRQ %s reserved for device %s\n",
2104 fore200e_irq_itoa(fore200e->irq), fore200e->name);
2105
2106#ifdef FORE200E_USE_TASKLET
2107 tasklet_init(&fore200e->tx_tasklet, fore200e_tx_tasklet, (unsigned long)fore200e);
2108 tasklet_init(&fore200e->rx_tasklet, fore200e_rx_tasklet, (unsigned long)fore200e);
2109#endif
2110
2111 fore200e->state = FORE200E_STATE_IRQ;
2112 return 0;
2113}
2114
2115
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002116static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117fore200e_get_esi(struct fore200e* fore200e)
2118{
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002119 struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002120 int ok, i;
2121
2122 if (!prom)
2123 return -ENOMEM;
2124
2125 ok = fore200e->bus->prom_read(fore200e, prom);
2126 if (ok < 0) {
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002127 kfree(prom);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 return -EBUSY;
2129 }
2130
2131 printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %02x:%02x:%02x:%02x:%02x:%02x\n",
2132 fore200e->name,
2133 (prom->hw_revision & 0xFF) + '@', /* probably meaningless with SBA boards */
2134 prom->serial_number & 0xFFFF,
2135 prom->mac_addr[ 2 ], prom->mac_addr[ 3 ], prom->mac_addr[ 4 ],
2136 prom->mac_addr[ 5 ], prom->mac_addr[ 6 ], prom->mac_addr[ 7 ]);
2137
2138 for (i = 0; i < ESI_LEN; i++) {
2139 fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
2140 }
2141
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002142 kfree(prom);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
2144 return 0;
2145}
2146
2147
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002148static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149fore200e_alloc_rx_buf(struct fore200e* fore200e)
2150{
2151 int scheme, magn, nbr, size, i;
2152
2153 struct host_bsq* bsq;
2154 struct buffer* buffer;
2155
2156 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
2157 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
2158
2159 bsq = &fore200e->host_bsq[ scheme ][ magn ];
2160
2161 nbr = fore200e_rx_buf_nbr[ scheme ][ magn ];
2162 size = fore200e_rx_buf_size[ scheme ][ magn ];
2163
2164 DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
2165
2166 /* allocate the array of receive buffers */
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002167 buffer = bsq->buffer = kzalloc(nbr * sizeof(struct buffer), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168
2169 if (buffer == NULL)
2170 return -ENOMEM;
2171
2172 bsq->freebuf = NULL;
2173
2174 for (i = 0; i < nbr; i++) {
2175
2176 buffer[ i ].scheme = scheme;
2177 buffer[ i ].magn = magn;
2178#ifdef FORE200E_BSQ_DEBUG
2179 buffer[ i ].index = i;
2180 buffer[ i ].supplied = 0;
2181#endif
2182
2183 /* allocate the receive buffer body */
2184 if (fore200e_chunk_alloc(fore200e,
2185 &buffer[ i ].data, size, fore200e->bus->buffer_alignment,
2186 DMA_FROM_DEVICE) < 0) {
2187
2188 while (i > 0)
2189 fore200e_chunk_free(fore200e, &buffer[ --i ].data);
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002190 kfree(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191
2192 return -ENOMEM;
2193 }
2194
2195 /* insert the buffer into the free buffer list */
2196 buffer[ i ].next = bsq->freebuf;
2197 bsq->freebuf = &buffer[ i ];
2198 }
2199 /* all the buffers are free, initially */
2200 bsq->freebuf_count = nbr;
2201
2202#ifdef FORE200E_BSQ_DEBUG
2203 bsq_audit(3, bsq, scheme, magn);
2204#endif
2205 }
2206 }
2207
2208 fore200e->state = FORE200E_STATE_ALLOC_BUF;
2209 return 0;
2210}
2211
2212
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002213static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214fore200e_init_bs_queue(struct fore200e* fore200e)
2215{
2216 int scheme, magn, i;
2217
2218 struct host_bsq* bsq;
2219 struct cp_bsq_entry __iomem * cp_entry;
2220
2221 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
2222 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
2223
2224 DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn);
2225
2226 bsq = &fore200e->host_bsq[ scheme ][ magn ];
2227
2228 /* allocate and align the array of status words */
2229 if (fore200e->bus->dma_chunk_alloc(fore200e,
2230 &bsq->status,
2231 sizeof(enum status),
2232 QUEUE_SIZE_BS,
2233 fore200e->bus->status_alignment) < 0) {
2234 return -ENOMEM;
2235 }
2236
2237 /* allocate and align the array of receive buffer descriptors */
2238 if (fore200e->bus->dma_chunk_alloc(fore200e,
2239 &bsq->rbd_block,
2240 sizeof(struct rbd_block),
2241 QUEUE_SIZE_BS,
2242 fore200e->bus->descr_alignment) < 0) {
2243
2244 fore200e->bus->dma_chunk_free(fore200e, &bsq->status);
2245 return -ENOMEM;
2246 }
2247
2248 /* get the base address of the cp resident buffer supply queue entries */
2249 cp_entry = fore200e->virt_base +
2250 fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]);
2251
2252 /* fill the host resident and cp resident buffer supply queue entries */
2253 for (i = 0; i < QUEUE_SIZE_BS; i++) {
2254
2255 bsq->host_entry[ i ].status =
2256 FORE200E_INDEX(bsq->status.align_addr, enum status, i);
2257 bsq->host_entry[ i ].rbd_block =
2258 FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
2259 bsq->host_entry[ i ].rbd_block_dma =
2260 FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
2261 bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2262
2263 *bsq->host_entry[ i ].status = STATUS_FREE;
2264
2265 fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i),
2266 &cp_entry[ i ].status_haddr);
2267 }
2268 }
2269 }
2270
2271 fore200e->state = FORE200E_STATE_INIT_BSQ;
2272 return 0;
2273}
2274
2275
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002276static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277fore200e_init_rx_queue(struct fore200e* fore200e)
2278{
2279 struct host_rxq* rxq = &fore200e->host_rxq;
2280 struct cp_rxq_entry __iomem * cp_entry;
2281 int i;
2282
2283 DPRINTK(2, "receive queue is being initialized\n");
2284
2285 /* allocate and align the array of status words */
2286 if (fore200e->bus->dma_chunk_alloc(fore200e,
2287 &rxq->status,
2288 sizeof(enum status),
2289 QUEUE_SIZE_RX,
2290 fore200e->bus->status_alignment) < 0) {
2291 return -ENOMEM;
2292 }
2293
2294 /* allocate and align the array of receive PDU descriptors */
2295 if (fore200e->bus->dma_chunk_alloc(fore200e,
2296 &rxq->rpd,
2297 sizeof(struct rpd),
2298 QUEUE_SIZE_RX,
2299 fore200e->bus->descr_alignment) < 0) {
2300
2301 fore200e->bus->dma_chunk_free(fore200e, &rxq->status);
2302 return -ENOMEM;
2303 }
2304
2305 /* get the base address of the cp resident rx queue entries */
2306 cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_rxq);
2307
2308 /* fill the host resident and cp resident rx entries */
2309 for (i=0; i < QUEUE_SIZE_RX; i++) {
2310
2311 rxq->host_entry[ i ].status =
2312 FORE200E_INDEX(rxq->status.align_addr, enum status, i);
2313 rxq->host_entry[ i ].rpd =
2314 FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i);
2315 rxq->host_entry[ i ].rpd_dma =
2316 FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i);
2317 rxq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2318
2319 *rxq->host_entry[ i ].status = STATUS_FREE;
2320
2321 fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i),
2322 &cp_entry[ i ].status_haddr);
2323
2324 fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i),
2325 &cp_entry[ i ].rpd_haddr);
2326 }
2327
2328 /* set the head entry of the queue */
2329 rxq->head = 0;
2330
2331 fore200e->state = FORE200E_STATE_INIT_RXQ;
2332 return 0;
2333}
2334
2335
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002336static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337fore200e_init_tx_queue(struct fore200e* fore200e)
2338{
2339 struct host_txq* txq = &fore200e->host_txq;
2340 struct cp_txq_entry __iomem * cp_entry;
2341 int i;
2342
2343 DPRINTK(2, "transmit queue is being initialized\n");
2344
2345 /* allocate and align the array of status words */
2346 if (fore200e->bus->dma_chunk_alloc(fore200e,
2347 &txq->status,
2348 sizeof(enum status),
2349 QUEUE_SIZE_TX,
2350 fore200e->bus->status_alignment) < 0) {
2351 return -ENOMEM;
2352 }
2353
2354 /* allocate and align the array of transmit PDU descriptors */
2355 if (fore200e->bus->dma_chunk_alloc(fore200e,
2356 &txq->tpd,
2357 sizeof(struct tpd),
2358 QUEUE_SIZE_TX,
2359 fore200e->bus->descr_alignment) < 0) {
2360
2361 fore200e->bus->dma_chunk_free(fore200e, &txq->status);
2362 return -ENOMEM;
2363 }
2364
2365 /* get the base address of the cp resident tx queue entries */
2366 cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_txq);
2367
2368 /* fill the host resident and cp resident tx entries */
2369 for (i=0; i < QUEUE_SIZE_TX; i++) {
2370
2371 txq->host_entry[ i ].status =
2372 FORE200E_INDEX(txq->status.align_addr, enum status, i);
2373 txq->host_entry[ i ].tpd =
2374 FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i);
2375 txq->host_entry[ i ].tpd_dma =
2376 FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i);
2377 txq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2378
2379 *txq->host_entry[ i ].status = STATUS_FREE;
2380
2381 fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i),
2382 &cp_entry[ i ].status_haddr);
2383
2384 /* although there is a one-to-one mapping of tx queue entries and tpds,
2385 we do not write here the DMA (physical) base address of each tpd into
2386 the related cp resident entry, because the cp relies on this write
2387 operation to detect that a new pdu has been submitted for tx */
2388 }
2389
2390 /* set the head and tail entries of the queue */
2391 txq->head = 0;
2392 txq->tail = 0;
2393
2394 fore200e->state = FORE200E_STATE_INIT_TXQ;
2395 return 0;
2396}
2397
2398
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002399static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400fore200e_init_cmd_queue(struct fore200e* fore200e)
2401{
2402 struct host_cmdq* cmdq = &fore200e->host_cmdq;
2403 struct cp_cmdq_entry __iomem * cp_entry;
2404 int i;
2405
2406 DPRINTK(2, "command queue is being initialized\n");
2407
2408 /* allocate and align the array of status words */
2409 if (fore200e->bus->dma_chunk_alloc(fore200e,
2410 &cmdq->status,
2411 sizeof(enum status),
2412 QUEUE_SIZE_CMD,
2413 fore200e->bus->status_alignment) < 0) {
2414 return -ENOMEM;
2415 }
2416
2417 /* get the base address of the cp resident cmd queue entries */
2418 cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_cmdq);
2419
2420 /* fill the host resident and cp resident cmd entries */
2421 for (i=0; i < QUEUE_SIZE_CMD; i++) {
2422
2423 cmdq->host_entry[ i ].status =
2424 FORE200E_INDEX(cmdq->status.align_addr, enum status, i);
2425 cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2426
2427 *cmdq->host_entry[ i ].status = STATUS_FREE;
2428
2429 fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i),
2430 &cp_entry[ i ].status_haddr);
2431 }
2432
2433 /* set the head entry of the queue */
2434 cmdq->head = 0;
2435
2436 fore200e->state = FORE200E_STATE_INIT_CMDQ;
2437 return 0;
2438}
2439
2440
2441static void __init
2442fore200e_param_bs_queue(struct fore200e* fore200e,
2443 enum buffer_scheme scheme, enum buffer_magn magn,
2444 int queue_length, int pool_size, int supply_blksize)
2445{
2446 struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ];
2447
2448 fore200e->bus->write(queue_length, &bs_spec->queue_length);
2449 fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size);
2450 fore200e->bus->write(pool_size, &bs_spec->pool_size);
2451 fore200e->bus->write(supply_blksize, &bs_spec->supply_blksize);
2452}
2453
2454
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002455static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002456fore200e_initialize(struct fore200e* fore200e)
2457{
2458 struct cp_queues __iomem * cpq;
2459 int ok, scheme, magn;
2460
2461 DPRINTK(2, "device %s being initialized\n", fore200e->name);
2462
2463 init_MUTEX(&fore200e->rate_sf);
2464 spin_lock_init(&fore200e->q_lock);
2465
2466 cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET;
2467
2468 /* enable cp to host interrupts */
2469 fore200e->bus->write(1, &cpq->imask);
2470
2471 if (fore200e->bus->irq_enable)
2472 fore200e->bus->irq_enable(fore200e);
2473
2474 fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect);
2475
2476 fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len);
2477 fore200e->bus->write(QUEUE_SIZE_RX, &cpq->init.rx_queue_len);
2478 fore200e->bus->write(QUEUE_SIZE_TX, &cpq->init.tx_queue_len);
2479
2480 fore200e->bus->write(RSD_EXTENSION, &cpq->init.rsd_extension);
2481 fore200e->bus->write(TSD_EXTENSION, &cpq->init.tsd_extension);
2482
2483 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++)
2484 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++)
2485 fore200e_param_bs_queue(fore200e, scheme, magn,
2486 QUEUE_SIZE_BS,
2487 fore200e_rx_buf_nbr[ scheme ][ magn ],
2488 RBD_BLK_SIZE);
2489
2490 /* issue the initialize command */
2491 fore200e->bus->write(STATUS_PENDING, &cpq->init.status);
2492 fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode);
2493
2494 ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000);
2495 if (ok == 0) {
2496 printk(FORE200E "device %s initialization failed\n", fore200e->name);
2497 return -ENODEV;
2498 }
2499
2500 printk(FORE200E "device %s initialized\n", fore200e->name);
2501
2502 fore200e->state = FORE200E_STATE_INITIALIZE;
2503 return 0;
2504}
2505
2506
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002507static void __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508fore200e_monitor_putc(struct fore200e* fore200e, char c)
2509{
2510 struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
2511
2512#if 0
2513 printk("%c", c);
2514#endif
2515 fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send);
2516}
2517
2518
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002519static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520fore200e_monitor_getc(struct fore200e* fore200e)
2521{
2522 struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
2523 unsigned long timeout = jiffies + msecs_to_jiffies(50);
2524 int c;
2525
2526 while (time_before(jiffies, timeout)) {
2527
2528 c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
2529
2530 if (c & FORE200E_CP_MONITOR_UART_AVAIL) {
2531
2532 fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv);
2533#if 0
2534 printk("%c", c & 0xFF);
2535#endif
2536 return c & 0xFF;
2537 }
2538 }
2539
2540 return -1;
2541}
2542
2543
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002544static void __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545fore200e_monitor_puts(struct fore200e* fore200e, char* str)
2546{
2547 while (*str) {
2548
2549 /* the i960 monitor doesn't accept any new character if it has something to say */
2550 while (fore200e_monitor_getc(fore200e) >= 0);
2551
2552 fore200e_monitor_putc(fore200e, *str++);
2553 }
2554
2555 while (fore200e_monitor_getc(fore200e) >= 0);
2556}
2557
2558
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002559static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002560fore200e_start_fw(struct fore200e* fore200e)
2561{
2562 int ok;
2563 char cmd[ 48 ];
2564 struct fw_header* fw_header = (struct fw_header*) fore200e->bus->fw_data;
2565
2566 DPRINTK(2, "device %s firmware being started\n", fore200e->name);
2567
2568#if defined(__sparc_v9__)
2569 /* reported to be required by SBA cards on some sparc64 hosts */
2570 fore200e_spin(100);
2571#endif
2572
2573 sprintf(cmd, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
2574
2575 fore200e_monitor_puts(fore200e, cmd);
2576
2577 ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000);
2578 if (ok == 0) {
2579 printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
2580 return -ENODEV;
2581 }
2582
2583 printk(FORE200E "device %s firmware started\n", fore200e->name);
2584
2585 fore200e->state = FORE200E_STATE_START_FW;
2586 return 0;
2587}
2588
2589
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002590static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591fore200e_load_fw(struct fore200e* fore200e)
2592{
2593 u32* fw_data = (u32*) fore200e->bus->fw_data;
2594 u32 fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32);
2595
2596 struct fw_header* fw_header = (struct fw_header*) fw_data;
2597
2598 u32 __iomem *load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
2599
2600 DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
2601 fore200e->name, load_addr, fw_size);
2602
2603 if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
2604 printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
2605 return -ENODEV;
2606 }
2607
2608 for (; fw_size--; fw_data++, load_addr++)
2609 fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
2610
2611 fore200e->state = FORE200E_STATE_LOAD_FW;
2612 return 0;
2613}
2614
2615
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002616static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617fore200e_register(struct fore200e* fore200e)
2618{
2619 struct atm_dev* atm_dev;
2620
2621 DPRINTK(2, "device %s being registered\n", fore200e->name);
2622
2623 atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1,
2624 NULL);
2625 if (atm_dev == NULL) {
2626 printk(FORE200E "unable to register device %s\n", fore200e->name);
2627 return -ENODEV;
2628 }
2629
2630 atm_dev->dev_data = fore200e;
2631 fore200e->atm_dev = atm_dev;
2632
2633 atm_dev->ci_range.vpi_bits = FORE200E_VPI_BITS;
2634 atm_dev->ci_range.vci_bits = FORE200E_VCI_BITS;
2635
2636 fore200e->available_cell_rate = ATM_OC3_PCR;
2637
2638 fore200e->state = FORE200E_STATE_REGISTER;
2639 return 0;
2640}
2641
2642
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002643static int __devinit
Linus Torvalds1da177e2005-04-16 15:20:36 -07002644fore200e_init(struct fore200e* fore200e)
2645{
2646 if (fore200e_register(fore200e) < 0)
2647 return -ENODEV;
2648
2649 if (fore200e->bus->configure(fore200e) < 0)
2650 return -ENODEV;
2651
2652 if (fore200e->bus->map(fore200e) < 0)
2653 return -ENODEV;
2654
2655 if (fore200e_reset(fore200e, 1) < 0)
2656 return -ENODEV;
2657
2658 if (fore200e_load_fw(fore200e) < 0)
2659 return -ENODEV;
2660
2661 if (fore200e_start_fw(fore200e) < 0)
2662 return -ENODEV;
2663
2664 if (fore200e_initialize(fore200e) < 0)
2665 return -ENODEV;
2666
2667 if (fore200e_init_cmd_queue(fore200e) < 0)
2668 return -ENOMEM;
2669
2670 if (fore200e_init_tx_queue(fore200e) < 0)
2671 return -ENOMEM;
2672
2673 if (fore200e_init_rx_queue(fore200e) < 0)
2674 return -ENOMEM;
2675
2676 if (fore200e_init_bs_queue(fore200e) < 0)
2677 return -ENOMEM;
2678
2679 if (fore200e_alloc_rx_buf(fore200e) < 0)
2680 return -ENOMEM;
2681
2682 if (fore200e_get_esi(fore200e) < 0)
2683 return -EIO;
2684
2685 if (fore200e_irq_request(fore200e) < 0)
2686 return -EBUSY;
2687
2688 fore200e_supply(fore200e);
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002689
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690 /* all done, board initialization is now complete */
2691 fore200e->state = FORE200E_STATE_COMPLETE;
2692 return 0;
2693}
2694
2695
2696static int __devinit
2697fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent)
2698{
2699 const struct fore200e_bus* bus = (struct fore200e_bus*) pci_ent->driver_data;
2700 struct fore200e* fore200e;
2701 int err = 0;
2702 static int index = 0;
2703
2704 if (pci_enable_device(pci_dev)) {
2705 err = -EINVAL;
2706 goto out;
2707 }
2708
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002709 fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 if (fore200e == NULL) {
2711 err = -ENOMEM;
2712 goto out_disable;
2713 }
2714
2715 fore200e->bus = bus;
2716 fore200e->bus_dev = pci_dev;
2717 fore200e->irq = pci_dev->irq;
2718 fore200e->phys_base = pci_resource_start(pci_dev, 0);
2719
2720 sprintf(fore200e->name, "%s-%d", bus->model_name, index - 1);
2721
2722 pci_set_master(pci_dev);
2723
2724 printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
2725 fore200e->bus->model_name,
2726 fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
2727
2728 sprintf(fore200e->name, "%s-%d", bus->model_name, index);
2729
2730 err = fore200e_init(fore200e);
2731 if (err < 0) {
2732 fore200e_shutdown(fore200e);
2733 goto out_free;
2734 }
2735
2736 ++index;
2737 pci_set_drvdata(pci_dev, fore200e);
2738
2739out:
2740 return err;
2741
2742out_free:
2743 kfree(fore200e);
2744out_disable:
2745 pci_disable_device(pci_dev);
2746 goto out;
2747}
2748
2749
2750static void __devexit fore200e_pca_remove_one(struct pci_dev *pci_dev)
2751{
2752 struct fore200e *fore200e;
2753
2754 fore200e = pci_get_drvdata(pci_dev);
2755
Linus Torvalds1da177e2005-04-16 15:20:36 -07002756 fore200e_shutdown(fore200e);
2757 kfree(fore200e);
2758 pci_disable_device(pci_dev);
2759}
2760
2761
2762#ifdef CONFIG_ATM_FORE200E_PCA
2763static struct pci_device_id fore200e_pca_tbl[] = {
2764 { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID,
2765 0, 0, (unsigned long) &fore200e_bus[0] },
2766 { 0, }
2767};
2768
2769MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl);
2770
2771static struct pci_driver fore200e_pca_driver = {
2772 .name = "fore_200e",
2773 .probe = fore200e_pca_detect,
2774 .remove = __devexit_p(fore200e_pca_remove_one),
2775 .id_table = fore200e_pca_tbl,
2776};
2777#endif
2778
2779
2780static int __init
2781fore200e_module_init(void)
2782{
2783 const struct fore200e_bus* bus;
2784 struct fore200e* fore200e;
2785 int index;
2786
2787 printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
2788
2789 /* for each configured bus interface */
2790 for (bus = fore200e_bus; bus->model_name; bus++) {
2791
2792 /* detect all boards present on that bus */
2793 for (index = 0; bus->detect && (fore200e = bus->detect(bus, index)); index++) {
2794
2795 printk(FORE200E "device %s found at 0x%lx, IRQ %s\n",
2796 fore200e->bus->model_name,
2797 fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
2798
2799 sprintf(fore200e->name, "%s-%d", bus->model_name, index);
2800
2801 if (fore200e_init(fore200e) < 0) {
2802
2803 fore200e_shutdown(fore200e);
2804 break;
2805 }
2806
2807 list_add(&fore200e->entry, &fore200e_boards);
2808 }
2809 }
2810
2811#ifdef CONFIG_ATM_FORE200E_PCA
chas williams18900822005-04-24 18:58:15 -07002812 if (!pci_register_driver(&fore200e_pca_driver))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 return 0;
2814#endif
2815
2816 if (!list_empty(&fore200e_boards))
2817 return 0;
2818
2819 return -ENODEV;
2820}
2821
2822
2823static void __exit
2824fore200e_module_cleanup(void)
2825{
2826 struct fore200e *fore200e, *next;
2827
2828#ifdef CONFIG_ATM_FORE200E_PCA
2829 pci_unregister_driver(&fore200e_pca_driver);
2830#endif
2831
2832 list_for_each_entry_safe(fore200e, next, &fore200e_boards, entry) {
2833 fore200e_shutdown(fore200e);
2834 kfree(fore200e);
2835 }
2836 DPRINTK(1, "module being removed\n");
2837}
2838
2839
2840static int
2841fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
2842{
2843 struct fore200e* fore200e = FORE200E_DEV(dev);
2844 struct fore200e_vcc* fore200e_vcc;
2845 struct atm_vcc* vcc;
2846 int i, len, left = *pos;
2847 unsigned long flags;
2848
2849 if (!left--) {
2850
2851 if (fore200e_getstats(fore200e) < 0)
2852 return -EIO;
2853
2854 len = sprintf(page,"\n"
2855 " device:\n"
2856 " internal name:\t\t%s\n", fore200e->name);
2857
2858 /* print bus-specific information */
2859 if (fore200e->bus->proc_read)
2860 len += fore200e->bus->proc_read(fore200e, page + len);
2861
2862 len += sprintf(page + len,
2863 " interrupt line:\t\t%s\n"
2864 " physical base address:\t0x%p\n"
2865 " virtual base address:\t0x%p\n"
2866 " factory address (ESI):\t%02x:%02x:%02x:%02x:%02x:%02x\n"
2867 " board serial number:\t\t%d\n\n",
2868 fore200e_irq_itoa(fore200e->irq),
2869 (void*)fore200e->phys_base,
2870 fore200e->virt_base,
2871 fore200e->esi[0], fore200e->esi[1], fore200e->esi[2],
2872 fore200e->esi[3], fore200e->esi[4], fore200e->esi[5],
2873 fore200e->esi[4] * 256 + fore200e->esi[5]);
2874
2875 return len;
2876 }
2877
2878 if (!left--)
2879 return sprintf(page,
2880 " free small bufs, scheme 1:\t%d\n"
2881 " free large bufs, scheme 1:\t%d\n"
2882 " free small bufs, scheme 2:\t%d\n"
2883 " free large bufs, scheme 2:\t%d\n",
2884 fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].freebuf_count,
2885 fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].freebuf_count,
2886 fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].freebuf_count,
2887 fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].freebuf_count);
2888
2889 if (!left--) {
2890 u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
2891
2892 len = sprintf(page,"\n\n"
2893 " cell processor:\n"
2894 " heartbeat state:\t\t");
2895
2896 if (hb >> 16 != 0xDEAD)
2897 len += sprintf(page + len, "0x%08x\n", hb);
2898 else
2899 len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF);
2900
2901 return len;
2902 }
2903
2904 if (!left--) {
2905 static const char* media_name[] = {
2906 "unshielded twisted pair",
2907 "multimode optical fiber ST",
2908 "multimode optical fiber SC",
2909 "single-mode optical fiber ST",
2910 "single-mode optical fiber SC",
2911 "unknown"
2912 };
2913
2914 static const char* oc3_mode[] = {
2915 "normal operation",
2916 "diagnostic loopback",
2917 "line loopback",
2918 "unknown"
2919 };
2920
2921 u32 fw_release = fore200e->bus->read(&fore200e->cp_queues->fw_release);
2922 u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release);
2923 u32 oc3_revision = fore200e->bus->read(&fore200e->cp_queues->oc3_revision);
2924 u32 media_index = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
2925 u32 oc3_index;
2926
2927 if ((media_index < 0) || (media_index > 4))
2928 media_index = 5;
2929
2930 switch (fore200e->loop_mode) {
2931 case ATM_LM_NONE: oc3_index = 0;
2932 break;
2933 case ATM_LM_LOC_PHY: oc3_index = 1;
2934 break;
2935 case ATM_LM_RMT_PHY: oc3_index = 2;
2936 break;
2937 default: oc3_index = 3;
2938 }
2939
2940 return sprintf(page,
2941 " firmware release:\t\t%d.%d.%d\n"
2942 " monitor release:\t\t%d.%d\n"
2943 " media type:\t\t\t%s\n"
2944 " OC-3 revision:\t\t0x%x\n"
2945 " OC-3 mode:\t\t\t%s",
2946 fw_release >> 16, fw_release << 16 >> 24, fw_release << 24 >> 24,
2947 mon960_release >> 16, mon960_release << 16 >> 16,
2948 media_name[ media_index ],
2949 oc3_revision,
2950 oc3_mode[ oc3_index ]);
2951 }
2952
2953 if (!left--) {
2954 struct cp_monitor __iomem * cp_monitor = fore200e->cp_monitor;
2955
2956 return sprintf(page,
2957 "\n\n"
2958 " monitor:\n"
2959 " version number:\t\t%d\n"
2960 " boot status word:\t\t0x%08x\n",
2961 fore200e->bus->read(&cp_monitor->mon_version),
2962 fore200e->bus->read(&cp_monitor->bstat));
2963 }
2964
2965 if (!left--)
2966 return sprintf(page,
2967 "\n"
2968 " device statistics:\n"
2969 " 4b5b:\n"
2970 " crc_header_errors:\t\t%10u\n"
2971 " framing_errors:\t\t%10u\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002972 cpu_to_be32(fore200e->stats->phy.crc_header_errors),
2973 cpu_to_be32(fore200e->stats->phy.framing_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974
2975 if (!left--)
2976 return sprintf(page, "\n"
2977 " OC-3:\n"
2978 " section_bip8_errors:\t%10u\n"
2979 " path_bip8_errors:\t\t%10u\n"
2980 " line_bip24_errors:\t\t%10u\n"
2981 " line_febe_errors:\t\t%10u\n"
2982 " path_febe_errors:\t\t%10u\n"
2983 " corr_hcs_errors:\t\t%10u\n"
2984 " ucorr_hcs_errors:\t\t%10u\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002985 cpu_to_be32(fore200e->stats->oc3.section_bip8_errors),
2986 cpu_to_be32(fore200e->stats->oc3.path_bip8_errors),
2987 cpu_to_be32(fore200e->stats->oc3.line_bip24_errors),
2988 cpu_to_be32(fore200e->stats->oc3.line_febe_errors),
2989 cpu_to_be32(fore200e->stats->oc3.path_febe_errors),
2990 cpu_to_be32(fore200e->stats->oc3.corr_hcs_errors),
2991 cpu_to_be32(fore200e->stats->oc3.ucorr_hcs_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992
2993 if (!left--)
2994 return sprintf(page,"\n"
2995 " ATM:\t\t\t\t cells\n"
2996 " TX:\t\t\t%10u\n"
2997 " RX:\t\t\t%10u\n"
2998 " vpi out of range:\t\t%10u\n"
2999 " vpi no conn:\t\t%10u\n"
3000 " vci out of range:\t\t%10u\n"
3001 " vci no conn:\t\t%10u\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08003002 cpu_to_be32(fore200e->stats->atm.cells_transmitted),
3003 cpu_to_be32(fore200e->stats->atm.cells_received),
3004 cpu_to_be32(fore200e->stats->atm.vpi_bad_range),
3005 cpu_to_be32(fore200e->stats->atm.vpi_no_conn),
3006 cpu_to_be32(fore200e->stats->atm.vci_bad_range),
3007 cpu_to_be32(fore200e->stats->atm.vci_no_conn));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008
3009 if (!left--)
3010 return sprintf(page,"\n"
3011 " AAL0:\t\t\t cells\n"
3012 " TX:\t\t\t%10u\n"
3013 " RX:\t\t\t%10u\n"
3014 " dropped:\t\t\t%10u\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08003015 cpu_to_be32(fore200e->stats->aal0.cells_transmitted),
3016 cpu_to_be32(fore200e->stats->aal0.cells_received),
3017 cpu_to_be32(fore200e->stats->aal0.cells_dropped));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
3019 if (!left--)
3020 return sprintf(page,"\n"
3021 " AAL3/4:\n"
3022 " SAR sublayer:\t\t cells\n"
3023 " TX:\t\t\t%10u\n"
3024 " RX:\t\t\t%10u\n"
3025 " dropped:\t\t\t%10u\n"
3026 " CRC errors:\t\t%10u\n"
3027 " protocol errors:\t\t%10u\n\n"
3028 " CS sublayer:\t\t PDUs\n"
3029 " TX:\t\t\t%10u\n"
3030 " RX:\t\t\t%10u\n"
3031 " dropped:\t\t\t%10u\n"
3032 " protocol errors:\t\t%10u\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08003033 cpu_to_be32(fore200e->stats->aal34.cells_transmitted),
3034 cpu_to_be32(fore200e->stats->aal34.cells_received),
3035 cpu_to_be32(fore200e->stats->aal34.cells_dropped),
3036 cpu_to_be32(fore200e->stats->aal34.cells_crc_errors),
3037 cpu_to_be32(fore200e->stats->aal34.cells_protocol_errors),
3038 cpu_to_be32(fore200e->stats->aal34.cspdus_transmitted),
3039 cpu_to_be32(fore200e->stats->aal34.cspdus_received),
3040 cpu_to_be32(fore200e->stats->aal34.cspdus_dropped),
3041 cpu_to_be32(fore200e->stats->aal34.cspdus_protocol_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042
3043 if (!left--)
3044 return sprintf(page,"\n"
3045 " AAL5:\n"
3046 " SAR sublayer:\t\t cells\n"
3047 " TX:\t\t\t%10u\n"
3048 " RX:\t\t\t%10u\n"
3049 " dropped:\t\t\t%10u\n"
3050 " congestions:\t\t%10u\n\n"
3051 " CS sublayer:\t\t PDUs\n"
3052 " TX:\t\t\t%10u\n"
3053 " RX:\t\t\t%10u\n"
3054 " dropped:\t\t\t%10u\n"
3055 " CRC errors:\t\t%10u\n"
3056 " protocol errors:\t\t%10u\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08003057 cpu_to_be32(fore200e->stats->aal5.cells_transmitted),
3058 cpu_to_be32(fore200e->stats->aal5.cells_received),
3059 cpu_to_be32(fore200e->stats->aal5.cells_dropped),
3060 cpu_to_be32(fore200e->stats->aal5.congestion_experienced),
3061 cpu_to_be32(fore200e->stats->aal5.cspdus_transmitted),
3062 cpu_to_be32(fore200e->stats->aal5.cspdus_received),
3063 cpu_to_be32(fore200e->stats->aal5.cspdus_dropped),
3064 cpu_to_be32(fore200e->stats->aal5.cspdus_crc_errors),
3065 cpu_to_be32(fore200e->stats->aal5.cspdus_protocol_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066
3067 if (!left--)
3068 return sprintf(page,"\n"
3069 " AUX:\t\t allocation failures\n"
3070 " small b1:\t\t\t%10u\n"
3071 " large b1:\t\t\t%10u\n"
3072 " small b2:\t\t\t%10u\n"
3073 " large b2:\t\t\t%10u\n"
3074 " RX PDUs:\t\t\t%10u\n"
3075 " TX PDUs:\t\t\t%10lu\n",
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08003076 cpu_to_be32(fore200e->stats->aux.small_b1_failed),
3077 cpu_to_be32(fore200e->stats->aux.large_b1_failed),
3078 cpu_to_be32(fore200e->stats->aux.small_b2_failed),
3079 cpu_to_be32(fore200e->stats->aux.large_b2_failed),
3080 cpu_to_be32(fore200e->stats->aux.rpd_alloc_failed),
Linus Torvalds1da177e2005-04-16 15:20:36 -07003081 fore200e->tx_sat);
3082
3083 if (!left--)
3084 return sprintf(page,"\n"
3085 " receive carrier:\t\t\t%s\n",
3086 fore200e->stats->aux.receive_carrier ? "ON" : "OFF!");
3087
3088 if (!left--) {
3089 return sprintf(page,"\n"
3090 " VCCs:\n address VPI VCI AAL "
3091 "TX PDUs TX min/max size RX PDUs RX min/max size\n");
3092 }
3093
3094 for (i = 0; i < NBR_CONNECT; i++) {
3095
3096 vcc = fore200e->vc_map[i].vcc;
3097
3098 if (vcc == NULL)
3099 continue;
3100
3101 spin_lock_irqsave(&fore200e->q_lock, flags);
3102
3103 if (vcc && test_bit(ATM_VF_READY, &vcc->flags) && !left--) {
3104
3105 fore200e_vcc = FORE200E_VCC(vcc);
3106 ASSERT(fore200e_vcc);
3107
3108 len = sprintf(page,
3109 " %08x %03d %05d %1d %09lu %05d/%05d %09lu %05d/%05d\n",
3110 (u32)(unsigned long)vcc,
3111 vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
3112 fore200e_vcc->tx_pdu,
3113 fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu,
3114 fore200e_vcc->tx_max_pdu,
3115 fore200e_vcc->rx_pdu,
3116 fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
3117 fore200e_vcc->rx_max_pdu);
3118
3119 spin_unlock_irqrestore(&fore200e->q_lock, flags);
3120 return len;
3121 }
3122
3123 spin_unlock_irqrestore(&fore200e->q_lock, flags);
3124 }
3125
3126 return 0;
3127}
3128
3129module_init(fore200e_module_init);
3130module_exit(fore200e_module_cleanup);
3131
3132
3133static const struct atmdev_ops fore200e_ops =
3134{
3135 .open = fore200e_open,
3136 .close = fore200e_close,
3137 .ioctl = fore200e_ioctl,
3138 .getsockopt = fore200e_getsockopt,
3139 .setsockopt = fore200e_setsockopt,
3140 .send = fore200e_send,
3141 .change_qos = fore200e_change_qos,
3142 .proc_read = fore200e_proc_read,
3143 .owner = THIS_MODULE
3144};
3145
3146
3147#ifdef CONFIG_ATM_FORE200E_PCA
3148extern const unsigned char _fore200e_pca_fw_data[];
3149extern const unsigned int _fore200e_pca_fw_size;
3150#endif
3151#ifdef CONFIG_ATM_FORE200E_SBA
3152extern const unsigned char _fore200e_sba_fw_data[];
3153extern const unsigned int _fore200e_sba_fw_size;
3154#endif
3155
3156static const struct fore200e_bus fore200e_bus[] = {
3157#ifdef CONFIG_ATM_FORE200E_PCA
3158 { "PCA-200E", "pca200e", 32, 4, 32,
3159 _fore200e_pca_fw_data, &_fore200e_pca_fw_size,
3160 fore200e_pca_read,
3161 fore200e_pca_write,
3162 fore200e_pca_dma_map,
3163 fore200e_pca_dma_unmap,
3164 fore200e_pca_dma_sync_for_cpu,
3165 fore200e_pca_dma_sync_for_device,
3166 fore200e_pca_dma_chunk_alloc,
3167 fore200e_pca_dma_chunk_free,
3168 NULL,
3169 fore200e_pca_configure,
3170 fore200e_pca_map,
3171 fore200e_pca_reset,
3172 fore200e_pca_prom_read,
3173 fore200e_pca_unmap,
3174 NULL,
3175 fore200e_pca_irq_check,
3176 fore200e_pca_irq_ack,
3177 fore200e_pca_proc_read,
3178 },
3179#endif
3180#ifdef CONFIG_ATM_FORE200E_SBA
3181 { "SBA-200E", "sba200e", 32, 64, 32,
3182 _fore200e_sba_fw_data, &_fore200e_sba_fw_size,
3183 fore200e_sba_read,
3184 fore200e_sba_write,
3185 fore200e_sba_dma_map,
3186 fore200e_sba_dma_unmap,
3187 fore200e_sba_dma_sync_for_cpu,
3188 fore200e_sba_dma_sync_for_device,
3189 fore200e_sba_dma_chunk_alloc,
3190 fore200e_sba_dma_chunk_free,
3191 fore200e_sba_detect,
3192 fore200e_sba_configure,
3193 fore200e_sba_map,
3194 fore200e_sba_reset,
3195 fore200e_sba_prom_read,
3196 fore200e_sba_unmap,
3197 fore200e_sba_irq_enable,
3198 fore200e_sba_irq_check,
3199 fore200e_sba_irq_ack,
3200 fore200e_sba_proc_read,
3201 },
3202#endif
3203 {}
3204};
3205
3206#ifdef MODULE_LICENSE
3207MODULE_LICENSE("GPL");
3208#endif