3 #include <asm/amcc440.h>
6 #include <aros/debug.h>
7 #include <exec/types.h>
8 #include <exec/resident.h>
10 #include <exec/errors.h>
11 #include <exec/lists.h>
13 #include <aros/libcall.h>
14 #include <aros/symbolsets.h>
18 #include <devices/sana2.h>
19 #include <devices/sana2specialstats.h>
21 #include <proto/exec.h>
22 #include <proto/kernel.h>
26 #include LC_LIBDEFS_FILE
28 void rx_int(struct EMACUnit
*unit
, struct ExecBase
*SysBase
);
30 static void MALMRE(struct EMACBase
*EMACBase
, struct EMACUnit
*unit
)
32 //Cause(&unit->eu_RXInt);
33 rx_int(unit
, SysBase
);
36 static void MALIRQHandler(struct EMACBase
*EMACBase
, uint8_t inttype
)
43 /* get the information about channel causing the interrupt */
44 temp
= rddcr(MAL0_TXEOBISR
);
45 /* Clear the interrupt flag */
46 wrdcr(MAL0_TXEOBISR
, temp
);
50 /* get the information about channel causing the interrupt */
51 temp
= rddcr(MAL0_RXEOBISR
);
52 /* Clear the interrupt flag */
53 wrdcr(MAL0_RXEOBISR
, temp
);
54 if (temp
& 0x80000000)
55 MALMRE(EMACBase
, EMACBase
->emb_Units
[0]);
56 if (temp
& 0x40000000)
57 MALMRE(EMACBase
, EMACBase
->emb_Units
[0]);
61 D(bug("[EMAC ] MAL TXDE\n"));
65 D(bug("[EMAC ] MAL RXDE\n"));
69 D(bug("[EMAC ] MAL SERR\n"));
74 extern ULONG
GetPVR(void);
76 void EMAC_MAL_Init(struct EMACBase
*EMACBase
)
82 D(bug("[EMAC ] Memory Access Layer (MAL) Init\n"));
85 * Add all interrupt handlers required. Oh boy, MAL serves us FIVE different
89 KernelBase
= OpenResource("kernel.resource");
91 if (GetPVR() == PVR_PPC460EX_B
) {
92 EMACBase
->emb_MALHandlers
[0] = KrnAddIRQHandler(INTR_UIC2_MAL_TX_EOB
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MTE
);
93 EMACBase
->emb_MALHandlers
[1] = KrnAddIRQHandler(INTR_UIC2_MAL_RX_EOB
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MRE
);
94 EMACBase
->emb_MALHandlers
[2] = KrnAddIRQHandler(INTR_UIC2_MAL_TXDE
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MTDE
);
95 EMACBase
->emb_MALHandlers
[3] = KrnAddIRQHandler(INTR_UIC2_MAL_RXDE
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MRDE
);
96 EMACBase
->emb_MALHandlers
[4] = KrnAddIRQHandler(INTR_UIC2_MAL_SERR
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MS
);
98 EMACBase
->emb_MALHandlers
[0] = KrnAddIRQHandler(INTR_MTE
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MTE
);
99 EMACBase
->emb_MALHandlers
[1] = KrnAddIRQHandler(INTR_MRE
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MRE
);
100 EMACBase
->emb_MALHandlers
[2] = KrnAddIRQHandler(INTR_MTDE
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MTDE
);
101 EMACBase
->emb_MALHandlers
[3] = KrnAddIRQHandler(INTR_MRDE
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MRDE
);
102 EMACBase
->emb_MALHandlers
[4] = KrnAddIRQHandler(INTR_MS
, MALIRQHandler
, EMACBase
, (APTR
)INTR_MS
);
105 intptr_t buffers
= (intptr_t)AllocPooled(EMACBase
->emb_Pool
,
106 32 + 4 * (RX_RING_SIZE
+ TX_RING_SIZE
) * ((RXTX_ALLOC_BUFSIZE
+31)& ~31));
108 D(bug("[EMAC ] Allocating %d bytes @ %p for buffers\n",
109 32 + 4 * (RX_RING_SIZE
+ TX_RING_SIZE
) * ((RXTX_ALLOC_BUFSIZE
+31)& ~31), buffers
));
111 buffers
= (buffers
+ 31) & ~31;
113 /* Allocate memory for 2 RX channels */
114 for (i
=0; i
< 2; i
++)
118 EMACBase
->emb_MALRXChannels
[i
] = (void*)((intptr_t)AllocVecPooled(EMACBase
->emb_Pool
, 32 + RX_RING_SIZE
* sizeof(mal_descriptor_t
)) & ~31);
120 for (j
= 0; j
< RX_RING_SIZE
; j
++)
122 EMACBase
->emb_MALRXChannels
[i
][j
].md_buffer
= (char*)buffers
;
123 EMACBase
->emb_MALRXChannels
[i
][j
].md_length
= RXTX_ALLOC_BUFSIZE
;
124 EMACBase
->emb_MALRXChannels
[i
][j
].md_ctrl
= MAL_CTRL_RX_E
| MAL_CTRL_RX_I
;
126 buffers
+= (RXTX_ALLOC_BUFSIZE
+31) & ~31;
129 EMACBase
->emb_MALRXChannels
[i
][RX_RING_SIZE
-1].md_ctrl
|= MAL_CTRL_RX_W
;
131 CacheClearE(EMACBase
->emb_MALRXChannels
[i
], RX_RING_SIZE
* sizeof(mal_descriptor_t
), CACRF_ClearD
);
133 D(bug("[EMAC ] MAL RX Channel %d @ %p\n", i
, EMACBase
->emb_MALRXChannels
[i
]));
136 /* Allocate memory for 2 TX channels */
137 for (i
=0; i
< 2; i
++)
141 EMACBase
->emb_MALTXChannels
[i
] = (void*)((intptr_t)AllocVecPooled(EMACBase
->emb_Pool
, 32 + TX_RING_SIZE
* sizeof(mal_descriptor_t
)) & ~31);
143 for (j
= 0; j
< TX_RING_SIZE
; j
++)
145 EMACBase
->emb_MALTXChannels
[i
][j
].md_buffer
= (char*)buffers
;
146 EMACBase
->emb_MALTXChannels
[i
][j
].md_length
= RXTX_ALLOC_BUFSIZE
;
147 EMACBase
->emb_MALTXChannels
[i
][j
].md_ctrl
= 0;
149 buffers
+= (RXTX_ALLOC_BUFSIZE
+31) & ~31;
152 EMACBase
->emb_MALTXChannels
[i
][TX_RING_SIZE
- 1].md_ctrl
|= MAL_CTRL_TX_W
;
154 CacheClearE(EMACBase
->emb_MALTXChannels
[i
], RX_RING_SIZE
* sizeof(mal_descriptor_t
), CACRF_ClearD
);
156 D(bug("[EMAC ] MAL TX Channel %d @ %p\n", i
, EMACBase
->emb_MALTXChannels
[i
]));
160 /* Writing to DCR registers requires supervisor rights. */
161 stack
= SuperState();
163 /* Set the MAL dcr's containing pointers to the transfer descriptors */
164 // wrdcr(MAL0_TXCTP0R, (intptr_t)EMACBase->emb_MALTXChannels[0]);
165 // wrdcr(MAL0_TXCTP1R, (intptr_t)EMACBase->emb_MALTXChannels[1]);
166 // wrdcr(MAL0_TXCTP2R, (intptr_t)EMACBase->emb_MALTXChannels[2]);
167 // wrdcr(MAL0_TXCTP3R, (intptr_t)EMACBase->emb_MALTXChannels[3]);
168 wrdcr(MAL0_TXCTP0R
, (intptr_t)EMACBase
->emb_MALTXChannels
[0]);
169 wrdcr(MAL0_TXCTP2R
, (intptr_t)EMACBase
->emb_MALTXChannels
[1]);
170 wrdcr(MAL0_RXCTP0R
, (intptr_t)EMACBase
->emb_MALRXChannels
[0]);
171 wrdcr(MAL0_RXCTP1R
, (intptr_t)EMACBase
->emb_MALRXChannels
[1]);
173 /* Length of receive buffers */
174 wrdcr(MAL0_RCBS0
, (RXTX_ALLOC_BUFSIZE
+ 15) >> 4);
175 wrdcr(MAL0_RCBS1
, (RXTX_ALLOC_BUFSIZE
+ 15) >> 4);
178 wrdcr(MAL0_CFG
, MAL_CR_PLBB
| MAL_CR_OPBBL
| MAL_CR_LEA
| MAL_CR_PLBLT_DEFAULT
);