diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2009-10-27 19:47:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-28 06:25:41 -0400 |
commit | 51466239fb9f95343e88c14475a0f99fe4882c54 (patch) | |
tree | 2a038fd1a925c84bee3bee717d99e146018a453d /drivers/net/igb | |
parent | 7d5753f08c5be5440ac0385b5f2518d2630be7b7 (diff) |
igb: rework handling of the vfta and vlvf registers in relation to mng_vlan
This patch corrects some errors in how vlans are being handled when vfs
start interacting with the management vlans.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/igb')
-rw-r--r-- | drivers/net/igb/igb_main.c | 94 |
1 files changed, 32 insertions, 62 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 3ab297844d6a..91709272ae1f 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -963,24 +963,23 @@ static void igb_irq_enable(struct igb_adapter *adapter) | |||
963 | 963 | ||
964 | static void igb_update_mng_vlan(struct igb_adapter *adapter) | 964 | static void igb_update_mng_vlan(struct igb_adapter *adapter) |
965 | { | 965 | { |
966 | struct net_device *netdev = adapter->netdev; | 966 | struct e1000_hw *hw = &adapter->hw; |
967 | u16 vid = adapter->hw.mng_cookie.vlan_id; | 967 | u16 vid = adapter->hw.mng_cookie.vlan_id; |
968 | u16 old_vid = adapter->mng_vlan_id; | 968 | u16 old_vid = adapter->mng_vlan_id; |
969 | if (adapter->vlgrp) { | ||
970 | if (!vlan_group_get_device(adapter->vlgrp, vid)) { | ||
971 | if (adapter->hw.mng_cookie.status & | ||
972 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { | ||
973 | igb_vlan_rx_add_vid(netdev, vid); | ||
974 | adapter->mng_vlan_id = vid; | ||
975 | } else | ||
976 | adapter->mng_vlan_id = IGB_MNG_VLAN_NONE; | ||
977 | 969 | ||
978 | if ((old_vid != (u16)IGB_MNG_VLAN_NONE) && | 970 | if (hw->mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { |
979 | (vid != old_vid) && | 971 | /* add VID to filter table */ |
980 | !vlan_group_get_device(adapter->vlgrp, old_vid)) | 972 | igb_vfta_set(hw, vid, true); |
981 | igb_vlan_rx_kill_vid(netdev, old_vid); | 973 | adapter->mng_vlan_id = vid; |
982 | } else | 974 | } else { |
983 | adapter->mng_vlan_id = vid; | 975 | adapter->mng_vlan_id = IGB_MNG_VLAN_NONE; |
976 | } | ||
977 | |||
978 | if ((old_vid != (u16)IGB_MNG_VLAN_NONE) && | ||
979 | (vid != old_vid) && | ||
980 | !vlan_group_get_device(adapter->vlgrp, old_vid)) { | ||
981 | /* remove VID from filter table */ | ||
982 | igb_vfta_set(hw, old_vid, false); | ||
984 | } | 983 | } |
985 | } | 984 | } |
986 | 985 | ||
@@ -1847,11 +1846,6 @@ static int igb_open(struct net_device *netdev) | |||
1847 | 1846 | ||
1848 | /* e1000_power_up_phy(adapter); */ | 1847 | /* e1000_power_up_phy(adapter); */ |
1849 | 1848 | ||
1850 | adapter->mng_vlan_id = IGB_MNG_VLAN_NONE; | ||
1851 | if ((adapter->hw.mng_cookie.status & | ||
1852 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) | ||
1853 | igb_update_mng_vlan(adapter); | ||
1854 | |||
1855 | /* before we allocate an interrupt, we must be ready to handle it. | 1849 | /* before we allocate an interrupt, we must be ready to handle it. |
1856 | * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt | 1850 | * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt |
1857 | * as soon as we call pci_request_irq, so we have to setup our | 1851 | * as soon as we call pci_request_irq, so we have to setup our |
@@ -1924,14 +1918,6 @@ static int igb_close(struct net_device *netdev) | |||
1924 | igb_free_all_tx_resources(adapter); | 1918 | igb_free_all_tx_resources(adapter); |
1925 | igb_free_all_rx_resources(adapter); | 1919 | igb_free_all_rx_resources(adapter); |
1926 | 1920 | ||
1927 | /* kill manageability vlan ID if supported, but not if a vlan with | ||
1928 | * the same ID is registered on the host OS (let 8021q kill it) */ | ||
1929 | if ((adapter->hw.mng_cookie.status & | ||
1930 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && | ||
1931 | !(adapter->vlgrp && | ||
1932 | vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) | ||
1933 | igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); | ||
1934 | |||
1935 | return 0; | 1921 | return 0; |
1936 | } | 1922 | } |
1937 | 1923 | ||
@@ -4235,7 +4221,11 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | |||
4235 | struct e1000_hw *hw = &adapter->hw; | 4221 | struct e1000_hw *hw = &adapter->hw; |
4236 | u32 reg, i; | 4222 | u32 reg, i; |
4237 | 4223 | ||
4238 | /* It is an error to call this function when VFs are not enabled */ | 4224 | /* The vlvf table only exists on 82576 hardware and newer */ |
4225 | if (hw->mac.type < e1000_82576) | ||
4226 | return -1; | ||
4227 | |||
4228 | /* we only need to do this if VMDq is enabled */ | ||
4239 | if (!adapter->vfs_allocated_count) | 4229 | if (!adapter->vfs_allocated_count) |
4240 | return -1; | 4230 | return -1; |
4241 | 4231 | ||
@@ -4265,16 +4255,12 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | |||
4265 | 4255 | ||
4266 | /* if !enabled we need to set this up in vfta */ | 4256 | /* if !enabled we need to set this up in vfta */ |
4267 | if (!(reg & E1000_VLVF_VLANID_ENABLE)) { | 4257 | if (!(reg & E1000_VLVF_VLANID_ENABLE)) { |
4268 | /* add VID to filter table, if bit already set | 4258 | /* add VID to filter table */ |
4269 | * PF must have added it outside of table */ | 4259 | igb_vfta_set(hw, vid, true); |
4270 | if (igb_vfta_set(hw, vid, true)) | ||
4271 | reg |= 1 << (E1000_VLVF_POOLSEL_SHIFT + | ||
4272 | adapter->vfs_allocated_count); | ||
4273 | reg |= E1000_VLVF_VLANID_ENABLE; | 4260 | reg |= E1000_VLVF_VLANID_ENABLE; |
4274 | } | 4261 | } |
4275 | reg &= ~E1000_VLVF_VLANID_MASK; | 4262 | reg &= ~E1000_VLVF_VLANID_MASK; |
4276 | reg |= vid; | 4263 | reg |= vid; |
4277 | |||
4278 | wr32(E1000_VLVF(i), reg); | 4264 | wr32(E1000_VLVF(i), reg); |
4279 | 4265 | ||
4280 | /* do not modify RLPML for PF devices */ | 4266 | /* do not modify RLPML for PF devices */ |
@@ -4290,8 +4276,8 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf) | |||
4290 | reg |= size; | 4276 | reg |= size; |
4291 | wr32(E1000_VMOLR(vf), reg); | 4277 | wr32(E1000_VMOLR(vf), reg); |
4292 | } | 4278 | } |
4293 | adapter->vf_data[vf].vlans_enabled++; | ||
4294 | 4279 | ||
4280 | adapter->vf_data[vf].vlans_enabled++; | ||
4295 | return 0; | 4281 | return 0; |
4296 | } | 4282 | } |
4297 | } else { | 4283 | } else { |
@@ -5393,21 +5379,15 @@ static void igb_vlan_rx_register(struct net_device *netdev, | |||
5393 | ctrl |= E1000_CTRL_VME; | 5379 | ctrl |= E1000_CTRL_VME; |
5394 | wr32(E1000_CTRL, ctrl); | 5380 | wr32(E1000_CTRL, ctrl); |
5395 | 5381 | ||
5396 | /* enable VLAN receive filtering */ | 5382 | /* Disable CFI check */ |
5397 | rctl = rd32(E1000_RCTL); | 5383 | rctl = rd32(E1000_RCTL); |
5398 | rctl &= ~E1000_RCTL_CFIEN; | 5384 | rctl &= ~E1000_RCTL_CFIEN; |
5399 | wr32(E1000_RCTL, rctl); | 5385 | wr32(E1000_RCTL, rctl); |
5400 | igb_update_mng_vlan(adapter); | ||
5401 | } else { | 5386 | } else { |
5402 | /* disable VLAN tag insert/strip */ | 5387 | /* disable VLAN tag insert/strip */ |
5403 | ctrl = rd32(E1000_CTRL); | 5388 | ctrl = rd32(E1000_CTRL); |
5404 | ctrl &= ~E1000_CTRL_VME; | 5389 | ctrl &= ~E1000_CTRL_VME; |
5405 | wr32(E1000_CTRL, ctrl); | 5390 | wr32(E1000_CTRL, ctrl); |
5406 | |||
5407 | if (adapter->mng_vlan_id != (u16)IGB_MNG_VLAN_NONE) { | ||
5408 | igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); | ||
5409 | adapter->mng_vlan_id = IGB_MNG_VLAN_NONE; | ||
5410 | } | ||
5411 | } | 5391 | } |
5412 | 5392 | ||
5413 | igb_rlpml_set(adapter); | 5393 | igb_rlpml_set(adapter); |
@@ -5422,16 +5402,11 @@ static void igb_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
5422 | struct e1000_hw *hw = &adapter->hw; | 5402 | struct e1000_hw *hw = &adapter->hw; |
5423 | int pf_id = adapter->vfs_allocated_count; | 5403 | int pf_id = adapter->vfs_allocated_count; |
5424 | 5404 | ||
5425 | if ((hw->mng_cookie.status & | 5405 | /* attempt to add filter to vlvf array */ |
5426 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && | 5406 | igb_vlvf_set(adapter, vid, true, pf_id); |
5427 | (vid == adapter->mng_vlan_id)) | ||
5428 | return; | ||
5429 | |||
5430 | /* add vid to vlvf if sr-iov is enabled, | ||
5431 | * if that fails add directly to filter table */ | ||
5432 | if (igb_vlvf_set(adapter, vid, true, pf_id)) | ||
5433 | igb_vfta_set(hw, vid, true); | ||
5434 | 5407 | ||
5408 | /* add the filter since PF can receive vlans w/o entry in vlvf */ | ||
5409 | igb_vfta_set(hw, vid, true); | ||
5435 | } | 5410 | } |
5436 | 5411 | ||
5437 | static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | 5412 | static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) |
@@ -5439,6 +5414,7 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
5439 | struct igb_adapter *adapter = netdev_priv(netdev); | 5414 | struct igb_adapter *adapter = netdev_priv(netdev); |
5440 | struct e1000_hw *hw = &adapter->hw; | 5415 | struct e1000_hw *hw = &adapter->hw; |
5441 | int pf_id = adapter->vfs_allocated_count; | 5416 | int pf_id = adapter->vfs_allocated_count; |
5417 | s32 err; | ||
5442 | 5418 | ||
5443 | igb_irq_disable(adapter); | 5419 | igb_irq_disable(adapter); |
5444 | vlan_group_set_device(adapter->vlgrp, vid, NULL); | 5420 | vlan_group_set_device(adapter->vlgrp, vid, NULL); |
@@ -5446,17 +5422,11 @@ static void igb_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
5446 | if (!test_bit(__IGB_DOWN, &adapter->state)) | 5422 | if (!test_bit(__IGB_DOWN, &adapter->state)) |
5447 | igb_irq_enable(adapter); | 5423 | igb_irq_enable(adapter); |
5448 | 5424 | ||
5449 | if ((adapter->hw.mng_cookie.status & | 5425 | /* remove vlan from VLVF table array */ |
5450 | E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && | 5426 | err = igb_vlvf_set(adapter, vid, false, pf_id); |
5451 | (vid == adapter->mng_vlan_id)) { | ||
5452 | /* release control to f/w */ | ||
5453 | igb_release_hw_control(adapter); | ||
5454 | return; | ||
5455 | } | ||
5456 | 5427 | ||
5457 | /* remove vid from vlvf if sr-iov is enabled, | 5428 | /* if vid was not present in VLVF just remove it from table */ |
5458 | * if not in vlvf remove from vfta */ | 5429 | if (err) |
5459 | if (igb_vlvf_set(adapter, vid, false, pf_id)) | ||
5460 | igb_vfta_set(hw, vid, false); | 5430 | igb_vfta_set(hw, vid, false); |
5461 | } | 5431 | } |
5462 | 5432 | ||