}
 #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;
 
 
        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 */
 
 
 /* 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);
 
        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);
 
        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)
 
                                      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);
 
 }
 
 #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);
 }
 
 /**
 
        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
 
        return 0;
 }
 
-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
 
                                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;
 
                                     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;
 
 
        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);
 
 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
        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);
 
 {
        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) {
        }
 
        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);
 }
         * 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 {