]> git.sur5r.net Git - freertos/blob
0e813ccc99fe7181ae8fe6cb33839c0aa347d5fc
[freertos] /
1 /* $Id: xemacps_intr.c,v 1.1.2.1 2011/01/20 03:39:02 sadanan Exp $ */
2 /******************************************************************************
3 *
4 * Copyright (C) 2010 - 2014 Xilinx, Inc.  All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal 
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * Use of the Software is limited solely to applications:
17 * (a) running on a Xilinx device, or
18 * (b) that interact with a Xilinx device through a bus or interconnect.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 
25 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 *
28 * Except as contained in this notice, the name of the Xilinx shall not be used
29 * in advertising or otherwise to promote the sale, use or other dealings in
30 * this Software without prior written authorization from Xilinx.
31 *
32 ******************************************************************************/
33 /*****************************************************************************/
34 /**
35 *
36 * @file xemacps_intr.c
37 *
38 * Functions in this file implement general purpose interrupt processing related
39 * functionality. See xemacps.h for a detailed description of the driver.
40 *
41 * <pre>
42 * MODIFICATION HISTORY:
43 *
44 * Ver   Who  Date     Changes
45 * ----- ---- -------- -------------------------------------------------------
46 * 1.00a wsy  01/10/10 First release
47 * 1.03a asa  01/24/13 Fix for CR #692702 which updates error handling for
48 *                     Rx errors. Under heavy Rx traffic, there will be a large
49 *                     number of errors related to receive buffer not available.
50 *                     Because of a HW bug (SI #692601), under such heavy errors,
51 *                     the Rx data path can become unresponsive. To reduce the
52 *                     probabilities for hitting this HW bug, the SW writes to
53 *                     bit 18 to flush a packet from Rx DPRAM immediately. The
54 *                     changes for it are done in the function
55 *                     XEmacPs_IntrHandler.
56 * </pre>
57 ******************************************************************************/
58
59 /***************************** Include Files *********************************/
60
61 #include "xemacps.h"
62
63 /************************** Constant Definitions *****************************/
64
65
66 /**************************** Type Definitions *******************************/
67
68
69 /***************** Macros (Inline Functions) Definitions *********************/
70
71
72 /************************** Function Prototypes ******************************/
73
74
75 /************************** Variable Definitions *****************************/
76
77
78 /*****************************************************************************/
79 /**
80  * Install an asynchronious handler function for the given HandlerType:
81  *
82  * @param InstancePtr is a pointer to the instance to be worked on.
83  * @param HandlerType indicates what interrupt handler type is.
84  *        XEMACPS_HANDLER_DMASEND, XEMACPS_HANDLER_DMARECV and
85  *        XEMACPS_HANDLER_ERROR.
86  * @param FuncPtr is the pointer to the callback function
87  * @param CallBackRef is the upper layer callback reference passed back when
88  *        when the callback function is invoked.
89  *
90  * @return
91  *
92  * None.
93  *
94  * @note
95  * There is no assert on the CallBackRef since the driver doesn't know what
96  * it is.
97  *
98  *****************************************************************************/
99 int XEmacPs_SetHandler(XEmacPs *InstancePtr, u32 HandlerType,
100                         void *FuncPtr, void *CallBackRef)
101 {
102         Xil_AssertNonvoid(InstancePtr != NULL);
103         Xil_AssertNonvoid(FuncPtr != NULL);
104         Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
105
106         switch (HandlerType) {
107         case XEMACPS_HANDLER_DMASEND:
108                 InstancePtr->SendHandler = (XEmacPs_Handler) FuncPtr;
109                 InstancePtr->SendRef = CallBackRef;
110                 break;
111         case XEMACPS_HANDLER_DMARECV:
112                 InstancePtr->RecvHandler = (XEmacPs_Handler) FuncPtr;
113                 InstancePtr->RecvRef = CallBackRef;
114                 break;
115         case XEMACPS_HANDLER_ERROR:
116                 InstancePtr->ErrorHandler = (XEmacPs_ErrHandler) FuncPtr;
117                 InstancePtr->ErrorRef = CallBackRef;
118                 break;
119         default:
120                 return (XST_INVALID_PARAM);
121         }
122         return (XST_SUCCESS);
123 }
124
125 /*****************************************************************************/
126 /**
127 * Master interrupt handler for EMAC driver. This routine will query the
128 * status of the device, bump statistics, and invoke user callbacks.
129 *
130 * This routine must be connected to an interrupt controller using OS/BSP
131 * specific methods.
132 *
133 * @param XEmacPsPtr is a pointer to the XEMACPS instance that has caused the
134 *        interrupt.
135 *
136 ******************************************************************************/
137 void XEmacPs_IntrHandler(void *XEmacPsPtr)
138 {
139         u32 RegISR;
140         u32 RegSR;
141         u32 RegCtrl;
142         XEmacPs *InstancePtr = (XEmacPs *) XEmacPsPtr;
143
144         Xil_AssertVoid(InstancePtr != NULL);
145         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
146
147         /* This ISR will try to handle as many interrupts as it can in a single
148          * call. However, in most of the places where the user's error handler
149          * is called, this ISR exits because it is expected that the user will
150          * reset the device in nearly all instances.
151          */
152         RegISR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
153                                    XEMACPS_ISR_OFFSET);
154
155         /* Clear the interrupt status register */
156         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
157                            RegISR);
158
159         /* Receive complete interrupt */
160         if (RegISR & (XEMACPS_IXR_FRAMERX_MASK)) {
161                 /* Clear RX status register RX complete indication but preserve
162                  * error bits if there is any */
163                 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
164                                    XEMACPS_RXSR_OFFSET,
165                                    XEMACPS_RXSR_FRAMERX_MASK |
166                                    XEMACPS_RXSR_BUFFNA_MASK);
167                 InstancePtr->RecvHandler(InstancePtr->RecvRef);
168         }
169
170         /* Transmit complete interrupt */
171         if (RegISR & (XEMACPS_IXR_TXCOMPL_MASK)) {
172                 /* Clear TX status register TX complete indication but preserve
173                  * error bits if there is any */
174                 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
175                                    XEMACPS_TXSR_OFFSET,
176                                    XEMACPS_TXSR_TXCOMPL_MASK |
177                                    XEMACPS_TXSR_USEDREAD_MASK);
178                 InstancePtr->SendHandler(InstancePtr->SendRef);
179         }
180
181         /* Receive error conditions interrupt */
182         if (RegISR & (XEMACPS_IXR_RX_ERR_MASK)) {
183                 /* Clear RX status register */
184                 RegSR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
185                                           XEMACPS_RXSR_OFFSET);
186                 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
187                                    XEMACPS_RXSR_OFFSET, RegSR);
188
189                 /* Fix for CR # 692702. Write to bit 18 of net_ctrl
190                  * register to flush a packet out of Rx SRAM upon
191                  * an error for receive buffer not available. */
192                 if (RegISR & XEMACPS_IXR_RXUSED_MASK) {
193                         RegCtrl =
194                         XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
195                                                 XEMACPS_NWCTRL_OFFSET);
196                         RegCtrl |= XEMACPS_NWCTRL_FLUSH_DPRAM_MASK;
197                         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
198                                         XEMACPS_NWCTRL_OFFSET, RegCtrl);
199                 }
200                 InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XEMACPS_RECV,
201                                           RegSR);
202         }
203
204         /* When XEMACPS_IXR_TXCOMPL_MASK is flaged, XEMACPS_IXR_TXUSED_MASK
205          * will be asserted the same time.
206          * Have to distinguish this bit to handle the real error condition.
207          */
208         /* Transmit error conditions interrupt */
209         if (RegISR & (XEMACPS_IXR_TX_ERR_MASK) &&
210             !(RegISR & (XEMACPS_IXR_TXCOMPL_MASK))) {
211                 /* Clear TX status register */
212                 RegSR = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
213                                           XEMACPS_TXSR_OFFSET);
214                 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
215                                    XEMACPS_TXSR_OFFSET, RegSR);
216                 InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XEMACPS_SEND,
217                                           RegSR);
218         }
219
220 }