summaryrefslogtreecommitdiff
path: root/board/xilinx/xilinx_enet/xemac_options.c
blob: 1f225f8f521046c53b92a2a3f00909b947035013 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
/******************************************************************************
*
*     Author: Xilinx, Inc.
*
*
*     This program is free software; you can redistribute it and/or modify it
*     under the terms of the GNU General Public License as published by the
*     Free Software Foundation; either version 2 of the License, or (at your
*     option) any later version.
*
*
*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD,
*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING
*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY
*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM
*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND
*     FITNESS FOR A PARTICULAR PURPOSE.
*
*
*     Xilinx hardware products are not intended for use in life support
*     appliances, devices, or systems. Use in such applications is
*     expressly prohibited.
*
*
*     (c) Copyright 2002-2004 Xilinx Inc.
*     All rights reserved.
*
*
*     You should have received a copy of the GNU General Public License along
*     with this program; if not, write to the Free Software Foundation, Inc.,
*     675 Mass Ave, Cambridge, MA 02139, USA.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xemac_options.c
*
* Functions in this file handle configuration of the XEmac driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a rpm  07/31/01 First release
* 1.00b rpm  02/20/02 Repartitioned files and functions
* 1.00c rpm  12/05/02 New version includes support for simple DMA
* </pre>
*
******************************************************************************/

/***************************** Include Files *********************************/

#include "xbasic_types.h"
#include "xemac_i.h"
#include "xio.h"

/************************** Constant Definitions *****************************/

#define XEM_MAX_IFG         32	/* Maximum Interframe gap value */

/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

/************************** Function Prototypes ******************************/

/************************** Variable Definitions *****************************/

/*
 * A table of options and masks. This table maps the user-visible options with
 * the control register masks. It is used in Set/GetOptions as an alternative
 * to a series of if/else pairs. Note that the polled options does not have a
 * corresponding entry in the control register, so it does not exist in the
 * table.
 */
typedef struct {
	u32 Option;
	u32 Mask;
} OptionMap;

static OptionMap OptionsTable[] = {
	{XEM_UNICAST_OPTION, XEM_ECR_UNICAST_ENABLE_MASK},
	{XEM_BROADCAST_OPTION, XEM_ECR_BROAD_ENABLE_MASK},
	{XEM_PROMISC_OPTION, XEM_ECR_PROMISC_ENABLE_MASK},
	{XEM_FDUPLEX_OPTION, XEM_ECR_FULL_DUPLEX_MASK},
	{XEM_LOOPBACK_OPTION, XEM_ECR_LOOPBACK_MASK},
	{XEM_MULTICAST_OPTION, XEM_ECR_MULTI_ENABLE_MASK},
	{XEM_FLOW_CONTROL_OPTION, XEM_ECR_PAUSE_FRAME_MASK},
	{XEM_INSERT_PAD_OPTION, XEM_ECR_XMIT_PAD_ENABLE_MASK},
	{XEM_INSERT_FCS_OPTION, XEM_ECR_XMIT_FCS_ENABLE_MASK},
	{XEM_INSERT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_INSERT_MASK},
	{XEM_OVWRT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_OVWRT_MASK},
	{XEM_STRIP_PAD_FCS_OPTION, XEM_ECR_RECV_STRIP_ENABLE_MASK}
};

#define XEM_NUM_OPTIONS     (sizeof(OptionsTable) / sizeof(OptionMap))

/*****************************************************************************/
/**
*
* Set Ethernet driver/device options.  The device must be stopped before
* calling this function.  The options are contained within a bit-mask with each
* bit representing an option (i.e., you can OR the options together). A one (1)
* in the bit-mask turns an option on, and a zero (0) turns the option off.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param OptionsFlag is a bit-mask representing the Ethernet options to turn on
*        or off. See xemac.h for a description of the available options.
*
* @return
*
* - XST_SUCCESS if the options were set successfully
* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
*
* @note
*
* This function is not thread-safe and makes use of internal resources that are
* shared between the Start, Stop, and SetOptions functions, so if one task
* might be setting device options while another is trying to start the device,
* protection of this shared data (typically using a semaphore) is required.
*
******************************************************************************/
XStatus
XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag)
{
	u32 ControlReg;
	int Index;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
		return XST_DEVICE_IS_STARTED;
	}

	ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);

	/*
	 * Loop through the options table, turning the option on or off
	 * depending on whether the bit is set in the incoming options flag.
	 */
	for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
		if (OptionsFlag & OptionsTable[Index].Option) {
			ControlReg |= OptionsTable[Index].Mask;	/* turn it on */
		} else {
			ControlReg &= ~OptionsTable[Index].Mask;	/* turn it off */
		}
	}

	/*
	 * TODO: need to validate addr-overwrite only if addr-insert?
	 */

	/*
	 * Now write the control register. Leave it to the upper layers
	 * to restart the device.
	 */
	XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);

	/*
	 * Check the polled option
	 */
	if (OptionsFlag & XEM_POLLED_OPTION) {
		InstancePtr->IsPolled = TRUE;
	} else {
		InstancePtr->IsPolled = FALSE;
	}

	return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* Get Ethernet driver/device options. The 32-bit value returned is a bit-mask
* representing the options.  A one (1) in the bit-mask means the option is on,
* and a zero (0) means the option is off.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
*
* @return
*
* The 32-bit value of the Ethernet options. The value is a bit-mask
* representing all options that are currently enabled. See xemac.h for a
* description of the available options.
*
* @note
*
* None.
*
******************************************************************************/
u32
XEmac_GetOptions(XEmac * InstancePtr)
{
	u32 OptionsFlag = 0;
	u32 ControlReg;
	int Index;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Get the control register to determine which options are currently set.
	 */
	ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);

	/*
	 * Loop through the options table to determine which options are set
	 */
	for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
		if (ControlReg & OptionsTable[Index].Mask) {
			OptionsFlag |= OptionsTable[Index].Option;
		}
	}

	if (InstancePtr->IsPolled) {
		OptionsFlag |= XEM_POLLED_OPTION;
	}

	return OptionsFlag;
}

/*****************************************************************************/
/**
*
* Set the Interframe Gap (IFG), which is the time the MAC delays between
* transmitting frames.  There are two parts required.  The total interframe gap
* is the total of the two parts.  The values provided for the Part1 and Part2
* parameters are multiplied by 4 to obtain the bit-time interval. The first
* part should be the first 2/3 of the total interframe gap. The MAC will reset
* the interframe gap timer if carrier sense becomes true during the period
* defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and
* can be as small as zero. The second part should be the last 1/3 of the total
* interframe gap, but can be as large as the total interframe gap. The MAC
* will not reset the interframe gap timer if carrier sense becomes true during
* the period defined by interframe gap Part2.
*
* The device must be stopped before setting the interframe gap.
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to
*        get the bit-time interval).
* @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to
*        get the bit-time interval).
*
* @return
*
* - XST_SUCCESS if the interframe gap was set successfully
* - XST_DEVICE_IS_STARTED if the device has not been stopped
*
* @note
*
* None.
*
******************************************************************************/
XStatus
XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2)
{
	u32 Ifg;

	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(Part1 < XEM_MAX_IFG);
	XASSERT_NONVOID(Part2 < XEM_MAX_IFG);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	/*
	 * Be sure device has been stopped
	 */
	if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
		return XST_DEVICE_IS_STARTED;
	}

	Ifg = Part1 << XEM_IFGP_PART1_SHIFT;
	Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT);
	XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg);

	return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* Get the interframe gap, parts 1 and 2. See the description of interframe gap
* above in XEmac_SetInterframeGap().
*
* @param InstancePtr is a pointer to the XEmac instance to be worked on.
* @param Part1Ptr is a pointer to an 8-bit buffer into which the interframe gap
*        part 1 value will be copied.
* @param Part2Ptr is a pointer to an 8-bit buffer into which the interframe gap
*        part 2 value will be copied.
*
* @return
*
* None. The values of the interframe gap parts are copied into the
* output parameters.
*
******************************************************************************/
void
XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr)
{
	u32 Ifg;

	XASSERT_VOID(InstancePtr != NULL);
	XASSERT_VOID(Part1Ptr != NULL);
	XASSERT_VOID(Part2Ptr != NULL);
	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);

	Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);
	*Part1Ptr = (Ifg & XEM_IFGP_PART1_MASK) >> XEM_IFGP_PART1_SHIFT;
	*Part2Ptr = (Ifg & XEM_IFGP_PART2_MASK) >> XEM_IFGP_PART2_SHIFT;
}