Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/mellanox/mlx5/core/lib/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  geneve.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2019 Mellanox Technologies. */

#include <linux/kernel.h>
#include "mlx5_core.h"
#include "geneve.h"

struct mlx5_geneve {
 struct mlx5_core_dev *mdev;
 __be16 opt_class;
 u8 opt_type;
 u32 obj_id;
 struct mutex sync_lock; /* protect GENEVE obj operations */
 u32 refcount;
};

static int mlx5_geneve_tlv_option_create(struct mlx5_core_dev *mdev,
      __be16 class,
      u8 type,
      u8 len)
{
 u32 in[MLX5_ST_SZ_DW(create_geneve_tlv_option_in)] = {};
 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
 u64 general_obj_types;
 void *hdr, *opt;
 u16 obj_id;
 int err;

 general_obj_types = MLX5_CAP_GEN_64(mdev, general_obj_types);
 if (!(general_obj_types & MLX5_GENERAL_OBJ_TYPES_CAP_GENEVE_TLV_OPT))
  return -EINVAL;

 hdr = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, hdr);
 opt = MLX5_ADDR_OF(create_geneve_tlv_option_in, in, geneve_tlv_opt);

 MLX5_SET(general_obj_in_cmd_hdr, hdr, opcode, MLX5_CMD_OP_CREATE_GENERAL_OBJECT);
 MLX5_SET(general_obj_in_cmd_hdr, hdr, obj_type, MLX5_OBJ_TYPE_GENEVE_TLV_OPT);

 MLX5_SET(geneve_tlv_option, opt, option_class, be16_to_cpu(class));
 MLX5_SET(geneve_tlv_option, opt, option_type, type);
 MLX5_SET(geneve_tlv_option, opt, option_data_length, len);

 err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
 if (err)
  return err;

 obj_id = MLX5_GET(general_obj_out_cmd_hdr, out, obj_id);
 return obj_id;
}

static void mlx5_geneve_tlv_option_destroy(struct mlx5_core_dev *mdev, u16 obj_id)
{
 u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)] = {};
 u32 in[MLX5_ST_SZ_DW(general_obj_in_cmd_hdr)] = {};

 MLX5_SET(general_obj_in_cmd_hdr, in, opcode, MLX5_CMD_OP_DESTROY_GENERAL_OBJECT);
 MLX5_SET(general_obj_in_cmd_hdr, in, obj_type, MLX5_OBJ_TYPE_GENEVE_TLV_OPT);
 MLX5_SET(general_obj_in_cmd_hdr, in, obj_id, obj_id);

 mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
}

int mlx5_geneve_tlv_option_add(struct mlx5_geneve *geneve, struct geneve_opt *opt)
{
 int res = 0;

 if (IS_ERR_OR_NULL(geneve))
  return -EOPNOTSUPP;

 mutex_lock(&geneve->sync_lock);

 if (geneve->refcount) {
  if (geneve->opt_class == opt->opt_class &&
      geneve->opt_type == opt->type) {
   /* We already have TLV options obj allocated */
   geneve->refcount++;
  } else {
   /* TLV options obj allocated, but its params
 * do not match the new request.
 * We support only one such object.
 */

   mlx5_core_warn(geneve->mdev,
           "Won't create Geneve TLV opt object with class:type:len = 0x%x:0x%x:%d (another class:type already exists)\n",
           be16_to_cpu(opt->opt_class),
           opt->type,
           opt->length);
   res = -EOPNOTSUPP;
   goto unlock;
  }
 } else {
  /* We don't have any TLV options obj allocated */

  res = mlx5_geneve_tlv_option_create(geneve->mdev,
          opt->opt_class,
          opt->type,
          opt->length);
  if (res < 0) {
   mlx5_core_warn(geneve->mdev,
           "Failed creating Geneve TLV opt object class:type:len = 0x%x:0x%x:%d (err=%d)\n",
           be16_to_cpu(opt->opt_class),
           opt->type, opt->length, res);
   goto unlock;
  }
  geneve->opt_class = opt->opt_class;
  geneve->opt_type = opt->type;
  geneve->obj_id = res;
  geneve->refcount++;
  res = 0;
 }

unlock:
 mutex_unlock(&geneve->sync_lock);
 return res;
}

void mlx5_geneve_tlv_option_del(struct mlx5_geneve *geneve)
{
 if (IS_ERR_OR_NULL(geneve))
  return;

 mutex_lock(&geneve->sync_lock);
 if (--geneve->refcount == 0) {
  /* We've just removed the last user of Geneve option.
 * Now delete the object in FW.
 */

  mlx5_geneve_tlv_option_destroy(geneve->mdev, geneve->obj_id);

  geneve->opt_class = 0;
  geneve->opt_type = 0;
  geneve->obj_id = 0;
 }
 mutex_unlock(&geneve->sync_lock);
}

struct mlx5_geneve *mlx5_geneve_create(struct mlx5_core_dev *mdev)
{
 struct mlx5_geneve *geneve =
  kzalloc(sizeof(*geneve), GFP_KERNEL);

 if (!geneve)
  return ERR_PTR(-ENOMEM);
 geneve->mdev = mdev;
 mutex_init(&geneve->sync_lock);

 return geneve;
}

void mlx5_geneve_destroy(struct mlx5_geneve *geneve)
{
 if (IS_ERR_OR_NULL(geneve))
  return;

 /* Lockless since we are unloading */
 if (geneve->refcount)
  mlx5_geneve_tlv_option_destroy(geneve->mdev, geneve->obj_id);

 kfree(geneve);
}

Messung V0.5
C=96 H=97 G=96

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.