1 /* $Id: xemacps_control.c,v 1.1.2.1 2011/01/20 03:39:02 sadanan Exp $ */
2 /******************************************************************************
4 * Copyright (C) 2009 - 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 /*****************************************************************************/
36 * @file xemacps_control.c
38 * Functions in this file implement general purpose command and control related
39 * functionality. 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
47 * 1.02a asa 11/05/12 Added a new API for deleting an entry from the HASH
48 * register. Added a new API for setting the BURST length
51 *****************************************************************************/
53 /***************************** Include Files *********************************/
57 /************************** Constant Definitions *****************************/
60 /**************************** Type Definitions *******************************/
63 /***************** Macros (Inline Functions) Definitions *********************/
66 /************************** Function Prototypes ******************************/
69 /************************** Variable Definitions *****************************/
72 /*****************************************************************************/
74 * Set the MAC address for this driver/device. The address is a 48-bit value.
75 * The device must be stopped before calling this function.
77 * @param InstancePtr is a pointer to the instance to be worked on.
78 * @param AddressPtr is a pointer to a 6-byte MAC address.
79 * @param Index is a index to which MAC (1-4) address.
82 * - XST_SUCCESS if the MAC address was set successfully
83 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
85 *****************************************************************************/
86 int XEmacPs_SetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index)
89 u8 *Aptr = (u8 *) AddressPtr;
91 Xil_AssertNonvoid(InstancePtr != NULL);
92 Xil_AssertNonvoid(AddressPtr != NULL);
93 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
94 Xil_AssertNonvoid((Index <= XEMACPS_MAX_MAC_ADDR) && (Index > 0));
96 /* Be sure device has been stopped */
97 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
98 return (XST_DEVICE_IS_STARTED);
101 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
104 /* Set the MAC bits [31:0] in BOT */
106 MacAddr |= Aptr[1] << 8;
107 MacAddr |= Aptr[2] << 16;
108 MacAddr |= Aptr[3] << 24;
109 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
110 (XEMACPS_LADDR1L_OFFSET + Index * 8), MacAddr);
112 /* There are reserved bits in TOP so don't affect them */
113 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
114 (XEMACPS_LADDR1H_OFFSET + (Index * 8)));
116 MacAddr &= ~XEMACPS_LADDR_MACH_MASK;
118 /* Set MAC bits [47:32] in TOP */
120 MacAddr |= Aptr[5] << 8;
122 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
123 (XEMACPS_LADDR1H_OFFSET + (Index * 8)), MacAddr);
125 return (XST_SUCCESS);
129 /*****************************************************************************/
131 * Get the MAC address for this driver/device.
133 * @param InstancePtr is a pointer to the instance to be worked on.
134 * @param AddressPtr is an output parameter, and is a pointer to a buffer into
135 * which the current MAC address will be copied.
136 * @param Index is a index to which MAC (1-4) address.
138 *****************************************************************************/
139 void XEmacPs_GetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index)
142 u8 *Aptr = (u8 *) AddressPtr;
144 Xil_AssertVoid(InstancePtr != NULL);
145 Xil_AssertVoid(AddressPtr != NULL);
146 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
147 Xil_AssertVoid((Index <= XEMACPS_MAX_MAC_ADDR) && (Index > 0));
149 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
152 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
153 (XEMACPS_LADDR1L_OFFSET + (Index * 8)));
154 Aptr[0] = (u8) MacAddr;
155 Aptr[1] = (u8) (MacAddr >> 8);
156 Aptr[2] = (u8) (MacAddr >> 16);
157 Aptr[3] = (u8) (MacAddr >> 24);
159 /* Read MAC bits [47:32] in TOP */
160 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
161 (XEMACPS_LADDR1H_OFFSET + (Index * 8)));
162 Aptr[4] = (u8) MacAddr;
163 Aptr[5] = (u8) (MacAddr >> 8);
167 /*****************************************************************************/
169 * Set 48-bit MAC addresses in hash table.
170 * The device must be stopped before calling this function.
172 * The hash address register is 64 bits long and takes up two locations in
173 * the memory map. The least significant bits are stored in hash register
174 * bottom and the most significant bits in hash register top.
176 * The unicast hash enable and the multicast hash enable bits in the network
177 * configuration register enable the reception of hash matched frames. The
178 * destination address is reduced to a 6 bit index into the 64 bit hash
179 * register using the following hash function. The hash function is an XOR
180 * of every sixth bit of the destination address.
183 * hash_index[05] = da[05]^da[11]^da[17]^da[23]^da[29]^da[35]^da[41]^da[47]
184 * hash_index[04] = da[04]^da[10]^da[16]^da[22]^da[28]^da[34]^da[40]^da[46]
185 * hash_index[03] = da[03]^da[09]^da[15]^da[21]^da[27]^da[33]^da[39]^da[45]
186 * hash_index[02] = da[02]^da[08]^da[14]^da[20]^da[26]^da[32]^da[38]^da[44]
187 * hash_index[01] = da[01]^da[07]^da[13]^da[19]^da[25]^da[31]^da[37]^da[43]
188 * hash_index[00] = da[00]^da[06]^da[12]^da[18]^da[24]^da[30]^da[36]^da[42]
191 * da[0] represents the least significant bit of the first byte received,
192 * that is, the multicast/unicast indicator, and da[47] represents the most
193 * significant bit of the last byte received.
195 * If the hash index points to a bit that is set in the hash register then
196 * the frame will be matched according to whether the frame is multicast
199 * A multicast match will be signaled if the multicast hash enable bit is
200 * set, da[0] is logic 1 and the hash index points to a bit set in the hash
203 * A unicast match will be signaled if the unicast hash enable bit is set,
204 * da[0] is logic 0 and the hash index points to a bit set in the hash
207 * To receive all multicast frames, the hash register should be set with
208 * all ones and the multicast hash enable bit should be set in the network
209 * configuration register.
212 * @param InstancePtr is a pointer to the instance to be worked on.
213 * @param AddressPtr is a pointer to a 6-byte MAC address.
216 * - XST_SUCCESS if the HASH MAC address was set successfully
217 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
218 * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
219 * requirement after calculation
222 * Having Aptr be unsigned type prevents the following operations from sign
224 *****************************************************************************/
225 int XEmacPs_SetHash(XEmacPs *InstancePtr, void *AddressPtr)
228 u8 *Aptr = (u8 *) AddressPtr;
229 u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
232 Xil_AssertNonvoid(InstancePtr != NULL);
233 Xil_AssertNonvoid(AddressPtr != NULL);
234 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
236 /* Be sure device has been stopped */
237 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
238 return (XST_DEVICE_IS_STARTED);
240 Temp1 = Aptr[0] & 0x3F;
241 Temp2 = ((Aptr[0] >> 6) & 0x3) | ((Aptr[1] & 0xF) << 2);
242 Temp3 = ((Aptr[1] >> 4) & 0xF) | ((Aptr[2] & 0x3) << 4);
243 Temp4 = ((Aptr[2] >> 2) & 0x3F);
244 Temp5 = Aptr[3] & 0x3F;
245 Temp6 = ((Aptr[3] >> 6) & 0x3) | ((Aptr[4] & 0xF) << 2);
246 Temp7 = ((Aptr[4] >> 4) & 0xF) | ((Aptr[5] & 0x3) << 4);
247 Temp8 = ((Aptr[5] >> 2) & 0x3F);
249 Result = Temp1 ^ Temp2 ^ Temp3 ^ Temp4 ^ Temp5 ^ Temp6 ^ Temp7 ^ Temp8;
251 if (Result >= XEMACPS_MAX_HASH_BITS) {
252 return (XST_INVALID_PARAM);
256 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
257 XEMACPS_HASHL_OFFSET);
258 HashAddr |= (1 << Result);
259 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
260 XEMACPS_HASHL_OFFSET, HashAddr);
262 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
263 XEMACPS_HASHH_OFFSET);
264 HashAddr |= (1 << (Result - 32));
265 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
266 XEMACPS_HASHH_OFFSET, HashAddr);
269 return (XST_SUCCESS);
272 /*****************************************************************************/
274 * Delete 48-bit MAC addresses in hash table.
275 * The device must be stopped before calling this function.
277 * @param InstancePtr is a pointer to the instance to be worked on.
278 * @param AddressPtr is a pointer to a 6-byte MAC address.
281 * - XST_SUCCESS if the HASH MAC address was deleted successfully
282 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
283 * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
284 * requirement after calculation
287 * Having Aptr be unsigned type prevents the following operations from sign
289 *****************************************************************************/
290 int XEmacPs_DeleteHash(XEmacPs *InstancePtr, void *AddressPtr)
293 u8 *Aptr = (u8 *) AddressPtr;
294 u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
297 Xil_AssertNonvoid(InstancePtr != NULL);
298 Xil_AssertNonvoid(AddressPtr != NULL);
299 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
301 /* Be sure device has been stopped */
302 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
303 return (XST_DEVICE_IS_STARTED);
305 Temp1 = Aptr[0] & 0x3F;
306 Temp2 = ((Aptr[0] >> 6) & 0x3) | ((Aptr[1] & 0xF) << 2);
307 Temp3 = ((Aptr[1] >> 4) & 0xF) | ((Aptr[2] & 0x3) << 4);
308 Temp4 = ((Aptr[2] >> 2) & 0x3F);
309 Temp5 = Aptr[3] & 0x3F;
310 Temp6 = ((Aptr[3] >> 6) & 0x3) | ((Aptr[4] & 0xF) << 2);
311 Temp7 = ((Aptr[4] >> 4) & 0xF) | ((Aptr[5] & 0x3) << 4);
312 Temp8 = ((Aptr[5] >> 2) & 0x3F);
314 Result = Temp1 ^ Temp2 ^ Temp3 ^ Temp4 ^ Temp5 ^ Temp6 ^ Temp7 ^ Temp8;
316 if (Result >= XEMACPS_MAX_HASH_BITS) {
317 return (XST_INVALID_PARAM);
321 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
322 XEMACPS_HASHL_OFFSET);
323 HashAddr &= (~(1 << Result));
324 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
325 XEMACPS_HASHL_OFFSET, HashAddr);
327 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
328 XEMACPS_HASHH_OFFSET);
329 HashAddr &= (~(1 << (Result - 32)));
330 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
331 XEMACPS_HASHH_OFFSET, HashAddr);
334 return (XST_SUCCESS);
338 /*****************************************************************************/
340 * Clear the Hash registers for the mac address pointed by AddressPtr.
342 * @param InstancePtr is a pointer to the instance to be worked on.
344 *****************************************************************************/
345 void XEmacPs_ClearHash(XEmacPs *InstancePtr)
347 Xil_AssertVoid(InstancePtr != NULL);
348 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
350 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
351 XEMACPS_HASHL_OFFSET, 0x0);
353 /* write bits [63:32] in TOP */
354 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
355 XEMACPS_HASHH_OFFSET, 0x0);
359 /*****************************************************************************/
361 * Get the Hash address for this driver/device.
363 * @param InstancePtr is a pointer to the instance to be worked on.
364 * @param AddressPtr is an output parameter, and is a pointer to a buffer into
365 * which the current HASH MAC address will be copied.
367 *****************************************************************************/
368 void XEmacPs_GetHash(XEmacPs *InstancePtr, void *AddressPtr)
370 u32 *Aptr = (u32 *) AddressPtr;
372 Xil_AssertVoid(InstancePtr != NULL);
373 Xil_AssertVoid(AddressPtr != NULL);
374 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
376 Aptr[0] = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
377 XEMACPS_HASHL_OFFSET);
379 /* Read Hash bits [63:32] in TOP */
380 Aptr[1] = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
381 XEMACPS_HASHH_OFFSET);
385 /*****************************************************************************/
387 * Set the Type ID match for this driver/device. The register is a 32-bit
388 * value. The device must be stopped before calling this function.
390 * @param InstancePtr is a pointer to the instance to be worked on.
391 * @param Id_Check is type ID to be configured.
392 * @param Index is a index to which Type ID (1-4).
395 * - XST_SUCCESS if the MAC address was set successfully
396 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
398 *****************************************************************************/
399 int XEmacPs_SetTypeIdCheck(XEmacPs *InstancePtr, u32 Id_Check, u8 Index)
401 Xil_AssertNonvoid(InstancePtr != NULL);
402 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
403 Xil_AssertNonvoid((Index <= XEMACPS_MAX_TYPE_ID) && (Index > 0));
405 /* Be sure device has been stopped */
406 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
407 return (XST_DEVICE_IS_STARTED);
410 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
413 /* Set the ID bits in MATCHx register */
414 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
415 (XEMACPS_MATCH1_OFFSET + (Index * 4)), Id_Check);
417 return (XST_SUCCESS);
420 /*****************************************************************************/
422 * Set options for the driver/device. The driver should be stopped with
423 * XEmacPs_Stop() before changing options.
425 * @param InstancePtr is a pointer to the instance to be worked on.
426 * @param Options are the options to set. Multiple options can be set by OR'ing
427 * XTE_*_OPTIONS constants together. Options not specified are not
431 * - XST_SUCCESS if the options were set successfully
432 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
435 * See xemacps.h for a description of the available options.
437 *****************************************************************************/
438 int XEmacPs_SetOptions(XEmacPs *InstancePtr, u32 Options)
440 u32 Reg; /* Generic register contents */
441 u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
442 u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
444 Xil_AssertNonvoid(InstancePtr != NULL);
445 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
447 /* Be sure device has been stopped */
448 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
449 return (XST_DEVICE_IS_STARTED);
452 /* Many of these options will change the NET_CONFIG registers.
453 * To reduce the amount of IO to the device, group these options here
454 * and change them all at once.
457 /* Grab current register contents */
458 RegNetCfg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
459 XEMACPS_NWCFG_OFFSET);
460 RegNewNetCfg = RegNetCfg;
463 * It is configured to max 1536.
465 if (Options & XEMACPS_FRAME1536_OPTION) {
466 RegNewNetCfg |= (XEMACPS_NWCFG_1536RXEN_MASK);
469 /* Turn on VLAN packet only, only VLAN tagged will be accepted */
470 if (Options & XEMACPS_VLAN_OPTION) {
471 RegNewNetCfg |= XEMACPS_NWCFG_NVLANDISC_MASK;
474 /* Turn on FCS stripping on receive packets */
475 if (Options & XEMACPS_FCS_STRIP_OPTION) {
476 RegNewNetCfg |= XEMACPS_NWCFG_FCSREM_MASK;
479 /* Turn on length/type field checking on receive packets */
480 if (Options & XEMACPS_LENTYPE_ERR_OPTION) {
481 RegNewNetCfg |= XEMACPS_NWCFG_LENGTHERRDSCRD_MASK;
484 /* Turn on flow control */
485 if (Options & XEMACPS_FLOW_CONTROL_OPTION) {
486 RegNewNetCfg |= XEMACPS_NWCFG_PAUSEEN_MASK;
489 /* Turn on promiscuous frame filtering (all frames are received) */
490 if (Options & XEMACPS_PROMISC_OPTION) {
491 RegNewNetCfg |= XEMACPS_NWCFG_COPYALLEN_MASK;
494 /* Allow broadcast address reception */
495 if (Options & XEMACPS_BROADCAST_OPTION) {
496 RegNewNetCfg &= ~XEMACPS_NWCFG_BCASTDI_MASK;
499 /* Allow multicast address filtering */
500 if (Options & XEMACPS_MULTICAST_OPTION) {
501 RegNewNetCfg |= XEMACPS_NWCFG_MCASTHASHEN_MASK;
504 /* enable RX checksum offload */
505 if (Options & XEMACPS_RX_CHKSUM_ENABLE_OPTION) {
506 RegNewNetCfg |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
509 /* Officially change the NET_CONFIG registers if it needs to be
512 if (RegNetCfg != RegNewNetCfg) {
513 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
514 XEMACPS_NWCFG_OFFSET, RegNewNetCfg);
517 /* Enable TX checksum offload */
518 if (Options & XEMACPS_TX_CHKSUM_ENABLE_OPTION) {
519 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
520 XEMACPS_DMACR_OFFSET);
521 Reg |= XEMACPS_DMACR_TCPCKSUM_MASK;
522 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
523 XEMACPS_DMACR_OFFSET, Reg);
526 /* Enable transmitter */
527 if (Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
528 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
529 XEMACPS_NWCTRL_OFFSET);
530 Reg |= XEMACPS_NWCTRL_TXEN_MASK;
531 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
532 XEMACPS_NWCTRL_OFFSET, Reg);
535 /* Enable receiver */
536 if (Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
537 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
538 XEMACPS_NWCTRL_OFFSET);
539 Reg |= XEMACPS_NWCTRL_RXEN_MASK;
540 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
541 XEMACPS_NWCTRL_OFFSET, Reg);
544 /* The remaining options not handled here are managed elsewhere in the
545 * driver. No register modifications are needed at this time. Reflecting
546 * the option in InstancePtr->Options is good enough for now.
549 /* Set options word to its new value */
550 InstancePtr->Options |= Options;
552 return (XST_SUCCESS);
556 /*****************************************************************************/
558 * Clear options for the driver/device
560 * @param InstancePtr is a pointer to the instance to be worked on.
561 * @param Options are the options to clear. Multiple options can be cleared by
562 * OR'ing XEMACPS_*_OPTIONS constants together. Options not specified
566 * - XST_SUCCESS if the options were set successfully
567 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
570 * See xemacps.h for a description of the available options.
572 *****************************************************************************/
573 int XEmacPs_ClearOptions(XEmacPs *InstancePtr, u32 Options)
575 u32 Reg; /* Generic */
576 u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
577 u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
579 Xil_AssertNonvoid(InstancePtr != NULL);
580 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
582 /* Be sure device has been stopped */
583 if (InstancePtr->IsStarted == XIL_COMPONENT_IS_STARTED) {
584 return (XST_DEVICE_IS_STARTED);
587 /* Many of these options will change the NET_CONFIG registers.
588 * To reduce the amount of IO to the device, group these options here
589 * and change them all at once.
592 /* Grab current register contents */
593 RegNetCfg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
594 XEMACPS_NWCFG_OFFSET);
595 RegNewNetCfg = RegNetCfg;
597 /* There is only RX configuration!?
598 * It is configured in two different length, upto 1536 and 10240 bytes
600 if (Options & XEMACPS_FRAME1536_OPTION) {
601 RegNewNetCfg &= ~XEMACPS_NWCFG_1536RXEN_MASK;
604 /* Turn off VLAN packet only */
605 if (Options & XEMACPS_VLAN_OPTION) {
606 RegNewNetCfg &= ~XEMACPS_NWCFG_NVLANDISC_MASK;
609 /* Turn off FCS stripping on receive packets */
610 if (Options & XEMACPS_FCS_STRIP_OPTION) {
611 RegNewNetCfg &= ~XEMACPS_NWCFG_FCSREM_MASK;
614 /* Turn off length/type field checking on receive packets */
615 if (Options & XEMACPS_LENTYPE_ERR_OPTION) {
616 RegNewNetCfg &= ~XEMACPS_NWCFG_LENGTHERRDSCRD_MASK;
619 /* Turn off flow control */
620 if (Options & XEMACPS_FLOW_CONTROL_OPTION) {
621 RegNewNetCfg &= ~XEMACPS_NWCFG_PAUSEEN_MASK;
624 /* Turn off promiscuous frame filtering (all frames are received) */
625 if (Options & XEMACPS_PROMISC_OPTION) {
626 RegNewNetCfg &= ~XEMACPS_NWCFG_COPYALLEN_MASK;
629 /* Disallow broadcast address filtering => broadcast reception */
630 if (Options & XEMACPS_BROADCAST_OPTION) {
631 RegNewNetCfg |= XEMACPS_NWCFG_BCASTDI_MASK;
634 /* Disallow multicast address filtering */
635 if (Options & XEMACPS_MULTICAST_OPTION) {
636 RegNewNetCfg &= ~XEMACPS_NWCFG_MCASTHASHEN_MASK;
639 /* Disable RX checksum offload */
640 if (Options & XEMACPS_RX_CHKSUM_ENABLE_OPTION) {
641 RegNewNetCfg &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
644 /* Officially change the NET_CONFIG registers if it needs to be
647 if (RegNetCfg != RegNewNetCfg) {
648 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
649 XEMACPS_NWCFG_OFFSET, RegNewNetCfg);
652 /* Disable TX checksum offload */
653 if (Options & XEMACPS_TX_CHKSUM_ENABLE_OPTION) {
654 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
655 XEMACPS_DMACR_OFFSET);
656 Reg &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
657 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
658 XEMACPS_DMACR_OFFSET, Reg);
661 /* Disable transmitter */
662 if (Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) {
663 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
664 XEMACPS_NWCTRL_OFFSET);
665 Reg &= ~XEMACPS_NWCTRL_TXEN_MASK;
666 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
667 XEMACPS_NWCTRL_OFFSET, Reg);
670 /* Disable receiver */
671 if (Options & XEMACPS_RECEIVER_ENABLE_OPTION) {
672 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
673 XEMACPS_NWCTRL_OFFSET);
674 Reg &= ~XEMACPS_NWCTRL_RXEN_MASK;
675 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
676 XEMACPS_NWCTRL_OFFSET, Reg);
679 /* The remaining options not handled here are managed elsewhere in the
680 * driver. No register modifications are needed at this time. Reflecting
681 * option in InstancePtr->Options is good enough for now.
684 /* Set options word to its new value */
685 InstancePtr->Options &= ~Options;
687 return (XST_SUCCESS);
691 /*****************************************************************************/
693 * Get current option settings
695 * @param InstancePtr is a pointer to the instance to be worked on.
698 * A bitmask of XTE_*_OPTION constants. Any bit set to 1 is to be interpreted
702 * See xemacps.h for a description of the available options.
704 *****************************************************************************/
705 u32 XEmacPs_GetOptions(XEmacPs *InstancePtr)
707 Xil_AssertNonvoid(InstancePtr != NULL);
708 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
710 return (InstancePtr->Options);
714 /*****************************************************************************/
716 * Send a pause packet
718 * @param InstancePtr is a pointer to the instance to be worked on.
721 * - XST_SUCCESS if pause frame transmission was initiated
722 * - XST_DEVICE_IS_STOPPED if the device has not been started.
724 *****************************************************************************/
725 int XEmacPs_SendPausePacket(XEmacPs *InstancePtr)
729 Xil_AssertNonvoid(InstancePtr != NULL);
730 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
732 /* Make sure device is ready for this operation */
733 if (InstancePtr->IsStarted != XIL_COMPONENT_IS_STARTED) {
734 return (XST_DEVICE_IS_STOPPED);
737 /* Send flow control frame */
738 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
739 XEMACPS_NWCTRL_OFFSET);
740 Reg |= XEMACPS_NWCTRL_PAUSETX_MASK;
741 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
742 XEMACPS_NWCTRL_OFFSET, Reg);
743 return (XST_SUCCESS);
746 /*****************************************************************************/
748 * XEmacPs_GetOperatingSpeed gets the current operating link speed. This may
749 * be the value set by XEmacPs_SetOperatingSpeed() or a hardware default.
751 * @param InstancePtr references the TEMAC channel on which to operate.
753 * @return XEmacPs_GetOperatingSpeed returns the link speed in units of
754 * megabits per second.
758 *****************************************************************************/
759 u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr)
763 Xil_AssertNonvoid(InstancePtr != NULL);
764 Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
766 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
767 XEMACPS_NWCFG_OFFSET);
769 if (Reg & XEMACPS_NWCFG_1000_MASK) {
772 if (Reg & XEMACPS_NWCFG_100_MASK) {
781 /*****************************************************************************/
783 * XEmacPs_SetOperatingSpeed sets the current operating link speed. For any
784 * traffic to be passed, this speed must match the current MII/GMII/SGMII/RGMII
787 * @param InstancePtr references the TEMAC channel on which to operate.
788 * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100,
789 * or 1000. XEmacPs_SetOperatingSpeed ignores invalid values.
793 *****************************************************************************/
794 void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed)
798 Xil_AssertVoid(InstancePtr != NULL);
799 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
800 Xil_AssertVoid((Speed == 10) || (Speed == 100) || (Speed == 1000));
802 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
803 XEMACPS_NWCFG_OFFSET);
804 Reg &= ~(XEMACPS_NWCFG_1000_MASK | XEMACPS_NWCFG_100_MASK);
811 Reg |= XEMACPS_NWCFG_100_MASK;
815 Reg |= XEMACPS_NWCFG_1000_MASK;
822 /* Set register and return */
823 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
824 XEMACPS_NWCFG_OFFSET, Reg);
828 /*****************************************************************************/
830 * Set the MDIO clock divisor.
832 * Calculating the divisor:
836 * f[MDC] = -----------------
840 * where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the
841 * MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not
842 * exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster
843 * access. Here is the table to show values to generate MDC,
846 * 000 : divide pclk by 8 (pclk up to 20 MHz)
847 * 001 : divide pclk by 16 (pclk up to 40 MHz)
848 * 010 : divide pclk by 32 (pclk up to 80 MHz)
849 * 011 : divide pclk by 48 (pclk up to 120 MHz)
850 * 100 : divide pclk by 64 (pclk up to 160 MHz)
851 * 101 : divide pclk by 96 (pclk up to 240 MHz)
852 * 110 : divide pclk by 128 (pclk up to 320 MHz)
853 * 111 : divide pclk by 224 (pclk up to 540 MHz)
856 * @param InstancePtr is a pointer to the instance to be worked on.
857 * @param Divisor is the divisor to set. Range is 0b000 to 0b111.
859 *****************************************************************************/
860 void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr, XEmacPs_MdcDiv Divisor)
864 Xil_AssertVoid(InstancePtr != NULL);
865 Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
866 Xil_AssertVoid(Divisor <= 0x7); /* only last three bits are valid */
868 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
869 XEMACPS_NWCFG_OFFSET);
870 /* clear these three bits, could be done with mask */
871 Reg &= ~XEMACPS_NWCFG_MDCCLKDIV_MASK;
873 Reg |= (Divisor << XEMACPS_NWCFG_MDC_SHIFT_MASK);
875 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
876 XEMACPS_NWCFG_OFFSET, Reg);
881 /*****************************************************************************/
883 * Read the current value of the PHY register indicated by the PhyAddress and
884 * the RegisterNum parameters. The MAC provides the driver with the ability to
885 * talk to a PHY that adheres to the Media Independent Interface (MII) as
886 * defined in the IEEE 802.3 standard.
888 * Prior to PHY access with this function, the user should have setup the MDIO
889 * clock with XEmacPs_SetMdioDivisor().
891 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
892 * @param PhyAddress is the address of the PHY to be read (supports multiple
894 * @param RegisterNum is the register number, 0-31, of the specific PHY register
896 * @param PhyDataPtr is an output parameter, and points to a 16-bit buffer into
897 * which the current value of the register will be copied.
901 * - XST_SUCCESS if the PHY was read from successfully
902 * - XST_EMAC_MII_BUSY if there is another PHY operation in progress
906 * This function is not thread-safe. The user must provide mutually exclusive
907 * access to this function if there are to be multiple threads that can call it.
909 * There is the possibility that this function will not return if the hardware
910 * is broken (i.e., it never sets the status bit indicating that the read is
911 * done). If this is of concern to the user, the user should provide a mechanism
912 * suitable to their needs for recovery.
914 * For the duration of this function, all host interface reads and writes are
915 * blocked to the current XEmacPs instance.
917 ******************************************************************************/
918 int XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
919 u32 RegisterNum, u16 *PhyDataPtr)
924 Xil_AssertNonvoid(InstancePtr != NULL);
926 /* Make sure no other PHY operation is currently in progress */
927 if (!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
928 XEMACPS_NWSR_OFFSET) &
929 XEMACPS_NWSR_MDIOIDLE_MASK)) {
930 return (XST_EMAC_MII_BUSY);
933 /* Construct Mgtcr mask for the operation */
934 Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_R_MASK |
935 (PhyAddress << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK) |
936 (RegisterNum << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK);
938 /* Write Mgtcr and wait for completion */
939 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
940 XEMACPS_PHYMNTNC_OFFSET, Mgtcr);
943 Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
944 XEMACPS_NWSR_OFFSET);
945 } while ((Ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0);
948 *PhyDataPtr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
949 XEMACPS_PHYMNTNC_OFFSET);
951 return (XST_SUCCESS);
955 /*****************************************************************************/
957 * Write data to the specified PHY register. The Ethernet driver does not
958 * require the device to be stopped before writing to the PHY. Although it is
959 * probably a good idea to stop the device, it is the responsibility of the
960 * application to deem this necessary. The MAC provides the driver with the
961 * ability to talk to a PHY that adheres to the Media Independent Interface
962 * (MII) as defined in the IEEE 802.3 standard.
964 * Prior to PHY access with this function, the user should have setup the MDIO
965 * clock with XEmacPs_SetMdioDivisor().
967 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
968 * @param PhyAddress is the address of the PHY to be written (supports multiple
970 * @param RegisterNum is the register number, 0-31, of the specific PHY register
972 * @param PhyData is the 16-bit value that will be written to the register
976 * - XST_SUCCESS if the PHY was written to successfully. Since there is no error
977 * status from the MAC on a write, the user should read the PHY to verify the
978 * write was successful.
979 * - XST_EMAC_MII_BUSY if there is another PHY operation in progress
983 * This function is not thread-safe. The user must provide mutually exclusive
984 * access to this function if there are to be multiple threads that can call it.
986 * There is the possibility that this function will not return if the hardware
987 * is broken (i.e., it never sets the status bit indicating that the write is
988 * done). If this is of concern to the user, the user should provide a mechanism
989 * suitable to their needs for recovery.
991 * For the duration of this function, all host interface reads and writes are
992 * blocked to the current XEmacPs instance.
994 ******************************************************************************/
995 int XEmacPs_PhyWrite(XEmacPs *InstancePtr, u32 PhyAddress,
996 u32 RegisterNum, u16 PhyData)
1001 Xil_AssertNonvoid(InstancePtr != NULL);
1003 /* Make sure no other PHY operation is currently in progress */
1004 if (!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1005 XEMACPS_NWSR_OFFSET) &
1006 XEMACPS_NWSR_MDIOIDLE_MASK)) {
1007 return (XST_EMAC_MII_BUSY);
1010 /* Construct Mgtcr mask for the operation */
1011 Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_W_MASK |
1012 (PhyAddress << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK) |
1013 (RegisterNum << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK) | PhyData;
1015 /* Write Mgtcr and wait for completion */
1016 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
1017 XEMACPS_PHYMNTNC_OFFSET, Mgtcr);
1020 Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1021 XEMACPS_NWSR_OFFSET);
1022 } while ((Ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0);
1024 return (XST_SUCCESS);
1027 /*****************************************************************************/
1029 * API to update the Burst length in the DMACR register.
1031 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
1032 * @param BLength is the length in bytes for the dma burst.
1036 ******************************************************************************/
1037 void XEmacPs_DMABLengthUpdate(XEmacPs *InstancePtr, int BLength)
1040 u32 RegUpdateVal = 0;
1042 Xil_AssertVoid(InstancePtr != NULL);
1043 Xil_AssertVoid((BLength == XEMACPS_SINGLE_BURST) ||
1044 (BLength == XEMACPS_4BYTE_BURST) ||
1045 (BLength == XEMACPS_8BYTE_BURST) ||
1046 (BLength == XEMACPS_16BYTE_BURST));
1049 case XEMACPS_SINGLE_BURST:
1050 RegUpdateVal = XEMACPS_DMACR_SINGLE_AHB_BURST;
1053 case XEMACPS_4BYTE_BURST:
1054 RegUpdateVal = XEMACPS_DMACR_INCR4_AHB_BURST;
1057 case XEMACPS_8BYTE_BURST:
1058 RegUpdateVal = XEMACPS_DMACR_INCR8_AHB_BURST;
1061 case XEMACPS_16BYTE_BURST:
1062 RegUpdateVal = XEMACPS_DMACR_INCR16_AHB_BURST;
1068 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1069 XEMACPS_DMACR_OFFSET);
1071 Reg &= (~XEMACPS_DMACR_BLENGTH_MASK);
1072 Reg |= RegUpdateVal;
1073 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET,