1 /* $Id: xemacps.c,v 1.1.2.3 2011/05/17 12:00:33 anirudh Exp $ */
2 /******************************************************************************
4 * Copyright (C) 2010 - 2014 Xilinx, Inc. All rights reserved.
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
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
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.
32 ******************************************************************************/
33 /*****************************************************************************/
37 * @addtogroup emacps_v2_0
40 * The XEmacPs driver. Functions in this file are the minimum required functions
41 * for this driver. See xemacps.h for a detailed description of the driver.
44 * MODIFICATION HISTORY:
46 * Ver Who Date Changes
47 * ----- ---- -------- -------------------------------------------------------
48 * 1.00a wsy 01/10/10 First release
50 ******************************************************************************/
52 /***************************** Include Files *********************************/
56 /************************** Constant Definitions *****************************/
59 /**************************** Type Definitions *******************************/
62 /***************** Macros (Inline Functions) Definitions *********************/
65 /************************** Function Prototypes ******************************/
67 void XEmacPs_StubHandler(void); /* Default handler routine */
69 /************************** Variable Definitions *****************************/
72 /*****************************************************************************/
74 * Initialize a specific XEmacPs instance/driver. The initialization entails:
75 * - Initialize fields of the XEmacPs instance structure
76 * - Reset hardware and apply default options
77 * - Configure the DMA channels
79 * The PHY is setup independently from the device. Use the MII or whatever other
80 * interface may be present for setup.
82 * @param InstancePtr is a pointer to the instance to be worked on.
83 * @param CfgPtr is the device configuration structure containing required
84 * hardware build data.
85 * @param EffectiveAddress is the base address of the device. If address
86 * translation is not utilized, this parameter can be passed in using
87 * CfgPtr->Config.BaseAddress to specify the physical base address.
90 * - XST_SUCCESS if initialization was successful
92 ******************************************************************************/
93 int XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
96 /* Verify arguments */
97 Xil_AssertNonvoid(InstancePtr != NULL);
98 Xil_AssertNonvoid(CfgPtr != NULL);
100 /* Set device base address and ID */
101 InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
102 InstancePtr->Config.BaseAddress = EffectiveAddress;
104 /* Set callbacks to an initial stub routine */
105 InstancePtr->SendHandler = (XEmacPs_Handler) XEmacPs_StubHandler;
106 InstancePtr->RecvHandler = (XEmacPs_Handler) XEmacPs_StubHandler;
107 InstancePtr->ErrorHandler = (XEmacPs_ErrHandler) XEmacPs_StubHandler;
109 /* Reset the hardware and set default options */
110 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
111 XEmacPs_Reset(InstancePtr);
113 return (XST_SUCCESS);
117 /*****************************************************************************/
119 * Start the Ethernet controller as follows:
120 * - Enable transmitter if XTE_TRANSMIT_ENABLE_OPTION is set
121 * - Enable receiver if XTE_RECEIVER_ENABLE_OPTION is set
122 * - Start the SG DMA send and receive channels and enable the device
125 * @param InstancePtr is a pointer to the instance to be worked on.
130 * Hardware is configured with scatter-gather DMA, the driver expects to start
131 * the scatter-gather channels and expects that the user has previously set up
132 * the buffer descriptor lists.
134 * This function makes use of internal resources that are shared between the
135 * Start, Stop, and Set/ClearOptions functions. So if one task might be setting
136 * device options while another is trying to start the device, the user is
137 * required to provide protection of this shared data (typically using a
140 * This function must not be preempted by an interrupt that may service the
143 ******************************************************************************/
144 void XEmacPs_Start(XEmacPs *InstancePtr)
148 /* Assert bad arguments and conditions */
149 Xil_AssertVoid(InstancePtr != NULL);
150 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
151 Xil_AssertVoid(InstancePtr->RxBdRing.BaseBdAddr != 0);
152 Xil_AssertVoid(InstancePtr->TxBdRing.BaseBdAddr != 0);
154 /* If already started, then there is nothing to do */
155 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
160 /* When starting the DMA channels, both transmit and receive sides
161 * need an initialized BD list.
163 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
164 XEMACPS_RXQBASE_OFFSET,
165 InstancePtr->RxBdRing.BaseBdAddr);
167 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
168 XEMACPS_TXQBASE_OFFSET,
169 InstancePtr->TxBdRing.BaseBdAddr);
171 /* clear any existed int status */
172 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
173 XEMACPS_IXR_ALL_MASK);
175 /* Enable transmitter if not already enabled */
176 if (InstancePtr->Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
177 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
178 XEMACPS_NWCTRL_OFFSET);
179 if (!(Reg & XEMACPS_NWCTRL_TXEN_MASK)) {
180 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
181 XEMACPS_NWCTRL_OFFSET,
182 Reg | XEMACPS_NWCTRL_TXEN_MASK);
186 /* Enable receiver if not already enabled */
187 if (InstancePtr->Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
188 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
189 XEMACPS_NWCTRL_OFFSET);
190 if (!(Reg & XEMACPS_NWCTRL_RXEN_MASK)) {
191 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
192 XEMACPS_NWCTRL_OFFSET,
193 Reg | XEMACPS_NWCTRL_RXEN_MASK);
197 /* Enable TX and RX interrupts */
198 XEmacPs_IntEnable(InstancePtr, (XEMACPS_IXR_TX_ERR_MASK |
199 XEMACPS_IXR_RX_ERR_MASK | XEMACPS_IXR_FRAMERX_MASK |
200 XEMACPS_IXR_TXCOMPL_MASK));
202 /* Mark as started */
203 InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
209 /*****************************************************************************/
211 * Gracefully stop the Ethernet MAC as follows:
212 * - Disable all interrupts from this device
213 * - Stop DMA channels
214 * - Disable the tansmitter and receiver
216 * Device options currently in effect are not changed.
218 * This function will disable all interrupts. Default interrupts settings that
219 * had been enabled will be restored when XEmacPs_Start() is called.
221 * @param InstancePtr is a pointer to the instance to be worked on.
224 * This function makes use of internal resources that are shared between the
225 * Start, Stop, SetOptions, and ClearOptions functions. So if one task might be
226 * setting device options while another is trying to start the device, the user
227 * is required to provide protection of this shared data (typically using a
230 * Stopping the DMA channels causes this function to block until the DMA
231 * operation is complete.
233 ******************************************************************************/
234 void XEmacPs_Stop(XEmacPs *InstancePtr)
238 Xil_AssertVoid(InstancePtr != NULL);
239 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
241 /* Disable all interrupts */
242 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
243 XEMACPS_IXR_ALL_MASK);
245 /* Disable the receiver & transmitter */
246 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
247 XEMACPS_NWCTRL_OFFSET);
248 Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
249 Reg &= ~XEMACPS_NWCTRL_TXEN_MASK;
250 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
251 XEMACPS_NWCTRL_OFFSET, Reg);
253 /* Mark as stopped */
254 InstancePtr->IsStarted = 0;
258 /*****************************************************************************/
260 * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
261 * transmitter, and the receiver.
264 * - Stops transmit and receive channels
266 * - Configure transmit and receive buffer size to default
267 * - Clear transmit and receive status register and counters
268 * - Clear all interrupt sources
269 * - Clear phy (if there is any previously detected) address
270 * - Clear MAC addresses (1-4) as well as Type IDs and hash value
272 * All options are placed in their default state. Any frames in the
273 * descriptor lists will remain in the lists. The side effect of doing
274 * this is that after a reset and following a restart of the device, frames
275 * were in the list before the reset may be transmitted or received.
277 * The upper layer software is responsible for re-configuring (if necessary)
278 * and restarting the MAC after the reset. Note also that driver statistics
279 * are not cleared on reset. It is up to the upper layer software to clear the
280 * statistics if needed.
282 * When a reset is required, the driver notifies the upper layer software of
283 * this need through the ErrorHandler callback and specific status codes.
284 * The upper layer software is responsible for calling this Reset function
285 * and then re-configuring the device.
287 * @param InstancePtr is a pointer to the instance to be worked on.
289 ******************************************************************************/
290 void XEmacPs_Reset(XEmacPs *InstancePtr)
294 char EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
296 Xil_AssertVoid(InstancePtr != NULL);
297 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
299 /* Stop the device and reset hardware */
300 XEmacPs_Stop(InstancePtr);
301 InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
303 /* Setup hardware with default values */
304 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
305 XEMACPS_NWCTRL_OFFSET,
306 (XEMACPS_NWCTRL_STATCLR_MASK |
307 XEMACPS_NWCTRL_MDEN_MASK) &
308 ~XEMACPS_NWCTRL_LOOPEN_MASK);
310 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
311 XEMACPS_NWCFG_OFFSET,
312 XEMACPS_NWCFG_100_MASK |
313 XEMACPS_NWCFG_FDEN_MASK |
314 XEMACPS_NWCFG_UCASTHASHEN_MASK);
316 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
317 XEMACPS_DMACR_OFFSET,
318 ((((XEMACPS_RX_BUF_SIZE / XEMACPS_RX_BUF_UNIT) +
319 ((XEMACPS_RX_BUF_SIZE %
320 XEMACPS_RX_BUF_UNIT) ? 1 : 0)) <<
321 XEMACPS_DMACR_RXBUF_SHIFT) &
322 XEMACPS_DMACR_RXBUF_MASK) |
323 XEMACPS_DMACR_RXSIZE_MASK |
324 XEMACPS_DMACR_TXSIZE_MASK);
326 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
327 XEMACPS_TXSR_OFFSET, 0x0);
329 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
330 XEMACPS_RXQBASE_OFFSET, 0x0);
332 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
333 XEMACPS_TXQBASE_OFFSET, 0x0);
335 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
336 XEMACPS_RXSR_OFFSET, 0x0);
338 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
339 XEMACPS_IXR_ALL_MASK);
341 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
343 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
346 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
347 XEMACPS_PHYMNTNC_OFFSET, 0x0);
349 XEmacPs_ClearHash(InstancePtr);
351 for (i = 1; i < 5; i++) {
352 XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
353 XEmacPs_SetTypeIdCheck(InstancePtr, 0x0, i);
356 /* clear all counters */
357 for (i = 0; i < (XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4;
359 XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
360 XEMACPS_OCTTXL_OFFSET + i * 4);
363 /* Disable the receiver */
364 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
365 XEMACPS_NWCTRL_OFFSET);
366 Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
367 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
368 XEMACPS_NWCTRL_OFFSET, Reg);
370 /* Sync default options with hardware but leave receiver and
371 * transmitter disabled. They get enabled with XEmacPs_Start() if
372 * XEMACPS_TRANSMITTER_ENABLE_OPTION and
373 * XEMACPS_RECEIVER_ENABLE_OPTION are set.
375 XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
376 ~(XEMACPS_TRANSMITTER_ENABLE_OPTION |
377 XEMACPS_RECEIVER_ENABLE_OPTION));
379 XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
383 /******************************************************************************/
385 * This is a stub for the asynchronous callbacks. The stub is here in case the
386 * upper layer forgot to set the handler(s). On initialization, all handlers are
387 * set to this callback. It is considered an error for this handler to be
390 ******************************************************************************/
391 void XEmacPs_StubHandler(void)
393 Xil_AssertVoidAlways();