]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/emacps_v2_0/src/xemacps.c
cfad9bc5f9bac35dc2e272b00918aa285fb79b81
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo_bsp / ps7_cortexa9_0 / libsrc / emacps_v2_0 / src / xemacps.c
1 /* $Id: xemacps.c,v 1.1.2.3 2011/05/17 12:00:33 anirudh 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.c
37 *
38 * The XEmacPs driver. Functions in this file are the minimum required functions
39 * for this driver. 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 * </pre>
48 ******************************************************************************/
49
50 /***************************** Include Files *********************************/
51
52 #include "xemacps.h"
53
54 /************************** Constant Definitions *****************************/
55
56
57 /**************************** Type Definitions *******************************/
58
59
60 /***************** Macros (Inline Functions) Definitions *********************/
61
62
63 /************************** Function Prototypes ******************************/
64
65 void XEmacPs_StubHandler(void); /* Default handler routine */
66
67 /************************** Variable Definitions *****************************/
68
69
70 /*****************************************************************************/
71 /**
72 * Initialize a specific XEmacPs instance/driver. The initialization entails:
73 * - Initialize fields of the XEmacPs instance structure
74 * - Reset hardware and apply default options
75 * - Configure the DMA channels
76 *
77 * The PHY is setup independently from the device. Use the MII or whatever other
78 * interface may be present for setup.
79 *
80 * @param InstancePtr is a pointer to the instance to be worked on.
81 * @param CfgPtr is the device configuration structure containing required
82 *        hardware build data.
83 * @param EffectiveAddress is the base address of the device. If address
84 *        translation is not utilized, this parameter can be passed in using
85 *        CfgPtr->Config.BaseAddress to specify the physical base address.
86 *
87 * @return
88 * - XST_SUCCESS if initialization was successful
89 *
90 ******************************************************************************/
91 int XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
92                            u32 EffectiveAddress)
93 {
94         /* Verify arguments */
95         Xil_AssertNonvoid(InstancePtr != NULL);
96         Xil_AssertNonvoid(CfgPtr != NULL);
97
98         /* Set device base address and ID */
99         InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
100         InstancePtr->Config.BaseAddress = EffectiveAddress;
101
102         /* Set callbacks to an initial stub routine */
103         InstancePtr->SendHandler = (XEmacPs_Handler) XEmacPs_StubHandler;
104         InstancePtr->RecvHandler = (XEmacPs_Handler) XEmacPs_StubHandler;
105         InstancePtr->ErrorHandler = (XEmacPs_ErrHandler) XEmacPs_StubHandler;
106
107         /* Reset the hardware and set default options */
108         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
109         XEmacPs_Reset(InstancePtr);
110
111         return (XST_SUCCESS);
112 }
113
114
115 /*****************************************************************************/
116 /**
117 * Start the Ethernet controller as follows:
118 *   - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
119 *   - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
120 *   - Start the SG DMA send and receive channels and enable the device
121 *     interrupt
122 *
123 * @param InstancePtr is a pointer to the instance to be worked on.
124 *
125 * @return N/A
126 *
127 * @note
128 * Hardware is configured with scatter-gather DMA, the driver expects to start
129 * the scatter-gather channels and expects that the user has previously set up
130 * the buffer descriptor lists.
131 *
132 * This function makes use of internal resources that are shared between the
133 * Start, Stop, and Set/ClearOptions functions. So if one task might be setting
134 * device options while another is trying to start the device, the user is
135 * required to provide protection of this shared data (typically using a
136 * semaphore).
137 *
138 * This function must not be preempted by an interrupt that may service the
139 * device.
140 *
141 ******************************************************************************/
142 void XEmacPs_Start(XEmacPs *InstancePtr)
143 {
144         u32 Reg;
145
146         /* Assert bad arguments and conditions */
147         Xil_AssertVoid(InstancePtr != NULL);
148         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
149         Xil_AssertVoid(InstancePtr->RxBdRing.BaseBdAddr != 0);
150         Xil_AssertVoid(InstancePtr->TxBdRing.BaseBdAddr != 0);
151
152         /* If already started, then there is nothing to do */
153         if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
154                 return;
155         }
156
157         /* Start DMA */
158         /* When starting the DMA channels, both transmit and receive sides
159          * need an initialized BD list.
160          */
161         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
162                            XEMACPS_RXQBASE_OFFSET,
163                            InstancePtr->RxBdRing.BaseBdAddr);
164
165         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
166                            XEMACPS_TXQBASE_OFFSET,
167                            InstancePtr->TxBdRing.BaseBdAddr);
168
169         /* clear any existed int status */
170         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
171                            XEMACPS_IXR_ALL_MASK);
172
173         /* Enable transmitter if not already enabled */
174         if (InstancePtr->Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
175                 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
176                                         XEMACPS_NWCTRL_OFFSET);
177                 if (!(Reg & XEMACPS_NWCTRL_TXEN_MASK)) {
178                         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
179                                            XEMACPS_NWCTRL_OFFSET,
180                                            Reg | XEMACPS_NWCTRL_TXEN_MASK);
181                 }
182         }
183
184         /* Enable receiver if not already enabled */
185         if (InstancePtr->Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
186                 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
187                                         XEMACPS_NWCTRL_OFFSET);
188                 if (!(Reg & XEMACPS_NWCTRL_RXEN_MASK)) {
189                         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
190                                            XEMACPS_NWCTRL_OFFSET,
191                                            Reg | XEMACPS_NWCTRL_RXEN_MASK);
192                 }
193         }
194
195         /* Enable TX and RX interrupts */
196         XEmacPs_IntEnable(InstancePtr, (XEMACPS_IXR_TX_ERR_MASK |
197                 XEMACPS_IXR_RX_ERR_MASK | XEMACPS_IXR_FRAMERX_MASK |
198                 XEMACPS_IXR_TXCOMPL_MASK));
199
200         /* Mark as started */
201         InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
202
203         return;
204 }
205
206
207 /*****************************************************************************/
208 /**
209 * Gracefully stop the Ethernet MAC as follows:
210 *   - Disable all interrupts from this device
211 *   - Stop DMA channels
212 *   - Disable the tansmitter and receiver
213 *
214 * Device options currently in effect are not changed.
215 *
216 * This function will disable all interrupts. Default interrupts settings that
217 * had been enabled will be restored when XEmacPs_Start() is called.
218 *
219 * @param InstancePtr is a pointer to the instance to be worked on.
220 *
221 * @note
222 * This function makes use of internal resources that are shared between the
223 * Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
224 * setting device options while another is trying to start the device, the user
225 * is required to provide protection of this shared data (typically using a
226 * semaphore).
227 *
228 * Stopping the DMA channels causes this function to block until the DMA
229 * operation is complete.
230 *
231 ******************************************************************************/
232 void XEmacPs_Stop(XEmacPs *InstancePtr)
233 {
234         u32 Reg;
235
236         Xil_AssertVoid(InstancePtr != NULL);
237         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
238
239         /* Disable all interrupts */
240         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
241                            XEMACPS_IXR_ALL_MASK);
242
243         /* Disable the receiver & transmitter */
244         Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
245                                 XEMACPS_NWCTRL_OFFSET);
246         Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
247         Reg &= ~XEMACPS_NWCTRL_TXEN_MASK;
248         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
249                            XEMACPS_NWCTRL_OFFSET, Reg);
250
251         /* Mark as stopped */
252         InstancePtr->IsStarted = 0;
253 }
254
255
256 /*****************************************************************************/
257 /**
258 * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
259 * transmitter, and the receiver.
260 *
261 * Steps to reset
262 * - Stops transmit and receive channels
263 * - Stops DMA
264 * - Configure transmit and receive buffer size to default
265 * - Clear transmit and receive status register and counters
266 * - Clear all interrupt sources
267 * - Clear phy (if there is any previously detected) address
268 * - Clear MAC addresses (1-4) as well as Type IDs and hash value
269 *
270 * All options are placed in their default state. Any frames in the
271 * descriptor lists will remain in the lists. The side effect of doing
272 * this is that after a reset and following a restart of the device, frames
273 * were in the list before the reset may be transmitted or received.
274 *
275 * The upper layer software is responsible for re-configuring (if necessary)
276 * and restarting the MAC after the reset. Note also that driver statistics
277 * are not cleared on reset. It is up to the upper layer software to clear the
278 * statistics if needed.
279 *
280 * When a reset is required, the driver notifies the upper layer software of
281 * this need through the ErrorHandler callback and specific status codes.
282 * The upper layer software is responsible for calling this Reset function
283 * and then re-configuring the device.
284 *
285 * @param InstancePtr is a pointer to the instance to be worked on.
286 *
287 ******************************************************************************/
288 void XEmacPs_Reset(XEmacPs *InstancePtr)
289 {
290         u32 Reg;
291         u8 i;
292         char EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
293
294         Xil_AssertVoid(InstancePtr != NULL);
295         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
296
297         /* Stop the device and reset hardware */
298         XEmacPs_Stop(InstancePtr);
299         InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
300
301         /* Setup hardware with default values */
302         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
303                         XEMACPS_NWCTRL_OFFSET,
304                         (XEMACPS_NWCTRL_STATCLR_MASK |
305                         XEMACPS_NWCTRL_MDEN_MASK) &
306                         ~XEMACPS_NWCTRL_LOOPEN_MASK);
307
308         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
309                                         XEMACPS_NWCFG_OFFSET,
310                                         XEMACPS_NWCFG_100_MASK |
311                                         XEMACPS_NWCFG_FDEN_MASK |
312                                         XEMACPS_NWCFG_UCASTHASHEN_MASK);
313
314         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
315                         XEMACPS_DMACR_OFFSET,
316                         ((((XEMACPS_RX_BUF_SIZE / XEMACPS_RX_BUF_UNIT) +
317                                 ((XEMACPS_RX_BUF_SIZE %
318                                 XEMACPS_RX_BUF_UNIT) ? 1 : 0)) <<
319                                 XEMACPS_DMACR_RXBUF_SHIFT) &
320                                 XEMACPS_DMACR_RXBUF_MASK) |
321                                 XEMACPS_DMACR_RXSIZE_MASK |
322                                 XEMACPS_DMACR_TXSIZE_MASK);
323
324         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
325                            XEMACPS_TXSR_OFFSET, 0x0);
326
327         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
328                            XEMACPS_RXQBASE_OFFSET, 0x0);
329
330         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
331                            XEMACPS_TXQBASE_OFFSET, 0x0);
332
333         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
334                            XEMACPS_RXSR_OFFSET, 0x0);
335
336         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
337                            XEMACPS_IXR_ALL_MASK);
338
339         Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
340                                 XEMACPS_ISR_OFFSET);
341         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
342                            Reg);
343
344         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
345                            XEMACPS_PHYMNTNC_OFFSET, 0x0);
346
347         XEmacPs_ClearHash(InstancePtr);
348
349         for (i = 1; i < 5; i++) {
350                 XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
351                 XEmacPs_SetTypeIdCheck(InstancePtr, 0x0, i);
352         }
353
354         /* clear all counters */
355         for (i = 0; i < (XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4;
356              i++) {
357                 XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
358                                    XEMACPS_OCTTXL_OFFSET + i * 4);
359         }
360
361         /* Disable the receiver */
362         Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
363                                 XEMACPS_NWCTRL_OFFSET);
364         Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
365         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
366                            XEMACPS_NWCTRL_OFFSET, Reg);
367
368         /* Sync default options with hardware but leave receiver and
369          * transmitter disabled. They get enabled with XEmacPs_Start() if
370          * XEMACPS_TRANSMITTER_ENABLE_OPTION and
371          * XEMACPS_RECEIVER_ENABLE_OPTION are set.
372          */
373         XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
374                             ~(XEMACPS_TRANSMITTER_ENABLE_OPTION |
375                               XEMACPS_RECEIVER_ENABLE_OPTION));
376
377         XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
378 }
379
380
381 /******************************************************************************/
382 /**
383  * This is a stub for the asynchronous callbacks. The stub is here in case the
384  * upper layer forgot to set the handler(s). On initialization, all handlers are
385  * set to this callback. It is considered an error for this handler to be
386  * invoked.
387  *
388  ******************************************************************************/
389 void XEmacPs_StubHandler(void)
390 {
391         Xil_AssertVoidAlways();
392 }