Commit 77ecaf2d authored by Dai Haruki's avatar Dai Haruki Committed by David S. Miller

gianfar: Fix VLAN HW feature related frame/buffer size calculation.

Optimize the VLAN checking logic as well.
Signed-off-by: default avatarDai Haruki <dai.haruki@freescale.com>
Acked-by: default avatarAndy Fleming <afleming@freescale.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 12dea57b
...@@ -149,7 +149,7 @@ MODULE_LICENSE("GPL"); ...@@ -149,7 +149,7 @@ MODULE_LICENSE("GPL");
/* Returns 1 if incoming frames use an FCB */ /* Returns 1 if incoming frames use an FCB */
static inline int gfar_uses_fcb(struct gfar_private *priv) 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) static int gfar_of_init(struct net_device *dev)
...@@ -376,8 +376,6 @@ static int gfar_probe(struct of_device *ofdev, ...@@ -376,8 +376,6 @@ static int gfar_probe(struct of_device *ofdev,
dev->vlan_rx_register = gfar_vlan_rx_register; dev->vlan_rx_register = gfar_vlan_rx_register;
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 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) { if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
...@@ -1078,9 +1076,6 @@ int startup_gfar(struct net_device *dev) ...@@ -1078,9 +1076,6 @@ int startup_gfar(struct net_device *dev)
rctrl |= RCTRL_EMEN; rctrl |= RCTRL_EMEN;
} }
if (priv->vlan_enable)
rctrl |= RCTRL_VLAN;
if (priv->padding) { if (priv->padding) {
rctrl &= ~RCTRL_PAL_MASK; rctrl &= ~RCTRL_PAL_MASK;
rctrl |= RCTRL_PADDING(priv->padding); rctrl |= RCTRL_PADDING(priv->padding);
...@@ -1241,8 +1236,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -1241,8 +1236,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
gfar_tx_checksum(skb, fcb); gfar_tx_checksum(skb, fcb);
} }
if (priv->vlan_enable && if (priv->vlgrp && vlan_tx_tag_present(skb)) {
unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) {
if (unlikely(NULL == fcb)) { if (unlikely(NULL == fcb)) {
fcb = gfar_add_fcb(skb, txbdp); fcb = gfar_add_fcb(skb, txbdp);
status |= TXBD_TOE; status |= TXBD_TOE;
...@@ -1344,11 +1338,15 @@ static void gfar_vlan_rx_register(struct net_device *dev, ...@@ -1344,11 +1338,15 @@ static void gfar_vlan_rx_register(struct net_device *dev,
{ {
struct gfar_private *priv = netdev_priv(dev); struct gfar_private *priv = netdev_priv(dev);
unsigned long flags; unsigned long flags;
struct vlan_group *old_grp;
u32 tempval; u32 tempval;
spin_lock_irqsave(&priv->rxlock, flags); spin_lock_irqsave(&priv->rxlock, flags);
priv->vlgrp = grp; old_grp = priv->vlgrp;
if (old_grp == grp)
return;
if (grp) { if (grp) {
/* Enable VLAN tag insertion */ /* Enable VLAN tag insertion */
...@@ -1360,6 +1358,7 @@ static void gfar_vlan_rx_register(struct net_device *dev, ...@@ -1360,6 +1358,7 @@ static void gfar_vlan_rx_register(struct net_device *dev,
/* Enable VLAN tag extraction */ /* Enable VLAN tag extraction */
tempval = gfar_read(&priv->regs->rctrl); tempval = gfar_read(&priv->regs->rctrl);
tempval |= RCTRL_VLEX; tempval |= RCTRL_VLEX;
tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
gfar_write(&priv->regs->rctrl, tempval); gfar_write(&priv->regs->rctrl, tempval);
} else { } else {
/* Disable VLAN tag insertion */ /* Disable VLAN tag insertion */
...@@ -1370,9 +1369,16 @@ static void gfar_vlan_rx_register(struct net_device *dev, ...@@ -1370,9 +1369,16 @@ static void gfar_vlan_rx_register(struct net_device *dev,
/* Disable VLAN tag extraction */ /* Disable VLAN tag extraction */
tempval = gfar_read(&priv->regs->rctrl); tempval = gfar_read(&priv->regs->rctrl);
tempval &= ~RCTRL_VLEX; 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_write(&priv->regs->rctrl, tempval);
} }
gfar_change_mtu(dev, dev->mtu);
spin_unlock_irqrestore(&priv->rxlock, flags); spin_unlock_irqrestore(&priv->rxlock, flags);
} }
...@@ -1383,14 +1389,9 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1383,14 +1389,9 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
int oldsize = priv->rx_buffer_size; int oldsize = priv->rx_buffer_size;
int frame_size = new_mtu + ETH_HLEN; int frame_size = new_mtu + ETH_HLEN;
if (priv->vlan_enable) if (priv->vlgrp)
frame_size += VLAN_HLEN; 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 ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
if (netif_msg_drv(priv)) if (netif_msg_drv(priv))
printk(KERN_ERR "%s: Invalid MTU setting\n", printk(KERN_ERR "%s: Invalid MTU setting\n",
...@@ -1398,6 +1399,11 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) ...@@ -1398,6 +1399,11 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
return -EINVAL; return -EINVAL;
} }
if (gfar_uses_fcb(priv))
frame_size += GMAC_FCB_LEN;
frame_size += priv->padding;
tempsize = tempsize =
(frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
INCREMENTAL_BUFFER_SIZE; INCREMENTAL_BUFFER_SIZE;
......
...@@ -206,8 +206,10 @@ extern const char gfar_driver_version[]; ...@@ -206,8 +206,10 @@ extern const char gfar_driver_version[];
#define RCTRL_PRSDEP_INIT 0x000000c0 #define RCTRL_PRSDEP_INIT 0x000000c0
#define RCTRL_PROM 0x00000008 #define RCTRL_PROM 0x00000008
#define RCTRL_EMEN 0x00000002 #define RCTRL_EMEN 0x00000002
#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \ #define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \
| RCTRL_TUCSEN | RCTRL_PRSDEP_INIT) RCTRL_TUCSEN)
#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN | RCTRL_TUCSEN | \
RCTRL_PRSDEP_INIT)
#define RCTRL_EXTHASH (RCTRL_GHTX) #define RCTRL_EXTHASH (RCTRL_GHTX)
#define RCTRL_VLAN (RCTRL_PRSDEP_INIT) #define RCTRL_VLAN (RCTRL_PRSDEP_INIT)
#define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK) #define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK)
...@@ -754,8 +756,7 @@ struct gfar_private { ...@@ -754,8 +756,7 @@ struct gfar_private {
phy_interface_t interface; phy_interface_t interface;
char phy_bus_id[BUS_ID_SIZE]; char phy_bus_id[BUS_ID_SIZE];
u32 device_flags; u32 device_flags;
unsigned char vlan_enable:1, unsigned char rx_csum_enable:1,
rx_csum_enable:1,
extended_hash:1, extended_hash:1,
bd_stash_en:1, bd_stash_en:1,
wol_en:1; /* Wake-on-LAN enabled */ wol_en:1; /* Wake-on-LAN enabled */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment