]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/gianfar.c
gianfar: Fix VLAN HW feature related frame/buffer size calculation.
[linux-2.6-omap-h63xx.git] / drivers / net / gianfar.c
index 7398704c4b55acfa5dc48771598744ddc57cfa4a..6dc9361495bbbda246b5155c36ac6d902d41507e 100644 (file)
@@ -149,7 +149,7 @@ MODULE_LICENSE("GPL");
 /* Returns 1 if incoming frames use an FCB */
 static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
-       return (priv->vlan_enable || priv->rx_csum_enable);
+       return priv->vlgrp || priv->rx_csum_enable;
 }
 
 static int gfar_of_init(struct net_device *dev)
@@ -376,8 +376,6 @@ static int gfar_probe(struct of_device *ofdev,
                dev->vlan_rx_register = gfar_vlan_rx_register;
 
                dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-
-               priv->vlan_enable = 1;
        }
 
        if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
@@ -428,11 +426,9 @@ static int gfar_probe(struct of_device *ofdev,
        priv->rx_ring_size = DEFAULT_RX_RING_SIZE;
 
        priv->txcoalescing = DEFAULT_TX_COALESCE;
-       priv->txcount = DEFAULT_TXCOUNT;
-       priv->txtime = DEFAULT_TXTIME;
+       priv->txic = DEFAULT_TXIC;
        priv->rxcoalescing = DEFAULT_RX_COALESCE;
-       priv->rxcount = DEFAULT_RXCOUNT;
-       priv->rxtime = DEFAULT_RXTIME;
+       priv->rxic = DEFAULT_RXIC;
 
        /* Enable most messages by default */
        priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
@@ -894,6 +890,8 @@ void gfar_start(struct net_device *dev)
 
        /* Unmask the interrupts we look for */
        gfar_write(&regs->imask, IMASK_DEFAULT);
+
+       dev->trans_start = jiffies;
 }
 
 /* Bring the controller up and running */
@@ -1060,17 +1058,13 @@ int startup_gfar(struct net_device *dev)
        phy_start(priv->phydev);
 
        /* Configure the coalescing support */
+       gfar_write(&regs->txic, 0);
        if (priv->txcoalescing)
-               gfar_write(&regs->txic,
-                          mk_ic_value(priv->txcount, priv->txtime));
-       else
-               gfar_write(&regs->txic, 0);
+               gfar_write(&regs->txic, priv->txic);
 
+       gfar_write(&regs->rxic, 0);
        if (priv->rxcoalescing)
-               gfar_write(&regs->rxic,
-                          mk_ic_value(priv->rxcount, priv->rxtime));
-       else
-               gfar_write(&regs->rxic, 0);
+               gfar_write(&regs->rxic, priv->rxic);
 
        if (priv->rx_csum_enable)
                rctrl |= RCTRL_CHECKSUMMING;
@@ -1082,9 +1076,6 @@ int startup_gfar(struct net_device *dev)
                rctrl |= RCTRL_EMEN;
        }
 
-       if (priv->vlan_enable)
-               rctrl |= RCTRL_VLAN;
-
        if (priv->padding) {
                rctrl &= ~RCTRL_PAL_MASK;
                rctrl |= RCTRL_PADDING(priv->padding);
@@ -1239,15 +1230,13 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
        status = txbdp->status & TXBD_WRAP;
 
        /* Set up checksumming */
-       if (likely((dev->features & NETIF_F_IP_CSUM)
-                       && (CHECKSUM_PARTIAL == skb->ip_summed))) {
+       if (CHECKSUM_PARTIAL == skb->ip_summed) {
                fcb = gfar_add_fcb(skb, txbdp);
                status |= TXBD_TOE;
                gfar_tx_checksum(skb, fcb);
        }
 
-       if (priv->vlan_enable &&
-                       unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
+       if (priv->vlgrp && vlan_tx_tag_present(skb)) {
                if (unlikely(NULL == fcb)) {
                        fcb = gfar_add_fcb(skb, txbdp);
                        status |= TXBD_TOE;
@@ -1349,11 +1338,15 @@ static void gfar_vlan_rx_register(struct net_device *dev,
 {
        struct gfar_private *priv = netdev_priv(dev);
        unsigned long flags;
+       struct vlan_group *old_grp;
        u32 tempval;
 
        spin_lock_irqsave(&priv->rxlock, flags);
 
-       priv->vlgrp = grp;
+       old_grp = priv->vlgrp;
+
+       if (old_grp == grp)
+               return;
 
        if (grp) {
                /* Enable VLAN tag insertion */
@@ -1365,6 +1358,7 @@ static void gfar_vlan_rx_register(struct net_device *dev,
                /* Enable VLAN tag extraction */
                tempval = gfar_read(&priv->regs->rctrl);
                tempval |= RCTRL_VLEX;
+               tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
                gfar_write(&priv->regs->rctrl, tempval);
        } else {
                /* Disable VLAN tag insertion */
@@ -1375,9 +1369,16 @@ static void gfar_vlan_rx_register(struct net_device *dev,
                /* Disable VLAN tag extraction */
                tempval = gfar_read(&priv->regs->rctrl);
                tempval &= ~RCTRL_VLEX;
+               /* If parse is no longer required, then disable parser */
+               if (tempval & RCTRL_REQ_PARSER)
+                       tempval |= RCTRL_PRSDEP_INIT;
+               else
+                       tempval &= ~RCTRL_PRSDEP_INIT;
                gfar_write(&priv->regs->rctrl, tempval);
        }
 
+       gfar_change_mtu(dev, dev->mtu);
+
        spin_unlock_irqrestore(&priv->rxlock, flags);
 }
 
@@ -1388,14 +1389,9 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
        int oldsize = priv->rx_buffer_size;
        int frame_size = new_mtu + ETH_HLEN;
 
-       if (priv->vlan_enable)
+       if (priv->vlgrp)
                frame_size += VLAN_HLEN;
 
-       if (gfar_uses_fcb(priv))
-               frame_size += GMAC_FCB_LEN;
-
-       frame_size += priv->padding;
-
        if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
                if (netif_msg_drv(priv))
                        printk(KERN_ERR "%s: Invalid MTU setting\n",
@@ -1403,6 +1399,11 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
                return -EINVAL;
        }
 
+       if (gfar_uses_fcb(priv))
+               frame_size += GMAC_FCB_LEN;
+
+       frame_size += priv->padding;
+
        tempsize =
            (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
            INCREMENTAL_BUFFER_SIZE;
@@ -1538,8 +1539,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id)
        /* Otherwise, clear it */
        if (likely(priv->txcoalescing)) {
                gfar_write(&priv->regs->txic, 0);
-               gfar_write(&priv->regs->txic,
-                          mk_ic_value(priv->txcount, priv->txtime));
+               gfar_write(&priv->regs->txic, priv->txic);
        }
 
        spin_unlock(&priv->txlock);
@@ -1825,8 +1825,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
                /* Otherwise, clear it */
                if (likely(priv->rxcoalescing)) {
                        gfar_write(&priv->regs->rxic, 0);
-                       gfar_write(&priv->regs->rxic,
-                                  mk_ic_value(priv->rxcount, priv->rxtime));
+                       gfar_write(&priv->regs->rxic, priv->rxic);
                }
        }