📄 xtemac.c
字号:
} /* Enable receiver? */ if (InstancePtr->Options & XTE_RECEIVER_ENABLE_OPTION) { Reg = XTemac_mGetHostReg(XTE_RXC1_OFFSET) | XTE_RXC1_RXEN_MASK; XTemac_mSetHostReg(XTE_RXC1_OFFSET, Reg); } /* Mark as started */ InstancePtr->IsStarted = XCOMPONENT_IS_STARTED; /* Allow interrupts (if not in polled mode) and exit */ if ((InstancePtr->Options & XTE_POLLED_OPTION) == 0) { XTemac_mSetIpifReg(XTE_DGIE_OFFSET, XTE_DGIE_ENABLE_MASK); } return(XST_SUCCESS);}/*****************************************************************************//*** Gracefully stop the Ethernet MAC as follows:* - Disable all interrupts from this device* - Stop DMA channels (if configured)* - Disable the receiver** Device options currently in effect are not changed.** This function will disable all interrupts by clearing the global interrupt* enable. Any interrupts settings that had been enabled through* XTemac_IntrFifoEnable(), XTemac_IntrFifoDmaEnable(), or* XTemac_IntrSgEnable() will be restored when XTemac_Start() is called.** Since the transmitter is not disabled, frames currently in the packet FIFO* or in process by the SGDMA engine are allowed to be transmitted. XTemac API* functions that place new data in the packet FIFOs will not be allowed to do* so until XTemac_Start() is called.** @param InstancePtr is a pointer to the instance to be worked on.** @note* This function makes use of internal resources that are shared between the* Start, Stop, SetOptions, and ClearOptions 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).** Stopping the DMA channels may cause this function to block until the DMA* operation is complete. This function will not block waiting for frame data to* to exit the packet FIFO to the transmitter.*******************************************************************************/void XTemac_Stop(XTemac *InstancePtr){ volatile u32 Reg; XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* If already stopped, then there is nothing to do */ if (InstancePtr->IsStarted == 0) { return; } /* Disable interrupts */ XTemac_mSetIpifReg(XTE_DGIE_OFFSET, 0); /* For SGDMA, use the DMA driver function to stop the channels */ if (XTemac_mIsSgDma(InstancePtr)) { (void)XDmaV3_SgStop(&InstancePtr->SendDma); (void)XDmaV3_SgStop(&InstancePtr->RecvDma); } /* Disable the receiver */ Reg = XTemac_mGetHostReg(XTE_RXC1_OFFSET); Reg &= ~XTE_RXC1_RXEN_MASK; XTemac_mSetHostReg(XTE_RXC1_OFFSET, Reg); /* Stopping the receiver in mid-packet causes a dropped packet indication * from HW. Clear it. */ Reg = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); if (Reg & XTE_IPXR_RECV_REJECT_MASK) { XTemac_mSetIpifReg(XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK); } /* Mark as stopped */ InstancePtr->IsStarted = 0;}/*****************************************************************************//*** Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the* FIFOs, the transmitter, and the receiver.** All options are placed in their default state. 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.** The upper layer software is responsible for re-configuring (if necessary)* and restarting the MAC after the reset. 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.** Resetting the IPIF should suffice in most circumstances. As a last resort* however, the hard TEMAC core can be reset as well using the HardCoreAction* parameter. In systems with two TEMACs, the reset signal is shared between* both devices resulting in BOTH being reset. This requires the user save the* state of both TEMAC's prior to resetting the hard core on either device* instance.* @param InstancePtr is a pointer to the instance to be worked on.* @param HardCoreAction describes how the hard core part of the TEMAC should* be managed. If XTE_RESET_HARD is passed in, then the reset signal is* asserted to the hard core block. This will reset both hard cores.* If any other value is passed in, then only the IPIF of the given* instance is reset.*******************************************************************************/void XTemac_Reset(XTemac *InstancePtr, int HardCoreAction){ u32 Data; XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Stop the device and reset HW */ XTemac_Stop(InstancePtr); InstancePtr->Options = XTE_DEFAULT_OPTIONS; /* Reset IPIF */ XTemac_mSetIpifReg(XTE_DSR_OFFSET, XTE_DSR_RESET_MASK); udelay(XTE_RESET_IPIF_DELAY_US); /* Reset hard core if required */ if (HardCoreAction == XTE_RESET_HARD) { Data = XTemac_mGetIpifReg(XTE_CR_OFFSET); XTemac_mSetIpifReg(XTE_CR_OFFSET, Data | XTE_CR_HRST_MASK); udelay(XTE_RESET_HARD_DELAY_US); } /* Setup HW */ InitHw(InstancePtr);}/****************************************************************************** * Perform one-time setup of HW. The setups performed here only need to occur * once after any reset. * * @param InstancePtr is a pointer to the instance to be worked on. * ******************************************************************************/static void InitHw(XTemac *InstancePtr){ u32 Reg; /* Disable the receiver */ Reg = XTemac_mGetHostReg(XTE_RXC1_OFFSET); Reg &= ~XTE_RXC1_RXEN_MASK; XTemac_mSetHostReg(XTE_RXC1_OFFSET, Reg); /* Stopping the receiver in mid-packet causes a dropped packet indication * from HW. Clear it. */ Reg = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); if (Reg & XTE_IPXR_RECV_REJECT_MASK) { XTemac_mSetIpifReg(XTE_IPISR_OFFSET, XTE_IPXR_RECV_REJECT_MASK); } /* Default IPIF interrupt block enable mask */ Reg = (XTE_DXR_CORE_MASK | XTE_DXR_DPTO_MASK | XTE_DXR_TERR_MASK); if (XTemac_mIsFifo(InstancePtr)) { Reg |= (XTE_DXR_RECV_FIFO_MASK | XTE_DXR_SEND_FIFO_MASK); } XTemac_mSetIpifReg(XTE_DIER_OFFSET, Reg); if (XTemac_mIsSgDma(InstancePtr)) { /* Setup SGDMA interupt coalescing defaults */ (void)XTemac_IntrSgCoalSet(InstancePtr, XTE_SEND, XTE_SGDMA_DFT_THRESHOLD, XTE_SGDMA_DFT_WAITBOUND); (void)XTemac_IntrSgCoalSet(InstancePtr, XTE_RECV, XTE_SGDMA_DFT_THRESHOLD, XTE_SGDMA_DFT_WAITBOUND); /* Setup interrupt enable data for each channel */ Reg = (XDMAV3_IPXR_PCTR_MASK | XDMAV3_IPXR_PWBR_MASK | XDMAV3_IPXR_DE_MASK); XDmaV3_SetInterruptEnable(&InstancePtr->SendDma, Reg); XDmaV3_SetInterruptEnable(&InstancePtr->RecvDma, Reg); } /* Sync default options with HW but leave receiver and transmitter * disabled. They get enabled with XTemac_Start() if XTE_TRANSMITTER_ENABLE- * _OPTION and XTE_RECEIVER_ENABLE_OPTION are set */ XTemac_SetOptions(InstancePtr, InstancePtr->Options & ~(XTE_TRANSMITTER_ENABLE_OPTION | XTE_RECEIVER_ENABLE_OPTION)); XTemac_ClearOptions(InstancePtr, ~InstancePtr->Options); /* Set default MDIO divisor */ XTemac_PhySetMdioDivisor(InstancePtr, XTE_MDIO_DIV_DFT);}/******************************************************************************//** * This is a stub for the asynchronous callbacks. The stub is here in case the * upper layer forgot to set the handler(s). On initialization, all handlers are * set to this callback. It is considered an error for this handler to be * invoked. * ******************************************************************************/void XTemac_StubHandler(void){ XASSERT_VOID_ALWAYS();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -