diff options
author | Emil Tantilov <emil.s.tantilov@intel.com> | 2011-01-27 04:14:18 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-03-11 04:16:23 -0500 |
commit | e2444d92083cc1ceb07487425897d6d51a13e9dd (patch) | |
tree | 0ef862edfb70906a0bedafd599943645303c3692 | |
parent | 1b7fe59322bef9e7a2c05b64a07a66b875299736 (diff) |
ixgb: convert to new VLAN model
Based on a patch from Jesse Gross <jesse@nicira.com>
This switches the ixgb driver to use the new VLAN interfaces.
In doing this, it completes the work begun in
ae54496f9e8d40c89e5668205c181dccfa9ecda1 allowing the use of
hardware VLAN insertion without having a VLAN group configured.
CC: Jesse Gross <jesse@nicira.com>
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ixgb/ixgb.h | 2 | ||||
-rw-r--r-- | drivers/net/ixgb/ixgb_ethtool.c | 39 | ||||
-rw-r--r-- | drivers/net/ixgb/ixgb_main.c | 54 |
3 files changed, 52 insertions, 43 deletions
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index 521c0c732998..8f3df044e81e 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h | |||
@@ -149,7 +149,7 @@ struct ixgb_desc_ring { | |||
149 | 149 | ||
150 | struct ixgb_adapter { | 150 | struct ixgb_adapter { |
151 | struct timer_list watchdog_timer; | 151 | struct timer_list watchdog_timer; |
152 | struct vlan_group *vlgrp; | 152 | unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; |
153 | u32 bd_number; | 153 | u32 bd_number; |
154 | u32 rx_buffer_len; | 154 | u32 rx_buffer_len; |
155 | u32 part_num; | 155 | u32 part_num; |
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 43994c199991..cc53aa1541ba 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c | |||
@@ -706,6 +706,43 @@ ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) | |||
706 | } | 706 | } |
707 | } | 707 | } |
708 | 708 | ||
709 | static int ixgb_set_flags(struct net_device *netdev, u32 data) | ||
710 | { | ||
711 | struct ixgb_adapter *adapter = netdev_priv(netdev); | ||
712 | bool need_reset; | ||
713 | int rc; | ||
714 | |||
715 | /* | ||
716 | * Tx VLAN insertion does not work per HW design when Rx stripping is | ||
717 | * disabled. Disable txvlan when rxvlan is turned off, and enable | ||
718 | * rxvlan when txvlan is turned on. | ||
719 | */ | ||
720 | if (!(data & ETH_FLAG_RXVLAN) && | ||
721 | (netdev->features & NETIF_F_HW_VLAN_TX)) | ||
722 | data &= ~ETH_FLAG_TXVLAN; | ||
723 | else if (data & ETH_FLAG_TXVLAN) | ||
724 | data |= ETH_FLAG_RXVLAN; | ||
725 | |||
726 | need_reset = (data & ETH_FLAG_RXVLAN) != | ||
727 | (netdev->features & NETIF_F_HW_VLAN_RX); | ||
728 | |||
729 | rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN | | ||
730 | ETH_FLAG_TXVLAN); | ||
731 | if (rc) | ||
732 | return rc; | ||
733 | |||
734 | if (need_reset) { | ||
735 | if (netif_running(netdev)) { | ||
736 | ixgb_down(adapter, true); | ||
737 | ixgb_up(adapter); | ||
738 | ixgb_set_speed_duplex(netdev); | ||
739 | } else | ||
740 | ixgb_reset(adapter); | ||
741 | } | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
709 | static const struct ethtool_ops ixgb_ethtool_ops = { | 746 | static const struct ethtool_ops ixgb_ethtool_ops = { |
710 | .get_settings = ixgb_get_settings, | 747 | .get_settings = ixgb_get_settings, |
711 | .set_settings = ixgb_set_settings, | 748 | .set_settings = ixgb_set_settings, |
@@ -732,6 +769,8 @@ static const struct ethtool_ops ixgb_ethtool_ops = { | |||
732 | .phys_id = ixgb_phys_id, | 769 | .phys_id = ixgb_phys_id, |
733 | .get_sset_count = ixgb_get_sset_count, | 770 | .get_sset_count = ixgb_get_sset_count, |
734 | .get_ethtool_stats = ixgb_get_ethtool_stats, | 771 | .get_ethtool_stats = ixgb_get_ethtool_stats, |
772 | .get_flags = ethtool_op_get_flags, | ||
773 | .set_flags = ixgb_set_flags, | ||
735 | }; | 774 | }; |
736 | 775 | ||
737 | void ixgb_set_ethtool_ops(struct net_device *netdev) | 776 | void ixgb_set_ethtool_ops(struct net_device *netdev) |
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 5639cccb4935..0f681ac2da8d 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -100,8 +100,6 @@ static void ixgb_tx_timeout_task(struct work_struct *work); | |||
100 | 100 | ||
101 | static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter); | 101 | static void ixgb_vlan_strip_enable(struct ixgb_adapter *adapter); |
102 | static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter); | 102 | static void ixgb_vlan_strip_disable(struct ixgb_adapter *adapter); |
103 | static void ixgb_vlan_rx_register(struct net_device *netdev, | ||
104 | struct vlan_group *grp); | ||
105 | static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid); | 103 | static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid); |
106 | static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); | 104 | static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); |
107 | static void ixgb_restore_vlan(struct ixgb_adapter *adapter); | 105 | static void ixgb_restore_vlan(struct ixgb_adapter *adapter); |
@@ -336,7 +334,6 @@ static const struct net_device_ops ixgb_netdev_ops = { | |||
336 | .ndo_set_mac_address = ixgb_set_mac, | 334 | .ndo_set_mac_address = ixgb_set_mac, |
337 | .ndo_change_mtu = ixgb_change_mtu, | 335 | .ndo_change_mtu = ixgb_change_mtu, |
338 | .ndo_tx_timeout = ixgb_tx_timeout, | 336 | .ndo_tx_timeout = ixgb_tx_timeout, |
339 | .ndo_vlan_rx_register = ixgb_vlan_rx_register, | ||
340 | .ndo_vlan_rx_add_vid = ixgb_vlan_rx_add_vid, | 337 | .ndo_vlan_rx_add_vid = ixgb_vlan_rx_add_vid, |
341 | .ndo_vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid, | 338 | .ndo_vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid, |
342 | #ifdef CONFIG_NET_POLL_CONTROLLER | 339 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -1508,7 +1505,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1508 | DESC_NEEDED))) | 1505 | DESC_NEEDED))) |
1509 | return NETDEV_TX_BUSY; | 1506 | return NETDEV_TX_BUSY; |
1510 | 1507 | ||
1511 | if (adapter->vlgrp && vlan_tx_tag_present(skb)) { | 1508 | if (vlan_tx_tag_present(skb)) { |
1512 | tx_flags |= IXGB_TX_FLAGS_VLAN; | 1509 | tx_flags |= IXGB_TX_FLAGS_VLAN; |
1513 | vlan_id = vlan_tx_tag_get(skb); | 1510 | vlan_id = vlan_tx_tag_get(skb); |
1514 | } | 1511 | } |
@@ -2049,12 +2046,11 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do) | |||
2049 | ixgb_rx_checksum(adapter, rx_desc, skb); | 2046 | ixgb_rx_checksum(adapter, rx_desc, skb); |
2050 | 2047 | ||
2051 | skb->protocol = eth_type_trans(skb, netdev); | 2048 | skb->protocol = eth_type_trans(skb, netdev); |
2052 | if (adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) { | 2049 | if (status & IXGB_RX_DESC_STATUS_VP) |
2053 | vlan_hwaccel_receive_skb(skb, adapter->vlgrp, | 2050 | __vlan_hwaccel_put_tag(skb, |
2054 | le16_to_cpu(rx_desc->special)); | 2051 | le16_to_cpu(rx_desc->special)); |
2055 | } else { | 2052 | |
2056 | netif_receive_skb(skb); | 2053 | netif_receive_skb(skb); |
2057 | } | ||
2058 | 2054 | ||
2059 | rxdesc_done: | 2055 | rxdesc_done: |
2060 | /* clean up descriptor, might be written over by hw */ | 2056 | /* clean up descriptor, might be written over by hw */ |
@@ -2152,20 +2148,6 @@ map_skb: | |||
2152 | } | 2148 | } |
2153 | } | 2149 | } |
2154 | 2150 | ||
2155 | /** | ||
2156 | * ixgb_vlan_rx_register - enables or disables vlan tagging/stripping. | ||
2157 | * | ||
2158 | * @param netdev network interface device structure | ||
2159 | * @param grp indicates to enable or disable tagging/stripping | ||
2160 | **/ | ||
2161 | static void | ||
2162 | ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) | ||
2163 | { | ||
2164 | struct ixgb_adapter *adapter = netdev_priv(netdev); | ||
2165 | |||
2166 | adapter->vlgrp = grp; | ||
2167 | } | ||
2168 | |||
2169 | static void | 2151 | static void |
2170 | ixgb_vlan_strip_enable(struct ixgb_adapter *adapter) | 2152 | ixgb_vlan_strip_enable(struct ixgb_adapter *adapter) |
2171 | { | 2153 | { |
@@ -2200,6 +2182,7 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
2200 | vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); | 2182 | vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); |
2201 | vfta |= (1 << (vid & 0x1F)); | 2183 | vfta |= (1 << (vid & 0x1F)); |
2202 | ixgb_write_vfta(&adapter->hw, index, vfta); | 2184 | ixgb_write_vfta(&adapter->hw, index, vfta); |
2185 | set_bit(vid, adapter->active_vlans); | ||
2203 | } | 2186 | } |
2204 | 2187 | ||
2205 | static void | 2188 | static void |
@@ -2208,35 +2191,22 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
2208 | struct ixgb_adapter *adapter = netdev_priv(netdev); | 2191 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2209 | u32 vfta, index; | 2192 | u32 vfta, index; |
2210 | 2193 | ||
2211 | ixgb_irq_disable(adapter); | ||
2212 | |||
2213 | vlan_group_set_device(adapter->vlgrp, vid, NULL); | ||
2214 | |||
2215 | /* don't enable interrupts unless we are UP */ | ||
2216 | if (adapter->netdev->flags & IFF_UP) | ||
2217 | ixgb_irq_enable(adapter); | ||
2218 | |||
2219 | /* remove VID from filter table */ | 2194 | /* remove VID from filter table */ |
2220 | 2195 | ||
2221 | index = (vid >> 5) & 0x7F; | 2196 | index = (vid >> 5) & 0x7F; |
2222 | vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); | 2197 | vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index); |
2223 | vfta &= ~(1 << (vid & 0x1F)); | 2198 | vfta &= ~(1 << (vid & 0x1F)); |
2224 | ixgb_write_vfta(&adapter->hw, index, vfta); | 2199 | ixgb_write_vfta(&adapter->hw, index, vfta); |
2200 | clear_bit(vid, adapter->active_vlans); | ||
2225 | } | 2201 | } |
2226 | 2202 | ||
2227 | static void | 2203 | static void |
2228 | ixgb_restore_vlan(struct ixgb_adapter *adapter) | 2204 | ixgb_restore_vlan(struct ixgb_adapter *adapter) |
2229 | { | 2205 | { |
2230 | ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp); | 2206 | u16 vid; |
2231 | 2207 | ||
2232 | if (adapter->vlgrp) { | 2208 | for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) |
2233 | u16 vid; | 2209 | ixgb_vlan_rx_add_vid(adapter->netdev, vid); |
2234 | for (vid = 0; vid < VLAN_N_VID; vid++) { | ||
2235 | if (!vlan_group_get_device(adapter->vlgrp, vid)) | ||
2236 | continue; | ||
2237 | ixgb_vlan_rx_add_vid(adapter->netdev, vid); | ||
2238 | } | ||
2239 | } | ||
2240 | } | 2210 | } |
2241 | 2211 | ||
2242 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2212 | #ifdef CONFIG_NET_POLL_CONTROLLER |