From 99a4973c40a402da99a18b72181da42560b9d183 Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Mon, 13 Jan 2014 16:13:03 -0800 Subject: [PATCH 1/2] i40e: Warn admin to reload VF driver on port VLAN configuration The i40e Physical Function (PF) driver will allow the Virtual Function (VF) driver to configure its own VLAN filters if no port VLAN filter has been configured. This leads to the possibility of the administrator setting a port VLAN filter for the VF after the VF has already configured its own VLAN filters. This leads to a conflict that can only be resolved by reloading the VF driver. When the conflicting administrative command is detected in setting the port VLAN then log a message indicating to the system administrator that he must now reload the VF driver for the new port VLAN settings to take effect. Change-Id: I8de73b885d944a043aff32226297e4249862bcad Signed-off-by: Greg Rose Tested-by: Sibai Li Signed-off-by: Aaron Brown Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 53069c0dffd5..869b4fb991fc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2076,6 +2076,11 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, goto error_pvid; } + if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi)) + dev_err(&pf->pdev->dev, + "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n", + vf_id); + if (vsi->info.pvid) { /* kill old VLAN */ ret = i40e_vsi_kill_vlan(vsi, (le16_to_cpu(vsi->info.pvid) & From 8d82a7c5d8646b5fa68db2c9e695298bd95230cf Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Mon, 13 Jan 2014 16:13:04 -0800 Subject: [PATCH 2/2] i40e: Retain MAC filters on port VLAN deletion On port VLAN deletion the list of MAC filters for the virtual function (VF) VSI were all deleted. Let's keep them around, they come in handy for keeping the VF functional. Change-Id: I335e760392f274dc8b8b40efcb708f65b49d7973 Signed-off-by: Greg Rose Tested-by: Sibai Li Signed-off-by: Aaron Brown Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 62418ee331ad..7bfa78967276 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -1844,7 +1844,10 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid) return -ENOMEM; } } + } + /* Do not assume that I40E_VLAN_ANY should be reset to VLAN 0 */ + if (vid > 0 && !vsi->info.pvid) { list_for_each_entry(f, &vsi->mac_filter_list, list) { if (i40e_find_filter(vsi, f->macaddr, I40E_VLAN_ANY, is_vf, is_netdev)) { diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 869b4fb991fc..44bb3597d736 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2081,6 +2081,15 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, "VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n", vf_id); + /* Check for condition where there was already a port VLAN ID + * filter set and now it is being deleted by setting it to zero. + * Before deleting all the old VLAN filters we must add new ones + * with -1 (I40E_VLAN_ANY) or otherwise we're left with all our + * MAC addresses deleted. + */ + if (!(vlan_id || qos) && vsi->info.pvid) + ret = i40e_vsi_add_vlan(vsi, I40E_VLAN_ANY); + if (vsi->info.pvid) { /* kill old VLAN */ ret = i40e_vsi_kill_vlan(vsi, (le16_to_cpu(vsi->info.pvid) & @@ -2109,6 +2118,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, vsi->back->hw.aq.asq_last_status); goto error_pvid; } + /* Kill non-vlan MAC filters - ignore error return since + * there might not be any non-vlan MAC filters. + */ + i40e_vsi_kill_vlan(vsi, I40E_VLAN_ANY); } if (ret) {