📄 xtemac_control.c
字号:
/* Be sure device has been stopped */ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { return(XST_DEVICE_IS_STARTED); } /* Polled mode requires FIFO direct */ if ((Options & XTE_POLLED_OPTION) && (!XTemac_mIsFifo(InstancePtr))) { return(XST_NO_FEATURE); } /* Many of these options will change the ERXC1 or ETXC registers. * To reduce the amount of IO to the device, group these options here * and change them all at once. */ /* Grab current register contents */ RegErxc1 = XTemac_mGetHostReg(XTE_RXC1_OFFSET); RegEtxc = XTemac_mGetHostReg(XTE_TXC_OFFSET); RegNewErxc1 = RegErxc1; RegNewEtxc = RegEtxc; /* Turn on jumbo packet support for both Rx and Tx */ if (Options & XTE_JUMBO_OPTION) { RegNewEtxc |= XTE_TXC_TXJMBO_MASK; RegNewErxc1 |= XTE_RXC1_RXJMBO_MASK; } /* Turn on VLAN packet support for both Rx and Tx */ if (Options & XTE_VLAN_OPTION) { RegNewEtxc |= XTE_TXC_TXVLAN_MASK; RegNewErxc1 |= XTE_RXC1_RXVLAN_MASK; } /* Turn on FCS stripping on receive packets */ if (Options & XTE_FCS_STRIP_OPTION) { RegNewErxc1 &= ~XTE_RXC1_RXFCS_MASK; } /* Turn on FCS insertion on transmit packets */ if (Options & XTE_FCS_INSERT_OPTION) { RegNewEtxc &= ~XTE_TXC_TXFCS_MASK; } /* Turn on length/type field checking on receive packets */ if (Options & XTE_LENTYPE_ERR_OPTION) { RegNewErxc1 &= ~XTE_RXC1_RXLT_MASK; } /* Officially change the ETXC or ERXC1 registers if they need to be * modified */ if (RegEtxc != RegNewEtxc) { XTemac_mSetHostReg(XTE_TXC_OFFSET, RegNewEtxc); } if (RegErxc1 != RegNewErxc1) { XTemac_mSetHostReg(XTE_RXC1_OFFSET, RegNewErxc1); } /* Rest of options twiddle bits of other registers. Handle them one at * a time */ /* Turn on flow control */ if (Options & XTE_FLOW_CONTROL_OPTION) { Reg = XTemac_mGetHostReg(XTE_FCC_OFFSET); Reg |= XTE_FCC_RXFLO_MASK; XTemac_mSetHostReg(XTE_FCC_OFFSET, Reg); } /* Turn on promiscuous frame filtering (all frames are received ) */ if (Options & XTE_PROMISC_OPTION) { Reg = XTemac_mGetHostReg(XTE_AFM_OFFSET); Reg |= XTE_AFM_EPPRM_MASK; XTemac_mSetHostReg(XTE_AFM_OFFSET, Reg); } /* Allow broadcast address filtering */ if (Options & XTE_BROADCAST_OPTION) { Reg = XTemac_mGetIpifReg(XTE_CR_OFFSET); Reg &= ~XTE_CR_BCREJ_MASK; XTemac_mSetIpifReg(XTE_CR_OFFSET, Reg); } /* Allow multicast address filtering */ if (Options & XTE_MULTICAST_CAM_OPTION) { Reg = XTemac_mGetIpifReg(XTE_CR_OFFSET); Reg &= ~XTE_CR_MCREJ_MASK; XTemac_mSetIpifReg(XTE_CR_OFFSET, Reg); } /* Enable interrupts related to rejection of bad frames */ if (Options & XTE_REPORT_RXERR_OPTION) { /* Clear out any previous error conditions that may have existed * prior to enabling the reporting of these types of errors */ Reg = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); XTemac_mSetIpifReg(XTE_IPISR_OFFSET, Reg & XTE_IPXR_RECV_DROPPED_MASK); /* Whether these are enabled here are based on the last call to * XTemac_IntrFifoEnable/Disable() and XTemac_IntrSgDmaEnable/Disable() * for the receive channel. * * If receive interrupts are enabled, then enable these interrupts. This * way, when XTemac_Start() is called, these interrupt enables take * effect right away. * * If receive interrupts are disabled, then don't do anything here. The * XTemac_IntrFifoEnable() and XTemac_IntrSgDmaEnable() functions when * called will check this option and enable these interrupts if needed. */ if (InstancePtr->Flags & (XTE_FLAGS_RECV_FIFO_INT_ENABLE | XTE_FLAGS_RECV_SGDMA_INT_ENABLE)) { Reg = XTemac_mGetIpifReg(XTE_IPIER_OFFSET); Reg |= XTE_IPXR_RECV_DROPPED_MASK; XTemac_mSetIpifReg(XTE_IPIER_OFFSET, Reg); } } /* Enable interrrupt related to assertion of auto-negotiate HW interrupt */ if (Options & XTE_ANEG_OPTION) { /* Clear out any previous interupt condition that may have existed * prior to enabling the reporting of auto negotiation */ Reg = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); XTemac_mSetIpifReg(XTE_IPISR_OFFSET, Reg & XTE_IPXR_AUTO_NEG_MASK); /* Make this interupt source enabled when XTemac_Start() is called */ Reg = XTemac_mGetIpifReg(XTE_IPIER_OFFSET); XTemac_mSetIpifReg(XTE_IPIER_OFFSET, Reg & XTE_IPXR_AUTO_NEG_MASK); } /* Enable interrupts upon completing a SG list */ if ((Options & XTE_SGEND_INT_OPTION) && XTemac_mIsSgDma(InstancePtr)) { Reg = XDmaV3_GetInterruptEnable(&InstancePtr->SendDma); Reg |= XDMAV3_IPXR_SGEND_MASK; XDmaV3_SetInterruptEnable(&InstancePtr->SendDma, Reg); Reg = XDmaV3_GetInterruptEnable(&InstancePtr->RecvDma); Reg |= XDMAV3_IPXR_SGEND_MASK; XDmaV3_SetInterruptEnable(&InstancePtr->RecvDma, Reg); } /* The remaining options not handled here are managed elsewhere in the * driver. No register modifications are needed at this time. Reflecting the * option in InstancePtr->Options is good enough for now. */ /* Set options word to its new value */ InstancePtr->Options |= Options; return(XST_SUCCESS);}/*****************************************************************************//** * Clear options for the driver/device * * @param InstancePtr is a pointer to the instance to be worked on. * @param Options are the options to clear. Multiple options can be cleared by * OR'ing XTE_*_OPTIONS constants together. Options not specified are not * affected. * * @return * - XST_SUCCESS if the options were set successfully * - XST_DEVICE_IS_STARTED if the device has not yet been stopped * * @note * See xtemac.h for a description of the available options. * ******************************************************************************/XStatus XTemac_ClearOptions(XTemac *InstancePtr, u32 Options){ volatile u32 Reg;/* Generic */ u32 RegErxc1; /* Reflects original contents of ERXC1 */ u32 RegEtxc; /* Reflects original contents of ETXC */ u32 RegNewErxc1; /* Reflects new contents of ERXC1 */ u32 RegNewEtxc; /* Reflects new contents of ETXC */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Be sure device has been stopped */ if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { return(XST_DEVICE_IS_STARTED); } /* Many of these options will change the ERXC1 or ETXC registers. * Group these options here and change them all at once. What we are * trying to accomplish is to reduce the amount of IO to the device */ /* Grab current register contents */ RegErxc1 = XTemac_mGetHostReg(XTE_RXC1_OFFSET); RegEtxc = XTemac_mGetHostReg(XTE_TXC_OFFSET); RegNewErxc1 = RegErxc1; RegNewEtxc = RegEtxc; /* Turn off jumbo packet support for both Rx and Tx */ if (Options & XTE_JUMBO_OPTION) { RegNewEtxc &= ~XTE_TXC_TXJMBO_MASK; RegNewErxc1 &= ~XTE_RXC1_RXJMBO_MASK; } /* Turn off VLAN packet support for both Rx and Tx */ if (Options & XTE_VLAN_OPTION) { RegNewEtxc &= ~XTE_TXC_TXVLAN_MASK; RegNewErxc1 &= ~XTE_RXC1_RXVLAN_MASK; } /* Turn off FCS stripping on receive packets */ if (Options & XTE_FCS_STRIP_OPTION) { RegNewErxc1 |= XTE_RXC1_RXFCS_MASK; } /* Turn off FCS insertion on transmit packets */ if (Options & XTE_FCS_INSERT_OPTION) { RegNewEtxc |= XTE_TXC_TXFCS_MASK; } /* Turn off length/type field checking on receive packets */ if (Options & XTE_LENTYPE_ERR_OPTION) { RegNewErxc1 |= XTE_RXC1_RXLT_MASK; } /* Disable transmitter */ if (Options & XTE_TRANSMITTER_ENABLE_OPTION) { RegNewEtxc &= ~XTE_TXC_TXEN_MASK; } /* Disable receiver */ if (Options & XTE_RECEIVER_ENABLE_OPTION) { RegNewErxc1 &= ~XTE_RXC1_RXEN_MASK; } /* Officially change the ETXC or ERXC1 registers if they need to be * modified */ if (RegEtxc != RegNewEtxc) { XTemac_mSetHostReg(XTE_TXC_OFFSET, RegNewEtxc); } if (RegErxc1 != RegNewErxc1) { XTemac_mSetHostReg(XTE_RXC1_OFFSET, RegNewErxc1); } /* Rest of options twiddle bits of other registers. Handle them one at * a time */ /* Turn off flow control */ if (Options & XTE_FLOW_CONTROL_OPTION) { Reg = XTemac_mGetHostReg(XTE_FCC_OFFSET); Reg &= ~XTE_FCC_RXFLO_MASK; XTemac_mSetHostReg(XTE_FCC_OFFSET, Reg); } /* Turn off promiscuous frame filtering */ if (Options & XTE_PROMISC_OPTION) { Reg = XTemac_mGetHostReg(XTE_AFM_OFFSET); Reg &= ~XTE_AFM_EPPRM_MASK; XTemac_mSetHostReg(XTE_AFM_OFFSET, Reg); } /* Disable broadcast address filtering */ if (Options & XTE_BROADCAST_OPTION) { Reg = XTemac_mGetIpifReg(XTE_CR_OFFSET); Reg |= XTE_CR_BCREJ_MASK; XTemac_mSetIpifReg(XTE_CR_OFFSET, Reg); } /* Disable multicast address filtering */ if (Options & XTE_MULTICAST_CAM_OPTION) { Reg = XTemac_mGetIpifReg(XTE_CR_OFFSET); Reg |= XTE_CR_MCREJ_MASK; XTemac_mSetIpifReg(XTE_CR_OFFSET, Reg); } /* Disable interrupts related to rejection of bad frames */ if (Options & XTE_REPORT_RXERR_OPTION) { Reg = XTemac_mGetIpifReg(XTE_IPIER_OFFSET); Reg &= ~XTE_IPXR_RECV_DROPPED_MASK; XTemac_mSetIpifReg(XTE_IPIER_OFFSET, Reg); } /* Disable interrupts related to auto negotiate */ if (Options & XTE_ANEG_OPTION) { Reg = XTemac_mGetIpifReg(XTE_IPIER_OFFSET); Reg &= ~XTE_IPXR_AUTO_NEG_MASK; XTemac_mSetIpifReg(XTE_IPIER_OFFSET, Reg); } /* Disable interrupts upon completing a SG list */ if ((Options & XTE_SGEND_INT_OPTION) && XTemac_mIsSgDma(InstancePtr)) { Reg = XDmaV3_GetInterruptEnable(&InstancePtr->SendDma); Reg &= ~XDMAV3_IPXR_SGEND_MASK; XDmaV3_SetInterruptEnable(&InstancePtr->SendDma, Reg); Reg = XDmaV3_GetInterruptEnable(&InstancePtr->RecvDma); Reg &= ~XDMAV3_IPXR_SGEND_MASK; XDmaV3_SetInterruptEnable(&InstancePtr->RecvDma, Reg); } /* The remaining options not handled here are managed elsewhere in the * driver. No register modifications are needed at this time. Reflecting the * option in InstancePtr->Options is good enough for now. */ /* Set options word to its new value */ InstancePtr->Options &= ~Options; return(XST_SUCCESS);}/*****************************************************************************//** * Get current option settings * * @param InstancePtr is a pointer to the instance to be worked on. * * @return * A bitmask of XTE_*_OPTION constants. Any bit set to 1 is to be interpreted * as a set opion. * * @note * See xtemac.h for a description of the available options. * ******************************************************************************/u32 XTemac_GetOptions(XTemac *InstancePtr){ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); return(InstancePtr->Options);}/*****************************************************************************//** * Send a pause packet * * @param InstancePtr is a pointer to the instance to be worked on. * @param PauseValue is the pause value in units of 512 bit times. * * @return * - XST_SUCCESS if pause frame transmission was initiated * - XST_DEVICE_IS_STOPPED if the device has not been started. * ******************************************************************************/XStatus XTemac_SendPausePacket(XTemac *InstancePtr, u16 PauseValue){ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Make sure device is ready for this operation */ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) { return(XST_DEVICE_IS_STOPPED); } /* Send flow control frame */ XTemac_mSetIpifReg(XTE_TPPR_OFFSET, (u32)PauseValue); return(XST_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -