summaryrefslogtreecommitdiff
path: root/package/ifxmips-atm/src/common.h
blob: aad6a984e6ea642db60c8d17e5a512cfe21f6d58 (plain)
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
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
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
#include <linux/atmdev.h>
#include <asm/ifxmips/ifxmips_irq.h>
#include <linux/irq.h>
#include <linux/sem.h>
#include <linux/coda.h>

#define RX_DMA_CH_CBR                   0
#define RX_DMA_CH_VBR_RT                1
#define RX_DMA_CH_VBR_NRT               2
#define RX_DMA_CH_AVR                   3
#define RX_DMA_CH_UBR                   4
#define RX_DMA_CH_OAM                   5
#define RX_DMA_CH_TOTAL                 6

#define WRX_DMA_CHANNEL_INTERRUPT_MODE  0x00
#define WRX_DMA_CHANNEL_POLLING_MODE    0x01
//#define WRX_DMA_CHANNEL_COUNTER_MODE    0x02
#define WRX_DMA_CHANNEL_COUNTER_MODE    WRX_DMA_CHANNEL_INTERRUPT_MODE
#define WRX_DMA_BUF_LEN_PER_DESCRIPTOR  0x00
#define WRX_DMA_BUF_LEN_PER_CHANNEL     0x01

#define ATM_VBR_RT     6
#define ATM_VBR_NRT    ATM_VBR
#define ATM_UBR_PLUS   7

#define SET_BITS(x, msb, lsb, value)    (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))

#define GET_ATM_PRIV(dev)       ((Atm_Priv *)dev->priv)

#define CDM_CFG                         PPE_REG_ADDR(0x0100)

#define CDM_CFG_RAM1                    GET_BITS(*CDM_CFG, 3, 2)
#define CDM_CFG_RAM0                    (*CDM_CFG & (1 << 1))

#define CDM_CFG_RAM1_SET(value)         SET_BITS(0, 3, 2, value)
#define CDM_CFG_RAM0_SET(value)         ((value) ? (1 << 1) : 0)

/*
 *  EMA Registers
 */
#define EMA_CMDCFG                      PPE_REG_ADDR(0x0A00)
#define EMA_DATACFG                     PPE_REG_ADDR(0x0A01)
#define EMA_CMDCNT                      PPE_REG_ADDR(0x0A02)
#define EMA_DATACNT                     PPE_REG_ADDR(0x0A03)
#define EMA_ISR                         PPE_REG_ADDR(0x0A04)
#define EMA_IER                         PPE_REG_ADDR(0x0A05)
#define EMA_CFG                         PPE_REG_ADDR(0x0A06)
#define EMA_SUBID                       PPE_REG_ADDR(0x0A07)


/*
 *  QSB RAM Access Register
 */
#define QSB_RAMAC                       QSB_CONF_REG(0x000D)

#define QSB_RAMAC_RW                    (*QSB_RAMAC & (1 << 31))
#define QSB_RAMAC_TSEL                  GET_BITS(*QSB_RAMAC, 27, 24)
#define QSB_RAMAC_LH                    (*QSB_RAMAC & (1 << 16))
#define QSB_RAMAC_TESEL                 GET_BITS(*QSB_RAMAC, 9, 0)

#define QSB_RAMAC_RW_SET(value)         ((value) ? (1 << 31) : 0)
#define QSB_RAMAC_TSEL_SET(value)       SET_BITS(0, 27, 24, value)
#define QSB_RAMAC_LH_SET(value)         ((value) ? (1 << 16) : 0)
#define QSB_RAMAC_TESEL_SET(value)      SET_BITS(0, 9, 0, value)

/*  QSB */
#define QSB_RAMAC_RW_READ               0
#define QSB_RAMAC_RW_WRITE              1

#define QSB_RAMAC_TSEL_QPT              0x01
#define QSB_RAMAC_TSEL_SCT              0x02
#define QSB_RAMAC_TSEL_SPT              0x03
#define QSB_RAMAC_TSEL_VBR              0x08

#define QSB_RAMAC_LH_LOW                0
#define QSB_RAMAC_LH_HIGH               1

#define QSB_QPT_SET_MASK                0x0
#define QSB_QVPT_SET_MASK               0x0
#define QSB_SET_SCT_MASK                0x0
#define QSB_SET_SPT_MASK                0x0
#define QSB_SET_SPT_SBVALID_MASK        0x7FFFFFFF

#define QSB_SPT_SBV_VALID               (1 << 31)
#define QSB_SPT_PN_SET(value)           (((value) & 0x01) ? (1 << 16) : 0)
#define QSB_SPT_INTRATE_SET(value)      SET_BITS(0, 13, 0, value)

/*
 *  QSB Internal Cell Delay Variation Register
 */
#define QSB_ICDV                        QSB_CONF_REG(0x0007)

#define QSB_ICDV_TAU                    GET_BITS(*QSB_ICDV, 5, 0)

#define QSB_ICDV_TAU_SET(value)         SET_BITS(0, 5, 0, value)

/*
 *  QSB Scheduler Burst Limit Register
 */
#define QSB_SBL                         QSB_CONF_REG(0x0009)

#define QSB_SBL_SBL                     GET_BITS(*QSB_SBL, 3, 0)

#define QSB_SBL_SBL_SET(value)          SET_BITS(0, 3, 0, value)

/*
 *  QSB Configuration Register
 */
#define QSB_CFG                         QSB_CONF_REG(0x000A)

#define QSB_CFG_TSTEPC                  GET_BITS(*QSB_CFG, 1, 0)

#define QSB_CFG_TSTEPC_SET(value)       SET_BITS(0, 1, 0, value)

/*
 *  QSB RAM Transfer Table Register
 */
#define QSB_RTM                         QSB_CONF_REG(0x000B)

#define QSB_RTM_DM                      (*QSB_RTM)

#define QSB_RTM_DM_SET(value)           ((value) & 0xFFFFFFFF)

/*
 *  QSB RAM Transfer Data Register
 */
#define QSB_RTD                         QSB_CONF_REG(0x000C)

#define QSB_RTD_TTV                     (*QSB_RTD)

#define QSB_RTD_TTV_SET(value)          ((value) & 0xFFFFFFFF)

/*
 *  PP32 Debug Control Register
 */
#define PP32_DBG_CTRL                   PP32_DEBUG_REG_ADDR(0x0000)

#define DBG_CTRL_START_SET(value)       ((value) ? (1 << 0) : 0)
#define DBG_CTRL_STOP_SET(value)        ((value) ? (1 << 1) : 0)
#define DBG_CTRL_STEP_SET(value)        ((value) ? (1 << 2) : 0)

#define SB_RAM0_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x8000) << 2)))
#define UPDATE_VCC_STAT(conn, item, num)    do { ppe_dev.connection[conn].item += num; } while (0)
/*
 *  EMA Settings
 */
#define EMA_CMD_BUF_LEN      0x0040
#define EMA_CMD_BASE_ADDR    (0x00001580 << 2)
#define EMA_DATA_BUF_LEN     0x0100
#define EMA_DATA_BASE_ADDR   (0x00001900 << 2)
#define EMA_WRITE_BURST      0x2
#define EMA_READ_BURST       0x2


#define CELL_SIZE                       ATM_AAL0_SDU
#define IDLE_CYCLE_NUMBER               30000

#define MBOX_IGU1_ISR                   PPE_REG_ADDR(0x0206)
#define MBOX_IGU3_ISRS                  PPE_REG_ADDR(0x0214)
#define MBOX_IGU1_ISRC                  PPE_REG_ADDR(0x0205)
#define MBOX_IGU3_ISR                   PPE_REG_ADDR(0x0216)
#define MBOX_IGU3_ISRS_SET(n)           (1 << (n))
#define MBOX_IGU3_ISR_ISR(n)            (*MBOX_IGU3_ISR & (1 << (n)))
/*
 *  *  Mailbox IGU1 Registers
 *   */
#define MBOX_IGU1_ISRS                  PPE_REG_ADDR(0x0204)
#define MBOX_IGU1_IER                   PPE_REG_ADDR(0x0207)

#define MBOX_IGU1_ISRS_SET(n)           (1 << (n))
#define MBOX_IGU1_ISRC_CLEAR(n)         (1 << (n))
#define MBOX_IGU1_ISR_ISR(n)            (*MBOX_IGU1_ISR & (1 << (n)))
#define MBOX_IGU1_IER_EN(n)             (*MBOX_IGU1_IER & (1 << (n)))
#define MBOX_IGU1_IER_EN_SET(n)         (1 << (n))

/*
 *  *  Mailbox IGU3 Registers
 *   */
#define MBOX_IGU3_ISRC                  PPE_REG_ADDR(0x0215)
#define MBOX_IGU3_IER                   PPE_REG_ADDR(0x0217)

#define MBOX_IGU3_ISRS_SET(n)           (1 << (n))
#define MBOX_IGU3_ISRC_CLEAR(n)         (1 << (n))
#define MBOX_IGU3_ISR_ISR(n)            (*MBOX_IGU3_ISR & (1 << (n)))
#define MBOX_IGU3_IER_EN(n)             (*MBOX_IGU3_IER & (1 << (n)))
#define MBOX_IGU3_IER_EN_SET(n)         (1 << (n))


// RX Frame Definitions
#define MAX_RX_PACKET_ALIGN_BYTES       3
#define MAX_RX_PACKET_PADDING_BYTES     3
#define RX_INBAND_TRAILER_LENGTH        8
#define MAX_RX_FRAME_EXTRA_BYTES        (RX_INBAND_TRAILER_LENGTH + MAX_RX_PACKET_ALIGN_BYTES + MAX_RX_PACKET_PADDING_BYTES)

// TX Frame Definitions
#define MAX_TX_HEADER_ALIGN_BYTES       12
#define MAX_TX_PACKET_ALIGN_BYTES       3
#define MAX_TX_PACKET_PADDING_BYTES     3
#define TX_INBAND_HEADER_LENGTH         8
#define MAX_TX_FRAME_EXTRA_BYTES        (TX_INBAND_HEADER_LENGTH + MAX_TX_HEADER_ALIGN_BYTES + MAX_TX_PACKET_ALIGN_BYTES + MAX_TX_PACKET_PADDING_BYTES)


// DWORD-Length of Memory Blocks
#define PP32_DEBUG_REG_DWLEN            0x0030
#define PPM_INT_REG_DWLEN               0x0010
#define PP32_INTERNAL_RES_DWLEN         0x00C0
#define PPE_CLOCK_CONTROL_DWLEN         0x0F00
#define CDM_CODE_MEMORY_RAM0_DWLEN      0x1000
#define CDM_CODE_MEMORY_RAM1_DWLEN      0x0800
#define PPE_REG_DWLEN                   0x1000
#define PP32_DATA_MEMORY_RAM1_DWLEN     0x0800
#define PPM_INT_UNIT_DWLEN              0x0100
#define PPM_TIMER0_DWLEN                0x0100
#define PPM_TASK_IND_REG_DWLEN          0x0100
#define PPS_BRK_DWLEN                   0x0100
#define PPM_TIMER1_DWLEN                0x0100
#define SB_RAM0_DWLEN                   0x0400
#define SB_RAM1_DWLEN                   0x0800
#define SB_RAM2_DWLEN                   0x0A00
#define SB_RAM3_DWLEN                   0x0400
#define QSB_CONF_REG_DWLEN              0x0100
/*
 *  QSB Queue Scheduling and Shaping Definitions
 */
#define QSB_WFQ_NONUBR_MAX              0x3f00
#define QSB_WFQ_UBR_BYPASS              0x3fff
#define QSB_TP_TS_MAX                   65472
#define QSB_TAUS_MAX                    64512
#define QSB_GCR_MIN                     18



// OAM Definitions
#define OAM_RX_QUEUE_NUMBER             1
#define OAM_TX_QUEUE_NUMBER_PER_PORT    0
#define OAM_RX_DMA_CHANNEL_NUMBER       OAM_RX_QUEUE_NUMBER
#define OAM_HTU_ENTRY_NUMBER            3
#define OAM_F4_SEG_HTU_ENTRY            0
#define OAM_F4_TOT_HTU_ENTRY            1
#define OAM_F5_HTU_ENTRY                2
#define OAM_F4_CELL_ID                  0
#define OAM_F5_CELL_ID                  15

// ATM Port, QSB Queue, DMA RX/TX Channel Parameters
#define ATM_PORT_NUMBER                 2
#define MAX_QUEUE_NUMBER                16
#define QSB_QUEUE_NUMBER_BASE           1
#define MAX_QUEUE_NUMBER_PER_PORT       (MAX_QUEUE_NUMBER - QSB_QUEUE_NUMBER_BASE)
#define MAX_CONNECTION_NUMBER           MAX_QUEUE_NUMBER
#define MAX_RX_DMA_CHANNEL_NUMBER       8
#define MAX_TX_DMA_CHANNEL_NUMBER       16
#define DMA_ALIGNMENT                   4

#define DEFAULT_RX_HUNT_BITTH           4

/*
 *  FPI Configuration Bus Register and Memory Address Mapping
 */
#define DANUBE_PPE                      (KSEG1 + 0x1E180000)
#define PP32_DEBUG_REG_ADDR(x)          ((volatile u32*)(DANUBE_PPE + (((x) + 0x0000) << 2)))
#define PPM_INT_REG_ADDR(x)             ((volatile u32*)(DANUBE_PPE + (((x) + 0x0030) << 2)))
#define PP32_INTERNAL_RES_ADDR(x)       ((volatile u32*)(DANUBE_PPE + (((x) + 0x0040) << 2)))
#define PPE_CLOCK_CONTROL_ADDR(x)       ((volatile u32*)(DANUBE_PPE + (((x) + 0x0100) << 2)))
#define CDM_CODE_MEMORY_RAM0_ADDR(x)    ((volatile u32*)(DANUBE_PPE + (((x) + 0x1000) << 2)))
#define CDM_CODE_MEMORY_RAM1_ADDR(x)    ((volatile u32*)(DANUBE_PPE + (((x) + 0x2000) << 2)))
#define PPE_REG_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x4000) << 2)))
#define PP32_DATA_MEMORY_RAM1_ADDR(x)   ((volatile u32*)(DANUBE_PPE + (((x) + 0x5000) << 2)))
#define PPM_INT_UNIT_ADDR(x)            ((volatile u32*)(DANUBE_PPE + (((x) + 0x6000) << 2)))
#define PPM_TIMER0_ADDR(x)              ((volatile u32*)(DANUBE_PPE + (((x) + 0x6100) << 2)))
#define PPM_TASK_IND_REG_ADDR(x)        ((volatile u32*)(DANUBE_PPE + (((x) + 0x6200) << 2)))
#define PPS_BRK_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x6300) << 2)))
#define PPM_TIMER1_ADDR(x)              ((volatile u32*)(DANUBE_PPE + (((x) + 0x6400) << 2)))
#define SB_RAM0_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x8000) << 2)))
#define SB_RAM1_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x8400) << 2)))
#define SB_RAM2_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x8C00) << 2)))
#define SB_RAM3_ADDR(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0x9600) << 2)))
#define QSB_CONF_REG(x)                 ((volatile u32*)(DANUBE_PPE + (((x) + 0xC000) << 2)))

/*
 *  Host-PPE Communication Data Address Mapping
 */
#define CFG_WRX_HTUTS                   PPM_INT_UNIT_ADDR(0x2400)   /*  WAN RX HTU Table Size, must be configured before enable PPE firmware.   */
#define CFG_WRX_QNUM                    PPM_INT_UNIT_ADDR(0x2401)   /*  WAN RX Queue Number */
#define CFG_WRX_DCHNUM                  PPM_INT_UNIT_ADDR(0x2402)   /*  WAN RX DMA Channel Number, no more than 8, must be configured before enable PPE firmware.   */
#define CFG_WTX_DCHNUM                  PPM_INT_UNIT_ADDR(0x2403)   /*  WAN TX DMA Channel Number, no more than 16, must be configured before enable PPE firmware.  */
#define CFG_WRDES_DELAY                 PPM_INT_UNIT_ADDR(0x2404)   /*  WAN Descriptor Write Delay, must be configured before enable PPE firmware.  */
#define WRX_DMACH_ON                    PPM_INT_UNIT_ADDR(0x2405)   /*  WAN RX DMA Channel Enable, must be configured before enable PPE firmware.   */
#define WTX_DMACH_ON                    PPM_INT_UNIT_ADDR(0x2406)   /*  WAN TX DMA Channel Enable, must be configured before enable PPE firmware.   */
#define WRX_HUNT_BITTH                  PPM_INT_UNIT_ADDR(0x2407)   /*  WAN RX HUNT Threshold, must be between 2 to 8.  */
#define WRX_QUEUE_CONFIG(i)             ((struct wrx_queue_config*)PPM_INT_UNIT_ADDR(0x2500 + (i) * 20))
#define WRX_DMA_CHANNEL_CONFIG(i)       ((struct wrx_dma_channel_config*)PPM_INT_UNIT_ADDR(0x2640 + (i) * 7))
#define WTX_PORT_CONFIG(i)              ((struct wtx_port_config*)PPM_INT_UNIT_ADDR(0x2440 + (i)))
#define WTX_QUEUE_CONFIG(i)             ((struct wtx_queue_config*)PPM_INT_UNIT_ADDR(0x2710 + (i) * 27))
#define WTX_DMA_CHANNEL_CONFIG(i)       ((struct wtx_dma_channel_config*)PPM_INT_UNIT_ADDR(0x2711 + (i) * 27))
#define WAN_MIB_TABLE                   ((struct wan_mib_table*)PPM_INT_UNIT_ADDR(0x2410))
#define HTU_ENTRY(i)                    ((struct htu_entry*)PPM_INT_UNIT_ADDR(0x2000 + (i)))
#define HTU_MASK(i)                     ((struct htu_mask*)PPM_INT_UNIT_ADDR(0x2020 + (i)))
#define HTU_RESULT(i)                   ((struct htu_result*)PPM_INT_UNIT_ADDR(0x2040 + (i)))

// DREG Idle Counters
#define DREG_AT_CELL0                   PPE_REG_ADDR(0x0D24)
#define DREG_AT_CELL1                   PPE_REG_ADDR(0x0D25)
#define DREG_AT_IDLE_CNT0               PPE_REG_ADDR(0x0D26)
#define DREG_AT_IDLE_CNT1               PPE_REG_ADDR(0x0D27)
#define DREG_AR_CELL0                   PPE_REG_ADDR(0x0D68)
#define DREG_AR_CELL1                   PPE_REG_ADDR(0x0D69)
#define DREG_AR_IDLE_CNT0               PPE_REG_ADDR(0x0D6A)
#define DREG_AR_IDLE_CNT1               PPE_REG_ADDR(0x0D6B)
#define DREG_AR_AIIDLE_CNT0             PPE_REG_ADDR(0x0D6C)
#define DREG_AR_AIIDLE_CNT1             PPE_REG_ADDR(0x0D6D)
#define DREG_AR_BE_CNT0                 PPE_REG_ADDR(0x0D6E)
#define DREG_AR_BE_CNT1                 PPE_REG_ADDR(0x0D6F)


/*
 *  64-bit Data Type
 */
typedef struct {
    unsigned int    h: 32;
    unsigned int    l: 32;
} ppe_u64_t;

/*
 *  PPE ATM Cell Header
 */
#if defined(__BIG_ENDIAN)
    struct uni_cell_header {
        unsigned int        gfc     :4;
        unsigned int        vpi     :8;
        unsigned int        vci     :16;
        unsigned int        pti     :3;
        unsigned int        clp     :1;
    };
#else
    struct uni_cell_header {
        unsigned int        clp     :1;
        unsigned int        pti     :3;
        unsigned int        vci     :16;
        unsigned int        vpi     :8;
        unsigned int        gfc     :4;
    };
#endif  //  defined(__BIG_ENDIAN)

/*
 *  Inband Header and Trailer
 */
#if defined(__BIG_ENDIAN)
    struct rx_inband_trailer {
        /*  0 - 3h  */
        unsigned int        uu      :8;
        unsigned int        cpi     :8;
        unsigned int        stw_res1:4;
        unsigned int        stw_clp :1;
        unsigned int        stw_ec  :1;
        unsigned int        stw_uu  :1;
        unsigned int        stw_cpi :1;
        unsigned int        stw_ovz :1;
        unsigned int        stw_mfl :1;
        unsigned int        stw_usz :1;
        unsigned int        stw_crc :1;
        unsigned int        stw_il  :1;
        unsigned int        stw_ra  :1;
        unsigned int        stw_res2:2;
        /*  4 - 7h  */
        unsigned int        gfc     :4;
        unsigned int        vpi     :8;
        unsigned int        vci     :16;
        unsigned int        pti     :3;
        unsigned int        clp     :1;
    };

    struct tx_inband_header {
        /*  0 - 3h  */
        unsigned int        gfc     :4;
        unsigned int        vpi     :8;
        unsigned int        vci     :16;
        unsigned int        pti     :3;
        unsigned int        clp     :1;
        /*  4 - 7h  */
        unsigned int        uu      :8;
        unsigned int        cpi     :8;
        unsigned int        pad     :8;
        unsigned int        res1    :8;
    };
#else
    struct rx_inband_trailer {
        /*  0 - 3h  */
        unsigned int        stw_res2:2;
        unsigned int        stw_ra  :1;
        unsigned int        stw_il  :1;
        unsigned int        stw_crc :1;
        unsigned int        stw_usz :1;
        unsigned int        stw_mfl :1;
        unsigned int        stw_ovz :1;
        unsigned int        stw_cpi :1;
        unsigned int        stw_uu  :1;
        unsigned int        stw_ec  :1;
        unsigned int        stw_clp :1;
        unsigned int        stw_res1:4;
        unsigned int        cpi     :8;
        unsigned int        uu      :8;
        /*  4 - 7h  */
        unsigned int        clp     :1;
        unsigned int        pti     :3;
        unsigned int        vci     :16;
        unsigned int        vpi     :8;
        unsigned int        gfc     :4;
    };

    struct tx_inband_header {
        /*  0 - 3h  */
        unsigned int        clp     :1;
        unsigned int        pti     :3;
        unsigned int        vci     :16;
        unsigned int        vpi     :8;
        unsigned int        gfc     :4;
        /*  4 - 7h  */
        unsigned int        res1    :8;
        unsigned int        pad     :8;
        unsigned int        cpi     :8;
        unsigned int        uu      :8;
    };
#endif  //  defined(__BIG_ENDIAN)

struct wan_mib_table {
    unsigned int                     res1;
    unsigned int                     wrx_drophtu_cell;
    unsigned int                     wrx_dropdes_pdu;
    unsigned int                     wrx_correct_pdu;
    unsigned int                     wrx_err_pdu;
    unsigned int                     wrx_dropdes_cell;
    unsigned int                     wrx_correct_cell;
    unsigned int                     wrx_err_cell;
    unsigned int                     wrx_total_byte;
    unsigned int                     wtx_total_pdu;
    unsigned int                     wtx_total_cell;
    unsigned int                     wtx_total_byte;
};

/*
 *  Internal Structure of Device
 */
struct port {
    int                     connection_base;        /*  first connection ID (RX/TX queue ID)    */
    unsigned int                     max_connections;        /*  maximum connection number               */
    unsigned int                     connection_table;       /*  connection opened status, every bit     */
    unsigned int                     tx_max_cell_rate;       /*  maximum cell rate                       */
    unsigned int                     tx_current_cell_rate;   /*  currently used cell rate                */
#if !defined(ENABLE_RX_QOS) || !ENABLE_RX_QOS
    int                     rx_dma_channel_base;    /*  first RX DMA channel ID                 */
    unsigned int                     rx_dma_channel_assigned;/*  totally RX DMA channels used            */
#endif  //  !defined(ENABLE_RX_QOS) || !ENABLE_RX_QOS
    int                     oam_tx_queue;           /*  first TX queue ID of OAM cell           */
    struct atm_dev          *dev;

};

struct connection {
    struct atm_vcc          *vcc;                   /*  opened VCC                              */
    struct timespec         access_time;            /*  time when last F4/F5 user cell arrives  */
    unsigned int                     aal5_vcc_crc_err;       /*  number of packets with CRC error        */
    unsigned int                     aal5_vcc_oversize_sdu;  /*  number of packets with oversize error   */
    int                     rx_dma_channel;         /*  RX DMA channel ID assigned              */
    int                     port;                   /*  to which port the connection belongs    */
    unsigned int                     rx_pdu;
    unsigned int                     rx_err_pdu;
    unsigned int                     rx_sw_drop_pdu;
    unsigned int                     tx_pdu;
    unsigned int                     tx_err_pdu;
    unsigned int                     tx_hw_drop_pdu;
    unsigned int                     tx_sw_drop_pdu;
};

struct ppe_dev {
    struct connection       connection[MAX_CONNECTION_NUMBER];
    struct port             port[ATM_PORT_NUMBER];

    struct aal5 {
        unsigned char              padding_byte;               /*  padding byte pattern of AAL5 packet     */
        unsigned int             rx_max_packet_size;         /*  max AAL5 packet length                  */
        unsigned int             rx_min_packet_size;         /*  min AAL5 packet length                  */
        unsigned int             rx_buffer_size;             /*  max memory allocated for a AAL5 packet  */
        unsigned int             tx_max_packet_size;         /*  max AAL5 packet length                  */
        unsigned int             tx_min_packet_size;         /*  min AAL5 packet length                  */
        unsigned int             tx_buffer_size;             /*  max memory allocated for a AAL5 packet  */
        unsigned int    rx_drop_error_packet;       /*  1: drop error packet, 0: ignore errors  */
    }                       aal5;

    struct qsb {
        unsigned int             tau;                        /*  cell delay variation due to concurrency */
        unsigned int             tstepc;                     /*  shceduler burst length                  */
        unsigned int             sbl;                        /*  time step                               */
    }                       qsb;

    struct dma {
        unsigned int             rx_descriptor_number;       /*  number of RX descriptors                */
        unsigned int             tx_descriptor_number;       /*  number of TX descriptors                */
        unsigned int             rx_clp1_desc_threshold;     /*  threshold to drop cells with CLP1       */
        unsigned int             write_descriptor_delay;     /*  delay on descriptor write path          */
        unsigned int             rx_total_channel_used;      /*  total RX channel used                   */
        void            *rx_descriptor_addr;        /*  base address of memory allocated for    */
        struct rx_descriptor
                        *rx_descriptor_base;        /*  base address of RX descriptors          */
        int             rx_desc_read_pos[MAX_RX_DMA_CHANNEL_NUMBER];    /*  first RX descriptor */
                                                                        /*  to be read          */
//        struct sk_buff  **rx_skb_pointers;          /*  base address of RX sk_buff pointers     */

#if defined(ENABLE_RX_QOS) && ENABLE_RX_QOS
        long            rx_weight[MAX_RX_DMA_CHANNEL_NUMBER];           /*  RX schedule weight  */
        long            rx_default_weight[MAX_RX_DMA_CHANNEL_NUMBER];   /*  default weight      */
#endif

        unsigned int             tx_total_channel_used;      /*  total TX channel used                   */
        void            *tx_descriptor_addr;        /*  base address of memory allocated for    */
                                                    /*  TX descriptors                          */
        struct tx_descriptor
                        *tx_descriptor_base;        /*  base address of TX descriptors          */
        int             tx_desc_alloc_pos[MAX_TX_DMA_CHANNEL_NUMBER];   /*  first TX descriptor */
                                                                        /*  could be allocated  */
//        int             tx_desc_alloc_num[MAX_TX_DMA_CHANNEL_NUMBER];   /*  number of allocated */
//                                                                        /*  TX descriptors      */
        int             tx_desc_alloc_flag[MAX_TX_DMA_CHANNEL_NUMBER];  /*  at least one TX     */
                                                                        /*  descriptor is alloc */
//        int             tx_desc_send_pos[MAX_TX_DMA_CHANNEL_NUMBER];    /*  first TX descriptor */
//                                                                        /*  to be send          */
        int             tx_desc_release_pos[MAX_TX_DMA_CHANNEL_NUMBER]; /*  first TX descriptor */
                                                                        /*  to be released      */
        struct sk_buff  **tx_skb_pointers;          /*  base address of TX sk_buff pointers     */
    }                       dma;

    struct mib {
        ppe_u64_t       wrx_total_byte;             /*  bit-64 extention of MIB table member    */
        ppe_u64_t       wtx_total_byte;             /*  bit-64 extention of MIB talbe member    */

        unsigned int             wrx_pdu;                    /*  successfully received AAL5 packet       */
        unsigned int             wrx_drop_pdu;               /*  AAL5 packet dropped by driver on RX     */
        unsigned int             wtx_err_pdu;                /*  error AAL5 packet                       */
        unsigned int             wtx_drop_pdu;               /*  AAL5 packet dropped by driver on TX     */
    }                       mib;
    struct wan_mib_table    prev_mib;

    int                     oam_rx_queue;           /*  RX queue ID of OAM cell                 */
    int                     oam_rx_dma_channel;     /*  RX DMA channel ID of OAM cell           */
    int                     max_connections;        /*  total connections available             */

    struct semaphore        sem;                    /*  lock used by open/close function        */
};

/*
 *  Host-PPE Communication Data Structure
 */
#if defined(__BIG_ENDIAN)
    struct wrx_queue_config {
        /*  0h  */
        unsigned int    res2        :27;
        unsigned int    dmach       :4;
        unsigned int    errdp       :1;
        /*  1h  */
        unsigned int    oversize    :16;
        unsigned int    undersize   :16;
        /*  2h  */
        unsigned int    res1        :16;
        unsigned int    mfs         :16;
        /*  3h  */
        unsigned int    uumask      :8;
        unsigned int    cpimask     :8;
        unsigned int    uuexp       :8;
        unsigned int    cpiexp      :8;
    };

    struct wtx_port_config {
        unsigned int    res1        :27;
        unsigned int    qid         :4;
        unsigned int    qsben       :1;
    };

    struct wtx_queue_config {
        unsigned int    res1        :25;
        unsigned int    sbid        :1;
        unsigned int    res2        :3;
        unsigned int    type        :2;
        unsigned int    qsben       :1;
    };

    struct wrx_dma_channel_config {
        /*  0h  */
        unsigned int    res1        :1;
        unsigned int    mode        :2;
        unsigned int    rlcfg       :1;
        unsigned int    desba       :28;
        /*  1h  */
        unsigned int    chrl        :16;
        unsigned int    clp1th      :16;
        /*  2h  */
        unsigned int    deslen      :16;
        unsigned int    vlddes      :16;
    };

    struct wtx_dma_channel_config {
        /*  0h  */
        unsigned int    res2        :1;
        unsigned int    mode        :2;
        unsigned int    res3        :1;
        unsigned int    desba       :28;
        /*  1h  */
        unsigned int    res1        :32;
        /*  2h  */
        unsigned int    deslen      :16;
        unsigned int    vlddes      :16;
    };

    struct htu_entry {
        unsigned int    res1        :2;
        unsigned int    pid         :2;
        unsigned int    vpi         :8;
        unsigned int    vci         :16;
        unsigned int    pti         :3;
        unsigned int    vld         :1;
    };

    struct htu_mask {
        unsigned int    set         :2;
        unsigned int    pid_mask    :2;
        unsigned int    vpi_mask    :8;
        unsigned int    vci_mask    :16;
        unsigned int    pti_mask    :3;
        unsigned int    clear       :1;
    };

   struct htu_result {
        unsigned int    res1        :12;
        unsigned int    cellid      :4;
        unsigned int    res2        :5;
        unsigned int    type        :1;
        unsigned int    ven         :1;
        unsigned int    res3        :5;
        unsigned int    qid         :4;
    };

    struct rx_descriptor {
        /*  0 - 3h  */
        unsigned int    own         :1;
        unsigned int    c           :1;
        unsigned int    sop         :1;
        unsigned int    eop         :1;
        unsigned int    res1        :3;
        unsigned int    byteoff     :2;
        unsigned int    res2        :2;
        unsigned int    id          :4;
        unsigned int    err         :1;
        unsigned int    datalen     :16;
        /*  4 - 7h  */
        unsigned int    res3        :4;
        unsigned int    dataptr     :28;
    };

    struct tx_descriptor {
        /*  0 - 3h  */
        unsigned int    own         :1;
        unsigned int    c           :1;
        unsigned int    sop         :1;
        unsigned int    eop         :1;
        unsigned int    byteoff     :5;
        unsigned int    res1        :5;
        unsigned int    iscell      :1;
        unsigned int    clp         :1;
        unsigned int    datalen     :16;
        /*  4 - 7h  */
        unsigned int    res2        :4;
        unsigned int    dataptr     :28;
    };
#else
    struct wrx_queue_config {
        /*  0h  */
        unsigned int    errdp       :1;
        unsigned int    dmach       :4;
        unsigned int    res2        :27;
        /*  1h  */
        unsigned int    undersize   :16;
        unsigned int    oversize    :16;
        /*  2h  */
        unsigned int    mfs         :16;
        unsigned int    res1        :16;
        /*  3h  */
        unsigned int    cpiexp      :8;
        unsigned int    uuexp       :8;
        unsigned int    cpimask     :8;
        unsigned int    uumask      :8;
    };

    struct wtx_port_config {
        unsigned int    qsben       :1;
        unsigned int    qid         :4;
        unsigned int    res1        :27;
    };

    struct wtx_queue_config {
        unsigned int    qsben       :1;
        unsigned int    type        :2;
        unsigned int    res2        :3;
        unsigned int    sbid        :1;
        unsigned int    res1        :25;
    };

    struct wrx_dma_channel_config
    {
        /*  0h  */
        unsigned int    desba       :28;
        unsigned int    rlcfg       :1;
        unsigned int    mode        :2;
        unsigned int    res1        :1;
        /*  1h  */
        unsigned int    clp1th      :16;
        unsigned int    chrl        :16;
        /*  2h  */
        unsigned int    vlddes      :16;
        unsigned int    deslen      :16;
    };

    struct wtx_dma_channel_config {
        /*  0h  */
        unsigned int    desba       :28;
        unsigned int    res3        :1;
        unsigned int    mode        :2;
        unsigned int    res2        :1;
        /*  1h  */
        unsigned int    res1        :32;
        /*  2h  */
        unsigned int    vlddes      :16;
        unsigned int    deslen      :16;
    };

    struct rx_descriptor {
        /*  4 - 7h  */
        unsigned int    dataptr     :28;
        unsigned int    res3        :4;
        /*  0 - 3h  */
        unsigned int    datalen     :16;
        unsigned int    err         :1;
        unsigned int    id          :4;
        unsigned int    res2        :2;
        unsigned int    byteoff     :2;
        unsigned int    res1        :3;
        unsigned int    eop         :1;
        unsigned int    sop         :1;
        unsigned int    c           :1;
        unsigned int    own         :1;
    };

    struct tx_descriptor {
        /*  4 - 7h  */
        unsigned int    dataptr     :28;
        unsigned int    res2        :4;
        /*  0 - 3h  */
        unsigned int    datalen     :16;
        unsigned int    clp         :1;
        unsigned int    iscell      :1;
        unsigned int    res1        :5;
        unsigned int    byteoff     :5;
        unsigned int    eop         :1;
        unsigned int    sop         :1;
        unsigned int    c           :1;
        unsigned int    own         :1;
    };
#endif  //  defined(__BIG_ENDIAN)

/*
 *  QSB Queue Parameter Table Entry and Queue VBR Parameter Table Entry
 */
#if defined(__BIG_ENDIAN)
    union qsb_queue_parameter_table {
        struct {
            unsigned int    res1    :1;
            unsigned int    vbr     :1;
            unsigned int    wfqf    :14;
            unsigned int    tp      :16;
        }               bit;
        unsigned int             dword;
    };

    union qsb_queue_vbr_parameter_table {
        struct {
            unsigned int    taus    :16;
            unsigned int    ts      :16;
        }               bit;
        unsigned int             dword;
    };
#else
    union qsb_queue_parameter_table {
        struct {
            unsigned int    tp      :16;
            unsigned int    wfqf    :14;
            unsigned int    vbr     :1;
            unsigned int    res1    :1;
        }               bit;
        unsigned int             dword;
    };

    union qsb_queue_vbr_parameter_table {
        struct {
            unsigned int    ts      :16;
            unsigned int    taus    :16;
        }               bit;
        unsigned int             dword;
    };
#endif  //  defined(__BIG_ENDIAN)


typedef enum
{
    IAD_ATM_CBR     = 6,						/* IAD_ATM_PRI_HIGH,							*/
    IAD_ATM_VBR_RT  = 4,						/* IAD_ATM_PRI_MED_HIGH,	VBR, Real-Time 		*/
    IAD_ATM_VBR_NRT = 2,						/* IAD_ATM_PRI_MED_LOW,     VBR, Non-Real-Time 	*/
    IAD_ATM_UBR     = 0,						/* IAD_ATM_PRI_LOW		  						*/
} iad_atmServiceCategory;

typedef	unsigned int iad_atmDiffServCategory;

typedef struct 
{
   int cellRate;
   int round;   /* IAD_ATM_RATE_CEILING, IAD_ATM_RATE_FLOOR */
} iad_atmCellRateDesc;

typedef struct 
{
    unsigned int               phyID;          /* IAD_ATM_PHY0, IAD_ATM_PHY1 */
    unsigned int               txQHnd;         /* Tx HW Q */
    union _pri
    {
        int                     priority;       /* TS Q:    4 priorities: IAD_ATM_PRI_HIGH, IAD_ATM_PRI_MED_HIGH, IAD_ATM_PRI_MED_LOW, IAD_ATM_PRI_LOW
                                                  non-TS Q: 8 priorities: IAD_ATM_PRI_LEVEL_7, IAD_ATM_PRI_LEVEL_6,..., IAD_ATM_PRI_LEVEL_0 */
        iad_atmServiceCategory  qosClass;       /* IAD_ATM_CBR, IAD_ATM_VBR_RT, IAD_ATM_VBR_NRT, IAD_ATM_UBR */
        iad_atmDiffServCategory diffServClass;  /* IP_QOS */
    } srvCat; /* service category */
    iad_atmCellRateDesc         pcr;            /* Peak Cell Rate */
    iad_atmCellRateDesc         scr;            /* Sustained Cell Rate. */
    iad_atmCellRateDesc         mcr;            /* Minimum Cell Rate, not used */
    int                         mbs;            /* maximum bursting size in cells */
    int                         isPrioritize;   /* TRUE: This flow is of the higher priority than the flows of the same QOS category.(Use MCR to boost priority) */
} iad_atmTrfPar; /* Tx Traffic Parameters */

typedef struct
{
    unsigned int    txGrpId;
    unsigned int    flowId;
    iad_atmTrfPar   trfPar;
} Atm_Ictl_Flow_Set;

typedef struct
{
    unsigned int    txGrpId;
    unsigned int    vpi;
    unsigned int    vci;

    unsigned int    encaps;
    unsigned int    proto;

} Atm_Ictl_Open_Vcc;

typedef struct
{
    struct atm_vcc			vcc;
	unsigned int 			valid;
	unsigned int 			on;
    unsigned int			vccIndex; /* 0~7 */
	unsigned int 			itf;
    struct net_device_stats	stats; 
} Atm_Priv;


extern struct ppe_dev ppe_dev;


int pp32_start(void);
void pp32_stop(void);
void init_rx_tables(void);
void init_tx_tables(void);
struct sk_buff* alloc_skb_rx(void);
struct sk_buff* alloc_skb_tx(unsigned int);
void resize_skb_rx(struct sk_buff *, unsigned int, int);
struct sk_buff* atm_alloc_tx(struct atm_vcc *, unsigned int);
void atm_free_tx_skb_vcc(struct sk_buff *);
int alloc_tx_connection(int);
int ppe_open(struct atm_vcc *vcc);
void ppe_close(struct atm_vcc *vcc);
int ppe_ioctl(struct atm_dev *dev, unsigned int cmd, void *arg);
int ppe_send(struct atm_vcc *vcc, struct sk_buff *skb);
int ppe_send_oam(struct atm_vcc *vcc, void *cell, int flags);
int ppe_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags);
irqreturn_t mailbox_irq_handler(int, void *);
int find_vcc(struct atm_vcc *vcc);
int find_vpi(unsigned int vpi);
int find_vpivci(unsigned int vpi, unsigned int vci);
void mailbox_signal(unsigned int channel, int is_tx);