aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/gianfar.c
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-07-20 00:54:19 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-21 16:47:55 -0400
commit87c288c6e9aa31720b72e2bc2d665e24e1653c3e (patch)
tree18706b96ee67715b400868da1da3a46fff5e596e /drivers/net/gianfar.c
parent6ede746b62627b6f03fe88afad1a07d38917b85d (diff)
gianfar: do vlan cleanup
- unify vlan and nonvlan rx path - kill priv->vlgrp and gfar_vlan_rx_register - allow to turn on/off rx/tx vlan accel via ethtool Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r--drivers/net/gianfar.c55
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index d265c6e13873..835cd2588148 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -140,8 +140,6 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
140static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); 140static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
141static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, 141static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
142 int amount_pull); 142 int amount_pull);
143static void gfar_vlan_rx_register(struct net_device *netdev,
144 struct vlan_group *grp);
145void gfar_halt(struct net_device *dev); 143void gfar_halt(struct net_device *dev);
146static void gfar_halt_nodisable(struct net_device *dev); 144static void gfar_halt_nodisable(struct net_device *dev);
147void gfar_start(struct net_device *dev); 145void gfar_start(struct net_device *dev);
@@ -391,10 +389,11 @@ static void gfar_init_mac(struct net_device *ndev)
391 rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; 389 rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE;
392 390
393 /* keep vlan related bits if it's enabled */ 391 /* keep vlan related bits if it's enabled */
394 if (priv->vlgrp) { 392 if (ndev->features & NETIF_F_HW_VLAN_TX)
395 rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; 393 rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
394
395 if (ndev->features & NETIF_F_HW_VLAN_RX)
396 tctrl |= TCTRL_VLINS; 396 tctrl |= TCTRL_VLINS;
397 }
398 397
399 /* Init rctrl based on our settings */ 398 /* Init rctrl based on our settings */
400 gfar_write(&regs->rctrl, rctrl); 399 gfar_write(&regs->rctrl, rctrl);
@@ -467,7 +466,6 @@ static const struct net_device_ops gfar_netdev_ops = {
467 .ndo_tx_timeout = gfar_timeout, 466 .ndo_tx_timeout = gfar_timeout,
468 .ndo_do_ioctl = gfar_ioctl, 467 .ndo_do_ioctl = gfar_ioctl,
469 .ndo_get_stats = gfar_get_stats, 468 .ndo_get_stats = gfar_get_stats,
470 .ndo_vlan_rx_register = gfar_vlan_rx_register,
471 .ndo_set_mac_address = eth_mac_addr, 469 .ndo_set_mac_address = eth_mac_addr,
472 .ndo_validate_addr = eth_validate_addr, 470 .ndo_validate_addr = eth_validate_addr,
473#ifdef CONFIG_NET_POLL_CONTROLLER 471#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -507,10 +505,17 @@ void unlock_tx_qs(struct gfar_private *priv)
507 spin_unlock(&priv->tx_queue[i]->txlock); 505 spin_unlock(&priv->tx_queue[i]->txlock);
508} 506}
509 507
508static bool gfar_is_vlan_on(struct gfar_private *priv)
509{
510 return (priv->ndev->features & NETIF_F_HW_VLAN_RX) ||
511 (priv->ndev->features & NETIF_F_HW_VLAN_TX);
512}
513
510/* Returns 1 if incoming frames use an FCB */ 514/* Returns 1 if incoming frames use an FCB */
511static inline int gfar_uses_fcb(struct gfar_private *priv) 515static inline int gfar_uses_fcb(struct gfar_private *priv)
512{ 516{
513 return priv->vlgrp || (priv->ndev->features & NETIF_F_RXCSUM) || 517 return gfar_is_vlan_on(priv) ||
518 (priv->ndev->features & NETIF_F_RXCSUM) ||
514 (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER); 519 (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER);
515} 520}
516 521
@@ -1038,10 +1043,10 @@ static int gfar_probe(struct platform_device *ofdev)
1038 NETIF_F_RXCSUM | NETIF_F_HIGHDMA; 1043 NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
1039 } 1044 }
1040 1045
1041 priv->vlgrp = NULL; 1046 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN) {
1042 1047 dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1043 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_VLAN)
1044 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 1048 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1049 }
1045 1050
1046 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) { 1051 if (priv->device_flags & FSL_GIANFAR_DEV_HAS_EXTENDED_HASH) {
1047 priv->extended_hash = 1; 1052 priv->extended_hash = 1;
@@ -2304,10 +2309,8 @@ void gfar_check_rx_parser_mode(struct gfar_private *priv)
2304 gfar_write(&regs->rctrl, tempval); 2309 gfar_write(&regs->rctrl, tempval);
2305} 2310}
2306 2311
2307
2308/* Enables and disables VLAN insertion/extraction */ 2312/* Enables and disables VLAN insertion/extraction */
2309static void gfar_vlan_rx_register(struct net_device *dev, 2313void gfar_vlan_mode(struct net_device *dev, u32 features)
2310 struct vlan_group *grp)
2311{ 2314{
2312 struct gfar_private *priv = netdev_priv(dev); 2315 struct gfar_private *priv = netdev_priv(dev);
2313 struct gfar __iomem *regs = NULL; 2316 struct gfar __iomem *regs = NULL;
@@ -2318,25 +2321,24 @@ static void gfar_vlan_rx_register(struct net_device *dev,
2318 local_irq_save(flags); 2321 local_irq_save(flags);
2319 lock_rx_qs(priv); 2322 lock_rx_qs(priv);
2320 2323
2321 priv->vlgrp = grp; 2324 if (features & NETIF_F_HW_VLAN_TX) {
2322
2323 if (grp) {
2324 /* Enable VLAN tag insertion */ 2325 /* Enable VLAN tag insertion */
2325 tempval = gfar_read(&regs->tctrl); 2326 tempval = gfar_read(&regs->tctrl);
2326 tempval |= TCTRL_VLINS; 2327 tempval |= TCTRL_VLINS;
2327
2328 gfar_write(&regs->tctrl, tempval); 2328 gfar_write(&regs->tctrl, tempval);
2329
2330 /* Enable VLAN tag extraction */
2331 tempval = gfar_read(&regs->rctrl);
2332 tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
2333 gfar_write(&regs->rctrl, tempval);
2334 } else { 2329 } else {
2335 /* Disable VLAN tag insertion */ 2330 /* Disable VLAN tag insertion */
2336 tempval = gfar_read(&regs->tctrl); 2331 tempval = gfar_read(&regs->tctrl);
2337 tempval &= ~TCTRL_VLINS; 2332 tempval &= ~TCTRL_VLINS;
2338 gfar_write(&regs->tctrl, tempval); 2333 gfar_write(&regs->tctrl, tempval);
2334 }
2339 2335
2336 if (features & NETIF_F_HW_VLAN_RX) {
2337 /* Enable VLAN tag extraction */
2338 tempval = gfar_read(&regs->rctrl);
2339 tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
2340 gfar_write(&regs->rctrl, tempval);
2341 } else {
2340 /* Disable VLAN tag extraction */ 2342 /* Disable VLAN tag extraction */
2341 tempval = gfar_read(&regs->rctrl); 2343 tempval = gfar_read(&regs->rctrl);
2342 tempval &= ~RCTRL_VLEX; 2344 tempval &= ~RCTRL_VLEX;
@@ -2359,7 +2361,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
2359 int oldsize = priv->rx_buffer_size; 2361 int oldsize = priv->rx_buffer_size;
2360 int frame_size = new_mtu + ETH_HLEN; 2362 int frame_size = new_mtu + ETH_HLEN;
2361 2363
2362 if (priv->vlgrp) 2364 if (gfar_is_vlan_on(priv))
2363 frame_size += VLAN_HLEN; 2365 frame_size += VLAN_HLEN;
2364 2366
2365 if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) { 2367 if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
@@ -2712,11 +2714,12 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
2712 /* Tell the skb what kind of packet this is */ 2714 /* Tell the skb what kind of packet this is */
2713 skb->protocol = eth_type_trans(skb, dev); 2715 skb->protocol = eth_type_trans(skb, dev);
2714 2716
2717 /* Set vlan tag */
2718 if (fcb->flags & RXFCB_VLN)
2719 __vlan_hwaccel_put_tag(skb, fcb->vlctl);
2720
2715 /* Send the packet up the stack */ 2721 /* Send the packet up the stack */
2716 if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) 2722 ret = netif_receive_skb(skb);
2717 ret = vlan_hwaccel_receive_skb(skb, priv->vlgrp, fcb->vlctl);
2718 else
2719 ret = netif_receive_skb(skb);
2720 2723
2721 if (NET_RX_DROP == ret) 2724 if (NET_RX_DROP == ret)
2722 priv->extra_stats.kernel_dropped++; 2725 priv->extra_stats.kernel_dropped++;