diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-03-25 12:01:01 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-04-13 22:17:50 -0400 |
commit | 86d70e532c352bd309dab5f1d18d113f441cb3ae (patch) | |
tree | f905aa3db40ff99c23e1d7574a919c0c458183e4 /drivers/net/e1000e | |
parent | a5cc764206a3d01dce8ebc17b4e1534afb53c495 (diff) |
e1000e: convert to new VLAN model
This switches the e1000e driver to use the new VLAN interfaces.
CC: Jesse Gross <jesse@nicira.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/e1000.h | 4 | ||||
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 26 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 170 |
3 files changed, 119 insertions, 81 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 00bf595ebd67..500896e42206 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #ifndef _E1000_H_ | 31 | #ifndef _E1000_H_ |
32 | #define _E1000_H_ | 32 | #define _E1000_H_ |
33 | 33 | ||
34 | #include <linux/bitops.h> | ||
34 | #include <linux/types.h> | 35 | #include <linux/types.h> |
35 | #include <linux/timer.h> | 36 | #include <linux/timer.h> |
36 | #include <linux/workqueue.h> | 37 | #include <linux/workqueue.h> |
@@ -39,6 +40,7 @@ | |||
39 | #include <linux/pci.h> | 40 | #include <linux/pci.h> |
40 | #include <linux/pci-aspm.h> | 41 | #include <linux/pci-aspm.h> |
41 | #include <linux/crc32.h> | 42 | #include <linux/crc32.h> |
43 | #include <linux/if_vlan.h> | ||
42 | 44 | ||
43 | #include "hw.h" | 45 | #include "hw.h" |
44 | 46 | ||
@@ -280,7 +282,7 @@ struct e1000_adapter { | |||
280 | 282 | ||
281 | const struct e1000_info *ei; | 283 | const struct e1000_info *ei; |
282 | 284 | ||
283 | struct vlan_group *vlgrp; | 285 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; |
284 | u32 bd_number; | 286 | u32 bd_number; |
285 | u32 rx_buffer_len; | 287 | u32 rx_buffer_len; |
286 | u16 mng_vlan_id; | 288 | u16 mng_vlan_id; |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 5b4cf9076bac..a31d280ffb6d 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -2020,6 +2020,31 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, | |||
2020 | } | 2020 | } |
2021 | } | 2021 | } |
2022 | 2022 | ||
2023 | static int e1000e_set_flags(struct net_device *netdev, u32 data) | ||
2024 | { | ||
2025 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
2026 | bool need_reset = false; | ||
2027 | int rc; | ||
2028 | |||
2029 | need_reset = (data & ETH_FLAG_RXVLAN) != | ||
2030 | (netdev->features & NETIF_F_HW_VLAN_RX); | ||
2031 | |||
2032 | rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN | | ||
2033 | ETH_FLAG_TXVLAN); | ||
2034 | |||
2035 | if (rc) | ||
2036 | return rc; | ||
2037 | |||
2038 | if (need_reset) { | ||
2039 | if (netif_running(netdev)) | ||
2040 | e1000e_reinit_locked(adapter); | ||
2041 | else | ||
2042 | e1000e_reset(adapter); | ||
2043 | } | ||
2044 | |||
2045 | return 0; | ||
2046 | } | ||
2047 | |||
2023 | static const struct ethtool_ops e1000_ethtool_ops = { | 2048 | static const struct ethtool_ops e1000_ethtool_ops = { |
2024 | .get_settings = e1000_get_settings, | 2049 | .get_settings = e1000_get_settings, |
2025 | .set_settings = e1000_set_settings, | 2050 | .set_settings = e1000_set_settings, |
@@ -2055,6 +2080,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { | |||
2055 | .get_coalesce = e1000_get_coalesce, | 2080 | .get_coalesce = e1000_get_coalesce, |
2056 | .set_coalesce = e1000_set_coalesce, | 2081 | .set_coalesce = e1000_set_coalesce, |
2057 | .get_flags = ethtool_op_get_flags, | 2082 | .get_flags = ethtool_op_get_flags, |
2083 | .set_flags = e1000e_set_flags, | ||
2058 | }; | 2084 | }; |
2059 | 2085 | ||
2060 | void e1000e_set_ethtool_ops(struct net_device *netdev) | 2086 | void e1000e_set_ethtool_ops(struct net_device *netdev) |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 99c8c7c0b1fb..8812eb28e099 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -459,13 +459,13 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, | |||
459 | struct net_device *netdev, struct sk_buff *skb, | 459 | struct net_device *netdev, struct sk_buff *skb, |
460 | u8 status, __le16 vlan) | 460 | u8 status, __le16 vlan) |
461 | { | 461 | { |
462 | u16 tag = le16_to_cpu(vlan); | ||
462 | skb->protocol = eth_type_trans(skb, netdev); | 463 | skb->protocol = eth_type_trans(skb, netdev); |
463 | 464 | ||
464 | if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) | 465 | if (status & E1000_RXD_STAT_VP) |
465 | vlan_gro_receive(&adapter->napi, adapter->vlgrp, | 466 | __vlan_hwaccel_put_tag(skb, tag); |
466 | le16_to_cpu(vlan), skb); | 467 | |
467 | else | 468 | napi_gro_receive(&adapter->napi, skb); |
468 | napi_gro_receive(&adapter->napi, skb); | ||
469 | } | 469 | } |
470 | 470 | ||
471 | /** | 471 | /** |
@@ -2433,6 +2433,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
2433 | vfta |= (1 << (vid & 0x1F)); | 2433 | vfta |= (1 << (vid & 0x1F)); |
2434 | hw->mac.ops.write_vfta(hw, index, vfta); | 2434 | hw->mac.ops.write_vfta(hw, index, vfta); |
2435 | } | 2435 | } |
2436 | |||
2437 | set_bit(vid, adapter->active_vlans); | ||
2436 | } | 2438 | } |
2437 | 2439 | ||
2438 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | 2440 | static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) |
@@ -2441,13 +2443,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
2441 | struct e1000_hw *hw = &adapter->hw; | 2443 | struct e1000_hw *hw = &adapter->hw; |
2442 | u32 vfta, index; | 2444 | u32 vfta, index; |
2443 | 2445 | ||
2444 | if (!test_bit(__E1000_DOWN, &adapter->state)) | ||
2445 | e1000_irq_disable(adapter); | ||
2446 | vlan_group_set_device(adapter->vlgrp, vid, NULL); | ||
2447 | |||
2448 | if (!test_bit(__E1000_DOWN, &adapter->state)) | ||
2449 | e1000_irq_enable(adapter); | ||
2450 | |||
2451 | if ((adapter->hw.mng_cookie.status & | 2446 | if ((adapter->hw.mng_cookie.status & |
2452 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && | 2447 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && |
2453 | (vid == adapter->mng_vlan_id)) { | 2448 | (vid == adapter->mng_vlan_id)) { |
@@ -2463,93 +2458,105 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
2463 | vfta &= ~(1 << (vid & 0x1F)); | 2458 | vfta &= ~(1 << (vid & 0x1F)); |
2464 | hw->mac.ops.write_vfta(hw, index, vfta); | 2459 | hw->mac.ops.write_vfta(hw, index, vfta); |
2465 | } | 2460 | } |
2461 | |||
2462 | clear_bit(vid, adapter->active_vlans); | ||
2466 | } | 2463 | } |
2467 | 2464 | ||
2468 | static void e1000_update_mng_vlan(struct e1000_adapter *adapter) | 2465 | /** |
2466 | * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering | ||
2467 | * @adapter: board private structure to initialize | ||
2468 | **/ | ||
2469 | static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter) | ||
2469 | { | 2470 | { |
2470 | struct net_device *netdev = adapter->netdev; | 2471 | struct net_device *netdev = adapter->netdev; |
2471 | u16 vid = adapter->hw.mng_cookie.vlan_id; | 2472 | struct e1000_hw *hw = &adapter->hw; |
2472 | u16 old_vid = adapter->mng_vlan_id; | 2473 | u32 rctl; |
2473 | |||
2474 | if (!adapter->vlgrp) | ||
2475 | return; | ||
2476 | 2474 | ||
2477 | if (!vlan_group_get_device(adapter->vlgrp, vid)) { | 2475 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { |
2478 | adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; | 2476 | /* disable VLAN receive filtering */ |
2479 | if (adapter->hw.mng_cookie.status & | 2477 | rctl = er32(RCTL); |
2480 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { | 2478 | rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN); |
2481 | e1000_vlan_rx_add_vid(netdev, vid); | 2479 | ew32(RCTL, rctl); |
2482 | adapter->mng_vlan_id = vid; | 2480 | |
2481 | if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) { | ||
2482 | e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); | ||
2483 | adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; | ||
2483 | } | 2484 | } |
2484 | |||
2485 | if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && | ||
2486 | (vid != old_vid) && | ||
2487 | !vlan_group_get_device(adapter->vlgrp, old_vid)) | ||
2488 | e1000_vlan_rx_kill_vid(netdev, old_vid); | ||
2489 | } else { | ||
2490 | adapter->mng_vlan_id = vid; | ||
2491 | } | 2485 | } |
2492 | } | 2486 | } |
2493 | 2487 | ||
2488 | /** | ||
2489 | * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering | ||
2490 | * @adapter: board private structure to initialize | ||
2491 | **/ | ||
2492 | static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter) | ||
2493 | { | ||
2494 | struct e1000_hw *hw = &adapter->hw; | ||
2495 | u32 rctl; | ||
2496 | |||
2497 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { | ||
2498 | /* enable VLAN receive filtering */ | ||
2499 | rctl = er32(RCTL); | ||
2500 | rctl |= E1000_RCTL_VFE; | ||
2501 | rctl &= ~E1000_RCTL_CFIEN; | ||
2502 | ew32(RCTL, rctl); | ||
2503 | } | ||
2504 | } | ||
2494 | 2505 | ||
2495 | static void e1000_vlan_rx_register(struct net_device *netdev, | 2506 | /** |
2496 | struct vlan_group *grp) | 2507 | * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping |
2508 | * @adapter: board private structure to initialize | ||
2509 | **/ | ||
2510 | static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter) | ||
2497 | { | 2511 | { |
2498 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
2499 | struct e1000_hw *hw = &adapter->hw; | 2512 | struct e1000_hw *hw = &adapter->hw; |
2500 | u32 ctrl, rctl; | 2513 | u32 ctrl; |
2501 | 2514 | ||
2502 | if (!test_bit(__E1000_DOWN, &adapter->state)) | 2515 | /* disable VLAN tag insert/strip */ |
2503 | e1000_irq_disable(adapter); | 2516 | ctrl = er32(CTRL); |
2504 | adapter->vlgrp = grp; | 2517 | ctrl &= ~E1000_CTRL_VME; |
2518 | ew32(CTRL, ctrl); | ||
2519 | } | ||
2505 | 2520 | ||
2506 | if (grp) { | 2521 | /** |
2507 | /* enable VLAN tag insert/strip */ | 2522 | * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping |
2508 | ctrl = er32(CTRL); | 2523 | * @adapter: board private structure to initialize |
2509 | ctrl |= E1000_CTRL_VME; | 2524 | **/ |
2510 | ew32(CTRL, ctrl); | 2525 | static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter) |
2526 | { | ||
2527 | struct e1000_hw *hw = &adapter->hw; | ||
2528 | u32 ctrl; | ||
2511 | 2529 | ||
2512 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { | 2530 | /* enable VLAN tag insert/strip */ |
2513 | /* enable VLAN receive filtering */ | 2531 | ctrl = er32(CTRL); |
2514 | rctl = er32(RCTL); | 2532 | ctrl |= E1000_CTRL_VME; |
2515 | rctl &= ~E1000_RCTL_CFIEN; | 2533 | ew32(CTRL, ctrl); |
2516 | ew32(RCTL, rctl); | 2534 | } |
2517 | e1000_update_mng_vlan(adapter); | ||
2518 | } | ||
2519 | } else { | ||
2520 | /* disable VLAN tag insert/strip */ | ||
2521 | ctrl = er32(CTRL); | ||
2522 | ctrl &= ~E1000_CTRL_VME; | ||
2523 | ew32(CTRL, ctrl); | ||
2524 | 2535 | ||
2525 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { | 2536 | static void e1000_update_mng_vlan(struct e1000_adapter *adapter) |
2526 | if (adapter->mng_vlan_id != | 2537 | { |
2527 | (u16)E1000_MNG_VLAN_NONE) { | 2538 | struct net_device *netdev = adapter->netdev; |
2528 | e1000_vlan_rx_kill_vid(netdev, | 2539 | u16 vid = adapter->hw.mng_cookie.vlan_id; |
2529 | adapter->mng_vlan_id); | 2540 | u16 old_vid = adapter->mng_vlan_id; |
2530 | adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; | 2541 | |
2531 | } | 2542 | if (adapter->hw.mng_cookie.status & |
2532 | } | 2543 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { |
2544 | e1000_vlan_rx_add_vid(netdev, vid); | ||
2545 | adapter->mng_vlan_id = vid; | ||
2533 | } | 2546 | } |
2534 | 2547 | ||
2535 | if (!test_bit(__E1000_DOWN, &adapter->state)) | 2548 | if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid)) |
2536 | e1000_irq_enable(adapter); | 2549 | e1000_vlan_rx_kill_vid(netdev, old_vid); |
2537 | } | 2550 | } |
2538 | 2551 | ||
2539 | static void e1000_restore_vlan(struct e1000_adapter *adapter) | 2552 | static void e1000_restore_vlan(struct e1000_adapter *adapter) |
2540 | { | 2553 | { |
2541 | u16 vid; | 2554 | u16 vid; |
2542 | 2555 | ||
2543 | e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp); | 2556 | e1000_vlan_rx_add_vid(adapter->netdev, 0); |
2544 | |||
2545 | if (!adapter->vlgrp) | ||
2546 | return; | ||
2547 | 2557 | ||
2548 | for (vid = 0; vid < VLAN_N_VID; vid++) { | 2558 | for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) |
2549 | if (!vlan_group_get_device(adapter->vlgrp, vid)) | ||
2550 | continue; | ||
2551 | e1000_vlan_rx_add_vid(adapter->netdev, vid); | 2559 | e1000_vlan_rx_add_vid(adapter->netdev, vid); |
2552 | } | ||
2553 | } | 2560 | } |
2554 | 2561 | ||
2555 | static void e1000_init_manageability_pt(struct e1000_adapter *adapter) | 2562 | static void e1000_init_manageability_pt(struct e1000_adapter *adapter) |
@@ -3039,6 +3046,8 @@ static void e1000_set_multi(struct net_device *netdev) | |||
3039 | if (netdev->flags & IFF_PROMISC) { | 3046 | if (netdev->flags & IFF_PROMISC) { |
3040 | rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); | 3047 | rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); |
3041 | rctl &= ~E1000_RCTL_VFE; | 3048 | rctl &= ~E1000_RCTL_VFE; |
3049 | /* Do not hardware filter VLANs in promisc mode */ | ||
3050 | e1000e_vlan_filter_disable(adapter); | ||
3042 | } else { | 3051 | } else { |
3043 | if (netdev->flags & IFF_ALLMULTI) { | 3052 | if (netdev->flags & IFF_ALLMULTI) { |
3044 | rctl |= E1000_RCTL_MPE; | 3053 | rctl |= E1000_RCTL_MPE; |
@@ -3046,8 +3055,7 @@ static void e1000_set_multi(struct net_device *netdev) | |||
3046 | } else { | 3055 | } else { |
3047 | rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); | 3056 | rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); |
3048 | } | 3057 | } |
3049 | if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) | 3058 | e1000e_vlan_filter_enable(adapter); |
3050 | rctl |= E1000_RCTL_VFE; | ||
3051 | } | 3059 | } |
3052 | 3060 | ||
3053 | ew32(RCTL, rctl); | 3061 | ew32(RCTL, rctl); |
@@ -3072,6 +3080,11 @@ static void e1000_set_multi(struct net_device *netdev) | |||
3072 | */ | 3080 | */ |
3073 | e1000_update_mc_addr_list(hw, NULL, 0); | 3081 | e1000_update_mc_addr_list(hw, NULL, 0); |
3074 | } | 3082 | } |
3083 | |||
3084 | if (netdev->features & NETIF_F_HW_VLAN_RX) | ||
3085 | e1000e_vlan_strip_enable(adapter); | ||
3086 | else | ||
3087 | e1000e_vlan_strip_disable(adapter); | ||
3075 | } | 3088 | } |
3076 | 3089 | ||
3077 | /** | 3090 | /** |
@@ -3721,10 +3734,8 @@ static int e1000_close(struct net_device *netdev) | |||
3721 | * kill manageability vlan ID if supported, but not if a vlan with | 3734 | * kill manageability vlan ID if supported, but not if a vlan with |
3722 | * the same ID is registered on the host OS (let 8021q kill it) | 3735 | * the same ID is registered on the host OS (let 8021q kill it) |
3723 | */ | 3736 | */ |
3724 | if ((adapter->hw.mng_cookie.status & | 3737 | if (adapter->hw.mng_cookie.status & |
3725 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && | 3738 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) |
3726 | !(adapter->vlgrp && | ||
3727 | vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) | ||
3728 | e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); | 3739 | e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); |
3729 | 3740 | ||
3730 | /* | 3741 | /* |
@@ -5759,7 +5770,6 @@ static const struct net_device_ops e1000e_netdev_ops = { | |||
5759 | .ndo_tx_timeout = e1000_tx_timeout, | 5770 | .ndo_tx_timeout = e1000_tx_timeout, |
5760 | .ndo_validate_addr = eth_validate_addr, | 5771 | .ndo_validate_addr = eth_validate_addr, |
5761 | 5772 | ||
5762 | .ndo_vlan_rx_register = e1000_vlan_rx_register, | ||
5763 | .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, | 5773 | .ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid, |
5764 | .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, | 5774 | .ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid, |
5765 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5775 | #ifdef CONFIG_NET_POLL_CONTROLLER |