1 /* $Id: xemacps.c,v 1.1.2.3 2011/05/17 12:00:33 anirudh Exp $ */
2 /******************************************************************************
4 * (c) Copyright 2010 Xilinx, Inc. All rights reserved.
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.
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.
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.
38 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE
41 ******************************************************************************/
42 /*****************************************************************************/
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.
51 * MODIFICATION HISTORY:
53 * Ver Who Date Changes
54 * ----- ---- -------- -------------------------------------------------------
55 * 1.00a wsy 01/10/10 First release
57 ******************************************************************************/
59 /***************************** Include Files *********************************/
63 /************************** Constant Definitions *****************************/
66 /**************************** Type Definitions *******************************/
69 /***************** Macros (Inline Functions) Definitions *********************/
72 /************************** Function Prototypes ******************************/
74 void XEmacPs_StubHandler(void); /* Default handler routine */
76 /************************** Variable Definitions *****************************/
79 /*****************************************************************************/
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
86 * The PHY is setup independently from the device. Use the MII or whatever other
87 * interface may be present for setup.
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.
97 * - XST_SUCCESS if initialization was successful
99 ******************************************************************************/
100 int XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
101 u32 EffectiveAddress)
103 /* Verify arguments */
104 Xil_AssertNonvoid(InstancePtr != NULL);
105 Xil_AssertNonvoid(CfgPtr != NULL);
107 /* Set device base address and ID */
108 InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
109 InstancePtr->Config.BaseAddress = EffectiveAddress;
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;
116 /* Reset the hardware and set default options */
117 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
118 XEmacPs_Reset(InstancePtr);
120 return (XST_SUCCESS);
124 /*****************************************************************************/
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
132 * @param InstancePtr is a pointer to the instance to be worked on.
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.
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
147 * This function must not be preempted by an interrupt that may service the
150 ******************************************************************************/
151 void XEmacPs_Start(XEmacPs *InstancePtr)
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);
161 /* If already started, then there is nothing to do */
162 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
167 /* When starting the DMA channels, both transmit and receive sides
168 * need an initialized BD list.
170 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
171 XEMACPS_RXQBASE_OFFSET,
172 InstancePtr->RxBdRing.BaseBdAddr);
174 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
175 XEMACPS_TXQBASE_OFFSET,
176 InstancePtr->TxBdRing.BaseBdAddr);
178 /* clear any existed int status */
179 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
180 XEMACPS_IXR_ALL_MASK);
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);
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);
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));
209 /* Mark as started */
210 InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
216 /*****************************************************************************/
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
223 * Device options currently in effect are not changed.
225 * This function will disable all interrupts. Default interrupts settings that
226 * had been enabled will be restored when XEmacPs_Start() is called.
228 * @param InstancePtr is a pointer to the instance to be worked on.
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
237 * Stopping the DMA channels causes this function to block until the DMA
238 * operation is complete.
240 ******************************************************************************/
241 void XEmacPs_Stop(XEmacPs *InstancePtr)
245 Xil_AssertVoid(InstancePtr != NULL);
246 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
248 /* Disable all interrupts */
249 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
250 XEMACPS_IXR_ALL_MASK);
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);
260 /* Mark as stopped */
261 InstancePtr->IsStarted = 0;
265 /*****************************************************************************/
267 * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
268 * transmitter, and the receiver.
271 * - Stops transmit and receive channels
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
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.
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.
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.
294 * @param InstancePtr is a pointer to the instance to be worked on.
296 ******************************************************************************/
297 void XEmacPs_Reset(XEmacPs *InstancePtr)
301 char EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
303 Xil_AssertVoid(InstancePtr != NULL);
304 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
306 /* Stop the device and reset hardware */
307 XEmacPs_Stop(InstancePtr);
308 InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
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);
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);
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);
333 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
334 XEMACPS_TXSR_OFFSET, 0x0);
336 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
337 XEMACPS_RXQBASE_OFFSET, 0x0);
339 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
340 XEMACPS_TXQBASE_OFFSET, 0x0);
342 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
343 XEMACPS_RXSR_OFFSET, 0x0);
345 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
346 XEMACPS_IXR_ALL_MASK);
348 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
350 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
353 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
354 XEMACPS_PHYMNTNC_OFFSET, 0x0);
356 XEmacPs_ClearHash(InstancePtr);
358 for (i = 1; i < 5; i++) {
359 XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
360 XEmacPs_SetTypeIdCheck(InstancePtr, 0x0, i);
363 /* clear all counters */
364 for (i = 0; i < (XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4;
366 XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
367 XEMACPS_OCTTXL_OFFSET + i * 4);
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);
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.
382 XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
383 ~(XEMACPS_TRANSMITTER_ENABLE_OPTION |
384 XEMACPS_RECEIVER_ENABLE_OPTION));
386 XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
390 /******************************************************************************/
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
397 ******************************************************************************/
398 void XEmacPs_StubHandler(void)
400 Xil_AssertVoidAlways();