net/mlx5: Check max encap header size capability
authorHadar Hen Zion <hadarh@mellanox.com>
Mon, 7 Nov 2016 13:14:43 +0000 (15:14 +0200)
committerDavid S. Miller <davem@davemloft.net>
Wed, 9 Nov 2016 18:41:55 +0000 (13:41 -0500)
Instead of comparing to a const value, check the value of max encap
header size capability as reported by the Firmware.

Fixes: 575ddf5888ea ('net/mlx5: Introduce alloc_encap and dealloc_encap commands')
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c

index 6c9d99aaf07b1b782d002139a58702b7f0d481d8..301cec896eb6aa977cba1b9f661338843b44f520 100644 (file)
@@ -453,27 +453,32 @@ void mlx5_cmd_fc_bulk_get(struct mlx5_core_dev *dev,
        *bytes = MLX5_GET64(traffic_counter, stats, octets);
 }
 
-#define MAX_ENCAP_SIZE (128)
-
 int mlx5_encap_alloc(struct mlx5_core_dev *dev,
                     int header_type,
                     size_t size,
                     void *encap_header,
                     u32 *encap_id)
 {
+       int max_encap_size = MLX5_CAP_ESW(dev, max_encap_header_size);
        u32 out[MLX5_ST_SZ_DW(alloc_encap_header_out)];
-       u32 in[MLX5_ST_SZ_DW(alloc_encap_header_in) +
-             (MAX_ENCAP_SIZE / sizeof(u32))];
-       void *encap_header_in = MLX5_ADDR_OF(alloc_encap_header_in, in,
-                                            encap_header);
-       void *header = MLX5_ADDR_OF(encap_header_in, encap_header_in,
-                                   encap_header);
-       int inlen = header - (void *)in  + size;
+       void *encap_header_in;
+       void *header;
+       int inlen;
        int err;
+       u32 *in;
 
-       if (size > MAX_ENCAP_SIZE)
+       if (size > MLX5_CAP_ESW(dev, max_encap_header_size))
                return -EINVAL;
 
+       in = kzalloc(MLX5_ST_SZ_BYTES(alloc_encap_header_in) + max_encap_size,
+                    GFP_KERNEL);
+       if (!in)
+               return -ENOMEM;
+
+       encap_header_in = MLX5_ADDR_OF(alloc_encap_header_in, in, encap_header);
+       header = MLX5_ADDR_OF(encap_header_in, encap_header_in, encap_header);
+       inlen = header - (void *)in  + size;
+
        memset(in, 0, inlen);
        MLX5_SET(alloc_encap_header_in, in, opcode,
                 MLX5_CMD_OP_ALLOC_ENCAP_HEADER);
@@ -485,6 +490,7 @@ int mlx5_encap_alloc(struct mlx5_core_dev *dev,
        err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
 
        *encap_id = MLX5_GET(alloc_encap_header_out, out, encap_id);
+       kfree(in);
        return err;
 }