diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index a13eb30..293432f 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -239,6 +239,7 @@ struct fec_enet_private { int mii_timeout; uint phy_speed; phy_interface_t phy_interface; + unsigned phy_type; int link; int full_duplex; struct completion mdio_done; @@ -978,6 +979,17 @@ static int fec_enet_mii_probe(struct net_device *ndev) fep->phy_dev = NULL; + if (fep->phy_type == FEC_PHY_SWITCH) { + fep->link = 1; + netif_carrier_on(ndev); // always up + + fep->full_duplex = 1; // full duplex + + fec_restart(ndev, fep->full_duplex); + + return 0; + } + /* check for attached phy */ for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) { if ((fep->mii_bus->phy_mask & (1 << phy_id))) @@ -1170,8 +1182,20 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) if (!netif_running(ndev)) return -EINVAL; - if (!phydev) - return -ENODEV; + if (!phydev) { + // On i.mx28, this is not necessarily needed + // TODO: remove? + struct mii_ioctl_data *mii_data = if_mii(rq); + + if (cmd == SIOCGMIIREG) + mdiobus_write(fep->mii_bus, mii_data->phy_id, + mii_data->reg_num, mii_data->val_in); + else if (cmd == SIOCSMIIREG) + mii_data->val_out = mdiobus_read(fep->mii_bus, + mii_data->phy_id, mii_data->reg_num); + else return -ENODEV; + return 0; + } return phy_mii_ioctl(phydev, rq, cmd); } @@ -1274,7 +1298,8 @@ fec_enet_open(struct net_device *ndev) fec_enet_free_buffers(ndev); return ret; } - phy_start(fep->phy_dev); + if (fep->phy_type == FEC_PHY_NORMAL) + phy_start(fep->phy_dev); netif_start_queue(ndev); fep->opened = 1; return 0; @@ -1598,6 +1623,9 @@ fec_probe(struct platform_device *pdev) fep->phy_interface = ret; } + if (pdata) + fep->phy_type = pdata->phy_type; + fec_reset_phy(pdev); for (i = 0; i < FEC_IRQ_NUM; i++) { diff --git a/include/linux/fec.h b/include/linux/fec.h index bcff455..701fb2a 100644 --- a/include/linux/fec.h +++ b/include/linux/fec.h @@ -14,10 +14,15 @@ #ifndef __LINUX_FEC_H__ #define __LINUX_FEC_H__ +#define FEC_PHY_NORMAL 0 +#define FEC_PHY_SWITCH 1 +#define FEC_PHY_NONE 2 + #include struct fec_platform_data { phy_interface_t phy; + unsigned phy_type; unsigned char mac[ETH_ALEN]; };