diff options
author | Jiri Pirko <jpirko@redhat.com> | 2012-03-20 14:10:01 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-03-27 21:43:55 -0400 |
commit | 52f5509fe8ccb607ff9b84ad618f244262336475 (patch) | |
tree | 3ab3ceb5556c580715a799f5639b39d1748a9c38 /drivers/net/ethernet/intel/e1000 | |
parent | cc3425cdc04206f3c8b9efb2c693e89aa3cd9ec7 (diff) |
e1000: fix vlan processing regression
This patch fixes a regression introduced by commit "e1000: do vlan
cleanup (799d531)".
Apparently some e1000 chips (not mine) are sensitive about the order of
setting vlan filter and vlan stripping/inserting functionality. So this
patch changes the order so it's the same as before vlan cleanup.
Reported-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Tested-by: Ben Greear <greearb@candelatech.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000')
-rw-r--r-- | drivers/net/ethernet/intel/e1000/e1000_main.c | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 0e9aec8f6917..bcba9cfe3d03 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | |||
@@ -164,6 +164,8 @@ static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, | |||
164 | static bool e1000_vlan_used(struct e1000_adapter *adapter); | 164 | static bool e1000_vlan_used(struct e1000_adapter *adapter); |
165 | static void e1000_vlan_mode(struct net_device *netdev, | 165 | static void e1000_vlan_mode(struct net_device *netdev, |
166 | netdev_features_t features); | 166 | netdev_features_t features); |
167 | static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, | ||
168 | bool filter_on); | ||
167 | static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); | 169 | static int e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid); |
168 | static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); | 170 | static int e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid); |
169 | static void e1000_restore_vlan(struct e1000_adapter *adapter); | 171 | static void e1000_restore_vlan(struct e1000_adapter *adapter); |
@@ -1214,7 +1216,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, | |||
1214 | if (err) | 1216 | if (err) |
1215 | goto err_register; | 1217 | goto err_register; |
1216 | 1218 | ||
1217 | e1000_vlan_mode(netdev, netdev->features); | 1219 | e1000_vlan_filter_on_off(adapter, false); |
1218 | 1220 | ||
1219 | /* print bus type/speed/width info */ | 1221 | /* print bus type/speed/width info */ |
1220 | e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", | 1222 | e_info(probe, "(PCI%s:%dMHz:%d-bit) %pM\n", |
@@ -4770,6 +4772,22 @@ static bool e1000_vlan_used(struct e1000_adapter *adapter) | |||
4770 | return false; | 4772 | return false; |
4771 | } | 4773 | } |
4772 | 4774 | ||
4775 | static void __e1000_vlan_mode(struct e1000_adapter *adapter, | ||
4776 | netdev_features_t features) | ||
4777 | { | ||
4778 | struct e1000_hw *hw = &adapter->hw; | ||
4779 | u32 ctrl; | ||
4780 | |||
4781 | ctrl = er32(CTRL); | ||
4782 | if (features & NETIF_F_HW_VLAN_RX) { | ||
4783 | /* enable VLAN tag insert/strip */ | ||
4784 | ctrl |= E1000_CTRL_VME; | ||
4785 | } else { | ||
4786 | /* disable VLAN tag insert/strip */ | ||
4787 | ctrl &= ~E1000_CTRL_VME; | ||
4788 | } | ||
4789 | ew32(CTRL, ctrl); | ||
4790 | } | ||
4773 | static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, | 4791 | static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, |
4774 | bool filter_on) | 4792 | bool filter_on) |
4775 | { | 4793 | { |
@@ -4779,6 +4797,7 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, | |||
4779 | if (!test_bit(__E1000_DOWN, &adapter->flags)) | 4797 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
4780 | e1000_irq_disable(adapter); | 4798 | e1000_irq_disable(adapter); |
4781 | 4799 | ||
4800 | __e1000_vlan_mode(adapter, adapter->netdev->features); | ||
4782 | if (filter_on) { | 4801 | if (filter_on) { |
4783 | /* enable VLAN receive filtering */ | 4802 | /* enable VLAN receive filtering */ |
4784 | rctl = er32(RCTL); | 4803 | rctl = er32(RCTL); |
@@ -4799,24 +4818,14 @@ static void e1000_vlan_filter_on_off(struct e1000_adapter *adapter, | |||
4799 | } | 4818 | } |
4800 | 4819 | ||
4801 | static void e1000_vlan_mode(struct net_device *netdev, | 4820 | static void e1000_vlan_mode(struct net_device *netdev, |
4802 | netdev_features_t features) | 4821 | netdev_features_t features) |
4803 | { | 4822 | { |
4804 | struct e1000_adapter *adapter = netdev_priv(netdev); | 4823 | struct e1000_adapter *adapter = netdev_priv(netdev); |
4805 | struct e1000_hw *hw = &adapter->hw; | ||
4806 | u32 ctrl; | ||
4807 | 4824 | ||
4808 | if (!test_bit(__E1000_DOWN, &adapter->flags)) | 4825 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
4809 | e1000_irq_disable(adapter); | 4826 | e1000_irq_disable(adapter); |
4810 | 4827 | ||
4811 | ctrl = er32(CTRL); | 4828 | __e1000_vlan_mode(adapter, features); |
4812 | if (features & NETIF_F_HW_VLAN_RX) { | ||
4813 | /* enable VLAN tag insert/strip */ | ||
4814 | ctrl |= E1000_CTRL_VME; | ||
4815 | } else { | ||
4816 | /* disable VLAN tag insert/strip */ | ||
4817 | ctrl &= ~E1000_CTRL_VME; | ||
4818 | } | ||
4819 | ew32(CTRL, ctrl); | ||
4820 | 4829 | ||
4821 | if (!test_bit(__E1000_DOWN, &adapter->flags)) | 4830 | if (!test_bit(__E1000_DOWN, &adapter->flags)) |
4822 | e1000_irq_enable(adapter); | 4831 | e1000_irq_enable(adapter); |