diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
commit | 2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch) | |
tree | 848558de17fb3008cdf4d861b01ac7781903ce39 /drivers/net/ethernet/cisco/enic/vnic_vic.c | |
parent | Initial commit. (diff) | |
download | linux-upstream.tar.xz linux-upstream.zip |
Adding upstream version 6.1.76.upstream/6.1.76upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'drivers/net/ethernet/cisco/enic/vnic_vic.c')
-rw-r--r-- | drivers/net/ethernet/cisco/enic/vnic_vic.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/net/ethernet/cisco/enic/vnic_vic.c b/drivers/net/ethernet/cisco/enic/vnic_vic.c new file mode 100644 index 000000000..20fcb20b4 --- /dev/null +++ b/drivers/net/ethernet/cisco/enic/vnic_vic.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright 2010 Cisco Systems, Inc. All rights reserved. + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/types.h> +#include <linux/slab.h> + +#include "vnic_vic.h" + +struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui, + const u8 type) +{ + struct vic_provinfo *vp; + + if (!oui) + return NULL; + + vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags); + if (!vp) + return NULL; + + memcpy(vp->oui, oui, sizeof(vp->oui)); + vp->type = type; + vp->length = htonl(sizeof(vp->num_tlvs)); + + return vp; +} + +void vic_provinfo_free(struct vic_provinfo *vp) +{ + kfree(vp); +} + +int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, + const void *value) +{ + struct vic_provinfo_tlv *tlv; + + if (!vp || !value) + return -EINVAL; + + if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) + + length > VIC_PROVINFO_MAX_TLV_DATA) + return -ENOMEM; + + tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv + + ntohl(vp->length) - sizeof(vp->num_tlvs)); + + tlv->type = htons(type); + tlv->length = htons(length); + memcpy(tlv->value, value, length); + + vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1); + vp->length = htonl(ntohl(vp->length) + + offsetof(struct vic_provinfo_tlv, value) + length); + + return 0; +} + +size_t vic_provinfo_size(struct vic_provinfo *vp) +{ + return vp ? ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0; +} |