📄 xemac.c
字号:
XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress); return Result; } XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress); } return XST_SUCCESS;}/*****************************************************************************//**** Stop the Ethernet MAC as follows:* - If the device is configured with scatter-gather DMA, stop the DMA* channels (wait for acknowledgment of stop)* - Disable the transmitter and receiver* - Disable interrupts if not in polled mode (the higher layer software is* responsible for disabling interrupts at the interrupt controller)** The PHY is left enabled after a Stop is called.** If the device is configured for scatter-gather DMA, the DMA engine stops at* the next buffer descriptor in its list. The remaining descriptors in the list* are not removed, so anything in the list will be transmitted or received when* the device is restarted. The side effect of doing this is that the last* buffer descriptor processed by the DMA engine before stopping may not be the* last descriptor in the Ethernet frame. So when the device is restarted, a* partial frame (i.e., a bad frame) may be transmitted/received. This is only a* concern if a frame can span multiple buffer descriptors, which is dependent* on the size of the network buffers.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** - XST_SUCCESS if the device was stopped successfully* - XST_DEVICE_IS_STOPPED if the device is already stopped** @note** This function makes use of internal resources that are shared between the* Start, Stop, and SetOptions functions. So if one task might be setting device* options while another is trying to start the device, the user is required to* provide protection of this shared data (typically using a semaphore).*******************************************************************************/XStatus XEmac_Stop(XEmac *InstancePtr){ Xuint32 ControlReg; XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * If the device is already stopped, do nothing but return a status * indicating so */ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) { return XST_DEVICE_IS_STOPPED; } /* * If configured for scatter-gather DMA, stop the DMA channels. Ignore * the XST_DMA_SG_IS_STOPPED return code. There is a critical section * here between SgStart and SgStop, and SgStart can be called in interrupt * context, so disable interrupts while calling SgStop. */ if (XEmac_mIsSgDma(InstancePtr)) { XBufDescriptor *BdTemp; /* temporary descriptor pointer */ XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress); (void)XDmaChannel_SgStop(&InstancePtr->SendChannel, &BdTemp); (void)XDmaChannel_SgStop(&InstancePtr->RecvChannel, &BdTemp); XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress); } /* * Disable the transmitter and receiver. There is no critical section * here since this register is not modified during interrupt context. */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET); ControlReg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK); XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg); /* * If not in polled mode, disable interrupts for IPIF (includes MAC and * DMAs) */ if (!InstancePtr->IsPolled) { XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress); } InstancePtr->IsStarted = 0; return XST_SUCCESS;}/*****************************************************************************//**** Reset the Ethernet MAC. This is a graceful reset in that the device is stopped* first. Resets the DMA channels, the FIFOs, the transmitter, and the receiver.* The PHY is not reset. Any frames in the scatter-gather descriptor lists will* remain in the lists. The side effect of doing this is that after a reset and* following a restart of the device, frames that were in the list before the* reset may be transmitted or received. Reset must only be called after the* driver has been initialized.** The driver is also taken out of polled mode if polled mode was set. The user* is responsbile for re-configuring the driver into polled mode after the* reset if desired.** The configuration after this reset is as follows:* - Half duplex* - Disabled transmitter and receiver* - Enabled PHY (the PHY is not reset)* - MAC transmitter does pad insertion, FCS insertion, and source address* overwrite.* - MAC receiver does not strip padding or FCS* - Interframe Gap as recommended by IEEE Std. 802.3 (96 bit times)* - Unicast addressing enabled* - Broadcast addressing enabled* - Multicast addressing disabled (addresses are preserved)* - Promiscuous addressing disabled* - Default packet threshold and packet wait bound register values for* scatter-gather DMA operation* - MAC address of all zeros* - Non-polled mode** The upper layer software is responsible for re-configuring (if necessary)* and restarting the MAC after the reset. Note that the PHY is not reset. PHY* control is left to the upper layer software. Note also that driver statistics* are not cleared on reset. It is up to the upper layer software to clear the* statistics if needed.** When a reset is required due to an internal error, the driver notifies the* upper layer software of this need through the ErrorHandler callback and* specific status codes. The upper layer software is responsible for calling* this Reset function and then re-configuring the device.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** None.** @note** None.** @internal** The reset is accomplished by setting the IPIF reset register. This takes* care of resetting all hardware blocks, including the MAC.*******************************************************************************/void XEmac_Reset(XEmac *InstancePtr){ XASSERT_VOID(InstancePtr != XNULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Stop the device first */ (void)XEmac_Stop(InstancePtr); /* * Take the driver out of polled mode */ InstancePtr->IsPolled = XFALSE; /* * Reset the entire IPIF at once. If we choose someday to reset each * hardware block separately, the reset should occur in the direction of * data flow. For example, for the send direction the reset order is DMA * first, then FIFO, then the MAC transmitter. */ XIIF_V123B_RESET(InstancePtr->BaseAddress); if (XEmac_mIsSgDma(InstancePtr)) { /* * After reset, configure the scatter-gather DMA packet threshold and * packet wait bound registers to default values. Ignore the return * values of these functions since they only return error if the device * is not stopped. */ (void)XEmac_SetPktThreshold(InstancePtr, XEM_SEND, XEM_SGDMA_DFT_THRESHOLD); (void)XEmac_SetPktThreshold(InstancePtr, XEM_RECV, XEM_SGDMA_DFT_THRESHOLD); (void)XEmac_SetPktWaitBound(InstancePtr, XEM_SEND, XEM_SGDMA_DFT_WAITBOUND); (void)XEmac_SetPktWaitBound(InstancePtr, XEM_RECV, XEM_SGDMA_DFT_WAITBOUND); }}/*****************************************************************************//**** Set the MAC address for this driver/device. The address is a 48-bit value.* The device must be stopped before calling this function.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param AddressPtr is a pointer to a 6-byte MAC address.** @return** - XST_SUCCESS if the MAC address was set successfully* - XST_DEVICE_IS_STARTED if the device has not yet been stopped** @note** None.*******************************************************************************/XStatus XEmac_SetMacAddress(XEmac *InstancePtr, Xuint8 *AddressPtr){ Xuint32 MacAddr = 0; XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(AddressPtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * The device must be stopped before setting the MAC address */ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { return XST_DEVICE_IS_STARTED; } /* * Set the device station address high and low registers */ MacAddr = (AddressPtr[0] << 8) | AddressPtr[1]; XIo_Out32(InstancePtr->BaseAddress + XEM_SAH_OFFSET, MacAddr); MacAddr = (AddressPtr[2] << 24) | (AddressPtr[3] << 16) | (AddressPtr[4] << 8) | AddressPtr[5]; XIo_Out32(InstancePtr->BaseAddress + XEM_SAL_OFFSET, MacAddr); return XST_SUCCESS;}/*****************************************************************************//**** Get the MAC address for this driver/device.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param BufferPtr is an output parameter, and is a pointer to a buffer into* which the current MAC address will be copied. The buffer must be at* least 6 bytes.** @return** None.** @note** None.*******************************************************************************/void XEmac_GetMacAddress(XEmac *InstancePtr, Xuint8 *BufferPtr){ Xuint32 MacAddrHi; Xuint32 MacAddrLo; XASSERT_VOID(InstancePtr != XNULL); XASSERT_VOID(BufferPtr != XNULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); MacAddrHi = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET); MacAddrLo = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET); BufferPtr[0] = (Xuint8)(MacAddrHi >> 8); BufferPtr[1] = (Xuint8)MacAddrHi; BufferPtr[2] = (Xuint8)(MacAddrLo >> 24); BufferPtr[3] = (Xuint8)(MacAddrLo >> 16); BufferPtr[4] = (Xuint8)(MacAddrLo >> 8); BufferPtr[5] = (Xuint8)MacAddrLo;}/******************************************************************************//**** Configure DMA capabilities.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -