diff options
author | Dai Haruki <dai.haruki@freescale.com> | 2008-12-16 18:30:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-16 18:30:48 -0500 |
commit | 77ecaf2d5a8bfd548eed3f05c1c2e6573d5de4ba (patch) | |
tree | cb84f04691e26ebf72df6ca8185313194c4cdf90 /drivers/net/gianfar.c | |
parent | 12dea57be552a291e93827baeffbb91e33f587a6 (diff) |
gianfar: Fix VLAN HW feature related frame/buffer size calculation.
Optimize the VLAN checking logic as well.
Signed-off-by: Dai Haruki <dai.haruki@freescale.com>
Acked-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r-- | drivers/net/gianfar.c | 36 |
1 files changed, 21 insertions, 15 deletions
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"); | |||
149 | /* Returns 1 if incoming frames use an FCB */ | 149 | /* Returns 1 if incoming frames use an FCB */ |
150 | static inline int gfar_uses_fcb(struct gfar_private *priv) | 150 | static inline int gfar_uses_fcb(struct gfar_private *priv) |
151 | { | 151 | { |
152 | return (priv->vlan_enable || priv->rx_csum_enable); | 152 | return priv->vlgrp || priv->rx_csum_enable; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int gfar_of_init(struct net_device *dev) | 155 | static int gfar_of_init(struct net_device *dev) |
@@ -376,8 +376,6 @@ static int gfar_probe(struct of_device *ofdev, | |||
376 | dev->vlan_rx_register = gfar_vlan_rx_register; | 376 | dev->vlan_rx_register = gfar_vlan_rx_register; |
377 | 377 | ||
378 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 378 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
379 | |||
380 | priv->vlan_enable = 1; | ||
381 | } | 379 | } |
382 | 380 | ||
383 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { | 381 | if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { |
@@ -1078,9 +1076,6 @@ int startup_gfar(struct net_device *dev) | |||
1078 | rctrl |= RCTRL_EMEN; | 1076 | rctrl |= RCTRL_EMEN; |
1079 | } | 1077 | } |
1080 | 1078 | ||
1081 | if (priv->vlan_enable) | ||
1082 | rctrl |= RCTRL_VLAN; | ||
1083 | |||
1084 | if (priv->padding) { | 1079 | if (priv->padding) { |
1085 | rctrl &= ~RCTRL_PAL_MASK; | 1080 | rctrl &= ~RCTRL_PAL_MASK; |
1086 | rctrl |= RCTRL_PADDING(priv->padding); | 1081 | rctrl |= RCTRL_PADDING(priv->padding); |
@@ -1241,8 +1236,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1241 | gfar_tx_checksum(skb, fcb); | 1236 | gfar_tx_checksum(skb, fcb); |
1242 | } | 1237 | } |
1243 | 1238 | ||
1244 | if (priv->vlan_enable && | 1239 | if (priv->vlgrp && vlan_tx_tag_present(skb)) { |
1245 | unlikely(priv->vlgrp && vlan_tx_tag_present(skb))) { | ||
1246 | if (unlikely(NULL == fcb)) { | 1240 | if (unlikely(NULL == fcb)) { |
1247 | fcb = gfar_add_fcb(skb, txbdp); | 1241 | fcb = gfar_add_fcb(skb, txbdp); |
1248 | status |= TXBD_TOE; | 1242 | status |= TXBD_TOE; |
@@ -1344,11 +1338,15 @@ static void gfar_vlan_rx_register(struct net_device *dev, | |||
1344 | { | 1338 | { |
1345 | struct gfar_private *priv = netdev_priv(dev); | 1339 | struct gfar_private *priv = netdev_priv(dev); |
1346 | unsigned long flags; | 1340 | unsigned long flags; |
1341 | struct vlan_group *old_grp; | ||
1347 | u32 tempval; | 1342 | u32 tempval; |
1348 | 1343 | ||
1349 | spin_lock_irqsave(&priv->rxlock, flags); | 1344 | spin_lock_irqsave(&priv->rxlock, flags); |
1350 | 1345 | ||
1351 | priv->vlgrp = grp; | 1346 | old_grp = priv->vlgrp; |
1347 | |||
1348 | if (old_grp == grp) | ||
1349 | return; | ||
1352 | 1350 | ||
1353 | if (grp) { | 1351 | if (grp) { |
1354 | /* Enable VLAN tag insertion */ | 1352 | /* Enable VLAN tag insertion */ |
@@ -1360,6 +1358,7 @@ static void gfar_vlan_rx_register(struct net_device *dev, | |||
1360 | /* Enable VLAN tag extraction */ | 1358 | /* Enable VLAN tag extraction */ |
1361 | tempval = gfar_read(&priv->regs->rctrl); | 1359 | tempval = gfar_read(&priv->regs->rctrl); |
1362 | tempval |= RCTRL_VLEX; | 1360 | tempval |= RCTRL_VLEX; |
1361 | tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); | ||
1363 | gfar_write(&priv->regs->rctrl, tempval); | 1362 | gfar_write(&priv->regs->rctrl, tempval); |
1364 | } else { | 1363 | } else { |
1365 | /* Disable VLAN tag insertion */ | 1364 | /* Disable VLAN tag insertion */ |
@@ -1370,9 +1369,16 @@ static void gfar_vlan_rx_register(struct net_device *dev, | |||
1370 | /* Disable VLAN tag extraction */ | 1369 | /* Disable VLAN tag extraction */ |
1371 | tempval = gfar_read(&priv->regs->rctrl); | 1370 | tempval = gfar_read(&priv->regs->rctrl); |
1372 | tempval &= ~RCTRL_VLEX; | 1371 | tempval &= ~RCTRL_VLEX; |
1372 | /* If parse is no longer required, then disable parser */ | ||
1373 | if (tempval & RCTRL_REQ_PARSER) | ||
1374 | tempval |= RCTRL_PRSDEP_INIT; | ||
1375 | else | ||
1376 | tempval &= ~RCTRL_PRSDEP_INIT; | ||
1373 | gfar_write(&priv->regs->rctrl, tempval); | 1377 | gfar_write(&priv->regs->rctrl, tempval); |
1374 | } | 1378 | } |
1375 | 1379 | ||
1380 | gfar_change_mtu(dev, dev->mtu); | ||
1381 | |||
1376 | spin_unlock_irqrestore(&priv->rxlock, flags); | 1382 | spin_unlock_irqrestore(&priv->rxlock, flags); |
1377 | } | 1383 | } |
1378 | 1384 | ||
@@ -1383,14 +1389,9 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu) | |||
1383 | int oldsize = priv->rx_buffer_size; | 1389 | int oldsize = priv->rx_buffer_size; |
1384 | int frame_size = new_mtu + ETH_HLEN; | 1390 | int frame_size = new_mtu + ETH_HLEN; |
1385 | 1391 | ||
1386 | if (priv->vlan_enable) | 1392 | if (priv->vlgrp) |
1387 | frame_size += VLAN_HLEN; | 1393 | frame_size += VLAN_HLEN; |
1388 | 1394 | ||
1389 | if (gfar_uses_fcb(priv)) | ||
1390 | frame_size += GMAC_FCB_LEN; | ||
1391 | |||
1392 | frame_size += priv->padding; | ||
1393 | |||
1394 | if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { | 1395 | if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { |
1395 | if (netif_msg_drv(priv)) | 1396 | if (netif_msg_drv(priv)) |
1396 | printk(KERN_ERR "%s: Invalid MTU setting\n", | 1397 | 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 | return -EINVAL; | 1399 | return -EINVAL; |
1399 | } | 1400 | } |
1400 | 1401 | ||
1402 | if (gfar_uses_fcb(priv)) | ||
1403 | frame_size += GMAC_FCB_LEN; | ||
1404 | |||
1405 | frame_size += priv->padding; | ||
1406 | |||
1401 | tempsize = | 1407 | tempsize = |
1402 | (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + | 1408 | (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) + |
1403 | INCREMENTAL_BUFFER_SIZE; | 1409 | INCREMENTAL_BUFFER_SIZE; |