Blame lib/utils.c

Packit bcb633
/*
Packit bcb633
 * BSD LICENSE
Packit bcb633
 *
Packit bcb633
 * Copyright(c) 2014-2018 Intel Corporation. All rights reserved.
Packit bcb633
 * All rights reserved.
Packit bcb633
 *
Packit bcb633
 * Redistribution and use in source and binary forms, with or without
Packit bcb633
 * modification, are permitted provided that the following conditions
Packit bcb633
 * are met:
Packit bcb633
 *
Packit bcb633
 *   * Redistributions of source code must retain the above copyright
Packit bcb633
 *     notice, this list of conditions and the following disclaimer.
Packit bcb633
 *   * Redistributions in binary form must reproduce the above copyright
Packit bcb633
 *     notice, this list of conditions and the following disclaimer in
Packit bcb633
 *     the documentation and/or other materials provided with the
Packit bcb633
 *     distribution.
Packit bcb633
 *   * Neither the name of Intel Corporation nor the names of its
Packit bcb633
 *     contributors may be used to endorse or promote products derived
Packit bcb633
 *     from this software without specific prior written permission.
Packit bcb633
 *
Packit bcb633
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit bcb633
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit bcb633
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit bcb633
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit bcb633
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit bcb633
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit bcb633
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit bcb633
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit bcb633
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit bcb633
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit bcb633
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit bcb633
 */
Packit bcb633
Packit bcb633
/**
Packit bcb633
 * @brief Set of utility functions to operate on Platform QoS (pqos) data
Packit bcb633
 *        structures.
Packit bcb633
 *
Packit bcb633
 * These functions need no synchronization mechanisms.
Packit bcb633
 *
Packit bcb633
 */
Packit bcb633
#include <stdlib.h>
Packit bcb633
#include <string.h>
Packit bcb633
#ifdef __linux__
Packit bcb633
#include <alloca.h>       /* alloca() */
Packit bcb633
#endif /* __linux__ */
Packit bcb633
Packit bcb633
#include "pqos.h"
Packit bcb633
#include "types.h"
Packit bcb633
#include "utils.h"
Packit bcb633
Packit bcb633
#define TOPO_OBJ_SOCKET     0
Packit bcb633
#define TOPO_OBJ_L2_CLUSTER 2
Packit bcb633
#define TOPO_OBJ_L3_CLUSTER 3
Packit bcb633
Packit bcb633
static int m_interface = PQOS_INTER_MSR;
Packit bcb633
Packit bcb633
Packit bcb633
int
Packit bcb633
_pqos_utils_init(int interface)
Packit bcb633
{
Packit bcb633
        if (interface == PQOS_INTER_OS_RESCTRL_MON)
Packit bcb633
                m_interface = PQOS_INTER_OS;
Packit bcb633
        else
Packit bcb633
                m_interface = interface;
Packit bcb633
Packit bcb633
        return PQOS_RETVAL_OK;
Packit bcb633
}
Packit bcb633
Packit bcb633
Packit bcb633
unsigned *
Packit bcb633
pqos_cpu_get_sockets(const struct pqos_cpuinfo *cpu,
Packit bcb633
                     unsigned *count)
Packit bcb633
{
Packit bcb633
        unsigned scount = 0, i = 0;
Packit bcb633
        unsigned *sockets = NULL;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        ASSERT(count != NULL);
Packit bcb633
        if (cpu == NULL || count == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        sockets = (unsigned *) malloc(sizeof(sockets[0]) * cpu->num_cores);
Packit bcb633
        if (sockets == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++) {
Packit bcb633
                unsigned j = 0;
Packit bcb633
Packit bcb633
                /**
Packit bcb633
                 * Check if this socket id is already on the \a sockets list
Packit bcb633
                 */
Packit bcb633
                for (j = 0; j < scount && scount > 0; j++)
Packit bcb633
                        if (cpu->cores[i].socket == sockets[j])
Packit bcb633
                                break;
Packit bcb633
Packit bcb633
                if (j >= scount || scount == 0) {
Packit bcb633
                        /**
Packit bcb633
                         * This socket wasn't reported before
Packit bcb633
                         */
Packit bcb633
                        sockets[scount++] = cpu->cores[i].socket;
Packit bcb633
                }
Packit bcb633
        }
Packit bcb633
Packit bcb633
        *count = scount;
Packit bcb633
        return sockets;
Packit bcb633
}
Packit bcb633
Packit bcb633
unsigned *
Packit bcb633
pqos_cpu_get_l2ids(const struct pqos_cpuinfo *cpu,
Packit bcb633
                   unsigned *count)
Packit bcb633
{
Packit bcb633
        unsigned l2count = 0, i = 0;
Packit bcb633
        unsigned *l2ids = NULL;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        ASSERT(count != NULL);
Packit bcb633
        if (cpu == NULL || count == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        l2ids = (unsigned *) malloc(sizeof(l2ids[0]) * cpu->num_cores);
Packit bcb633
        if (l2ids == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++) {
Packit bcb633
                unsigned j = 0;
Packit bcb633
Packit bcb633
                /**
Packit bcb633
                 * Check if this L2 id is already on the list
Packit bcb633
                 */
Packit bcb633
                for (j = 0; j < l2count && l2count > 0; j++)
Packit bcb633
                        if (cpu->cores[i].l2_id == l2ids[j])
Packit bcb633
                                break;
Packit bcb633
Packit bcb633
                if (j >= l2count || l2count == 0) {
Packit bcb633
                        /**
Packit bcb633
                         * This l2id wasn't reported before
Packit bcb633
                         */
Packit bcb633
                        l2ids[l2count++] = cpu->cores[i].l2_id;
Packit bcb633
                }
Packit bcb633
        }
Packit bcb633
Packit bcb633
        *count = l2count;
Packit bcb633
        return l2ids;
Packit bcb633
}
Packit bcb633
Packit bcb633
/**
Packit bcb633
 * @brief Creates list of cores belonging to given topology object
Packit bcb633
 *
Packit bcb633
 * @param [in] cpu CPU topology
Packit bcb633
 * @param [in] type CPU topology object type to search cores for
Packit bcb633
 *             TOPO_OBJ_SOCKET - sockets
Packit bcb633
 *             TOPO_OBJ_L2_CLUSTER - L2 cache clusters
Packit bcb633
 *             TOPO_OBJ_L3_CLUSTER - L3 cache clusters
Packit bcb633
 * @param [in] id CPU topology object ID to search cores for
Packit bcb633
 * @param [out] count place to put number of objects found
Packit bcb633
 *
Packit bcb633
 * @return Pointer to list of cores for given topology object
Packit bcb633
 * @retval NULL on error or if no core found
Packit bcb633
 */
Packit bcb633
static unsigned *
Packit bcb633
__get_cores_per_topology_obj(const struct pqos_cpuinfo *cpu,
Packit bcb633
                             const int type,
Packit bcb633
                             const unsigned id,
Packit bcb633
                             unsigned *count)
Packit bcb633
{
Packit bcb633
        unsigned num = 0, i = 0;
Packit bcb633
        unsigned *core_list = NULL;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        ASSERT(count != NULL);
Packit bcb633
        if (cpu == NULL || count == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        core_list = (unsigned *) malloc(cpu->num_cores * sizeof(core_list[0]));
Packit bcb633
        if (core_list == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if ((type == TOPO_OBJ_L3_CLUSTER &&
Packit bcb633
                     id == cpu->cores[i].l3_id) ||
Packit bcb633
                    (type == TOPO_OBJ_L2_CLUSTER &&
Packit bcb633
                     id == cpu->cores[i].l2_id) ||
Packit bcb633
                    (type == TOPO_OBJ_SOCKET && id == cpu->cores[i].socket))
Packit bcb633
                        core_list[num++] = cpu->cores[i].lcore;
Packit bcb633
Packit bcb633
        if (num == 0) {
Packit bcb633
                free(core_list);
Packit bcb633
                return NULL;
Packit bcb633
        }
Packit bcb633
Packit bcb633
        *count = num;
Packit bcb633
        return core_list;
Packit bcb633
}
Packit bcb633
Packit bcb633
unsigned *
Packit bcb633
pqos_cpu_get_cores_l3id(const struct pqos_cpuinfo *cpu, const unsigned l3_id,
Packit bcb633
                        unsigned *count)
Packit bcb633
{
Packit bcb633
        return __get_cores_per_topology_obj(cpu, TOPO_OBJ_L3_CLUSTER, l3_id,
Packit bcb633
                                            count);
Packit bcb633
}
Packit bcb633
Packit bcb633
unsigned *
Packit bcb633
pqos_cpu_get_cores(const struct pqos_cpuinfo *cpu,
Packit bcb633
                   const unsigned socket,
Packit bcb633
                   unsigned *count)
Packit bcb633
{
Packit bcb633
        unsigned i = 0, cnt = 0;
Packit bcb633
        unsigned *cores = NULL;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        ASSERT(count != NULL);
Packit bcb633
Packit bcb633
        if (cpu == NULL || count == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        cores = (unsigned *) malloc(cpu->num_cores * sizeof(cores[0]));
Packit bcb633
        if (cores == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].socket == socket)
Packit bcb633
                        cores[cnt++] = cpu->cores[i].lcore;
Packit bcb633
Packit bcb633
        if (!cnt) {
Packit bcb633
                free(cores);
Packit bcb633
                return NULL;
Packit bcb633
        }
Packit bcb633
Packit bcb633
        *count = cnt;
Packit bcb633
        return cores;
Packit bcb633
}
Packit bcb633
Packit bcb633
const struct pqos_coreinfo *
Packit bcb633
pqos_cpu_get_core_info(const struct pqos_cpuinfo *cpu, unsigned lcore)
Packit bcb633
{
Packit bcb633
        unsigned i;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
Packit bcb633
        if (cpu == NULL)
Packit bcb633
                return NULL;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].lcore == lcore)
Packit bcb633
                        return &cpu->cores[i];
Packit bcb633
Packit bcb633
        return NULL;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cpu_get_one_core(const struct pqos_cpuinfo *cpu,
Packit bcb633
                      const unsigned socket,
Packit bcb633
                      unsigned *lcore)
Packit bcb633
{
Packit bcb633
        unsigned i = 0;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        ASSERT(lcore != NULL);
Packit bcb633
Packit bcb633
        if (cpu == NULL || lcore == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].socket == socket) {
Packit bcb633
                        *lcore = cpu->cores[i].lcore;
Packit bcb633
                        return PQOS_RETVAL_OK;
Packit bcb633
                }
Packit bcb633
Packit bcb633
        return PQOS_RETVAL_ERROR;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cpu_get_one_by_l2id(const struct pqos_cpuinfo *cpu,
Packit bcb633
                         const unsigned l2id,
Packit bcb633
                         unsigned *lcore)
Packit bcb633
{
Packit bcb633
        unsigned i = 0;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        ASSERT(lcore != NULL);
Packit bcb633
Packit bcb633
        if (cpu == NULL || lcore == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].l2_id == l2id) {
Packit bcb633
                        *lcore = cpu->cores[i].lcore;
Packit bcb633
                        return PQOS_RETVAL_OK;
Packit bcb633
                }
Packit bcb633
Packit bcb633
        return PQOS_RETVAL_ERROR;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cpu_check_core(const struct pqos_cpuinfo *cpu,
Packit bcb633
                    const unsigned lcore)
Packit bcb633
{
Packit bcb633
        unsigned i = 0;
Packit bcb633
Packit bcb633
        ASSERT(cpu != NULL);
Packit bcb633
        if (cpu == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].lcore == lcore)
Packit bcb633
                        return PQOS_RETVAL_OK;
Packit bcb633
Packit bcb633
        return PQOS_RETVAL_ERROR;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cpu_get_socketid(const struct pqos_cpuinfo *cpu,
Packit bcb633
                      const unsigned lcore,
Packit bcb633
                      unsigned *socket)
Packit bcb633
{
Packit bcb633
        unsigned i = 0;
Packit bcb633
Packit bcb633
        if (cpu == NULL || socket == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].lcore == lcore) {
Packit bcb633
                        *socket = cpu->cores[i].socket;
Packit bcb633
                        return PQOS_RETVAL_OK;
Packit bcb633
                }
Packit bcb633
Packit bcb633
        return PQOS_RETVAL_ERROR;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cpu_get_clusterid(const struct pqos_cpuinfo *cpu,
Packit bcb633
                       const unsigned lcore,
Packit bcb633
                       unsigned *cluster)
Packit bcb633
{
Packit bcb633
        unsigned i = 0;
Packit bcb633
Packit bcb633
        if (cpu == NULL || cluster == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        for (i = 0; i < cpu->num_cores; i++)
Packit bcb633
                if (cpu->cores[i].lcore == lcore) {
Packit bcb633
                        *cluster = cpu->cores[i].l3_id;
Packit bcb633
                        return PQOS_RETVAL_OK;
Packit bcb633
                }
Packit bcb633
Packit bcb633
        return PQOS_RETVAL_ERROR;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cap_get_type(const struct pqos_cap *cap,
Packit bcb633
                  const enum pqos_cap_type type,
Packit bcb633
                  const struct pqos_capability **cap_item)
Packit bcb633
{
Packit bcb633
        int ret = PQOS_RETVAL_RESOURCE;
Packit bcb633
        unsigned i;
Packit bcb633
Packit bcb633
        ASSERT(cap != NULL && cap_item != NULL);
Packit bcb633
        if (cap == NULL || cap_item == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ASSERT(type < PQOS_CAP_TYPE_NUMOF);
Packit bcb633
        if (type >= PQOS_CAP_TYPE_NUMOF)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        for (i = 0; i < cap->num_cap; i++) {
Packit bcb633
                if (cap->capabilities[i].type != type)
Packit bcb633
                        continue;
Packit bcb633
                /**
Packit bcb633
                 * Feature not supported for OS interface
Packit bcb633
                 */
Packit bcb633
                if (m_interface == PQOS_INTER_OS &&
Packit bcb633
                    !cap->capabilities[i].os_support)
Packit bcb633
                        continue;
Packit bcb633
                *cap_item = &cap->capabilities[i];
Packit bcb633
                ret = PQOS_RETVAL_OK;
Packit bcb633
                break;
Packit bcb633
        }
Packit bcb633
Packit bcb633
        return ret;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_cap_get_event(const struct pqos_cap *cap,
Packit bcb633
                   const enum pqos_mon_event event,
Packit bcb633
                   const struct pqos_monitor **p_mon)
Packit bcb633
{
Packit bcb633
        const struct pqos_capability *cap_item = NULL;
Packit bcb633
        const struct pqos_cap_mon *mon = NULL;
Packit bcb633
        int ret = PQOS_RETVAL_OK;
Packit bcb633
        unsigned i;
Packit bcb633
Packit bcb633
        if (cap == NULL || p_mon == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_MON, &cap_item);
Packit bcb633
        if (ret != PQOS_RETVAL_OK)
Packit bcb633
                return ret;
Packit bcb633
Packit bcb633
        ASSERT(cap_item != NULL);
Packit bcb633
        mon = cap_item->u.mon;
Packit bcb633
Packit bcb633
        ret = PQOS_RETVAL_ERROR;
Packit bcb633
Packit bcb633
        for (i = 0; i < mon->num_events; i++) {
Packit bcb633
                if (mon->events[i].type != event)
Packit bcb633
                        continue;
Packit bcb633
                /**
Packit bcb633
                 * Feature not supported for OS interface
Packit bcb633
                 */
Packit bcb633
                if (m_interface == PQOS_INTER_OS && !mon->events[i].os_support)
Packit bcb633
                        continue;
Packit bcb633
Packit bcb633
                *p_mon = &mon->events[i];
Packit bcb633
                ret = PQOS_RETVAL_OK;
Packit bcb633
                break;
Packit bcb633
        }
Packit bcb633
Packit bcb633
        return ret;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_l3ca_get_cos_num(const struct pqos_cap *cap,
Packit bcb633
                      unsigned *cos_num)
Packit bcb633
{
Packit bcb633
        const struct pqos_capability *item = NULL;
Packit bcb633
        int ret = PQOS_RETVAL_OK;
Packit bcb633
Packit bcb633
        ASSERT(cap != NULL && cos_num != NULL);
Packit bcb633
        if (cap == NULL || cos_num == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L3CA, &item);
Packit bcb633
        if (ret != PQOS_RETVAL_OK)
Packit bcb633
                return ret;                           /**< no L3CA capability */
Packit bcb633
Packit bcb633
        ASSERT(item != NULL);
Packit bcb633
        *cos_num = item->u.l3ca->num_classes;
Packit bcb633
        return ret;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_l2ca_get_cos_num(const struct pqos_cap *cap,
Packit bcb633
                      unsigned *cos_num)
Packit bcb633
{
Packit bcb633
        const struct pqos_capability *item = NULL;
Packit bcb633
        int ret = PQOS_RETVAL_OK;
Packit bcb633
Packit bcb633
        ASSERT(cap != NULL && cos_num != NULL);
Packit bcb633
        if (cap == NULL || cos_num == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L2CA, &item);
Packit bcb633
        if (ret != PQOS_RETVAL_OK)
Packit bcb633
                return ret;                           /**< no L2CA capability */
Packit bcb633
Packit bcb633
        ASSERT(item != NULL);
Packit bcb633
        *cos_num = item->u.l2ca->num_classes;
Packit bcb633
        return ret;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_mba_get_cos_num(const struct pqos_cap *cap,
Packit bcb633
                      unsigned *cos_num)
Packit bcb633
{
Packit bcb633
        const struct pqos_capability *item = NULL;
Packit bcb633
        int ret = PQOS_RETVAL_OK;
Packit bcb633
Packit bcb633
        ASSERT(cap != NULL && cos_num != NULL);
Packit bcb633
        if (cap == NULL || cos_num == NULL)
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_MBA, &item);
Packit bcb633
        if (ret != PQOS_RETVAL_OK)
Packit bcb633
                return ret;                           /**< no MBA capability */
Packit bcb633
Packit bcb633
        ASSERT(item != NULL);
Packit bcb633
        *cos_num = item->u.mba->num_classes;
Packit bcb633
        return ret;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_l3ca_cdp_enabled(const struct pqos_cap *cap,
Packit bcb633
                      int *cdp_supported,
Packit bcb633
                      int *cdp_enabled)
Packit bcb633
{
Packit bcb633
        const struct pqos_capability *item = NULL;
Packit bcb633
        int ret = PQOS_RETVAL_OK;
Packit bcb633
Packit bcb633
        ASSERT(cap != NULL && (cdp_enabled != NULL || cdp_supported != NULL));
Packit bcb633
        if (cap == NULL || (cdp_enabled == NULL && cdp_supported == NULL))
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L3CA, &item);
Packit bcb633
        if (ret != PQOS_RETVAL_OK)
Packit bcb633
                return ret;                           /**< no L3CA capability */
Packit bcb633
Packit bcb633
        ASSERT(item != NULL);
Packit bcb633
        if (cdp_supported != NULL) {
Packit bcb633
                if (m_interface == PQOS_INTER_MSR)
Packit bcb633
                        *cdp_supported = item->u.l3ca->cdp;
Packit bcb633
                else if (m_interface == PQOS_INTER_OS)
Packit bcb633
                        *cdp_supported = item->u.l3ca->os_cdp;
Packit bcb633
        }
Packit bcb633
        if (cdp_enabled != NULL)
Packit bcb633
                *cdp_enabled = item->u.l3ca->cdp_on;
Packit bcb633
Packit bcb633
        return ret;
Packit bcb633
}
Packit bcb633
Packit bcb633
int
Packit bcb633
pqos_l2ca_cdp_enabled(const struct pqos_cap *cap,
Packit bcb633
                      int *cdp_supported,
Packit bcb633
                      int *cdp_enabled)
Packit bcb633
{
Packit bcb633
        const struct pqos_capability *l2ca = NULL;
Packit bcb633
        int ret = PQOS_RETVAL_OK;
Packit bcb633
Packit bcb633
        ASSERT(cap != NULL && (cdp_enabled != NULL || cdp_supported != NULL));
Packit bcb633
        if (cap == NULL || (cdp_enabled == NULL && cdp_supported == NULL))
Packit bcb633
                return PQOS_RETVAL_PARAM;
Packit bcb633
Packit bcb633
        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L2CA, &l2ca);
Packit bcb633
        if (ret != PQOS_RETVAL_OK)
Packit bcb633
                return ret;                           /**< no L2CA capability */
Packit bcb633
Packit bcb633
        ASSERT(l2ca != NULL);
Packit bcb633
        if (cdp_supported != NULL) {
Packit bcb633
                if (m_interface == PQOS_INTER_MSR)
Packit bcb633
                        *cdp_supported = l2ca->u.l2ca->cdp;
Packit bcb633
                else if (m_interface == PQOS_INTER_OS)
Packit bcb633
                        *cdp_supported = l2ca->u.l2ca->os_cdp;
Packit bcb633
        }
Packit bcb633
        if (cdp_enabled != NULL)
Packit bcb633
                *cdp_enabled = l2ca->u.l2ca->cdp_on;
Packit bcb633
Packit bcb633
        return ret;
Packit bcb633
}