📄 xemac.c
字号:
*/ 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.*******************************************************************************/voidXEmac_Reset(XEmac * InstancePtr){ XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Stop the device first */ (void) XEmac_Stop(InstancePtr); /* * Take the driver out of polled mode */ InstancePtr->IsPolled = FALSE; /* * 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.*******************************************************************************/XStatusXEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr){ u32 MacAddr = 0; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(AddressPtr != NULL); 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.*******************************************************************************/voidXEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr){ u32 MacAddrHi; u32 MacAddrLo; XASSERT_VOID(InstancePtr != NULL); XASSERT_VOID(BufferPtr != NULL); 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] = (u8) (MacAddrHi >> 8); BufferPtr[1] = (u8) MacAddrHi; BufferPtr[2] = (u8) (MacAddrLo >> 24); BufferPtr[3] = (u8) (MacAddrLo >> 16); BufferPtr[4] = (u8) (MacAddrLo >> 8); BufferPtr[5] = (u8) MacAddrLo;}/******************************************************************************//**** Configure DMA capabilities.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** - XST_SUCCESS if successful initialization of DMA** @note** None.*******************************************************************************/static XStatusConfigureDma(XEmac * InstancePtr){ XStatus Result; /* * Initialize the DMA channels with their base addresses. We assume * scatter-gather DMA is the only possible configuration. Descriptor space * will need to be set later by the upper layer. */ Result = XDmaChannel_Initialize(&InstancePtr->RecvChannel, InstancePtr->BaseAddress + XEM_DMA_RECV_OFFSET); if (Result != XST_SUCCESS) { return Result; } Result = XDmaChannel_Initialize(&InstancePtr->SendChannel, InstancePtr->BaseAddress + XEM_DMA_SEND_OFFSET); return Result;}/******************************************************************************//**** Configure the send and receive FIFO components with their base addresses* and interrupt masks. Currently the base addresses are defined constants.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** XST_SUCCESS if successful initialization of the packet FIFOs** @note** None.*******************************************************************************/static XStatusConfigureFifo(XEmac * InstancePtr){ XStatus Result; /* * Return status from the packet FIFOs initialization is ignored since * they always return success. */ Result = XPacketFifoV100b_Initialize(&InstancePtr->RecvFifo, InstancePtr->BaseAddress + XEM_PFIFO_RXREG_OFFSET, InstancePtr->BaseAddress + XEM_PFIFO_RXDATA_OFFSET); if (Result != XST_SUCCESS) { return Result; } Result = XPacketFifoV100b_Initialize(&InstancePtr->SendFifo, InstancePtr->BaseAddress + XEM_PFIFO_TXREG_OFFSET, InstancePtr->BaseAddress + XEM_PFIFO_TXDATA_OFFSET); return Result;}/******************************************************************************//**** This is a stub for the scatter-gather send and recv callbacks. The stub* is here in case the upper layers forget to set the handlers.** @param CallBackRef is a pointer to the upper layer callback reference* @param BdPtr is a pointer to the first buffer descriptor in a list* @param NumBds is the number of descriptors in the list.** @return** None.** @note** None.*******************************************************************************/static voidStubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds){ XASSERT_VOID_ALWAYS();}/******************************************************************************//**** This is a stub for the non-DMA send and recv callbacks. The stub is here in* case the upper layers forget to set the handlers.** @param CallBackRef is a pointer to the upper layer callback reference** @return** None.** @note** None.*******************************************************************************/static voidStubFifoHandler(void *CallBackRef){ XASSERT_VOID_ALWAYS();}/******************************************************************************//**** This is a stub for the asynchronous error callback. The stub is here in* case the upper layers forget to set the handler.** @param CallBackRef is a pointer to the upper layer callback reference* @param ErrorCode is the Xilinx error code, indicating the cause of the error** @return** None.** @note** None.*******************************************************************************/static voidStubErrorHandler(void *CallBackRef, XStatus ErrorCode){ XASSERT_VOID_ALWAYS();}/*****************************************************************************//**** Lookup the device configuration based on the unique device ID. The table* EmacConfigTable contains the configuration info for each device in the system.** @param DeviceId is the unique device ID of the device being looked up.** @return** A pointer to the configuration table entry corresponding to the given* device ID, or NULL if no match is found.** @note** None.*******************************************************************************/XEmac_Config *XEmac_LookupConfig(u16 DeviceId){ XEmac_Config *CfgPtr = NULL; int i; for (i = 0; i < XPAR_XEMAC_NUM_INSTANCES; i++) { if (XEmac_ConfigTable[i].DeviceId == DeviceId) { CfgPtr = &XEmac_ConfigTable[i]; break; } } return CfgPtr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -