diff options
author | Jesse Gross <jesse@nicira.com> | 2010-10-20 09:56:10 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-10-21 04:26:55 -0400 |
commit | f62bbb5e62c6e4a91fb222d22bc46e8d4d7e59ef (patch) | |
tree | d85a5bfb7daf205859da588d50cf2d04b6c011fc /drivers/net/ixgbe | |
parent | 7d0fd2117e3d0550d7987b3aff2bfbc0244cf7c6 (diff) |
ixgbe: Update ixgbe to use new vlan accleration.
Make the ixgbe driver use the new vlan accleration model.
Signed-off-by: Jesse Gross <jesse@nicira.com>
CC: Peter Waskiewicz <peter.p.waskiewicz.jr@intel.com>
CC: Emil Tantilov <emil.s.tantilov@intel.com>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 4 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 12 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 137 |
3 files changed, 74 insertions, 79 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index a8c47b01a6fa..5e38de79fbbd 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h | |||
@@ -28,11 +28,13 @@ | |||
28 | #ifndef _IXGBE_H_ | 28 | #ifndef _IXGBE_H_ |
29 | #define _IXGBE_H_ | 29 | #define _IXGBE_H_ |
30 | 30 | ||
31 | #include <linux/bitops.h> | ||
31 | #include <linux/types.h> | 32 | #include <linux/types.h> |
32 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
33 | #include <linux/netdevice.h> | 34 | #include <linux/netdevice.h> |
34 | #include <linux/cpumask.h> | 35 | #include <linux/cpumask.h> |
35 | #include <linux/aer.h> | 36 | #include <linux/aer.h> |
37 | #include <linux/if_vlan.h> | ||
36 | 38 | ||
37 | #include "ixgbe_type.h" | 39 | #include "ixgbe_type.h" |
38 | #include "ixgbe_common.h" | 40 | #include "ixgbe_common.h" |
@@ -287,7 +289,7 @@ struct ixgbe_q_vector { | |||
287 | /* board specific private data structure */ | 289 | /* board specific private data structure */ |
288 | struct ixgbe_adapter { | 290 | struct ixgbe_adapter { |
289 | struct timer_list watchdog_timer; | 291 | struct timer_list watchdog_timer; |
290 | struct vlan_group *vlgrp; | 292 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; |
291 | u16 bd_number; | 293 | u16 bd_number; |
292 | struct work_struct reset_task; | 294 | struct work_struct reset_task; |
293 | struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; | 295 | struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; |
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index d4ac94324fa0..dbfd62fd40eb 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c | |||
@@ -2113,7 +2113,17 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) | |||
2113 | bool need_reset = false; | 2113 | bool need_reset = false; |
2114 | int rc; | 2114 | int rc; |
2115 | 2115 | ||
2116 | rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE); | 2116 | #ifdef CONFIG_IXGBE_DCB |
2117 | if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && | ||
2118 | !(data & ETH_FLAG_RXVLAN)) | ||
2119 | return -EINVAL; | ||
2120 | #endif | ||
2121 | |||
2122 | need_reset = (data & ETH_FLAG_RXVLAN) != | ||
2123 | (netdev->features & NETIF_F_HW_VLAN_RX); | ||
2124 | |||
2125 | rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | | ||
2126 | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); | ||
2117 | if (rc) | 2127 | if (rc) |
2118 | return rc; | 2128 | return rc; |
2119 | 2129 | ||
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 998debe8023b..56f6b80e1084 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -954,17 +954,13 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, | |||
954 | bool is_vlan = (status & IXGBE_RXD_STAT_VP); | 954 | bool is_vlan = (status & IXGBE_RXD_STAT_VP); |
955 | u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); | 955 | u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); |
956 | 956 | ||
957 | if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { | 957 | if (is_vlan && (tag & VLAN_VID_MASK)) |
958 | if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) | 958 | __vlan_hwaccel_put_tag(skb, tag); |
959 | vlan_gro_receive(napi, adapter->vlgrp, tag, skb); | 959 | |
960 | else | 960 | if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) |
961 | napi_gro_receive(napi, skb); | 961 | napi_gro_receive(napi, skb); |
962 | } else { | 962 | else |
963 | if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) | 963 | netif_rx(skb); |
964 | vlan_hwaccel_rx(skb, adapter->vlgrp, tag); | ||
965 | else | ||
966 | netif_rx(skb); | ||
967 | } | ||
968 | } | 964 | } |
969 | 965 | ||
970 | /** | 966 | /** |
@@ -3065,6 +3061,7 @@ static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
3065 | 3061 | ||
3066 | /* add VID to filter table */ | 3062 | /* add VID to filter table */ |
3067 | hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true); | 3063 | hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true); |
3064 | set_bit(vid, adapter->active_vlans); | ||
3068 | } | 3065 | } |
3069 | 3066 | ||
3070 | static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | 3067 | static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) |
@@ -3073,16 +3070,9 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
3073 | struct ixgbe_hw *hw = &adapter->hw; | 3070 | struct ixgbe_hw *hw = &adapter->hw; |
3074 | int pool_ndx = adapter->num_vfs; | 3071 | int pool_ndx = adapter->num_vfs; |
3075 | 3072 | ||
3076 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
3077 | ixgbe_irq_disable(adapter); | ||
3078 | |||
3079 | vlan_group_set_device(adapter->vlgrp, vid, NULL); | ||
3080 | |||
3081 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
3082 | ixgbe_irq_enable(adapter, true, true); | ||
3083 | |||
3084 | /* remove VID from filter table */ | 3073 | /* remove VID from filter table */ |
3085 | hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); | 3074 | hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); |
3075 | clear_bit(vid, adapter->active_vlans); | ||
3086 | } | 3076 | } |
3087 | 3077 | ||
3088 | /** | 3078 | /** |
@@ -3092,27 +3082,45 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
3092 | static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) | 3082 | static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) |
3093 | { | 3083 | { |
3094 | struct ixgbe_hw *hw = &adapter->hw; | 3084 | struct ixgbe_hw *hw = &adapter->hw; |
3095 | u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); | 3085 | u32 vlnctrl; |
3086 | |||
3087 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); | ||
3088 | vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); | ||
3089 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | ||
3090 | } | ||
3091 | |||
3092 | /** | ||
3093 | * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering | ||
3094 | * @adapter: driver data | ||
3095 | */ | ||
3096 | static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) | ||
3097 | { | ||
3098 | struct ixgbe_hw *hw = &adapter->hw; | ||
3099 | u32 vlnctrl; | ||
3100 | |||
3101 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); | ||
3102 | vlnctrl |= IXGBE_VLNCTRL_VFE; | ||
3103 | vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; | ||
3104 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | ||
3105 | } | ||
3106 | |||
3107 | /** | ||
3108 | * ixgbe_vlan_strip_disable - helper to disable hw vlan stripping | ||
3109 | * @adapter: driver data | ||
3110 | */ | ||
3111 | static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) | ||
3112 | { | ||
3113 | struct ixgbe_hw *hw = &adapter->hw; | ||
3114 | u32 vlnctrl; | ||
3096 | int i, j; | 3115 | int i, j; |
3097 | 3116 | ||
3098 | switch (hw->mac.type) { | 3117 | switch (hw->mac.type) { |
3099 | case ixgbe_mac_82598EB: | 3118 | case ixgbe_mac_82598EB: |
3100 | vlnctrl &= ~IXGBE_VLNCTRL_VFE; | 3119 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); |
3101 | #ifdef CONFIG_IXGBE_DCB | 3120 | vlnctrl &= ~IXGBE_VLNCTRL_VME; |
3102 | if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) | ||
3103 | vlnctrl &= ~IXGBE_VLNCTRL_VME; | ||
3104 | #endif | ||
3105 | vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; | ||
3106 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | 3121 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); |
3107 | break; | 3122 | break; |
3108 | case ixgbe_mac_82599EB: | 3123 | case ixgbe_mac_82599EB: |
3109 | vlnctrl &= ~IXGBE_VLNCTRL_VFE; | ||
3110 | vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; | ||
3111 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | ||
3112 | #ifdef CONFIG_IXGBE_DCB | ||
3113 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) | ||
3114 | break; | ||
3115 | #endif | ||
3116 | for (i = 0; i < adapter->num_rx_queues; i++) { | 3124 | for (i = 0; i < adapter->num_rx_queues; i++) { |
3117 | j = adapter->rx_ring[i]->reg_idx; | 3125 | j = adapter->rx_ring[i]->reg_idx; |
3118 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); | 3126 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); |
@@ -3126,25 +3134,22 @@ static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) | |||
3126 | } | 3134 | } |
3127 | 3135 | ||
3128 | /** | 3136 | /** |
3129 | * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering | 3137 | * ixgbe_vlan_strip_enable - helper to enable hw vlan stripping |
3130 | * @adapter: driver data | 3138 | * @adapter: driver data |
3131 | */ | 3139 | */ |
3132 | static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) | 3140 | static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) |
3133 | { | 3141 | { |
3134 | struct ixgbe_hw *hw = &adapter->hw; | 3142 | struct ixgbe_hw *hw = &adapter->hw; |
3135 | u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); | 3143 | u32 vlnctrl; |
3136 | int i, j; | 3144 | int i, j; |
3137 | 3145 | ||
3138 | switch (hw->mac.type) { | 3146 | switch (hw->mac.type) { |
3139 | case ixgbe_mac_82598EB: | 3147 | case ixgbe_mac_82598EB: |
3140 | vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE; | 3148 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); |
3141 | vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; | 3149 | vlnctrl |= IXGBE_VLNCTRL_VME; |
3142 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | 3150 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); |
3143 | break; | 3151 | break; |
3144 | case ixgbe_mac_82599EB: | 3152 | case ixgbe_mac_82599EB: |
3145 | vlnctrl |= IXGBE_VLNCTRL_VFE; | ||
3146 | vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; | ||
3147 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | ||
3148 | for (i = 0; i < adapter->num_rx_queues; i++) { | 3153 | for (i = 0; i < adapter->num_rx_queues; i++) { |
3149 | j = adapter->rx_ring[i]->reg_idx; | 3154 | j = adapter->rx_ring[i]->reg_idx; |
3150 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); | 3155 | vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); |
@@ -3157,40 +3162,14 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) | |||
3157 | } | 3162 | } |
3158 | } | 3163 | } |
3159 | 3164 | ||
3160 | static void ixgbe_vlan_rx_register(struct net_device *netdev, | ||
3161 | struct vlan_group *grp) | ||
3162 | { | ||
3163 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
3164 | |||
3165 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
3166 | ixgbe_irq_disable(adapter); | ||
3167 | adapter->vlgrp = grp; | ||
3168 | |||
3169 | /* | ||
3170 | * For a DCB driver, always enable VLAN tag stripping so we can | ||
3171 | * still receive traffic from a DCB-enabled host even if we're | ||
3172 | * not in DCB mode. | ||
3173 | */ | ||
3174 | ixgbe_vlan_filter_enable(adapter); | ||
3175 | |||
3176 | ixgbe_vlan_rx_add_vid(netdev, 0); | ||
3177 | |||
3178 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
3179 | ixgbe_irq_enable(adapter, true, true); | ||
3180 | } | ||
3181 | |||
3182 | static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) | 3165 | static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) |
3183 | { | 3166 | { |
3184 | ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp); | 3167 | u16 vid; |
3185 | 3168 | ||
3186 | if (adapter->vlgrp) { | 3169 | ixgbe_vlan_rx_add_vid(adapter->netdev, 0); |
3187 | u16 vid; | 3170 | |
3188 | for (vid = 0; vid < VLAN_N_VID; vid++) { | 3171 | for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) |
3189 | if (!vlan_group_get_device(adapter->vlgrp, vid)) | 3172 | ixgbe_vlan_rx_add_vid(adapter->netdev, vid); |
3190 | continue; | ||
3191 | ixgbe_vlan_rx_add_vid(adapter->netdev, vid); | ||
3192 | } | ||
3193 | } | ||
3194 | } | 3173 | } |
3195 | 3174 | ||
3196 | /** | 3175 | /** |
@@ -3305,6 +3284,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev) | |||
3305 | } | 3284 | } |
3306 | 3285 | ||
3307 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); | 3286 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); |
3287 | |||
3288 | if (netdev->features & NETIF_F_HW_VLAN_RX) | ||
3289 | ixgbe_vlan_strip_enable(adapter); | ||
3290 | else | ||
3291 | ixgbe_vlan_strip_disable(adapter); | ||
3308 | } | 3292 | } |
3309 | 3293 | ||
3310 | static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) | 3294 | static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) |
@@ -3388,7 +3372,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) | |||
3388 | IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); | 3372 | IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); |
3389 | } | 3373 | } |
3390 | /* Enable VLAN tag insert/strip */ | 3374 | /* Enable VLAN tag insert/strip */ |
3391 | ixgbe_vlan_filter_enable(adapter); | 3375 | adapter->netdev->features |= NETIF_F_HW_VLAN_RX; |
3392 | 3376 | ||
3393 | hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); | 3377 | hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); |
3394 | } | 3378 | } |
@@ -3400,13 +3384,13 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) | |||
3400 | struct ixgbe_hw *hw = &adapter->hw; | 3384 | struct ixgbe_hw *hw = &adapter->hw; |
3401 | int i; | 3385 | int i; |
3402 | 3386 | ||
3403 | ixgbe_set_rx_mode(netdev); | ||
3404 | |||
3405 | ixgbe_restore_vlan(adapter); | ||
3406 | #ifdef CONFIG_IXGBE_DCB | 3387 | #ifdef CONFIG_IXGBE_DCB |
3407 | ixgbe_configure_dcb(adapter); | 3388 | ixgbe_configure_dcb(adapter); |
3408 | #endif | 3389 | #endif |
3409 | 3390 | ||
3391 | ixgbe_set_rx_mode(netdev); | ||
3392 | ixgbe_restore_vlan(adapter); | ||
3393 | |||
3410 | #ifdef IXGBE_FCOE | 3394 | #ifdef IXGBE_FCOE |
3411 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) | 3395 | if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) |
3412 | ixgbe_configure_fcoe(adapter); | 3396 | ixgbe_configure_fcoe(adapter); |
@@ -6569,7 +6553,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { | |||
6569 | .ndo_set_mac_address = ixgbe_set_mac, | 6553 | .ndo_set_mac_address = ixgbe_set_mac, |
6570 | .ndo_change_mtu = ixgbe_change_mtu, | 6554 | .ndo_change_mtu = ixgbe_change_mtu, |
6571 | .ndo_tx_timeout = ixgbe_tx_timeout, | 6555 | .ndo_tx_timeout = ixgbe_tx_timeout, |
6572 | .ndo_vlan_rx_register = ixgbe_vlan_rx_register, | ||
6573 | .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, | 6556 | .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, |
6574 | .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, | 6557 | .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, |
6575 | .ndo_do_ioctl = ixgbe_ioctl, | 6558 | .ndo_do_ioctl = ixgbe_ioctl, |