wdenk | 028ab6b | 2004-02-23 23:54:43 +0000 | [diff] [blame] | 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 | } |