tizen 2.4 release
[kernel/u-boot-tm1.git] / board / xilinx / xilinx_enet / xemac_options.c
1 /******************************************************************************
2 *
3 *     Author: Xilinx, Inc.
4 *
5 *
6 *     This program is free software; you can redistribute it and/or modify it
7 *     under the terms of the GNU General Public License as published by the
8 *     Free Software Foundation; either version 2 of the License, or (at your
9 *     option) any later version.
10 *
11 *
12 *     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
13 *     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
14 *     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
15 *     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
16 *     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
17 *     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
18 *     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
19 *     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
20 *     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
21 *     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
22 *     FITNESS FOR A PARTICULAR PURPOSE.
23 *
24 *
25 *     Xilinx hardware products are not intended for use in life support
26 *     appliances, devices, or systems. Use in such applications is
27 *     expressly prohibited.
28 *
29 *
30 *     (c) Copyright 2002-2004 Xilinx Inc.
31 *     All rights reserved.
32 *
33 *
34 *     You should have received a copy of the GNU General Public License along
35 *     with this program; if not, write to the Free Software Foundation, Inc.,
36 *     675 Mass Ave, Cambridge, MA 02139, USA.
37 *
38 ******************************************************************************/
39 /*****************************************************************************/
40 /**
41 *
42 * @file xemac_options.c
43 *
44 * Functions in this file handle configuration of the XEmac driver.
45 *
46 * <pre>
47 * MODIFICATION HISTORY:
48 *
49 * Ver   Who  Date     Changes
50 * ----- ---- -------- -----------------------------------------------
51 * 1.00a rpm  07/31/01 First release
52 * 1.00b rpm  02/20/02 Repartitioned files and functions
53 * 1.00c rpm  12/05/02 New version includes support for simple DMA
54 * </pre>
55 *
56 ******************************************************************************/
57
58 /***************************** Include Files *********************************/
59
60 #include "xbasic_types.h"
61 #include "xemac_i.h"
62 #include "xio.h"
63
64 /************************** Constant Definitions *****************************/
65
66 #define XEM_MAX_IFG         32  /* Maximum Interframe gap value */
67
68 /**************************** Type Definitions *******************************/
69
70 /***************** Macros (Inline Functions) Definitions *********************/
71
72 /************************** Function Prototypes ******************************/
73
74 /************************** Variable Definitions *****************************/
75
76 /*
77  * A table of options and masks. This table maps the user-visible options with
78  * the control register masks. It is used in Set/GetOptions as an alternative
79  * to a series of if/else pairs. Note that the polled options does not have a
80  * corresponding entry in the control register, so it does not exist in the
81  * table.
82  */
83 typedef struct {
84         u32 Option;
85         u32 Mask;
86 } OptionMap;
87
88 static OptionMap OptionsTable[] = {
89         {XEM_UNICAST_OPTION, XEM_ECR_UNICAST_ENABLE_MASK},
90         {XEM_BROADCAST_OPTION, XEM_ECR_BROAD_ENABLE_MASK},
91         {XEM_PROMISC_OPTION, XEM_ECR_PROMISC_ENABLE_MASK},
92         {XEM_FDUPLEX_OPTION, XEM_ECR_FULL_DUPLEX_MASK},
93         {XEM_LOOPBACK_OPTION, XEM_ECR_LOOPBACK_MASK},
94         {XEM_MULTICAST_OPTION, XEM_ECR_MULTI_ENABLE_MASK},
95         {XEM_FLOW_CONTROL_OPTION, XEM_ECR_PAUSE_FRAME_MASK},
96         {XEM_INSERT_PAD_OPTION, XEM_ECR_XMIT_PAD_ENABLE_MASK},
97         {XEM_INSERT_FCS_OPTION, XEM_ECR_XMIT_FCS_ENABLE_MASK},
98         {XEM_INSERT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_INSERT_MASK},
99         {XEM_OVWRT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_OVWRT_MASK},
100         {XEM_STRIP_PAD_FCS_OPTION, XEM_ECR_RECV_STRIP_ENABLE_MASK}
101 };
102
103 #define XEM_NUM_OPTIONS     (sizeof(OptionsTable) / sizeof(OptionMap))
104
105 /*****************************************************************************/
106 /**
107 *
108 * Set Ethernet driver/device options.  The device must be stopped before
109 * calling this function.  The options are contained within a bit-mask with each
110 * bit representing an option (i.e., you can OR the options together). A one (1)
111 * in the bit-mask turns an option on, and a zero (0) turns the option off.
112 *
113 * @param InstancePtr is a pointer to the XEmac instance to be worked on.
114 * @param OptionsFlag is a bit-mask representing the Ethernet options to turn on
115 *        or off. See xemac.h for a description of the available options.
116 *
117 * @return
118 *
119 * - XST_SUCCESS if the options were set successfully
120 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
121 *
122 * @note
123 *
124 * This function is not thread-safe and makes use of internal resources that are
125 * shared between the Start, Stop, and SetOptions functions, so if one task
126 * might be setting device options while another is trying to start the device,
127 * protection of this shared data (typically using a semaphore) is required.
128 *
129 ******************************************************************************/
130 XStatus
131 XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag)
132 {
133         u32 ControlReg;
134         int Index;
135
136         XASSERT_NONVOID(InstancePtr != NULL);
137         XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
138
139         if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
140                 return XST_DEVICE_IS_STARTED;
141         }
142
143         ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
144
145         /*
146          * Loop through the options table, turning the option on or off
147          * depending on whether the bit is set in the incoming options flag.
148          */
149         for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
150                 if (OptionsFlag & OptionsTable[Index].Option) {
151                         ControlReg |= OptionsTable[Index].Mask; /* turn it on */
152                 } else {
153                         ControlReg &= ~OptionsTable[Index].Mask;        /* turn it off */
154                 }
155         }
156
157         /*
158          * TODO: need to validate addr-overwrite only if addr-insert?
159          */
160
161         /*
162          * Now write the control register. Leave it to the upper layers
163          * to restart the device.
164          */
165         XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
166
167         /*
168          * Check the polled option
169          */
170         if (OptionsFlag & XEM_POLLED_OPTION) {
171                 InstancePtr->IsPolled = TRUE;
172         } else {
173                 InstancePtr->IsPolled = FALSE;
174         }
175
176         return XST_SUCCESS;
177 }
178
179 /*****************************************************************************/
180 /**
181 *
182 * Get Ethernet driver/device options. The 32-bit value returned is a bit-mask
183 * representing the options.  A one (1) in the bit-mask means the option is on,
184 * and a zero (0) means the option is off.
185 *
186 * @param InstancePtr is a pointer to the XEmac instance to be worked on.
187 *
188 * @return
189 *
190 * The 32-bit value of the Ethernet options. The value is a bit-mask
191 * representing all options that are currently enabled. See xemac.h for a
192 * description of the available options.
193 *
194 * @note
195 *
196 * None.
197 *
198 ******************************************************************************/
199 u32
200 XEmac_GetOptions(XEmac * InstancePtr)
201 {
202         u32 OptionsFlag = 0;
203         u32 ControlReg;
204         int Index;
205
206         XASSERT_NONVOID(InstancePtr != NULL);
207         XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
208
209         /*
210          * Get the control register to determine which options are currently set.
211          */
212         ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
213
214         /*
215          * Loop through the options table to determine which options are set
216          */
217         for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
218                 if (ControlReg & OptionsTable[Index].Mask) {
219                         OptionsFlag |= OptionsTable[Index].Option;
220                 }
221         }
222
223         if (InstancePtr->IsPolled) {
224                 OptionsFlag |= XEM_POLLED_OPTION;
225         }
226
227         return OptionsFlag;
228 }
229
230 /*****************************************************************************/
231 /**
232 *
233 * Set the Interframe Gap (IFG), which is the time the MAC delays between
234 * transmitting frames.  There are two parts required.  The total interframe gap
235 * is the total of the two parts.  The values provided for the Part1 and Part2
236 * parameters are multiplied by 4 to obtain the bit-time interval. The first
237 * part should be the first 2/3 of the total interframe gap. The MAC will reset
238 * the interframe gap timer if carrier sense becomes true during the period
239 * defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and
240 * can be as small as zero. The second part should be the last 1/3 of the total
241 * interframe gap, but can be as large as the total interframe gap. The MAC
242 * will not reset the interframe gap timer if carrier sense becomes true during
243 * the period defined by interframe gap Part2.
244 *
245 * The device must be stopped before setting the interframe gap.
246 *
247 * @param InstancePtr is a pointer to the XEmac instance to be worked on.
248 * @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to
249 *        get the bit-time interval).
250 * @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to
251 *        get the bit-time interval).
252 *
253 * @return
254 *
255 * - XST_SUCCESS if the interframe gap was set successfully
256 * - XST_DEVICE_IS_STARTED if the device has not been stopped
257 *
258 * @note
259 *
260 * None.
261 *
262 ******************************************************************************/
263 XStatus
264 XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2)
265 {
266         u32 Ifg;
267
268         XASSERT_NONVOID(InstancePtr != NULL);
269         XASSERT_NONVOID(Part1 < XEM_MAX_IFG);
270         XASSERT_NONVOID(Part2 < XEM_MAX_IFG);
271         XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
272
273         /*
274          * Be sure device has been stopped
275          */
276         if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
277                 return XST_DEVICE_IS_STARTED;
278         }
279
280         Ifg = Part1 << XEM_IFGP_PART1_SHIFT;
281         Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT);
282         XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg);
283
284         return XST_SUCCESS;
285 }
286
287 /*****************************************************************************/
288 /**
289 *
290 * Get the interframe gap, parts 1 and 2. See the description of interframe gap
291 * above in XEmac_SetInterframeGap().
292 *
293 * @param InstancePtr is a pointer to the XEmac instance to be worked on.
294 * @param Part1Ptr is a pointer to an 8-bit buffer into which the interframe gap
295 *        part 1 value will be copied.
296 * @param Part2Ptr is a pointer to an 8-bit buffer into which the interframe gap
297 *        part 2 value will be copied.
298 *
299 * @return
300 *
301 * None. The values of the interframe gap parts are copied into the
302 * output parameters.
303 *
304 ******************************************************************************/
305 void
306 XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr)
307 {
308         u32 Ifg;
309
310         XASSERT_VOID(InstancePtr != NULL);
311         XASSERT_VOID(Part1Ptr != NULL);
312         XASSERT_VOID(Part2Ptr != NULL);
313         XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
314
315         Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);
316         *Part1Ptr = (Ifg & XEM_IFGP_PART1_MASK) >> XEM_IFGP_PART1_SHIFT;
317         *Part2Ptr = (Ifg & XEM_IFGP_PART2_MASK) >> XEM_IFGP_PART2_SHIFT;
318 }