1 /******************************************************************************
3 * Copyright (C) 2009 - 2016 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /*****************************************************************************/
35 * @file xemacps_control.c
36 * @addtogroup emacps_v3_1
39 * Functions in this file implement general purpose command and control related
40 * functionality. See xemacps.h for a detailed description of the driver.
43 * MODIFICATION HISTORY:
45 * Ver Who Date Changes
46 * ----- ---- -------- -------------------------------------------------------
47 * 1.00a wsy 01/10/10 First release
48 * 1.02a asa 11/05/12 Added a new API for deleting an entry from the HASH
49 * register. Added a new API for setting the BURST length
51 * 2.1 srt 07/15/14 Add support for Zynq Ultrascale Mp architecture.
52 * 3.0 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
53 * 3.0 hk 02/20/15 Added support for jumbo frames.
54 * 3.2 hk 02/22/16 Added SGMII support for Zynq Ultrascale+ MPSoC.
56 *****************************************************************************/
58 /***************************** Include Files *********************************/
62 /************************** Constant Definitions *****************************/
65 /**************************** Type Definitions *******************************/
68 /***************** Macros (Inline Functions) Definitions *********************/
71 /************************** Function Prototypes ******************************/
74 /************************** Variable Definitions *****************************/
77 /*****************************************************************************/
79 * Set the MAC address for this driver/device. The address is a 48-bit value.
80 * The device must be stopped before calling this function.
82 * @param InstancePtr is a pointer to the instance to be worked on.
83 * @param AddressPtr is a pointer to a 6-byte MAC address.
84 * @param Index is a index to which MAC (1-4) address.
87 * - XST_SUCCESS if the MAC address was set successfully
88 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
90 *****************************************************************************/
91 LONG XEmacPs_SetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index)
94 u8 *Aptr = (u8 *)(void *)AddressPtr;
97 Xil_AssertNonvoid(InstancePtr != NULL);
98 Xil_AssertNonvoid(Aptr != NULL);
99 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
100 Xil_AssertNonvoid((IndexLoc <= (u8)XEMACPS_MAX_MAC_ADDR) && (IndexLoc > 0x00U));
102 /* Be sure device has been stopped */
103 if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
104 Status = (LONG)(XST_DEVICE_IS_STARTED);
107 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
110 /* Set the MAC bits [31:0] in BOT */
112 MacAddr |= ((u32)(*(Aptr+1)) << 8U);
113 MacAddr |= ((u32)(*(Aptr+2)) << 16U);
114 MacAddr |= ((u32)(*(Aptr+3)) << 24U);
115 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
116 ((u32)XEMACPS_LADDR1L_OFFSET + ((u32)IndexLoc * (u32)8)), MacAddr);
118 /* There are reserved bits in TOP so don't affect them */
119 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
120 ((u32)XEMACPS_LADDR1H_OFFSET + ((u32)IndexLoc * (u32)8)));
122 MacAddr &= (u32)(~XEMACPS_LADDR_MACH_MASK);
124 /* Set MAC bits [47:32] in TOP */
125 MacAddr |= (u32)(*(Aptr+4));
126 MacAddr |= (u32)(*(Aptr+5)) << 8U;
128 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
129 ((u32)XEMACPS_LADDR1H_OFFSET + ((u32)IndexLoc * (u32)8)), MacAddr);
131 Status = (LONG)(XST_SUCCESS);
137 /*****************************************************************************/
139 * Get the MAC address for this driver/device.
141 * @param InstancePtr is a pointer to the instance to be worked on.
142 * @param AddressPtr is an output parameter, and is a pointer to a buffer into
143 * which the current MAC address will be copied.
144 * @param Index is a index to which MAC (1-4) address.
146 *****************************************************************************/
147 void XEmacPs_GetMacAddress(XEmacPs *InstancePtr, void *AddressPtr, u8 Index)
150 u8 *Aptr = (u8 *)(void *)AddressPtr;
152 Xil_AssertVoid(InstancePtr != NULL);
153 Xil_AssertVoid(Aptr != NULL);
154 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
155 Xil_AssertVoid((IndexLoc <= (u8)XEMACPS_MAX_MAC_ADDR) && (IndexLoc > 0x00U));
157 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
160 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
161 ((u32)XEMACPS_LADDR1L_OFFSET + ((u32)IndexLoc * (u32)8)));
162 *Aptr = (u8) MacAddr;
163 *(Aptr+1) = (u8) (MacAddr >> 8U);
164 *(Aptr+2) = (u8) (MacAddr >> 16U);
165 *(Aptr+3) = (u8) (MacAddr >> 24U);
167 /* Read MAC bits [47:32] in TOP */
168 MacAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
169 ((u32)XEMACPS_LADDR1H_OFFSET + ((u32)IndexLoc * (u32)8)));
170 *(Aptr+4) = (u8) MacAddr;
171 *(Aptr+5) = (u8) (MacAddr >> 8U);
175 /*****************************************************************************/
177 * Set 48-bit MAC addresses in hash table.
178 * The device must be stopped before calling this function.
180 * The hash address register is 64 bits long and takes up two locations in
181 * the memory map. The least significant bits are stored in hash register
182 * bottom and the most significant bits in hash register top.
184 * The unicast hash enable and the multicast hash enable bits in the network
185 * configuration register enable the reception of hash matched frames. The
186 * destination address is reduced to a 6 bit index into the 64 bit hash
187 * register using the following hash function. The hash function is an XOR
188 * of every sixth bit of the destination address.
191 * hash_index[05] = da[05]^da[11]^da[17]^da[23]^da[29]^da[35]^da[41]^da[47]
192 * hash_index[04] = da[04]^da[10]^da[16]^da[22]^da[28]^da[34]^da[40]^da[46]
193 * hash_index[03] = da[03]^da[09]^da[15]^da[21]^da[27]^da[33]^da[39]^da[45]
194 * hash_index[02] = da[02]^da[08]^da[14]^da[20]^da[26]^da[32]^da[38]^da[44]
195 * hash_index[01] = da[01]^da[07]^da[13]^da[19]^da[25]^da[31]^da[37]^da[43]
196 * hash_index[00] = da[00]^da[06]^da[12]^da[18]^da[24]^da[30]^da[36]^da[42]
199 * da[0] represents the least significant bit of the first byte received,
200 * that is, the multicast/unicast indicator, and da[47] represents the most
201 * significant bit of the last byte received.
203 * If the hash index points to a bit that is set in the hash register then
204 * the frame will be matched according to whether the frame is multicast
207 * A multicast match will be signaled if the multicast hash enable bit is
208 * set, da[0] is logic 1 and the hash index points to a bit set in the hash
211 * A unicast match will be signaled if the unicast hash enable bit is set,
212 * da[0] is logic 0 and the hash index points to a bit set in the hash
215 * To receive all multicast frames, the hash register should be set with
216 * all ones and the multicast hash enable bit should be set in the network
217 * configuration register.
220 * @param InstancePtr is a pointer to the instance to be worked on.
221 * @param AddressPtr is a pointer to a 6-byte MAC address.
224 * - XST_SUCCESS if the HASH MAC address was set successfully
225 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
226 * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
227 * requirement after calculation
230 * Having Aptr be unsigned type prevents the following operations from sign
232 *****************************************************************************/
233 LONG XEmacPs_SetHash(XEmacPs *InstancePtr, void *AddressPtr)
236 u8 *Aptr = (u8 *)(void *)AddressPtr;
237 u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
241 Xil_AssertNonvoid(InstancePtr != NULL);
242 Xil_AssertNonvoid(AddressPtr != NULL);
243 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
245 /* Be sure device has been stopped */
246 if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
247 Status = (LONG)(XST_DEVICE_IS_STARTED);
249 Temp1 = (*(Aptr+0)) & 0x3FU;
250 Temp2 = ((*(Aptr+0) >> 6U) & 0x03U) | ((*(Aptr+1) & 0x0FU) << 2U);
252 Temp3 = ((*(Aptr+1) >> 4U) & 0x0FU) | ((*(Aptr+2) & 0x3U) << 4U);
253 Temp4 = ((*(Aptr+2) >> 2U) & 0x3FU);
254 Temp5 = (*(Aptr+3)) & 0x3FU;
255 Temp6 = ((*(Aptr+3) >> 6U) & 0x03U) | ((*(Aptr+4) & 0x0FU) << 2U);
256 Temp7 = ((*(Aptr+4) >> 4U) & 0x0FU) | ((*(Aptr+5) & 0x03U) << 4U);
257 Temp8 = ((*(Aptr+5) >> 2U) & 0x3FU);
259 Result = (u32)((u32)Temp1 ^ (u32)Temp2 ^ (u32)Temp3 ^ (u32)Temp4 ^
260 (u32)Temp5 ^ (u32)Temp6 ^ (u32)Temp7 ^ (u32)Temp8);
262 if (Result >= (u32)XEMACPS_MAX_HASH_BITS) {
263 Status = (LONG)(XST_INVALID_PARAM);
266 if (Result < (u32)32) {
267 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
268 XEMACPS_HASHL_OFFSET);
269 HashAddr |= (u32)(0x00000001U << Result);
270 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
271 XEMACPS_HASHL_OFFSET, HashAddr);
273 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
274 XEMACPS_HASHH_OFFSET);
275 HashAddr |= (u32)(0x00000001U << (u32)(Result - (u32)32));
276 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
277 XEMACPS_HASHH_OFFSET, HashAddr);
279 Status = (LONG)(XST_SUCCESS);
285 /*****************************************************************************/
287 * Delete 48-bit MAC addresses in hash table.
288 * The device must be stopped before calling this function.
290 * @param InstancePtr is a pointer to the instance to be worked on.
291 * @param AddressPtr is a pointer to a 6-byte MAC address.
294 * - XST_SUCCESS if the HASH MAC address was deleted successfully
295 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
296 * - XST_INVALID_PARAM if the HASH MAC address passed in does not meet
297 * requirement after calculation
300 * Having Aptr be unsigned type prevents the following operations from sign
302 *****************************************************************************/
303 LONG XEmacPs_DeleteHash(XEmacPs *InstancePtr, void *AddressPtr)
306 u8 *Aptr = (u8 *)(void *)AddressPtr;
307 u8 Temp1, Temp2, Temp3, Temp4, Temp5, Temp6, Temp7, Temp8;
311 Xil_AssertNonvoid(InstancePtr != NULL);
312 Xil_AssertNonvoid(Aptr != NULL);
313 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
315 /* Be sure device has been stopped */
316 if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
317 Status = (LONG)(XST_DEVICE_IS_STARTED);
319 Temp1 = (*(Aptr+0)) & 0x3FU;
320 Temp2 = ((*(Aptr+0) >> 6U) & 0x03U) | ((*(Aptr+1) & 0x0FU) << 2U);
321 Temp3 = ((*(Aptr+1) >> 4U) & 0x0FU) | ((*(Aptr+2) & 0x03U) << 4U);
322 Temp4 = ((*(Aptr+2) >> 2U) & 0x3FU);
323 Temp5 = (*(Aptr+3)) & 0x3FU;
324 Temp6 = ((*(Aptr+3) >> 6U) & 0x03U) | ((*(Aptr+4) & 0x0FU) << 2U);
325 Temp7 = ((*(Aptr+4) >> 4U) & 0x0FU) | ((*(Aptr+5) & 0x03U) << 4U);
326 Temp8 = ((*(Aptr+5) >> 2U) & 0x3FU);
328 Result = (u32)((u32)Temp1 ^ (u32)Temp2 ^ (u32)Temp3 ^ (u32)Temp4 ^
329 (u32)Temp5 ^ (u32)Temp6 ^ (u32)Temp7 ^ (u32)Temp8);
331 if (Result >= (u32)(XEMACPS_MAX_HASH_BITS)) {
332 Status = (LONG)(XST_INVALID_PARAM);
334 if (Result < (u32)32) {
335 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
336 XEMACPS_HASHL_OFFSET);
337 HashAddr &= (u32)(~(0x00000001U << Result));
338 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
339 XEMACPS_HASHL_OFFSET, HashAddr);
341 HashAddr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
342 XEMACPS_HASHH_OFFSET);
343 HashAddr &= (u32)(~(0x00000001U << (u32)(Result - (u32)32)));
344 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
345 XEMACPS_HASHH_OFFSET, HashAddr);
347 Status = (LONG)(XST_SUCCESS);
352 /*****************************************************************************/
354 * Clear the Hash registers for the mac address pointed by AddressPtr.
356 * @param InstancePtr is a pointer to the instance to be worked on.
358 *****************************************************************************/
359 void XEmacPs_ClearHash(XEmacPs *InstancePtr)
361 Xil_AssertVoid(InstancePtr != NULL);
362 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
364 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
365 XEMACPS_HASHL_OFFSET, 0x0U);
367 /* write bits [63:32] in TOP */
368 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
369 XEMACPS_HASHH_OFFSET, 0x0U);
373 /*****************************************************************************/
375 * Get the Hash address for this driver/device.
377 * @param InstancePtr is a pointer to the instance to be worked on.
378 * @param AddressPtr is an output parameter, and is a pointer to a buffer into
379 * which the current HASH MAC address will be copied.
381 *****************************************************************************/
382 void XEmacPs_GetHash(XEmacPs *InstancePtr, void *AddressPtr)
384 u32 *Aptr = (u32 *)(void *)AddressPtr;
386 Xil_AssertVoid(InstancePtr != NULL);
387 Xil_AssertVoid(AddressPtr != NULL);
388 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
390 *(Aptr+0) = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
391 XEMACPS_HASHL_OFFSET);
393 /* Read Hash bits [63:32] in TOP */
394 *(Aptr+1) = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
395 XEMACPS_HASHH_OFFSET);
399 /*****************************************************************************/
401 * Set the Type ID match for this driver/device. The register is a 32-bit
402 * value. The device must be stopped before calling this function.
404 * @param InstancePtr is a pointer to the instance to be worked on.
405 * @param Id_Check is type ID to be configured.
406 * @param Index is a index to which Type ID (1-4).
409 * - XST_SUCCESS if the MAC address was set successfully
410 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
412 *****************************************************************************/
413 LONG XEmacPs_SetTypeIdCheck(XEmacPs *InstancePtr, u32 Id_Check, u8 Index)
417 Xil_AssertNonvoid(InstancePtr != NULL);
418 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
419 Xil_AssertNonvoid((IndexLoc <= (u8)XEMACPS_MAX_TYPE_ID) && (IndexLoc > 0x00U));
421 /* Be sure device has been stopped */
422 if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
423 Status = (LONG)(XST_DEVICE_IS_STARTED);
426 /* Index ranges 1 to 4, for offset calculation is 0 to 3. */
429 /* Set the ID bits in MATCHx register */
430 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
431 ((u32)XEMACPS_MATCH1_OFFSET + ((u32)IndexLoc * (u32)4)), Id_Check);
433 Status = (LONG)(XST_SUCCESS);
438 /*****************************************************************************/
440 * Set options for the driver/device. The driver should be stopped with
441 * XEmacPs_Stop() before changing options.
443 * @param InstancePtr is a pointer to the instance to be worked on.
444 * @param Options are the options to set. Multiple options can be set by OR'ing
445 * XTE_*_OPTIONS constants together. Options not specified are not
449 * - XST_SUCCESS if the options were set successfully
450 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
453 * See xemacps.h for a description of the available options.
455 *****************************************************************************/
456 LONG XEmacPs_SetOptions(XEmacPs *InstancePtr, u32 Options)
458 u32 Reg; /* Generic register contents */
459 u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
460 u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
462 Xil_AssertNonvoid(InstancePtr != NULL);
463 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
465 /* Be sure device has been stopped */
466 if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
467 Status = (LONG)(XST_DEVICE_IS_STARTED);
470 /* Many of these options will change the NET_CONFIG registers.
471 * To reduce the amount of IO to the device, group these options here
472 * and change them all at once.
475 /* Grab current register contents */
476 RegNetCfg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
477 XEMACPS_NWCFG_OFFSET);
478 RegNewNetCfg = RegNetCfg;
481 * It is configured to max 1536.
483 if ((Options & XEMACPS_FRAME1536_OPTION) != 0x00000000U) {
484 RegNewNetCfg |= (XEMACPS_NWCFG_1536RXEN_MASK);
487 /* Turn on VLAN packet only, only VLAN tagged will be accepted */
488 if ((Options & XEMACPS_VLAN_OPTION) != 0x00000000U) {
489 RegNewNetCfg |= XEMACPS_NWCFG_NVLANDISC_MASK;
492 /* Turn on FCS stripping on receive packets */
493 if ((Options & XEMACPS_FCS_STRIP_OPTION) != 0x00000000U) {
494 RegNewNetCfg |= XEMACPS_NWCFG_FCSREM_MASK;
497 /* Turn on length/type field checking on receive packets */
498 if ((Options & XEMACPS_LENTYPE_ERR_OPTION) != 0x00000000U) {
499 RegNewNetCfg |= XEMACPS_NWCFG_LENERRDSCRD_MASK;
502 /* Turn on flow control */
503 if ((Options & XEMACPS_FLOW_CONTROL_OPTION) != 0x00000000U) {
504 RegNewNetCfg |= XEMACPS_NWCFG_PAUSEEN_MASK;
507 /* Turn on promiscuous frame filtering (all frames are received) */
508 if ((Options & XEMACPS_PROMISC_OPTION) != 0x00000000U) {
509 RegNewNetCfg |= XEMACPS_NWCFG_COPYALLEN_MASK;
512 /* Allow broadcast address reception */
513 if ((Options & XEMACPS_BROADCAST_OPTION) != 0x00000000U) {
514 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_BCASTDI_MASK);
517 /* Allow multicast address filtering */
518 if ((Options & XEMACPS_MULTICAST_OPTION) != 0x00000000U) {
519 RegNewNetCfg |= XEMACPS_NWCFG_MCASTHASHEN_MASK;
522 /* enable RX checksum offload */
523 if ((Options & XEMACPS_RX_CHKSUM_ENABLE_OPTION) != 0x00000000U) {
524 RegNewNetCfg |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
527 /* Enable jumbo frames */
528 if (((Options & XEMACPS_JUMBO_ENABLE_OPTION) != 0x00000000U) &&
529 (InstancePtr->Version > 2)) {
530 RegNewNetCfg |= XEMACPS_NWCFG_JUMBO_MASK;
531 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
532 XEMACPS_JUMBOMAXLEN_OFFSET, XEMACPS_RX_BUF_SIZE_JUMBO);
533 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
534 XEMACPS_DMACR_OFFSET);
535 Reg &= ~XEMACPS_DMACR_RXBUF_MASK;
536 Reg |= (((((u32)XEMACPS_RX_BUF_SIZE_JUMBO / (u32)XEMACPS_RX_BUF_UNIT) +
537 (((((u32)XEMACPS_RX_BUF_SIZE_JUMBO %
538 (u32)XEMACPS_RX_BUF_UNIT))!=(u32)0) ? 1U : 0U)) <<
539 (u32)(XEMACPS_DMACR_RXBUF_SHIFT)) &
540 (u32)(XEMACPS_DMACR_RXBUF_MASK));
541 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
542 XEMACPS_DMACR_OFFSET, Reg);
543 InstancePtr->MaxMtuSize = XEMACPS_MTU_JUMBO;
544 InstancePtr->MaxFrameSize = XEMACPS_MTU_JUMBO +
545 XEMACPS_HDR_SIZE + XEMACPS_TRL_SIZE;
546 InstancePtr->MaxVlanFrameSize = InstancePtr->MaxFrameSize +
547 XEMACPS_HDR_VLAN_SIZE;
548 InstancePtr->RxBufMask = XEMACPS_RXBUF_LEN_JUMBO_MASK;
551 if (((Options & XEMACPS_SGMII_ENABLE_OPTION) != 0x00000000U) &&
552 (InstancePtr->Version > 2)) {
553 RegNewNetCfg |= (XEMACPS_NWCFG_SGMIIEN_MASK |
554 XEMACPS_NWCFG_PCSSEL_MASK);
557 /* Officially change the NET_CONFIG registers if it needs to be
560 if (RegNetCfg != RegNewNetCfg) {
561 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
562 XEMACPS_NWCFG_OFFSET, RegNewNetCfg);
565 /* Enable TX checksum offload */
566 if ((Options & XEMACPS_TX_CHKSUM_ENABLE_OPTION) != 0x00000000U) {
567 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
568 XEMACPS_DMACR_OFFSET);
569 Reg |= XEMACPS_DMACR_TCPCKSUM_MASK;
570 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
571 XEMACPS_DMACR_OFFSET, Reg);
574 /* Enable transmitter */
575 if ((Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) != 0x00000000U) {
576 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
577 XEMACPS_NWCTRL_OFFSET);
578 Reg |= XEMACPS_NWCTRL_TXEN_MASK;
579 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
580 XEMACPS_NWCTRL_OFFSET, Reg);
583 /* Enable receiver */
584 if ((Options & XEMACPS_RECEIVER_ENABLE_OPTION) != 0x00000000U) {
585 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
586 XEMACPS_NWCTRL_OFFSET);
587 Reg |= XEMACPS_NWCTRL_RXEN_MASK;
588 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
589 XEMACPS_NWCTRL_OFFSET, Reg);
592 /* The remaining options not handled here are managed elsewhere in the
593 * driver. No register modifications are needed at this time. Reflecting
594 * the option in InstancePtr->Options is good enough for now.
597 /* Set options word to its new value */
598 InstancePtr->Options |= Options;
600 Status = (LONG)(XST_SUCCESS);
606 /*****************************************************************************/
608 * Clear options for the driver/device
610 * @param InstancePtr is a pointer to the instance to be worked on.
611 * @param Options are the options to clear. Multiple options can be cleared by
612 * OR'ing XEMACPS_*_OPTIONS constants together. Options not specified
616 * - XST_SUCCESS if the options were set successfully
617 * - XST_DEVICE_IS_STARTED if the device has not yet been stopped
620 * See xemacps.h for a description of the available options.
622 *****************************************************************************/
623 LONG XEmacPs_ClearOptions(XEmacPs *InstancePtr, u32 Options)
625 u32 Reg; /* Generic */
626 u32 RegNetCfg; /* Reflects original contents of NET_CONFIG */
627 u32 RegNewNetCfg; /* Reflects new contents of NET_CONFIG */
629 Xil_AssertNonvoid(InstancePtr != NULL);
630 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
632 /* Be sure device has been stopped */
633 if (InstancePtr->IsStarted == (u32)XIL_COMPONENT_IS_STARTED) {
634 Status = (LONG)(XST_DEVICE_IS_STARTED);
637 /* Many of these options will change the NET_CONFIG registers.
638 * To reduce the amount of IO to the device, group these options here
639 * and change them all at once.
642 /* Grab current register contents */
643 RegNetCfg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
644 XEMACPS_NWCFG_OFFSET);
645 RegNewNetCfg = RegNetCfg;
647 /* There is only RX configuration!?
648 * It is configured in two different length, upto 1536 and 10240 bytes
650 if ((Options & XEMACPS_FRAME1536_OPTION) != 0x00000000U) {
651 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_1536RXEN_MASK);
654 /* Turn off VLAN packet only */
655 if ((Options & XEMACPS_VLAN_OPTION) != 0x00000000U) {
656 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_NVLANDISC_MASK);
659 /* Turn off FCS stripping on receive packets */
660 if ((Options & XEMACPS_FCS_STRIP_OPTION) != 0x00000000U) {
661 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_FCSREM_MASK);
664 /* Turn off length/type field checking on receive packets */
665 if ((Options & XEMACPS_LENTYPE_ERR_OPTION) != 0x00000000U) {
666 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_LENERRDSCRD_MASK);
669 /* Turn off flow control */
670 if ((Options & XEMACPS_FLOW_CONTROL_OPTION) != 0x00000000U) {
671 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_PAUSEEN_MASK);
674 /* Turn off promiscuous frame filtering (all frames are received) */
675 if ((Options & XEMACPS_PROMISC_OPTION) != 0x00000000U) {
676 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_COPYALLEN_MASK);
679 /* Disallow broadcast address filtering => broadcast reception */
680 if ((Options & XEMACPS_BROADCAST_OPTION) != 0x00000000U) {
681 RegNewNetCfg |= XEMACPS_NWCFG_BCASTDI_MASK;
684 /* Disallow multicast address filtering */
685 if ((Options & XEMACPS_MULTICAST_OPTION) != 0x00000000U) {
686 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_MCASTHASHEN_MASK);
689 /* Disable RX checksum offload */
690 if ((Options & XEMACPS_RX_CHKSUM_ENABLE_OPTION) != 0x00000000U) {
691 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_RXCHKSUMEN_MASK);
694 /* Disable jumbo frames */
695 if (((Options & XEMACPS_JUMBO_ENABLE_OPTION) != 0x00000000U) &&
696 (InstancePtr->Version > 2)) {
697 RegNewNetCfg &= (u32)(~XEMACPS_NWCFG_JUMBO_MASK);
698 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
699 XEMACPS_DMACR_OFFSET);
700 Reg &= ~XEMACPS_DMACR_RXBUF_MASK;
701 Reg |= (((((u32)XEMACPS_RX_BUF_SIZE / (u32)XEMACPS_RX_BUF_UNIT) +
702 (((((u32)XEMACPS_RX_BUF_SIZE %
703 (u32)XEMACPS_RX_BUF_UNIT))!=(u32)0) ? 1U : 0U)) <<
704 (u32)(XEMACPS_DMACR_RXBUF_SHIFT)) &
705 (u32)(XEMACPS_DMACR_RXBUF_MASK));
706 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
707 XEMACPS_DMACR_OFFSET, Reg);
708 InstancePtr->MaxMtuSize = XEMACPS_MTU;
709 InstancePtr->MaxFrameSize = XEMACPS_MTU +
710 XEMACPS_HDR_SIZE + XEMACPS_TRL_SIZE;
711 InstancePtr->MaxVlanFrameSize = InstancePtr->MaxFrameSize +
712 XEMACPS_HDR_VLAN_SIZE;
713 InstancePtr->RxBufMask = XEMACPS_RXBUF_LEN_MASK;
716 if (((Options & XEMACPS_SGMII_ENABLE_OPTION) != 0x00000000U) &&
717 (InstancePtr->Version > 2)) {
718 RegNewNetCfg &= (u32)(~(XEMACPS_NWCFG_SGMIIEN_MASK |
719 XEMACPS_NWCFG_PCSSEL_MASK));
722 /* Officially change the NET_CONFIG registers if it needs to be
725 if (RegNetCfg != RegNewNetCfg) {
726 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
727 XEMACPS_NWCFG_OFFSET, RegNewNetCfg);
730 /* Disable TX checksum offload */
731 if ((Options & XEMACPS_TX_CHKSUM_ENABLE_OPTION) != 0x00000000U) {
732 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
733 XEMACPS_DMACR_OFFSET);
734 Reg &= (u32)(~XEMACPS_DMACR_TCPCKSUM_MASK);
735 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
736 XEMACPS_DMACR_OFFSET, Reg);
739 /* Disable transmitter */
740 if ((Options & XEMACPS_TRANSMITTER_ENABLE_OPTION) != 0x00000000U) {
741 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
742 XEMACPS_NWCTRL_OFFSET);
743 Reg &= (u32)(~XEMACPS_NWCTRL_TXEN_MASK);
744 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
745 XEMACPS_NWCTRL_OFFSET, Reg);
748 /* Disable receiver */
749 if ((Options & XEMACPS_RECEIVER_ENABLE_OPTION) != 0x00000000U) {
750 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
751 XEMACPS_NWCTRL_OFFSET);
752 Reg &= (u32)(~XEMACPS_NWCTRL_RXEN_MASK);
753 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
754 XEMACPS_NWCTRL_OFFSET, Reg);
757 /* The remaining options not handled here are managed elsewhere in the
758 * driver. No register modifications are needed at this time. Reflecting
759 * option in InstancePtr->Options is good enough for now.
762 /* Set options word to its new value */
763 InstancePtr->Options &= ~Options;
765 Status = (LONG)(XST_SUCCESS);
771 /*****************************************************************************/
773 * Get current option settings
775 * @param InstancePtr is a pointer to the instance to be worked on.
778 * A bitmask of XTE_*_OPTION constants. Any bit set to 1 is to be interpreted
782 * See xemacps.h for a description of the available options.
784 *****************************************************************************/
785 u32 XEmacPs_GetOptions(XEmacPs *InstancePtr)
787 Xil_AssertNonvoid(InstancePtr != NULL);
788 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
790 return (InstancePtr->Options);
794 /*****************************************************************************/
796 * Send a pause packet
798 * @param InstancePtr is a pointer to the instance to be worked on.
801 * - XST_SUCCESS if pause frame transmission was initiated
802 * - XST_DEVICE_IS_STOPPED if the device has not been started.
804 *****************************************************************************/
805 LONG XEmacPs_SendPausePacket(XEmacPs *InstancePtr)
810 Xil_AssertNonvoid(InstancePtr != NULL);
811 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
813 /* Make sure device is ready for this operation */
814 if (InstancePtr->IsStarted != (u32)XIL_COMPONENT_IS_STARTED) {
815 Status = (LONG)(XST_DEVICE_IS_STOPPED);
817 /* Send flow control frame */
818 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
819 XEMACPS_NWCTRL_OFFSET);
820 Reg |= XEMACPS_NWCTRL_PAUSETX_MASK;
821 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
822 XEMACPS_NWCTRL_OFFSET, Reg);
823 Status = (LONG)(XST_SUCCESS);
828 /*****************************************************************************/
830 * XEmacPs_GetOperatingSpeed gets the current operating link speed. This may
831 * be the value set by XEmacPs_SetOperatingSpeed() or a hardware default.
833 * @param InstancePtr references the TEMAC channel on which to operate.
835 * @return XEmacPs_GetOperatingSpeed returns the link speed in units of
836 * megabits per second.
840 *****************************************************************************/
841 u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr)
846 Xil_AssertNonvoid(InstancePtr != NULL);
847 Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
849 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
850 XEMACPS_NWCFG_OFFSET);
852 if ((Reg & XEMACPS_NWCFG_1000_MASK) != 0x00000000U) {
853 Status = (u16)(1000);
855 if ((Reg & XEMACPS_NWCFG_100_MASK) != 0x00000000U) {
865 /*****************************************************************************/
867 * XEmacPs_SetOperatingSpeed sets the current operating link speed. For any
868 * traffic to be passed, this speed must match the current MII/GMII/SGMII/RGMII
871 * @param InstancePtr references the TEMAC channel on which to operate.
872 * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100,
873 * or 1000. XEmacPs_SetOperatingSpeed ignores invalid values.
877 *****************************************************************************/
878 void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed)
882 Xil_AssertVoid(InstancePtr != NULL);
883 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
884 Xil_AssertVoid((Speed == (u16)10) || (Speed == (u16)100) || (Speed == (u16)1000));
886 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
887 XEMACPS_NWCFG_OFFSET);
888 Reg &= (u32)(~(XEMACPS_NWCFG_1000_MASK | XEMACPS_NWCFG_100_MASK));
897 Reg |= XEMACPS_NWCFG_100_MASK;
902 Reg |= XEMACPS_NWCFG_1000_MASK;
909 if(Status == (u16)1){
913 /* Set register and return */
914 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
915 XEMACPS_NWCFG_OFFSET, Reg);
919 /*****************************************************************************/
921 * Set the MDIO clock divisor.
923 * Calculating the divisor:
927 * f[MDC] = -----------------
931 * where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the
932 * MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not
933 * exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster
934 * access. Here is the table to show values to generate MDC,
937 * 000 : divide pclk by 8 (pclk up to 20 MHz)
938 * 001 : divide pclk by 16 (pclk up to 40 MHz)
939 * 010 : divide pclk by 32 (pclk up to 80 MHz)
940 * 011 : divide pclk by 48 (pclk up to 120 MHz)
941 * 100 : divide pclk by 64 (pclk up to 160 MHz)
942 * 101 : divide pclk by 96 (pclk up to 240 MHz)
943 * 110 : divide pclk by 128 (pclk up to 320 MHz)
944 * 111 : divide pclk by 224 (pclk up to 540 MHz)
947 * @param InstancePtr is a pointer to the instance to be worked on.
948 * @param Divisor is the divisor to set. Range is 0b000 to 0b111.
950 *****************************************************************************/
951 void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr, XEmacPs_MdcDiv Divisor)
954 Xil_AssertVoid(InstancePtr != NULL);
955 Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY);
956 Xil_AssertVoid(Divisor <= (XEmacPs_MdcDiv)0x7); /* only last three bits are valid */
958 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
959 XEMACPS_NWCFG_OFFSET);
960 /* clear these three bits, could be done with mask */
961 Reg &= (u32)(~XEMACPS_NWCFG_MDCCLKDIV_MASK);
963 Reg |= ((u32)Divisor << XEMACPS_NWCFG_MDC_SHIFT_MASK);
965 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
966 XEMACPS_NWCFG_OFFSET, Reg);
970 /*****************************************************************************/
972 * Read the current value of the PHY register indicated by the PhyAddress and
973 * the RegisterNum parameters. The MAC provides the driver with the ability to
974 * talk to a PHY that adheres to the Media Independent Interface (MII) as
975 * defined in the IEEE 802.3 standard.
977 * Prior to PHY access with this function, the user should have setup the MDIO
978 * clock with XEmacPs_SetMdioDivisor().
980 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
981 * @param PhyAddress is the address of the PHY to be read (supports multiple
983 * @param RegisterNum is the register number, 0-31, of the specific PHY register
985 * @param PhyDataPtr is an output parameter, and points to a 16-bit buffer into
986 * which the current value of the register will be copied.
990 * - XST_SUCCESS if the PHY was read from successfully
991 * - XST_EMAC_MII_BUSY if there is another PHY operation in progress
995 * This function is not thread-safe. The user must provide mutually exclusive
996 * access to this function if there are to be multiple threads that can call it.
998 * There is the possibility that this function will not return if the hardware
999 * is broken (i.e., it never sets the status bit indicating that the read is
1000 * done). If this is of concern to the user, the user should provide a mechanism
1001 * suitable to their needs for recovery.
1003 * For the duration of this function, all host interface reads and writes are
1004 * blocked to the current XEmacPs instance.
1006 ******************************************************************************/
1007 LONG XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress,
1008 u32 RegisterNum, u16 *PhyDataPtr)
1015 Xil_AssertNonvoid(InstancePtr != NULL);
1017 /* Make sure no other PHY operation is currently in progress */
1018 if ((!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1019 XEMACPS_NWSR_OFFSET) &
1020 XEMACPS_NWSR_MDIOIDLE_MASK))==TRUE) {
1021 Status = (LONG)(XST_EMAC_MII_BUSY);
1024 /* Construct Mgtcr mask for the operation */
1025 Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_R_MASK |
1026 (PhyAddress << XEMACPS_PHYMNTNC_PHAD_SHFT_MSK) |
1027 (RegisterNum << XEMACPS_PHYMNTNC_PREG_SHFT_MSK);
1029 /* Write Mgtcr and wait for completion */
1030 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
1031 XEMACPS_PHYMNTNC_OFFSET, Mgtcr);
1034 Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1035 XEMACPS_NWSR_OFFSET);
1037 } while ((IpReadTemp & XEMACPS_NWSR_MDIOIDLE_MASK) == 0x00000000U);
1040 *PhyDataPtr = (u16)XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1041 XEMACPS_PHYMNTNC_OFFSET);
1042 Status = (LONG)(XST_SUCCESS);
1048 /*****************************************************************************/
1050 * Write data to the specified PHY register. The Ethernet driver does not
1051 * require the device to be stopped before writing to the PHY. Although it is
1052 * probably a good idea to stop the device, it is the responsibility of the
1053 * application to deem this necessary. The MAC provides the driver with the
1054 * ability to talk to a PHY that adheres to the Media Independent Interface
1055 * (MII) as defined in the IEEE 802.3 standard.
1057 * Prior to PHY access with this function, the user should have setup the MDIO
1058 * clock with XEmacPs_SetMdioDivisor().
1060 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
1061 * @param PhyAddress is the address of the PHY to be written (supports multiple
1063 * @param RegisterNum is the register number, 0-31, of the specific PHY register
1065 * @param PhyData is the 16-bit value that will be written to the register
1069 * - XST_SUCCESS if the PHY was written to successfully. Since there is no error
1070 * status from the MAC on a write, the user should read the PHY to verify the
1071 * write was successful.
1072 * - XST_EMAC_MII_BUSY if there is another PHY operation in progress
1076 * This function is not thread-safe. The user must provide mutually exclusive
1077 * access to this function if there are to be multiple threads that can call it.
1079 * There is the possibility that this function will not return if the hardware
1080 * is broken (i.e., it never sets the status bit indicating that the write is
1081 * done). If this is of concern to the user, the user should provide a mechanism
1082 * suitable to their needs for recovery.
1084 * For the duration of this function, all host interface reads and writes are
1085 * blocked to the current XEmacPs instance.
1087 ******************************************************************************/
1088 LONG XEmacPs_PhyWrite(XEmacPs *InstancePtr, u32 PhyAddress,
1089 u32 RegisterNum, u16 PhyData)
1096 Xil_AssertNonvoid(InstancePtr != NULL);
1098 /* Make sure no other PHY operation is currently in progress */
1099 if ((!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1100 XEMACPS_NWSR_OFFSET) &
1101 XEMACPS_NWSR_MDIOIDLE_MASK))==TRUE) {
1102 Status = (LONG)(XST_EMAC_MII_BUSY);
1104 /* Construct Mgtcr mask for the operation */
1105 Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_W_MASK |
1106 (PhyAddress << XEMACPS_PHYMNTNC_PHAD_SHFT_MSK) |
1107 (RegisterNum << XEMACPS_PHYMNTNC_PREG_SHFT_MSK) | (u32)PhyData;
1109 /* Write Mgtcr and wait for completion */
1110 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress,
1111 XEMACPS_PHYMNTNC_OFFSET, Mgtcr);
1114 Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1115 XEMACPS_NWSR_OFFSET);
1116 IpWriteTemp = Ipisr;
1117 } while ((IpWriteTemp & XEMACPS_NWSR_MDIOIDLE_MASK) == 0x00000000U);
1119 Status = (LONG)(XST_SUCCESS);
1124 /*****************************************************************************/
1126 * API to update the Burst length in the DMACR register.
1128 * @param InstancePtr is a pointer to the XEmacPs instance to be worked on.
1129 * @param BLength is the length in bytes for the dma burst.
1133 ******************************************************************************/
1134 void XEmacPs_DMABLengthUpdate(XEmacPs *InstancePtr, s32 BLength)
1139 Xil_AssertVoid(InstancePtr != NULL);
1140 Xil_AssertVoid((BLength == XEMACPS_SINGLE_BURST) ||
1141 (BLength == XEMACPS_4BYTE_BURST) ||
1142 (BLength == XEMACPS_8BYTE_BURST) ||
1143 (BLength == XEMACPS_16BYTE_BURST));
1146 case XEMACPS_SINGLE_BURST:
1147 RegUpdateVal = XEMACPS_DMACR_SINGLE_AHB_BURST;
1150 case XEMACPS_4BYTE_BURST:
1151 RegUpdateVal = XEMACPS_DMACR_INCR4_AHB_BURST;
1154 case XEMACPS_8BYTE_BURST:
1155 RegUpdateVal = XEMACPS_DMACR_INCR8_AHB_BURST;
1158 case XEMACPS_16BYTE_BURST:
1159 RegUpdateVal = XEMACPS_DMACR_INCR16_AHB_BURST;
1163 RegUpdateVal = 0x00000000U;
1166 Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress,
1167 XEMACPS_DMACR_OFFSET);
1169 Reg &= (u32)(~XEMACPS_DMACR_BLENGTH_MASK);
1170 Reg |= RegUpdateVal;
1171 XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_DMACR_OFFSET,