]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/emacps_v2_0/src/xemacps.c
Add back Zynq demo - this time using SDK V14.2.
[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 * (c) Copyright 2010 Xilinx, Inc. All rights reserved.
5 *
6 * This file contains confidential and proprietary information of Xilinx, Inc.
7 * and is protected under U.S. and international copyright and other
8 * intellectual property laws.
9 *
10 * DISCLAIMER
11 * This disclaimer is not a license and does not grant any rights to the
12 * materials distributed herewith. Except as otherwise provided in a valid
13 * license issued to you by Xilinx, and to the maximum extent permitted by
14 * applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL
15 * FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,
16 * IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
17 * MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;
18 * and (2) Xilinx shall not be liable (whether in contract or tort, including
19 * negligence, or under any other theory of liability) for any loss or damage
20 * of any kind or nature related to, arising under or in connection with these
21 * materials, including for any direct, or any indirect, special, incidental,
22 * or consequential loss or damage (including loss of data, profits, goodwill,
23 * or any type of loss or damage suffered as a result of any action brought by
24 * a third party) even if such damage or loss was reasonably foreseeable or
25 * Xilinx had been advised of the possibility of the same.
26 *
27 * CRITICAL APPLICATIONS
28 * Xilinx products are not designed or intended to be fail-safe, or for use in
29 * any application requiring fail-safe performance, such as life-support or
30 * safety devices or systems, Class III medical devices, nuclear facilities,
31 * applications related to the deployment of airbags, or any other applications
32 * that could lead to death, personal injury, or severe property or
33 * environmental damage (individually and collectively, "Critical
34 * Applications"). Customer assumes the sole risk and liability of any use of
35 * Xilinx products in Critical Applications, subject only to applicable laws
36 * and regulations governing limitations on product liability.
37 *
38 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
39 * AT ALL TIMES.
40 *
41 ******************************************************************************/
42 /*****************************************************************************/
43 /**
44 *
45 * @file xemacps.c
46 *
47 * The XEmacPs driver. Functions in this file are the minimum required functions
48 * for this driver. See xemacps.h for a detailed description of the driver.
49 *
50 * <pre>
51 * MODIFICATION HISTORY:
52 *
53 * Ver   Who  Date     Changes
54 * ----- ---- -------- -------------------------------------------------------
55 * 1.00a wsy  01/10/10 First release
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 void XEmacPs_StubHandler(void); /* Default handler routine */
75
76 /************************** Variable Definitions *****************************/
77
78
79 /*****************************************************************************/
80 /**
81 * Initialize a specific XEmacPs instance/driver. The initialization entails:
82 * - Initialize fields of the XEmacPs instance structure
83 * - Reset hardware and apply default options
84 * - Configure the DMA channels
85 *
86 * The PHY is setup independently from the device. Use the MII or whatever other
87 * interface may be present for setup.
88 *
89 * @param InstancePtr is a pointer to the instance to be worked on.
90 * @param CfgPtr is the device configuration structure containing required
91 *        hardware build data.
92 * @param EffectiveAddress is the base address of the device. If address
93 *        translation is not utilized, this parameter can be passed in using
94 *        CfgPtr->Config.BaseAddress to specify the physical base address.
95 *
96 * @return
97 * - XST_SUCCESS if initialization was successful
98 *
99 ******************************************************************************/
100 int XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
101                            u32 EffectiveAddress)
102 {
103         /* Verify arguments */
104         Xil_AssertNonvoid(InstancePtr != NULL);
105         Xil_AssertNonvoid(CfgPtr != NULL);
106
107         /* Set device base address and ID */
108         InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
109         InstancePtr->Config.BaseAddress = EffectiveAddress;
110
111         /* Set callbacks to an initial stub routine */
112         InstancePtr->SendHandler = (XEmacPs_Handler) XEmacPs_StubHandler;
113         InstancePtr->RecvHandler = (XEmacPs_Handler) XEmacPs_StubHandler;
114         InstancePtr->ErrorHandler = (XEmacPs_ErrHandler) XEmacPs_StubHandler;
115
116         /* Reset the hardware and set default options */
117         InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
118         XEmacPs_Reset(InstancePtr);
119
120         return (XST_SUCCESS);
121 }
122
123
124 /*****************************************************************************/
125 /**
126 * Start the Ethernet controller as follows:
127 *   - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
128 *   - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
129 *   - Start the SG DMA send and receive channels and enable the device
130 *     interrupt
131 *
132 * @param InstancePtr is a pointer to the instance to be worked on.
133 *
134 * @return N/A
135 *
136 * @note
137 * Hardware is configured with scatter-gather DMA, the driver expects to start
138 * the scatter-gather channels and expects that the user has previously set up
139 * the buffer descriptor lists.
140 *
141 * This function makes use of internal resources that are shared between the
142 * Start, Stop, and Set/ClearOptions functions. So if one task might be setting
143 * device options while another is trying to start the device, the user is
144 * required to provide protection of this shared data (typically using a
145 * semaphore).
146 *
147 * This function must not be preempted by an interrupt that may service the
148 * device.
149 *
150 ******************************************************************************/
151 void XEmacPs_Start(XEmacPs *InstancePtr)
152 {
153         u32 Reg;
154
155         /* Assert bad arguments and conditions */
156         Xil_AssertVoid(InstancePtr != NULL);
157         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
158         Xil_AssertVoid(InstancePtr->RxBdRing.BaseBdAddr != 0);
159         Xil_AssertVoid(InstancePtr->TxBdRing.BaseBdAddr != 0);
160
161         /* If already started, then there is nothing to do */
162         if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
163                 return;
164         }
165
166         /* Start DMA */
167         /* When starting the DMA channels, both transmit and receive sides
168          * need an initialized BD list.
169          */
170         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
171                            XEMACPS_RXQBASE_OFFSET,
172                            InstancePtr->RxBdRing.BaseBdAddr);
173
174         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
175                            XEMACPS_TXQBASE_OFFSET,
176                            InstancePtr->TxBdRing.BaseBdAddr);
177
178         /* clear any existed int status */
179         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
180                            XEMACPS_IXR_ALL_MASK);
181
182         /* Enable transmitter if not already enabled */
183         if (InstancePtr->Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
184                 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
185                                         XEMACPS_NWCTRL_OFFSET);
186                 if (!(Reg & XEMACPS_NWCTRL_TXEN_MASK)) {
187                         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
188                                            XEMACPS_NWCTRL_OFFSET,
189                                            Reg | XEMACPS_NWCTRL_TXEN_MASK);
190                 }
191         }
192
193         /* Enable receiver if not already enabled */
194         if (InstancePtr->Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
195                 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
196                                         XEMACPS_NWCTRL_OFFSET);
197                 if (!(Reg & XEMACPS_NWCTRL_RXEN_MASK)) {
198                         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
199                                            XEMACPS_NWCTRL_OFFSET,
200                                            Reg | XEMACPS_NWCTRL_RXEN_MASK);
201                 }
202         }
203
204         /* Enable TX and RX interrupts */
205         XEmacPs_IntEnable(InstancePtr, (XEMACPS_IXR_TX_ERR_MASK |
206                 XEMACPS_IXR_RX_ERR_MASK | XEMACPS_IXR_FRAMERX_MASK |
207                 XEMACPS_IXR_TXCOMPL_MASK));
208
209         /* Mark as started */
210         InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
211
212         return;
213 }
214
215
216 /*****************************************************************************/
217 /**
218 * Gracefully stop the Ethernet MAC as follows:
219 *   - Disable all interrupts from this device
220 *   - Stop DMA channels
221 *   - Disable the tansmitter and receiver
222 *
223 * Device options currently in effect are not changed.
224 *
225 * This function will disable all interrupts. Default interrupts settings that
226 * had been enabled will be restored when XEmacPs_Start() is called.
227 *
228 * @param InstancePtr is a pointer to the instance to be worked on.
229 *
230 * @note
231 * This function makes use of internal resources that are shared between the
232 * Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
233 * setting device options while another is trying to start the device, the user
234 * is required to provide protection of this shared data (typically using a
235 * semaphore).
236 *
237 * Stopping the DMA channels causes this function to block until the DMA
238 * operation is complete.
239 *
240 ******************************************************************************/
241 void XEmacPs_Stop(XEmacPs *InstancePtr)
242 {
243         u32 Reg;
244
245         Xil_AssertVoid(InstancePtr != NULL);
246         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
247
248         /* Disable all interrupts */
249         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
250                            XEMACPS_IXR_ALL_MASK);
251
252         /* Disable the receiver & transmitter */
253         Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
254                                 XEMACPS_NWCTRL_OFFSET);
255         Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
256         Reg &= ~XEMACPS_NWCTRL_TXEN_MASK;
257         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
258                            XEMACPS_NWCTRL_OFFSET, Reg);
259
260         /* Mark as stopped */
261         InstancePtr->IsStarted = 0;
262 }
263
264
265 /*****************************************************************************/
266 /**
267 * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
268 * transmitter, and the receiver.
269 *
270 * Steps to reset
271 * - Stops transmit and receive channels
272 * - Stops DMA
273 * - Configure transmit and receive buffer size to default
274 * - Clear transmit and receive status register and counters
275 * - Clear all interrupt sources
276 * - Clear phy (if there is any previously detected) address
277 * - Clear MAC addresses (1-4) as well as Type IDs and hash value
278 *
279 * All options are placed in their default state. Any frames in the
280 * descriptor lists will remain in the lists. The side effect of doing
281 * this is that after a reset and following a restart of the device, frames
282 * were in the list before the reset may be transmitted or received.
283 *
284 * The upper layer software is responsible for re-configuring (if necessary)
285 * and restarting the MAC after the reset. Note also that driver statistics
286 * are not cleared on reset. It is up to the upper layer software to clear the
287 * statistics if needed.
288 *
289 * When a reset is required, the driver notifies the upper layer software of
290 * this need through the ErrorHandler callback and specific status codes.
291 * The upper layer software is responsible for calling this Reset function
292 * and then re-configuring the device.
293 *
294 * @param InstancePtr is a pointer to the instance to be worked on.
295 *
296 ******************************************************************************/
297 void XEmacPs_Reset(XEmacPs *InstancePtr)
298 {
299         u32 Reg;
300         u8 i;
301         char EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
302
303         Xil_AssertVoid(InstancePtr != NULL);
304         Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
305
306         /* Stop the device and reset hardware */
307         XEmacPs_Stop(InstancePtr);
308         InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
309
310         /* Setup hardware with default values */
311         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
312                         XEMACPS_NWCTRL_OFFSET,
313                         (XEMACPS_NWCTRL_STATCLR_MASK |
314                         XEMACPS_NWCTRL_MDEN_MASK) &
315                         ~XEMACPS_NWCTRL_LOOPEN_MASK);
316
317         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
318                                         XEMACPS_NWCFG_OFFSET,
319                                         XEMACPS_NWCFG_100_MASK |
320                                         XEMACPS_NWCFG_FDEN_MASK |
321                                         XEMACPS_NWCFG_UCASTHASHEN_MASK);
322
323         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
324                         XEMACPS_DMACR_OFFSET,
325                         ((((XEMACPS_RX_BUF_SIZE / XEMACPS_RX_BUF_UNIT) +
326                                 ((XEMACPS_RX_BUF_SIZE %
327                                 XEMACPS_RX_BUF_UNIT) ? 1 : 0)) <<
328                                 XEMACPS_DMACR_RXBUF_SHIFT) &
329                                 XEMACPS_DMACR_RXBUF_MASK) |
330                                 XEMACPS_DMACR_RXSIZE_MASK |
331                                 XEMACPS_DMACR_TXSIZE_MASK);
332
333         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
334                            XEMACPS_TXSR_OFFSET, 0x0);
335
336         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
337                            XEMACPS_RXQBASE_OFFSET, 0x0);
338
339         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
340                            XEMACPS_TXQBASE_OFFSET, 0x0);
341
342         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
343                            XEMACPS_RXSR_OFFSET, 0x0);
344
345         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
346                            XEMACPS_IXR_ALL_MASK);
347
348         Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
349                                 XEMACPS_ISR_OFFSET);
350         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
351                            Reg);
352
353         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
354                            XEMACPS_PHYMNTNC_OFFSET, 0x0);
355
356         XEmacPs_ClearHash(InstancePtr);
357
358         for (i = 1; i < 5; i++) {
359                 XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
360                 XEmacPs_SetTypeIdCheck(InstancePtr, 0x0, i);
361         }
362
363         /* clear all counters */
364         for (i = 0; i < (XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4;
365              i++) {
366                 XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
367                                    XEMACPS_OCTTXL_OFFSET + i * 4);
368         }
369
370         /* Disable the receiver */
371         Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
372                                 XEMACPS_NWCTRL_OFFSET);
373         Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
374         XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
375                            XEMACPS_NWCTRL_OFFSET, Reg);
376
377         /* Sync default options with hardware but leave receiver and
378          * transmitter disabled. They get enabled with XEmacPs_Start() if
379          * XEMACPS_TRANSMITTER_ENABLE_OPTION and
380          * XEMACPS_RECEIVER_ENABLE_OPTION are set.
381          */
382         XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
383                             ~(XEMACPS_TRANSMITTER_ENABLE_OPTION |
384                               XEMACPS_RECEIVER_ENABLE_OPTION));
385
386         XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
387 }
388
389
390 /******************************************************************************/
391 /**
392  * This is a stub for the asynchronous callbacks. The stub is here in case the
393  * upper layer forgot to set the handler(s). On initialization, all handlers are
394  * set to this callback. It is considered an error for this handler to be
395  * invoked.
396  *
397  ******************************************************************************/
398 void XEmacPs_StubHandler(void)
399 {
400         Xil_AssertVoidAlways();
401 }