]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
net: rework setup_tc ndo op to consume general tc operand
authorJohn Fastabend <john.fastabend@gmail.com>
Wed, 17 Feb 2016 05:16:43 +0000 (21:16 -0800)
committerTim Gardner <tim.gardner@canonical.com>
Wed, 6 Apr 2016 09:28:54 +0000 (10:28 +0100)
BugLink: http://bugs.launchpad.net/bugs/1562326
This patch updates setup_tc so we can pass additional parameters into
the ndo op in a generic way. To do this we provide structured union
and type flag.

This lets each classifier and qdisc provide its own set of attributes
without having to add new ndo ops or grow the signature of the
callback.

Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(back ported from commit 16e5cc647173a97e33b3e3ba81f73eb455561794)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
 Conflicts:
drivers/net/ethernet/mellanox/mlx4/en_netdev.c

14 files changed:
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/i40e/i40e.h
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/sfc/efx.h
drivers/net/ethernet/sfc/tx.c
drivers/net/ethernet/ti/netcp_core.c
include/linux/netdevice.h
net/sched/sch_mqprio.c

index 8348ba4c6fab2570e4e7e782050bfcc943eabb9e..87d5376e38715d9330352018e9bf608531f1579d 100644 (file)
@@ -1626,15 +1626,18 @@ static void xgbe_poll_controller(struct net_device *netdev)
 }
 #endif /* End CONFIG_NET_POLL_CONTROLLER */
 
-static int xgbe_setup_tc(struct net_device *netdev, u32 handle, u8 tc)
+static int xgbe_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+                        struct tc_to_netdev *tc_to_netdev)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
        unsigned int offset, queue;
-       u8 i;
+       u8 i, tc;
 
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc_to_netdev->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
+       tc = tc_to_netdev->tc;
+
        if (tc && (tc != pdata->hw_feat.tc_cnt))
                return -EINVAL;
 
index 2affdf8fe30e1a8eba9da3893c61050cba43e2eb..de75d12cbb14ac6f0506d40a0aecdfaf8c90c23a 100644 (file)
@@ -4332,11 +4332,12 @@ int bnx2x_setup_tc(struct net_device *dev, u8 num_tc)
        return 0;
 }
 
-int __bnx2x_setup_tc(struct net_device *dev, u32 handle, u8 num_tc)
+int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                    struct tc_to_netdev *tc)
 {
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
-       return bnx2x_setup_tc(dev, num_tc);
+       return bnx2x_setup_tc(dev, tc->tc);
 }
 
 /* called with rtnl_lock */
index 9af249fc37ed05db34b22978a8e10d284b233712..3786f2261f8d3afb839fe14a979831a97b31e7b5 100644 (file)
@@ -486,7 +486,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /* setup_tc callback */
 int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
-int __bnx2x_setup_tc(struct net_device *dev, u32 handle, u8 num_tc);
+int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                    struct tc_to_netdev *tc);
 
 int bnx2x_get_vf_config(struct net_device *dev, int vf,
                        struct ifla_vf_info *ivi);
index 268a0af0af2acf1da6f10f7a716a969942821e3e..f3f74019fc85740081d4cff03ea760291e99c4f6 100644 (file)
@@ -5280,13 +5280,17 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-static int bnxt_setup_tc(struct net_device *dev, u32 handle, u8 tc)
+static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                        struct tc_to_netdev *ntc)
 {
        struct bnxt *bp = netdev_priv(dev);
+       u8 tc;
 
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || ntc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
+       tc = ntc->tc;
+
        if (tc > bp->max_tc) {
                netdev_err(dev, "too many traffic classes requested: %d Max supported is %d\n",
                           tc, bp->max_tc);
index 3901c0c3924e61b4120b551f9079486e9674ec0b..c1a035ff3df03b98c54eed4dffdf2f4ad413337f 100644 (file)
@@ -1204,12 +1204,13 @@ err_queueing_scheme:
        return err;
 }
 
-static int __fm10k_setup_tc(struct net_device *dev, u32 handle, u8 tc)
+static int __fm10k_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                           struct tc_to_netdev *tc)
 {
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return fm10k_setup_tc(dev, tc);
+       return fm10k_setup_tc(dev, tc->tc);
 }
 
 static int fm10k_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
index 0d8fa5a29f3fb45d6226811ab079ebfb7881e4f5..e99be9f696c39215ec13ee667db7ae1c394241ab 100644 (file)
@@ -809,7 +809,8 @@ struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr,
                                      bool is_vf, bool is_netdev);
 #ifdef I40E_FCOE
 int i40e_close(struct net_device *netdev);
-int __i40e_setup_tc(struct net_device *netdev, u32 handle, u8 tc);
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+                   struct tc_to_netdev *tc);
 void i40e_netpoll(struct net_device *netdev);
 int i40e_fcoe_enable(struct net_device *netdev);
 int i40e_fcoe_disable(struct net_device *netdev);
index d2439449849ce60bcedb88cebf7bb6374c331e05..e7a2cd667916904edf8da37e5b50126d248460d1 100644 (file)
@@ -5321,14 +5321,16 @@ exit:
 }
 
 #ifdef I40E_FCOE
-int __i40e_setup_tc(struct net_device *netdev, u32 handle, u8 tc)
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+                   struct tc_to_netdev *tc)
 #else
-static int __i40e_setup_tc(struct net_device *netdev, u32 handle, u8 tc)
+static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+                          struct tc_to_netdev *tc)
 #endif
 {
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
-       return i40e_setup_tc(netdev, tc);
+       return i40e_setup_tc(netdev, tc->tc);
 }
 
 /**
index f5c04d1cbc5119b136da7d580c4bbed8185c0e7b..3d50304625c520d1ba99b5deb885a4cef4a866da 100644 (file)
@@ -8200,13 +8200,14 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
        return 0;
 }
 
-int __ixgbe_setup_tc(struct net_device *dev, u32 handle, u8 tc)
+int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                    struct tc_to_netdev *tc)
 {
        /* Only support egress tc setup for now */
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return ixgbe_setup_tc(dev, tc);
+       return ixgbe_setup_tc(dev, tc->tc);
 }
 
 #ifdef CONFIG_PCI_IOV
index 6e74e3a71f2002a54bfd458b9bdbd7f2cbfd77ee..3cc2f76591a000203d14eea3ff68103fb1e9470d 100644 (file)
@@ -97,12 +97,13 @@ static int mlx4_en_low_latency_recv(struct napi_struct *napi)
 }
 #endif /* CONFIG_NET_RX_BUSY_POLL */
 
-static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, u8 up)
+static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                             struct tc_to_netdev *tc)
 {
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
-       return mlx4_en_setup_tc(dev, up);
+       return mlx4_en_setup_tc(dev, tc->tc);
 }
 
 #ifdef CONFIG_RFS_ACCEL
index 7815fa09b15d09613f364ec0429f7d2047e0240d..5e3f93f04e624a6b5f4e7885a625c47922766342 100644 (file)
@@ -32,7 +32,8 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
                                struct net_device *net_dev);
 netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
 void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index);
-int efx_setup_tc(struct net_device *net_dev, u32 handle, u8 num_tc);
+int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
+                struct tc_to_netdev *tc);
 unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);
 extern unsigned int efx_piobuf_size;
 extern bool efx_separate_tx_channels;
index d576bdfc0506868e0e2c884ca5e357912a466029..9980dfe27fe6610c54824c8e452c0ed945c21dd9 100644 (file)
@@ -562,17 +562,20 @@ void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue)
                                     efx->n_tx_channels : 0));
 }
 
-int efx_setup_tc(struct net_device *net_dev, u32 handle, u8 num_tc)
+int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
+                struct tc_to_netdev *ntc)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_channel *channel;
        struct efx_tx_queue *tx_queue;
-       unsigned tc;
+       unsigned tc, num_tc;
        int rc;
 
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || ntc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
+       num_tc = ntc->tc;
+
        if (efx_nic_rev(efx) < EFX_REV_FALCON_B0 || num_tc > EFX_MAX_TX_TC)
                return -EINVAL;
 
index 75b28100773e5aa1e350f0faf1625aa786b4a414..535b1a9b5893c954b6d2da2669fa6927b5555825 100644 (file)
@@ -1811,25 +1811,26 @@ static u16 netcp_select_queue(struct net_device *dev, struct sk_buff *skb,
        return 0;
 }
 
-static int netcp_setup_tc(struct net_device *dev, u32 handle, u8 num_tc)
+static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+                         struct tc_to_netdev tc)
 {
        int i;
 
        /* setup tc must be called under rtnl lock */
        ASSERT_RTNL();
 
-       if (handle != TC_H_ROOT)
+       if (handle != TC_H_ROOT || tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
        /* Sanity-check the number of traffic classes requested */
        if ((dev->real_num_tx_queues <= 1) ||
-           (dev->real_num_tx_queues < num_tc))
+           (dev->real_num_tx_queues < tc->tc))
                return -EINVAL;
 
        /* Configure traffic class to queue mappings */
-       if (num_tc) {
-               netdev_set_num_tc(dev, num_tc);
-               for (i = 0; i < num_tc; i++)
+       if (tc->tc) {
+               netdev_set_num_tc(dev, tc->tc);
+               for (i = 0; i < tc->tc; i++)
                        netdev_set_tc_queue(dev, i, 1, i);
        } else {
                netdev_reset_tc(dev);
index 167d45e56efe805b60f8c3fd7d311c53f236d93c..9a398ef249cb89171119d259eba12c620d2628dd 100644 (file)
@@ -778,6 +778,21 @@ static inline bool netdev_phys_item_id_same(struct netdev_phys_item_id *a,
 typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
                                       struct sk_buff *skb);
 
+/* This structure holds attributes of qdisc and classifiers
+ * that are being passed to the netdevice through the setup_tc op.
+ */
+enum {
+       TC_SETUP_MQPRIO,
+};
+
+struct tc_to_netdev {
+       unsigned int type;
+       union {
+               u8 tc;
+       };
+};
+
+
 /*
  * This structure defines the management hooks for network devices.
  * The following hooks can be defined; unless noted otherwise, they are
@@ -1147,7 +1162,10 @@ struct net_device_ops {
        int                     (*ndo_set_vf_rss_query_en)(
                                                   struct net_device *dev,
                                                   int vf, bool setting);
-       int                     (*ndo_setup_tc)(struct net_device *dev, u32 handle, u8 tc);
+       int                     (*ndo_setup_tc)(struct net_device *dev,
+                                               u32 handle,
+                                               __be16 protocol,
+                                               struct tc_to_netdev *tc);
 #if IS_ENABLED(CONFIG_FCOE)
        int                     (*ndo_fcoe_enable)(struct net_device *dev);
        int                     (*ndo_fcoe_disable)(struct net_device *dev);
index f5a0e8a4dbd7734c52dd22dd2ead65f53bb5693d..f9947d1f4952096049137df70974ea0a26a8fed9 100644 (file)
@@ -28,6 +28,7 @@ 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,7 +40,7 @@ static void mqprio_destroy(struct Qdisc *sch)
        }
 
        if (priv->hw_owned && dev->netdev_ops->ndo_setup_tc)
-               dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0);
+               dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
        else
                netdev_set_num_tc(dev, 0);
 }
@@ -140,9 +141,11 @@ 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};
+
                priv->hw_owned = 1;
-               err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle,
-                                                   qopt->num_tc);
+               err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
                if (err)
                        goto err;
        } else {