diff options
author | Jiri Pirko <jpirko@redhat.com> | 2011-07-20 00:54:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-07-21 16:47:55 -0400 |
commit | 87c288c6e9aa31720b72e2bc2d665e24e1653c3e (patch) | |
tree | 18706b96ee67715b400868da1da3a46fff5e596e /drivers | |
parent | 6ede746b62627b6f03fe88afad1a07d38917b85d (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')
-rw-r--r-- | drivers/net/gianfar.c | 55 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 3 | ||||
-rw-r--r-- | drivers/net/gianfar_ethtool.c | 3 |
3 files changed, 33 insertions, 28 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); | |||
140 | static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); | 140 | static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue); |
141 | static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, | 141 | static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, |
142 | int amount_pull); | 142 | int amount_pull); |
143 | static void gfar_vlan_rx_register(struct net_device *netdev, | ||
144 | struct vlan_group *grp); | ||
145 | void gfar_halt(struct net_device *dev); | 143 | void gfar_halt(struct net_device *dev); |
146 | static void gfar_halt_nodisable(struct net_device *dev); | 144 | static void gfar_halt_nodisable(struct net_device *dev); |
147 | void gfar_start(struct net_device *dev); | 145 | void 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(®s->rctrl, rctrl); | 399 | gfar_write(®s->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 | ||
508 | static 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 */ |
511 | static inline int gfar_uses_fcb(struct gfar_private *priv) | 515 | static 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(®s->rctrl, tempval); | 2309 | gfar_write(®s->rctrl, tempval); |
2305 | } | 2310 | } |
2306 | 2311 | ||
2307 | |||
2308 | /* Enables and disables VLAN insertion/extraction */ | 2312 | /* Enables and disables VLAN insertion/extraction */ |
2309 | static void gfar_vlan_rx_register(struct net_device *dev, | 2313 | void 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(®s->tctrl); | 2326 | tempval = gfar_read(®s->tctrl); |
2326 | tempval |= TCTRL_VLINS; | 2327 | tempval |= TCTRL_VLINS; |
2327 | |||
2328 | gfar_write(®s->tctrl, tempval); | 2328 | gfar_write(®s->tctrl, tempval); |
2329 | |||
2330 | /* Enable VLAN tag extraction */ | ||
2331 | tempval = gfar_read(®s->rctrl); | ||
2332 | tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); | ||
2333 | gfar_write(®s->rctrl, tempval); | ||
2334 | } else { | 2329 | } else { |
2335 | /* Disable VLAN tag insertion */ | 2330 | /* Disable VLAN tag insertion */ |
2336 | tempval = gfar_read(®s->tctrl); | 2331 | tempval = gfar_read(®s->tctrl); |
2337 | tempval &= ~TCTRL_VLINS; | 2332 | tempval &= ~TCTRL_VLINS; |
2338 | gfar_write(®s->tctrl, tempval); | 2333 | gfar_write(®s->tctrl, tempval); |
2334 | } | ||
2339 | 2335 | ||
2336 | if (features & NETIF_F_HW_VLAN_RX) { | ||
2337 | /* Enable VLAN tag extraction */ | ||
2338 | tempval = gfar_read(®s->rctrl); | ||
2339 | tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT); | ||
2340 | gfar_write(®s->rctrl, tempval); | ||
2341 | } else { | ||
2340 | /* Disable VLAN tag extraction */ | 2342 | /* Disable VLAN tag extraction */ |
2341 | tempval = gfar_read(®s->rctrl); | 2343 | tempval = gfar_read(®s->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++; |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 87c1d8608b73..9aa43773e8e3 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -1077,8 +1077,6 @@ struct gfar_private { | |||
1077 | 1077 | ||
1078 | struct sk_buff_head rx_recycle; | 1078 | struct sk_buff_head rx_recycle; |
1079 | 1079 | ||
1080 | struct vlan_group *vlgrp; | ||
1081 | |||
1082 | /* RX queue filer rule set*/ | 1080 | /* RX queue filer rule set*/ |
1083 | struct ethtool_rx_list rx_list; | 1081 | struct ethtool_rx_list rx_list; |
1084 | struct mutex rx_queue_access; | 1082 | struct mutex rx_queue_access; |
@@ -1183,6 +1181,7 @@ extern void gfar_configure_coalescing(struct gfar_private *priv, | |||
1183 | void gfar_init_sysfs(struct net_device *dev); | 1181 | void gfar_init_sysfs(struct net_device *dev); |
1184 | int gfar_set_features(struct net_device *dev, u32 features); | 1182 | int gfar_set_features(struct net_device *dev, u32 features); |
1185 | extern void gfar_check_rx_parser_mode(struct gfar_private *priv); | 1183 | extern void gfar_check_rx_parser_mode(struct gfar_private *priv); |
1184 | extern void gfar_vlan_mode(struct net_device *dev, u32 features); | ||
1186 | 1185 | ||
1187 | extern const struct ethtool_ops gfar_ethtool_ops; | 1186 | extern const struct ethtool_ops gfar_ethtool_ops; |
1188 | 1187 | ||
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 203369cc1272..6e350692d118 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c | |||
@@ -526,6 +526,9 @@ int gfar_set_features(struct net_device *dev, u32 features) | |||
526 | int err = 0, i = 0; | 526 | int err = 0, i = 0; |
527 | u32 changed = dev->features ^ features; | 527 | u32 changed = dev->features ^ features; |
528 | 528 | ||
529 | if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)) | ||
530 | gfar_vlan_mode(dev, features); | ||
531 | |||
529 | if (!(changed & NETIF_F_RXCSUM)) | 532 | if (!(changed & NETIF_F_RXCSUM)) |
530 | return 0; | 533 | return 0; |
531 | 534 | ||