}
 #endif /* End CONFIG_NET_POLL_CONTROLLER */
 
-static int xgbe_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+static int xgbe_setup_tc(struct net_device *netdev, u32 handle, u32 chain_index,
+                        __be16 proto,
                         struct tc_to_netdev *tc_to_netdev)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
 
        return 0;
 }
 
-int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
-                    struct tc_to_netdev *tc)
+int __bnx2x_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                    __be16 proto, struct tc_to_netdev *tc)
 {
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
 
 /* setup_tc callback */
 int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
-int __bnx2x_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
-                    struct tc_to_netdev *tc);
+int __bnx2x_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                    __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, __be16 proto,
-                        struct tc_to_netdev *ntc)
+static int bnxt_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                        __be16 proto, struct tc_to_netdev *ntc)
 {
        if (ntc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
        return err;
 }
 
-static int cxgb_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
-                        struct tc_to_netdev *tc)
+static int cxgb_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                        __be16 proto, struct tc_to_netdev *tc)
 {
        struct port_info *pi = netdev2pinfo(dev);
        struct adapter *adap = netdev2adap(dev);
 
+       if (chain_index)
+               return -EOPNOTSUPP;
+
        if (!(adap->flags & FULL_INIT_DONE)) {
                dev_err(adap->pdev_dev,
                        "Failed to setup tc on port %d. Link Down?\n",
 
        }
 }
 
-static int dpaa_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
-                        struct tc_to_netdev *tc)
+static int dpaa_setup_tc(struct net_device *net_dev, u32 handle,
+                        u32 chain_index, __be16 proto, struct tc_to_netdev *tc)
 {
        struct dpaa_priv *priv = netdev_priv(net_dev);
        u8 num_tc;
 
        return err;
 }
 
-static int __fm10k_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
-                           struct tc_to_netdev *tc)
+static int __fm10k_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                           __be16 proto, struct tc_to_netdev *tc)
 {
        if (tc->type != TC_SETUP_MQPRIO)
                return -EINVAL;
 
        return ret;
 }
 
-static int __i40e_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
+static int __i40e_setup_tc(struct net_device *netdev, u32 handle,
+                          u32 chain_index, __be16 proto,
                           struct tc_to_netdev *tc)
 {
        if (tc->type != TC_SETUP_MQPRIO)
 
        return err;
 }
 
-static int __ixgbe_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
-                           struct tc_to_netdev *tc)
+static int __ixgbe_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                           __be16 proto, struct tc_to_netdev *tc)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
 
+       if (chain_index)
+               return -EOPNOTSUPP;
+
        if (TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS) &&
            tc->type == TC_SETUP_CLSU32) {
                switch (tc->cls_u32->command) {
 
        return 0;
 }
 
-static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
+static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle,
+                             u32 chain_index, __be16 proto,
                              struct tc_to_netdev *tc)
 {
        if (tc->type != TC_SETUP_MQPRIO)
 
 }
 
 static int mlx5e_ndo_setup_tc(struct net_device *dev, u32 handle,
-                             __be16 proto, struct tc_to_netdev *tc)
+                             u32 chain_index, __be16 proto,
+                             struct tc_to_netdev *tc)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
 
        if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
                goto mqprio;
 
+       if (chain_index)
+               return -EOPNOTSUPP;
+
        switch (tc->type) {
        case TC_SETUP_CLSFLOWER:
                switch (tc->cls_flower->command) {
 
 }
 
 static int mlx5e_rep_ndo_setup_tc(struct net_device *dev, u32 handle,
-                                 __be16 proto, struct tc_to_netdev *tc)
+                                 u32 chain_index, __be16 proto,
+                                 struct tc_to_netdev *tc)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
 
                struct net_device *uplink_dev = mlx5_eswitch_get_uplink_netdev(esw);
 
                return uplink_dev->netdev_ops->ndo_setup_tc(uplink_dev, handle,
+                                                           chain_index,
                                                            proto, tc);
        }
 
+       if (chain_index)
+               return -EOPNOTSUPP;
+
        switch (tc->type) {
        case TC_SETUP_CLSFLOWER:
                switch (tc->cls_flower->command) {
 
 }
 
 static int mlxsw_sp_setup_tc(struct net_device *dev, u32 handle,
-                            __be16 proto, struct tc_to_netdev *tc)
+                            u32 chain_index, __be16 proto,
+                            struct tc_to_netdev *tc)
 {
        struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
        bool ingress = TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS);
 
+       if (chain_index)
+               return -EOPNOTSUPP;
+
        switch (tc->type) {
        case TC_SETUP_MATCHALL:
                switch (tc->cls_mall->command) {
 
 }
 
 static int
-nfp_net_setup_tc(struct net_device *netdev, u32 handle, __be16 proto,
-                struct tc_to_netdev *tc)
+nfp_net_setup_tc(struct net_device *netdev, u32 handle, u32 chain_index,
+                __be16 proto, struct tc_to_netdev *tc)
 {
        struct nfp_net *nn = netdev_priv(netdev);
 
+       if (chain_index)
+               return -EOPNOTSUPP;
+
        return nfp_app_setup_tc(nn->app, netdev, handle, proto, tc);
 }
 
 
                                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, __be16 proto,
-                struct tc_to_netdev *tc);
+int efx_setup_tc(struct net_device *net_dev, u32 handle, u32 chain_index,
+                __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;
 
                                struct net_device *net_dev);
 netdev_tx_t ef4_enqueue_skb(struct ef4_tx_queue *tx_queue, struct sk_buff *skb);
 void ef4_xmit_done(struct ef4_tx_queue *tx_queue, unsigned int index);
-int ef4_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
-                struct tc_to_netdev *tc);
+int ef4_setup_tc(struct net_device *net_dev, u32 handle, u32 chain_index,
+                __be16 proto, struct tc_to_netdev *tc);
 unsigned int ef4_tx_max_skb_descs(struct ef4_nic *efx);
 extern bool ef4_separate_tx_channels;
 
 
                                     efx->n_tx_channels : 0));
 }
 
-int ef4_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
-                struct tc_to_netdev *ntc)
+int ef4_setup_tc(struct net_device *net_dev, u32 handle, u32 chain_index,
+                __be16 proto, struct tc_to_netdev *ntc)
 {
        struct ef4_nic *efx = netdev_priv(net_dev);
        struct ef4_channel *channel;
 
                                     efx->n_tx_channels : 0));
 }
 
-int efx_setup_tc(struct net_device *net_dev, u32 handle, __be16 proto,
-                struct tc_to_netdev *ntc)
+int efx_setup_tc(struct net_device *net_dev, u32 handle, u32 chain_index,
+                __be16 proto, struct tc_to_netdev *ntc)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_channel *channel;
 
        return 0;
 }
 
-static int netcp_setup_tc(struct net_device *dev, u32 handle, __be16 proto,
-                         struct tc_to_netdev *tc)
+static int netcp_setup_tc(struct net_device *dev, u32 handle, u32 chain_index,
+                         __be16 proto, struct tc_to_netdev *tc)
 {
        u8 num_tc;
        int i;
 
  *      with PF and querying it may introduce a theoretical security risk.
  * int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting);
  * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
- * int (*ndo_setup_tc)(struct net_device *dev, u32 handle,
+ * int (*ndo_setup_tc)(struct net_device *dev, u32 handle, u32 chain_index,
  *                    __be16 protocol, struct tc_to_netdev *tc);
  *     Called to setup any 'tc' scheduler, classifier or action on @dev.
  *     This is always called from the stack with the rtnl lock held and netif
                                                   struct net_device *dev,
                                                   int vf, bool setting);
        int                     (*ndo_setup_tc)(struct net_device *dev,
-                                               u32 handle,
+                                               u32 handle, u32 chain_index,
                                                __be16 protocol,
                                                struct tc_to_netdev *tc);
 #if IS_ENABLED(CONFIG_FCOE)
 
 }
 
 static int dsa_slave_setup_tc(struct net_device *dev, u32 handle,
-                             __be16 protocol, struct tc_to_netdev *tc)
+                             u32 chain_index, __be16 protocol,
+                             struct tc_to_netdev *tc)
 {
        bool ingress = TC_H_MAJ(handle) == TC_H_MAJ(TC_H_INGRESS);
-       int ret = -EOPNOTSUPP;
+
+       if (chain_index)
+               return -EOPNOTSUPP;
 
        switch (tc->type) {
        case TC_SETUP_MATCHALL:
                        return 0;
                }
        default:
-               break;
+               return -EOPNOTSUPP;
        }
-
-       return ret;
 }
 
 void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops)
 
        bpf_offload.gen_flags = prog->gen_flags;
 
        err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+                                           tp->chain->index,
                                            tp->protocol, &offload);
 
        if (!err && (cmd == TC_CLSBPF_ADD || cmd == TC_CLSBPF_REPLACE))
 
        tc->type = TC_SETUP_CLSFLOWER;
        tc->cls_flower = &offload;
 
-       dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, tc);
+       dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->chain->index,
+                                     tp->protocol, tc);
 }
 
 static int fl_hw_replace_filter(struct tcf_proto *tp,
        tc->type = TC_SETUP_CLSFLOWER;
        tc->cls_flower = &offload;
 
-       err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
-                                           tc);
+       err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+                                           tp->chain->index, tp->protocol, tc);
        if (!err)
                f->flags |= TCA_CLS_FLAGS_IN_HW;
 
        tc->type = TC_SETUP_CLSFLOWER;
        tc->cls_flower = &offload;
 
-       dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, tc);
+       dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+                                     tp->chain->index, tp->protocol, tc);
 }
 
 static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f)
 
        offload.cls_mall->exts = &head->exts;
        offload.cls_mall->cookie = cookie;
 
-       err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
-                                           &offload);
+       err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
+                                           tp->chain->index,
+                                           tp->protocol, &offload);
        if (!err)
                head->flags |= TCA_CLS_FLAGS_IN_HW;
 
        offload.cls_mall->exts = NULL;
        offload.cls_mall->cookie = cookie;
 
-       dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol,
-                                            &offload);
+       dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->chain->index,
+                                     tp->protocol, &offload);
 }
 
 static void mall_destroy(struct tcf_proto *tp)
 
                offload.cls_u32->command = TC_CLSU32_DELETE_KNODE;
                offload.cls_u32->knode.handle = handle;
                dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
-                                             tp->protocol, &offload);
+                                             tp->chain->index, tp->protocol,
+                                             &offload);
        }
 }
 
        offload.cls_u32->hnode.prio = h->prio;
 
        err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
-                                           tp->protocol, &offload);
+                                           tp->chain->index, tp->protocol,
+                                           &offload);
        if (tc_skip_sw(flags))
                return err;
 
                offload.cls_u32->hnode.prio = h->prio;
 
                dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
-                                             tp->protocol, &offload);
+                                             tp->chain->index, tp->protocol,
+                                             &offload);
        }
 }
 
                offload.cls_u32->knode.link_handle = n->ht_down->handle;
 
        err = dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle,
-                                           tp->protocol, &offload);
+                                           tp->chain->index, tp->protocol,
+                                           &offload);
 
        if (!err)
                n->flags |= TCA_CLS_FLAGS_IN_HW;
 
                struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO,
                                           { .mqprio = &offload } };
 
-               dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
+               dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, 0, &tc);
        } else {
                netdev_set_num_tc(dev, 0);
        }
                struct tc_to_netdev tc = { .type = TC_SETUP_MQPRIO,
                                           { .mqprio = &offload } };
 
-               err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0, &tc);
+               err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle,
+                                                   0, 0, &tc);
                if (err)
                        return err;