i40e: Add allmulti support for the VF
authorAnjali Singhai Jain <anjali.singhai@intel.com>
Tue, 3 May 2016 22:13:10 +0000 (15:13 -0700)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 14 May 2016 05:31:42 +0000 (22:31 -0700)
This patch enables a feature to enable/disable all multicast
for a trusted VF.

Change-Id: I926eba7f8850c8d40f8ad7e08bbe4056bbd3985f
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40evf/i40evf.h
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/i40evf/i40evf_virtchnl.c

index fa044a904208ce74a176fac36c9792b67504006a..76ed97db28e2e883f51a7ca5fc9e225a31d8396f 100644 (file)
@@ -215,6 +215,7 @@ struct i40evf_adapter {
 #define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE     BIT(12)
 #define I40EVF_FLAG_ADDR_SET_BY_PF             BIT(13)
 #define I40EVF_FLAG_PROMISC_ON                 BIT(15)
+#define I40EVF_FLAG_ALLMULTI_ON                        BIT(16)
 /* duplicates for common code */
 #define I40E_FLAG_FDIR_ATR_ENABLED              0
 #define I40E_FLAG_DCB_ENABLED                   0
@@ -241,6 +242,8 @@ struct i40evf_adapter {
 #define I40EVF_FLAG_AQ_SET_RSS_LUT             BIT(14)
 #define I40EVF_FLAG_AQ_REQUEST_PROMISC         BIT(15)
 #define I40EVF_FLAG_AQ_RELEASE_PROMISC         BIT(16)
+#define I40EVF_FLAG_AQ_REQUEST_ALLMULTI                BIT(17)
+#define I40EVF_FLAG_AQ_RELEASE_ALLMULTI                BIT(18)
 
        /* OS defined structs */
        struct net_device *netdev;
index b548dbe78cd3439bc0293c27283ee8a072536e2c..642bb45ed9067bac11d7ee9469f10e44b29b42e1 100644 (file)
@@ -934,6 +934,13 @@ bottom_of_search_loop:
                 adapter->flags & I40EVF_FLAG_PROMISC_ON)
                adapter->aq_required |= I40EVF_FLAG_AQ_RELEASE_PROMISC;
 
+       if (netdev->flags & IFF_ALLMULTI &&
+           !(adapter->flags & I40EVF_FLAG_ALLMULTI_ON))
+               adapter->aq_required |= I40EVF_FLAG_AQ_REQUEST_ALLMULTI;
+       else if (!(netdev->flags & IFF_ALLMULTI) &&
+                adapter->flags & I40EVF_FLAG_ALLMULTI_ON)
+               adapter->aq_required |= I40EVF_FLAG_AQ_RELEASE_ALLMULTI;
+
        clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
 }
 
@@ -1612,7 +1619,13 @@ static void i40evf_watchdog_task(struct work_struct *work)
                goto watchdog_done;
        }
 
-       if (adapter->aq_required & I40EVF_FLAG_AQ_RELEASE_PROMISC) {
+       if (adapter->aq_required & I40EVF_FLAG_AQ_REQUEST_ALLMULTI) {
+               i40evf_set_promiscuous(adapter, I40E_FLAG_VF_MULTICAST_PROMISC);
+               goto watchdog_done;
+       }
+
+       if ((adapter->aq_required & I40EVF_FLAG_AQ_RELEASE_PROMISC) &&
+           (adapter->aq_required & I40EVF_FLAG_AQ_RELEASE_ALLMULTI)) {
                i40evf_set_promiscuous(adapter, 0);
                goto watchdog_done;
        }
index c5d33a2cea877752cb7c7b371b9299fdd3760f88..f13445691507c2b7ea668f402cbb04e6f65cf38c 100644 (file)
@@ -641,6 +641,7 @@ void i40evf_del_vlans(struct i40evf_adapter *adapter)
 void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags)
 {
        struct i40e_virtchnl_promisc_info vpi;
+       int promisc_all;
 
        if (adapter->current_op != I40E_VIRTCHNL_OP_UNKNOWN) {
                /* bail because we already have a command pending */
@@ -649,11 +650,21 @@ void i40evf_set_promiscuous(struct i40evf_adapter *adapter, int flags)
                return;
        }
 
-       if (flags) {
+       promisc_all = I40E_FLAG_VF_UNICAST_PROMISC |
+                     I40E_FLAG_VF_MULTICAST_PROMISC;
+       if ((flags & promisc_all) == promisc_all) {
                adapter->flags |= I40EVF_FLAG_PROMISC_ON;
                adapter->aq_required &= ~I40EVF_FLAG_AQ_REQUEST_PROMISC;
                dev_info(&adapter->pdev->dev, "Entering promiscuous mode\n");
-       } else {
+       }
+
+       if (flags & I40E_FLAG_VF_MULTICAST_PROMISC) {
+               adapter->flags |= I40EVF_FLAG_ALLMULTI_ON;
+               adapter->aq_required &= ~I40EVF_FLAG_AQ_REQUEST_ALLMULTI;
+               dev_info(&adapter->pdev->dev, "Entering multicast promiscuous mode\n");
+       }
+
+       if (!flags) {
                adapter->flags &= ~I40EVF_FLAG_PROMISC_ON;
                adapter->aq_required &= ~I40EVF_FLAG_AQ_RELEASE_PROMISC;
                dev_info(&adapter->pdev->dev, "Leaving promiscuous mode\n");