return err;
        }
 
+       if (MLX5_CAP_GEN(dev, shampo)) {
+               err = mlx5_core_get_caps_mode(dev, MLX5_CAP_SHAMPO, HCA_CAP_OPMOD_GET_CUR);
+               if (err)
+                       return err;
+       }
+
        return 0;
 }
 
 
        u16 opmod = (cap_type << 1) | (cap_mode & 0x01);
        int err;
 
+       if (WARN_ON(!dev->caps.hca[cap_type]))
+               /* this cap_type must be added to mlx5_hca_caps_alloc() */
+               return -EINVAL;
+
        memset(in, 0, sizeof(in));
        out = kzalloc(out_sz, GFP_KERNEL);
        if (!out)
        MLX5_CAP_MACSEC,
        MLX5_CAP_ADV_VIRTUALIZATION,
        MLX5_CAP_CRYPTO,
+       MLX5_CAP_SHAMPO,
 };
 
 static void mlx5_hca_caps_free(struct mlx5_core_dev *dev)
 
        MLX5_CAP_DEV_EVENT = 0x14,
        MLX5_CAP_IPSEC,
        MLX5_CAP_CRYPTO = 0x1a,
+       MLX5_CAP_SHAMPO = 0x1d,
        MLX5_CAP_MACSEC = 0x1f,
        MLX5_CAP_GENERAL_2 = 0x20,
        MLX5_CAP_PORT_SELECTION = 0x25,
 #define MLX5_CAP_MACSEC(mdev, cap)\
        MLX5_GET(macsec_cap, (mdev)->caps.hca[MLX5_CAP_MACSEC]->cur, cap)
 
+#define MLX5_CAP_SHAMPO(mdev, cap) \
+       MLX5_GET(shampo_cap, mdev->caps.hca[MLX5_CAP_SHAMPO]->cur, cap)
+
 enum {
        MLX5_CMD_STAT_OK                        = 0x0,
        MLX5_CMD_STAT_INT_ERR                   = 0x1,
 
        u8         headers_mkey[0x20];
 
        u8         shampo_enable[0x1];
-       u8         reserved_at_1e1[0x4];
+       u8         reserved_at_1e1[0x1];
+       u8         shampo_mode[0x2];
+       u8         reserved_at_1e4[0x1];
        u8         log_reservation_size[0x3];
        u8         reserved_at_1e8[0x5];
        u8         log_max_num_of_packets_per_reservation[0x3];
        u8    reserved_at_80[0x780];
 };
 
+struct mlx5_ifc_shampo_cap_bits {
+       u8    reserved_at_0[0x3];
+       u8    shampo_log_max_reservation_size[0x5];
+       u8    reserved_at_8[0x3];
+       u8    shampo_log_min_reservation_size[0x5];
+       u8    shampo_min_mss_size[0x10];
+
+       u8    shampo_header_split[0x1];
+       u8    shampo_header_split_data_merge[0x1];
+       u8    reserved_at_22[0x1];
+       u8    shampo_log_max_headers_entry_size[0x5];
+       u8    reserved_at_28[0x18];
+
+       u8    reserved_at_40[0x7c0];
+};
+
 union mlx5_ifc_hca_cap_union_bits {
        struct mlx5_ifc_cmd_hca_cap_bits cmd_hca_cap;
        struct mlx5_ifc_cmd_hca_cap_2_bits cmd_hca_cap_2;