ixgbe: fix return values and memcpy parameters to eliminate Smatch warnings
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / intel / ixgbe / ixgbe_dcb_nl.c
index f1e002d5fa8f5dfb53c9d865dab1fd558bf7ea7b..373559010da0137604c4e2d252685a73ae21959b 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/dcbnl.h>
 #include "ixgbe_dcb_82598.h"
 #include "ixgbe_dcb_82599.h"
+#include "ixgbe_sriov.h"
 
 /* Callbacks for DCB netlink in the kernel */
 #define BIT_DCB_MODE   0x01
@@ -301,7 +302,6 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
        *setting = adapter->dcb_cfg.tc_config[priority].dcb_pfc;
 }
 
-#ifdef IXGBE_FCOE
 static void ixgbe_dcbnl_devreset(struct net_device *dev)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
@@ -320,7 +320,6 @@ static void ixgbe_dcbnl_devreset(struct net_device *dev)
 
        clear_bit(__IXGBE_RESETTING, &adapter->state);
 }
-#endif
 
 static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 {
@@ -450,7 +449,6 @@ static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
 static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       u8 rval = 0;
 
        if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
                switch (tcid) {
@@ -461,14 +459,14 @@ static int ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num)
                        *num = adapter->dcb_cfg.num_tcs.pfc_tcs;
                        break;
                default:
-                       rval = -EINVAL;
+                       return -EINVAL;
                        break;
                }
        } else {
-               rval = -EINVAL;
+               return -EINVAL;
        }
 
-       return rval;
+       return 0;
 }
 
 static int ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
@@ -541,6 +539,7 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
        int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
        int i, err = 0;
        __u8 max_tc = 0;
+       __u8 map_chg = 0;
 
        if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
                return -EINVAL;
@@ -550,15 +549,22 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
                                                  GFP_KERNEL);
                if (!adapter->ixgbe_ieee_ets)
                        return -ENOMEM;
-       }
 
-       memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
+               /* initialize UP2TC mappings to invalid value */
+               for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+                       adapter->ixgbe_ieee_ets->prio_tc[i] =
+                               IEEE_8021QAZ_MAX_TCS;
+       }
 
        for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
                if (ets->prio_tc[i] > max_tc)
                        max_tc = ets->prio_tc[i];
+               if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i])
+                       map_chg = 1;
        }
 
+       memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets));
+
        if (max_tc)
                max_tc++;
 
@@ -567,6 +573,8 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev,
 
        if (max_tc != netdev_get_num_tc(dev))
                err = ixgbe_setup_tc(dev, max_tc);
+       else if (map_chg)
+               ixgbe_dcbnl_devreset(dev);
 
        if (err)
                goto err_out;
@@ -643,9 +651,11 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
                return err;
 
        err = dcb_ieee_setapp(dev, app);
+       if (err)
+               return err;
 
 #ifdef IXGBE_FCOE
-       if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
+       if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
            app->protocol == ETH_P_FCOE) {
                u8 app_mask = dcb_ieee_getapp_mask(dev, app);
 
@@ -656,6 +666,23 @@ static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev,
                ixgbe_dcbnl_devreset(dev);
        }
 #endif
+
+       /* VF devices should use default UP when available */
+       if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
+           app->protocol == 0) {
+               int vf;
+
+               adapter->default_up = app->priority;
+
+               for (vf = 0; vf < adapter->num_vfs; vf++) {
+                       struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
+
+                       if (!vfinfo->pf_qos)
+                               ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
+                                               app->priority, vf);
+               }
+       }
+
        return 0;
 }
 
@@ -683,6 +710,24 @@ static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev,
                ixgbe_dcbnl_devreset(dev);
        }
 #endif
+       /* IF default priority is being removed clear VF default UP */
+       if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE &&
+           app->protocol == 0 && adapter->default_up == app->priority) {
+               int vf;
+               long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app);
+               int qos = app_mask ? find_first_bit(&app_mask, 8) : 0;
+
+               adapter->default_up = qos;
+
+               for (vf = 0; vf < adapter->num_vfs; vf++) {
+                       struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
+
+                       if (!vfinfo->pf_qos)
+                               ixgbe_set_vmvir(adapter, vfinfo->pf_vlan,
+                                               qos, vf);
+               }
+       }
+
        return err;
 }