]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
net/mlx5e: Vxlan, move vxlan logic to core driver
authorSaeed Mahameed <saeedm@mellanox.com>
Wed, 9 May 2018 20:28:00 +0000 (13:28 -0700)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 27 Jul 2018 22:46:13 +0000 (15:46 -0700)
Move vxlan logic and objects to mlx5 core dirver.
Since it going to be used from different mlx5 interfaces.
e.g. mlx5e PF NIC netdev and mlx5e E-Switch representors.

Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/Makefile
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h [new file with mode: 0644]
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c [deleted file]
drivers/net/ethernet/mellanox/mlx5/core/vxlan.h [deleted file]
include/linux/mlx5/driver.h

index ae2bdcb1647ce3d422efadaee3c3841f2604b1d1..f20fda1ced4f57d4ca0cd04f2a5264071012bb7f 100644 (file)
@@ -14,8 +14,8 @@ mlx5_core-$(CONFIG_MLX5_FPGA) += fpga/cmd.o fpga/core.o fpga/conn.o fpga/sdk.o \
                fpga/ipsec.o fpga/tls.o
 
 mlx5_core-$(CONFIG_MLX5_CORE_EN) += en_main.o en_common.o en_fs.o en_ethtool.o \
-               en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o vxlan.o \
-               en_arfs.o en_fs_ethtool.o en_selftest.o en/port.o
+               en_tx.o en_rx.o en_dim.o en_txrx.o en/xdp.o en_stats.o \
+               en_arfs.o en_fs_ethtool.o en_selftest.o en/port.o lib/vxlan.o
 
 mlx5_core-$(CONFIG_MLX5_MPFS) += lib/mpfs.o
 
index 1bd4536b9061e5e6394b784bde9f47235ac557a1..c7ed3d20fd54b7924f8622e7606f80e68d21e2ab 100644 (file)
@@ -52,7 +52,6 @@
 #include "wq.h"
 #include "mlx5_core.h"
 #include "en_stats.h"
-#include "vxlan.h"
 
 struct page_pool;
 
@@ -812,7 +811,6 @@ struct mlx5e_priv {
        u32                        tx_rates[MLX5E_MAX_NUM_SQS];
 
        struct mlx5e_flow_steering fs;
-       struct mlx5_vxlan          *vxlan;
 
        struct workqueue_struct    *wq;
        struct work_struct         update_carrier_work;
index ef4b2f0c427c98748c2909acb1b9cd863f420a8b..fde35021a257ef01e7f98803fc4737bca2c8553e 100644 (file)
@@ -45,7 +45,7 @@
 #include "en_accel/tls.h"
 #include "accel/ipsec.h"
 #include "accel/tls.h"
-#include "vxlan.h"
+#include "lib/vxlan.h"
 #include "en/port.h"
 #include "en/xdp.h"
 
@@ -2974,7 +2974,7 @@ int mlx5e_open(struct net_device *netdev)
                mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
        mutex_unlock(&priv->state_lock);
 
-       if (mlx5_vxlan_allowed(priv->vxlan))
+       if (mlx5_vxlan_allowed(priv->mdev->vxlan))
                udp_tunnel_get_rx_info(netdev);
 
        return err;
@@ -3983,7 +3983,7 @@ static void mlx5e_vxlan_add_work(struct work_struct *work)
        u16 port = vxlan_work->port;
 
        mutex_lock(&priv->state_lock);
-       mlx5_vxlan_add_port(priv->vxlan, port);
+       mlx5_vxlan_add_port(priv->mdev->vxlan, port);
        mutex_unlock(&priv->state_lock);
 
        kfree(vxlan_work);
@@ -3997,7 +3997,7 @@ static void mlx5e_vxlan_del_work(struct work_struct *work)
        u16 port = vxlan_work->port;
 
        mutex_lock(&priv->state_lock);
-       mlx5_vxlan_del_port(priv->vxlan, port);
+       mlx5_vxlan_del_port(priv->mdev->vxlan, port);
        mutex_unlock(&priv->state_lock);
        kfree(vxlan_work);
 }
@@ -4028,7 +4028,7 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev,
        if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
                return;
 
-       if (!mlx5_vxlan_allowed(priv->vxlan))
+       if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
                return;
 
        mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
@@ -4042,7 +4042,7 @@ static void mlx5e_del_vxlan_port(struct net_device *netdev,
        if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
                return;
 
-       if (!mlx5_vxlan_allowed(priv->vxlan))
+       if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
                return;
 
        mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
@@ -4076,7 +4076,7 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
                port = be16_to_cpu(udph->dest);
 
                /* Verify if UDP port is being offloaded by HW */
-               if (mlx5_vxlan_lookup_port(priv->vxlan, port))
+               if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
                        return features;
        }
 
@@ -4648,7 +4648,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
        netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_FILTER;
        netdev->hw_features      |= NETIF_F_HW_VLAN_STAG_TX;
 
-       if (mlx5_vxlan_allowed(priv->vxlan) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
+       if (mlx5_vxlan_allowed(mdev->vxlan) || MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
                netdev->hw_enc_features |= NETIF_F_IP_CSUM;
                netdev->hw_enc_features |= NETIF_F_IPV6_CSUM;
                netdev->hw_enc_features |= NETIF_F_TSO;
@@ -4656,7 +4656,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
                netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
        }
 
-       if (mlx5_vxlan_allowed(priv->vxlan)) {
+       if (mlx5_vxlan_allowed(mdev->vxlan)) {
                netdev->hw_features     |= NETIF_F_GSO_UDP_TUNNEL |
                                           NETIF_F_GSO_UDP_TUNNEL_CSUM;
                netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
@@ -4758,8 +4758,6 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
        struct mlx5e_priv *priv = netdev_priv(netdev);
        int err;
 
-       priv->vxlan = mlx5_vxlan_create(mdev);
-
        mlx5e_build_nic_netdev_priv(mdev, netdev, profile, ppriv);
        err = mlx5e_ipsec_init(priv);
        if (err)
@@ -4773,7 +4771,6 @@ static void mlx5e_nic_init(struct mlx5_core_dev *mdev,
 
 static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
 {
-       mlx5_vxlan_destroy(priv->vxlan);
        mlx5e_tls_cleanup(priv);
        mlx5e_ipsec_cleanup(priv);
 }
index 1b4931b62094c6eefcba271827ad52f8628fa77b..288a57f76e84308f50dbca9b1e12704e97105d13 100644 (file)
@@ -50,7 +50,7 @@
 #include "en_rep.h"
 #include "en_tc.h"
 #include "eswitch.h"
-#include "vxlan.h"
+#include "lib/vxlan.h"
 #include "fs_core.h"
 #include "en/port.h"
 
@@ -1133,7 +1133,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
                if (memchr_inv(&mask->dst, 0xff, sizeof(mask->dst)))
                        goto vxlan_match_offload_err;
 
-               if (mlx5_vxlan_lookup_port(up_priv->vxlan, be16_to_cpu(key->dst)) &&
+               if (mlx5_vxlan_lookup_port(up_priv->mdev->vxlan, be16_to_cpu(key->dst)) &&
                    MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
                        parse_vxlan_attr(spec, f);
                else {
@@ -2557,7 +2557,7 @@ vxlan_encap_offload_err:
                return -EOPNOTSUPP;
        }
 
-       if (mlx5_vxlan_lookup_port(up_priv->vxlan, be16_to_cpu(key->tp_dst)) &&
+       if (mlx5_vxlan_lookup_port(up_priv->mdev->vxlan, be16_to_cpu(key->tp_dst)) &&
            MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap)) {
                tunnel_type = MLX5_HEADER_TYPE_VXLAN;
        } else {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
new file mode 100644 (file)
index 0000000..9a8fd76
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies, Ltd.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mlx5/driver.h>
+#include "mlx5_core.h"
+#include "vxlan.h"
+
+struct mlx5_vxlan {
+       struct mlx5_core_dev            *mdev;
+       spinlock_t                      lock; /* protect vxlan table */
+       /* max_num_ports is usuallly 4, 16 buckets is more than enough */
+       DECLARE_HASHTABLE(htable, 4);
+       int                             num_ports;
+       struct mutex                    sync_lock; /* sync add/del port HW operations */
+};
+
+struct mlx5_vxlan_port {
+       struct hlist_node hlist;
+       atomic_t refcount;
+       u16 udp_port;
+};
+
+static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
+{
+       return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
+}
+
+static int mlx5_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
+{
+       u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)] = {0};
+
+       MLX5_SET(add_vxlan_udp_dport_in, in, opcode,
+                MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT);
+       MLX5_SET(add_vxlan_udp_dport_in, in, vxlan_udp_port, port);
+       return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+}
+
+static int mlx5_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
+{
+       u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)]   = {0};
+       u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)] = {0};
+
+       MLX5_SET(delete_vxlan_udp_dport_in, in, opcode,
+                MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
+       MLX5_SET(delete_vxlan_udp_dport_in, in, vxlan_udp_port, port);
+       return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
+}
+
+static struct mlx5_vxlan_port*
+mlx5_vxlan_lookup_port_locked(struct mlx5_vxlan *vxlan, u16 port)
+{
+       struct mlx5_vxlan_port *vxlanp;
+
+       hash_for_each_possible(vxlan->htable, vxlanp, hlist, port) {
+               if (vxlanp->udp_port == port)
+                       return vxlanp;
+       }
+
+       return NULL;
+}
+
+struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port)
+{
+       struct mlx5_vxlan_port *vxlanp;
+
+       if (!mlx5_vxlan_allowed(vxlan))
+               return NULL;
+
+       spin_lock_bh(&vxlan->lock);
+       vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
+       spin_unlock_bh(&vxlan->lock);
+
+       return vxlanp;
+}
+
+int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
+{
+       struct mlx5_vxlan_port *vxlanp;
+       int ret = -ENOSPC;
+
+       vxlanp = mlx5_vxlan_lookup_port(vxlan, port);
+       if (vxlanp) {
+               atomic_inc(&vxlanp->refcount);
+               return 0;
+       }
+
+       mutex_lock(&vxlan->sync_lock);
+       if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
+               mlx5_core_info(vxlan->mdev,
+                              "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
+                              port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
+               ret = -ENOSPC;
+               goto unlock;
+       }
+
+       ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
+       if (ret)
+               goto unlock;
+
+       vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
+       if (!vxlanp) {
+               ret = -ENOMEM;
+               goto err_delete_port;
+       }
+
+       vxlanp->udp_port = port;
+       atomic_set(&vxlanp->refcount, 1);
+
+       spin_lock_bh(&vxlan->lock);
+       hash_add(vxlan->htable, &vxlanp->hlist, port);
+       spin_unlock_bh(&vxlan->lock);
+
+       vxlan->num_ports++;
+       mutex_unlock(&vxlan->sync_lock);
+       return 0;
+
+err_delete_port:
+       mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
+
+unlock:
+       mutex_unlock(&vxlan->sync_lock);
+       return ret;
+}
+
+int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
+{
+       struct mlx5_vxlan_port *vxlanp;
+       bool remove = false;
+       int ret = 0;
+
+       mutex_lock(&vxlan->sync_lock);
+
+       spin_lock_bh(&vxlan->lock);
+       vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
+       if (!vxlanp) {
+               ret = -ENOENT;
+               goto out_unlock;
+       }
+
+       if (atomic_dec_and_test(&vxlanp->refcount)) {
+               hash_del(&vxlanp->hlist);
+               remove = true;
+       }
+
+out_unlock:
+       spin_unlock_bh(&vxlan->lock);
+
+       if (remove) {
+               mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
+               kfree(vxlanp);
+               vxlan->num_ports--;
+       }
+
+       mutex_unlock(&vxlan->sync_lock);
+
+       return ret;
+}
+
+struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev)
+{
+       struct mlx5_vxlan *vxlan;
+
+       if (!MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) || !mlx5_core_is_pf(mdev))
+               return ERR_PTR(-ENOTSUPP);
+
+       vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL);
+       if (!vxlan)
+               return ERR_PTR(-ENOMEM);
+
+       vxlan->mdev = mdev;
+       mutex_init(&vxlan->sync_lock);
+       spin_lock_init(&vxlan->lock);
+       hash_init(vxlan->htable);
+
+       /* Hardware adds 4789 by default */
+       mlx5_vxlan_add_port(vxlan, 4789);
+
+       return vxlan;
+}
+
+void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan)
+{
+       struct mlx5_vxlan_port *vxlanp;
+       struct hlist_node *tmp;
+       int bkt;
+
+       if (!mlx5_vxlan_allowed(vxlan))
+               return;
+
+       /* Lockless since we are the only hash table consumers*/
+       hash_for_each_safe(vxlan->htable, bkt, tmp, vxlanp, hlist) {
+               hash_del(&vxlanp->hlist);
+               mlx5_vxlan_core_del_port_cmd(vxlan->mdev, vxlanp->udp_port);
+               kfree(vxlanp);
+       }
+
+       kfree(vxlan);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.h
new file mode 100644 (file)
index 0000000..fd874a3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Mellanox Technologies, Ltd.  All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef __MLX5_VXLAN_H__
+#define __MLX5_VXLAN_H__
+
+#include <linux/mlx5/driver.h>
+
+struct mlx5_vxlan;
+struct mlx5_vxlan_port;
+
+#ifdef CONFIG_MLX5_CORE_EN
+
+static inline bool mlx5_vxlan_allowed(struct mlx5_vxlan *vxlan)
+{
+       /* not allowed reason is encoded in vxlan pointer as error,
+        * on mlx5_vxlan_create
+        */
+       return !IS_ERR_OR_NULL(vxlan);
+}
+
+struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev);
+void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan);
+int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port);
+int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port);
+struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port);
+
+#else
+
+static inline struct mlx5_vxlan*
+mlx5_vxlan_create(struct mlx5_core_dev *mdev) { return ERR_PTR(-ENOTSUPP); }
+static inline void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan) { return; }
+
+#endif
+
+#endif /* __MLX5_VXLAN_H__ */
index 6ddbb70e95deff33a69fc9708f37287b97f1d656..03b9c6733eedffb34165c83e817f1ab23484b111 100644 (file)
@@ -62,6 +62,7 @@
 #include "accel/ipsec.h"
 #include "accel/tls.h"
 #include "lib/clock.h"
+#include "lib/vxlan.h"
 #include "diag/fw_tracer.h"
 
 MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
@@ -961,6 +962,8 @@ static int mlx5_init_once(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
 
        mlx5_init_clock(dev);
 
+       dev->vxlan = mlx5_vxlan_create(dev);
+
        err = mlx5_init_rl_table(dev);
        if (err) {
                dev_err(&pdev->dev, "Failed to init rate limiting\n");
@@ -1004,6 +1007,7 @@ err_mpfs_cleanup:
 err_rl_cleanup:
        mlx5_cleanup_rl_table(dev);
 err_tables_cleanup:
+       mlx5_vxlan_destroy(dev->vxlan);
        mlx5_cleanup_mkey_table(dev);
        mlx5_cleanup_srq_table(dev);
        mlx5_cleanup_qp_table(dev);
@@ -1024,6 +1028,7 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
        mlx5_eswitch_cleanup(dev->priv.eswitch);
        mlx5_mpfs_cleanup(dev);
        mlx5_cleanup_rl_table(dev);
+       mlx5_vxlan_destroy(dev->vxlan);
        mlx5_cleanup_clock(dev);
        mlx5_cleanup_reserved_gids(dev);
        mlx5_cleanup_mkey_table(dev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
deleted file mode 100644 (file)
index 9a8fd76..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) 2016, Mellanox Technologies, Ltd.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mlx5/driver.h>
-#include "mlx5_core.h"
-#include "vxlan.h"
-
-struct mlx5_vxlan {
-       struct mlx5_core_dev            *mdev;
-       spinlock_t                      lock; /* protect vxlan table */
-       /* max_num_ports is usuallly 4, 16 buckets is more than enough */
-       DECLARE_HASHTABLE(htable, 4);
-       int                             num_ports;
-       struct mutex                    sync_lock; /* sync add/del port HW operations */
-};
-
-struct mlx5_vxlan_port {
-       struct hlist_node hlist;
-       atomic_t refcount;
-       u16 udp_port;
-};
-
-static inline u8 mlx5_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
-{
-       return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
-}
-
-static int mlx5_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
-{
-       u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)]   = {0};
-       u32 out[MLX5_ST_SZ_DW(add_vxlan_udp_dport_out)] = {0};
-
-       MLX5_SET(add_vxlan_udp_dport_in, in, opcode,
-                MLX5_CMD_OP_ADD_VXLAN_UDP_DPORT);
-       MLX5_SET(add_vxlan_udp_dport_in, in, vxlan_udp_port, port);
-       return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
-}
-
-static int mlx5_vxlan_core_del_port_cmd(struct mlx5_core_dev *mdev, u16 port)
-{
-       u32 in[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_in)]   = {0};
-       u32 out[MLX5_ST_SZ_DW(delete_vxlan_udp_dport_out)] = {0};
-
-       MLX5_SET(delete_vxlan_udp_dport_in, in, opcode,
-                MLX5_CMD_OP_DELETE_VXLAN_UDP_DPORT);
-       MLX5_SET(delete_vxlan_udp_dport_in, in, vxlan_udp_port, port);
-       return mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
-}
-
-static struct mlx5_vxlan_port*
-mlx5_vxlan_lookup_port_locked(struct mlx5_vxlan *vxlan, u16 port)
-{
-       struct mlx5_vxlan_port *vxlanp;
-
-       hash_for_each_possible(vxlan->htable, vxlanp, hlist, port) {
-               if (vxlanp->udp_port == port)
-                       return vxlanp;
-       }
-
-       return NULL;
-}
-
-struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port)
-{
-       struct mlx5_vxlan_port *vxlanp;
-
-       if (!mlx5_vxlan_allowed(vxlan))
-               return NULL;
-
-       spin_lock_bh(&vxlan->lock);
-       vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
-       spin_unlock_bh(&vxlan->lock);
-
-       return vxlanp;
-}
-
-int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
-{
-       struct mlx5_vxlan_port *vxlanp;
-       int ret = -ENOSPC;
-
-       vxlanp = mlx5_vxlan_lookup_port(vxlan, port);
-       if (vxlanp) {
-               atomic_inc(&vxlanp->refcount);
-               return 0;
-       }
-
-       mutex_lock(&vxlan->sync_lock);
-       if (vxlan->num_ports >= mlx5_vxlan_max_udp_ports(vxlan->mdev)) {
-               mlx5_core_info(vxlan->mdev,
-                              "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
-                              port, mlx5_vxlan_max_udp_ports(vxlan->mdev));
-               ret = -ENOSPC;
-               goto unlock;
-       }
-
-       ret = mlx5_vxlan_core_add_port_cmd(vxlan->mdev, port);
-       if (ret)
-               goto unlock;
-
-       vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL);
-       if (!vxlanp) {
-               ret = -ENOMEM;
-               goto err_delete_port;
-       }
-
-       vxlanp->udp_port = port;
-       atomic_set(&vxlanp->refcount, 1);
-
-       spin_lock_bh(&vxlan->lock);
-       hash_add(vxlan->htable, &vxlanp->hlist, port);
-       spin_unlock_bh(&vxlan->lock);
-
-       vxlan->num_ports++;
-       mutex_unlock(&vxlan->sync_lock);
-       return 0;
-
-err_delete_port:
-       mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
-
-unlock:
-       mutex_unlock(&vxlan->sync_lock);
-       return ret;
-}
-
-int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
-{
-       struct mlx5_vxlan_port *vxlanp;
-       bool remove = false;
-       int ret = 0;
-
-       mutex_lock(&vxlan->sync_lock);
-
-       spin_lock_bh(&vxlan->lock);
-       vxlanp = mlx5_vxlan_lookup_port_locked(vxlan, port);
-       if (!vxlanp) {
-               ret = -ENOENT;
-               goto out_unlock;
-       }
-
-       if (atomic_dec_and_test(&vxlanp->refcount)) {
-               hash_del(&vxlanp->hlist);
-               remove = true;
-       }
-
-out_unlock:
-       spin_unlock_bh(&vxlan->lock);
-
-       if (remove) {
-               mlx5_vxlan_core_del_port_cmd(vxlan->mdev, port);
-               kfree(vxlanp);
-               vxlan->num_ports--;
-       }
-
-       mutex_unlock(&vxlan->sync_lock);
-
-       return ret;
-}
-
-struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev)
-{
-       struct mlx5_vxlan *vxlan;
-
-       if (!MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) || !mlx5_core_is_pf(mdev))
-               return ERR_PTR(-ENOTSUPP);
-
-       vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL);
-       if (!vxlan)
-               return ERR_PTR(-ENOMEM);
-
-       vxlan->mdev = mdev;
-       mutex_init(&vxlan->sync_lock);
-       spin_lock_init(&vxlan->lock);
-       hash_init(vxlan->htable);
-
-       /* Hardware adds 4789 by default */
-       mlx5_vxlan_add_port(vxlan, 4789);
-
-       return vxlan;
-}
-
-void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan)
-{
-       struct mlx5_vxlan_port *vxlanp;
-       struct hlist_node *tmp;
-       int bkt;
-
-       if (!mlx5_vxlan_allowed(vxlan))
-               return;
-
-       /* Lockless since we are the only hash table consumers*/
-       hash_for_each_safe(vxlan->htable, bkt, tmp, vxlanp, hlist) {
-               hash_del(&vxlanp->hlist);
-               mlx5_vxlan_core_del_port_cmd(vxlan->mdev, vxlanp->udp_port);
-               kfree(vxlanp);
-       }
-
-       kfree(vxlan);
-}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h b/drivers/net/ethernet/mellanox/mlx5/core/vxlan.h
deleted file mode 100644 (file)
index fd874a3..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2016, Mellanox Technologies, Ltd.  All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#ifndef __MLX5_VXLAN_H__
-#define __MLX5_VXLAN_H__
-
-#include <linux/mlx5/driver.h>
-
-struct mlx5_vxlan;
-struct mlx5_vxlan_port;
-
-#ifdef CONFIG_MLX5_CORE_EN
-
-static inline bool mlx5_vxlan_allowed(struct mlx5_vxlan *vxlan)
-{
-       /* not allowed reason is encoded in vxlan pointer as error,
-        * on mlx5_vxlan_create
-        */
-       return !IS_ERR_OR_NULL(vxlan);
-}
-
-struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev);
-void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan);
-int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port);
-int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port);
-struct mlx5_vxlan_port *mlx5_vxlan_lookup_port(struct mlx5_vxlan *vxlan, u16 port);
-
-#else
-
-static inline struct mlx5_vxlan*
-mlx5_vxlan_create(struct mlx5_core_dev *mdev) { return ERR_PTR(-ENOTSUPP); }
-static inline void mlx5_vxlan_destroy(struct mlx5_vxlan *vxlan) { return; }
-
-#endif
-
-#endif /* __MLX5_VXLAN_H__ */
index fd0aaa5568feba8fc47712215e6dbd62edb03879..54f385cc881131061d164fcf370a77666344a864 100644 (file)
@@ -818,6 +818,7 @@ struct mlx5_clock {
 };
 
 struct mlx5_fw_tracer;
+struct mlx5_vxlan;
 
 struct mlx5_core_dev {
        struct pci_dev         *pdev;
@@ -850,6 +851,7 @@ struct mlx5_core_dev {
        atomic_t                num_qps;
        u32                     issi;
        struct mlx5e_resources  mlx5e_res;
+       struct mlx5_vxlan       *vxlan;
        struct {
                struct mlx5_rsvd_gids   reserved_gids;
                u32                     roce_en;