From 77ecaf2d5a8bfd548eed3f05c1c2e6573d5de4ba Mon Sep 17 00:00:00 2001 From: Dai Haruki Date: Tue, 16 Dec 2008 15:30:48 -0800 Subject: gianfar: Fix VLAN HW feature related frame/buffer size calculation. Optimize the VLAN checking logic as well. Signed-off-by: Dai Haruki Acked-by: Andy Fleming Signed-off-by: David S. Miller --- drivers/net/gianfar.c | 36 +++++++++++++++++++++--------------- drivers/net/gianfar.h | 9 +++++---- 2 files changed, 26 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 19fdf93e0ec2..6dc9361495bb 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -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) { @@ -1078,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); @@ -1241,8 +1236,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) 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; @@ -1344,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 */ @@ -1360,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 */ @@ -1370,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); } @@ -1383,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", @@ -1398,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; diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 449f508a5640..1bdb50c7936e 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -206,8 +206,10 @@ extern const char gfar_driver_version[]; #define RCTRL_PRSDEP_INIT 0x000000c0 #define RCTRL_PROM 0x00000008 #define RCTRL_EMEN 0x00000002 -#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \ - | RCTRL_TUCSEN | RCTRL_PRSDEP_INIT) +#define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \ + RCTRL_TUCSEN) +#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN | RCTRL_TUCSEN | \ + RCTRL_PRSDEP_INIT) #define RCTRL_EXTHASH (RCTRL_GHTX) #define RCTRL_VLAN (RCTRL_PRSDEP_INIT) #define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK) @@ -754,8 +756,7 @@ struct gfar_private { phy_interface_t interface; char phy_bus_id[BUS_ID_SIZE]; u32 device_flags; - unsigned char vlan_enable:1, - rx_csum_enable:1, + unsigned char rx_csum_enable:1, extended_hash:1, bd_stash_en:1, wol_en:1; /* Wake-on-LAN enabled */ -- cgit v1.2.2