⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xtemac_control.c

📁 xilinx trimode mac driver for linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************//** * Get the current operating link speed. This may be the value set by * XTemac_SetOperatingSpeed() or a HW default. * * @param InstancePtr is a pointer to the instance to be worked on. * * @return Link speed in units of megabits per second * ******************************************************************************/u16 XTemac_GetOperatingSpeed(XTemac *InstancePtr){    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    switch(XTemac_mGetHostReg(XTE_EMCFG_OFFSET) & XTE_EMCFG_LINKSPD_MASK)    {        case XTE_EMCFG_LINKSPD_1000:            return(1000);        case XTE_EMCFG_LINKSPD_100:            return(100);        case XTE_EMCFG_LINKSPD_10:            return(10);        default:            return(0);    }}/*****************************************************************************//** * Set 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 is a pointer to the instance to be worked on. * @param Speed is the speed to set in units of Mbps. Valid values are 10, 100, *        or 1000. Invalid values result in no change to the device. * ******************************************************************************/void XTemac_SetOperatingSpeed(XTemac *InstancePtr, u16 Speed){    u32 EcfgReg;    XASSERT_VOID(InstancePtr != NULL);    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    XASSERT_VOID((Speed == 10) || (Speed == 100) || (Speed == 1000));    /* Get the current contents of the EMAC config register and zero out     * speed bits     */    EcfgReg = XTemac_mGetHostReg(XTE_EMCFG_OFFSET) & ~XTE_EMCFG_LINKSPD_MASK;    switch(Speed)    {        case 10:            break;        case 100:            EcfgReg |= XTE_EMCFG_LINKSPD_100;            break;        case 1000:            EcfgReg |= XTE_EMCFG_LINKSPD_1000;            break;        default:            return;    }    /* Set register and return */    XTemac_mSetHostReg(XTE_EMCFG_OFFSET, EcfgReg);}/*****************************************************************************//** * Get the current state of the link when media interface is of the SGMII type * * @param InstancePtr is a pointer to the instance to be worked on. * @param SpeedPtr is a return value set to either 0, 10, 100, or 1000. Units *        are in Mbits/sec. * * @return *   - XST_SUCCESS if the SGMII status was read and return values set. *   - XST_NO_FEATURE if the device is not using SGMII. * ******************************************************************************/XStatus XTemac_GetSgmiiStatus(XTemac *InstancePtr, u16 *SpeedPtr){    int PhyType;    u32 EgmicReg;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /* Make sure PHY is SGMII */    PhyType = XTemac_mGetPhysicalInterface(InstancePtr);    if (PhyType != XTE_PHY_TYPE_SGMII)    {        return(XST_NO_FEATURE);    }    /* Get the current contents of RGMII/SGMII config register */    EgmicReg = XTemac_mGetHostReg(XTE_GMIC_OFFSET);    /* Extract speed */    switch (EgmicReg & XTE_GMIC_RGLINKSPD_MASK)    {        case XTE_GMIC_RGLINKSPD_10:            *SpeedPtr = 10;            break;        case XTE_GMIC_RGLINKSPD_100:            *SpeedPtr = 100;            break;        case XTE_GMIC_RGLINKSPD_1000:            *SpeedPtr = 1000;            break;        default:            *SpeedPtr = 0;    }    return(XST_SUCCESS);}/*****************************************************************************//** * Get the current state of the link when media interface is of the RGMII type * * @param InstancePtr is a pointer to the instance to be worked on. * @param SpeedPtr is a return value set to either 0, 10, 100, or 1000. Units *        are in Mbits/sec. * @param IsFullDuplexPtr is a return value set to TRUE if the RGMII link *        is operating in full duplex, or FALSE if operating in half duplex. *        XTE_RGMII_LINK_UP. * @param IsLinkUpPtr is a return value set to TRUE if the RGMII link is up, *        or FALSE if the link is down. * * @return *   - XST_SUCCESS if the RGMII status was read and return values set. *   - XST_NO_FEATURE if the device is not using RGMII. * ******************************************************************************/XStatus XTemac_GetRgmiiStatus(XTemac *InstancePtr, u16 *SpeedPtr,                              u32 *IsFullDuplexPtr, u32 *IsLinkUpPtr){    int PhyType;    u32 EgmicReg;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /* Make sure PHY is RGMII */    PhyType = XTemac_mGetPhysicalInterface(InstancePtr);    if ((PhyType != XTE_PHY_TYPE_RGMII_1_3) &&        (PhyType != XTE_PHY_TYPE_RGMII_2_0))    {        return(XST_NO_FEATURE);    }    /* Get the current contents of RGMII/SGMII config register */    EgmicReg = XTemac_mGetHostReg(XTE_GMIC_OFFSET);    /* Extract speed */    switch (EgmicReg & XTE_GMIC_RGLINKSPD_MASK)    {        case XTE_GMIC_RGLINKSPD_10:            *SpeedPtr = 10;            break;        case XTE_GMIC_RGLINKSPD_100:            *SpeedPtr = 100;            break;        case XTE_GMIC_RGLINKSPD_1000:            *SpeedPtr = 1000;            break;        default:            *SpeedPtr = 0;    }    /* Extract duplex and link status */    if (EgmicReg & XTE_GMIC_RGHALFDUPLEX_MASK)    {        *IsFullDuplexPtr = FALSE;    }    else    {        *IsFullDuplexPtr = TRUE;    }    if (EgmicReg & XTE_GMIC_RGSTATUS_MASK)    {        *IsLinkUpPtr = TRUE;    }    else    {        *IsLinkUpPtr = FALSE;    }    return(XST_SUCCESS);}/*****************************************************************************//** * Set the MDIO clock divisor. This function must be called once after each * reset prior to accessing MII PHY registers. * * Calculating the divisor: * * From the Virtex-4 Embedded Tri-Mode Ethernet MAC User's Guide, the * following equation governs the MDIO clock to the PHY: * * <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. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Divisor is the divisor to set. Range is 0 to XTE_MC_CLK_DVD_MAX. * ******************************************************************************/void XTemac_PhySetMdioDivisor(XTemac *InstancePtr, u8 Divisor){    XASSERT_VOID(InstancePtr != NULL);    XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY)    XASSERT_VOID(Divisor <= XTE_MC_CLK_DVD_MAX);    XTemac_mSetHostReg(XTE_MC_OFFSET, (u32)Divisor | XTE_MC_MDIO_MASK);}/*****************************************************************************//*** 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 XTemac_PhySetMdioDivisor().** @param InstancePtr is a pointer to the XTemac 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_NO_FEATURE if the device is not configured with MII support* - 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.* <br><br>* 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.* <br><br>* For the duration of this function, all host interface reads and writes are* blocked to the current Temac instance and also the 2nd instance if it exists* in the system. This is a HW limitation. See xtemac.h for a list of functions* that will be blocked until this operation completes.*******************************************************************************/XStatus XTemac_PhyRead(XTemac *InstancePtr, u32 PhyAddress,                       u32 RegisterNum, u16 *PhyDataPtr){    u32 Mgtcr;    volatile u32 Ipisr;    XASSERT_NONVOID(InstancePtr != NULL);    /* Make sure no other PHY operation is currently in progress */    if (XTemac_mGetIpifReg(XTE_IPISR_OFFSET) & XTE_IPXR_MII_PEND_MASK)    {        return(XST_EMAC_MII_BUSY);    }    /* Construct Mgtcr mask for the operation */    Mgtcr = RegisterNum & XTE_MGTCR_REGAD_MASK;    Mgtcr |= ((PhyAddress << XTE_MGTCR_PHYAD_SHIFT_MASK) & XTE_MGTCR_PHYAD_MASK);    Mgtcr |= XTE_MGTCR_RWN_MASK;    /* Write Mgtcr and wait for completion */    XTemac_mSetIpifReg(XTE_MGTCR_OFFSET, Mgtcr);    do    {        Ipisr = XTemac_mGetIpifReg(XTE_IPISR_OFFSET);    } while (!(Ipisr & XTE_IPXR_MII_DONE_MASK));    /* Read data */    *PhyDataPtr = XTemac_mGetIpifReg(XTE_MGTDR_OFFSET);    /* Clear MII status bits */    XTemac_mSetIpifReg(XTE_IPISR_OFFSET,                       Ipisr & (XTE_IPXR_MII_DONE_MASK | XTE_IPXR_MII_PEND_MASK));    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 XTemac_PhySetMdioDivisor().** @param InstancePtr is a pointer to the XTemac 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_NO_FEATURE if the device is not configured with MII support* - 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.* <br><br>* 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.* <br><br>* For the duration of this function, all host interface reads and writes are* blocked to the current Temac instance and also the 2nd instance if it exists* in the system. This is a HW limitation. See xtemac.h for a list of functions* that will be blocked until this operation completes.*******************************************************************************/XStatus XTemac_PhyWrite(XTemac *InstancePtr, u32 PhyAddress,                        u32 RegisterNum, u16 PhyData){    u32 Mgtcr;    volatile u32 Ipisr;    XASSERT_NONVOID(InstancePtr != NULL);    /* Make sure no other PHY operation is currently in progress */    if (XTemac_mGetIpifReg(XTE_IPISR_OFFSET) & XTE_IPXR_MII_PEND_MASK)    {        return(XST_EMAC_MII_BUSY);    }    /* Construct Mgtcr mask for the operation */    Mgtcr = RegisterNum & XTE_MGTCR_REGAD_MASK;    Mgtcr |= ((PhyAddress << XTE_MGTCR_PHYAD_SHIFT_MASK) & XTE_MGTCR_PHYAD_MASK);    /* Write Mgtdr and Mgtcr and wait for completion */    XTemac_mSetIpifReg(XTE_MGTDR_OFFSET, (u32)PhyData);    XTemac_mSetIpifReg(XTE_MGTCR_OFFSET, Mgtcr);    do    {        Ipisr = XTemac_mGetIpifReg(XTE_IPISR_OFFSET);    } while (!(Ipisr & XTE_IPXR_MII_DONE_MASK));    /* Clear MII status bits */    XTemac_mSetIpifReg(XTE_IPISR_OFFSET,                       Ipisr & (XTE_IPXR_MII_DONE_MASK | XTE_IPXR_MII_PEND_MASK));    return(XST_SUCCESS);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -