1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62#include <linux/module.h>
63#include <linux/mm.h>
64#include <linux/atmdev.h>
65#include <asm/io.h>
66#include <asm/byteorder.h>
67#include <linux/spinlock.h>
68#include <linux/pci.h>
69#include <linux/init.h>
70#include <linux/delay.h>
71#include <linux/interrupt.h>
72
73#ifndef PCI_VENDOR_ID_EF_ATM_LANAI2
74
75#define PCI_VENDOR_ID_EF_ATM_LANAI2 0x0003
76#define PCI_VENDOR_ID_EF_ATM_LANAIHB 0x0005
77#endif
78
79
80
81
82
83
84
85
86#define NUM_VCI (1024)
87
88
89
90
91#define DEBUG
92
93
94
95
96
97#undef DEBUG_RW
98
99
100
101
102
103#define FULL_MEMORY_TEST
104
105
106
107
108
109
110#define SERVICE_ENTRIES (1024)
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127#define TX_FIFO_DEPTH (7)
128
129
130
131
132
133
134#define LANAI_POLL_PERIOD (10*HZ)
135
136
137
138
139
140
141#define AAL5_RX_MULTIPLIER (3)
142
143
144
145
146
147#define AAL5_TX_MULTIPLIER (3)
148
149
150
151
152
153
154
155#define AAL0_TX_MULTIPLIER (40)
156
157
158
159
160
161
162#define AAL0_RX_BUFFER_SIZE (PAGE_SIZE)
163
164
165
166
167
168
169
170
171
172
173#define DEV_LABEL "lanai"
174
175#ifdef DEBUG
176
177#define DPRINTK(format, args...) \
178 printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
179#define APRINTK(truth, format, args...) \
180 do { \
181 if (!(truth)) \
182 printk(KERN_ERR DEV_LABEL ": " format, ##args); \
183 } while (0)
184
185#else
186
187#define DPRINTK(format, args...)
188#define APRINTK(truth, format, args...)
189
190#endif
191
192#ifdef DEBUG_RW
193#define RWDEBUG(format, args...) \
194 printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
195#else
196#define RWDEBUG(format, args...)
197#endif
198
199
200
201#define LANAI_MAPPING_SIZE (0x40000)
202#define LANAI_EEPROM_SIZE (128)
203
204typedef int vci_t;
205typedef unsigned long bus_addr_t;
206
207
208#define VCI_BITFIELD_NELEM ((NUM_VCI + BITS_PER_LONG - 1) / BITS_PER_LONG)
209typedef struct {
210 unsigned long ul[VCI_BITFIELD_NELEM];
211} vci_bitfield;
212
213
214struct lanai_buffer {
215 u32 *start;
216 u32 *end;
217 u32 *ptr;
218 int order;
219};
220
221struct lanai_vcc_stats {
222 unsigned rx_nomem;
223 union {
224 struct {
225 unsigned rx_badlen;
226 unsigned service_trash;
227 unsigned service_stream;
228 unsigned service_rxcrc;
229 } aal5;
230 struct {
231 } aal0;
232 } x;
233};
234
235struct lanai_dev;
236
237
238
239
240
241
242
243
244
245struct lanai_vcc {
246 bus_addr_t vbase;
247 struct lanai_vcc_stats stats;
248 int nref;
249 vci_t vci;
250 struct {
251 struct lanai_buffer buf;
252 struct atm_vcc *atmvcc;
253 } rx;
254 struct {
255 struct lanai_buffer buf;
256 struct atm_vcc *atmvcc;
257 int endptr;
258 struct sk_buff_head backlog;
259 struct sk_buff *inprogress;
260 unsigned char *pptr;
261 int inprogleft;
262 void (*unqueue)(struct lanai_dev *, struct lanai_vcc *, int);
263 } tx;
264};
265
266enum lanai_type {
267 lanai2 = PCI_VENDOR_ID_EF_ATM_LANAI2,
268 lanaihb = PCI_VENDOR_ID_EF_ATM_LANAIHB
269};
270
271struct lanai_dev_stats {
272 unsigned ovfl_trash;
273 unsigned vci_trash;
274 unsigned hec_err;
275 unsigned atm_ovfl;
276 unsigned pcierr_parity_detect;
277 unsigned pcierr_serr_set;
278 unsigned pcierr_master_abort;
279 unsigned pcierr_m_target_abort;
280 unsigned pcierr_s_target_abort;
281 unsigned pcierr_master_parity;
282 unsigned service_novcc_rx;
283 unsigned service_novcc_tx;
284 unsigned service_notx;
285 unsigned service_norx;
286 unsigned service_rxnotaal5;
287 unsigned dma_reenable;
288 unsigned card_reset;
289};
290
291struct lanai_dev {
292 bus_addr_t base;
293 struct lanai_dev_stats stats;
294 struct lanai_buffer service;
295 struct lanai_vcc **vccs;
296#ifdef USE_POWERDOWN
297 int nbound;
298#endif
299 enum lanai_type type;
300 vci_t num_vci;
301 u8 eeprom[LANAI_EEPROM_SIZE];
302 u32 serialno, magicno;
303 struct pci_dev *pci;
304 vci_bitfield backlog_vccs;
305 vci_bitfield transmit_ready;
306 struct timer_list timer;
307 int naal0;
308 struct lanai_buffer aal0buf;
309 u32 conf1, conf2;
310 u32 status;
311 spinlock_t txlock;
312 spinlock_t servicelock;
313 struct atm_vcc *cbrvcc;
314 int number;
315 int board_rev;
316 u8 pci_revision;
317
318
319
320};
321
322
323
324
325
326
327
328#if (BITS_PER_LONG & (BITS_PER_LONG - 1))
329#error lanai driver requires type long to have a power of two number of bits
330#endif
331
332
333
334
335
336
337
338static inline void vci_bitfield_set(vci_bitfield *bf, vci_t vci)
339{
340 unsigned long bit = 1;
341 bit <<= (unsigned long) (vci & (BITS_PER_LONG - 1));
342 bf->ul[vci / BITS_PER_LONG] |= bit;
343}
344
345static inline void vci_bitfield_clear(vci_bitfield *bf, vci_t vci)
346{
347 unsigned long bit = 1;
348 bit <<= (unsigned long) (vci & (BITS_PER_LONG - 1));
349 bf->ul[vci / BITS_PER_LONG] &= ~bit;
350}
351
352static inline void vci_bitfield_init(vci_bitfield *bf)
353{
354 memset(bf, 0, sizeof(*bf));
355}
356
357static void vci_bitfield_iterate(struct lanai_dev *lanai,
358 const vci_bitfield *bf, void (*func)(struct lanai_dev *,vci_t vci))
359{
360 vci_t vci;
361 unsigned long mask;
362 const unsigned long *lp = &(bf->ul[0]);
363 for (vci = 0; vci < NUM_VCI; lp++)
364 if (*lp == 0)
365 vci += BITS_PER_LONG;
366 else
367 for (mask = 1; mask != 0; mask <<= 1, vci++)
368 if (*lp & mask)
369 func(lanai, vci);
370}
371
372
373
374
375
376
377
378
379#if PAGE_SIZE < 1024
380#error PAGE_SIZE too small to support LANAI chipset
381#endif
382
383
384
385
386#if PAGE_SIZE > (128 * 1024)
387#error PAGE_SIZE too large to support LANAI chipset
388#endif
389
390
391static int bytes_to_order(int bytes)
392{
393 int order = 0;
394 if (bytes > (128 * 1024))
395 bytes = 128 * 1024;
396 while ((PAGE_SIZE << order) < bytes)
397 order++;
398 return order;
399}
400
401
402
403
404
405
406
407
408
409
410
411
412static void lanai_buf_allocate(struct lanai_buffer *buf,
413 int bytes, int minbytes)
414{
415 unsigned long address;
416 int order = bytes_to_order(bytes);
417 do {
418 address = __get_free_pages(GFP_KERNEL, order);
419 if (address != 0) {
420 bytes = PAGE_SIZE << order;
421 buf->start = buf->ptr = (u32 *) address;
422 buf->end = (u32 *) (address + bytes);
423 memset((void *) address, 0, bytes);
424 break;
425 }
426 if ((PAGE_SIZE << --order) < minbytes)
427 order = -1;
428 } while (order >= 0);
429 buf->order = order;
430}
431
432static inline void lanai_buf_deallocate(struct lanai_buffer *buf)
433{
434 if (buf->order >= 0) {
435 APRINTK(buf->start != 0, "lanai_buf_deallocate: start==0!\n");
436 free_pages((unsigned long) buf->start, buf->order);
437 buf->start = buf->end = buf->ptr = 0;
438 }
439}
440
441
442static inline int lanai_buf_size(const struct lanai_buffer *buf)
443{
444 return ((unsigned long) buf->end) - ((unsigned long) buf->start);
445}
446
447
448static inline int lanai_buf_size_cardorder(const struct lanai_buffer *buf)
449{
450 return buf->order + PAGE_SHIFT - 10;
451}
452
453
454static unsigned long lanai_buf_dmaaddr(const struct lanai_buffer *buf)
455{
456 unsigned long r = virt_to_bus(buf->start);
457 APRINTK((r & ~0xFFFFFF00) == 0, "bad dmaaddr: 0x%lx\n", (long) r);
458 return r;
459}
460
461
462
463static inline void vcc_mark_backlogged(struct lanai_dev *lanai,
464 const struct lanai_vcc *lvcc)
465{
466 APRINTK(lvcc->vbase != 0, "vcc_mark_backlogged: zero vbase!\n");
467 vci_bitfield_set(&lanai->backlog_vccs, lvcc->vci);
468}
469
470static inline void vcc_unmark_backlogged(struct lanai_dev *lanai,
471 const struct lanai_vcc *lvcc)
472{
473 APRINTK(lvcc->vbase != 0, "vcc_unmark_backlogged: zero vbase!\n");
474 vci_bitfield_clear(&lanai->backlog_vccs, lvcc->vci);
475}
476
477static inline void vcc_backlog_init(struct lanai_dev *lanai)
478{
479 vci_bitfield_init(&lanai->backlog_vccs);
480}
481
482static inline int vcc_is_backlogged( struct lanai_vcc *lvcc)
483{
484 return lvcc->tx.inprogress != NULL ||
485 !skb_queue_empty(&lvcc->tx.backlog);
486}
487
488
489
490
491enum lanai_register {
492 Reset_Reg = 0x00,
493#define RESET_GET_BOARD_REV(x) (((x)>> 0)&0x03)
494#define RESET_GET_BOARD_ID(x) (((x)>> 2)&0x03)
495#define BOARD_ID_LANAI256 (0)
496 Endian_Reg = 0x04,
497 IntStatus_Reg = 0x08,
498 IntStatusMasked_Reg = 0x0C,
499 IntAck_Reg = 0x10,
500 IntAckMasked_Reg = 0x14,
501 IntStatusSet_Reg = 0x18,
502 IntStatusSetMasked_Reg = 0x1C,
503 IntControlEna_Reg = 0x20,
504 IntControlDis_Reg = 0x24,
505 Status_Reg = 0x28,
506#define STATUS_PROMDATA (0x00000001)
507#define STATUS_WAITING (0x00000002)
508#define STATUS_SOOL (0x00000004)
509#define STATUS_LOCD (0x00000008)
510#define STATUS_LED (0x00000010)
511#define STATUS_GPIN (0x00000020)
512#define STATUS_BUTTBUSY (0x00000040)
513 Config1_Reg = 0x2C,
514#define CONFIG1_PROMDATA (0x00000001)
515#define CONFIG1_PROMCLK (0x00000002)
516#define CONFIG1_SET_READMODE(x) ((x)*0x004)
517#define READMODE_PLAIN (0)
518#define READMODE_LINE (2)
519#define READMODE_MULTIPLE (3)
520#define CONFIG1_DMA_ENABLE (0x00000010)
521#define CONFIG1_POWERDOWN (0x00000020)
522#define CONFIG1_SET_LOOPMODE(x) ((x)*0x080)
523#define LOOPMODE_NORMAL (0)
524#define LOOPMODE_TIME (1)
525#define LOOPMODE_DIAG (2)
526#define LOOPMODE_LINE (3)
527#define CONFIG1_MASK_LOOPMODE (0x00000180)
528#define CONFIG1_SET_LEDMODE(x) ((x)*0x0200)
529#define LEDMODE_NOT_SOOL (0)
530#define LEDMODE_OFF (1)
531#define LEDMODE_ON (2)
532#define LEDMODE_NOT_LOCD (3)
533#define LEDMORE_GPIN (4)
534#define LEDMODE_NOT_GPIN (7)
535#define CONFIG1_MASK_LEDMODE (0x00000E00)
536#define CONFIG1_GPOUT1 (0x00001000)
537#define CONFIG1_GPOUT2 (0x00002000)
538#define CONFIG1_GPOUT3 (0x00004000)
539 Config2_Reg = 0x30,
540#define CONFIG2_HOWMANY (0x00000001)
541#define CONFIG2_PTI7_MODE (0x00000002)
542#define CONFIG2_VPI_CHK_DIS (0x00000004)
543#define CONFIG2_HEC_DROP (0x00000008)
544#define CONFIG2_VCI0_NORMAL (0x00000010)
545#define CONFIG2_CBR_ENABLE (0x00000020)
546#define CONFIG2_TRASH_ALL (0x00000040)
547#define CONFIG2_TX_DISABLE (0x00000080)
548#define CONFIG2_SET_TRASH (0x00000100)
549 Statistics_Reg = 0x34,
550#define STATS_GET_FIFO_OVFL(x) (((x)>> 0)&0xFF)
551#define STATS_GET_HEC_ERR(x) (((x)>> 8)&0xFF)
552#define STATS_GET_BAD_VCI(x) (((x)>>16)&0xFF)
553#define STATS_GET_BUF_OVFL(x) (((x)>>24)&0xFF)
554 ServiceStuff_Reg = 0x38,
555#define SSTUFF_SET_SIZE(x) ((x)*0x20000000)
556#define SSTUFF_SET_ADDR(x) ((x)>>8)
557 ServWrite_Reg = 0x3C,
558 ServRead_Reg = 0x40,
559 TxDepth_Reg = 0x44,
560 Butt_Reg = 0x48,
561 CBR_ICG_Reg = 0x50,
562 CBR_PTR_Reg = 0x54,
563 PingCount_Reg = 0x58,
564 DMA_Addr_Reg = 0x5C
565};
566
567static inline bus_addr_t reg_addr(const struct lanai_dev *lanai,
568 enum lanai_register reg)
569{
570 return lanai->base + (bus_addr_t) reg;
571}
572
573
574static inline u32 reg_read(const struct lanai_dev *lanai,
575 enum lanai_register reg)
576{
577 u32 t;
578 t = readl(reg_addr(lanai, reg));
579 RWDEBUG("R [0x%08X] 0x%02X = 0x%08X\n", (unsigned int) lanai->base,
580 (int) reg, t);
581 return t;
582}
583
584static inline void reg_write(const struct lanai_dev *lanai, u32 val,
585 enum lanai_register reg)
586{
587 RWDEBUG("W [0x%08X] 0x%02X < 0x%08X\n", (unsigned int) lanai->base,
588 (int) reg, val);
589 writel(val, reg_addr(lanai, reg));
590 mdelay(1);
591}
592
593static inline void conf1_write(const struct lanai_dev *lanai)
594{
595 reg_write(lanai, lanai->conf1, Config1_Reg);
596}
597
598static inline void conf2_write(const struct lanai_dev *lanai)
599{
600 reg_write(lanai, lanai->conf2, Config2_Reg);
601}
602
603static inline void reset_board(const struct lanai_dev *lanai)
604{
605 DPRINTK("about to reset board\n");
606 reg_write(lanai, 0, Reset_Reg);
607
608
609
610
611
612
613 udelay(5);
614}
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668#define vcclist_read_lock() do {} while (0)
669#define vcclist_read_unlock() do {} while (0)
670#define vcclist_write_lock() do {} while (0)
671#define vcclist_write_unlock() do {} while (0)
672
673
674
675
676
677
678
679
680#define SRAM_START (0x20000)
681#define SRAM_BYTES (0x20000)
682
683static inline bus_addr_t sram_addr(const struct lanai_dev *lanai, int offset)
684{
685 return lanai->base + SRAM_START + offset;
686}
687
688static inline u32 sram_read(const struct lanai_dev *lanai, int offset)
689{
690 return readl(sram_addr(lanai, offset));
691}
692
693static inline void sram_write(const struct lanai_dev *lanai,
694 u32 val, int offset)
695{
696 writel(val, sram_addr(lanai, offset));
697}
698
699static int __init sram_test_word(
700 const struct lanai_dev *lanai, int offset, u32 pattern)
701{
702 u32 readback;
703 sram_write(lanai, pattern, offset);
704 readback = sram_read(lanai, offset);
705 if (readback == pattern)
706 return 0;
707 printk(KERN_ERR DEV_LABEL
708 "(itf %d): SRAM word at %d bad: wrote 0x%X, read 0x%X\n",
709 lanai->number, offset, pattern, readback);
710 return -EIO;
711}
712
713static int __init sram_test_pass(const struct lanai_dev *lanai, u32 pattern)
714{
715 int offset, result = 0;
716 for (offset = 0; offset < SRAM_BYTES && result == 0; offset += 4)
717 result = sram_test_word(lanai, offset, pattern);
718 return result;
719}
720
721static int __init sram_test_and_clear(const struct lanai_dev *lanai)
722{
723#ifdef FULL_MEMORY_TEST
724 int result;
725 DPRINTK("testing SRAM\n");
726 if ((result = sram_test_pass(lanai, 0x5555)) != 0)
727 return result;
728 if ((result = sram_test_pass(lanai, 0xAAAA)) != 0)
729 return result;
730#endif
731 DPRINTK("clearing SRAM\n");
732 return sram_test_pass(lanai, 0x0000);
733}
734
735
736
737
738enum lanai_vcc_offset {
739 vcc_rxaddr1 = 0x00,
740#define RXADDR1_SET_SIZE(x) ((x)*0x0000100)
741#define RXADDR1_SET_RMMODE(x) ((x)*0x00800)
742#define RMMODE_TRASH (0)
743#define RMMODE_PRESERVE (1)
744#define RMMODE_PIPE (2)
745#define RMMODE_PIPEALL (3)
746#define RXADDR1_OAM_PRESERVE (0x00002000)
747#define RXADDR1_SET_MODE(x) ((x)*0x0004000)
748#define RXMODE_TRASH (0)
749#define RXMODE_AAL0 (1)
750#define RXMODE_AAL5 (2)
751#define RXMODE_AAL5_STREAM (3)
752 vcc_rxaddr2 = 0x04,
753 vcc_rxcrc1 = 0x08,
754 vcc_rxcrc2 = 0x0C,
755 vcc_rxwriteptr = 0x10,
756#define RXWRITEPTR_LASTEFCI (0x00002000)
757#define RXWRITEPTR_DROPPING (0x00004000)
758#define RXWRITEPTR_TRASHING (0x00008000)
759 vcc_rxbufstart = 0x14,
760#define RXBUFSTART_CLP (0x00004000)
761#define RXBUFSTART_CI (0x00008000)
762 vcc_rxreadptr = 0x18,
763 vcc_txicg = 0x1C,
764 vcc_txaddr1 = 0x20,
765#define TXADDR1_SET_SIZE(x) ((x)*0x0000100)
766#define TXADDR1_ABR (0x00008000)
767 vcc_txaddr2 = 0x24,
768 vcc_txcrc1 = 0x28,
769 vcc_txcrc2 = 0x2C,
770 vcc_txreadptr = 0x30,
771#define TXREADPTR_GET_PTR(x) ((x)&0x01FFF)
772#define TXREADPTR_MASK_DELTA (0x0000E000)
773 vcc_txendptr = 0x34,
774#define TXENDPTR_CLP (0x00002000)
775#define TXENDPTR_MASK_PDUMODE (0x0000C000)
776#define PDUMODE_AAL0 (0*0x04000)
777#define PDUMODE_AAL5 (2*0x04000)
778#define PDUMODE_AAL5STREAM (3*0x04000)
779 vcc_txwriteptr = 0x38,
780#define TXWRITEPTR_GET_PTR(x) ((x)&0x1FFF)
781 vcc_txcbr_next = 0x3C
782#define TXCBR_NEXT_BOZO (0x00008000)
783};
784
785#define CARDVCC_SIZE (0x40)
786
787static inline bus_addr_t cardvcc_addr(const struct lanai_dev *lanai,
788 vci_t vci)
789{
790 return sram_addr(lanai, vci * CARDVCC_SIZE);
791}
792
793static inline u32 cardvcc_read(const struct lanai_vcc *lvcc,
794 enum lanai_vcc_offset offset)
795{
796 u32 val;
797 APRINTK(lvcc->vbase != 0, "cardvcc_read: unbound vcc!\n");
798 val= readl(lvcc->vbase + (bus_addr_t) offset);
799 RWDEBUG("VR vci=%04d 0x%02X = 0x%08X\n",
800 lvcc->vci, (int) offset, val);
801 return val;
802}
803
804static inline void cardvcc_write(const struct lanai_vcc *lvcc,
805 u32 val, enum lanai_vcc_offset offset)
806{
807 APRINTK(lvcc->vbase != 0, "cardvcc_write: unbound vcc!\n");
808 APRINTK((val & ~0xFFFF) == 0,
809 "cardvcc_write: bad val 0x%X (vci=%d, addr=0x%02X)\n",
810 val, lvcc->vci, (int) offset);
811 RWDEBUG("VW vci=%04d 0x%02X > 0x%08X\n",
812 lvcc->vci, (int) offset, val);
813 writel(val, lvcc->vbase + (bus_addr_t) offset);
814}
815
816
817
818
819
820
821
822static inline int aal5_size(int size)
823{
824 int cells = (size + 8 + 47) / 48;
825 return cells * 48;
826}
827
828
829
830
831static inline int aal5_spacefor(int space)
832{
833 int cells = space / 48;
834 return cells * 48;
835}
836
837
838
839static inline void lanai_free_skb(struct atm_vcc *atmvcc, struct sk_buff *skb)
840{
841 if (atmvcc->pop != NULL)
842 atmvcc->pop(atmvcc, skb);
843 else
844 dev_kfree_skb_any(skb);
845}
846
847
848
849static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
850{
851 u32 addr1;
852 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) {
853 unsigned long dmaaddr = lanai_buf_dmaaddr(&lvcc->rx.buf);
854 cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc1);
855 cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc2);
856 cardvcc_write(lvcc, 0, vcc_rxwriteptr);
857 cardvcc_write(lvcc, 0, vcc_rxbufstart);
858 cardvcc_write(lvcc, 0, vcc_rxreadptr);
859 cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_rxaddr2);
860 addr1 = ((dmaaddr >> 8) & 0xFF) |
861 RXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->rx.buf))|
862 RXADDR1_SET_RMMODE(RMMODE_TRASH) |
863
864 RXADDR1_SET_MODE(RXMODE_AAL5);
865 } else
866 addr1 = RXADDR1_SET_RMMODE(RMMODE_PRESERVE) |
867 RXADDR1_OAM_PRESERVE |
868 RXADDR1_SET_MODE(RXMODE_AAL0);
869
870 cardvcc_write(lvcc, addr1, vcc_rxaddr1);
871}
872
873static void host_vcc_start_tx(const struct lanai_vcc *lvcc)
874{
875 unsigned long dmaaddr = lanai_buf_dmaaddr(&lvcc->tx.buf);
876 cardvcc_write(lvcc, 0, vcc_txicg);
877 cardvcc_write(lvcc, 0xFFFF, vcc_txcrc1);
878 cardvcc_write(lvcc, 0xFFFF, vcc_txcrc2);
879 cardvcc_write(lvcc, 0, vcc_txreadptr);
880 cardvcc_write(lvcc, 0, vcc_txendptr);
881 cardvcc_write(lvcc, 0, vcc_txwriteptr);
882 cardvcc_write(lvcc,
883 (lvcc->tx.atmvcc->qos.txtp.traffic_class == ATM_CBR) ?
884 TXCBR_NEXT_BOZO | lvcc->vci : 0, vcc_txcbr_next);
885 cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_txaddr2);
886 cardvcc_write(lvcc,
887 ((dmaaddr >> 8) & 0xFF) |
888 TXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->tx.buf)),
889 vcc_txaddr1);
890}
891
892
893static void lanai_shutdown_rx_vci(const struct lanai_vcc *lvcc)
894{
895 if (lvcc->vbase == 0)
896 return;
897
898 cardvcc_write(lvcc,
899 RXADDR1_SET_RMMODE(RMMODE_TRASH) |
900 RXADDR1_SET_MODE(RXMODE_TRASH), vcc_rxaddr1);
901 udelay(15);
902
903 cardvcc_write(lvcc, 0, vcc_rxaddr2);
904 cardvcc_write(lvcc, 0, vcc_rxcrc1);
905 cardvcc_write(lvcc, 0, vcc_rxcrc2);
906 cardvcc_write(lvcc, 0, vcc_rxwriteptr);
907 cardvcc_write(lvcc, 0, vcc_rxbufstart);
908 cardvcc_write(lvcc, 0, vcc_rxreadptr);
909}
910
911
912
913
914
915
916
917
918static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
919 struct lanai_vcc *lvcc)
920{
921 struct sk_buff *skb;
922 unsigned long flags, timeout;
923 int read, write, lastread = -1;
924 APRINTK(!in_interrupt(),
925 "lanai_shutdown_tx_vci called w/o process context!\n");
926 if (lvcc->vbase == 0)
927 return;
928
929 spin_lock_irqsave(&lanai->txlock, flags);
930 if (lvcc->tx.inprogress != NULL) {
931 lanai_free_skb(lvcc->tx.atmvcc, lvcc->tx.inprogress);
932 lvcc->tx.inprogress = NULL;
933 }
934 while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
935 lanai_free_skb(lvcc->tx.atmvcc, skb);
936 vcc_unmark_backlogged(lanai, lvcc);
937 spin_unlock_irqrestore(&lanai->txlock, flags);
938 timeout = jiffies + ((lanai_buf_size(&lvcc->tx.buf) * HZ) >> 17);
939 write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
940 goto start;
941 while (time_before_eq(jiffies, timeout)) {
942 schedule_timeout(HZ / 25);
943 start:
944 read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
945 if (read == write &&
946 (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||
947 (cardvcc_read(lvcc, vcc_txcbr_next) &
948 TXCBR_NEXT_BOZO) == 0))
949 goto done;
950 if (read != lastread) {
951 lastread = read;
952 timeout += HZ / 10;
953 }
954 }
955 printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on backlog closing "
956 "vci %d\n", lvcc->tx.atmvcc->dev->number, lvcc->vci);
957 DPRINTK("read, write = %d, %d\n", read, write);
958 done:
959
960 cardvcc_write(lvcc, 0, vcc_txreadptr);
961 cardvcc_write(lvcc, 0, vcc_txwriteptr);
962 cardvcc_write(lvcc, 0, vcc_txendptr);
963 cardvcc_write(lvcc, 0, vcc_txcrc1);
964 cardvcc_write(lvcc, 0, vcc_txcrc2);
965 cardvcc_write(lvcc, 0, vcc_txaddr2);
966 cardvcc_write(lvcc, 0, vcc_txaddr1);
967}
968
969
970
971static inline int aal0_buffer_allocate(struct lanai_dev *lanai)
972{
973 DPRINTK("aal0_buffer_allocate: allocating AAL0 RX buffer\n");
974 lanai_buf_allocate(&lanai->aal0buf, AAL0_RX_BUFFER_SIZE, 80);
975 return (lanai->aal0buf.order < 0) ? -ENOMEM : 0;
976}
977
978static inline void aal0_buffer_free(struct lanai_dev *lanai)
979{
980 DPRINTK("aal0_buffer_allocate: freeing AAL0 RX buffer\n");
981 lanai_buf_deallocate(&lanai->aal0buf);
982}
983
984
985
986
987#define EEPROM_COPYRIGHT (0)
988#define EEPROM_COPYRIGHT_LEN (44)
989#define EEPROM_CHECKSUM (62)
990#define EEPROM_CHECKSUM_REV (63)
991#define EEPROM_MAC (64)
992#define EEPROM_MAC_REV (70)
993#define EEPROM_SERIAL (112)
994#define EEPROM_SERIAL_REV (116)
995#define EEPROM_MAGIC (120)
996#define EEPROM_MAGIC_REV (124)
997
998#define EEPROM_MAGIC_VALUE (0x5AB478D2)
999
1000#ifndef READ_EEPROM
1001
1002
1003static int __init eeprom_read(struct lanai_dev *lanai)
1004{
1005 printk(KERN_INFO DEV_LABEL "(itf %d): *NOT* reading EEPROM\n",
1006 lanai->number);
1007 memset(&lanai->eeprom[EEPROM_MAC], 0, 6);
1008 return 0;
1009}
1010
1011static int __init eeprom_validate(struct lanai_dev *lanai)
1012{
1013 lanai->serialno = 0;
1014 lanai->magicno = EEPROM_MAGIC_VALUE;
1015 return 0;
1016}
1017
1018#else
1019
1020static int __init eeprom_read(struct lanai_dev *lanai)
1021{
1022 int i, address;
1023 u8 data;
1024 u32 tmp;
1025#define set_config1(x) do { lanai->conf1 = x; conf1_write(lanai); \
1026 } while (0)
1027#define clock_h() set_config1(lanai->conf1 | CONFIG1_PROMCLK)
1028#define clock_l() set_config1(lanai->conf1 &~ CONFIG1_PROMCLK)
1029#define data_h() set_config1(lanai->conf1 | CONFIG1_PROMDATA)
1030#define data_l() set_config1(lanai->conf1 &~ CONFIG1_PROMDATA)
1031#define pre_read() do { data_h(); clock_h(); udelay(5); } while (0)
1032#define read_pin() (reg_read(lanai, Status_Reg) & STATUS_PROMDATA)
1033#define send_stop() do { data_l(); udelay(5); clock_h(); udelay(5); \
1034 data_h(); udelay(5); } while (0)
1035
1036 data_h(); clock_h(); udelay(5);
1037 for (address = 0; address < LANAI_EEPROM_SIZE; address++) {
1038 data = (address << 1) | 1;
1039
1040 data_l(); udelay(5);
1041 clock_l(); udelay(5);
1042 for (i = 128; i != 0; i >>= 1) {
1043 tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
1044 (data & i) ? CONFIG1_PROMDATA : 0;
1045 if (lanai->conf1 != tmp) {
1046 set_config1(tmp);
1047 udelay(5);
1048 }
1049 clock_h(); udelay(5); clock_l(); udelay(5);
1050 }
1051
1052 data_h(); clock_h(); udelay(5);
1053 if (read_pin() != 0)
1054 goto error;
1055 clock_l(); udelay(5);
1056
1057 for (data = 0, i = 7; i >= 0; i--) {
1058 data_h(); clock_h(); udelay(5);
1059 data = (data << 1) | !!read_pin();
1060 clock_l(); udelay(5);
1061 }
1062
1063 data_h(); clock_h(); udelay(5);
1064 if (read_pin() == 0)
1065 goto error;
1066 clock_l(); udelay(5);
1067 send_stop();
1068 lanai->eeprom[address] = data;
1069 DPRINTK("EEPROM 0x%04X %02X\n", address, data);
1070 }
1071 return 0;
1072 error:
1073 clock_l(); udelay(5);
1074 send_stop();
1075 printk(KERN_ERR DEV_LABEL "(itf %d): error reading EEPROM byte %d\n",
1076 lanai->number, address);
1077 return -EIO;
1078#undef set_config1
1079#undef clock_h
1080#undef clock_l
1081#undef data_h
1082#undef data_l
1083#undef pre_read
1084#undef read_pin
1085#undef send_stop
1086}
1087
1088
1089static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)
1090{
1091 return be32_to_cpup((u32 *) (&lanai->eeprom[address]));
1092}
1093
1094
1095static int __init eeprom_validate(struct lanai_dev *lanai)
1096{
1097 int i, s;
1098 u32 v;
1099 const u8 *e = lanai->eeprom;
1100#ifdef DEBUG
1101
1102 for (i = EEPROM_COPYRIGHT;
1103 i < (EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN); i++)
1104 if (e[i] < 0x20 || e[i] > 0x7E)
1105 break;
1106 if ( i != EEPROM_COPYRIGHT &&
1107 i != EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN && e[i] == '\0')
1108 DPRINTK("eeprom: copyright = \"%s\"\n",
1109 (char *) &e[EEPROM_COPYRIGHT]);
1110 else
1111 DPRINTK("eeprom: copyright not found\n");
1112#endif
1113
1114 for (i = s = 0; i < EEPROM_CHECKSUM; i++)
1115 s += e[i];
1116 s &= 0xFF;
1117 if (s != e[EEPROM_CHECKSUM]) {
1118 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM checksum bad "
1119 "(wanted 0x%02X, got 0x%02X)\n", lanai->number,
1120 s, e[EEPROM_CHECKSUM]);
1121 return -EIO;
1122 }
1123 s ^= 0xFF;
1124 if (s != e[EEPROM_CHECKSUM_REV]) {
1125 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM inverse checksum "
1126 "bad (wanted 0x%02X, got 0x%02X)\n", lanai->number,
1127 s, e[EEPROM_CHECKSUM_REV]);
1128 return -EIO;
1129 }
1130
1131 for (i = 0; i < 6; i++)
1132 if ((e[EEPROM_MAC + i] ^ e[EEPROM_MAC_REV + i]) != 0xFF) {
1133 printk(KERN_ERR DEV_LABEL
1134 "(itf %d) : EEPROM MAC addresses don't match "
1135 "(0x%02X, inverse 0x%02X)\n", lanai->number,
1136 e[EEPROM_MAC + i], e[EEPROM_MAC_REV + i]);
1137 return -EIO;
1138 }
1139 DPRINTK("eeprom: MAC address = %02X:%02X:%02X:%02X:%02X:%02X\n",
1140 e[EEPROM_MAC + 0], e[EEPROM_MAC + 1], e[EEPROM_MAC + 2],
1141 e[EEPROM_MAC + 3], e[EEPROM_MAC + 4], e[EEPROM_MAC + 5]);
1142
1143 lanai->serialno = eeprom_be4(lanai, EEPROM_SERIAL);
1144 v = eeprom_be4(lanai, EEPROM_SERIAL_REV);
1145 if ((lanai->serialno ^ v) != 0xFFFFFFFF) {
1146 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM serial numbers "
1147 "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
1148 lanai->serialno, v);
1149 return -EIO;
1150 }
1151 DPRINTK("eeprom: Serial number = %d\n", lanai->serialno);
1152
1153 lanai->magicno = eeprom_be4(lanai, EEPROM_MAGIC);
1154 v = eeprom_be4(lanai, EEPROM_MAGIC_REV);
1155 if ((lanai->magicno ^ v) != 0xFFFFFFFF) {
1156 printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM magic numbers "
1157 "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
1158 lanai->magicno, v);
1159 return -EIO;
1160 }
1161 DPRINTK("eeprom: Magic number = 0x%08X\n", lanai->magicno);
1162 if (lanai->magicno != EEPROM_MAGIC_VALUE)
1163 printk(KERN_WARNING DEV_LABEL "(itf %d): warning - EEPROM "
1164 "magic not what expected (got 0x%08X, not 0x%08X)\n",
1165 lanai->number, lanai->magicno, EEPROM_MAGIC_VALUE);
1166 return 0;
1167}
1168
1169#endif
1170
1171static inline const u8 *eeprom_mac(const struct lanai_dev *lanai)
1172{
1173 return &lanai->eeprom[EEPROM_MAC];
1174}
1175
1176
1177
1178
1179#define INT_STATS (0x00000002)
1180#define INT_SOOL (0x00000004)
1181#define INT_LOCD (0x00000008)
1182#define INT_LED (0x00000010)
1183#define INT_GPIN (0x00000020)
1184#define INT_PING (0x00000040)
1185#define INT_WAKE (0x00000080)
1186#define INT_CBR0 (0x00000100)
1187#define INT_LOCK (0x00000200)
1188#define INT_MISMATCH (0x00000400)
1189#define INT_AAL0_STR (0x00000800)
1190#define INT_AAL0 (0x00001000)
1191#define INT_SERVICE (0x00002000)
1192#define INT_TABORTSENT (0x00004000)
1193#define INT_TABORTBM (0x00008000)
1194#define INT_TIMEOUTBM (0x00010000)
1195#define INT_PCIPARITY (0x00020000)
1196
1197
1198#define INT_ALL (0x0003FFFE)
1199#define INT_STATUS (0x0000003C)
1200#define INT_DMASHUT (0x00038000)
1201#define INT_SEGSHUT (0x00000700)
1202
1203static inline u32 intr_pending(const struct lanai_dev *lanai)
1204{
1205 return reg_read(lanai, IntStatusMasked_Reg);
1206}
1207
1208static inline void intr_enable(const struct lanai_dev *lanai, u32 i)
1209{
1210 reg_write(lanai, i, IntControlEna_Reg);
1211}
1212
1213static inline void intr_disable(const struct lanai_dev *lanai, u32 i)
1214{
1215 reg_write(lanai, i, IntControlDis_Reg);
1216}
1217
1218
1219
1220static void status_message(int itf, const char *name, int status)
1221{
1222 static const char *onoff[2] = { "off to on", "on to off" };
1223 printk(KERN_INFO DEV_LABEL "(itf %d): %s changed from %s\n",
1224 itf, name, onoff[!status]);
1225}
1226
1227static void lanai_check_status(struct lanai_dev *lanai)
1228{
1229 u32 new = reg_read(lanai, Status_Reg);
1230 u32 changes = new ^ lanai->status;
1231 lanai->status = new;
1232#define e(flag, name) \
1233 if (changes & flag) \
1234 status_message(lanai->number, name, new & flag)
1235 e(STATUS_SOOL, "SOOL");
1236 e(STATUS_LOCD, "LOCD");
1237 e(STATUS_LED, "LED");
1238 e(STATUS_GPIN, "GPIN");
1239#undef e
1240}
1241
1242static void pcistatus_got(int itf, const char *name)
1243{
1244 printk(KERN_INFO DEV_LABEL "(itf %d): PCI got %s error\n", itf, name);
1245}
1246
1247static void pcistatus_check(struct lanai_dev *lanai, int clearonly)
1248{
1249 u16 s;
1250 int result;
1251 result = pci_read_config_word(lanai->pci, PCI_STATUS, &s);
1252 if (result != PCIBIOS_SUCCESSFUL) {
1253 printk(KERN_ERR DEV_LABEL "(itf %d): can't read PCI_STATUS: "
1254 "%d\n", lanai->number, result);
1255 return;
1256 }
1257 s &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
1258 PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT |
1259 PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_PARITY;
1260 if (s == 0)
1261 return;
1262 result = pci_write_config_word(lanai->pci, PCI_STATUS, s);
1263 if (result != PCIBIOS_SUCCESSFUL)
1264 printk(KERN_ERR DEV_LABEL "(itf %d): can't write PCI_STATUS: "
1265 "%d\n", lanai->number, result);
1266 if (clearonly)
1267 return;
1268#define e(flag, name, stat) \
1269 if (s & flag) { \
1270 pcistatus_got(lanai->number, name); \
1271 ++lanai->stats.pcierr_##stat; \
1272 }
1273 e(PCI_STATUS_DETECTED_PARITY, "parity", parity_detect);
1274 e(PCI_STATUS_SIG_SYSTEM_ERROR, "signalled system", serr_set);
1275 e(PCI_STATUS_REC_MASTER_ABORT, "master", master_abort);
1276 e(PCI_STATUS_REC_TARGET_ABORT, "master target", m_target_abort);
1277 e(PCI_STATUS_SIG_TARGET_ABORT, "slave", s_target_abort);
1278 e(PCI_STATUS_PARITY, "master parity", master_parity);
1279#undef e
1280}
1281
1282
1283
1284
1285static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
1286{
1287 int r;
1288 r = endptr * 16;
1289 r -= ((unsigned long) lvcc->tx.buf.ptr) -
1290 ((unsigned long) lvcc->tx.buf.start);
1291 r -= 16;
1292 if (r < 0)
1293 r += lanai_buf_size(&lvcc->tx.buf);
1294 return r;
1295}
1296
1297
1298#define DESCRIPTOR_MAGIC (0xD0000000)
1299#define DESCRIPTOR_AAL5 (0x00008000)
1300#define DESCRIPTOR_AAL5_STREAM (0x00004000)
1301#define DESCRIPTOR_CLP (0x00002000)
1302
1303
1304static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
1305 u32 flags, int len)
1306{
1307 int pos;
1308 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 0,
1309 "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
1310 lvcc->tx.buf.ptr += 4;
1311 pos = ((unsigned char *) lvcc->tx.buf.ptr) -
1312 (unsigned char *) lvcc->tx.buf.start;
1313 APRINTK((pos & ~0x0001FFF0) == 0,
1314 "vcc_tx_add_aal5_descriptor: bad pos (%d) before, vci=%d, "
1315 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
1316 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
1317 pos = (pos + len) & (lanai_buf_size(&lvcc->tx.buf) - 1);
1318 APRINTK((pos & ~0x0001FFF0) == 0,
1319 "vcc_tx_add_aal5_descriptor: bad pos (%d) after, vci=%d, "
1320 "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
1321 lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
1322 lvcc->tx.buf.ptr[-1] =
1323 cpu_to_le32(DESCRIPTOR_MAGIC | DESCRIPTOR_AAL5 |
1324 ((lvcc->tx.atmvcc->atm_options & ATM_ATMOPT_CLP) ?
1325 DESCRIPTOR_CLP : 0) | flags | pos >> 4);
1326 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
1327 lvcc->tx.buf.ptr = lvcc->tx.buf.start;
1328}
1329
1330
1331static inline void vcc_tx_add_aal5trailer(struct lanai_vcc *lvcc,
1332 int len, int cpi, int uu)
1333{
1334 APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,
1335 "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
1336 lvcc->tx.buf.ptr += 2;
1337 lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);
1338 if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
1339 lvcc->tx.buf.ptr = lvcc->tx.buf.start;
1340}
1341
1342static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,
1343 const unsigned char *src, int n)
1344{
1345 unsigned char *e;
1346 int m;
1347 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
1348 m = e - (unsigned char *) lvcc->tx.buf.end;
1349 if (m < 0)
1350 m = 0;
1351 memcpy(lvcc->tx.buf.ptr, src, n - m);
1352 if (m != 0) {
1353 memcpy(lvcc->tx.buf.start, src + n - m, m);
1354 e = ((unsigned char *) lvcc->tx.buf.start) + m;
1355 }
1356 lvcc->tx.buf.ptr = (u32 *) e;
1357}
1358
1359static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
1360{
1361 unsigned char *e;
1362 int m;
1363 if (n == 0)
1364 return;
1365 e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
1366 m = e - (unsigned char *) lvcc->tx.buf.end;
1367 if (m < 0)
1368 m = 0;
1369 memset(lvcc->tx.buf.ptr, 0, n - m);
1370 if (m != 0) {
1371 memset(lvcc->tx.buf.start, 0, m);
1372 e = ((unsigned char *) lvcc->tx.buf.start) + m;
1373 }
1374 lvcc->tx.buf.ptr = (u32 *) e;
1375}
1376
1377
1378static inline void lanai_endtx(const struct lanai_dev *lanai,
1379 const struct lanai_vcc *lvcc)
1380{
1381 int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -
1382 (unsigned char *) lvcc->tx.buf.start;
1383 APRINTK((ptr & ~0x0001FFF0) == 0,
1384 "lanai_endtx: bad ptr (%d), vci=%d, start,ptr,end=%p,%p,%p\n",
1385 ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,
1386 lvcc->tx.buf.end);
1387
1388
1389
1390
1391
1392
1393 for (i = 0; reg_read(lanai, Status_Reg) & STATUS_BUTTBUSY; i++) {
1394 if (i > 50) {
1395 printk(KERN_ERR DEV_LABEL "(itf %d): butt register "
1396 "always busy!\n", lanai->number);
1397 break;
1398 }
1399 udelay(5);
1400 }
1401 reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);
1402}
1403
1404
1405static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,
1406 struct lanai_vcc *lvcc, int endptr)
1407{
1408 int pad, n;
1409 struct sk_buff *skb;
1410 int space = vcc_tx_space(lvcc, endptr);
1411 APRINTK(vcc_is_backlogged(lvcc),
1412 "vcc_tx_unqueue() called with empty backlog (vci=%d)\n",
1413 lvcc->vci);
1414 if (space < 64)
1415 return;
1416 if (lvcc->tx.inprogress != NULL) {
1417 APRINTK((lvcc->tx.inprogleft % 48) == 0,
1418 "vcc_tx_unqueue_aal5: bad progleft=%d\n",
1419 lvcc->tx.inprogleft);
1420 if (lvcc->tx.inprogleft + 16 > space) {
1421 n = aal5_spacefor(space - 16);
1422 vcc_tx_add_aal5_descriptor(lvcc,
1423 DESCRIPTOR_AAL5_STREAM, n);
1424 pad = lvcc->tx.pptr + n - lvcc->tx.inprogress->tail;
1425 if (pad < 0)
1426 pad = 0;
1427 vcc_tx_memcpy(lvcc, lvcc->tx.pptr, n - pad);
1428 vcc_tx_memzero(lvcc, pad);
1429 lvcc->tx.pptr += n;
1430 lvcc->tx.inprogleft -= n;
1431 goto end;
1432 }
1433
1434 vcc_tx_add_aal5_descriptor(lvcc, 0,
1435 lvcc->tx.inprogleft);
1436 pad = lvcc->tx.pptr + lvcc->tx.inprogleft -
1437 lvcc->tx.inprogress->tail;
1438 if (pad >= lvcc->tx.inprogleft) {
1439 APRINTK(lvcc->tx.inprogleft == 48,
1440 "vcc_tx_unqueue_aal5: bad pure-pad=%d\n",
1441 lvcc->tx.inprogleft);
1442 pad = 48;
1443 } else
1444 vcc_tx_memcpy(lvcc, lvcc->tx.pptr,
1445 lvcc->tx.inprogleft - pad);
1446 vcc_tx_memzero(lvcc, pad - 8);
1447 vcc_tx_add_aal5trailer(lvcc, lvcc->tx.inprogress->len, 0, 0);
1448 lanai_free_skb(lvcc->tx.atmvcc, lvcc->tx.inprogress);
1449 lvcc->tx.inprogress = NULL;
1450 space -= lvcc->tx.inprogleft + 16;
1451 atomic_inc(&lvcc->tx.atmvcc->stats->tx);
1452 }
1453 while (space >= 64) {
1454 if ((skb = skb_dequeue(&lvcc->tx.backlog)) == NULL)
1455 break;
1456 n = aal5_size(skb->len);
1457 if (n + 16 > space) {
1458 int m = aal5_spacefor(space - 16);
1459 vcc_tx_add_aal5_descriptor(lvcc,
1460 DESCRIPTOR_AAL5_STREAM, m);
1461 lvcc->tx.pptr = skb->data + m;
1462 pad = lvcc->tx.pptr - skb->tail;
1463 if (pad < 0)
1464 pad = 0;
1465 vcc_tx_memcpy(lvcc, skb->data, m - pad);
1466 vcc_tx_memzero(lvcc, pad);
1467 lvcc->tx.inprogleft = n - m;
1468 lvcc->tx.inprogress = skb;
1469 goto end;
1470 }
1471 vcc_tx_add_aal5_descriptor(lvcc, 0, n);
1472 pad = n - skb->len - 8;
1473 vcc_tx_memcpy(lvcc, skb->data, skb->len);
1474 vcc_tx_memzero(lvcc, pad);
1475 lanai_free_skb(lvcc->tx.atmvcc, skb);
1476 vcc_tx_add_aal5trailer(lvcc, skb->len, 0, 0);
1477 space -= n + 16;
1478 atomic_inc(&lvcc->tx.atmvcc->stats->tx);
1479 }
1480 if (skb_queue_empty(&lvcc->tx.backlog))
1481 vcc_unmark_backlogged(lanai, lvcc);
1482 end:
1483 lanai_endtx(lanai, lvcc);
1484}
1485
1486
1487static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1488 struct sk_buff *skb)
1489{
1490 int space, n, pad;
1491 if (vcc_is_backlogged(lvcc))
1492 goto queue_it;
1493 space = vcc_tx_space(lvcc, TXREADPTR_GET_PTR(cardvcc_read(lvcc,
1494 vcc_txreadptr)));
1495 if (space < 64) {
1496 vcc_mark_backlogged(lanai, lvcc);
1497 goto queue_it;
1498 }
1499 if (space >= 16 + (n = aal5_size(skb->len))) {
1500
1501 vcc_tx_add_aal5_descriptor(lvcc, 0, n);
1502 pad = n - skb->len;
1503 vcc_tx_memcpy(lvcc, skb->data, skb->len);
1504 vcc_tx_memzero(lvcc, pad - 8);
1505 vcc_tx_add_aal5trailer(lvcc, skb->len, 0, 0);
1506 lanai_free_skb(lvcc->tx.atmvcc, skb);
1507 atomic_inc(&lvcc->tx.atmvcc->stats->tx);
1508 } else {
1509 int bytes = aal5_spacefor(space - 16);
1510 vcc_tx_add_aal5_descriptor(lvcc,
1511 DESCRIPTOR_AAL5_STREAM, bytes);
1512 pad = bytes - skb->len;
1513 if (pad < 0)
1514 pad = 0;
1515 vcc_tx_memcpy(lvcc, skb->data, bytes - pad);
1516 vcc_tx_memzero(lvcc, pad);
1517 lvcc->tx.inprogress = skb;
1518 lvcc->tx.inprogleft = n - bytes;
1519 lvcc->tx.pptr = skb->data + bytes;
1520 vcc_mark_backlogged(lanai, lvcc);
1521 }
1522 lanai_endtx(lanai, lvcc);
1523 return;
1524 queue_it:
1525 skb_queue_tail(&lvcc->tx.backlog, skb);
1526}
1527
1528static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai,
1529 struct lanai_vcc *lvcc, int endptr)
1530{
1531 printk(KERN_INFO DEV_LABEL
1532 ": vcc_tx_unqueue_aal0: not implemented\n");
1533}
1534
1535static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
1536 struct sk_buff *skb)
1537{
1538 printk(KERN_INFO DEV_LABEL ": vcc_tx_aal0: not implemented\n");
1539
1540 lanai_free_skb(lvcc->tx.atmvcc, skb);
1541}
1542
1543
1544static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
1545{
1546 struct lanai_vcc *lvcc = lanai->vccs[vci];
1547 int endptr;
1548 if (lvcc == NULL || !vcc_is_backlogged(lvcc)) {
1549 vci_bitfield_clear(&lanai->backlog_vccs, vci);
1550 return;
1551 }
1552 endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
1553 lvcc->tx.unqueue(lanai, lvcc, endptr);
1554}
1555
1556
1557static inline void vcc_tx_dequeue_all(struct lanai_dev *lanai)
1558{
1559 unsigned long flags;
1560 spin_lock_irqsave(&lanai->txlock, flags);
1561 vci_bitfield_iterate(lanai, &lanai->backlog_vccs, iter_dequeue);
1562 spin_unlock_irqrestore(&lanai->txlock, flags);
1563}
1564
1565
1566
1567
1568static inline void vcc_rx_memcpy(unsigned char *dest,
1569 const struct lanai_vcc *lvcc, int n)
1570{
1571 int m = ((const unsigned char *) lvcc->rx.buf.ptr) + n -
1572 ((const unsigned char *) (lvcc->rx.buf.end));
1573 if (m < 0)
1574 m = 0;
1575 memcpy(dest, lvcc->rx.buf.ptr, n - m);
1576 memcpy(dest + n - m, lvcc->rx.buf.start, m);
1577}
1578
1579
1580static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
1581{
1582 int size;
1583 struct sk_buff *skb;
1584 u32 *x, *end = &lvcc->rx.buf.start[endptr * 4];
1585 int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
1586 if (n < 0)
1587 n += lanai_buf_size(&lvcc->rx.buf);
1588 APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15),
1589 "vcc_rx_aal5: n out of range (%d/%d)\n",
1590 n, lanai_buf_size(&lvcc->rx.buf));
1591
1592 if ((x = &end[-2]) < lvcc->rx.buf.start)
1593 x = &lvcc->rx.buf.end[-2];
1594 size = be32_to_cpup(x) & 0xffff;
1595 if (n != aal5_size(size)) {
1596 printk(KERN_INFO DEV_LABEL "(itf %d): Got bad AAL5 length "
1597 "on vci=%d - size=%d n=%d\n",
1598 lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n);
1599 lvcc->stats.x.aal5.rx_badlen++;
1600 goto out;
1601 }
1602 skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC);
1603 if (skb == NULL) {
1604 lvcc->stats.rx_nomem++;
1605 goto out;
1606 }
1607 skb_put(skb, size);
1608 ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
1609 skb->stamp = xtime;
1610 vcc_rx_memcpy(skb->data, lvcc, size);
1611 lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
1612 atomic_inc(&lvcc->rx.atmvcc->stats->rx);
1613 out:
1614 lvcc->rx.buf.ptr = end;
1615 cardvcc_write(lvcc, endptr, vcc_rxreadptr);
1616}
1617
1618static void vcc_rx_aal0(struct lanai_dev *lanai)
1619{
1620 printk(KERN_INFO DEV_LABEL ": vcc_rx_aal0: not implemented\n");
1621
1622
1623}
1624
1625
1626
1627
1628#if (NUM_VCI * BITS_PER_LONG) <= PAGE_SIZE
1629#define VCCTABLE_GETFREEPAGE
1630#else
1631#include <linux/vmalloc.h>
1632#endif
1633
1634static int __init vcc_table_allocate(struct lanai_dev *lanai)
1635{
1636#ifdef VCCTABLE_GETFREEPAGE
1637 APRINTK((lanai->num_vci) * sizeof(struct lanai_vcc *) <= PAGE_SIZE,
1638 "vcc table > PAGE_SIZE!");
1639 lanai->vccs = (struct lanai_vcc **) get_free_page(GFP_KERNEL);
1640 return (lanai->vccs == NULL) ? -ENOMEM : 0;
1641#else
1642 int bytes = (lanai->num_vci) * sizeof(struct lanai_vcc *);
1643 lanai->vccs = (struct lanai_vcc **) vmalloc(bytes);
1644 if (lanai->vccs == NULL)
1645 return -ENOMEM;
1646 memset(lanai->vccs, 0, bytes);
1647 return 0;
1648#endif
1649}
1650
1651static inline void vcc_table_deallocate(const struct lanai_dev *lanai)
1652{
1653#ifdef VCCTABLE_GETFREEPAGE
1654 free_page((unsigned long) lanai->vccs);
1655#else
1656 vfree(lanai->vccs);
1657#endif
1658}
1659
1660
1661static inline struct lanai_vcc *new_lanai_vcc(void)
1662{
1663 struct lanai_vcc *lvcc;
1664 lvcc = (struct lanai_vcc *) kmalloc(sizeof(*lvcc), GFP_KERNEL);
1665 if (lvcc != NULL) {
1666 lvcc->vbase = 0;
1667 lvcc->rx.atmvcc = lvcc->tx.atmvcc = NULL;
1668 lvcc->nref = 0;
1669 memset(&lvcc->stats, 0, sizeof lvcc->stats);
1670 lvcc->rx.buf.start = lvcc->tx.buf.start = NULL;
1671 skb_queue_head_init(&lvcc->tx.backlog);
1672 lvcc->tx.inprogress = NULL;
1673#ifdef DEBUG
1674 lvcc->tx.unqueue = NULL;
1675 lvcc->vci = -1;
1676#endif
1677 }
1678 return lvcc;
1679}
1680
1681static int lanai_get_sized_buffer(int number, struct lanai_buffer *buf,
1682 int max_sdu, int multiplier, int min, const char *name)
1683{
1684 int size;
1685 if (max_sdu < 1)
1686 max_sdu = 1;
1687 max_sdu = aal5_size(max_sdu);
1688 size = (max_sdu + 16) * multiplier + 16;
1689 lanai_buf_allocate(buf, size, min);
1690 if (buf->order < 0)
1691 return -ENOMEM;
1692 if (lanai_buf_size(buf) < size)
1693 printk(KERN_WARNING DEV_LABEL "(itf %d): wanted %d bytes "
1694 "for %s buffer, got only %d\n", number, size, name,
1695 lanai_buf_size(buf));
1696 DPRINTK("Allocated %d byte %s buffer\n", lanai_buf_size(buf), name);
1697 return 0;
1698}
1699
1700
1701static inline int lanai_setup_rx_vci_aal5(int number, struct lanai_vcc *lvcc,
1702 const struct atm_qos *qos)
1703{
1704 return lanai_get_sized_buffer(number, &lvcc->rx.buf,
1705 qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, qos->rxtp.max_sdu + 32,
1706 "RX");
1707}
1708
1709
1710static int lanai_setup_tx_vci(int number, struct lanai_vcc *lvcc,
1711 const struct atm_qos *qos)
1712{
1713 int max_sdu, multiplier;
1714 if (qos->aal == ATM_AAL0) {
1715 lvcc->tx.unqueue = vcc_tx_unqueue_aal0;
1716 max_sdu = ATM_CELL_SIZE - 1;
1717 multiplier = AAL0_TX_MULTIPLIER;
1718 } else {
1719 lvcc->tx.unqueue = vcc_tx_unqueue_aal5;
1720 max_sdu = qos->txtp.max_sdu;
1721 multiplier = AAL5_TX_MULTIPLIER;
1722 }
1723 return lanai_get_sized_buffer(number, &lvcc->tx.buf, max_sdu,
1724 multiplier, 80, "TX");
1725}
1726
1727static inline void host_vcc_bind(struct lanai_dev *lanai,
1728 struct lanai_vcc *lvcc, vci_t vci)
1729{
1730 if (lvcc->vbase != 0)
1731 return;
1732 DPRINTK("Binding vci %d\n", vci);
1733#ifdef USE_POWERDOWN
1734 if (lanai->nbound++ == 0) {
1735 DPRINTK("Coming out of powerdown\n");
1736 lanai->conf1 &= ~CONFIG1_POWERDOWN;
1737 conf1_write(lanai);
1738 conf2_write(lanai);
1739 }
1740#endif
1741 lvcc->vbase = cardvcc_addr(lanai, vci);
1742 lanai->vccs[lvcc->vci = vci] = lvcc;
1743}
1744
1745static inline void host_vcc_unbind(struct lanai_dev *lanai,
1746 struct lanai_vcc *lvcc)
1747{
1748 if (lvcc->vbase == 0)
1749 return;
1750 DPRINTK("Unbinding vci %d\n", lvcc->vci);
1751 lvcc->vbase = 0;
1752 lanai->vccs[lvcc->vci] = NULL;
1753#ifdef USE_POWERDOWN
1754 if (--lanai->nbound == 0) {
1755 DPRINTK("Going into powerdown\n");
1756 lanai->conf1 |= CONFIG1_POWERDOWN;
1757 conf1_write(lanai);
1758 }
1759#endif
1760}
1761
1762
1763
1764static void lanai_reset(struct lanai_dev *lanai)
1765{
1766 printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* reseting - not "
1767 "implemented\n", lanai->number);
1768
1769
1770
1771
1772
1773 reg_write(lanai, INT_ALL, IntAck_Reg);
1774 lanai->stats.card_reset++;
1775}
1776
1777
1778
1779
1780
1781
1782static int __init service_buffer_allocate(struct lanai_dev *lanai)
1783{
1784 lanai_buf_allocate(&lanai->service, SERVICE_ENTRIES * 4, 0);
1785 if (lanai->service.order < 0)
1786 return -ENOMEM;
1787 DPRINTK("allocated service buffer at 0x%08lX, size %d(%d)\n",
1788 (unsigned long) lanai->service.start,
1789 lanai_buf_size(&lanai->service),
1790 lanai_buf_size_cardorder(&lanai->service));
1791
1792 reg_write(lanai, 0, ServWrite_Reg);
1793
1794 reg_write(lanai,
1795 SSTUFF_SET_SIZE(lanai_buf_size_cardorder(&lanai->service)) |
1796 SSTUFF_SET_ADDR(lanai_buf_dmaaddr(&lanai->service)),
1797 ServiceStuff_Reg);
1798 return 0;
1799}
1800
1801static inline void service_buffer_deallocate(struct lanai_dev *lanai)
1802{
1803 lanai_buf_deallocate(&lanai->service);
1804}
1805
1806
1807#define SERVICE_TX (0x80000000)
1808#define SERVICE_TRASH (0x40000000)
1809#define SERVICE_CRCERR (0x20000000)
1810#define SERVICE_CI (0x10000000)
1811#define SERVICE_CLP (0x08000000)
1812#define SERVICE_STREAM (0x04000000)
1813#define SERVICE_GET_VCI(x) (((x)>>16)&0x3FF)
1814#define SERVICE_GET_END(x) ((x)&0x1FFF)
1815
1816
1817
1818
1819static int handle_service(struct lanai_dev *lanai, u32 s)
1820{
1821 vci_t vci = SERVICE_GET_VCI(s);
1822 struct lanai_vcc *lvcc;
1823 vcclist_read_lock();
1824 lvcc = lanai->vccs[vci];
1825 if (lvcc == NULL) {
1826 vcclist_read_unlock();
1827 DPRINTK("(itf %d) got service entry 0x%X for nonexistent "
1828 "vcc %d\n", lanai->number, s, vci);
1829 if (s & SERVICE_TX)
1830 lanai->stats.service_novcc_tx++;
1831 else
1832 lanai->stats.service_novcc_rx++;
1833 return 0;
1834 }
1835 if (s & SERVICE_TX) {
1836 if (lvcc->tx.atmvcc == NULL) {
1837 vcclist_read_unlock();
1838 DPRINTK("(itf %d) got service entry 0x%X for non-TX "
1839 "vcc %d\n", lanai->number, s, vci);
1840 lanai->stats.service_notx++;
1841 return 0;
1842 }
1843 vci_bitfield_set(&lanai->transmit_ready, vci);
1844 lvcc->tx.endptr = SERVICE_GET_END(s);
1845 vcclist_read_unlock();
1846 return 1;
1847 }
1848 if (lvcc->rx.atmvcc == NULL) {
1849 vcclist_read_unlock();
1850 DPRINTK("(itf %d) got service entry 0x%X for non-RX "
1851 "vcc %d\n", lanai->number, s, vci);
1852 lanai->stats.service_norx++;
1853 return 0;
1854 }
1855 if (lvcc->rx.atmvcc->qos.aal != ATM_AAL5) {
1856 vcclist_read_unlock();
1857 DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
1858 "vcc %d\n", lanai->number, s, vci);
1859 lanai->stats.service_rxnotaal5++;
1860 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1861 return 0;
1862 }
1863 if ((s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)) == 0) {
1864 vcc_rx_aal5(lvcc, SERVICE_GET_END(s));
1865 vcclist_read_unlock();
1866 return 0;
1867 }
1868 if (s & SERVICE_TRASH) {
1869 int bytes;
1870 vcclist_read_unlock();
1871 DPRINTK("got trashed rx pdu on vci %d\n", vci);
1872 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1873 lvcc->stats.x.aal5.service_trash++;
1874 bytes = (SERVICE_GET_END(s) * 16) -
1875 (((unsigned long) lvcc->rx.buf.ptr) -
1876 ((unsigned long) lvcc->rx.buf.start)) + 47;
1877 if (bytes < 0)
1878 bytes += lanai_buf_size(&lvcc->rx.buf);
1879 lanai->stats.ovfl_trash += (bytes / 48);
1880 return 0;
1881 }
1882 if (s & SERVICE_STREAM) {
1883 vcclist_read_unlock();
1884 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1885 lvcc->stats.x.aal5.service_stream++;
1886 printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
1887 "PDU on VCI %d!\n", lanai->number, vci);
1888 lanai_reset(lanai);
1889 return 0;
1890 }
1891 DPRINTK("got rx crc error on vci %d\n", vci);
1892 atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
1893 lvcc->stats.x.aal5.service_rxcrc++;
1894 lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
1895 cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
1896 vcclist_read_unlock();
1897 return 0;
1898}
1899
1900
1901static void iter_transmit(struct lanai_dev *lanai, vci_t vci)
1902{
1903 struct lanai_vcc *lvcc = lanai->vccs[vci];
1904 if (!vcc_is_backlogged(lvcc))
1905 return;
1906 lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
1907}
1908
1909
1910
1911
1912
1913static void run_service(struct lanai_dev *lanai)
1914{
1915 int ntx = 0;
1916 u32 wreg = reg_read(lanai, ServWrite_Reg);
1917 const u32 *end = lanai->service.start + wreg;
1918 while (lanai->service.ptr != end) {
1919 ntx += handle_service(lanai,
1920 le32_to_cpup(lanai->service.ptr++));
1921 if (lanai->service.ptr >= lanai->service.end)
1922 lanai->service.ptr = lanai->service.start;
1923 }
1924 reg_write(lanai, wreg, ServRead_Reg);
1925 if (ntx != 0) {
1926 spin_lock(&lanai->txlock);
1927 vcclist_read_lock();
1928 vci_bitfield_iterate(lanai, &lanai->transmit_ready,
1929 iter_transmit);
1930 vci_bitfield_init(&lanai->transmit_ready);
1931 vcclist_read_unlock();
1932 spin_unlock(&lanai->txlock);
1933 }
1934}
1935
1936
1937
1938static void get_statistics(struct lanai_dev *lanai)
1939{
1940 u32 statreg = reg_read(lanai, Statistics_Reg);
1941 lanai->stats.atm_ovfl += STATS_GET_FIFO_OVFL(statreg);
1942 lanai->stats.hec_err += STATS_GET_HEC_ERR(statreg);
1943 lanai->stats.vci_trash += STATS_GET_BAD_VCI(statreg);
1944 lanai->stats.ovfl_trash += STATS_GET_BUF_OVFL(statreg);
1945}
1946
1947
1948
1949static void lanai_timed_poll(unsigned long arg)
1950{
1951#ifndef DEBUG_RW
1952 struct lanai_dev *lanai = (struct lanai_dev *) arg;
1953 unsigned long flags;
1954#ifdef USE_POWERDOWN
1955 if (lanai->conf1 & CONFIG1_POWERDOWN)
1956 return;
1957#endif
1958 spin_lock_irqsave(&lanai->servicelock, flags);
1959 run_service(lanai);
1960 spin_unlock_irqrestore(&lanai->servicelock, flags);
1961 vcc_tx_dequeue_all(lanai);
1962 get_statistics(lanai);
1963 mod_timer(&lanai->timer, jiffies + LANAI_POLL_PERIOD);
1964#endif
1965}
1966
1967static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
1968{
1969 init_timer(&lanai->timer);
1970 lanai->timer.expires = jiffies + LANAI_POLL_PERIOD;
1971 lanai->timer.data = (unsigned long) lanai;
1972 lanai->timer.function = lanai_timed_poll;
1973 add_timer(&lanai->timer);
1974}
1975
1976static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)
1977{
1978 del_timer(&lanai->timer);
1979}
1980
1981
1982
1983static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason)
1984{
1985 u32 ack = 0;
1986 if (reason & INT_SERVICE) {
1987 ack = INT_SERVICE;
1988 spin_lock(&lanai->servicelock);
1989 run_service(lanai);
1990 spin_unlock(&lanai->servicelock);
1991 }
1992 if (reason & (INT_AAL0_STR | INT_AAL0)) {
1993 ack |= reason & (INT_AAL0_STR | INT_AAL0);
1994 vcc_rx_aal0(lanai);
1995 }
1996 if (reason & INT_STATS) {
1997 reason &= ~INT_STATS;
1998 get_statistics(lanai);
1999 }
2000 if (reason & INT_STATUS) {
2001 ack |= reason & INT_STATUS;
2002 lanai_check_status(lanai);
2003 }
2004 if (reason & INT_DMASHUT) {
2005 printk(KERN_ERR DEV_LABEL "(itf %d): driver error - DMA "
2006 "shutdown, reason=0x%08X, address=0x%08X\n",
2007 lanai->number, reason & INT_DMASHUT,
2008 reg_read(lanai, DMA_Addr_Reg));
2009 if (reason & INT_TABORTBM) {
2010 lanai_reset(lanai);
2011 return;
2012 }
2013 ack |= (reason & INT_DMASHUT);
2014 printk(KERN_ERR DEV_LABEL "(itf %d): re-enabling DMA\n",
2015 lanai->number);
2016 conf1_write(lanai);
2017 lanai->stats.dma_reenable++;
2018 pcistatus_check(lanai, 0);
2019 }
2020 if (reason & INT_TABORTSENT) {
2021 ack |= (reason & INT_TABORTSENT);
2022 printk(KERN_ERR DEV_LABEL "(itf %d): sent PCI target abort\n",
2023 lanai->number);
2024 pcistatus_check(lanai, 0);
2025 }
2026 if (reason & INT_SEGSHUT) {
2027 printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "
2028 "segmentation shutdown, reason=0x%08X\n", lanai->number,
2029 reason & INT_SEGSHUT);
2030 lanai_reset(lanai);
2031 return;
2032 }
2033 if (reason & (INT_PING | INT_WAKE)) {
2034 printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "
2035 "unexpected interrupt 0x%08X, resetting\n",
2036 lanai->number, reason & (INT_PING | INT_WAKE));
2037 lanai_reset(lanai);
2038 return;
2039 }
2040#ifdef DEBUG
2041 if (ack != reason) {
2042 DPRINTK("unacked ints: 0x%08X\n", reason & ~ack);
2043 ack = reason;
2044 }
2045#endif
2046 if (ack != 0)
2047 reg_write(lanai, ack, IntAck_Reg);
2048}
2049
2050static void lanai_int(int irq, void *devid, struct pt_regs *regs)
2051{
2052 struct lanai_dev *lanai = (struct lanai_dev *) devid;
2053 u32 reason;
2054 (void) irq; (void) regs;
2055#ifdef USE_POWERDOWN
2056 if (lanai->conf1 & CONFIG1_POWERDOWN) {
2057 lanai->conf1 &= ~CONFIG1_POWERDOWN;
2058 conf1_write(lanai);
2059 printk(KERN_WARNING DEV_LABEL "(itf %d): Got interrupt "
2060 "0x%08X while in POWERDOWN, powering up\n", lanai->conf1,
2061 intr_pending(lanai));
2062 conf2_write(lanai);
2063 }
2064#endif
2065 while ((reason = intr_pending(lanai)) != 0)
2066 lanai_int_1(lanai, reason);
2067}
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080static int check_board_id_and_rev(const char *name, u32 val, int *revp)
2081{
2082 DPRINTK("%s says board_id=%d, board_rev=%d\n", name,
2083 RESET_GET_BOARD_ID(val), RESET_GET_BOARD_REV(val));
2084 if (RESET_GET_BOARD_ID(val) != BOARD_ID_LANAI256) {
2085 printk(KERN_ERR DEV_LABEL ": Found %s board-id %d -- not a "
2086 "Lanai 25.6\n", name, RESET_GET_BOARD_ID(val));
2087 return -ENODEV;
2088 }
2089 if (revp != NULL)
2090 *revp = RESET_GET_BOARD_REV(val);
2091 return 0;
2092}
2093
2094
2095
2096static inline int __init lanai_pci_start(struct lanai_dev *lanai)
2097{
2098 struct pci_dev *pci = lanai->pci;
2099 int result;
2100 u16 w;
2101
2102 result = pci_read_config_byte(pci, PCI_REVISION_ID,
2103 &lanai->pci_revision);
2104 if (result != PCIBIOS_SUCCESSFUL) {
2105 printk(KERN_ERR DEV_LABEL "(itf %d): can't read "
2106 "PCI_REVISION_ID: %d\n", lanai->number, result);
2107 return -EINVAL;
2108 }
2109 result = pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &w);
2110 if (result != PCIBIOS_SUCCESSFUL) {
2111 printk(KERN_ERR DEV_LABEL "(itf %d): can't read "
2112 "PCI_SUBSYSTEM_ID: %d\n", lanai->number, result);
2113 return -EINVAL;
2114 }
2115 if ((result = check_board_id_and_rev("PCI", w, NULL)) != 0)
2116 return result;
2117
2118 result = pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0);
2119 if (result != PCIBIOS_SUCCESSFUL) {
2120 printk(KERN_ERR DEV_LABEL "(itf %d): can't write "
2121 "PCI_LATENCY_TIMER: %d\n", lanai->number, result);
2122 return -EINVAL;
2123 }
2124 result = pci_read_config_word(pci, PCI_COMMAND, &w);
2125 if (result != PCIBIOS_SUCCESSFUL) {
2126 printk(KERN_ERR DEV_LABEL "(itf %d): can't read "
2127 "PCI_COMMAND: %d\n", lanai->number, result);
2128 return -EINVAL;
2129 }
2130 w |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SERR |
2131 PCI_COMMAND_PARITY);
2132 result = pci_write_config_word(pci, PCI_COMMAND, w);
2133 if (result != PCIBIOS_SUCCESSFUL) {
2134 printk(KERN_ERR DEV_LABEL "(itf %d): can't "
2135 "write PCI_COMMAND: %d\n", lanai->number, result);
2136 return -EINVAL;
2137 }
2138 pcistatus_check(lanai, 1);
2139 pcistatus_check(lanai, 0);
2140 return 0;
2141}
2142
2143static void lanai_pci_stop(struct lanai_dev *lanai)
2144{
2145 struct pci_dev *pci = lanai->pci;
2146 int result;
2147 u16 pci_command;
2148 result = pci_read_config_word(pci, PCI_COMMAND, &pci_command);
2149 if (result != PCIBIOS_SUCCESSFUL) {
2150 printk(KERN_ERR DEV_LABEL "(itf %d): can't "
2151 "read PCI_COMMAND: %d\n", lanai->number, result);
2152 return;
2153 }
2154 pci_command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
2155 result = pci_write_config_word(pci, PCI_COMMAND, pci_command);
2156 if (result != PCIBIOS_SUCCESSFUL)
2157 printk(KERN_ERR DEV_LABEL "(itf %d): can't "
2158 "write PCI_COMMAND: %d\n", lanai->number, result);
2159}
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169static inline int vci0_is_ok(struct lanai_dev *lanai,
2170 const struct atm_qos *qos)
2171{
2172 if (qos->txtp.traffic_class == ATM_CBR || qos->aal == ATM_AAL0)
2173 return 0;
2174 if (qos->rxtp.traffic_class != ATM_NONE) {
2175 if (lanai->naal0 != 0)
2176 return 0;
2177 lanai->conf2 |= CONFIG2_VCI0_NORMAL;
2178#ifdef USE_POWERDOWN
2179 if ((lanai->conf1 & CONFIG1_POWERDOWN) == 0)
2180#endif
2181 conf2_write(lanai);
2182 }
2183 return 1;
2184}
2185
2186
2187
2188
2189static int vci_is_ok(struct lanai_dev *lanai, vci_t vci,
2190 const struct atm_vcc *atmvcc)
2191{
2192 const struct atm_qos *qos = &atmvcc->qos;
2193 const struct lanai_vcc *lvcc = lanai->vccs[vci];
2194 if (vci == 0 && !vci0_is_ok(lanai, qos))
2195 return 0;
2196 if (lvcc != NULL) {
2197 if (qos->rxtp.traffic_class != ATM_NONE &&
2198 lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc)
2199 return 0;
2200 if (qos->txtp.traffic_class != ATM_NONE &&
2201 lvcc->tx.atmvcc != NULL && lvcc->tx.atmvcc != atmvcc)
2202 return 0;
2203 if (qos->txtp.traffic_class == ATM_CBR &&
2204 lanai->cbrvcc != NULL && lanai->cbrvcc != atmvcc)
2205 return 0;
2206 }
2207 if (qos->aal == ATM_AAL0 && lanai->naal0 == 0 &&
2208 qos->rxtp.traffic_class != ATM_NONE) {
2209 const struct lanai_vcc *vci0 = lanai->vccs[0];
2210 if (vci0 != NULL && vci0->rx.atmvcc != NULL)
2211 return 0;
2212 lanai->conf2 &= ~CONFIG2_VCI0_NORMAL;
2213#ifdef USE_POWERDOWN
2214 if ((lanai->conf1 & CONFIG1_POWERDOWN) == 0)
2215#endif
2216 conf2_write(lanai);
2217 }
2218 return 1;
2219}
2220
2221static int lanai_normalize_ci(struct lanai_dev *lanai,
2222 const struct atm_vcc *atmvcc, short *vpip, vci_t *vcip)
2223{
2224 switch (*vpip) {
2225 case ATM_VPI_ANY:
2226 *vpip = 0;
2227
2228 case 0:
2229 break;
2230 default:
2231 return -EADDRINUSE;
2232 }
2233 switch (*vcip) {
2234 case ATM_VCI_ANY:
2235 for (*vcip = ATM_NOT_RSV_VCI; *vcip < lanai->num_vci;
2236 (*vcip)++)
2237 if (vci_is_ok(lanai, *vcip, atmvcc))
2238 return 0;
2239 return -EADDRINUSE;
2240 default:
2241 if (*vcip >= lanai->num_vci || *vcip < 0 ||
2242 !vci_is_ok(lanai, *vcip, atmvcc))
2243 return -EADDRINUSE;
2244 }
2245 return 0;
2246}
2247
2248
2249
2250
2251
2252
2253
2254
2255#define CBRICG_FRAC_BITS (4)
2256#define CBRICG_MAX (2046 << CBRICG_FRAC_BITS)
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273static int pcr_to_cbricg( struct atm_qos *qos)
2274{
2275 int rounddown = 0;
2276 int x, icg, pcr = atm_pcr_goal(&qos->txtp);
2277 if (pcr == 0)
2278 return 0;
2279 if (pcr < 0) {
2280 rounddown = 1;
2281 pcr = -pcr;
2282 }
2283 x = pcr * 27;
2284 icg = (3125 << (9 + CBRICG_FRAC_BITS)) - (x << CBRICG_FRAC_BITS);
2285 if (rounddown)
2286 icg += x - 1;
2287 icg /= x;
2288 if (icg > CBRICG_MAX)
2289 icg = CBRICG_MAX;
2290 DPRINTK("pcr_to_cbricg: pcr=%d rounddown=%c icg=%d\n",
2291 pcr, rounddown ? 'Y' : 'N', icg);
2292 return icg;
2293}
2294
2295static inline void lanai_cbr_setup(struct lanai_dev *lanai)
2296{
2297 reg_write(lanai, pcr_to_cbricg(&lanai->cbrvcc->qos), CBR_ICG_Reg);
2298 reg_write(lanai, lanai->cbrvcc->vci, CBR_PTR_Reg);
2299 lanai->conf2 |= CONFIG2_CBR_ENABLE;
2300 conf2_write(lanai);
2301}
2302
2303static inline void lanai_cbr_shutdown(struct lanai_dev *lanai)
2304{
2305 lanai->conf2 &= ~CONFIG2_CBR_ENABLE;
2306 conf2_write(lanai);
2307}
2308
2309
2310
2311
2312static int __init lanai_dev_open(struct atm_dev *atmdev)
2313{
2314 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
2315 unsigned long raw_base;
2316 int result;
2317
2318 DPRINTK("In lanai_dev_open()\n");
2319
2320 lanai->number = atmdev->number;
2321 lanai->num_vci = NUM_VCI;
2322 vci_bitfield_init(&lanai->backlog_vccs);
2323 vci_bitfield_init(&lanai->transmit_ready);
2324 lanai->naal0 = 0;
2325#ifdef USE_POWERDOWN
2326 lanai->nbound = 0;
2327#endif
2328 lanai->cbrvcc = NULL;
2329 memset(&lanai->stats, 0, sizeof lanai->stats);
2330 spin_lock_init(&lanai->txlock);
2331 spin_lock_init(&lanai->servicelock);
2332 atmdev->ci_range.vpi_bits = 0;
2333 atmdev->ci_range.vci_bits = 0;
2334 while (1 << atmdev->ci_range.vci_bits < lanai->num_vci)
2335 atmdev->ci_range.vci_bits++;
2336 atmdev->link_rate = ((25600000 / 8 - 8000) / 54);
2337
2338
2339 if ((result = lanai_pci_start(lanai)) != 0)
2340 goto error;
2341 raw_base = (bus_addr_t) lanai->pci->resource[0].start;
2342 lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);
2343 if (lanai->base == 0) {
2344 printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");
2345 goto error_pci;
2346 }
2347
2348 reset_board(lanai);
2349 lanai->conf1 = reg_read(lanai, Config1_Reg);
2350 lanai->conf1 &= ~(CONFIG1_GPOUT1 | CONFIG1_POWERDOWN |
2351 CONFIG1_MASK_LEDMODE);
2352 lanai->conf1 |= CONFIG1_SET_LEDMODE(LEDMODE_NOT_SOOL);
2353 reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
2354 udelay(1000);
2355 conf1_write(lanai);
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366 result = check_board_id_and_rev("register",
2367 reg_read(lanai, Reset_Reg), &lanai->board_rev);
2368 if (result != 0)
2369 goto error_unmap;
2370
2371
2372 if ((result = eeprom_read(lanai)) != 0)
2373 goto error_unmap;
2374 if ((result = eeprom_validate(lanai)) != 0)
2375 goto error_unmap;
2376
2377
2378 reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
2379 udelay(1000);
2380 conf1_write(lanai);
2381
2382 lanai->conf1 |= (CONFIG1_GPOUT2 | CONFIG1_GPOUT3 | CONFIG1_DMA_ENABLE);
2383 conf1_write(lanai);
2384
2385
2386 if ((result = sram_test_and_clear(lanai)) != 0)
2387 goto error_unmap;
2388
2389
2390 lanai->conf1 |= CONFIG1_DMA_ENABLE;
2391 conf1_write(lanai);
2392 if ((result = service_buffer_allocate(lanai)) != 0)
2393 goto error_unmap;
2394 if ((result = vcc_table_allocate(lanai)) != 0)
2395 goto error_service;
2396 lanai->conf2 = (lanai->num_vci >= 512 ? CONFIG2_HOWMANY : 0) |
2397 CONFIG2_HEC_DROP | CONFIG2_PTI7_MODE;
2398 conf2_write(lanai);
2399 reg_write(lanai, TX_FIFO_DEPTH, TxDepth_Reg);
2400 reg_write(lanai, 0, CBR_ICG_Reg);
2401 if ((result = request_irq(lanai->pci->irq, lanai_int, SA_SHIRQ,
2402 "lanai", lanai)) != 0) {
2403 printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
2404 goto error_vcctable;
2405 }
2406 MOD_INC_USE_COUNT;
2407 intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
2408
2409 lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) |
2410 CONFIG1_SET_LOOPMODE(LOOPMODE_NORMAL) |
2411 CONFIG1_GPOUT2 | CONFIG1_GPOUT3;
2412 conf1_write(lanai);
2413 lanai->status = reg_read(lanai, Status_Reg);
2414
2415#ifdef USE_POWERDOWN
2416 lanai->conf1 |= CONFIG1_POWERDOWN;
2417 conf1_write(lanai);
2418#endif
2419 memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN);
2420 lanai_timed_poll_start(lanai);
2421 printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=0x%lx, irq=%d "
2422 "(%02X-%02X-%02X-%02X-%02X-%02X)\n", lanai->number,
2423 lanai->pci_revision, (long) lanai->base, lanai->pci->irq,
2424 atmdev->esi[0], atmdev->esi[1], atmdev->esi[2],
2425 atmdev->esi[3], atmdev->esi[4], atmdev->esi[5]);
2426 printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%d(0x%X), "
2427 "board_rev=%d\n", lanai->number,
2428 lanai->type==lanai2 ? "2" : "HB", lanai->serialno,
2429 lanai->serialno, lanai->board_rev);
2430 return 0;
2431
2432 error_vcctable:
2433 vcc_table_deallocate(lanai);
2434 error_service:
2435 service_buffer_deallocate(lanai);
2436 error_unmap:
2437 reset_board(lanai);
2438#ifdef USE_POWERDOWN
2439 lanai->conf1 = reg_read(lanai, Config1_Reg) | CONFIG1_POWERDOWN;
2440 conf1_write(lanai);
2441#endif
2442 iounmap((void *) lanai->base);
2443 error_pci:
2444 lanai_pci_stop(lanai);
2445 error:
2446 return result;
2447}
2448
2449
2450
2451
2452static void lanai_dev_close(struct atm_dev *atmdev)
2453{
2454 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
2455 printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n",
2456 lanai->number);
2457 lanai_timed_poll_stop(lanai);
2458#ifdef USE_POWERDOWN
2459 lanai->conf1 = reg_read(lanai, Config1_Reg) & ~CONFIG1_POWERDOWN;
2460 conf1_write(lanai);
2461#endif
2462 intr_disable(lanai, INT_ALL);
2463 free_irq(lanai->pci->irq, lanai);
2464 reset_board(lanai);
2465#ifdef USE_POWERDOWN
2466 lanai->conf1 |= CONFIG1_POWERDOWN;
2467 conf1_write(lanai);
2468#endif
2469 lanai_pci_stop(lanai);
2470 vcc_table_deallocate(lanai);
2471 service_buffer_deallocate(lanai);
2472 iounmap((void *) lanai->base);
2473 kfree(lanai);
2474 MOD_DEC_USE_COUNT;
2475}
2476
2477
2478static void lanai_close(struct atm_vcc *atmvcc)
2479{
2480 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
2481 struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
2482 if (lvcc == NULL)
2483 return;
2484 clear_bit(ATM_VF_READY, &atmvcc->flags);
2485 clear_bit(ATM_VF_PARTIAL, &atmvcc->flags);
2486 if (lvcc->rx.atmvcc == atmvcc) {
2487 lanai_shutdown_rx_vci(lvcc);
2488 if (atmvcc->qos.aal == ATM_AAL0) {
2489 if (--lanai->naal0 <= 0)
2490 aal0_buffer_free(lanai);
2491 } else
2492 lanai_buf_deallocate(&lvcc->rx.buf);
2493 lvcc->rx.atmvcc = NULL;
2494 }
2495 if (lvcc->tx.atmvcc == atmvcc) {
2496 if (atmvcc == lanai->cbrvcc) {
2497 if (lvcc->vbase != 0)
2498 lanai_cbr_shutdown(lanai);
2499 lanai->cbrvcc = NULL;
2500 }
2501 lanai_shutdown_tx_vci(lanai, lvcc);
2502 lanai_buf_deallocate(&lvcc->tx.buf);
2503 lvcc->tx.atmvcc = NULL;
2504 }
2505 if (--lvcc->nref == 0) {
2506 host_vcc_unbind(lanai, lvcc);
2507 kfree(lvcc);
2508 }
2509 atmvcc->dev_data = NULL;
2510 clear_bit(ATM_VF_ADDR, &atmvcc->flags);
2511}
2512
2513
2514static int lanai_open(struct atm_vcc *atmvcc, short vpi, int vci)
2515{
2516 struct lanai_dev *lanai;
2517 struct lanai_vcc *lvcc;
2518 int result = 0;
2519
2520 if ((test_bit(ATM_VF_PARTIAL, &atmvcc->flags)) ||
2521 (vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC))
2522 return -EINVAL;
2523 lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
2524 if ((result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci)) != 0)
2525 goto out;
2526 atmvcc->vpi = vpi;
2527 atmvcc->vci = vci;
2528 set_bit(ATM_VF_ADDR, &atmvcc->flags);
2529 lvcc = lanai->vccs[vci];
2530 if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5)
2531 return -EINVAL;
2532#if 0
2533 DPRINTK(DEV_LABEL "(itf %d): open %d.%d flags=0x%X\n",
2534 lanai->number, vpi, vci, (unsigned long) atmvcc->flags);
2535#else
2536 DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number, vpi, vci);
2537#endif
2538 if (lvcc == NULL && (lvcc = new_lanai_vcc()) == NULL)
2539 return -ENOMEM;
2540 atmvcc->dev_data = lvcc;
2541 lvcc->nref++;
2542 if (atmvcc->qos.rxtp.traffic_class != ATM_NONE) {
2543 APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n",
2544 vci);
2545 if (atmvcc->qos.aal == ATM_AAL0) {
2546 if (lanai->naal0 == 0)
2547 result = aal0_buffer_allocate(lanai);
2548 } else
2549 result = lanai_setup_rx_vci_aal5(
2550 lanai->number, lvcc, &atmvcc->qos);
2551 if (result != 0)
2552 goto out_free;
2553 lvcc->rx.atmvcc = atmvcc;
2554 lvcc->stats.rx_nomem = 0;
2555 lvcc->stats.x.aal5.rx_badlen = 0;
2556 lvcc->stats.x.aal5.service_trash = 0;
2557 lvcc->stats.x.aal5.service_stream = 0;
2558 lvcc->stats.x.aal5.service_rxcrc = 0;
2559 if (atmvcc->qos.aal == ATM_AAL0)
2560 lanai->naal0++;
2561 }
2562 if (atmvcc->qos.txtp.traffic_class != ATM_NONE) {
2563 APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n",
2564 vci);
2565 result = lanai_setup_tx_vci(lanai->number, lvcc, &atmvcc->qos);
2566 if (result != 0)
2567 goto out_free;
2568 lvcc->tx.atmvcc = atmvcc;
2569 if (atmvcc->qos.txtp.traffic_class == ATM_CBR) {
2570 APRINTK(lanai->cbrvcc == NULL,
2571 "cbrvcc!=NULL, vci=%d\n", vci);
2572 lanai->cbrvcc = atmvcc;
2573 }
2574 }
2575 host_vcc_bind(lanai, lvcc, vci);
2576 if (atmvcc == lvcc->rx.atmvcc)
2577 host_vcc_start_rx(lvcc);
2578 if (atmvcc == lvcc->tx.atmvcc) {
2579 host_vcc_start_tx(lvcc);
2580 if (lanai->cbrvcc == atmvcc)
2581 lanai_cbr_setup(lanai);
2582 }
2583 set_bit(ATM_VF_READY, &atmvcc->flags);
2584 return 0;
2585 out_free:
2586 lanai_close(atmvcc);
2587 out:
2588 return result;
2589}
2590
2591
2592
2593static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void *arg)
2594{
2595 int result = 0;
2596 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
2597 switch(cmd) {
2598 case 2106275:
2599 shutdown_atm_dev(atmdev);
2600 return 0;
2601 case 2200000: {
2602 unsigned long flags;
2603 spin_lock_irqsave(&lanai->servicelock, flags);
2604 run_service(lanai);
2605 spin_unlock_irqrestore(&lanai->servicelock, flags);
2606 return 0; }
2607 case 2200001:
2608 vcc_tx_dequeue_all(lanai);
2609 return 0;
2610 case 2200002:
2611 get_statistics(lanai);
2612 return 0;
2613 case 2200003: {
2614 int i;
2615 for (i = 0; i <= 0x5C ; i += 4) {
2616 if (i==0x48)
2617 continue;
2618 printk(KERN_CRIT DEV_LABEL " 0x%02X: "
2619 "0x%08X\n", i,
2620 (u32) readl(lanai->base + i));
2621 barrier(); mb();
2622 pcistatus_check(lanai, 0);
2623 barrier(); mb();
2624 }
2625 return 0; }
2626 case 2200004: {
2627 u8 b;
2628 u16 w;
2629 u32 dw;
2630 struct pci_dev *pci = lanai->pci;
2631 (void) pci_read_config_word(pci, PCI_VENDOR_ID, &w);
2632 DPRINTK("vendor = 0x%X\n", w);
2633 (void) pci_read_config_word(pci, PCI_DEVICE_ID, &w);
2634 DPRINTK("device = 0x%X\n", w);
2635 (void) pci_read_config_word(pci, PCI_COMMAND, &w);
2636 DPRINTK("command = 0x%X\n", w);
2637 (void) pci_read_config_word(pci, PCI_STATUS, &w);
2638 DPRINTK("status = 0x%X\n", w);
2639 (void) pci_read_config_dword(pci,
2640 PCI_CLASS_REVISION, &dw);
2641 DPRINTK("class/revision = 0x%X\n", dw);
2642 (void) pci_read_config_byte(pci,
2643 PCI_CACHE_LINE_SIZE, &b);
2644 DPRINTK("cache line size = 0x%X\n", b);
2645 (void) pci_read_config_byte(pci, PCI_LATENCY_TIMER, &b);
2646 DPRINTK("latency = %d (0x%X)\n", b, b);
2647 (void) pci_read_config_byte(pci, PCI_HEADER_TYPE, &b);
2648 DPRINTK("header type = 0x%X\n", b);
2649 (void) pci_read_config_byte(pci, PCI_BIST, &b);
2650 DPRINTK("bist = 0x%X\n", b);
2651
2652 (void) pci_read_config_byte(pci,
2653 PCI_INTERRUPT_LINE, &b);
2654 DPRINTK("pci_int_line = 0x%X\n", b);
2655 (void) pci_read_config_byte(pci,
2656 PCI_INTERRUPT_PIN, &b);
2657 DPRINTK("pci_int_pin = 0x%X\n", b);
2658 (void) pci_read_config_byte(pci, PCI_MIN_GNT, &b);
2659 DPRINTK("min_gnt = 0x%X\n", b);
2660 (void) pci_read_config_byte(pci, PCI_MAX_LAT, &b);
2661 DPRINTK("max_lat = 0x%X\n", b); }
2662 return 0;
2663#ifdef USE_POWERDOWN
2664 case 2200005:
2665 DPRINTK("Coming out of powerdown\n");
2666 lanai->conf1 &= ~CONFIG1_POWERDOWN;
2667 conf1_write(lanai);
2668 return 0;
2669#endif
2670 default:
2671 result = -EINVAL;
2672 }
2673 return result;
2674}
2675
2676static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
2677{
2678 struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
2679 struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
2680 unsigned long flags;
2681 if (lvcc == NULL || lvcc->vbase == 0 || lvcc->tx.atmvcc != atmvcc)
2682 goto einval;
2683#ifdef DEBUG
2684 if (skb == NULL) {
2685 DPRINTK("lanai_send: skb==NULL for vci=%d\n", atmvcc->vci);
2686 goto einval;
2687 }
2688 if (lanai == NULL) {
2689 DPRINTK("lanai_send: lanai==NULL for vci=%d\n", atmvcc->vci);
2690 goto einval;
2691 }
2692#endif
2693 ATM_SKB(skb)->vcc = atmvcc;
2694 switch (atmvcc->qos.aal) {
2695 case ATM_AAL5:
2696 spin_lock_irqsave(&lanai->txlock, flags);
2697 vcc_tx_aal5(lanai, lvcc, skb);
2698 spin_unlock_irqrestore(&lanai->txlock, flags);
2699 return 0;
2700 case ATM_AAL0:
2701 if (skb->len != ATM_CELL_SIZE-1)
2702 goto einval;
2703
2704 cpu_to_be32s((u32 *) skb->data);
2705 spin_lock_irqsave(&lanai->txlock, flags);
2706 vcc_tx_aal0(lanai, lvcc, skb);
2707 spin_unlock_irqrestore(&lanai->txlock, flags);
2708 return 0;
2709 }
2710 DPRINTK("lanai_send: bad aal=%d on vci=%d\n", atmvcc->qos.aal,
2711 atmvcc->vci);
2712 einval:
2713 lanai_free_skb(atmvcc, skb);
2714 return -EINVAL;
2715}
2716
2717static int lanai_change_qos(struct atm_vcc *atmvcc,
2718 struct atm_qos *qos, int flags)
2719{
2720 return -EBUSY;
2721}
2722
2723#ifndef CONFIG_PROC_FS
2724#define lanai_proc_read NULL
2725#else
2726static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
2727{
2728 struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
2729 loff_t left = *pos;
2730 struct lanai_vcc *lvcc;
2731 if (left-- == 0)
2732 return sprintf(page, DEV_LABEL "(itf %d): chip=LANAI%s, "
2733 "serial=%d, magic=0x%08X, num_vci=%d\n",
2734 atmdev->number, lanai->type==lanai2 ? "2" : "HB",
2735 lanai->serialno, lanai->magicno, lanai->num_vci);
2736 if (left-- == 0)
2737 return sprintf(page, "revision: board=%d, pci_if=%d\n",
2738 lanai->board_rev, lanai->pci_revision);
2739 if (left-- == 0)
2740 return sprintf(page, "EEPROM ESI: "
2741 "%02X:%02X:%02X:%02X:%02X:%02X\n",
2742 lanai->eeprom[EEPROM_MAC + 0],
2743 lanai->eeprom[EEPROM_MAC + 1],
2744 lanai->eeprom[EEPROM_MAC + 2],
2745 lanai->eeprom[EEPROM_MAC + 3],
2746 lanai->eeprom[EEPROM_MAC + 4],
2747 lanai->eeprom[EEPROM_MAC + 5]);
2748 if (left-- == 0)
2749 return sprintf(page, "status: SOOL=%d, LOCD=%d, LED=%d, "
2750 "GPIN=%d\n", (lanai->status & STATUS_SOOL) ? 1 : 0,
2751 (lanai->status & STATUS_LOCD) ? 1 : 0,
2752 (lanai->status & STATUS_LED) ? 1 : 0,
2753 (lanai->status & STATUS_GPIN) ? 1 : 0);
2754 if (left-- == 0)
2755 return sprintf(page, "global buffer sizes: service=%d, "
2756 "aal0_rx=%d\n", lanai_buf_size(&lanai->service),
2757 lanai->naal0 ? lanai_buf_size(&lanai->aal0buf) : 0);
2758 if (left-- == 0) {
2759 get_statistics(lanai);
2760 return sprintf(page, "cells in error: overflow=%d, "
2761 "closed_vci=%d, bad_HEC=%d, rx_fifo=%d\n",
2762 lanai->stats.ovfl_trash, lanai->stats.vci_trash,
2763 lanai->stats.hec_err, lanai->stats.atm_ovfl);
2764 }
2765 if (left-- == 0)
2766 return sprintf(page, "PCI errors: parity_detect=%d, "
2767 "master_abort=%d, master_target_abort=%d,\n",
2768 lanai->stats.pcierr_parity_detect,
2769 lanai->stats.pcierr_serr_set,
2770 lanai->stats.pcierr_m_target_abort);
2771 if (left-- == 0)
2772 return sprintf(page, " slave_target_abort=%d, "
2773 "master_parity=%d\n", lanai->stats.pcierr_s_target_abort,
2774 lanai->stats.pcierr_master_parity);
2775 if (left-- == 0)
2776 return sprintf(page, "service list errors: no_vcc_rx=%d, "
2777 "no_vcc_tx=%d,\n", lanai->stats.service_novcc_rx,
2778 lanai->stats.service_novcc_tx);
2779 if (left-- == 0)
2780 return sprintf(page, " no_tx=%d, "
2781 "no_rx=%d, bad_rx_aal=%d\n", lanai->stats.service_norx,
2782 lanai->stats.service_notx,
2783 lanai->stats.service_rxnotaal5);
2784 if (left-- == 0)
2785 return sprintf(page, "resets: dma=%d, card=%d\n",
2786 lanai->stats.dma_reenable, lanai->stats.card_reset);
2787
2788 vcclist_read_lock();
2789 for (; ; left++) {
2790 if (left >= NUM_VCI) {
2791 left = 0;
2792 goto out;
2793 }
2794 if ((lvcc = lanai->vccs[left]) != NULL)
2795 break;
2796 (*pos)++;
2797 }
2798
2799 left = sprintf(page, "VCI %4d: nref=%d, rx_nomem=%d", (vci_t) left,
2800 lvcc->nref, lvcc->stats.rx_nomem);
2801 if (lvcc->rx.atmvcc != NULL) {
2802 left += sprintf(&page[left], ",\n rx_AAL=%d",
2803 lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0);
2804 if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5)
2805 left += sprintf(&page[left], ", rx_buf_size=%d, "
2806 "rx_bad_len=%d,\n rx_service_trash=%d, "
2807 "rx_service_stream=%d, rx_bad_crc=%d",
2808 lanai_buf_size(&lvcc->rx.buf),
2809 lvcc->stats.x.aal5.rx_badlen,
2810 lvcc->stats.x.aal5.service_trash,
2811 lvcc->stats.x.aal5.service_stream,
2812 lvcc->stats.x.aal5.service_rxcrc);
2813 }
2814 if (lvcc->tx.atmvcc != NULL)
2815 left += sprintf(&page[left], ",\n tx_AAL=%d, "
2816 "tx_buf_size=%d, tx_qos=%cBR, tx_backlogged=%c",
2817 lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0,
2818 lanai_buf_size(&lvcc->tx.buf),
2819 lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U',
2820 vcc_is_backlogged(lvcc) ? 'Y' : 'N');
2821 page[left++] = '\n';
2822 page[left] = '\0';
2823 out:
2824 vcclist_read_unlock();
2825 return left;
2826}
2827#endif
2828
2829
2830
2831static const struct atmdev_ops ops = {
2832 dev_close: lanai_dev_close,
2833 open: lanai_open,
2834 close: lanai_close,
2835 ioctl: lanai_ioctl,
2836 getsockopt: NULL,
2837 setsockopt: NULL,
2838 send: lanai_send,
2839 sg_send: NULL,
2840 send_oam: NULL,
2841 phy_put: NULL,
2842 phy_get: NULL,
2843 feedback: NULL,
2844 change_qos: lanai_change_qos,
2845 proc_read: lanai_proc_read
2846};
2847
2848
2849static int __init lanai_detect_1(unsigned int vendor, unsigned int device)
2850{
2851 struct pci_dev *pci = NULL;
2852 struct lanai_dev *lanai;
2853 struct atm_dev *atmdev;
2854 int count = 0, result;
2855 while ((pci = pci_find_device(vendor, device, pci)) != NULL) {
2856 lanai = (struct lanai_dev *)
2857 kmalloc(sizeof *lanai, GFP_KERNEL);
2858 if (lanai == NULL) {
2859 printk(KERN_ERR DEV_LABEL ": couldn't allocate "
2860 "dev_data structure!\n");
2861 break;
2862 }
2863 atmdev = atm_dev_register(DEV_LABEL, &ops, -1, 0);
2864 if (atmdev == NULL) {
2865 printk(KERN_ERR DEV_LABEL ": couldn't register "
2866 "atm device!\n");
2867 kfree(lanai);
2868 break;
2869 }
2870 atmdev->dev_data = lanai;
2871 lanai->pci = pci;
2872 lanai->type = (enum lanai_type) device;
2873 if ((result = lanai_dev_open(atmdev)) != 0) {
2874 DPRINTK("lanai_start() failed, err=%d\n", -result);
2875 atm_dev_deregister(atmdev);
2876 kfree(lanai);
2877 continue;
2878 }
2879 count++;
2880 }
2881 return count;
2882}
2883
2884#ifdef MODULE
2885static
2886#endif
2887int __init lanai_detect(void)
2888{
2889 return lanai_detect_1(PCI_VENDOR_ID_EF, PCI_VENDOR_ID_EF_ATM_LANAI2) +
2890 lanai_detect_1(PCI_VENDOR_ID_EF, PCI_VENDOR_ID_EF_ATM_LANAIHB);
2891}
2892
2893#ifdef MODULE
2894
2895int init_module(void)
2896{
2897 if (lanai_detect() == 0) {
2898 printk(KERN_ERR DEV_LABEL ": no adaptor found\n");
2899 return -ENODEV;
2900 }
2901 return 0;
2902}
2903
2904void cleanup_module(void)
2905{
2906
2907
2908
2909 DPRINTK("cleanup_module()\n");
2910}
2911
2912MODULE_AUTHOR("Mitchell Blank Jr <mitch@sfgoth.com>");
2913MODULE_DESCRIPTION("Efficient Networks Speedstream 3010 driver");
2914MODULE_LICENSE("GPL");
2915
2916#endif
2917