linux/drivers/net/ethernet/cisco/enic/vnic_vic.c
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Cisco Systems, Inc.  All rights reserved.
   3 *
   4 * This program is free software; you may redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; version 2 of the License.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  15 * SOFTWARE.
  16 *
  17 */
  18
  19#include <linux/kernel.h>
  20#include <linux/errno.h>
  21#include <linux/types.h>
  22#include <linux/slab.h>
  23
  24#include "vnic_vic.h"
  25
  26struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
  27        const u8 type)
  28{
  29        struct vic_provinfo *vp;
  30
  31        if (!oui)
  32                return NULL;
  33
  34        vp = kzalloc(VIC_PROVINFO_MAX_DATA, flags);
  35        if (!vp)
  36                return NULL;
  37
  38        memcpy(vp->oui, oui, sizeof(vp->oui));
  39        vp->type = type;
  40        vp->length = htonl(sizeof(vp->num_tlvs));
  41
  42        return vp;
  43}
  44
  45void vic_provinfo_free(struct vic_provinfo *vp)
  46{
  47        kfree(vp);
  48}
  49
  50int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
  51        const void *value)
  52{
  53        struct vic_provinfo_tlv *tlv;
  54
  55        if (!vp || !value)
  56                return -EINVAL;
  57
  58        if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) +
  59                length > VIC_PROVINFO_MAX_TLV_DATA)
  60                return -ENOMEM;
  61
  62        tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv +
  63                ntohl(vp->length) - sizeof(vp->num_tlvs));
  64
  65        tlv->type = htons(type);
  66        tlv->length = htons(length);
  67        memcpy(tlv->value, value, length);
  68
  69        vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1);
  70        vp->length = htonl(ntohl(vp->length) +
  71                offsetof(struct vic_provinfo_tlv, value) + length);
  72
  73        return 0;
  74}
  75
  76size_t vic_provinfo_size(struct vic_provinfo *vp)
  77{
  78        return vp ?  ntohl(vp->length) + sizeof(*vp) - sizeof(vp->num_tlvs) : 0;
  79}
  80