unsigned configure_IEEE_phy_speed(XLlTemac *xlltemacp, unsigned speed) { u16 control; u32 phy_addr = detect_phy(xlltemacp); XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); control &= ~IEEE_CTRL_LINKSPEED_1000M; control &= ~IEEE_CTRL_LINKSPEED_100M; control &= ~IEEE_CTRL_LINKSPEED_10M; if (speed == 1000) { control |= IEEE_CTRL_LINKSPEED_1000M; } else if (speed == 100) { control |= IEEE_CTRL_LINKSPEED_100M; /* Dont advertise PHY speed of 1000 Mbps */ XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0); /* Dont advertise PHY speed of 10 Mbps */ XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, ADVERTISE_100); } else if (speed == 10) { control |= IEEE_CTRL_LINKSPEED_10M; /* Dont advertise PHY speed of 1000 Mbps */ XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0); /* Dont advertise PHY speed of 100 Mbps */ XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, ADVERTISE_10); } XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control | IEEE_CTRL_RESET_MASK); { volatile int wait; for (wait=0; wait < 100000; wait++); for (wait=0; wait < 100000; wait++); } return 0; }
static inline void _XLlTemac_PhyReadPage(XLlTemac *InstancePtr, u32 PhyAddress, u32 RegisterNum, u16 *PhyDataPtr, u8 Page) { unsigned long flags; u16 pagetmp; spin_lock_irqsave(&XTE_spinlock, flags); XLlTemac_PhyRead(InstancePtr, PhyAddress, MARVELL_88E1112_PAGE_REG, &pagetmp); XLlTemac_PhyWrite(InstancePtr, PhyAddress, MARVELL_88E1112_PAGE_REG, (pagetmp&0x7f00)|(u16)Page); XLlTemac_PhyRead(InstancePtr, PhyAddress, RegisterNum, PhyDataPtr); XLlTemac_PhyWrite(InstancePtr, PhyAddress, MARVELL_88E1112_PAGE_REG, pagetmp); spin_unlock_irqrestore(&XTE_spinlock, flags); }
unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp) { u16 control; u16 status; u16 partner_capabilities; u16 partner_capabilities_1000; u16 phylinkspeed; u32 phy_addr = detect_phy(xlltemacp); #if 0 XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, ADVERTISE_1000); XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, ADVERTISE_100_AND_10); XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE | IEEE_STAT_AUTONEGOTIATE_RESTART); XLlTemac_PhyWrite(xlltemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control); #endif /* Read PHY control and status registers is successful. */ XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control); XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status); if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status & IEEE_STAT_AUTONEGOTIATE_CAPABLE)) { while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) { XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status); } XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET, &partner_capabilities); if (status & IEEE_STAT_1GBPS_EXTENSIONS) { XLlTemac_PhyRead(xlltemacp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET, &partner_capabilities_1000); if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS) return 1000; } if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS) return 100; if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS) return 10; xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n", __FUNCTION__); return 10; } else { /* Update TEMAC speed accordingly */ if (status & IEEE_STAT_1GBPS_EXTENSIONS) { /* Get commanded link speed */ phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK; switch (phylinkspeed) { case (IEEE_CTRL_LINKSPEED_1000M): return 1000; case (IEEE_CTRL_LINKSPEED_100M): return 100; case (IEEE_CTRL_LINKSPEED_10M): return 10; default: xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n", __FUNCTION__, phylinkspeed); return 10; } } else { return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10; } } }