blob: beeb71088560dce0d48ddd81dfc2f376d2a63e8c [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 A FORE Systems 200E-series driver for ATM on Linux.
3 Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2003.
4
5 Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
6
7 This driver simultaneously supports PCA-200E and SBA-200E adapters
8 on i386, alpha (untested), powerpc, sparc and sparc64 architectures.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23*/
24
25
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/kernel.h>
27#include <linux/slab.h>
28#include <linux/init.h>
29#include <linux/capability.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070030#include <linux/interrupt.h>
31#include <linux/bitops.h>
32#include <linux/pci.h>
33#include <linux/module.h>
34#include <linux/atmdev.h>
35#include <linux/sonet.h>
36#include <linux/atm_suni.h>
37#include <linux/dma-mapping.h>
38#include <linux/delay.h>
Chas Williamse92481f2008-06-17 16:23:11 -070039#include <linux/firmware.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <asm/io.h>
41#include <asm/string.h>
42#include <asm/page.h>
43#include <asm/irq.h>
44#include <asm/dma.h>
45#include <asm/byteorder.h>
Linus Torvalds7c0f6ba2016-12-24 11:46:01 -080046#include <linux/uaccess.h>
Arun Sharma600634972011-07-26 16:09:06 -070047#include <linux/atomic.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
Chas Williamse92481f2008-06-17 16:23:11 -070049#ifdef CONFIG_SBUS
David S. Miller826b6cf2008-08-27 01:06:07 -070050#include <linux/of.h>
51#include <linux/of_device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070052#include <asm/idprom.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070053#include <asm/openprom.h>
54#include <asm/oplib.h>
55#include <asm/pgtable.h>
56#endif
57
58#if defined(CONFIG_ATM_FORE200E_USE_TASKLET) /* defer interrupt work to a tasklet */
59#define FORE200E_USE_TASKLET
60#endif
61
62#if 0 /* enable the debugging code of the buffer supply queues */
63#define FORE200E_BSQ_DEBUG
64#endif
65
66#if 1 /* ensure correct handling of 52-byte AAL0 SDUs expected by atmdump-like apps */
67#define FORE200E_52BYTE_AAL0_SDU
68#endif
69
70#include "fore200e.h"
71#include "suni.h"
72
73#define FORE200E_VERSION "0.3e"
74
75#define FORE200E "fore200e: "
76
77#if 0 /* override .config */
78#define CONFIG_ATM_FORE200E_DEBUG 1
79#endif
80#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
81#define DPRINTK(level, format, args...) do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
82 printk(FORE200E format, ##args); } while (0)
83#else
84#define DPRINTK(level, format, args...) do {} while (0)
85#endif
86
87
88#define FORE200E_ALIGN(addr, alignment) \
89 ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr))
90
91#define FORE200E_DMA_INDEX(dma_addr, type, index) ((dma_addr) + (index) * sizeof(type))
92
93#define FORE200E_INDEX(virt_addr, type, index) (&((type *)(virt_addr))[ index ])
94
David S. Miller30dfe2c2010-11-18 11:49:25 -080095#define FORE200E_NEXT_ENTRY(index, modulo) (index = ((index) + 1) % (modulo))
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
97#if 1
98#define ASSERT(expr) if (!(expr)) { \
99 printk(FORE200E "assertion failed! %s[%d]: %s\n", \
Harvey Harrison5a346a12008-03-05 18:38:07 -0800100 __func__, __LINE__, #expr); \
101 panic(FORE200E "%s", __func__); \
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 }
103#else
104#define ASSERT(expr) do {} while (0)
105#endif
106
107
108static const struct atmdev_ops fore200e_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109
110static LIST_HEAD(fore200e_boards);
111
112
113MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
114MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION);
115MODULE_SUPPORTED_DEVICE("PCA-200E, SBA-200E");
116
117
118static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
119 { BUFFER_S1_NBR, BUFFER_L1_NBR },
120 { BUFFER_S2_NBR, BUFFER_L2_NBR }
121};
122
123static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
124 { BUFFER_S1_SIZE, BUFFER_L1_SIZE },
125 { BUFFER_S2_SIZE, BUFFER_L2_SIZE }
126};
127
128
129#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
130static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" };
131#endif
132
133
134#if 0 /* currently unused */
135static int
136fore200e_fore2atm_aal(enum fore200e_aal aal)
137{
138 switch(aal) {
139 case FORE200E_AAL0: return ATM_AAL0;
140 case FORE200E_AAL34: return ATM_AAL34;
141 case FORE200E_AAL5: return ATM_AAL5;
142 }
143
144 return -EINVAL;
145}
146#endif
147
148
149static enum fore200e_aal
150fore200e_atm2fore_aal(int aal)
151{
152 switch(aal) {
153 case ATM_AAL0: return FORE200E_AAL0;
154 case ATM_AAL34: return FORE200E_AAL34;
155 case ATM_AAL1:
156 case ATM_AAL2:
157 case ATM_AAL5: return FORE200E_AAL5;
158 }
159
160 return -EINVAL;
161}
162
163
164static char*
165fore200e_irq_itoa(int irq)
166{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 static char str[8];
168 sprintf(str, "%d", irq);
169 return str;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170}
171
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173/* allocate and align a chunk of memory intended to hold the data behing exchanged
174 between the driver and the adapter (using streaming DVMA) */
175
176static int
177fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment, int direction)
178{
179 unsigned long offset = 0;
180
181 if (alignment <= sizeof(int))
182 alignment = 0;
183
184 chunk->alloc_size = size + alignment;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 chunk->direction = direction;
186
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -0800187 chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL | GFP_DMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 if (chunk->alloc_addr == NULL)
189 return -ENOMEM;
190
191 if (alignment > 0)
192 offset = FORE200E_ALIGN(chunk->alloc_addr, alignment);
193
194 chunk->align_addr = chunk->alloc_addr + offset;
195
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +0200196 chunk->dma_addr = dma_map_single(fore200e->dev, chunk->align_addr,
197 size, direction);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 return 0;
199}
200
201
202/* free a chunk of memory */
203
204static void
205fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
206{
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +0200207 dma_unmap_single(fore200e->dev, chunk->dma_addr, chunk->dma_size,
208 chunk->direction);
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -0800209 kfree(chunk->alloc_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210}
211
212
213static void
214fore200e_spin(int msecs)
215{
216 unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
217 while (time_before(jiffies, timeout));
218}
219
220
221static int
222fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
223{
224 unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
225 int ok;
226
227 mb();
228 do {
229 if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
230 break;
231
232 } while (time_before(jiffies, timeout));
233
234#if 1
235 if (!ok) {
236 printk(FORE200E "cmd polling failed, got status 0x%08x, expected 0x%08x\n",
237 *addr, val);
238 }
239#endif
240
241 return ok;
242}
243
244
245static int
246fore200e_io_poll(struct fore200e* fore200e, volatile u32 __iomem *addr, u32 val, int msecs)
247{
248 unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
249 int ok;
250
251 do {
252 if ((ok = (fore200e->bus->read(addr) == val)))
253 break;
254
255 } while (time_before(jiffies, timeout));
256
257#if 1
258 if (!ok) {
259 printk(FORE200E "I/O polling failed, got status 0x%08x, expected 0x%08x\n",
260 fore200e->bus->read(addr), val);
261 }
262#endif
263
264 return ok;
265}
266
267
268static void
269fore200e_free_rx_buf(struct fore200e* fore200e)
270{
271 int scheme, magn, nbr;
272 struct buffer* buffer;
273
274 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
275 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
276
277 if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) {
278
279 for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) {
280
281 struct chunk* data = &buffer[ nbr ].data;
282
283 if (data->alloc_addr != NULL)
284 fore200e_chunk_free(fore200e, data);
285 }
286 }
287 }
288 }
289}
290
291
292static void
293fore200e_uninit_bs_queue(struct fore200e* fore200e)
294{
295 int scheme, magn;
296
297 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
298 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
299
300 struct chunk* status = &fore200e->host_bsq[ scheme ][ magn ].status;
301 struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block;
302
303 if (status->alloc_addr)
304 fore200e->bus->dma_chunk_free(fore200e, status);
305
306 if (rbd_block->alloc_addr)
307 fore200e->bus->dma_chunk_free(fore200e, rbd_block);
308 }
309 }
310}
311
312
313static int
314fore200e_reset(struct fore200e* fore200e, int diag)
315{
316 int ok;
317
318 fore200e->cp_monitor = fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET;
319
320 fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat);
321
322 fore200e->bus->reset(fore200e);
323
324 if (diag) {
325 ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000);
326 if (ok == 0) {
327
328 printk(FORE200E "device %s self-test failed\n", fore200e->name);
329 return -ENODEV;
330 }
331
332 printk(FORE200E "device %s self-test passed\n", fore200e->name);
333
334 fore200e->state = FORE200E_STATE_RESET;
335 }
336
337 return 0;
338}
339
340
341static void
342fore200e_shutdown(struct fore200e* fore200e)
343{
344 printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n",
345 fore200e->name, fore200e->phys_base,
346 fore200e_irq_itoa(fore200e->irq));
347
348 if (fore200e->state > FORE200E_STATE_RESET) {
349 /* first, reset the board to prevent further interrupts or data transfers */
350 fore200e_reset(fore200e, 0);
351 }
352
353 /* then, release all allocated resources */
354 switch(fore200e->state) {
355
356 case FORE200E_STATE_COMPLETE:
Jesper Juhla2c1aa52005-06-02 13:04:07 -0700357 kfree(fore200e->stats);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500359 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 case FORE200E_STATE_IRQ:
361 free_irq(fore200e->irq, fore200e->atm_dev);
362
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500363 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 case FORE200E_STATE_ALLOC_BUF:
365 fore200e_free_rx_buf(fore200e);
366
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500367 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 case FORE200E_STATE_INIT_BSQ:
369 fore200e_uninit_bs_queue(fore200e);
370
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500371 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 case FORE200E_STATE_INIT_RXQ:
373 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.status);
374 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_rxq.rpd);
375
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500376 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 case FORE200E_STATE_INIT_TXQ:
378 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.status);
379 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_txq.tpd);
380
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500381 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 case FORE200E_STATE_INIT_CMDQ:
383 fore200e->bus->dma_chunk_free(fore200e, &fore200e->host_cmdq.status);
384
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500385 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 case FORE200E_STATE_INITIALIZE:
387 /* nothing to do for that state */
388
389 case FORE200E_STATE_START_FW:
390 /* nothing to do for that state */
391
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 case FORE200E_STATE_RESET:
393 /* nothing to do for that state */
394
395 case FORE200E_STATE_MAP:
396 fore200e->bus->unmap(fore200e);
397
Gustavo A. R. Silvaec0d0982017-10-12 16:11:32 -0500398 /* fall through */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 case FORE200E_STATE_CONFIGURE:
400 /* nothing to do for that state */
401
402 case FORE200E_STATE_REGISTER:
403 /* XXX shouldn't we *start* by deregistering the device? */
404 atm_dev_deregister(fore200e->atm_dev);
405
406 case FORE200E_STATE_BLANK:
407 /* nothing to do for that state */
408 break;
409 }
410}
411
412
Chas Williamse92481f2008-06-17 16:23:11 -0700413#ifdef CONFIG_PCI
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
415static u32 fore200e_pca_read(volatile u32 __iomem *addr)
416{
417 /* on big-endian hosts, the board is configured to convert
418 the endianess of slave RAM accesses */
419 return le32_to_cpu(readl(addr));
420}
421
422
423static void fore200e_pca_write(u32 val, volatile u32 __iomem *addr)
424{
425 /* on big-endian hosts, the board is configured to convert
426 the endianess of slave RAM accesses */
427 writel(cpu_to_le32(val), addr);
428}
429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430/* allocate a DMA consistent chunk of memory intended to act as a communication mechanism
431 (to hold descriptors, status, queues, etc.) shared by the driver and the adapter */
432
433static int
434fore200e_pca_dma_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk,
435 int size, int nbr, int alignment)
436{
437 /* returned chunks are page-aligned */
438 chunk->alloc_size = size * nbr;
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200439 chunk->alloc_addr = dma_alloc_coherent(fore200e->dev,
chas williams - CONTRACTORede58ef2015-01-16 08:57:21 -0500440 chunk->alloc_size,
441 &chunk->dma_addr,
442 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443
444 if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
445 return -ENOMEM;
446
447 chunk->align_addr = chunk->alloc_addr;
448
449 return 0;
450}
451
452
453/* free a DMA consistent chunk of memory */
454
455static void
456fore200e_pca_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
457{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200458 dma_free_coherent(fore200e->dev,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 chunk->alloc_size,
460 chunk->alloc_addr,
461 chunk->dma_addr);
462}
463
464
465static int
466fore200e_pca_irq_check(struct fore200e* fore200e)
467{
468 /* this is a 1 bit register */
469 int irq_posted = readl(fore200e->regs.pca.psr);
470
471#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG == 2)
472 if (irq_posted && (readl(fore200e->regs.pca.hcr) & PCA200E_HCR_OUTFULL)) {
473 DPRINTK(2,"FIFO OUT full, device %d\n", fore200e->atm_dev->number);
474 }
475#endif
476
477 return irq_posted;
478}
479
480
481static void
482fore200e_pca_irq_ack(struct fore200e* fore200e)
483{
484 writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr);
485}
486
487
488static void
489fore200e_pca_reset(struct fore200e* fore200e)
490{
491 writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr);
492 fore200e_spin(10);
493 writel(0, fore200e->regs.pca.hcr);
494}
495
496
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -0800497static int fore200e_pca_map(struct fore200e* fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498{
499 DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
500
501 fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH);
502
503 if (fore200e->virt_base == NULL) {
504 printk(FORE200E "can't map device %s\n", fore200e->name);
505 return -EFAULT;
506 }
507
508 DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
509
510 /* gain access to the PCA specific registers */
511 fore200e->regs.pca.hcr = fore200e->virt_base + PCA200E_HCR_OFFSET;
512 fore200e->regs.pca.imr = fore200e->virt_base + PCA200E_IMR_OFFSET;
513 fore200e->regs.pca.psr = fore200e->virt_base + PCA200E_PSR_OFFSET;
514
515 fore200e->state = FORE200E_STATE_MAP;
516 return 0;
517}
518
519
520static void
521fore200e_pca_unmap(struct fore200e* fore200e)
522{
523 DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
524
525 if (fore200e->virt_base != NULL)
526 iounmap(fore200e->virt_base);
527}
528
529
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -0800530static int fore200e_pca_configure(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200532 struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700533 u8 master_ctrl, latency;
534
535 DPRINTK(2, "device %s being configured\n", fore200e->name);
536
537 if ((pci_dev->irq == 0) || (pci_dev->irq == 0xFF)) {
538 printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n");
539 return -EIO;
540 }
541
542 pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl);
543
544 master_ctrl = master_ctrl
545#if defined(__BIG_ENDIAN)
546 /* request the PCA board to convert the endianess of slave RAM accesses */
547 | PCA200E_CTRL_CONVERT_ENDIAN
548#endif
549#if 0
550 | PCA200E_CTRL_DIS_CACHE_RD
551 | PCA200E_CTRL_DIS_WRT_INVAL
552 | PCA200E_CTRL_ENA_CONT_REQ_MODE
553 | PCA200E_CTRL_2_CACHE_WRT_INVAL
554#endif
555 | PCA200E_CTRL_LARGE_PCI_BURSTS;
556
557 pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl);
558
559 /* raise latency from 32 (default) to 192, as this seems to prevent NIC
560 lockups (under heavy rx loads) due to continuous 'FIFO OUT full' condition.
561 this may impact the performances of other PCI devices on the same bus, though */
562 latency = 192;
563 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
564
565 fore200e->state = FORE200E_STATE_CONFIGURE;
566 return 0;
567}
568
569
570static int __init
571fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
572{
573 struct host_cmdq* cmdq = &fore200e->host_cmdq;
574 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
575 struct prom_opcode opcode;
576 int ok;
577 u32 prom_dma;
578
579 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
580
581 opcode.opcode = OPCODE_GET_PROM;
582 opcode.pad = 0;
583
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +0200584 prom_dma = dma_map_single(fore200e->dev, prom, sizeof(struct prom_data),
585 DMA_FROM_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586
587 fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
588
589 *entry->status = STATUS_PENDING;
590
591 fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.prom_block.opcode);
592
593 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
594
595 *entry->status = STATUS_FREE;
596
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +0200597 dma_unmap_single(fore200e->dev, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 if (ok == 0) {
600 printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
601 return -EIO;
602 }
603
604#if defined(__BIG_ENDIAN)
605
606#define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) ))
607
608 /* MAC address is stored as little-endian */
609 swap_here(&prom->mac_addr[0]);
610 swap_here(&prom->mac_addr[4]);
611#endif
612
613 return 0;
614}
615
616
617static int
618fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
619{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200620 struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621
622 return sprintf(page, " PCI bus/slot/function:\t%d/%d/%d\n",
623 pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
624}
625
Christoph Hellwig0efe5522018-10-09 16:57:14 +0200626static const struct fore200e_bus fore200e_pci_ops = {
627 .model_name = "PCA-200E",
628 .proc_name = "pca200e",
629 .descr_alignment = 32,
630 .buffer_alignment = 4,
631 .status_alignment = 32,
632 .read = fore200e_pca_read,
633 .write = fore200e_pca_write,
Christoph Hellwig0efe5522018-10-09 16:57:14 +0200634 .dma_chunk_alloc = fore200e_pca_dma_chunk_alloc,
635 .dma_chunk_free = fore200e_pca_dma_chunk_free,
636 .configure = fore200e_pca_configure,
637 .map = fore200e_pca_map,
638 .reset = fore200e_pca_reset,
639 .prom_read = fore200e_pca_prom_read,
640 .unmap = fore200e_pca_unmap,
641 .irq_check = fore200e_pca_irq_check,
642 .irq_ack = fore200e_pca_irq_ack,
643 .proc_read = fore200e_pca_proc_read,
644};
Chas Williamse92481f2008-06-17 16:23:11 -0700645#endif /* CONFIG_PCI */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646
Chas Williamse92481f2008-06-17 16:23:11 -0700647#ifdef CONFIG_SBUS
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648
David S. Miller826b6cf2008-08-27 01:06:07 -0700649static u32 fore200e_sba_read(volatile u32 __iomem *addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650{
651 return sbus_readl(addr);
652}
653
David S. Miller826b6cf2008-08-27 01:06:07 -0700654static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655{
656 sbus_writel(val, addr);
657}
658
David S. Miller826b6cf2008-08-27 01:06:07 -0700659/* Allocate a DVMA consistent chunk of memory intended to act as a communication mechanism
660 * (to hold descriptors, status, queues, etc.) shared by the driver and the adapter.
661 */
662static int fore200e_sba_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk,
663 int size, int nbr, int alignment)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664{
Christoph Hellwig8b08adb2018-10-09 16:57:16 +0200665 chunk->alloc_size = size * nbr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666
David S. Miller826b6cf2008-08-27 01:06:07 -0700667 /* returned chunks are page-aligned */
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200668 chunk->alloc_addr = dma_alloc_coherent(fore200e->dev, chunk->alloc_size,
David S. Miller826b6cf2008-08-27 01:06:07 -0700669 &chunk->dma_addr, GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
David S. Miller826b6cf2008-08-27 01:06:07 -0700671 if ((chunk->alloc_addr == NULL) || (chunk->dma_addr == 0))
672 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673
David S. Miller826b6cf2008-08-27 01:06:07 -0700674 chunk->align_addr = chunk->alloc_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675
David S. Miller826b6cf2008-08-27 01:06:07 -0700676 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677}
678
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679/* free a DVMA consistent chunk of memory */
David S. Miller826b6cf2008-08-27 01:06:07 -0700680static void fore200e_sba_dma_chunk_free(struct fore200e *fore200e, struct chunk *chunk)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200682 dma_free_coherent(fore200e->dev, chunk->alloc_size,
David S. Miller826b6cf2008-08-27 01:06:07 -0700683 chunk->alloc_addr, chunk->dma_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684}
685
David S. Miller826b6cf2008-08-27 01:06:07 -0700686static void fore200e_sba_irq_enable(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687{
David S. Miller826b6cf2008-08-27 01:06:07 -0700688 u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
689 fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690}
691
David S. Miller826b6cf2008-08-27 01:06:07 -0700692static int fore200e_sba_irq_check(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693{
David S. Miller826b6cf2008-08-27 01:06:07 -0700694 return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695}
696
David S. Miller826b6cf2008-08-27 01:06:07 -0700697static void fore200e_sba_irq_ack(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698{
David S. Miller826b6cf2008-08-27 01:06:07 -0700699 u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
700 fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701}
702
David S. Miller826b6cf2008-08-27 01:06:07 -0700703static void fore200e_sba_reset(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704{
David S. Miller826b6cf2008-08-27 01:06:07 -0700705 fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
706 fore200e_spin(10);
707 fore200e->bus->write(0, fore200e->regs.sba.hcr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708}
709
David S. Miller826b6cf2008-08-27 01:06:07 -0700710static int __init fore200e_sba_map(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200712 struct platform_device *op = to_platform_device(fore200e->dev);
David S. Miller826b6cf2008-08-27 01:06:07 -0700713 unsigned int bursts;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
David S. Miller826b6cf2008-08-27 01:06:07 -0700715 /* gain access to the SBA specific registers */
716 fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
717 fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
718 fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
719 fore200e->virt_base = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
David S. Miller826b6cf2008-08-27 01:06:07 -0700721 if (!fore200e->virt_base) {
722 printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
723 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 }
David S. Miller826b6cf2008-08-27 01:06:07 -0700725
726 DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727
David S. Miller826b6cf2008-08-27 01:06:07 -0700728 fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
David S. Miller826b6cf2008-08-27 01:06:07 -0700730 /* get the supported DVMA burst sizes */
Grant Likely61c7a082010-04-13 16:12:29 -0700731 bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
David S. Miller826b6cf2008-08-27 01:06:07 -0700733 if (sbus_can_dma_64bit())
734 sbus_set_sbus64(&op->dev, bursts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
David S. Miller826b6cf2008-08-27 01:06:07 -0700736 fore200e->state = FORE200E_STATE_MAP;
737 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738}
739
David S. Miller826b6cf2008-08-27 01:06:07 -0700740static void fore200e_sba_unmap(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200742 struct platform_device *op = to_platform_device(fore200e->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743
David S. Miller826b6cf2008-08-27 01:06:07 -0700744 of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
745 of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
746 of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
747 of_iounmap(&op->resource[3], fore200e->virt_base, SBA200E_RAM_LENGTH);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748}
749
David S. Miller826b6cf2008-08-27 01:06:07 -0700750static int __init fore200e_sba_configure(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700751{
David S. Miller826b6cf2008-08-27 01:06:07 -0700752 fore200e->state = FORE200E_STATE_CONFIGURE;
753 return 0;
754}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755
David S. Miller826b6cf2008-08-27 01:06:07 -0700756static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom)
757{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200758 struct platform_device *op = to_platform_device(fore200e->dev);
David S. Miller826b6cf2008-08-27 01:06:07 -0700759 const u8 *prop;
760 int len;
761
Grant Likely61c7a082010-04-13 16:12:29 -0700762 prop = of_get_property(op->dev.of_node, "madaddrlo2", &len);
David S. Miller826b6cf2008-08-27 01:06:07 -0700763 if (!prop)
764 return -ENODEV;
765 memcpy(&prom->mac_addr[4], prop, 4);
766
Grant Likely61c7a082010-04-13 16:12:29 -0700767 prop = of_get_property(op->dev.of_node, "madaddrhi4", &len);
David S. Miller826b6cf2008-08-27 01:06:07 -0700768 if (!prop)
769 return -ENODEV;
770 memcpy(&prom->mac_addr[2], prop, 4);
771
Grant Likely61c7a082010-04-13 16:12:29 -0700772 prom->serial_number = of_getintprop_default(op->dev.of_node,
773 "serialnumber", 0);
774 prom->hw_revision = of_getintprop_default(op->dev.of_node,
775 "promversion", 0);
David S. Miller826b6cf2008-08-27 01:06:07 -0700776
777 return 0;
778}
779
780static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
781{
Christoph Hellwigaff9d262018-10-09 16:57:15 +0200782 struct platform_device *op = to_platform_device(fore200e->dev);
David S. Miller826b6cf2008-08-27 01:06:07 -0700783 const struct linux_prom_registers *regs;
784
Grant Likely61c7a082010-04-13 16:12:29 -0700785 regs = of_get_property(op->dev.of_node, "reg", NULL);
David S. Miller826b6cf2008-08-27 01:06:07 -0700786
787 return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n",
Grant Likely61c7a082010-04-13 16:12:29 -0700788 (regs ? regs->which_io : 0), op->dev.of_node->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
Christoph Hellwig0efe5522018-10-09 16:57:14 +0200791static const struct fore200e_bus fore200e_sbus_ops = {
792 .model_name = "SBA-200E",
793 .proc_name = "sba200e",
794 .descr_alignment = 32,
795 .buffer_alignent = 64,
796 .status_alignment = 32,
797 .read = fore200e_sba_read,
798 .write = fore200e_sba_write,
Christoph Hellwig0efe5522018-10-09 16:57:14 +0200799 .dma_chunk_alloc = fore200e_sba_dma_chunk_alloc,
800 .dma_chunk_free = fore200e_sba_dma_chunk_free,
801 .configure = fore200e_sba_configure,
802 .map = fore200e_sba_map,
803 .reset = fore200e_sba_reset,
804 .prom_read = fore200e_sba_prom_read,
805 .unmap = fore200e_sba_unmap,
806 .irq_enable = fore200e_sba_irq_enable,
807 .irq_check = fore200e_sba_irq_check,
808 .irq_ack = fore200e_sba_irq_ack,
809 .proc_read = fore200e_sba_proc_read,
810};
811#endif /* CONFIG_SBUS */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
813static void
814fore200e_tx_irq(struct fore200e* fore200e)
815{
816 struct host_txq* txq = &fore200e->host_txq;
817 struct host_txq_entry* entry;
818 struct atm_vcc* vcc;
819 struct fore200e_vc_map* vc_map;
820
821 if (fore200e->host_txq.txing == 0)
822 return;
823
824 for (;;) {
825
826 entry = &txq->host_entry[ txq->tail ];
827
828 if ((*entry->status & STATUS_COMPLETE) == 0) {
829 break;
830 }
831
832 DPRINTK(3, "TX COMPLETED: entry = %p [tail = %d], vc_map = %p, skb = %p\n",
833 entry, txq->tail, entry->vc_map, entry->skb);
834
835 /* free copy of misaligned data */
Jesper Juhla2c1aa52005-06-02 13:04:07 -0700836 kfree(entry->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838 /* remove DMA mapping */
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +0200839 dma_unmap_single(fore200e->dev, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 DMA_TO_DEVICE);
841
842 vc_map = entry->vc_map;
843
844 /* vcc closed since the time the entry was submitted for tx? */
845 if ((vc_map->vcc == NULL) ||
846 (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
847
848 DPRINTK(1, "no ready vcc found for PDU sent on device %d\n",
849 fore200e->atm_dev->number);
850
851 dev_kfree_skb_any(entry->skb);
852 }
853 else {
854 ASSERT(vc_map->vcc);
855
856 /* vcc closed then immediately re-opened? */
857 if (vc_map->incarn != entry->incarn) {
858
859 /* when a vcc is closed, some PDUs may be still pending in the tx queue.
860 if the same vcc is immediately re-opened, those pending PDUs must
861 not be popped after the completion of their emission, as they refer
862 to the prior incarnation of that vcc. otherwise, sk_atm(vcc)->sk_wmem_alloc
863 would be decremented by the size of the (unrelated) skb, possibly
864 leading to a negative sk->sk_wmem_alloc count, ultimately freezing the vcc.
865 we thus bind the tx entry to the current incarnation of the vcc
866 when the entry is submitted for tx. When the tx later completes,
867 if the incarnation number of the tx entry does not match the one
868 of the vcc, then this implies that the vcc has been closed then re-opened.
869 we thus just drop the skb here. */
870
871 DPRINTK(1, "vcc closed-then-re-opened; dropping PDU sent on device %d\n",
872 fore200e->atm_dev->number);
873
874 dev_kfree_skb_any(entry->skb);
875 }
876 else {
877 vcc = vc_map->vcc;
878 ASSERT(vcc);
879
880 /* notify tx completion */
881 if (vcc->pop) {
882 vcc->pop(vcc, entry->skb);
883 }
884 else {
885 dev_kfree_skb_any(entry->skb);
886 }
Reshetova, Elena14afee42017-06-30 13:08:00 +0300887
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 /* check error condition */
889 if (*entry->status & STATUS_ERROR)
890 atomic_inc(&vcc->stats->tx_err);
891 else
892 atomic_inc(&vcc->stats->tx);
893 }
894 }
895
896 *entry->status = STATUS_FREE;
897
898 fore200e->host_txq.txing--;
899
900 FORE200E_NEXT_ENTRY(txq->tail, QUEUE_SIZE_TX);
901 }
902}
903
904
905#ifdef FORE200E_BSQ_DEBUG
906int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn)
907{
908 struct buffer* buffer;
909 int count = 0;
910
911 buffer = bsq->freebuf;
912 while (buffer) {
913
914 if (buffer->supplied) {
915 printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld supplied but in free list!\n",
916 where, scheme, magn, buffer->index);
917 }
918
919 if (buffer->magn != magn) {
920 printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected magn = %d\n",
921 where, scheme, magn, buffer->index, buffer->magn);
922 }
923
924 if (buffer->scheme != scheme) {
925 printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected scheme = %d\n",
926 where, scheme, magn, buffer->index, buffer->scheme);
927 }
928
929 if ((buffer->index < 0) || (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ])) {
930 printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
931 where, scheme, magn, buffer->index);
932 }
933
934 count++;
935 buffer = buffer->next;
936 }
937
938 if (count != bsq->freebuf_count) {
939 printk(FORE200E "bsq_audit(%d): queue %d.%d, %d bufs in free list, but freebuf_count = %d\n",
940 where, scheme, magn, count, bsq->freebuf_count);
941 }
942 return 0;
943}
944#endif
945
946
947static void
948fore200e_supply(struct fore200e* fore200e)
949{
950 int scheme, magn, i;
951
952 struct host_bsq* bsq;
953 struct host_bsq_entry* entry;
954 struct buffer* buffer;
955
956 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
957 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
958
959 bsq = &fore200e->host_bsq[ scheme ][ magn ];
960
961#ifdef FORE200E_BSQ_DEBUG
962 bsq_audit(1, bsq, scheme, magn);
963#endif
964 while (bsq->freebuf_count >= RBD_BLK_SIZE) {
965
966 DPRINTK(2, "supplying %d rx buffers to queue %d / %d, freebuf_count = %d\n",
967 RBD_BLK_SIZE, scheme, magn, bsq->freebuf_count);
968
969 entry = &bsq->host_entry[ bsq->head ];
970
971 for (i = 0; i < RBD_BLK_SIZE; i++) {
972
973 /* take the first buffer in the free buffer list */
974 buffer = bsq->freebuf;
975 if (!buffer) {
976 printk(FORE200E "no more free bufs in queue %d.%d, but freebuf_count = %d\n",
977 scheme, magn, bsq->freebuf_count);
978 return;
979 }
980 bsq->freebuf = buffer->next;
981
982#ifdef FORE200E_BSQ_DEBUG
983 if (buffer->supplied)
984 printk(FORE200E "queue %d.%d, buffer %lu already supplied\n",
985 scheme, magn, buffer->index);
986 buffer->supplied = 1;
987#endif
988 entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
989 entry->rbd_block->rbd[ i ].handle = FORE200E_BUF2HDL(buffer);
990 }
991
992 FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
993
994 /* decrease accordingly the number of free rx buffers */
995 bsq->freebuf_count -= RBD_BLK_SIZE;
996
997 *entry->status = STATUS_PENDING;
998 fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
999 }
1000 }
1001 }
1002}
1003
1004
1005static int
1006fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rpd)
1007{
1008 struct sk_buff* skb;
1009 struct buffer* buffer;
1010 struct fore200e_vcc* fore200e_vcc;
1011 int i, pdu_len = 0;
1012#ifdef FORE200E_52BYTE_AAL0_SDU
1013 u32 cell_header = 0;
1014#endif
1015
1016 ASSERT(vcc);
1017
1018 fore200e_vcc = FORE200E_VCC(vcc);
1019 ASSERT(fore200e_vcc);
1020
1021#ifdef FORE200E_52BYTE_AAL0_SDU
1022 if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) {
1023
1024 cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) |
1025 (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) |
1026 (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) |
1027 (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) |
1028 rpd->atm_header.clp;
1029 pdu_len = 4;
1030 }
1031#endif
1032
1033 /* compute total PDU length */
1034 for (i = 0; i < rpd->nseg; i++)
1035 pdu_len += rpd->rsd[ i ].length;
1036
1037 skb = alloc_skb(pdu_len, GFP_ATOMIC);
1038 if (skb == NULL) {
1039 DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
1040
1041 atomic_inc(&vcc->stats->rx_drop);
1042 return -ENOMEM;
1043 }
1044
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001045 __net_timestamp(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
1047#ifdef FORE200E_52BYTE_AAL0_SDU
1048 if (cell_header) {
1049 *((u32*)skb_put(skb, 4)) = cell_header;
1050 }
1051#endif
1052
1053 /* reassemble segments */
1054 for (i = 0; i < rpd->nseg; i++) {
1055
1056 /* rebuild rx buffer address from rsd handle */
1057 buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
1058
1059 /* Make device DMA transfer visible to CPU. */
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +02001060 dma_sync_single_for_cpu(fore200e->dev, buffer->data.dma_addr,
1061 rpd->rsd[i].length, DMA_FROM_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062
Johannes Berg59ae1d12017-06-16 14:29:20 +02001063 skb_put_data(skb, buffer->data.align_addr, rpd->rsd[i].length);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
1065 /* Now let the device get at it again. */
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +02001066 dma_sync_single_for_device(fore200e->dev, buffer->data.dma_addr,
1067 rpd->rsd[i].length, DMA_FROM_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 }
1069
1070 DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
1071
1072 if (pdu_len < fore200e_vcc->rx_min_pdu)
1073 fore200e_vcc->rx_min_pdu = pdu_len;
1074 if (pdu_len > fore200e_vcc->rx_max_pdu)
1075 fore200e_vcc->rx_max_pdu = pdu_len;
1076 fore200e_vcc->rx_pdu++;
1077
1078 /* push PDU */
1079 if (atm_charge(vcc, skb->truesize) == 0) {
1080
1081 DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n",
1082 vcc->itf, vcc->vpi, vcc->vci);
1083
1084 dev_kfree_skb_any(skb);
1085
1086 atomic_inc(&vcc->stats->rx_drop);
1087 return -ENOMEM;
1088 }
1089
Linus Torvalds1da177e2005-04-16 15:20:36 -07001090 vcc->push(vcc, skb);
1091 atomic_inc(&vcc->stats->rx);
1092
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093 return 0;
1094}
1095
1096
1097static void
1098fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd)
1099{
1100 struct host_bsq* bsq;
1101 struct buffer* buffer;
1102 int i;
1103
1104 for (i = 0; i < rpd->nseg; i++) {
1105
1106 /* rebuild rx buffer address from rsd handle */
1107 buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
1108
1109 bsq = &fore200e->host_bsq[ buffer->scheme ][ buffer->magn ];
1110
1111#ifdef FORE200E_BSQ_DEBUG
1112 bsq_audit(2, bsq, buffer->scheme, buffer->magn);
1113
1114 if (buffer->supplied == 0)
1115 printk(FORE200E "queue %d.%d, buffer %ld was not supplied\n",
1116 buffer->scheme, buffer->magn, buffer->index);
1117 buffer->supplied = 0;
1118#endif
1119
1120 /* re-insert the buffer into the free buffer list */
1121 buffer->next = bsq->freebuf;
1122 bsq->freebuf = buffer;
1123
1124 /* then increment the number of free rx buffers */
1125 bsq->freebuf_count++;
1126 }
1127}
1128
1129
1130static void
1131fore200e_rx_irq(struct fore200e* fore200e)
1132{
1133 struct host_rxq* rxq = &fore200e->host_rxq;
1134 struct host_rxq_entry* entry;
1135 struct atm_vcc* vcc;
1136 struct fore200e_vc_map* vc_map;
1137
1138 for (;;) {
1139
1140 entry = &rxq->host_entry[ rxq->head ];
1141
1142 /* no more received PDUs */
1143 if ((*entry->status & STATUS_COMPLETE) == 0)
1144 break;
1145
1146 vc_map = FORE200E_VC_MAP(fore200e, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
1147
1148 if ((vc_map->vcc == NULL) ||
1149 (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
1150
1151 DPRINTK(1, "no ready VC found for PDU received on %d.%d.%d\n",
1152 fore200e->atm_dev->number,
1153 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
1154 }
1155 else {
1156 vcc = vc_map->vcc;
1157 ASSERT(vcc);
1158
1159 if ((*entry->status & STATUS_ERROR) == 0) {
1160
1161 fore200e_push_rpd(fore200e, vcc, entry->rpd);
1162 }
1163 else {
1164 DPRINTK(2, "damaged PDU on %d.%d.%d\n",
1165 fore200e->atm_dev->number,
1166 entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
1167 atomic_inc(&vcc->stats->rx_err);
1168 }
1169 }
1170
1171 FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
1172
1173 fore200e_collect_rpd(fore200e, entry->rpd);
1174
1175 /* rewrite the rpd address to ack the received PDU */
1176 fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr);
1177 *entry->status = STATUS_FREE;
1178
1179 fore200e_supply(fore200e);
1180 }
1181}
1182
1183
1184#ifndef FORE200E_USE_TASKLET
1185static void
1186fore200e_irq(struct fore200e* fore200e)
1187{
1188 unsigned long flags;
1189
1190 spin_lock_irqsave(&fore200e->q_lock, flags);
1191 fore200e_rx_irq(fore200e);
1192 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1193
1194 spin_lock_irqsave(&fore200e->q_lock, flags);
1195 fore200e_tx_irq(fore200e);
1196 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1197}
1198#endif
1199
1200
1201static irqreturn_t
David Howells7d12e782006-10-05 14:55:46 +01001202fore200e_interrupt(int irq, void* dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203{
1204 struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
1205
1206 if (fore200e->bus->irq_check(fore200e) == 0) {
1207
1208 DPRINTK(3, "interrupt NOT triggered by device %d\n", fore200e->atm_dev->number);
1209 return IRQ_NONE;
1210 }
1211 DPRINTK(3, "interrupt triggered by device %d\n", fore200e->atm_dev->number);
1212
1213#ifdef FORE200E_USE_TASKLET
1214 tasklet_schedule(&fore200e->tx_tasklet);
1215 tasklet_schedule(&fore200e->rx_tasklet);
1216#else
1217 fore200e_irq(fore200e);
1218#endif
1219
1220 fore200e->bus->irq_ack(fore200e);
1221 return IRQ_HANDLED;
1222}
1223
1224
1225#ifdef FORE200E_USE_TASKLET
1226static void
1227fore200e_tx_tasklet(unsigned long data)
1228{
1229 struct fore200e* fore200e = (struct fore200e*) data;
1230 unsigned long flags;
1231
1232 DPRINTK(3, "tx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
1233
1234 spin_lock_irqsave(&fore200e->q_lock, flags);
1235 fore200e_tx_irq(fore200e);
1236 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1237}
1238
1239
1240static void
1241fore200e_rx_tasklet(unsigned long data)
1242{
1243 struct fore200e* fore200e = (struct fore200e*) data;
1244 unsigned long flags;
1245
1246 DPRINTK(3, "rx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
1247
1248 spin_lock_irqsave(&fore200e->q_lock, flags);
1249 fore200e_rx_irq((struct fore200e*) data);
1250 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1251}
1252#endif
1253
1254
1255static int
1256fore200e_select_scheme(struct atm_vcc* vcc)
1257{
1258 /* fairly balance the VCs over (identical) buffer schemes */
1259 int scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
1260
1261 DPRINTK(1, "VC %d.%d.%d uses buffer scheme %d\n",
1262 vcc->itf, vcc->vpi, vcc->vci, scheme);
1263
1264 return scheme;
1265}
1266
1267
1268static int
1269fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu)
1270{
1271 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1272 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1273 struct activate_opcode activ_opcode;
1274 struct deactivate_opcode deactiv_opcode;
1275 struct vpvc vpvc;
1276 int ok;
1277 enum fore200e_aal aal = fore200e_atm2fore_aal(vcc->qos.aal);
1278
1279 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1280
1281 if (activate) {
1282 FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc);
1283
1284 activ_opcode.opcode = OPCODE_ACTIVATE_VCIN;
1285 activ_opcode.aal = aal;
1286 activ_opcode.scheme = FORE200E_VCC(vcc)->scheme;
1287 activ_opcode.pad = 0;
1288 }
1289 else {
1290 deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN;
1291 deactiv_opcode.pad = 0;
1292 }
1293
1294 vpvc.vci = vcc->vci;
1295 vpvc.vpi = vcc->vpi;
1296
1297 *entry->status = STATUS_PENDING;
1298
1299 if (activate) {
1300
1301#ifdef FORE200E_52BYTE_AAL0_SDU
1302 mtu = 48;
1303#endif
1304 /* the MTU is not used by the cp, except in the case of AAL0 */
1305 fore200e->bus->write(mtu, &entry->cp_entry->cmd.activate_block.mtu);
1306 fore200e->bus->write(*(u32*)&vpvc, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.vpvc);
1307 fore200e->bus->write(*(u32*)&activ_opcode, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.opcode);
1308 }
1309 else {
1310 fore200e->bus->write(*(u32*)&vpvc, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.vpvc);
1311 fore200e->bus->write(*(u32*)&deactiv_opcode, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.opcode);
1312 }
1313
1314 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1315
1316 *entry->status = STATUS_FREE;
1317
1318 if (ok == 0) {
1319 printk(FORE200E "unable to %s VC %d.%d.%d\n",
1320 activate ? "open" : "close", vcc->itf, vcc->vpi, vcc->vci);
1321 return -EIO;
1322 }
1323
1324 DPRINTK(1, "VC %d.%d.%d %sed\n", vcc->itf, vcc->vpi, vcc->vci,
1325 activate ? "open" : "clos");
1326
1327 return 0;
1328}
1329
1330
1331#define FORE200E_MAX_BACK2BACK_CELLS 255 /* XXX depends on CDVT */
1332
1333static void
1334fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
1335{
1336 if (qos->txtp.max_pcr < ATM_OC3_PCR) {
1337
1338 /* compute the data cells to idle cells ratio from the tx PCR */
1339 rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR;
1340 rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells;
1341 }
1342 else {
1343 /* disable rate control */
1344 rate->data_cells = rate->idle_cells = 0;
1345 }
1346}
1347
1348
1349static int
1350fore200e_open(struct atm_vcc *vcc)
1351{
1352 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1353 struct fore200e_vcc* fore200e_vcc;
1354 struct fore200e_vc_map* vc_map;
1355 unsigned long flags;
1356 int vci = vcc->vci;
1357 short vpi = vcc->vpi;
1358
1359 ASSERT((vpi >= 0) && (vpi < 1<<FORE200E_VPI_BITS));
1360 ASSERT((vci >= 0) && (vci < 1<<FORE200E_VCI_BITS));
1361
1362 spin_lock_irqsave(&fore200e->q_lock, flags);
1363
1364 vc_map = FORE200E_VC_MAP(fore200e, vpi, vci);
1365 if (vc_map->vcc) {
1366
1367 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1368
1369 printk(FORE200E "VC %d.%d.%d already in use\n",
1370 fore200e->atm_dev->number, vpi, vci);
1371
1372 return -EINVAL;
1373 }
1374
1375 vc_map->vcc = vcc;
1376
1377 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1378
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001379 fore200e_vcc = kzalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 if (fore200e_vcc == NULL) {
1381 vc_map->vcc = NULL;
1382 return -ENOMEM;
1383 }
1384
1385 DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
1386 "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
1387 vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
1388 fore200e_traffic_class[ vcc->qos.txtp.traffic_class ],
1389 vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu,
1390 fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ],
1391 vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu);
1392
1393 /* pseudo-CBR bandwidth requested? */
1394 if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
1395
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001396 mutex_lock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001398 mutex_unlock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001400 kfree(fore200e_vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 vc_map->vcc = NULL;
1402 return -EAGAIN;
1403 }
1404
1405 /* reserve bandwidth */
1406 fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001407 mutex_unlock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 }
1409
1410 vcc->itf = vcc->dev->number;
1411
1412 set_bit(ATM_VF_PARTIAL,&vcc->flags);
1413 set_bit(ATM_VF_ADDR, &vcc->flags);
1414
1415 vcc->dev_data = fore200e_vcc;
1416
1417 if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) {
1418
1419 vc_map->vcc = NULL;
1420
1421 clear_bit(ATM_VF_ADDR, &vcc->flags);
1422 clear_bit(ATM_VF_PARTIAL,&vcc->flags);
1423
1424 vcc->dev_data = NULL;
1425
1426 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
1427
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001428 kfree(fore200e_vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 return -EINVAL;
1430 }
1431
1432 /* compute rate control parameters */
1433 if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
1434
1435 fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate);
1436 set_bit(ATM_VF_HASQOS, &vcc->flags);
1437
1438 DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n",
1439 vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
1440 vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr,
1441 fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells);
1442 }
1443
1444 fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = MAX_PDU_SIZE + 1;
1445 fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
1446 fore200e_vcc->tx_pdu = fore200e_vcc->rx_pdu = 0;
1447
1448 /* new incarnation of the vcc */
1449 vc_map->incarn = ++fore200e->incarn_count;
1450
1451 /* VC unusable before this flag is set */
1452 set_bit(ATM_VF_READY, &vcc->flags);
1453
1454 return 0;
1455}
1456
1457
1458static void
1459fore200e_close(struct atm_vcc* vcc)
1460{
1461 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1462 struct fore200e_vcc* fore200e_vcc;
1463 struct fore200e_vc_map* vc_map;
1464 unsigned long flags;
1465
1466 ASSERT(vcc);
1467 ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<<FORE200E_VPI_BITS));
1468 ASSERT((vcc->vci >= 0) && (vcc->vci < 1<<FORE200E_VCI_BITS));
1469
1470 DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
1471
1472 clear_bit(ATM_VF_READY, &vcc->flags);
1473
1474 fore200e_activate_vcin(fore200e, 0, vcc, 0);
1475
1476 spin_lock_irqsave(&fore200e->q_lock, flags);
1477
1478 vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
1479
1480 /* the vc is no longer considered as "in use" by fore200e_open() */
1481 vc_map->vcc = NULL;
1482
1483 vcc->itf = vcc->vci = vcc->vpi = 0;
1484
1485 fore200e_vcc = FORE200E_VCC(vcc);
1486 vcc->dev_data = NULL;
1487
1488 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1489
1490 /* release reserved bandwidth, if any */
1491 if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
1492
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001493 mutex_lock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001495 mutex_unlock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496
1497 clear_bit(ATM_VF_HASQOS, &vcc->flags);
1498 }
1499
1500 clear_bit(ATM_VF_ADDR, &vcc->flags);
1501 clear_bit(ATM_VF_PARTIAL,&vcc->flags);
1502
1503 ASSERT(fore200e_vcc);
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001504 kfree(fore200e_vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505}
1506
1507
1508static int
1509fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
1510{
1511 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1512 struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
1513 struct fore200e_vc_map* vc_map;
1514 struct host_txq* txq = &fore200e->host_txq;
1515 struct host_txq_entry* entry;
1516 struct tpd* tpd;
1517 struct tpd_haddr tpd_haddr;
1518 int retry = CONFIG_ATM_FORE200E_TX_RETRY;
1519 int tx_copy = 0;
1520 int tx_len = skb->len;
1521 u32* cell_header = NULL;
1522 unsigned char* skb_data;
1523 int skb_len;
1524 unsigned char* data;
1525 unsigned long flags;
1526
1527 ASSERT(vcc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 ASSERT(fore200e);
1529 ASSERT(fore200e_vcc);
1530
1531 if (!test_bit(ATM_VF_READY, &vcc->flags)) {
1532 DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
1533 dev_kfree_skb_any(skb);
1534 return -EINVAL;
1535 }
1536
1537#ifdef FORE200E_52BYTE_AAL0_SDU
1538 if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
1539 cell_header = (u32*) skb->data;
1540 skb_data = skb->data + 4; /* skip 4-byte cell header */
1541 skb_len = tx_len = skb->len - 4;
1542
1543 DPRINTK(3, "user-supplied cell header = 0x%08x\n", *cell_header);
1544 }
1545 else
1546#endif
1547 {
1548 skb_data = skb->data;
1549 skb_len = skb->len;
1550 }
1551
1552 if (((unsigned long)skb_data) & 0x3) {
1553
1554 DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name);
1555 tx_copy = 1;
1556 tx_len = skb_len;
1557 }
1558
1559 if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) {
1560
1561 /* this simply NUKES the PCA board */
1562 DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name);
1563 tx_copy = 1;
1564 tx_len = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD;
1565 }
1566
1567 if (tx_copy) {
1568 data = kmalloc(tx_len, GFP_ATOMIC | GFP_DMA);
1569 if (data == NULL) {
1570 if (vcc->pop) {
1571 vcc->pop(vcc, skb);
1572 }
1573 else {
1574 dev_kfree_skb_any(skb);
1575 }
1576 return -ENOMEM;
1577 }
1578
1579 memcpy(data, skb_data, skb_len);
1580 if (skb_len < tx_len)
1581 memset(data + skb_len, 0x00, tx_len - skb_len);
1582 }
1583 else {
1584 data = skb_data;
1585 }
1586
1587 vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
1588 ASSERT(vc_map->vcc == vcc);
1589
1590 retry_here:
1591
1592 spin_lock_irqsave(&fore200e->q_lock, flags);
1593
1594 entry = &txq->host_entry[ txq->head ];
1595
1596 if ((*entry->status != STATUS_FREE) || (txq->txing >= QUEUE_SIZE_TX - 2)) {
1597
1598 /* try to free completed tx queue entries */
1599 fore200e_tx_irq(fore200e);
1600
1601 if (*entry->status != STATUS_FREE) {
1602
1603 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1604
1605 /* retry once again? */
1606 if (--retry > 0) {
1607 udelay(50);
1608 goto retry_here;
1609 }
1610
1611 atomic_inc(&vcc->stats->tx_err);
1612
1613 fore200e->tx_sat++;
1614 DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
1615 fore200e->name, fore200e->cp_queues->heartbeat);
1616 if (vcc->pop) {
1617 vcc->pop(vcc, skb);
1618 }
1619 else {
1620 dev_kfree_skb_any(skb);
1621 }
1622
1623 if (tx_copy)
1624 kfree(data);
1625
1626 return -ENOBUFS;
1627 }
1628 }
1629
1630 entry->incarn = vc_map->incarn;
1631 entry->vc_map = vc_map;
1632 entry->skb = skb;
1633 entry->data = tx_copy ? data : NULL;
1634
1635 tpd = entry->tpd;
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +02001636 tpd->tsd[ 0 ].buffer = dma_map_single(fore200e->dev, data, tx_len,
1637 DMA_TO_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 tpd->tsd[ 0 ].length = tx_len;
1639
1640 FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
1641 txq->txing++;
1642
1643 /* The dma_map call above implies a dma_sync so the device can use it,
1644 * thus no explicit dma_sync call is necessary here.
1645 */
1646
1647 DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n",
1648 vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
1649 tpd->tsd[0].length, skb_len);
1650
1651 if (skb_len < fore200e_vcc->tx_min_pdu)
1652 fore200e_vcc->tx_min_pdu = skb_len;
1653 if (skb_len > fore200e_vcc->tx_max_pdu)
1654 fore200e_vcc->tx_max_pdu = skb_len;
1655 fore200e_vcc->tx_pdu++;
1656
1657 /* set tx rate control information */
1658 tpd->rate.data_cells = fore200e_vcc->rate.data_cells;
1659 tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells;
1660
1661 if (cell_header) {
1662 tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP);
1663 tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
1664 tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
1665 tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
1666 tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT;
1667 }
1668 else {
1669 /* set the ATM header, common to all cells conveying the PDU */
1670 tpd->atm_header.clp = 0;
1671 tpd->atm_header.plt = 0;
1672 tpd->atm_header.vci = vcc->vci;
1673 tpd->atm_header.vpi = vcc->vpi;
1674 tpd->atm_header.gfc = 0;
1675 }
1676
1677 tpd->spec.length = tx_len;
1678 tpd->spec.nseg = 1;
1679 tpd->spec.aal = fore200e_atm2fore_aal(vcc->qos.aal);
1680 tpd->spec.intr = 1;
1681
1682 tpd_haddr.size = sizeof(struct tpd) / (1<<TPD_HADDR_SHIFT); /* size is expressed in 32 byte blocks */
1683 tpd_haddr.pad = 0;
1684 tpd_haddr.haddr = entry->tpd_dma >> TPD_HADDR_SHIFT; /* shift the address, as we are in a bitfield */
1685
1686 *entry->status = STATUS_PENDING;
1687 fore200e->bus->write(*(u32*)&tpd_haddr, (u32 __iomem *)&entry->cp_entry->tpd_haddr);
1688
1689 spin_unlock_irqrestore(&fore200e->q_lock, flags);
1690
1691 return 0;
1692}
1693
1694
1695static int
1696fore200e_getstats(struct fore200e* fore200e)
1697{
1698 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1699 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1700 struct stats_opcode opcode;
1701 int ok;
1702 u32 stats_dma_addr;
1703
1704 if (fore200e->stats == NULL) {
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08001705 fore200e->stats = kzalloc(sizeof(struct stats), GFP_KERNEL | GFP_DMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 if (fore200e->stats == NULL)
1707 return -ENOMEM;
1708 }
1709
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +02001710 stats_dma_addr = dma_map_single(fore200e->dev, fore200e->stats,
1711 sizeof(struct stats), DMA_FROM_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
1713 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1714
1715 opcode.opcode = OPCODE_GET_STATS;
1716 opcode.pad = 0;
1717
1718 fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr);
1719
1720 *entry->status = STATUS_PENDING;
1721
1722 fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.stats_block.opcode);
1723
1724 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1725
1726 *entry->status = STATUS_FREE;
1727
Christoph Hellwigf3fadcb2018-10-09 16:57:17 +02001728 dma_unmap_single(fore200e->dev, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
1730 if (ok == 0) {
1731 printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
1732 return -EIO;
1733 }
1734
1735 return 0;
1736}
1737
1738
1739static int
1740fore200e_getsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, int optlen)
1741{
1742 /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
1743
1744 DPRINTK(2, "getsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
1745 vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
1746
1747 return -EINVAL;
1748}
1749
1750
1751static int
David S. Millerb7058842009-09-30 16:12:20 -07001752fore200e_setsockopt(struct atm_vcc* vcc, int level, int optname, void __user *optval, unsigned int optlen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753{
1754 /* struct fore200e* fore200e = FORE200E_DEV(vcc->dev); */
1755
1756 DPRINTK(2, "setsockopt %d.%d.%d, level = %d, optname = 0x%x, optval = 0x%p, optlen = %d\n",
1757 vcc->itf, vcc->vpi, vcc->vci, level, optname, optval, optlen);
1758
1759 return -EINVAL;
1760}
1761
1762
1763#if 0 /* currently unused */
1764static int
1765fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
1766{
1767 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1768 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1769 struct oc3_opcode opcode;
1770 int ok;
1771 u32 oc3_regs_dma_addr;
1772
1773 oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
1774
1775 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1776
1777 opcode.opcode = OPCODE_GET_OC3;
1778 opcode.reg = 0;
1779 opcode.value = 0;
1780 opcode.mask = 0;
1781
1782 fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr);
1783
1784 *entry->status = STATUS_PENDING;
1785
1786 fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
1787
1788 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1789
1790 *entry->status = STATUS_FREE;
1791
1792 fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
1793
1794 if (ok == 0) {
1795 printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
1796 return -EIO;
1797 }
1798
1799 return 0;
1800}
1801#endif
1802
1803
1804static int
1805fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask)
1806{
1807 struct host_cmdq* cmdq = &fore200e->host_cmdq;
1808 struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
1809 struct oc3_opcode opcode;
1810 int ok;
1811
1812 DPRINTK(2, "set OC-3 reg = 0x%02x, value = 0x%02x, mask = 0x%02x\n", reg, value, mask);
1813
1814 FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
1815
1816 opcode.opcode = OPCODE_SET_OC3;
1817 opcode.reg = reg;
1818 opcode.value = value;
1819 opcode.mask = mask;
1820
1821 fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr);
1822
1823 *entry->status = STATUS_PENDING;
1824
1825 fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.oc3_block.opcode);
1826
1827 ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
1828
1829 *entry->status = STATUS_FREE;
1830
1831 if (ok == 0) {
1832 printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name);
1833 return -EIO;
1834 }
1835
1836 return 0;
1837}
1838
1839
1840static int
1841fore200e_setloop(struct fore200e* fore200e, int loop_mode)
1842{
1843 u32 mct_value, mct_mask;
1844 int error;
1845
1846 if (!capable(CAP_NET_ADMIN))
1847 return -EPERM;
1848
1849 switch (loop_mode) {
1850
1851 case ATM_LM_NONE:
1852 mct_value = 0;
1853 mct_mask = SUNI_MCT_DLE | SUNI_MCT_LLE;
1854 break;
1855
1856 case ATM_LM_LOC_PHY:
1857 mct_value = mct_mask = SUNI_MCT_DLE;
1858 break;
1859
1860 case ATM_LM_RMT_PHY:
1861 mct_value = mct_mask = SUNI_MCT_LLE;
1862 break;
1863
1864 default:
1865 return -EINVAL;
1866 }
1867
1868 error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask);
1869 if (error == 0)
1870 fore200e->loop_mode = loop_mode;
1871
1872 return error;
1873}
1874
1875
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876static int
1877fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
1878{
1879 struct sonet_stats tmp;
1880
1881 if (fore200e_getstats(fore200e) < 0)
1882 return -EIO;
1883
Al Viro63734a32008-03-16 22:23:04 +00001884 tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors);
1885 tmp.line_bip = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors);
1886 tmp.path_bip = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors);
1887 tmp.line_febe = be32_to_cpu(fore200e->stats->oc3.line_febe_errors);
1888 tmp.path_febe = be32_to_cpu(fore200e->stats->oc3.path_febe_errors);
1889 tmp.corr_hcs = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors);
1890 tmp.uncorr_hcs = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors);
1891 tmp.tx_cells = be32_to_cpu(fore200e->stats->aal0.cells_transmitted) +
1892 be32_to_cpu(fore200e->stats->aal34.cells_transmitted) +
1893 be32_to_cpu(fore200e->stats->aal5.cells_transmitted);
1894 tmp.rx_cells = be32_to_cpu(fore200e->stats->aal0.cells_received) +
1895 be32_to_cpu(fore200e->stats->aal34.cells_received) +
1896 be32_to_cpu(fore200e->stats->aal5.cells_received);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897
1898 if (arg)
1899 return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;
1900
1901 return 0;
1902}
1903
1904
1905static int
1906fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
1907{
1908 struct fore200e* fore200e = FORE200E_DEV(dev);
1909
1910 DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg);
1911
1912 switch (cmd) {
1913
1914 case SONET_GETSTAT:
1915 return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
1916
1917 case SONET_GETDIAG:
1918 return put_user(0, (int __user *)arg) ? -EFAULT : 0;
1919
1920 case ATM_SETLOOP:
1921 return fore200e_setloop(fore200e, (int)(unsigned long)arg);
1922
1923 case ATM_GETLOOP:
1924 return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
1925
1926 case ATM_QUERYLOOP:
1927 return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
1928 }
1929
1930 return -ENOSYS; /* not implemented */
1931}
1932
1933
1934static int
1935fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
1936{
1937 struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
1938 struct fore200e* fore200e = FORE200E_DEV(vcc->dev);
1939
1940 if (!test_bit(ATM_VF_READY, &vcc->flags)) {
1941 DPRINTK(1, "VC %d.%d.%d not ready for QoS change\n", vcc->itf, vcc->vpi, vcc->vpi);
1942 return -EINVAL;
1943 }
1944
1945 DPRINTK(2, "change_qos %d.%d.%d, "
1946 "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
1947 "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
1948 "available_cell_rate = %u",
1949 vcc->itf, vcc->vpi, vcc->vci,
1950 fore200e_traffic_class[ qos->txtp.traffic_class ],
1951 qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu,
1952 fore200e_traffic_class[ qos->rxtp.traffic_class ],
1953 qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu,
1954 flags, fore200e->available_cell_rate);
1955
1956 if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
1957
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001958 mutex_lock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001960 mutex_unlock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961 return -EAGAIN;
1962 }
1963
1964 fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
1965 fore200e->available_cell_rate -= qos->txtp.max_pcr;
1966
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07001967 mutex_unlock(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001968
1969 memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
1970
1971 /* update rate control parameters */
1972 fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
1973
1974 set_bit(ATM_VF_HASQOS, &vcc->flags);
1975
1976 return 0;
1977 }
1978
1979 return -EINVAL;
1980}
1981
1982
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08001983static int fore200e_irq_request(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984{
Thomas Gleixnerdace1452006-07-01 19:29:38 -07001985 if (request_irq(fore200e->irq, fore200e_interrupt, IRQF_SHARED, fore200e->name, fore200e->atm_dev) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001986
1987 printk(FORE200E "unable to reserve IRQ %s for device %s\n",
1988 fore200e_irq_itoa(fore200e->irq), fore200e->name);
1989 return -EBUSY;
1990 }
1991
1992 printk(FORE200E "IRQ %s reserved for device %s\n",
1993 fore200e_irq_itoa(fore200e->irq), fore200e->name);
1994
1995#ifdef FORE200E_USE_TASKLET
1996 tasklet_init(&fore200e->tx_tasklet, fore200e_tx_tasklet, (unsigned long)fore200e);
1997 tasklet_init(&fore200e->rx_tasklet, fore200e_rx_tasklet, (unsigned long)fore200e);
1998#endif
1999
2000 fore200e->state = FORE200E_STATE_IRQ;
2001 return 0;
2002}
2003
2004
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002005static int fore200e_get_esi(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006{
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002007 struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL | GFP_DMA);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008 int ok, i;
2009
2010 if (!prom)
2011 return -ENOMEM;
2012
2013 ok = fore200e->bus->prom_read(fore200e, prom);
2014 if (ok < 0) {
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002015 kfree(prom);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 return -EBUSY;
2017 }
2018
hartleys3008ab32010-01-05 06:22:20 +00002019 printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 fore200e->name,
2021 (prom->hw_revision & 0xFF) + '@', /* probably meaningless with SBA boards */
hartleys3008ab32010-01-05 06:22:20 +00002022 prom->serial_number & 0xFFFF, &prom->mac_addr[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002023
2024 for (i = 0; i < ESI_LEN; i++) {
2025 fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
2026 }
2027
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002028 kfree(prom);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029
2030 return 0;
2031}
2032
2033
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002034static int fore200e_alloc_rx_buf(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035{
2036 int scheme, magn, nbr, size, i;
2037
2038 struct host_bsq* bsq;
2039 struct buffer* buffer;
2040
2041 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
2042 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
2043
2044 bsq = &fore200e->host_bsq[ scheme ][ magn ];
2045
2046 nbr = fore200e_rx_buf_nbr[ scheme ][ magn ];
2047 size = fore200e_rx_buf_size[ scheme ][ magn ];
2048
2049 DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
2050
2051 /* allocate the array of receive buffers */
Kees Cook6396bb22018-06-12 14:03:40 -07002052 buffer = bsq->buffer = kcalloc(nbr, sizeof(struct buffer),
2053 GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054
2055 if (buffer == NULL)
2056 return -ENOMEM;
2057
2058 bsq->freebuf = NULL;
2059
2060 for (i = 0; i < nbr; i++) {
2061
2062 buffer[ i ].scheme = scheme;
2063 buffer[ i ].magn = magn;
2064#ifdef FORE200E_BSQ_DEBUG
2065 buffer[ i ].index = i;
2066 buffer[ i ].supplied = 0;
2067#endif
2068
2069 /* allocate the receive buffer body */
2070 if (fore200e_chunk_alloc(fore200e,
2071 &buffer[ i ].data, size, fore200e->bus->buffer_alignment,
2072 DMA_FROM_DEVICE) < 0) {
2073
2074 while (i > 0)
2075 fore200e_chunk_free(fore200e, &buffer[ --i ].data);
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002076 kfree(buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077
2078 return -ENOMEM;
2079 }
2080
2081 /* insert the buffer into the free buffer list */
2082 buffer[ i ].next = bsq->freebuf;
2083 bsq->freebuf = &buffer[ i ];
2084 }
2085 /* all the buffers are free, initially */
2086 bsq->freebuf_count = nbr;
2087
2088#ifdef FORE200E_BSQ_DEBUG
2089 bsq_audit(3, bsq, scheme, magn);
2090#endif
2091 }
2092 }
2093
2094 fore200e->state = FORE200E_STATE_ALLOC_BUF;
2095 return 0;
2096}
2097
2098
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002099static int fore200e_init_bs_queue(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002100{
2101 int scheme, magn, i;
2102
2103 struct host_bsq* bsq;
2104 struct cp_bsq_entry __iomem * cp_entry;
2105
2106 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
2107 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
2108
2109 DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn);
2110
2111 bsq = &fore200e->host_bsq[ scheme ][ magn ];
2112
2113 /* allocate and align the array of status words */
2114 if (fore200e->bus->dma_chunk_alloc(fore200e,
2115 &bsq->status,
2116 sizeof(enum status),
2117 QUEUE_SIZE_BS,
2118 fore200e->bus->status_alignment) < 0) {
2119 return -ENOMEM;
2120 }
2121
2122 /* allocate and align the array of receive buffer descriptors */
2123 if (fore200e->bus->dma_chunk_alloc(fore200e,
2124 &bsq->rbd_block,
2125 sizeof(struct rbd_block),
2126 QUEUE_SIZE_BS,
2127 fore200e->bus->descr_alignment) < 0) {
2128
2129 fore200e->bus->dma_chunk_free(fore200e, &bsq->status);
2130 return -ENOMEM;
2131 }
2132
2133 /* get the base address of the cp resident buffer supply queue entries */
2134 cp_entry = fore200e->virt_base +
2135 fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]);
2136
2137 /* fill the host resident and cp resident buffer supply queue entries */
2138 for (i = 0; i < QUEUE_SIZE_BS; i++) {
2139
2140 bsq->host_entry[ i ].status =
2141 FORE200E_INDEX(bsq->status.align_addr, enum status, i);
2142 bsq->host_entry[ i ].rbd_block =
2143 FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
2144 bsq->host_entry[ i ].rbd_block_dma =
2145 FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
2146 bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2147
2148 *bsq->host_entry[ i ].status = STATUS_FREE;
2149
2150 fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i),
2151 &cp_entry[ i ].status_haddr);
2152 }
2153 }
2154 }
2155
2156 fore200e->state = FORE200E_STATE_INIT_BSQ;
2157 return 0;
2158}
2159
2160
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002161static int fore200e_init_rx_queue(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162{
2163 struct host_rxq* rxq = &fore200e->host_rxq;
2164 struct cp_rxq_entry __iomem * cp_entry;
2165 int i;
2166
2167 DPRINTK(2, "receive queue is being initialized\n");
2168
2169 /* allocate and align the array of status words */
2170 if (fore200e->bus->dma_chunk_alloc(fore200e,
2171 &rxq->status,
2172 sizeof(enum status),
2173 QUEUE_SIZE_RX,
2174 fore200e->bus->status_alignment) < 0) {
2175 return -ENOMEM;
2176 }
2177
2178 /* allocate and align the array of receive PDU descriptors */
2179 if (fore200e->bus->dma_chunk_alloc(fore200e,
2180 &rxq->rpd,
2181 sizeof(struct rpd),
2182 QUEUE_SIZE_RX,
2183 fore200e->bus->descr_alignment) < 0) {
2184
2185 fore200e->bus->dma_chunk_free(fore200e, &rxq->status);
2186 return -ENOMEM;
2187 }
2188
2189 /* get the base address of the cp resident rx queue entries */
2190 cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_rxq);
2191
2192 /* fill the host resident and cp resident rx entries */
2193 for (i=0; i < QUEUE_SIZE_RX; i++) {
2194
2195 rxq->host_entry[ i ].status =
2196 FORE200E_INDEX(rxq->status.align_addr, enum status, i);
2197 rxq->host_entry[ i ].rpd =
2198 FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i);
2199 rxq->host_entry[ i ].rpd_dma =
2200 FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i);
2201 rxq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2202
2203 *rxq->host_entry[ i ].status = STATUS_FREE;
2204
2205 fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i),
2206 &cp_entry[ i ].status_haddr);
2207
2208 fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i),
2209 &cp_entry[ i ].rpd_haddr);
2210 }
2211
2212 /* set the head entry of the queue */
2213 rxq->head = 0;
2214
2215 fore200e->state = FORE200E_STATE_INIT_RXQ;
2216 return 0;
2217}
2218
2219
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002220static int fore200e_init_tx_queue(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221{
2222 struct host_txq* txq = &fore200e->host_txq;
2223 struct cp_txq_entry __iomem * cp_entry;
2224 int i;
2225
2226 DPRINTK(2, "transmit queue is being initialized\n");
2227
2228 /* allocate and align the array of status words */
2229 if (fore200e->bus->dma_chunk_alloc(fore200e,
2230 &txq->status,
2231 sizeof(enum status),
2232 QUEUE_SIZE_TX,
2233 fore200e->bus->status_alignment) < 0) {
2234 return -ENOMEM;
2235 }
2236
2237 /* allocate and align the array of transmit PDU descriptors */
2238 if (fore200e->bus->dma_chunk_alloc(fore200e,
2239 &txq->tpd,
2240 sizeof(struct tpd),
2241 QUEUE_SIZE_TX,
2242 fore200e->bus->descr_alignment) < 0) {
2243
2244 fore200e->bus->dma_chunk_free(fore200e, &txq->status);
2245 return -ENOMEM;
2246 }
2247
2248 /* get the base address of the cp resident tx queue entries */
2249 cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_txq);
2250
2251 /* fill the host resident and cp resident tx entries */
2252 for (i=0; i < QUEUE_SIZE_TX; i++) {
2253
2254 txq->host_entry[ i ].status =
2255 FORE200E_INDEX(txq->status.align_addr, enum status, i);
2256 txq->host_entry[ i ].tpd =
2257 FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i);
2258 txq->host_entry[ i ].tpd_dma =
2259 FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i);
2260 txq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2261
2262 *txq->host_entry[ i ].status = STATUS_FREE;
2263
2264 fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i),
2265 &cp_entry[ i ].status_haddr);
2266
2267 /* although there is a one-to-one mapping of tx queue entries and tpds,
2268 we do not write here the DMA (physical) base address of each tpd into
2269 the related cp resident entry, because the cp relies on this write
2270 operation to detect that a new pdu has been submitted for tx */
2271 }
2272
2273 /* set the head and tail entries of the queue */
2274 txq->head = 0;
2275 txq->tail = 0;
2276
2277 fore200e->state = FORE200E_STATE_INIT_TXQ;
2278 return 0;
2279}
2280
2281
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002282static int fore200e_init_cmd_queue(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283{
2284 struct host_cmdq* cmdq = &fore200e->host_cmdq;
2285 struct cp_cmdq_entry __iomem * cp_entry;
2286 int i;
2287
2288 DPRINTK(2, "command queue is being initialized\n");
2289
2290 /* allocate and align the array of status words */
2291 if (fore200e->bus->dma_chunk_alloc(fore200e,
2292 &cmdq->status,
2293 sizeof(enum status),
2294 QUEUE_SIZE_CMD,
2295 fore200e->bus->status_alignment) < 0) {
2296 return -ENOMEM;
2297 }
2298
2299 /* get the base address of the cp resident cmd queue entries */
2300 cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_cmdq);
2301
2302 /* fill the host resident and cp resident cmd entries */
2303 for (i=0; i < QUEUE_SIZE_CMD; i++) {
2304
2305 cmdq->host_entry[ i ].status =
2306 FORE200E_INDEX(cmdq->status.align_addr, enum status, i);
2307 cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ];
2308
2309 *cmdq->host_entry[ i ].status = STATUS_FREE;
2310
2311 fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i),
2312 &cp_entry[ i ].status_haddr);
2313 }
2314
2315 /* set the head entry of the queue */
2316 cmdq->head = 0;
2317
2318 fore200e->state = FORE200E_STATE_INIT_CMDQ;
2319 return 0;
2320}
2321
2322
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002323static void fore200e_param_bs_queue(struct fore200e *fore200e,
2324 enum buffer_scheme scheme,
2325 enum buffer_magn magn, int queue_length,
2326 int pool_size, int supply_blksize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327{
2328 struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ];
2329
2330 fore200e->bus->write(queue_length, &bs_spec->queue_length);
2331 fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size);
2332 fore200e->bus->write(pool_size, &bs_spec->pool_size);
2333 fore200e->bus->write(supply_blksize, &bs_spec->supply_blksize);
2334}
2335
2336
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002337static int fore200e_initialize(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338{
2339 struct cp_queues __iomem * cpq;
2340 int ok, scheme, magn;
2341
2342 DPRINTK(2, "device %s being initialized\n", fore200e->name);
2343
Matthias Kaehlckebfbf3c02007-04-26 01:41:49 -07002344 mutex_init(&fore200e->rate_mtx);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345 spin_lock_init(&fore200e->q_lock);
2346
2347 cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET;
2348
2349 /* enable cp to host interrupts */
2350 fore200e->bus->write(1, &cpq->imask);
2351
2352 if (fore200e->bus->irq_enable)
2353 fore200e->bus->irq_enable(fore200e);
2354
2355 fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect);
2356
2357 fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len);
2358 fore200e->bus->write(QUEUE_SIZE_RX, &cpq->init.rx_queue_len);
2359 fore200e->bus->write(QUEUE_SIZE_TX, &cpq->init.tx_queue_len);
2360
2361 fore200e->bus->write(RSD_EXTENSION, &cpq->init.rsd_extension);
2362 fore200e->bus->write(TSD_EXTENSION, &cpq->init.tsd_extension);
2363
2364 for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++)
2365 for (magn = 0; magn < BUFFER_MAGN_NBR; magn++)
2366 fore200e_param_bs_queue(fore200e, scheme, magn,
2367 QUEUE_SIZE_BS,
2368 fore200e_rx_buf_nbr[ scheme ][ magn ],
2369 RBD_BLK_SIZE);
2370
2371 /* issue the initialize command */
2372 fore200e->bus->write(STATUS_PENDING, &cpq->init.status);
2373 fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode);
2374
2375 ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000);
2376 if (ok == 0) {
2377 printk(FORE200E "device %s initialization failed\n", fore200e->name);
2378 return -ENODEV;
2379 }
2380
2381 printk(FORE200E "device %s initialized\n", fore200e->name);
2382
2383 fore200e->state = FORE200E_STATE_INITIALIZE;
2384 return 0;
2385}
2386
2387
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002388static void fore200e_monitor_putc(struct fore200e *fore200e, char c)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002389{
2390 struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
2391
2392#if 0
2393 printk("%c", c);
2394#endif
2395 fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send);
2396}
2397
2398
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002399static int fore200e_monitor_getc(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002400{
2401 struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
2402 unsigned long timeout = jiffies + msecs_to_jiffies(50);
2403 int c;
2404
2405 while (time_before(jiffies, timeout)) {
2406
2407 c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
2408
2409 if (c & FORE200E_CP_MONITOR_UART_AVAIL) {
2410
2411 fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv);
2412#if 0
2413 printk("%c", c & 0xFF);
2414#endif
2415 return c & 0xFF;
2416 }
2417 }
2418
2419 return -1;
2420}
2421
2422
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002423static void fore200e_monitor_puts(struct fore200e *fore200e, char *str)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424{
2425 while (*str) {
2426
2427 /* the i960 monitor doesn't accept any new character if it has something to say */
2428 while (fore200e_monitor_getc(fore200e) >= 0);
2429
2430 fore200e_monitor_putc(fore200e, *str++);
2431 }
2432
2433 while (fore200e_monitor_getc(fore200e) >= 0);
2434}
2435
Chas Williamse92481f2008-06-17 16:23:11 -07002436#ifdef __LITTLE_ENDIAN
2437#define FW_EXT ".bin"
2438#else
2439#define FW_EXT "_ecd.bin2"
2440#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002442static int fore200e_load_and_start_fw(struct fore200e *fore200e)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443{
Chas Williamse92481f2008-06-17 16:23:11 -07002444 const struct firmware *firmware;
LABBE Corentinb65b24d2016-08-17 15:56:45 +02002445 const struct fw_header *fw_header;
Chas Williams6f75a9b2008-07-23 20:29:21 -07002446 const __le32 *fw_data;
2447 u32 fw_size;
Chas Williamse92481f2008-06-17 16:23:11 -07002448 u32 __iomem *load_addr;
2449 char buf[48];
Christoph Hellwigaff9d262018-10-09 16:57:15 +02002450 int err;
Chas Williamse92481f2008-06-17 16:23:11 -07002451
2452 sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
Christoph Hellwigaff9d262018-10-09 16:57:15 +02002453 if ((err = request_firmware(&firmware, buf, fore200e->dev)) < 0) {
Meelis Roosfcffd0d2009-02-10 17:19:19 -08002454 printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
Chas Williamse92481f2008-06-17 16:23:11 -07002455 return err;
2456 }
2457
LABBE Corentinb65b24d2016-08-17 15:56:45 +02002458 fw_data = (const __le32 *)firmware->data;
Chas Williamse92481f2008-06-17 16:23:11 -07002459 fw_size = firmware->size / sizeof(u32);
LABBE Corentinb65b24d2016-08-17 15:56:45 +02002460 fw_header = (const struct fw_header *)firmware->data;
Chas Williamse92481f2008-06-17 16:23:11 -07002461 load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
2462
2463 DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
2464 fore200e->name, load_addr, fw_size);
2465
2466 if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
2467 printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
2468 goto release;
2469 }
2470
2471 for (; fw_size--; fw_data++, load_addr++)
2472 fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473
2474 DPRINTK(2, "device %s firmware being started\n", fore200e->name);
2475
2476#if defined(__sparc_v9__)
2477 /* reported to be required by SBA cards on some sparc64 hosts */
2478 fore200e_spin(100);
2479#endif
2480
Chas Williamse92481f2008-06-17 16:23:11 -07002481 sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
2482 fore200e_monitor_puts(fore200e, buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483
Chas Williamse92481f2008-06-17 16:23:11 -07002484 if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
Chas Williamse92481f2008-06-17 16:23:11 -07002486 goto release;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 }
2488
2489 printk(FORE200E "device %s firmware started\n", fore200e->name);
2490
2491 fore200e->state = FORE200E_STATE_START_FW;
Chas Williamse92481f2008-06-17 16:23:11 -07002492 err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493
Chas Williamse92481f2008-06-17 16:23:11 -07002494release:
2495 release_firmware(firmware);
2496 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002497}
2498
2499
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002500static int fore200e_register(struct fore200e *fore200e, struct device *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002501{
2502 struct atm_dev* atm_dev;
2503
2504 DPRINTK(2, "device %s being registered\n", fore200e->name);
2505
Dan Williamsd9ca6762010-12-08 19:40:47 +00002506 atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
2507 -1, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 if (atm_dev == NULL) {
2509 printk(FORE200E "unable to register device %s\n", fore200e->name);
2510 return -ENODEV;
2511 }
2512
2513 atm_dev->dev_data = fore200e;
2514 fore200e->atm_dev = atm_dev;
2515
2516 atm_dev->ci_range.vpi_bits = FORE200E_VPI_BITS;
2517 atm_dev->ci_range.vci_bits = FORE200E_VCI_BITS;
2518
2519 fore200e->available_cell_rate = ATM_OC3_PCR;
2520
2521 fore200e->state = FORE200E_STATE_REGISTER;
2522 return 0;
2523}
2524
2525
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002526static int fore200e_init(struct fore200e *fore200e, struct device *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527{
Dan Williamsd9ca6762010-12-08 19:40:47 +00002528 if (fore200e_register(fore200e, parent) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 return -ENODEV;
2530
2531 if (fore200e->bus->configure(fore200e) < 0)
2532 return -ENODEV;
2533
2534 if (fore200e->bus->map(fore200e) < 0)
2535 return -ENODEV;
2536
2537 if (fore200e_reset(fore200e, 1) < 0)
2538 return -ENODEV;
2539
Chas Williamse92481f2008-06-17 16:23:11 -07002540 if (fore200e_load_and_start_fw(fore200e) < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 return -ENODEV;
2542
2543 if (fore200e_initialize(fore200e) < 0)
2544 return -ENODEV;
2545
2546 if (fore200e_init_cmd_queue(fore200e) < 0)
2547 return -ENOMEM;
2548
2549 if (fore200e_init_tx_queue(fore200e) < 0)
2550 return -ENOMEM;
2551
2552 if (fore200e_init_rx_queue(fore200e) < 0)
2553 return -ENOMEM;
2554
2555 if (fore200e_init_bs_queue(fore200e) < 0)
2556 return -ENOMEM;
2557
2558 if (fore200e_alloc_rx_buf(fore200e) < 0)
2559 return -ENOMEM;
2560
2561 if (fore200e_get_esi(fore200e) < 0)
2562 return -EIO;
2563
2564 if (fore200e_irq_request(fore200e) < 0)
2565 return -EBUSY;
2566
2567 fore200e_supply(fore200e);
Sam Ravnborgc027f5f2006-03-03 17:50:37 -08002568
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569 /* all done, board initialization is now complete */
2570 fore200e->state = FORE200E_STATE_COMPLETE;
2571 return 0;
2572}
2573
David S. Miller826b6cf2008-08-27 01:06:07 -07002574#ifdef CONFIG_SBUS
Grant Likelyb1608d62011-05-18 11:19:24 -06002575static const struct of_device_id fore200e_sba_match[];
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002576static int fore200e_sba_probe(struct platform_device *op)
David S. Miller826b6cf2008-08-27 01:06:07 -07002577{
Grant Likelyb1608d62011-05-18 11:19:24 -06002578 const struct of_device_id *match;
David S. Miller826b6cf2008-08-27 01:06:07 -07002579 struct fore200e *fore200e;
2580 static int index = 0;
2581 int err;
2582
Grant Likelyb1608d62011-05-18 11:19:24 -06002583 match = of_match_device(fore200e_sba_match, &op->dev);
2584 if (!match)
Grant Likely1c48a5c2011-02-17 02:43:24 -07002585 return -EINVAL;
Grant Likely1c48a5c2011-02-17 02:43:24 -07002586
David S. Miller826b6cf2008-08-27 01:06:07 -07002587 fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
2588 if (!fore200e)
2589 return -ENOMEM;
2590
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002591 fore200e->bus = &fore200e_sbus_ops;
Christoph Hellwigaff9d262018-10-09 16:57:15 +02002592 fore200e->dev = &op->dev;
Grant Likely1636f8a2010-06-18 11:09:58 -06002593 fore200e->irq = op->archdata.irqs[0];
David S. Miller826b6cf2008-08-27 01:06:07 -07002594 fore200e->phys_base = op->resource[0].start;
2595
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002596 sprintf(fore200e->name, "SBA-200E-%d", index);
David S. Miller826b6cf2008-08-27 01:06:07 -07002597
Dan Williamsd9ca6762010-12-08 19:40:47 +00002598 err = fore200e_init(fore200e, &op->dev);
David S. Miller826b6cf2008-08-27 01:06:07 -07002599 if (err < 0) {
2600 fore200e_shutdown(fore200e);
2601 kfree(fore200e);
2602 return err;
2603 }
2604
2605 index++;
2606 dev_set_drvdata(&op->dev, fore200e);
2607
2608 return 0;
2609}
2610
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002611static int fore200e_sba_remove(struct platform_device *op)
David S. Miller826b6cf2008-08-27 01:06:07 -07002612{
2613 struct fore200e *fore200e = dev_get_drvdata(&op->dev);
2614
2615 fore200e_shutdown(fore200e);
2616 kfree(fore200e);
2617
2618 return 0;
2619}
2620
David S. Millerfd098312008-08-31 01:23:17 -07002621static const struct of_device_id fore200e_sba_match[] = {
David S. Miller826b6cf2008-08-27 01:06:07 -07002622 {
2623 .name = SBA200E_PROM_NAME,
David S. Miller826b6cf2008-08-27 01:06:07 -07002624 },
2625 {},
2626};
2627MODULE_DEVICE_TABLE(of, fore200e_sba_match);
2628
Grant Likely1c48a5c2011-02-17 02:43:24 -07002629static struct platform_driver fore200e_sba_driver = {
Grant Likely40182942010-04-13 16:13:02 -07002630 .driver = {
2631 .name = "fore_200e",
Grant Likely40182942010-04-13 16:13:02 -07002632 .of_match_table = fore200e_sba_match,
2633 },
David S. Miller826b6cf2008-08-27 01:06:07 -07002634 .probe = fore200e_sba_probe,
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002635 .remove = fore200e_sba_remove,
David S. Miller826b6cf2008-08-27 01:06:07 -07002636};
2637#endif
2638
Chas Williamse92481f2008-06-17 16:23:11 -07002639#ifdef CONFIG_PCI
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002640static int fore200e_pca_detect(struct pci_dev *pci_dev,
2641 const struct pci_device_id *pci_ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642{
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643 struct fore200e* fore200e;
2644 int err = 0;
2645 static int index = 0;
2646
2647 if (pci_enable_device(pci_dev)) {
2648 err = -EINVAL;
2649 goto out;
2650 }
chas williams - CONTRACTORede58ef2015-01-16 08:57:21 -05002651
2652 if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32))) {
2653 err = -EINVAL;
2654 goto out;
2655 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002656
Adrian Bunk1f8a5fb2006-12-19 19:36:32 -08002657 fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 if (fore200e == NULL) {
2659 err = -ENOMEM;
2660 goto out_disable;
2661 }
2662
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002663 fore200e->bus = &fore200e_pci_ops;
Christoph Hellwigaff9d262018-10-09 16:57:15 +02002664 fore200e->dev = &pci_dev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 fore200e->irq = pci_dev->irq;
2666 fore200e->phys_base = pci_resource_start(pci_dev, 0);
2667
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002668 sprintf(fore200e->name, "PCA-200E-%d", index - 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669
2670 pci_set_master(pci_dev);
2671
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002672 printk(FORE200E "device PCA-200E found at 0x%lx, IRQ %s\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
2674
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002675 sprintf(fore200e->name, "PCA-200E-%d", index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676
Dan Williamsd9ca6762010-12-08 19:40:47 +00002677 err = fore200e_init(fore200e, &pci_dev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 if (err < 0) {
2679 fore200e_shutdown(fore200e);
2680 goto out_free;
2681 }
2682
2683 ++index;
2684 pci_set_drvdata(pci_dev, fore200e);
2685
2686out:
2687 return err;
2688
2689out_free:
2690 kfree(fore200e);
2691out_disable:
2692 pci_disable_device(pci_dev);
2693 goto out;
2694}
2695
2696
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002697static void fore200e_pca_remove_one(struct pci_dev *pci_dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698{
2699 struct fore200e *fore200e;
2700
2701 fore200e = pci_get_drvdata(pci_dev);
2702
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703 fore200e_shutdown(fore200e);
2704 kfree(fore200e);
2705 pci_disable_device(pci_dev);
2706}
2707
2708
Arvind Yadavd5c56652017-07-16 15:02:31 +05302709static const struct pci_device_id fore200e_pca_tbl[] = {
Christoph Hellwig0efe5522018-10-09 16:57:14 +02002710 { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID },
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 { 0, }
2712};
2713
2714MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl);
2715
2716static struct pci_driver fore200e_pca_driver = {
2717 .name = "fore_200e",
2718 .probe = fore200e_pca_detect,
Greg Kroah-Hartman6c445122012-12-21 13:25:04 -08002719 .remove = fore200e_pca_remove_one,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720 .id_table = fore200e_pca_tbl,
2721};
2722#endif
2723
David S. Miller826b6cf2008-08-27 01:06:07 -07002724static int __init fore200e_module_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725{
Rickard Strandqvist74e8ce32014-06-01 01:08:32 +02002726 int err = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727
David S. Miller826b6cf2008-08-27 01:06:07 -07002728 printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729
David S. Miller826b6cf2008-08-27 01:06:07 -07002730#ifdef CONFIG_SBUS
Grant Likely1c48a5c2011-02-17 02:43:24 -07002731 err = platform_driver_register(&fore200e_sba_driver);
David S. Miller826b6cf2008-08-27 01:06:07 -07002732 if (err)
2733 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734#endif
2735
Chas Williamse92481f2008-06-17 16:23:11 -07002736#ifdef CONFIG_PCI
David S. Miller826b6cf2008-08-27 01:06:07 -07002737 err = pci_register_driver(&fore200e_pca_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738#endif
2739
David S. Miller826b6cf2008-08-27 01:06:07 -07002740#ifdef CONFIG_SBUS
2741 if (err)
Grant Likely1c48a5c2011-02-17 02:43:24 -07002742 platform_driver_unregister(&fore200e_sba_driver);
David S. Miller826b6cf2008-08-27 01:06:07 -07002743#endif
2744
2745 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002746}
2747
David S. Miller826b6cf2008-08-27 01:06:07 -07002748static void __exit fore200e_module_cleanup(void)
2749{
2750#ifdef CONFIG_PCI
2751 pci_unregister_driver(&fore200e_pca_driver);
2752#endif
2753#ifdef CONFIG_SBUS
Grant Likely1c48a5c2011-02-17 02:43:24 -07002754 platform_driver_unregister(&fore200e_sba_driver);
David S. Miller826b6cf2008-08-27 01:06:07 -07002755#endif
2756}
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757
2758static int
2759fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
2760{
2761 struct fore200e* fore200e = FORE200E_DEV(dev);
2762 struct fore200e_vcc* fore200e_vcc;
2763 struct atm_vcc* vcc;
2764 int i, len, left = *pos;
2765 unsigned long flags;
2766
2767 if (!left--) {
2768
2769 if (fore200e_getstats(fore200e) < 0)
2770 return -EIO;
2771
2772 len = sprintf(page,"\n"
2773 " device:\n"
2774 " internal name:\t\t%s\n", fore200e->name);
2775
2776 /* print bus-specific information */
2777 if (fore200e->bus->proc_read)
2778 len += fore200e->bus->proc_read(fore200e, page + len);
2779
2780 len += sprintf(page + len,
2781 " interrupt line:\t\t%s\n"
2782 " physical base address:\t0x%p\n"
2783 " virtual base address:\t0x%p\n"
hartleys3008ab32010-01-05 06:22:20 +00002784 " factory address (ESI):\t%pM\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07002785 " board serial number:\t\t%d\n\n",
2786 fore200e_irq_itoa(fore200e->irq),
2787 (void*)fore200e->phys_base,
2788 fore200e->virt_base,
hartleys3008ab32010-01-05 06:22:20 +00002789 fore200e->esi,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002790 fore200e->esi[4] * 256 + fore200e->esi[5]);
2791
2792 return len;
2793 }
2794
2795 if (!left--)
2796 return sprintf(page,
2797 " free small bufs, scheme 1:\t%d\n"
2798 " free large bufs, scheme 1:\t%d\n"
2799 " free small bufs, scheme 2:\t%d\n"
2800 " free large bufs, scheme 2:\t%d\n",
2801 fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].freebuf_count,
2802 fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].freebuf_count,
2803 fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].freebuf_count,
2804 fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].freebuf_count);
2805
2806 if (!left--) {
2807 u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
2808
2809 len = sprintf(page,"\n\n"
2810 " cell processor:\n"
2811 " heartbeat state:\t\t");
2812
2813 if (hb >> 16 != 0xDEAD)
2814 len += sprintf(page + len, "0x%08x\n", hb);
2815 else
2816 len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF);
2817
2818 return len;
2819 }
2820
2821 if (!left--) {
2822 static const char* media_name[] = {
2823 "unshielded twisted pair",
2824 "multimode optical fiber ST",
2825 "multimode optical fiber SC",
2826 "single-mode optical fiber ST",
2827 "single-mode optical fiber SC",
2828 "unknown"
2829 };
2830
2831 static const char* oc3_mode[] = {
2832 "normal operation",
2833 "diagnostic loopback",
2834 "line loopback",
2835 "unknown"
2836 };
2837
2838 u32 fw_release = fore200e->bus->read(&fore200e->cp_queues->fw_release);
2839 u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release);
2840 u32 oc3_revision = fore200e->bus->read(&fore200e->cp_queues->oc3_revision);
2841 u32 media_index = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
2842 u32 oc3_index;
2843
roel kluine0c55672009-10-23 06:09:55 +00002844 if (media_index > 4)
2845 media_index = 5;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846
2847 switch (fore200e->loop_mode) {
2848 case ATM_LM_NONE: oc3_index = 0;
2849 break;
2850 case ATM_LM_LOC_PHY: oc3_index = 1;
2851 break;
2852 case ATM_LM_RMT_PHY: oc3_index = 2;
2853 break;
2854 default: oc3_index = 3;
2855 }
2856
2857 return sprintf(page,
2858 " firmware release:\t\t%d.%d.%d\n"
2859 " monitor release:\t\t%d.%d\n"
2860 " media type:\t\t\t%s\n"
2861 " OC-3 revision:\t\t0x%x\n"
2862 " OC-3 mode:\t\t\t%s",
2863 fw_release >> 16, fw_release << 16 >> 24, fw_release << 24 >> 24,
2864 mon960_release >> 16, mon960_release << 16 >> 16,
2865 media_name[ media_index ],
2866 oc3_revision,
2867 oc3_mode[ oc3_index ]);
2868 }
2869
2870 if (!left--) {
2871 struct cp_monitor __iomem * cp_monitor = fore200e->cp_monitor;
2872
2873 return sprintf(page,
2874 "\n\n"
2875 " monitor:\n"
2876 " version number:\t\t%d\n"
2877 " boot status word:\t\t0x%08x\n",
2878 fore200e->bus->read(&cp_monitor->mon_version),
2879 fore200e->bus->read(&cp_monitor->bstat));
2880 }
2881
2882 if (!left--)
2883 return sprintf(page,
2884 "\n"
2885 " device statistics:\n"
2886 " 4b5b:\n"
2887 " crc_header_errors:\t\t%10u\n"
2888 " framing_errors:\t\t%10u\n",
Al Viro63734a32008-03-16 22:23:04 +00002889 be32_to_cpu(fore200e->stats->phy.crc_header_errors),
2890 be32_to_cpu(fore200e->stats->phy.framing_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891
2892 if (!left--)
2893 return sprintf(page, "\n"
2894 " OC-3:\n"
2895 " section_bip8_errors:\t%10u\n"
2896 " path_bip8_errors:\t\t%10u\n"
2897 " line_bip24_errors:\t\t%10u\n"
2898 " line_febe_errors:\t\t%10u\n"
2899 " path_febe_errors:\t\t%10u\n"
2900 " corr_hcs_errors:\t\t%10u\n"
2901 " ucorr_hcs_errors:\t\t%10u\n",
Al Viro63734a32008-03-16 22:23:04 +00002902 be32_to_cpu(fore200e->stats->oc3.section_bip8_errors),
2903 be32_to_cpu(fore200e->stats->oc3.path_bip8_errors),
2904 be32_to_cpu(fore200e->stats->oc3.line_bip24_errors),
2905 be32_to_cpu(fore200e->stats->oc3.line_febe_errors),
2906 be32_to_cpu(fore200e->stats->oc3.path_febe_errors),
2907 be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors),
2908 be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
2910 if (!left--)
2911 return sprintf(page,"\n"
2912 " ATM:\t\t\t\t cells\n"
2913 " TX:\t\t\t%10u\n"
2914 " RX:\t\t\t%10u\n"
2915 " vpi out of range:\t\t%10u\n"
2916 " vpi no conn:\t\t%10u\n"
2917 " vci out of range:\t\t%10u\n"
2918 " vci no conn:\t\t%10u\n",
Al Viro63734a32008-03-16 22:23:04 +00002919 be32_to_cpu(fore200e->stats->atm.cells_transmitted),
2920 be32_to_cpu(fore200e->stats->atm.cells_received),
2921 be32_to_cpu(fore200e->stats->atm.vpi_bad_range),
2922 be32_to_cpu(fore200e->stats->atm.vpi_no_conn),
2923 be32_to_cpu(fore200e->stats->atm.vci_bad_range),
2924 be32_to_cpu(fore200e->stats->atm.vci_no_conn));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
2926 if (!left--)
2927 return sprintf(page,"\n"
2928 " AAL0:\t\t\t cells\n"
2929 " TX:\t\t\t%10u\n"
2930 " RX:\t\t\t%10u\n"
2931 " dropped:\t\t\t%10u\n",
Al Viro63734a32008-03-16 22:23:04 +00002932 be32_to_cpu(fore200e->stats->aal0.cells_transmitted),
2933 be32_to_cpu(fore200e->stats->aal0.cells_received),
2934 be32_to_cpu(fore200e->stats->aal0.cells_dropped));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935
2936 if (!left--)
2937 return sprintf(page,"\n"
2938 " AAL3/4:\n"
2939 " SAR sublayer:\t\t cells\n"
2940 " TX:\t\t\t%10u\n"
2941 " RX:\t\t\t%10u\n"
2942 " dropped:\t\t\t%10u\n"
2943 " CRC errors:\t\t%10u\n"
2944 " protocol errors:\t\t%10u\n\n"
2945 " CS sublayer:\t\t PDUs\n"
2946 " TX:\t\t\t%10u\n"
2947 " RX:\t\t\t%10u\n"
2948 " dropped:\t\t\t%10u\n"
2949 " protocol errors:\t\t%10u\n",
Al Viro63734a32008-03-16 22:23:04 +00002950 be32_to_cpu(fore200e->stats->aal34.cells_transmitted),
2951 be32_to_cpu(fore200e->stats->aal34.cells_received),
2952 be32_to_cpu(fore200e->stats->aal34.cells_dropped),
2953 be32_to_cpu(fore200e->stats->aal34.cells_crc_errors),
2954 be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors),
2955 be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted),
2956 be32_to_cpu(fore200e->stats->aal34.cspdus_received),
2957 be32_to_cpu(fore200e->stats->aal34.cspdus_dropped),
2958 be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959
2960 if (!left--)
2961 return sprintf(page,"\n"
2962 " AAL5:\n"
2963 " SAR sublayer:\t\t cells\n"
2964 " TX:\t\t\t%10u\n"
2965 " RX:\t\t\t%10u\n"
2966 " dropped:\t\t\t%10u\n"
2967 " congestions:\t\t%10u\n\n"
2968 " CS sublayer:\t\t PDUs\n"
2969 " TX:\t\t\t%10u\n"
2970 " RX:\t\t\t%10u\n"
2971 " dropped:\t\t\t%10u\n"
2972 " CRC errors:\t\t%10u\n"
2973 " protocol errors:\t\t%10u\n",
Al Viro63734a32008-03-16 22:23:04 +00002974 be32_to_cpu(fore200e->stats->aal5.cells_transmitted),
2975 be32_to_cpu(fore200e->stats->aal5.cells_received),
2976 be32_to_cpu(fore200e->stats->aal5.cells_dropped),
2977 be32_to_cpu(fore200e->stats->aal5.congestion_experienced),
2978 be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted),
2979 be32_to_cpu(fore200e->stats->aal5.cspdus_received),
2980 be32_to_cpu(fore200e->stats->aal5.cspdus_dropped),
2981 be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors),
2982 be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983
2984 if (!left--)
2985 return sprintf(page,"\n"
2986 " AUX:\t\t allocation failures\n"
2987 " small b1:\t\t\t%10u\n"
2988 " large b1:\t\t\t%10u\n"
2989 " small b2:\t\t\t%10u\n"
2990 " large b2:\t\t\t%10u\n"
2991 " RX PDUs:\t\t\t%10u\n"
2992 " TX PDUs:\t\t\t%10lu\n",
Al Viro63734a32008-03-16 22:23:04 +00002993 be32_to_cpu(fore200e->stats->aux.small_b1_failed),
2994 be32_to_cpu(fore200e->stats->aux.large_b1_failed),
2995 be32_to_cpu(fore200e->stats->aux.small_b2_failed),
2996 be32_to_cpu(fore200e->stats->aux.large_b2_failed),
2997 be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed),
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998 fore200e->tx_sat);
2999
3000 if (!left--)
3001 return sprintf(page,"\n"
3002 " receive carrier:\t\t\t%s\n",
3003 fore200e->stats->aux.receive_carrier ? "ON" : "OFF!");
3004
3005 if (!left--) {
3006 return sprintf(page,"\n"
3007 " VCCs:\n address VPI VCI AAL "
3008 "TX PDUs TX min/max size RX PDUs RX min/max size\n");
3009 }
3010
3011 for (i = 0; i < NBR_CONNECT; i++) {
3012
3013 vcc = fore200e->vc_map[i].vcc;
3014
3015 if (vcc == NULL)
3016 continue;
3017
3018 spin_lock_irqsave(&fore200e->q_lock, flags);
3019
3020 if (vcc && test_bit(ATM_VF_READY, &vcc->flags) && !left--) {
3021
3022 fore200e_vcc = FORE200E_VCC(vcc);
3023 ASSERT(fore200e_vcc);
3024
3025 len = sprintf(page,
Colin Ian King22dac9f2017-11-27 13:24:15 +00003026 " %pK %03d %05d %1d %09lu %05d/%05d %09lu %05d/%05d\n",
3027 vcc,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
3029 fore200e_vcc->tx_pdu,
3030 fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu,
3031 fore200e_vcc->tx_max_pdu,
3032 fore200e_vcc->rx_pdu,
3033 fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
3034 fore200e_vcc->rx_max_pdu);
3035
3036 spin_unlock_irqrestore(&fore200e->q_lock, flags);
3037 return len;
3038 }
3039
3040 spin_unlock_irqrestore(&fore200e->q_lock, flags);
3041 }
3042
3043 return 0;
3044}
3045
3046module_init(fore200e_module_init);
3047module_exit(fore200e_module_cleanup);
3048
3049
Christoph Hellwig0efe5522018-10-09 16:57:14 +02003050static const struct atmdev_ops fore200e_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 .open = fore200e_open,
3052 .close = fore200e_close,
3053 .ioctl = fore200e_ioctl,
3054 .getsockopt = fore200e_getsockopt,
3055 .setsockopt = fore200e_setsockopt,
3056 .send = fore200e_send,
3057 .change_qos = fore200e_change_qos,
3058 .proc_read = fore200e_proc_read,
3059 .owner = THIS_MODULE
3060};
3061
Linus Torvalds1da177e2005-04-16 15:20:36 -07003062MODULE_LICENSE("GPL");
Chas Williams6f75a9b2008-07-23 20:29:21 -07003063#ifdef CONFIG_PCI
3064#ifdef __LITTLE_ENDIAN__
3065MODULE_FIRMWARE("pca200e.bin");
3066#else
3067MODULE_FIRMWARE("pca200e_ecd.bin2");
3068#endif
3069#endif /* CONFIG_PCI */
3070#ifdef CONFIG_SBUS
3071MODULE_FIRMWARE("sba200e_ecd.bin2");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003072#endif