X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fibm_emac%2Fibm_emac_core.c;h=cac939732d5d4bb766129c152d560ea786e51259;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=2ca3de076ccf7e7cee109621d8a17777d01b8472;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 2ca3de076..cac939732 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -40,9 +40,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -90,23 +90,24 @@ MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n" #define RGMII_PRIV(ocpdev) ((struct ibm_ocp_rgmii*)ocp_get_drvdata(ocpdev)) -static unsigned int rgmii_enable[] = - { RGMII_RTBI, RGMII_RGMII, RGMII_TBI, RGMII_GMII }; +static unsigned int rgmii_enable[] = { + RGMII_RTBI, + RGMII_RGMII, + RGMII_TBI, + RGMII_GMII +}; -static unsigned int rgmii_speed_mask[] = { 0, - 0, +static unsigned int rgmii_speed_mask[] = { RGMII_MII2_SPDMASK, RGMII_MII3_SPDMASK }; -static unsigned int rgmii_speed100[] = { 0, - 0, +static unsigned int rgmii_speed100[] = { RGMII_MII2_100MB, RGMII_MII3_100MB }; -static unsigned int rgmii_speed1000[] = { 0, - 0, +static unsigned int rgmii_speed1000[] = { RGMII_MII2_1000MB, RGMII_MII3_1000MB }; @@ -122,11 +123,21 @@ static unsigned int zmii_enable[][4] = { ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI3)}, {ZMII_SMII3, ZMII_RMII3, ZMII_MII3, ~(ZMII_MDI0 | ZMII_MDI1 | ZMII_MDI2)} }; -static unsigned int mdi_enable[] = - { ZMII_MDI0, ZMII_MDI1, ZMII_MDI2, ZMII_MDI3 }; + +static unsigned int mdi_enable[] = { + ZMII_MDI0, + ZMII_MDI1, + ZMII_MDI2, + ZMII_MDI3 +}; static unsigned int zmii_speed = 0x0; -static unsigned int zmii_speed100[] = { ZMII_MII0_100MB, ZMII_MII1_100MB }; +static unsigned int zmii_speed100[] = { + ZMII_MII0_100MB, + ZMII_MII1_100MB, + ZMII_MII2_100MB, + ZMII_MII3_100MB +}; /* Since multiple EMACs share MDIO lines in various ways, we need * to avoid re-using the same PHY ID in cases where the arch didn't @@ -367,6 +378,7 @@ static void emac_close_zmii(struct ocp_device *ocpdev) int emac_phy_read(struct net_device *dev, int mii_id, int reg) { + int count; uint32_t stacr; struct ocp_enet_private *fep = dev->priv; emac_t *emacp = fep->emacp; @@ -385,9 +397,13 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) emacp = fep->emacp; } - udelay(MDIO_DELAY); + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); - if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) { + if ((stacr & EMAC_STACR_OC) == 0) { printk(KERN_WARNING "%s: PHY read timeout #1!\n", dev->name); return -1; } @@ -398,8 +414,11 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) out_be32(&emacp->em0stacr, stacr); - udelay(MDIO_DELAY); - stacr = in_be32(&emacp->em0stacr); + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); if ((stacr & EMAC_STACR_OC) == 0) { printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name); @@ -419,6 +438,7 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) { + int count; uint32_t stacr; struct ocp_enet_private *fep = dev->priv; emac_t *emacp = fep->emacp; @@ -437,9 +457,13 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) emacp = fep->emacp; } - udelay(MDIO_DELAY); + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); - if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) { + if ((stacr & EMAC_STACR_OC) == 0) { printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); return; } @@ -451,9 +475,13 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) out_be32(&emacp->em0stacr, stacr); - udelay(MDIO_DELAY); + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); - if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) + if ((stacr & EMAC_STACR_OC) == 0) printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); /* Check for a write error */ @@ -593,7 +621,7 @@ emac_rx_csum(struct net_device *dev, unsigned short ctrl, struct sk_buff *skb) static int emac_rx_clean(struct net_device *dev) { - int i, b, bnum, buf[6]; + int i, b, bnum = 0, buf[6]; int error, frame_length; struct ocp_enet_private *fep = dev->priv; unsigned short ctrl; @@ -885,7 +913,6 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) PKT_DEBUG(("emac_start_xmit() stopping queue\n")); netif_stop_queue(dev); spin_unlock_irqrestore(&fep->lock, flags); - restore_flags(flags); return -EBUSY; } @@ -994,7 +1021,6 @@ static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev) static int emac_adjust_to_link(struct ocp_enet_private *fep) { emac_t *emacp = fep->emacp; - struct ibm_ocp_rgmii *rgmii; unsigned long mode_reg; int full_duplex, speed; @@ -1011,21 +1037,23 @@ static int emac_adjust_to_link(struct ocp_enet_private *fep) speed = fep->phy_mii.speed; } - if (fep->rgmii_dev) - rgmii = RGMII_PRIV(fep->rgmii_dev); /* set speed (default is 10Mb) */ switch (speed) { case SPEED_1000: mode_reg |= EMAC_M1_JUMBO_ENABLE | EMAC_M1_RFS_16K; - if ((rgmii->mode[fep->rgmii_input] == RTBI) - || (rgmii->mode[fep->rgmii_input] == TBI)) - mode_reg |= EMAC_M1_MF_1000GPCS; - else - mode_reg |= EMAC_M1_MF_1000MBPS; - if (fep->rgmii_dev) + if (fep->rgmii_dev) { + struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev); + + if ((rgmii->mode[fep->rgmii_input] == RTBI) + || (rgmii->mode[fep->rgmii_input] == TBI)) + mode_reg |= EMAC_M1_MF_1000GPCS; + else + mode_reg |= EMAC_M1_MF_1000MBPS; + emac_rgmii_port_speed(fep->rgmii_dev, fep->rgmii_input, 1000); + } break; case SPEED_100: mode_reg |= EMAC_M1_MF_100MBPS | EMAC_M1_RFS_4K; @@ -1253,7 +1281,7 @@ static void emac_init_rings(struct net_device *dev) /* Format the receive descriptor ring. */ ep->rx_slot = 0; /* Default is MTU=1500 + Ethernet overhead */ - ep->rx_buffer_size = ENET_DEF_BUF_SIZE; + ep->rx_buffer_size = dev->mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE; emac_rx_fill(dev, 0); if (ep->rx_slot != 0) { printk(KERN_ERR @@ -1335,6 +1363,9 @@ static void emac_reset_configure(struct ocp_enet_private *fep) /* set frame gap */ out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP); + + /* set VLAN Tag Protocol Identifier */ + out_be32(&emacp->em0vtpid, 0x8100); /* Init ring buffers */ emac_init_rings(fep->ndev); @@ -1672,6 +1703,15 @@ struct mal_commac_ops emac_commac_ops = { .rxde = &emac_rxde_dev, }; +#ifdef CONFIG_NET_POLL_CONTROLLER +static int emac_netpoll(struct net_device *ndev) +{ + emac_rxeob_dev((void *)ndev, 0); + emac_txeob_dev((void *)ndev, 0); + return 0; +} +#endif + static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal) { int deferred_init = 0; @@ -1854,6 +1894,9 @@ static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal) SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); if (emacdata->tah_idx >= 0) ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG; +#ifdef CONFIG_NET_POLL_CONTROLLER + ndev->poll_controller = emac_netpoll; +#endif SET_MODULE_OWNER(ndev); @@ -1940,8 +1983,6 @@ static struct ocp_driver emac_driver = { static int __init emac_init(void) { - int rc; - printk(KERN_INFO DRV_NAME ": " DRV_DESC ", version " DRV_VERSION "\n"); printk(KERN_INFO "Maintained by " DRV_AUTHOR "\n"); @@ -1950,13 +1991,8 @@ static int __init emac_init(void) skb_res); skb_res = 2; } - rc = ocp_register_driver(&emac_driver); - if (rc < 0) { - ocp_unregister_driver(&emac_driver); - return -ENODEV; - } - return 0; + return ocp_register_driver(&emac_driver); } static void __exit emac_exit(void)