1 /******************************************************************************
3 * Copyright (C) 2004 - 2014 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 /*****************************************************************************/
37 * Functions in this file are the minimum required functions for the EmacLite
38 * driver. See xemaclite.h for a detailed description of the driver.
41 * MODIFICATION HISTORY:
43 * Ver Who Date Changes
44 * ----- ---- -------- --------------------------------------------------------
45 * 1.01a ecm 01/31/04 First release
46 * 1.11a mta 03/21/07 Updated to new coding style
47 * 1.11a ecm 05/18/07 Updated the TxBufferAvailable routine to look at both
48 * the active and busy bits
49 * 1.13a sv 02/1/08 Updated the TxBufferAvailable routine to return
50 * busy status properly
51 * 2.00a ktn 02/16/09 Added support for MDIO
52 * 2.01a ktn 07/20/09 Modified XEmacLite_Send function to use Ping buffers
53 * Interrupt enable bit since this alone is used to enable
54 * the interrupts for both Ping and Pong Buffers.
55 * 3.00a ktn 10/22/09 Updated driver to use the HAL APIs/macros.
56 * The macros have been renamed to remove _m from the name.
57 * 3.01a ktn 07/08/10 The macro XEmacLite_GetReceiveDataLength is changed to
59 * Updated the XEmacLite_GetReceiveDataLength and
60 * XEmacLite_Recv functions to support little endian
62 * 3.02a sdm 07/22/11 Removed redundant code in XEmacLite_Recv functions for
64 * 3.04a srt 04/13/13 Removed warnings (CR 705000).
67 ******************************************************************************/
69 /***************************** Include Files *********************************/
73 #include "xemaclite.h"
74 #include "xemaclite_i.h"
76 /************************** Constant Definitions *****************************/
78 /**************************** Type Definitions *******************************/
80 /***************** Macros (Inline Functions) Definitions *********************/
83 /************************** Function Prototypes ******************************/
85 static u16 XEmacLite_GetReceiveDataLength(u32 BaseAddress);
87 /************************** Variable Definitions *****************************/
89 /*****************************************************************************/
92 * Initialize a specific XEmacLite instance/driver. The initialization entails:
93 * - Initialize fields of the XEmacLite instance structure.
95 * The driver defaults to polled mode operation.
97 * @param InstancePtr is a pointer to the XEmacLite instance.
98 * @param EmacLiteConfigPtr points to the XEmacLite device configuration
100 * @param EffectiveAddr is the device base address in the virtual memory
101 * address space. If the address translation is not used then the
102 * physical address is passed.
103 * Unexpected errors may occur if the address mapping is changed
104 * after this function is invoked.
107 * - XST_SUCCESS if initialization was successful.
109 * @note The initialization of the PHY device is not done in this
110 * function. The user needs to use XEmacLite_PhyRead and
111 * XEmacLite_PhyWrite functions to access the PHY device.
113 ******************************************************************************/
114 int XEmacLite_CfgInitialize(XEmacLite *InstancePtr,
115 XEmacLite_Config *EmacLiteConfigPtr,
120 * Verify that each of the inputs are valid.
122 Xil_AssertNonvoid(InstancePtr != NULL);
123 Xil_AssertNonvoid(EmacLiteConfigPtr != NULL);
126 * Zero the provided instance memory.
128 memset(InstancePtr, 0, sizeof(XEmacLite));
131 * Set some default values for instance data, don't indicate the device
132 * is ready to use until everything has been initialized successfully.
134 InstancePtr->EmacLiteConfig.BaseAddress = EffectiveAddr;
135 InstancePtr->EmacLiteConfig.DeviceId = EmacLiteConfigPtr->DeviceId;
136 InstancePtr->EmacLiteConfig.TxPingPong = EmacLiteConfigPtr->TxPingPong;
137 InstancePtr->EmacLiteConfig.RxPingPong = EmacLiteConfigPtr->RxPingPong;
138 InstancePtr->EmacLiteConfig.MdioInclude = EmacLiteConfigPtr->MdioInclude;
139 InstancePtr->EmacLiteConfig.Loopback = EmacLiteConfigPtr->Loopback;
141 InstancePtr->NextTxBufferToUse = 0x0;
142 InstancePtr->NextRxBufferToUse = 0x0;
143 InstancePtr->RecvHandler = (XEmacLite_Handler) StubHandler;
144 InstancePtr->SendHandler = (XEmacLite_Handler) StubHandler;
147 * Clear the TX CSR's in case this is a restart.
149 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
151 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
152 XEL_BUFFER_OFFSET + XEL_TSR_OFFSET, 0);
155 * Since there were no failures, indicate the device is ready to use.
157 InstancePtr->IsReady = XIL_COMPONENT_IS_READY;
162 /*****************************************************************************/
165 * Send an Ethernet frame. The ByteCount is the total frame size, including
168 * @param InstancePtr is a pointer to the XEmacLite instance.
169 * @param FramePtr is a pointer to frame. For optimal performance, a
170 * 32-bit aligned buffer should be used but it is not required, the
171 * function will align the data if necessary.
172 * @param ByteCount is the size, in bytes, of the frame
175 * - XST_SUCCESS if data was transmitted.
176 * - XST_FAILURE if buffer(s) was (were) full and no valid data was
181 * This function call is not blocking in nature, i.e. it will not wait until the
182 * frame is transmitted.
184 ******************************************************************************/
185 int XEmacLite_Send(XEmacLite *InstancePtr, u8 *FramePtr, unsigned ByteCount)
190 u32 IntrEnableStatus;
193 * Verify that each of the inputs are valid.
195 Xil_AssertNonvoid(InstancePtr != NULL);
198 * Determine the expected TX buffer address.
200 BaseAddress = XEmacLite_NextTransmitAddr(InstancePtr);
201 EmacBaseAddress = InstancePtr->EmacLiteConfig.BaseAddress;
204 * Check the Length if it is too large, truncate it.
205 * The maximum Tx packet size is
206 * Ethernet header (14 Bytes) + Maximum MTU (1500 bytes).
208 if (ByteCount > XEL_MAX_TX_FRAME_SIZE) {
210 ByteCount = XEL_MAX_TX_FRAME_SIZE;
214 * Determine if the expected buffer address is empty.
216 Register = XEmacLite_GetTxStatus(BaseAddress);
219 * If the expected buffer is available, fill it with the provided data
220 * Align if necessary.
222 if ((Register & (XEL_TSR_XMIT_BUSY_MASK |
223 XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
226 * Switch to next buffer if configured.
228 if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
229 InstancePtr->NextTxBufferToUse ^= XEL_BUFFER_OFFSET;
233 * Write the frame to the buffer.
235 XEmacLite_AlignedWrite(FramePtr, (u32 *) BaseAddress,
240 * The frame is in the buffer, now send it.
242 XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
243 (ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
244 XEL_TPLR_LENGTH_MASK_LO)));
247 * Update the Tx Status Register to indicate that there is a
249 * If the interrupt enable bit of Ping buffer(since this
250 * controls both the buffers) is enabled then set the
251 * XEL_TSR_XMIT_ACTIVE_MASK flag which is used by the interrupt
252 * handler to call the callback function provided by the user
253 * to indicate that the frame has been transmitted.
255 Register = XEmacLite_GetTxStatus(BaseAddress);
256 Register |= XEL_TSR_XMIT_BUSY_MASK;
257 IntrEnableStatus = XEmacLite_GetTxStatus(EmacBaseAddress);
258 if ((IntrEnableStatus & XEL_TSR_XMIT_IE_MASK) != 0) {
259 Register |= XEL_TSR_XMIT_ACTIVE_MASK;
261 XEmacLite_SetTxStatus(BaseAddress, Register);
267 * If the expected buffer was full, try the other buffer if configured.
269 if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
271 BaseAddress ^= XEL_BUFFER_OFFSET;
274 * Determine if the expected buffer address is empty.
276 Register = XEmacLite_GetTxStatus(BaseAddress);
279 * If the next buffer is available, fill it with the provided
282 if ((Register & (XEL_TSR_XMIT_BUSY_MASK |
283 XEL_TSR_XMIT_ACTIVE_MASK)) == 0) {
286 * Write the frame to the buffer.
288 XEmacLite_AlignedWrite(FramePtr, (u32 *) BaseAddress,
292 * The frame is in the buffer, now send it.
294 XEmacLite_WriteReg(BaseAddress, XEL_TPLR_OFFSET,
295 (ByteCount & (XEL_TPLR_LENGTH_MASK_HI |
296 XEL_TPLR_LENGTH_MASK_LO)));
299 * Update the Tx Status Register to indicate that there
300 * is a frame to send.
301 * If the interrupt enable bit of Ping buffer(since this
302 * controls both the buffers) is enabled then set the
303 * XEL_TSR_XMIT_ACTIVE_MASK flag which is used by the
304 * interrupt handler to call the callback function
305 * provided by the user to indicate that the frame has
308 Register = XEmacLite_GetTxStatus(BaseAddress);
309 Register |= XEL_TSR_XMIT_BUSY_MASK;
311 XEmacLite_GetTxStatus(EmacBaseAddress);
312 if ((IntrEnableStatus & XEL_TSR_XMIT_IE_MASK) != 0) {
313 Register |= XEL_TSR_XMIT_ACTIVE_MASK;
315 XEmacLite_SetTxStatus(BaseAddress, Register);
318 * Do not switch to next buffer, there is a sync problem
319 * and the expected buffer should not change.
327 * Buffer(s) was(were) full, return failure to allow for polling usage.
332 /*****************************************************************************/
335 * Receive a frame. Intended to be called from the interrupt context or
336 * with a wrapper which waits for the receive frame to be available.
338 * @param InstancePtr is a pointer to the XEmacLite instance.
339 * @param FramePtr is a pointer to a buffer where the frame will
340 * be stored. The buffer must be at least XEL_MAX_FRAME_SIZE bytes.
341 * For optimal performance, a 32-bit aligned buffer should be used
342 * but it is not required, the function will align the data if
347 * The type/length field of the frame received. When the type/length field
348 * contains the type, XEL_MAX_FRAME_SIZE bytes will be copied out of the
349 * buffer and it is up to the higher layers to sort out the frame.
350 * Function returns 0 if there is no data waiting in the receive buffer or
351 * the pong buffer if configured.
355 * This function call is not blocking in nature, i.e. it will not wait until
358 ******************************************************************************/
359 u16 XEmacLite_Recv(XEmacLite *InstancePtr, u8 *FramePtr)
367 * Verify that each of the inputs are valid.
370 Xil_AssertNonvoid(InstancePtr != NULL);
373 * Determine the expected buffer address.
375 BaseAddress = XEmacLite_NextReceiveAddr(InstancePtr);
378 * Verify which buffer has valid data.
380 Register = XEmacLite_GetRxStatus(BaseAddress);
382 if ((Register & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
385 * The driver is in sync, update the next expected buffer if
389 if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
390 InstancePtr->NextRxBufferToUse ^= XEL_BUFFER_OFFSET;
395 * The instance is out of sync, try other buffer if other
396 * buffer is configured, return 0 otherwise. If the instance is
397 * out of sync, do not update the 'NextRxBufferToUse' since it
398 * will correct on subsequent calls.
400 if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
401 BaseAddress ^= XEL_BUFFER_OFFSET;
404 return 0; /* No data was available */
408 * Verify that buffer has valid data.
410 Register = XEmacLite_GetRxStatus(BaseAddress);
411 if ((Register & XEL_RSR_RECV_DONE_MASK) !=
412 XEL_RSR_RECV_DONE_MASK) {
413 return 0; /* No data was available */
418 * Get the length of the frame that arrived.
420 LengthType = XEmacLite_GetReceiveDataLength(BaseAddress);
423 * Check if length is valid.
425 if (LengthType > XEL_MAX_FRAME_SIZE) {
428 if (LengthType == XEL_ETHER_PROTO_TYPE_IP) {
431 * The packet is a an IP Packet.
433 #ifdef __LITTLE_ENDIAN__
434 Length = (XEmacLite_ReadReg((BaseAddress),
435 XEL_HEADER_IP_LENGTH_OFFSET +
437 (XEL_RPLR_LENGTH_MASK_HI |
438 XEL_RPLR_LENGTH_MASK_LO));
439 Length = (u16) (((Length & 0xFF00) >> 8) | ((Length & 0x00FF) << 8));
441 Length = ((XEmacLite_ReadReg((BaseAddress),
442 XEL_HEADER_IP_LENGTH_OFFSET +
443 XEL_RXBUFF_OFFSET) >>
445 (XEL_RPLR_LENGTH_MASK_HI |
446 XEL_RPLR_LENGTH_MASK_LO));
449 Length += XEL_HEADER_SIZE + XEL_FCS_SIZE;
451 } else if (LengthType == XEL_ETHER_PROTO_TYPE_ARP) {
454 * The packet is an ARP Packet.
456 Length = XEL_ARP_PACKET_SIZE + XEL_HEADER_SIZE +
461 * Field contains type other than IP or ARP, use max
462 * frame size and let user parse it.
464 Length = XEL_MAX_FRAME_SIZE;
470 * Use the length in the frame, plus the header and trailer.
472 Length = LengthType + XEL_HEADER_SIZE + XEL_FCS_SIZE;
476 * Read from the EmacLite.
478 XEmacLite_AlignedRead(((u32 *) (BaseAddress + XEL_RXBUFF_OFFSET)),
482 * Acknowledge the frame.
484 Register = XEmacLite_GetRxStatus(BaseAddress);
485 Register &= ~XEL_RSR_RECV_DONE_MASK;
486 XEmacLite_SetRxStatus(BaseAddress, Register);
491 /*****************************************************************************/
494 * Set the MAC address for this device. The address is a 48-bit value.
496 * @param InstancePtr is a pointer to the XEmacLite instance.
497 * @param AddressPtr is a pointer to a 6-byte MAC address.
498 * the format of the MAC address is major octet to minor octet
504 * - TX must be idle and RX should be idle for deterministic results.
505 * It is recommended that this function should be called after the
506 * initialization and before transmission of any packets from the device.
507 * - Function will not return if hardware is absent or not functioning
509 * - The MAC address can be programmed using any of the two transmit
510 * buffers (if configured).
512 ******************************************************************************/
513 void XEmacLite_SetMacAddress(XEmacLite *InstancePtr, u8 *AddressPtr)
518 * Verify that each of the inputs are valid.
520 Xil_AssertVoid(InstancePtr != NULL);
523 * Determine the expected TX buffer address.
525 BaseAddress = XEmacLite_NextTransmitAddr(InstancePtr);
528 * Copy the MAC address to the Transmit buffer.
530 XEmacLite_AlignedWrite(AddressPtr,
537 XEmacLite_WriteReg(BaseAddress,
542 * Update the MAC address in the EmacLite.
544 XEmacLite_SetTxStatus(BaseAddress, XEL_TSR_PROG_MAC_ADDR);
548 * Wait for EmacLite to finish with the MAC address update.
550 while ((XEmacLite_GetTxStatus(BaseAddress) &
551 XEL_TSR_PROG_MAC_ADDR) != 0);
555 /******************************************************************************/
558 * This is a stub for the send and receive callbacks. The stub
559 * is here in case the upper layers forget to set the handlers.
561 * @param CallBackRef is a pointer to the upper layer callback reference.
567 ******************************************************************************/
568 void StubHandler(void *CallBackRef)
571 Xil_AssertVoidAlways();
575 /****************************************************************************/
578 * Determine if there is a transmit buffer available.
580 * @param InstancePtr is the pointer to the instance of the driver to
584 * - TRUE if there is a TX buffer available for data to be written
585 * - FALSE if Tx Buffer is not available.
589 *****************************************************************************/
590 int XEmacLite_TxBufferAvailable(XEmacLite *InstancePtr)
598 * Verify that each of the inputs are valid.
600 Xil_AssertNonvoid(InstancePtr != NULL);
603 * Read the Tx Status and determine if the buffer is available.
605 Register = XEmacLite_GetTxStatus(InstancePtr->EmacLiteConfig.
608 TxPingBusy = (Register & (XEL_TSR_XMIT_BUSY_MASK |
609 XEL_TSR_XMIT_ACTIVE_MASK));
613 * Read the Tx Status of the second buffer register and determine if the
614 * buffer is available.
616 if (InstancePtr->EmacLiteConfig.TxPingPong != 0) {
617 Register = XEmacLite_GetTxStatus(InstancePtr->EmacLiteConfig.
621 TxPongBusy = (Register & (XEL_TSR_XMIT_BUSY_MASK |
622 XEL_TSR_XMIT_ACTIVE_MASK));
624 return (!(TxPingBusy && TxPongBusy));
627 return (!TxPingBusy);
632 /****************************************************************************/
635 * Flush the Receive buffers. All data will be lost.
637 * @param InstancePtr is the pointer to the instance of the driver to
644 *****************************************************************************/
645 void XEmacLite_FlushReceive(XEmacLite *InstancePtr)
651 * Verify that each of the inputs are valid.
653 Xil_AssertVoid(InstancePtr != NULL);
656 * Read the current buffer register and determine if the buffer is
659 Register = XEmacLite_GetRxStatus(InstancePtr->EmacLiteConfig.
663 * Preserve the IE bit.
665 Register &= XEL_RSR_RECV_IE_MASK;
668 * Write out the value to flush the RX buffer.
670 XEmacLite_SetRxStatus(InstancePtr->EmacLiteConfig.BaseAddress,
674 * If the pong buffer is available, flush it also.
676 if (InstancePtr->EmacLiteConfig.RxPingPong != 0) {
678 * Read the current buffer register and determine if the buffer
681 Register = XEmacLite_GetRxStatus(InstancePtr->EmacLiteConfig.
686 * Preserve the IE bit.
688 Register &= XEL_RSR_RECV_IE_MASK;
691 * Write out the value to flush the RX buffer.
693 XEmacLite_SetRxStatus(InstancePtr->EmacLiteConfig.BaseAddress +
694 XEL_BUFFER_OFFSET, Register);
700 /******************************************************************************/
703 * Read the specified PHY register.
705 * @param InstancePtr is the pointer to the instance of the driver.
706 * @param PhyAddress is the address of the PHY device. The valid range is
708 * @param RegNum is the register number in the PHY device which
709 * is to be read. The valid range is is from 0 to 31.
710 * @param PhyDataPtr is a pointer to the data in which the data read
711 * from the PHY device is returned.
714 * - XST_SUCCESS if the data is read from the PHY.
715 * - XST_DEVICE_BUSY if MDIO is busy.
717 * @note This function waits for the completion of MDIO data transfer.
719 *****************************************************************************/
720 int XEmacLite_PhyRead(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
727 * Verify that each of the inputs are valid.
729 Xil_AssertNonvoid(InstancePtr != NULL);
730 Xil_AssertNonvoid(InstancePtr->EmacLiteConfig.MdioInclude == TRUE);
731 Xil_AssertNonvoid(PhyAddress <= 31);
732 Xil_AssertNonvoid(RegNum <= 31);
733 Xil_AssertNonvoid(PhyDataPtr != NULL);
736 * Verify MDIO master status.
738 if (XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
739 XEL_MDIOCNTR_OFFSET) &
740 XEL_MDIOCNTR_STATUS_MASK) {
741 return XST_DEVICE_BUSY;
744 PhyAddrReg = ((((PhyAddress << XEL_MDIO_ADDRESS_SHIFT) &
745 XEL_MDIO_ADDRESS_MASK) | RegNum) | XEL_MDIO_OP_MASK);
746 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
747 XEL_MDIOADDR_OFFSET, PhyAddrReg);
750 * Enable MDIO and start the transfer.
753 XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
754 XEL_MDIOCNTR_OFFSET);
755 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
758 XEL_MDIOCNTR_STATUS_MASK |
759 XEL_MDIOCNTR_ENABLE_MASK);
762 * Wait till the completion of transfer.
764 while ((XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
765 XEL_MDIOCNTR_OFFSET) &
766 XEL_MDIOCNTR_STATUS_MASK));
769 * Read data from MDIO read data register.
771 *PhyDataPtr = (u16)XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
778 XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
779 XEL_MDIOCNTR_OFFSET);
781 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
783 MdioCtrlReg & ~XEL_MDIOCNTR_ENABLE_MASK);
789 /******************************************************************************/
792 * Write the given data to the specified register in the PHY device.
794 * @param InstancePtr is the pointer to the instance of the driver.
795 * @param PhyAddress is the address of the PHY device. The valid range is
797 * @param RegNum is the register number in the PHY device which
798 * is to be written. The valid range is is from 0 to 31.
799 * @param PhyData is the data to be written to the specified register in
803 * - XST_SUCCESS if the data is written to the PHY.
804 * - XST_DEVICE_BUSY if MDIO is busy.
806 * @note This function waits for the completion of MDIO data transfer.
808 *******************************************************************************/
809 int XEmacLite_PhyWrite(XEmacLite *InstancePtr, u32 PhyAddress, u32 RegNum,
816 * Verify that each of the inputs are valid.
818 Xil_AssertNonvoid(InstancePtr != NULL);
819 Xil_AssertNonvoid(InstancePtr->EmacLiteConfig.MdioInclude == TRUE);
820 Xil_AssertNonvoid(PhyAddress <= 31);
821 Xil_AssertNonvoid(RegNum <= 31);
824 * Verify MDIO master status.
826 if (XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
827 XEL_MDIOCNTR_OFFSET) &
828 XEL_MDIOCNTR_STATUS_MASK) {
829 return XST_DEVICE_BUSY;
834 PhyAddrReg = ((((PhyAddress << XEL_MDIO_ADDRESS_SHIFT) &
835 XEL_MDIO_ADDRESS_MASK) | RegNum) & ~XEL_MDIO_OP_MASK);
836 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
837 XEL_MDIOADDR_OFFSET, PhyAddrReg);
840 * Write data to MDIO write data register.
842 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
843 XEL_MDIOWR_OFFSET, (u32)PhyData);
846 * Enable MDIO and start the transfer.
849 XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
850 XEL_MDIOCNTR_OFFSET);
851 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
853 MdioCtrlReg | XEL_MDIOCNTR_STATUS_MASK |
854 XEL_MDIOCNTR_ENABLE_MASK);
857 * Wait till the completion of transfer.
859 while ((XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
860 XEL_MDIOCNTR_OFFSET) & XEL_MDIOCNTR_STATUS_MASK));
867 XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
868 XEL_MDIOCNTR_OFFSET);
869 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
871 MdioCtrlReg & ~XEL_MDIOCNTR_ENABLE_MASK);
880 /****************************************************************************/
883 * Enable Internal loop back functionality.
885 * @param InstancePtr is the pointer to the instance of the driver.
891 *****************************************************************************/
892 void XEmacLite_EnableLoopBack(XEmacLite *InstancePtr)
897 * Verify that each of the inputs are valid.
899 Xil_AssertVoid(InstancePtr != NULL);
900 Xil_AssertVoid(InstancePtr->EmacLiteConfig.Loopback == TRUE);
902 TsrReg = XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
904 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
905 XEL_TSR_OFFSET, TsrReg | XEL_TSR_LOOPBACK_MASK);
908 /****************************************************************************/
911 * Disable Internal loop back functionality.
913 * @param InstancePtr is the pointer to the instance of the driver.
919 *****************************************************************************/
920 void XEmacLite_DisableLoopBack(XEmacLite *InstancePtr)
925 * Verify that each of the inputs are valid.
927 Xil_AssertVoid(InstancePtr != NULL);
928 Xil_AssertVoid(InstancePtr->EmacLiteConfig.Loopback == TRUE);
930 TsrReg = XEmacLite_ReadReg(InstancePtr->EmacLiteConfig.BaseAddress,
932 XEmacLite_WriteReg(InstancePtr->EmacLiteConfig.BaseAddress,
933 XEL_TSR_OFFSET, TsrReg & (~XEL_TSR_LOOPBACK_MASK));
937 /*****************************************************************************/
940 * Return the length of the data in the Receive Buffer.
942 * @param BaseAddress contains the base address of the device.
944 * @return The type/length field of the frame received.
948 ******************************************************************************/
949 static u16 XEmacLite_GetReceiveDataLength(u32 BaseAddress)
953 #ifdef __LITTLE_ENDIAN__
954 Length = (XEmacLite_ReadReg((BaseAddress),
955 XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET) &
956 (XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO));
957 Length = (u16) (((Length & 0xFF00) >> 8) | ((Length & 0x00FF) << 8));
959 Length = ((XEmacLite_ReadReg((BaseAddress),
960 XEL_HEADER_OFFSET + XEL_RXBUFF_OFFSET) >>
962 (XEL_RPLR_LENGTH_MASK_HI | XEL_RPLR_LENGTH_MASK_LO));