net: rework ndo tc op to consume additional qdisc handle parameter
authorJohn Fastabend <john.fastabend@gmail.com>
Wed, 17 Feb 2016 05:16:15 +0000 (21:16 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Feb 2016 14:47:35 +0000 (09:47 -0500)
The ndo_setup_tc() op was added to support drivers offloading tx
qdiscs however only support for mqprio was ever added. So we
only ever added support for passing the number of traffic classes
to the driver.

This patch generalizes the ndo_setup_tc op so that a handle can
be provided to indicate if the offload is for ingress or egress
or potentially even child qdiscs.

CC: Murali Karicheri <m-karicheri2@ti.com>
CC: Shradha Shah <sshah@solarflare.com>
CC: Or Gerlitz <ogerlitz@mellanox.com>
CC: Ariel Elior <ariel.elior@qlogic.com>
CC: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
CC: Bruce Allan <bruce.w.allan@intel.com>
CC: Jesse Brandeburg <jesse.brandeburg@intel.com>
CC: Don Skidmore <donald.c.skidmore@intel.com>
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>
16 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/bnx2x/bnx2x_main.c
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_fcoe.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/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 8a9b493566c90f9443099f94146945931f61c3b4..9955cae3cabc54e19333d995c6010b7bc3dddf95 100644 (file)
@@ -1626,12 +1626,15 @@ static void xgbe_poll_controller(struct net_device *netdev)
 }
 #endif /* End CONFIG_NET_POLL_CONTROLLER */
 
-static int xgbe_setup_tc(struct net_device *netdev, u8 tc)
+static int xgbe_setup_tc(struct net_device *netdev, u32 handle, u8 tc)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
        unsigned int offset, queue;
        u8 i;
 
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
        if (tc && (tc != pdata->hw_feat.tc_cnt))
                return -EINVAL;
 
index 9e42bcaf991760e41e2776092e0676ae0da22ae9..b262cba34dfae8bf634f43bfacd67f695b85a1cb 100644 (file)
@@ -4272,6 +4272,13 @@ 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)
+{
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+       return bnx2x_setup_tc(dev, num_tc);
+}
+
 /* called with rtnl_lock */
 int bnx2x_change_mac_addr(struct net_device *dev, void *p)
 {
index 37369865ca6d86ba787f23da19210421d9a92091..60a4109dcdebe8a9d2ae8fa6b73de01d8145ce7d 100644 (file)
@@ -486,6 +486,7 @@ 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_get_vf_config(struct net_device *dev, int vf,
                        struct ifla_vf_info *ivi);
index c5845252c920bede9f75c8a4b34a8ba58336aee5..81fc51c4ec2ba9e59069427032fc01d170361d05 100644 (file)
@@ -13061,7 +13061,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = poll_bnx2x,
 #endif
-       .ndo_setup_tc           = bnx2x_setup_tc,
+       .ndo_setup_tc           = __bnx2x_setup_tc,
 #ifdef CONFIG_BNX2X_SRIOV
        .ndo_set_vf_mac         = bnx2x_set_vf_mac,
        .ndo_set_vf_vlan        = bnx2x_set_vf_vlan,
index 5dc89e527e7deefe04c831d9ec556ed76ac40d26..ff08faf44ee557c7ffaef2dae713a5f4b642b1e4 100644 (file)
@@ -5370,10 +5370,13 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-static int bnxt_setup_tc(struct net_device *dev, u8 tc)
+static int bnxt_setup_tc(struct net_device *dev, u32 handle, u8 tc)
 {
        struct bnxt *bp = netdev_priv(dev);
 
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
        if (tc > bp->max_tc) {
                netdev_err(dev, "too many traffic classes requested: %d Max supported is %d\n",
                           tc, bp->max_tc);
index 662569d5b7c01a0af679fcecb147270a9c8f0c7c..12701a4923253a39b9cf76779e6779772c6c3c1d 100644 (file)
@@ -1204,6 +1204,14 @@ err_queueing_scheme:
        return err;
 }
 
+static int __fm10k_setup_tc(struct net_device *dev, u32 handle, u8 tc)
+{
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
+       return fm10k_setup_tc(dev, tc);
+}
+
 static int fm10k_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
        switch (cmd) {
@@ -1386,7 +1394,7 @@ static const struct net_device_ops fm10k_netdev_ops = {
        .ndo_vlan_rx_kill_vid   = fm10k_vlan_rx_kill_vid,
        .ndo_set_rx_mode        = fm10k_set_rx_mode,
        .ndo_get_stats64        = fm10k_get_stats64,
-       .ndo_setup_tc           = fm10k_setup_tc,
+       .ndo_setup_tc           = __fm10k_setup_tc,
        .ndo_set_vf_mac         = fm10k_ndo_set_vf_mac,
        .ndo_set_vf_vlan        = fm10k_ndo_set_vf_vlan,
        .ndo_set_vf_rate        = fm10k_ndo_set_vf_bw,
index 53ed3bdd836311be4b0b4e2c383e8a2e04c311fa..ef9ca075d5e504ceeb46c21b2463c3deca213246 100644 (file)
@@ -788,7 +788,7 @@ 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, u8 tc);
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, u8 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 579a46ca82dfa3bce548b7ae81527b064d7b1509..7c66ce416ec79c8d7034eac63a2440490c4b06a3 100644 (file)
@@ -1457,7 +1457,7 @@ static const struct net_device_ops i40e_fcoe_netdev_ops = {
        .ndo_tx_timeout         = i40e_tx_timeout,
        .ndo_vlan_rx_add_vid    = i40e_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = i40e_vlan_rx_kill_vid,
-       .ndo_setup_tc           = i40e_setup_tc,
+       .ndo_setup_tc           = __i40e_setup_tc,
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = i40e_netpoll,
index 320b0491abd95db56a7d71028fba3585acd20134..abcb6c152186fa6dd59f0982b31828634977eee5 100644 (file)
@@ -5253,11 +5253,7 @@ void i40e_down(struct i40e_vsi *vsi)
  * @netdev: net device to configure
  * @tc: number of traffic classes to enable
  **/
-#ifdef I40E_FCOE
-int i40e_setup_tc(struct net_device *netdev, u8 tc)
-#else
 static int i40e_setup_tc(struct net_device *netdev, u8 tc)
-#endif
 {
        struct i40e_netdev_priv *np = netdev_priv(netdev);
        struct i40e_vsi *vsi = np->vsi;
@@ -5310,6 +5306,17 @@ exit:
        return ret;
 }
 
+#ifdef I40E_FCOE
+int __i40e_setup_tc(struct net_device *netdev, u32 handle, u8 tc)
+#else
+static int __i40e_setup_tc(struct net_device *netdev, u32 handle, u8 tc)
+#endif
+{
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+       return i40e_setup_tc(netdev, tc);
+}
+
 /**
  * i40e_open - Called when a network interface is made active
  * @netdev: network interface device structure
@@ -8951,7 +8958,7 @@ static const struct net_device_ops i40e_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = i40e_netpoll,
 #endif
-       .ndo_setup_tc           = i40e_setup_tc,
+       .ndo_setup_tc           = __i40e_setup_tc,
 #ifdef I40E_FCOE
        .ndo_fcoe_enable        = i40e_fcoe_enable,
        .ndo_fcoe_disable       = i40e_fcoe_disable,
index 0c701b8438b6e5ff4f2eddbebc76df0fe855846c..1ba714efd78c48c91a674d2e5d7493637ae01ed0 100644 (file)
@@ -8200,6 +8200,15 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
        return 0;
 }
 
+int __ixgbe_setup_tc(struct net_device *dev, u32 handle, u8 tc)
+{
+       /* Only support egress tc setup for now */
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
+       return ixgbe_setup_tc(dev, tc);
+}
+
 #ifdef CONFIG_PCI_IOV
 void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter)
 {
@@ -8658,7 +8667,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_get_vf_config      = ixgbe_ndo_get_vf_config,
        .ndo_get_stats64        = ixgbe_get_stats64,
 #ifdef CONFIG_IXGBE_DCB
-       .ndo_setup_tc           = ixgbe_setup_tc,
+       .ndo_setup_tc           = __ixgbe_setup_tc,
 #endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = ixgbe_netpoll,
index 0c7e3f69a73bb6f787b8387efd3d34624a188568..d5c6c16b9457618d94d59773bc85de21e4454f1f 100644 (file)
@@ -69,6 +69,14 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up)
        return 0;
 }
 
+static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle, u8 up)
+{
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
+       return mlx4_en_setup_tc(dev, up);
+}
+
 #ifdef CONFIG_RFS_ACCEL
 
 struct mlx4_en_filter {
@@ -2466,7 +2474,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
 #endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
-       .ndo_setup_tc           = mlx4_en_setup_tc,
+       .ndo_setup_tc           = __mlx4_en_setup_tc,
 #ifdef CONFIG_RFS_ACCEL
        .ndo_rx_flow_steer      = mlx4_en_filter_rfs,
 #endif
@@ -2504,7 +2512,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
 #endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
-       .ndo_setup_tc           = mlx4_en_setup_tc,
+       .ndo_setup_tc           = __mlx4_en_setup_tc,
 #ifdef CONFIG_RFS_ACCEL
        .ndo_rx_flow_steer      = mlx4_en_filter_rfs,
 #endif
index 10827476bc0b38237b9b6999a31a907cd330cf9e..7815fa09b15d09613f364ec0429f7d2047e0240d 100644 (file)
@@ -32,7 +32,7 @@ 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, u8 num_tc);
+int efx_setup_tc(struct net_device *net_dev, u32 handle, u8 num_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 f7a0ec1bca97d96a4debc2324ad944380726cca6..8f1d53e2aca73946317acb9f00bf1f904254655e 100644 (file)
@@ -562,7 +562,7 @@ 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, u8 num_tc)
+int efx_setup_tc(struct net_device *net_dev, u32 handle, u8 num_tc)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
        struct efx_channel *channel;
@@ -570,6 +570,9 @@ int efx_setup_tc(struct net_device *net_dev, u8 num_tc)
        unsigned tc;
        int rc;
 
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
        if (efx_nic_rev(efx) < EFX_REV_FALCON_B0 || num_tc > EFX_MAX_TX_TC)
                return -EINVAL;
 
index c61d66d386346a2eda12b8fab2efaa8760b3fff3..40cde814608b7147daeae2488d2bbddf93b74495 100644 (file)
@@ -1835,13 +1835,16 @@ static u16 netcp_select_queue(struct net_device *dev, struct sk_buff *skb,
        return 0;
 }
 
-static int netcp_setup_tc(struct net_device *dev, u8 num_tc)
+static int netcp_setup_tc(struct net_device *dev, u32 handle, u8 num_tc)
 {
        int i;
 
        /* setup tc must be called under rtnl lock */
        ASSERT_RTNL();
 
+       if (handle != TC_H_ROOT)
+               return -EINVAL;
+
        /* Sanity-check the number of traffic classes requested */
        if ((dev->real_num_tx_queues <= 1) ||
            (dev->real_num_tx_queues < num_tc))
index 0499569c256d09aa16152a99b128bfa59c2c27d9..48928b6f9cb6a153eae00a3c2a55f53402ed6074 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/neighbour.h>
 #include <uapi/linux/netdevice.h>
 #include <uapi/linux/if_bonding.h>
+#include <uapi/linux/pkt_cls.h>
 
 struct netpoll_info;
 struct device;
@@ -1150,7 +1151,7 @@ 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, u8 tc);
+       int                     (*ndo_setup_tc)(struct net_device *dev, u32 handle, u8 tc);
 #if IS_ENABLED(CONFIG_FCOE)
        int                     (*ndo_fcoe_enable)(struct net_device *dev);
        int                     (*ndo_fcoe_disable)(struct net_device *dev);
index ad70ecf57ce793d7b50b50e9220c24fa4ab30ab5..f5a0e8a4dbd7734c52dd22dd2ead65f53bb5693d 100644 (file)
@@ -39,7 +39,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, 0);
+               dev->netdev_ops->ndo_setup_tc(dev, sch->handle, 0);
        else
                netdev_set_num_tc(dev, 0);
 }
@@ -141,7 +141,8 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
         */
        if (qopt->hw) {
                priv->hw_owned = 1;
-               err = dev->netdev_ops->ndo_setup_tc(dev, qopt->num_tc);
+               err = dev->netdev_ops->ndo_setup_tc(dev, sch->handle,
+                                                   qopt->num_tc);
                if (err)
                        goto err;
        } else {