net/mlx5e: Vxlan, check maximum number of UDP ports
authorGal Pressman <galp@mellanox.com>
Mon, 25 Dec 2017 16:40:52 +0000 (18:40 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 27 Jul 2018 20:56:44 +0000 (13:56 -0700)
The NIC has a limited number of offloaded VXLAN UDP ports (usually 4).
Instead of letting the firmware fail when trying to add more ports than
it can handle, let the driver check it on its own.

Signed-off-by: Gal Pressman <galp@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/vxlan.c
include/linux/mlx5/mlx5_ifc.h

index c41cfc2a4b701264187d14acf3c54c63245d52fe..c4d4db8722f555794db594f5f7000f493629cd0d 100644 (file)
@@ -657,6 +657,7 @@ enum {
 struct mlx5e_vxlan_db {
        spinlock_t                      lock; /* protect vxlan table */
        struct radix_tree_root          tree;
+       int                             num_ports;
 };
 
 struct mlx5e_l2_rule {
index 2f699998d13ed093ec4c5a3f46ecccb90d2e8a45..e3af2efe18ce8e42ef79d4bdfca047c6dee867f6 100644 (file)
@@ -52,6 +52,11 @@ void mlx5e_vxlan_init(struct mlx5e_priv *priv)
                mlx5e_vxlan_add_port(priv, 4789);
 }
 
+static inline u8 mlx5e_vxlan_max_udp_ports(struct mlx5_core_dev *mdev)
+{
+       return MLX5_CAP_ETH(mdev, max_vxlan_udp_ports) ?: 4;
+}
+
 static int mlx5e_vxlan_core_add_port_cmd(struct mlx5_core_dev *mdev, u16 port)
 {
        u32 in[MLX5_ST_SZ_DW(add_vxlan_udp_dport_in)]   = {0};
@@ -98,6 +103,13 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
                return;
        }
 
+       if (vxlan_db->num_ports >= mlx5e_vxlan_max_udp_ports(priv->mdev)) {
+               netdev_info(priv->netdev,
+                           "UDP port (%d) not offloaded, max number of UDP ports (%d) are already offloaded\n",
+                           port, mlx5e_vxlan_max_udp_ports(priv->mdev));
+               return;
+       }
+
        if (mlx5e_vxlan_core_add_port_cmd(priv->mdev, port))
                return;
 
@@ -114,6 +126,7 @@ static void mlx5e_vxlan_add_port(struct mlx5e_priv *priv, u16 port)
        if (err)
                goto err_free;
 
+       vxlan_db->num_ports++;
        return;
 
 err_free:
@@ -163,6 +176,7 @@ out_unlock:
        if (remove) {
                mlx5e_vxlan_core_del_port_cmd(priv->mdev, port);
                kfree(vxlan);
+               vxlan_db->num_ports--;
        }
        mutex_unlock(&priv->state_lock);
        kfree(vxlan_work);
index 22f54bedfaaec4d44d15bc9a3d298d0261bc6c19..60c2308fe062a1b35ad521a7b30a950823685f36 100644 (file)
@@ -668,7 +668,9 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
        u8         swp[0x1];
        u8         swp_csum[0x1];
        u8         swp_lso[0x1];
-       u8         reserved_at_23[0x1b];
+       u8         reserved_at_23[0xd];
+       u8         max_vxlan_udp_ports[0x8];
+       u8         reserved_at_38[0x6];
        u8         max_geneve_opt_len[0x1];
        u8         tunnel_stateless_geneve_rx[0x1];