mqprio: Modify mqprio to pass user parameters via ndo_setup_tc.
authorAmritha Nambiar <amritha.nambiar@intel.com>
Wed, 15 Mar 2017 17:39:25 +0000 (10:39 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 15 Mar 2017 22:20:27 +0000 (15:20 -0700)
The configurable priority to traffic class mapping and the user specified
queue ranges are used to configure the traffic class, overriding the
hardware defaults when the 'hw' option is set to 0. However, when the 'hw'
option is non-zero, the hardware QOS defaults are used.

This patch makes it so that we can pass the data the user provided to
ndo_setup_tc. This allows us to pull in the queue configuration if the
user requested it as well as any additional hardware offload type
requested by using a value other than 1 for the hw value.

Finally it also provides a means for the device driver to return the level
supported for the offload type via the qopt->hw value. Previously we were
just always assuming the value to be 1, in the future values beyond just 1
may be supported.

Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
14 files changed:
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/sfc/falcon/tx.c
drivers/net/ethernet/sfc/tx.c
drivers/net/ethernet/ti/netcp_core.c
include/linux/netdevice.h
net/sched/sch_mqprio.c

index ffea9859f5a72be1edbfdb1d52d2c70a0df2b19e..7ec2c9717cf1d173034bf8800f5ae217df62c6c0 100644 (file)
@@ -1854,7 +1854,8 @@ static int xgbe_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
        if (tc_to_netdev->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       tc = tc_to_netdev->tc;
+       tc_to_netdev->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+       tc = tc_to_netdev->mqprio->num_tc;
 
        if (tc > pdata->hw_feat.tc_cnt)
                return -EINVAL;
index 9e8c06130c092d3f061089448797c1da74e15043..ad3e0631877e799d2b1cd8e3c07495bbb5a1fd96 100644 (file)
@@ -4277,7 +4277,10 @@ int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
 {
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
-       return bnx2x_setup_tc(dev, tc->tc);
+
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return bnx2x_setup_tc(dev, tc->mqprio->num_tc);
 }
 
 /* called with rtnl_lock */
index 32de4589d16a2cde27f2e5674b234e2b7185f00d..174ec8f846370869b4095e5418b12aeecb3793d4 100644 (file)
@@ -6905,7 +6905,9 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
        if (ntc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return bnxt_setup_mq_tc(dev, ntc->tc);
+       ntc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return bnxt_setup_mq_tc(dev, ntc->mqprio->num_tc);
 }
 
 #ifdef CONFIG_RFS_ACCEL
index aa769cbc7425e8ac57b288421686ebd9c182746f..d4bb8bf86a45977cdabf61979de5849866f159bf 100644 (file)
@@ -346,33 +346,37 @@ static int dpaa_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
                         struct tc_to_netdev *tc)
 {
        struct dpaa_priv *priv = netdev_priv(net_dev);
+       u8 num_tc;
        int i;
 
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       if (tc->tc == priv->num_tc)
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+       num_tc = tc->mqprio->num_tc;
+
+       if (num_tc == priv->num_tc)
                return 0;
 
-       if (!tc->tc) {
+       if (!num_tc) {
                netdev_reset_tc(net_dev);
                goto out;
        }
 
-       if (tc->tc > DPAA_TC_NUM) {
+       if (num_tc > DPAA_TC_NUM) {
                netdev_err(net_dev, "Too many traffic classes: max %d supported.\n",
                           DPAA_TC_NUM);
                return -EINVAL;
        }
 
-       netdev_set_num_tc(net_dev, tc->tc);
+       netdev_set_num_tc(net_dev, num_tc);
 
-       for (i = 0; i < tc->tc; i++)
+       for (i = 0; i < num_tc; i++)
                netdev_set_tc_queue(net_dev, i, DPAA_TC_TXQ_NUM,
                                    i * DPAA_TC_TXQ_NUM);
 
 out:
-       priv->num_tc = tc->tc ? tc->tc : 1;
+       priv->num_tc = num_tc ? : 1;
        netif_set_real_num_tx_queues(net_dev, priv->num_tc * DPAA_TC_TXQ_NUM);
        return 0;
 }
index 01db688cf5398d434e81c2d4016e5764bbd49820..72481670478c3b75b15f8f7f09a21d4ae0731e36 100644 (file)
@@ -1226,7 +1226,9 @@ static int __fm10k_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return fm10k_setup_tc(dev, tc->tc);
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return fm10k_setup_tc(dev, tc->mqprio->num_tc);
 }
 
 static void fm10k_assign_l2_accel(struct fm10k_intfc *interface,
index 113b32911f1badb4878619cecdaa0dd0ff97288b..9df0d86812e7ea38d731e208f27c88c127749204 100644 (file)
@@ -5611,9 +5611,12 @@ static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
                           struct tc_to_netdev *tc)
 #endif
 {
-       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
+       if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
-       return i40e_setup_tc(netdev, tc->tc);
+
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return i40e_setup_tc(netdev, tc->mqprio->num_tc);
 }
 
 /**
index a7a430a7be2cd9201cc36022249219e94bfb41ca..d45477db0227ef73c7060d3812792abab8fdfd2a 100644 (file)
@@ -8948,7 +8948,9 @@ static int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return ixgbe_setup_tc(dev, tc->tc);
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return ixgbe_setup_tc(dev, tc->mqprio->num_tc);
 }
 
 #ifdef CONFIG_PCI_IOV
index 61420473fe5fb57032fa50de9a0d2abfa71831d6..94fab20ef146bd5874a21ec2ecbe3dea16180aec 100644 (file)
@@ -92,7 +92,9 @@ static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return mlx4_en_setup_tc(dev, tc->tc);
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return mlx4_en_setup_tc(dev, tc->mqprio->num_tc);
 }
 
 #ifdef CONFIG_RFS_ACCEL
index 8ef64c4db2c21ad6a752338cb32b054a5e5f3968..f96a73ea8e0bc24a64835c28bf44c1c437c397cf 100644 (file)
@@ -2737,7 +2737,9 @@ mqprio:
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return mlx5e_setup_tc(dev, tc->tc);
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
+       return mlx5e_setup_tc(dev, tc->mqprio->num_tc);
 }
 
 static void
index 104fb15a73f2074c145878f0466d8ff1fc650167..f6daf09b86272397d35bc72d59c5269b4644db1c 100644 (file)
@@ -437,11 +437,13 @@ int ef4_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
        if (ntc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       num_tc = ntc->tc;
+       num_tc = ntc->mqprio->num_tc;
 
        if (ef4_nic_rev(efx) < EF4_REV_FALCON_B0 || num_tc > EF4_MAX_TX_TC)
                return -EINVAL;
 
+       ntc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
        if (num_tc == net_dev->num_tc)
                return 0;
 
index ff88d60aa6d5650d04f46938eaf6abc63c4ff568..3bdf87f310877a31fee219afa3de3dea91e40521 100644 (file)
@@ -665,11 +665,13 @@ int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
        if (ntc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       num_tc = ntc->tc;
+       num_tc = ntc->mqprio->num_tc;
 
        if (num_tc > EFX_MAX_TX_TC)
                return -EINVAL;
 
+       ntc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+
        if (num_tc == net_dev->num_tc)
                return 0;
 
index 7c7ae0890e90c450c2228e44cf618cdfdedcceec..9027c9c509b581cda23c00006124ff3839a6ae2c 100644 (file)
@@ -1882,6 +1882,7 @@ static u16 netcp_select_queue(struct net_device *dev, struct sk_buff *skb,
 static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
                          struct tc_to_netdev *tc)
 {
+       u8 num_tc;
        int i;
 
        /* setup tc must be called under rtnl lock */
@@ -1890,15 +1891,18 @@ static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
+       tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
+       num_tc = tc->mqprio->num_tc;
+
        /* Sanity-check the number of traffic classes requested */
        if ((dev->real_num_tx_queues <= 1) ||
-           (dev->real_num_tx_queues < tc->tc))
+           (dev->real_num_tx_queues < num_tc))
                return -EINVAL;
 
        /* Configure traffic class to queue mappings */
-       if (tc->tc) {
-               netdev_set_num_tc(dev, tc->tc);
-               for (i = 0; i < tc->tc; i++)
+       if (num_tc) {
+               netdev_set_num_tc(dev, num_tc);
+               for (i = 0; i < num_tc; i++)
                        netdev_set_tc_queue(dev, i, 1, i);
        } else {
                netdev_reset_tc(dev);
index 97456b2539e46d6232dda804f6a434db6fd7134f..b7365b5878183bbfbfcd743a74f81d943feb7d88 100644 (file)
@@ -786,11 +786,11 @@ struct tc_cls_u32_offload;
 struct tc_to_netdev {
        unsigned int type;
        union {
-               u8 tc;
                struct tc_cls_u32_offload *cls_u32;
                struct tc_cls_flower_offload *cls_flower;
                struct tc_cls_matchall_offload *cls_mall;
                struct tc_cls_bpf_offload *cls_bpf;
+               struct tc_mqprio_qopt *mqprio;
        };
        bool egress_dev;
 };
index 5f55bf149d9fb29c3d300a5bb3bd0bee82110d1d..0a4cf27ea54bd78768d4fa084f7b082460f5f266 100644 (file)
@@ -28,7 +28,6 @@ static void mqprio_destroy(struct Qdisc *sch)
 {
        struct net_device *dev = qdisc_dev(sch);
        struct mqprio_sched *priv = qdisc_priv(sch);
-       struct tc_to_netdev tc = {.type = TC_SETUP_MQPRIO};
        unsigned int ntx;
 
        if (priv->qdiscs) {
@@ -39,10 +38,15 @@ static void mqprio_destroy(struct Qdisc *sch)
                kfree(priv->qdiscs);
        }
 
-       if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc)
+       if (priv->hw_offload && dev->netdev_ops->ndo_setup_tc) {
+               struct tc_mqprio_qopt offload = { 0 };
+               struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO,
+                                          { .mqprio = &offload } };
+
                dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
-       else
+       } else {
                netdev_set_num_tc(dev, 0);
+       }
 }
 
 static int mqprio_parse_opt(struct net_device *dev, struct tc_mqprio_qopt *qopt)
@@ -144,14 +148,15 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
         * supplied and verified mapping
         */
        if (qopt->hw) {
-               struct tc_to_netdev tc = {.type = TC_SETUP_MQPRIO,
-                                         { .tc = qopt->num_tc }};
+               struct tc_mqprio_qopt offload = *qopt;
+               struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO,
+                                          { .mqprio = &offload } };
 
                err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
                if (err)
                        return err;
 
-               priv->hw_offload = qopt->hw;
+               priv->hw_offload = offload.hw;
        } else {
                netdev_set_num_tc(dev, qopt->num_tc);
                for (i = 0; i < qopt->num_tc; i++)