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 /*****************************************************************************/
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.
42 * MODIFICATION HISTORY:
44 * Ver Who Date Changes
45 * ----- ---- -------- -------------------------------------------------------
46 * 1.00a wsy 01/10/10 First release
48 ******************************************************************************/
50 /***************************** Include Files *********************************/
54 /************************** Constant Definitions *****************************/
57 /**************************** Type Definitions *******************************/
60 /***************** Macros (Inline Functions) Definitions *********************/
63 /************************** Function Prototypes ******************************/
65 void XEmacPs_StubHandler(void); /* Default handler routine */
67 /************************** Variable Definitions *****************************/
70 /*****************************************************************************/
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
77 * The PHY is setup independently from the device. Use the MII or whatever other
78 * interface may be present for setup.
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.
88 * - XST_SUCCESS if initialization was successful
90 ******************************************************************************/
91 int XEmacPs_CfgInitialize(XEmacPs *InstancePtr, XEmacPs_Config * CfgPtr,
94 /* Verify arguments */
95 Xil_AssertNonvoid(InstancePtr != NULL);
96 Xil_AssertNonvoid(CfgPtr != NULL);
98 /* Set device base address and ID */
99 InstancePtr->Config.DeviceId = CfgPtr->DeviceId;
100 InstancePtr->Config.BaseAddress = EffectiveAddress;
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;
107 /* Reset the hardware and set default options */
108 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
109 XEmacPs_Reset(InstancePtr);
111 return (XST_SUCCESS);
115 /*****************************************************************************/
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
123 * @param InstancePtr is a pointer to the instance to be worked on.
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.
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
138 * This function must not be preempted by an interrupt that may service the
141 ******************************************************************************/
142 void XEmacPs_Start(XEmacPs *InstancePtr)
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);
152 /* If already started, then there is nothing to do */
153 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
158 /* When starting the DMA channels, both transmit and receive sides
159 * need an initialized BD list.
161 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
162 XEMACPS_RXQBASE_OFFSET,
163 InstancePtr->RxBdRing.BaseBdAddr);
165 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
166 XEMACPS_TXQBASE_OFFSET,
167 InstancePtr->TxBdRing.BaseBdAddr);
169 /* clear any existed int status */
170 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
171 XEMACPS_IXR_ALL_MASK);
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);
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);
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));
200 /* Mark as started */
201 InstancePtr->IsStarted = XIL_COMPONENT_IS_STARTED;
207 /*****************************************************************************/
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
214 * Device options currently in effect are not changed.
216 * This function will disable all interrupts. Default interrupts settings that
217 * had been enabled will be restored when XEmacPs_Start() is called.
219 * @param InstancePtr is a pointer to the instance to be worked on.
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
228 * Stopping the DMA channels causes this function to block until the DMA
229 * operation is complete.
231 ******************************************************************************/
232 void XEmacPs_Stop(XEmacPs *InstancePtr)
236 Xil_AssertVoid(InstancePtr != NULL);
237 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
239 /* Disable all interrupts */
240 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
241 XEMACPS_IXR_ALL_MASK);
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);
251 /* Mark as stopped */
252 InstancePtr->IsStarted = 0;
256 /*****************************************************************************/
258 * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
259 * transmitter, and the receiver.
262 * - Stops transmit and receive channels
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
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.
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.
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.
285 * @param InstancePtr is a pointer to the instance to be worked on.
287 ******************************************************************************/
288 void XEmacPs_Reset(XEmacPs *InstancePtr)
292 char EmacPs_zero_MAC[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
294 Xil_AssertVoid(InstancePtr != NULL);
295 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
297 /* Stop the device and reset hardware */
298 XEmacPs_Stop(InstancePtr);
299 InstancePtr->Options = XEMACPS_DEFAULT_OPTIONS;
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);
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);
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);
324 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
325 XEMACPS_TXSR_OFFSET, 0x0);
327 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
328 XEMACPS_RXQBASE_OFFSET, 0x0);
330 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
331 XEMACPS_TXQBASE_OFFSET, 0x0);
333 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
334 XEMACPS_RXSR_OFFSET, 0x0);
336 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_IDR_OFFSET,
337 XEMACPS_IXR_ALL_MASK);
339 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
341 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_ISR_OFFSET,
344 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
345 XEMACPS_PHYMNTNC_OFFSET, 0x0);
347 XEmacPs_ClearHash(InstancePtr);
349 for (i = 1; i < 5; i++) {
350 XEmacPs_SetMacAddress(InstancePtr, EmacPs_zero_MAC, i);
351 XEmacPs_SetTypeIdCheck(InstancePtr, 0x0, i);
354 /* clear all counters */
355 for (i = 0; i < (XEMACPS_LAST_OFFSET - XEMACPS_OCTTXL_OFFSET) / 4;
357 XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
358 XEMACPS_OCTTXL_OFFSET + i * 4);
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);
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.
373 XEmacPs_SetOptions(InstancePtr, InstancePtr->Options &
374 ~(XEMACPS_TRANSMITTER_ENABLE_OPTION |
375 XEMACPS_RECEIVER_ENABLE_OPTION));
377 XEmacPs_ClearOptions(InstancePtr, ~InstancePtr->Options);
381 /******************************************************************************/
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
388 ******************************************************************************/
389 void XEmacPs_StubHandler(void)
391 Xil_AssertVoidAlways();