mxc_fec_set_mac_address(hw_reg, enaddr);
priv->tx_busy = 0;
- mxc_fec_reg_write(hw_reg, rdar, mxc_fec_reg_read(hw_reg, rdar) | FEC_RX_TX_ACTIVE);
- mxc_fec_reg_write(hw_reg, ecr, mxc_fec_reg_read(hw_reg, ecr) | FEC_ETHER_EN);
+ mxc_fec_reg_write(hw_reg, rdar, FEC_RX_TX_ACTIVE);
+ mxc_fec_reg_write(hw_reg, ecr, FEC_ETHER_EN);
}
/*!
#ifdef CYGPKG_DEVS_ETH_PHY
unsigned short value;
value = _eth_phy_state(priv->phy);
+ if (value & ETH_PHY_STAT_LINK) {
+ mxc_fec_phy_status(priv, value, true);
+ }
#else
unsigned short value;
mxc_fec_mii_read(hw_reg, priv->phy_addr, 1, &value);
-#endif
if (value & PHY_STATUS_LINK_ST) {
- if (!(priv->status & FEC_STATUS_LINK_ON)) {
- mxc_fec_phy_status(priv, value, true);
- }
- } else {
- if (priv->status & FEC_STATUS_LINK_ON) {
- mxc_fec_phy_status(priv, value, true);
- }
+ mxc_fec_phy_status(priv, 0, true);
}
+#endif
}
return priv->status & FEC_STATUS_LINK_ON;
p++;
}
priv->rx_cur = p;
- mxc_fec_reg_write(hw_reg, rdar, mxc_fec_reg_read(hw_reg, rdar) | FEC_RX_TX_ACTIVE);
+ mxc_fec_reg_write(hw_reg, rdar, FEC_RX_TX_ACTIVE);
}
}
#ifdef CYGPKG_DEVS_ETH_PHY
unsigned short value;
value = _eth_phy_state(priv->phy);
+ if (!(value & ETH_PHY_STAT_LINK) ^
+ !(priv->status & FEC_STATUS_LINK_ON)) {
+ mxc_fec_phy_status(priv, value, true);
+ }
#else
unsigned short value;
mxc_fec_mii_read(hw_reg, priv->phy_addr, 1, &value);
+ if (!(value & PHY_STATUS_LINK_ST) ^
+ !(priv->status & FEC_STATUS_LINK_ON)) {
+ mxc_fec_phy_status(priv, 0, true);
+ }
#endif
last_poll = 0;
- if (value & PHY_STATUS_LINK_ST) {
- if (!(priv->status & FEC_STATUS_LINK_ON)) {
- mxc_fec_phy_status(priv, value, true);
- }
- } else {
- if (priv->status & FEC_STATUS_LINK_ON) {
- mxc_fec_phy_status(priv, value, true);
- }
- }
}
}
unsigned long ipg_clk;
unsigned long clkdiv;
- mxc_fec_reg_write(hw_reg, ecr, mxc_fec_reg_read(hw_reg, ecr) | FEC_RESET);
+ mxc_fec_reg_write(hw_reg, ecr, FEC_RESET);
while (mxc_fec_reg_read(hw_reg, ecr) & FEC_RESET) {
hal_delay_us(FEC_COMMON_TICK);
}
/* must be done before enabling the MII gasket
* (otherwise MIIGSK_ENR_READY will never assert)
*/
- mxc_fec_reg_write(hw_reg, ecr, mxc_fec_reg_read(hw_reg, ecr) | FEC_ETHER_EN);
+ mxc_fec_reg_write(hw_reg, ecr, FEC_ETHER_EN);
}
static void mxc_fec_phy_status(mxc_fec_priv_t *dev, unsigned short value, bool show)
{
+ int changed = 0;
#ifdef CYGPKG_DEVS_ETH_PHY
if (value & ETH_PHY_STAT_LINK) {
- int changed = !(dev->status & FEC_STATUS_LINK_ON);
-
+ changed = !(dev->status & FEC_STATUS_LINK_ON);
dev->status |= FEC_STATUS_LINK_ON;
if (value & ETH_PHY_STAT_FDX) {
dev->status |= FEC_STATUS_FULL_DPLX;
changed |= !!(dev->status & ETH_PHY_STAT_100MB);
dev->status &= ~FEC_STATUS_100M;
}
- if (changed) {
- mxc_fec_mii_setup(dev);
- }
} else {
+ changed = !!(dev->status & FEC_STATUS_LINK_ON);
dev->status &= ~FEC_STATUS_LINK_ON;
}
#else
- int changed = 0;
mxc_fec_mii_read(dev->hw_reg, dev->phy_addr, PHY_STATUS_REG, &value);
if (value & PHY_STATUS_LINK_ST) {
changed |= !(dev->status & FEC_STATUS_LINK_ON);
changed |= dev->status & FEC_STATUS_100M;
dev->status &= ~FEC_STATUS_100M;
}
+#endif
if (changed) {
+ if (dev->status & FEC_STATUS_FULL_DPLX) {
+ mxc_fec_reg_write(dev->hw_reg, tcr,
+ (mxc_fec_reg_read(dev->hw_reg, tcr) & ~FEC_TCR_HBC) |
+ FEC_TCR_FDEN);
+ mxc_fec_reg_write(dev->hw_reg, rcr,
+ (mxc_fec_reg_read(dev->hw_reg, rcr) & ~FEC_RCR_DRT) |
+ FEC_RCR_FCE);
+ } else {
+ mxc_fec_reg_write(dev->hw_reg, tcr,
+ (mxc_fec_reg_read(dev->hw_reg, tcr) & ~FEC_TCR_FDEN) |
+ FEC_TCR_HBC);
+ mxc_fec_reg_write(dev->hw_reg, rcr,
+ (mxc_fec_reg_read(dev->hw_reg, rcr) & ~FEC_RCR_FCE) |
+ FEC_RCR_DRT);
+ }
mxc_fec_mii_setup(dev);
}
-#endif
- if (!show) {
+ if (!show || !changed) {
return;
}
if (dev->status & FEC_STATUS_LINK_ON) {
unsigned short value = 0;
unsigned long timeout = FEC_COMMON_TIMEOUT;
- /*Reset PHY*/
+ /* Reset PHY */
mxc_fec_mii_write(dev->hw_reg, dev->phy_addr, PHY_CTRL_REG, PHY_CTRL_RESET);
while (timeout--) {
if (mxc_fec_mii_read(dev->hw_reg, dev->phy_addr, PHY_CTRL_REG, &value)) {
}
#endif
diag_printf("FEC: [ %s ] [ %s ] [ %s ]:\n",
- (dev->status&FEC_STATUS_FULL_DPLX)?"FULL_DUPLEX":"HALF_DUPLEX",
- (dev->status&FEC_STATUS_LINK_ON)?"connected":"disconnected",
- (dev->status&FEC_STATUS_100M)?"100M bps":"10M bps");
+ (dev->status & FEC_STATUS_FULL_DPLX) ? "FULL_DUPLEX" : "HALF_DUPLEX",
+ (dev->status & FEC_STATUS_LINK_ON) ? "connected" : "disconnected",
+ (dev->status & FEC_STATUS_100M) ? "100M bps" : "10M bps");
#endif
return true;
}