📄 xemacps_control.c
字号:
u32 XEmacPs_GetOptions(XEmacPs *InstancePtr){ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); return (InstancePtr->Options);}/*****************************************************************************//** * Send a pause packet * * @param InstancePtr is a pointer to the instance to be worked on. * * @return * - XST_SUCCESS if pause frame transmission was initiated * - XST_DEVICE_IS_STOPPED if the device has not been started. * *****************************************************************************/int XEmacPs_SendPausePacket(XEmacPs *InstancePtr){ u32 Reg; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* Make sure device is ready for this operation */ if (InstancePtr->IsStarted != XIL_COMPONENT_IS_STARTED) { return (XST_DEVICE_IS_STOPPED); } /* Send flow control frame */ Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCTRL_OFFSET); Reg |= XEMACPS_NWCTRL_PAUSETX_MASK; XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, Reg); return (XST_SUCCESS);}/*****************************************************************************//** * XEmacPs_GetOperatingSpeed gets the current operating link speed. This may * be the value set by XEmacPs_SetOperatingSpeed() or a hardware default. * * @param InstancePtr references the TEMAC channel on which to operate. * * @return XEmacPs_GetOperatingSpeed returns the link speed in units of * megabits per second. * * @note * *****************************************************************************/u16 XEmacPs_GetOperatingSpeed(XEmacPs *InstancePtr){ u32 Reg; Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET); if (Reg & XEMACPS_NWCFG_1000_MASK) { return (1000); } else { if (Reg & XEMACPS_NWCFG_100_MASK) { return (100); } else { return (10); } }}/*****************************************************************************//** * XEmacPs_SetOperatingSpeed sets the current operating link speed. For any * traffic to be passed, this speed must match the current MII/GMII/SGMII/RGMII * link speed. * * @param InstancePtr references the TEMAC channel on which to operate. * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100, * or 1000. XEmacPs_SetOperatingSpeed ignores invalid values. * * @note * *****************************************************************************/void XEmacPs_SetOperatingSpeed(XEmacPs *InstancePtr, u16 Speed){ u32 Reg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid((Speed == 10) || (Speed == 100) || (Speed == 1000)); Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET); Reg &= ~(XEMACPS_NWCFG_1000_MASK | XEMACPS_NWCFG_100_MASK); switch (Speed) { case 10: break; case 100: Reg |= XEMACPS_NWCFG_100_MASK; break; case 1000: Reg |= XEMACPS_NWCFG_1000_MASK; break; default: return; } /* Set register and return */ XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET, Reg);}/*****************************************************************************//** * Set the MDIO clock divisor. * * Calculating the divisor: * * <pre> * f[HOSTCLK] * f[MDC] = ----------------- * (1 + Divisor) * 2 * </pre> * * where f[HOSTCLK] is the bus clock frequency in MHz, and f[MDC] is the * MDIO clock frequency in MHz to the PHY. Typically, f[MDC] should not * exceed 2.5 MHz. Some PHYs can tolerate faster speeds which means faster * access. Here is the table to show values to generate MDC, * * <pre> * 000 : divide pclk by 8 (pclk up to 20 MHz) * 001 : divide pclk by 16 (pclk up to 40 MHz) * 010 : divide pclk by 32 (pclk up to 80 MHz) * 011 : divide pclk by 48 (pclk up to 120 MHz) * 100 : divide pclk by 64 (pclk up to 160 MHz) * 101 : divide pclk by 96 (pclk up to 240 MHz) * 110 : divide pclk by 128 (pclk up to 320 MHz) * 111 : divide pclk by 224 (pclk up to 540 MHz) * </pre> * * @param InstancePtr is a pointer to the instance to be worked on. * @param Divisor is the divisor to set. Range is 0b000 to 0b111. * *****************************************************************************/void XEmacPs_SetMdioDivisor(XEmacPs *InstancePtr, XEmacPs_MdcDiv Divisor){ u32 Reg; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertVoid(Divisor <= 0x7); /* only last three bits are valid */ Reg = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET); /* clear these three bits, could be done with mask */ Reg &= ~XEMACPS_NWCFG_MDCCLKDIV_MASK; Reg |= (Divisor << XEMACPS_NWCFG_MDC_SHIFT_MASK); XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_NWCFG_OFFSET, Reg);}/*****************************************************************************//*** Read the current value of the PHY register indicated by the PhyAddress and* the RegisterNum parameters. The MAC provides the driver with the ability to* talk to a PHY that adheres to the Media Independent Interface (MII) as* defined in the IEEE 802.3 standard.** Prior to PHY access with this function, the user should have setup the MDIO* clock with XEmacPs_SetMdioDivisor().** @param InstancePtr is a pointer to the XEmacPs instance to be worked on.* @param PhyAddress is the address of the PHY to be read (supports multiple* PHYs)* @param RegisterNum is the register number, 0-31, of the specific PHY register* to read* @param PhyDataPtr is an output parameter, and points to a 16-bit buffer into* which the current value of the register will be copied.** @return** - XST_SUCCESS if the PHY was read from successfully* - XST_EMAC_MII_BUSY if there is another PHY operation in progress** @note** This function is not thread-safe. The user must provide mutually exclusive* access to this function if there are to be multiple threads that can call it.** There is the possibility that this function will not return if the hardware* is broken (i.e., it never sets the status bit indicating that the read is* done). If this is of concern to the user, the user should provide a mechanism* suitable to their needs for recovery.** For the duration of this function, all host interface reads and writes are* blocked to the current XEmacPs instance.*******************************************************************************/int XEmacPs_PhyRead(XEmacPs *InstancePtr, u32 PhyAddress, u32 RegisterNum, u16 *PhyDataPtr){ u32 Mgtcr; volatile u32 Ipisr; Xil_AssertNonvoid(InstancePtr != NULL); /* Make sure no other PHY operation is currently in progress */ if (!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWSR_OFFSET) & XEMACPS_NWSR_MDIOIDLE_MASK)) { return (XST_EMAC_MII_BUSY); } /* Construct Mgtcr mask for the operation */ Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_R_MASK | (PhyAddress << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK) | (RegisterNum << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK); /* Write Mgtcr and wait for completion */ XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_PHYMNTNC_OFFSET, Mgtcr); do { Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWSR_OFFSET); } while ((Ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0); /* Read data */ *PhyDataPtr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_PHYMNTNC_OFFSET); return (XST_SUCCESS);}/*****************************************************************************//*** Write data to the specified PHY register. The Ethernet driver does not* require the device to be stopped before writing to the PHY. Although it is* probably a good idea to stop the device, it is the responsibility of the* application to deem this necessary. The MAC provides the driver with the* ability to talk to a PHY that adheres to the Media Independent Interface* (MII) as defined in the IEEE 802.3 standard.** Prior to PHY access with this function, the user should have setup the MDIO* clock with XEmacPs_SetMdioDivisor().** @param InstancePtr is a pointer to the XEmacPs instance to be worked on.* @param PhyAddress is the address of the PHY to be written (supports multiple* PHYs)* @param RegisterNum is the register number, 0-31, of the specific PHY register* to write* @param PhyData is the 16-bit value that will be written to the register** @return** - XST_SUCCESS if the PHY was written to successfully. Since there is no error* status from the MAC on a write, the user should read the PHY to verify the* write was successful.* - XST_EMAC_MII_BUSY if there is another PHY operation in progress** @note** This function is not thread-safe. The user must provide mutually exclusive* access to this function if there are to be multiple threads that can call it.** There is the possibility that this function will not return if the hardware* is broken (i.e., it never sets the status bit indicating that the write is* done). If this is of concern to the user, the user should provide a mechanism* suitable to their needs for recovery.** For the duration of this function, all host interface reads and writes are* blocked to the current XEmacPs instance.*******************************************************************************/int XEmacPs_PhyWrite(XEmacPs *InstancePtr, u32 PhyAddress, u32 RegisterNum, u16 PhyData){ u32 Mgtcr; volatile u32 Ipisr; Xil_AssertNonvoid(InstancePtr != NULL); /* Make sure no other PHY operation is currently in progress */ if (!(XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWSR_OFFSET) & XEMACPS_NWSR_MDIOIDLE_MASK)) { return (XST_EMAC_MII_BUSY); } /* Construct Mgtcr mask for the operation */ Mgtcr = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_W_MASK | (PhyAddress << XEMACPS_PHYMNTNC_PHYAD_SHIFT_MASK) | (RegisterNum << XEMACPS_PHYMNTNC_PHREG_SHIFT_MASK) | PhyData; /* Write Mgtcr and wait for completion */ XEmacPs_WriteReg(InstancePtr->Config.BaseAddress, XEMACPS_PHYMNTNC_OFFSET, Mgtcr); do { Ipisr = XEmacPs_ReadReg(InstancePtr->Config.BaseAddress, XEMACPS_NWSR_OFFSET); } while ((Ipisr & XEMACPS_NWSR_MDIOIDLE_MASK) == 0); return (XST_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -