aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDai Haruki <dai.haruki@freescale.com>2008-12-16 18:30:48 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-16 18:30:48 -0500
commit77ecaf2d5a8bfd548eed3f05c1c2e6573d5de4ba (patch)
treecb84f04691e26ebf72df6ca8185313194c4cdf90
parent12dea57be552a291e93827baeffbb91e33f587a6 (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>
-rw-r--r--drivers/net/gianfar.c36
-rw-r--r--drivers/net/gianfar.h9
2 files changed, 26 insertions, 19 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 */
150static inline int gfar_uses_fcb(struct gfar_private *priv) 150static 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
155static int gfar_of_init(struct net_device *dev) 155static 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;
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[];
206#define RCTRL_PRSDEP_INIT 0x000000c0 206#define RCTRL_PRSDEP_INIT 0x000000c0
207#define RCTRL_PROM 0x00000008 207#define RCTRL_PROM 0x00000008
208#define RCTRL_EMEN 0x00000002 208#define RCTRL_EMEN 0x00000002
209#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN \ 209#define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \
210 | RCTRL_TUCSEN | RCTRL_PRSDEP_INIT) 210 RCTRL_TUCSEN)
211#define RCTRL_CHECKSUMMING (RCTRL_IPCSEN | RCTRL_TUCSEN | \
212 RCTRL_PRSDEP_INIT)
211#define RCTRL_EXTHASH (RCTRL_GHTX) 213#define RCTRL_EXTHASH (RCTRL_GHTX)
212#define RCTRL_VLAN (RCTRL_PRSDEP_INIT) 214#define RCTRL_VLAN (RCTRL_PRSDEP_INIT)
213#define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK) 215#define RCTRL_PADDING(x) ((x << 16) & RCTRL_PAL_MASK)
@@ -754,8 +756,7 @@ struct gfar_private {
754 phy_interface_t interface; 756 phy_interface_t interface;
755 char phy_bus_id[BUS_ID_SIZE]; 757 char phy_bus_id[BUS_ID_SIZE];
756 u32 device_flags; 758 u32 device_flags;
757 unsigned char vlan_enable:1, 759 unsigned char rx_csum_enable:1,
758 rx_csum_enable:1,
759 extended_hash:1, 760 extended_hash:1,
760 bd_stash_en:1, 761 bd_stash_en:1,
761 wol_en:1; /* Wake-on-LAN enabled */ 762 wol_en:1; /* Wake-on-LAN enabled */