X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fibm_emac%2Fibm_emac_core.c;h=6482d994d4899aef539f2639bd70703c306d3c90;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=6b0328fbc97be893cd3686f59b3b5c7bdeb04d86;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;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 6b0328fbc..6482d994d 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 @@ -475,8 +475,9 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) out_be32(&emacp->em0stacr, stacr); - while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) - && (count++ < 5000)) + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) udelay(1); MDIO_DEBUG((" (count was %d)\n", count)); @@ -620,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; @@ -912,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; } @@ -1021,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; @@ -1038,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) + mode_reg |= EMAC_M1_RFS_16K; + 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; @@ -1117,6 +1118,7 @@ static int emac_change_mtu(struct net_device *dev, int new_mtu) { struct ocp_enet_private *fep = dev->priv; int old_mtu = dev->mtu; + unsigned long mode_reg; emac_t *emacp = fep->emacp; u32 em0mr0; int i, full; @@ -1159,10 +1161,17 @@ static int emac_change_mtu(struct net_device *dev, int new_mtu) fep->rx_skb[i] = NULL; } - /* Set new rx_buffer_size and advertise new mtu */ - fep->rx_buffer_size = - new_mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE; + /* Set new rx_buffer_size, jumbo cap, and advertise new mtu */ + mode_reg = in_be32(&emacp->em0mr1); + if (new_mtu > ENET_DEF_MTU_SIZE) { + mode_reg |= EMAC_M1_JUMBO_ENABLE; + fep->rx_buffer_size = EMAC_MAX_FRAME; + } else { + mode_reg &= ~EMAC_M1_JUMBO_ENABLE; + fep->rx_buffer_size = ENET_DEF_BUF_SIZE; + } dev->mtu = new_mtu; + out_be32(&emacp->em0mr1, mode_reg); /* Re-init rx skbs */ fep->rx_slot = 0; @@ -1280,7 +1289,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 @@ -1362,6 +1371,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); @@ -1583,7 +1595,7 @@ static struct ethtool_ops emac_ethtool_ops = { static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct ocp_enet_private *fep = dev->priv; - uint *data = (uint *) & rq->ifr_ifru; + uint16_t *data = (uint16_t *) & rq->ifr_ifru; switch (cmd) { case SIOCGMIIPHY: @@ -1699,6 +1711,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; @@ -1881,6 +1902,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);