Add infrastructure for exporting config schema from PF drivers
Differential Revision: https://reviews.freebsd.org/D80 MFC after: 1 month Sponsored by: Sandvine Inc.
This commit is contained in:
parent
b69884917f
commit
15b49f3639
@ -2032,6 +2032,7 @@ dev/pci/isa_pci.c optional pci isa
|
||||
dev/pci/pci.c optional pci
|
||||
dev/pci/pci_if.m standard
|
||||
dev/pci/pci_iov.c optional pci pci_iov
|
||||
dev/pci/pci_iov_schema.c optional pci pci_iov
|
||||
dev/pci/pci_pci.c optional pci
|
||||
dev/pci/pci_subr.c optional pci
|
||||
dev/pci/pci_user.c optional pci
|
||||
|
@ -46,6 +46,10 @@ CODE {
|
||||
}
|
||||
};
|
||||
|
||||
HEADER {
|
||||
struct nvlist;
|
||||
}
|
||||
|
||||
|
||||
METHOD u_int32_t read_config {
|
||||
device_t dev;
|
||||
@ -201,6 +205,8 @@ METHOD void child_added {
|
||||
METHOD int iov_attach {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
struct nvlist *pf_schema;
|
||||
struct nvlist *vf_schema;
|
||||
};
|
||||
|
||||
METHOD int iov_detach {
|
||||
|
@ -46,11 +46,16 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <sys/nv.h>
|
||||
#include <sys/iov_schema.h>
|
||||
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
#include <dev/pci/pci_private.h>
|
||||
#include <dev/pci/pci_iov_private.h>
|
||||
#include <dev/pci/schema_private.h>
|
||||
|
||||
#include "pci_if.h"
|
||||
#include "pcib_if.h"
|
||||
@ -71,18 +76,30 @@ static struct cdevsw iov_cdevsw = {
|
||||
#define IOV_WRITE(d, r, v, w) \
|
||||
pci_write_config((d)->cfg.dev, (d)->cfg.iov->iov_pos + r, v, w)
|
||||
|
||||
static nvlist_t *pci_iov_build_schema(nvlist_t **pf_schema,
|
||||
nvlist_t **vf_schema);
|
||||
static void pci_iov_build_pf_schema(nvlist_t *schema,
|
||||
nvlist_t **driver_schema);
|
||||
static void pci_iov_build_vf_schema(nvlist_t *schema,
|
||||
nvlist_t **driver_schema);
|
||||
static nvlist_t *pci_iov_get_pf_subsystem_schema(void);
|
||||
static nvlist_t *pci_iov_get_vf_subsystem_schema(void);
|
||||
|
||||
int
|
||||
pci_iov_attach_method(device_t bus, device_t dev)
|
||||
pci_iov_attach_method(device_t bus, device_t dev, nvlist_t *pf_schema,
|
||||
nvlist_t *vf_schema)
|
||||
{
|
||||
device_t pcib;
|
||||
struct pci_devinfo *dinfo;
|
||||
struct pcicfg_iov *iov;
|
||||
nvlist_t *schema;
|
||||
uint32_t version;
|
||||
int error;
|
||||
int iov_pos;
|
||||
|
||||
dinfo = device_get_ivars(dev);
|
||||
pcib = device_get_parent(bus);
|
||||
schema = NULL;
|
||||
|
||||
error = pci_find_extcap(dev, PCIZ_SRIOV, &iov_pos);
|
||||
|
||||
@ -108,6 +125,13 @@ pci_iov_attach_method(device_t bus, device_t dev)
|
||||
}
|
||||
iov->iov_pos = iov_pos;
|
||||
|
||||
schema = pci_iov_build_schema(&pf_schema, &vf_schema);
|
||||
if (schema == NULL) {
|
||||
error = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
iov->iov_schema = schema;
|
||||
|
||||
iov->iov_cdev = make_dev(&iov_cdevsw, device_get_unit(dev),
|
||||
UID_ROOT, GID_WHEEL, 0600, "iov/%s", device_get_nameunit(dev));
|
||||
|
||||
@ -123,6 +147,9 @@ pci_iov_attach_method(device_t bus, device_t dev)
|
||||
return (0);
|
||||
|
||||
cleanup:
|
||||
nvlist_destroy(schema);
|
||||
nvlist_destroy(pf_schema);
|
||||
nvlist_destroy(vf_schema);
|
||||
free(iov, M_SRIOV);
|
||||
mtx_unlock(&Giant);
|
||||
return (error);
|
||||
@ -154,6 +181,7 @@ pci_iov_detach_method(device_t bus, device_t dev)
|
||||
destroy_dev(iov->iov_cdev);
|
||||
iov->iov_cdev = NULL;
|
||||
}
|
||||
nvlist_destroy(iov->iov_schema);
|
||||
|
||||
free(iov, M_SRIOV);
|
||||
mtx_unlock(&Giant);
|
||||
@ -161,6 +189,115 @@ pci_iov_detach_method(device_t bus, device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static nvlist_t *
|
||||
pci_iov_build_schema(nvlist_t **pf, nvlist_t **vf)
|
||||
{
|
||||
nvlist_t *schema, *pf_driver, *vf_driver;
|
||||
|
||||
/* We always take ownership of the schemas. */
|
||||
pf_driver = *pf;
|
||||
*pf = NULL;
|
||||
vf_driver = *vf;
|
||||
*vf = NULL;
|
||||
|
||||
schema = pci_iov_schema_alloc_node();
|
||||
if (schema == NULL)
|
||||
goto cleanup;
|
||||
|
||||
pci_iov_build_pf_schema(schema, &pf_driver);
|
||||
pci_iov_build_vf_schema(schema, &vf_driver);
|
||||
|
||||
if (nvlist_error(schema) != 0)
|
||||
goto cleanup;
|
||||
|
||||
return (schema);
|
||||
|
||||
cleanup:
|
||||
nvlist_destroy(schema);
|
||||
nvlist_destroy(pf_driver);
|
||||
nvlist_destroy(vf_driver);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_iov_build_pf_schema(nvlist_t *schema, nvlist_t **driver_schema)
|
||||
{
|
||||
nvlist_t *pf_schema, *iov_schema;
|
||||
|
||||
pf_schema = pci_iov_schema_alloc_node();
|
||||
if (pf_schema == NULL) {
|
||||
nvlist_set_error(schema, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
iov_schema = pci_iov_get_pf_subsystem_schema();
|
||||
|
||||
/*
|
||||
* Note that if either *driver_schema or iov_schema is NULL, then
|
||||
* nvlist_move_nvlist will put the schema in the error state and
|
||||
* SR-IOV will fail to initialize later, so we don't have to explicitly
|
||||
* handle that case.
|
||||
*/
|
||||
nvlist_move_nvlist(pf_schema, DRIVER_CONFIG_NAME, *driver_schema);
|
||||
nvlist_move_nvlist(pf_schema, IOV_CONFIG_NAME, iov_schema);
|
||||
nvlist_move_nvlist(schema, PF_CONFIG_NAME, pf_schema);
|
||||
*driver_schema = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pci_iov_build_vf_schema(nvlist_t *schema, nvlist_t **driver_schema)
|
||||
{
|
||||
nvlist_t *vf_schema, *iov_schema;
|
||||
|
||||
vf_schema = pci_iov_schema_alloc_node();
|
||||
if (vf_schema == NULL) {
|
||||
nvlist_set_error(schema, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
iov_schema = pci_iov_get_vf_subsystem_schema();
|
||||
|
||||
/*
|
||||
* Note that if either *driver_schema or iov_schema is NULL, then
|
||||
* nvlist_move_nvlist will put the schema in the error state and
|
||||
* SR-IOV will fail to initialize later, so we don't have to explicitly
|
||||
* handle that case.
|
||||
*/
|
||||
nvlist_move_nvlist(vf_schema, DRIVER_CONFIG_NAME, *driver_schema);
|
||||
nvlist_move_nvlist(vf_schema, IOV_CONFIG_NAME, iov_schema);
|
||||
nvlist_move_nvlist(schema, VF_SCHEMA_NAME, vf_schema);
|
||||
*driver_schema = NULL;
|
||||
}
|
||||
|
||||
static nvlist_t *
|
||||
pci_iov_get_pf_subsystem_schema(void)
|
||||
{
|
||||
nvlist_t *pf;
|
||||
|
||||
pf = pci_iov_schema_alloc_node();
|
||||
if (pf == NULL)
|
||||
return (NULL);
|
||||
|
||||
pci_iov_schema_add_uint16(pf, "num_vfs", IOV_SCHEMA_REQUIRED, -1);
|
||||
pci_iov_schema_add_string(pf, "device", IOV_SCHEMA_REQUIRED, NULL);
|
||||
|
||||
return (pf);
|
||||
}
|
||||
|
||||
static nvlist_t *
|
||||
pci_iov_get_vf_subsystem_schema(void)
|
||||
{
|
||||
nvlist_t *vf;
|
||||
|
||||
vf = pci_iov_schema_alloc_node();
|
||||
if (vf == NULL)
|
||||
return (NULL);
|
||||
|
||||
pci_iov_schema_add_bool(vf, "passthrough", IOV_SCHEMA_HASDEFAULT, 0);
|
||||
|
||||
return (vf);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_iov_alloc_bar(struct pci_devinfo *dinfo, int bar, pci_addr_t bar_shift)
|
||||
{
|
||||
@ -605,6 +742,50 @@ pci_iov_delete(struct cdev *cdev)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_iov_get_schema_ioctl(struct cdev *cdev, struct pci_iov_schema *output)
|
||||
{
|
||||
struct pci_devinfo *dinfo;
|
||||
void *packed;
|
||||
size_t output_len, size;
|
||||
int error;
|
||||
|
||||
packed = NULL;
|
||||
|
||||
mtx_lock(&Giant);
|
||||
dinfo = cdev->si_drv1;
|
||||
packed = nvlist_pack(dinfo->cfg.iov->iov_schema, &size);
|
||||
mtx_unlock(&Giant);
|
||||
|
||||
if (packed == NULL) {
|
||||
error = ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
output_len = output->len;
|
||||
output->len = size;
|
||||
if (size <= output_len) {
|
||||
error = copyout(packed, output->schema, size);
|
||||
|
||||
if (error != 0)
|
||||
goto fail;
|
||||
|
||||
output->error = 0;
|
||||
} else
|
||||
/*
|
||||
* If we return an error then the ioctl code won't copyout
|
||||
* output back to userland, so we flag the error in the struct
|
||||
* instead.
|
||||
*/
|
||||
output->error = EMSGSIZE;
|
||||
|
||||
error = 0;
|
||||
|
||||
fail:
|
||||
free(packed, M_NVLIST);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pci_iov_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
@ -616,6 +797,9 @@ pci_iov_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
return (pci_iov_config(dev, (struct pci_iov_arg *)data));
|
||||
case IOV_DELETE:
|
||||
return (pci_iov_delete(dev));
|
||||
case IOV_GET_SCHEMA:
|
||||
return (pci_iov_get_schema_ioctl(dev,
|
||||
(struct pci_iov_schema *)data));
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ struct pci_iov_bar {
|
||||
|
||||
struct pcicfg_iov {
|
||||
struct cdev *iov_cdev;
|
||||
nvlist_t *iov_schema;
|
||||
|
||||
struct pci_iov_bar iov_bar[PCIR_MAX_BAR_0 + 1];
|
||||
struct rman rman;
|
||||
|
208
sys/dev/pci/pci_iov_schema.c
Normal file
208
sys/dev/pci/pci_iov_schema.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*-
|
||||
* Copyright (c) 2014-2015 Sandvine Inc. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <sys/nv.h>
|
||||
#include <sys/iov_schema.h>
|
||||
|
||||
#include <dev/pci/schema_private.h>
|
||||
|
||||
static const char *pci_iov_schema_valid_types[] = {
|
||||
"bool",
|
||||
"string",
|
||||
"uint8_t",
|
||||
"uint16_t",
|
||||
"uint32_t",
|
||||
"uint64_t",
|
||||
"unicast-mac",
|
||||
};
|
||||
|
||||
static void
|
||||
pci_iov_schema_add_type(nvlist_t *entry, const char *type)
|
||||
{
|
||||
int i, error;
|
||||
|
||||
error = EINVAL;
|
||||
for (i = 0; i < nitems(pci_iov_schema_valid_types); i++) {
|
||||
if (strcmp(type, pci_iov_schema_valid_types[i]) == 0) {
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error != 0) {
|
||||
nvlist_set_error(entry, error);
|
||||
return;
|
||||
}
|
||||
|
||||
nvlist_add_string(entry, "type", type);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_iov_schema_add_required(nvlist_t *entry, uint32_t flags)
|
||||
{
|
||||
|
||||
if (flags & IOV_SCHEMA_REQUIRED) {
|
||||
if (flags & IOV_SCHEMA_HASDEFAULT) {
|
||||
nvlist_set_error(entry, EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
nvlist_add_bool(entry, "required", 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_bool(nvlist_t *schema, const char *name, uint32_t flags,
|
||||
int defaultVal)
|
||||
{
|
||||
nvlist_t *entry;
|
||||
|
||||
entry = nvlist_create(NV_FLAG_IGNORE_CASE);
|
||||
if (entry == NULL) {
|
||||
nvlist_set_error(schema, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
pci_iov_schema_add_type(entry, "bool");
|
||||
if (flags & IOV_SCHEMA_HASDEFAULT)
|
||||
nvlist_add_bool(entry, "default", defaultVal);
|
||||
pci_iov_schema_add_required(entry, flags);
|
||||
|
||||
nvlist_move_nvlist(schema, name, entry);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_string(nvlist_t *schema, const char *name, uint32_t flags,
|
||||
const char *defaultVal)
|
||||
{
|
||||
nvlist_t *entry;
|
||||
|
||||
entry = nvlist_create(NV_FLAG_IGNORE_CASE);
|
||||
if (entry == NULL) {
|
||||
nvlist_set_error(schema, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
pci_iov_schema_add_type(entry, "string");
|
||||
if (flags & IOV_SCHEMA_HASDEFAULT)
|
||||
nvlist_add_string(entry, "default", defaultVal);
|
||||
pci_iov_schema_add_required(entry, flags);
|
||||
|
||||
nvlist_move_nvlist(schema, name, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
pci_iov_schema_int(nvlist_t *schema, const char *name, const char *type,
|
||||
uint32_t flags, uint64_t defaultVal)
|
||||
{
|
||||
nvlist_t *entry;
|
||||
|
||||
entry = nvlist_create(NV_FLAG_IGNORE_CASE);
|
||||
if (entry == NULL) {
|
||||
nvlist_set_error(schema, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
pci_iov_schema_add_type(entry, type);
|
||||
if (flags & IOV_SCHEMA_HASDEFAULT)
|
||||
nvlist_add_number(entry, "default", defaultVal);
|
||||
pci_iov_schema_add_required(entry, flags);
|
||||
|
||||
nvlist_move_nvlist(schema, name, entry);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_uint8(nvlist_t *schema, const char *name, uint32_t flags,
|
||||
uint8_t defaultVal)
|
||||
{
|
||||
|
||||
pci_iov_schema_int(schema, name, "uint8_t", flags, defaultVal);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_uint16(nvlist_t *schema, const char *name, uint32_t flags,
|
||||
uint16_t defaultVal)
|
||||
{
|
||||
|
||||
pci_iov_schema_int(schema, name, "uint16_t", flags, defaultVal);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_uint32(nvlist_t *schema, const char *name, uint32_t flags,
|
||||
uint32_t defaultVal)
|
||||
{
|
||||
|
||||
pci_iov_schema_int(schema, name, "uint32_t", flags, defaultVal);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_uint64(nvlist_t *schema, const char *name, uint32_t flags,
|
||||
uint64_t defaultVal)
|
||||
{
|
||||
|
||||
pci_iov_schema_int(schema, name, "uint64_t", flags, defaultVal);
|
||||
}
|
||||
|
||||
void
|
||||
pci_iov_schema_add_unicast_mac(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, const uint8_t * defaultVal)
|
||||
{
|
||||
nvlist_t *entry;
|
||||
|
||||
entry = nvlist_create(NV_FLAG_IGNORE_CASE);
|
||||
if (entry == NULL) {
|
||||
nvlist_set_error(schema, ENOMEM);
|
||||
return;
|
||||
}
|
||||
|
||||
pci_iov_schema_add_type(entry, "unicast-mac");
|
||||
if (flags & IOV_SCHEMA_HASDEFAULT)
|
||||
nvlist_add_binary(entry, "default", defaultVal, ETHER_ADDR_LEN);
|
||||
pci_iov_schema_add_required(entry, flags);
|
||||
|
||||
nvlist_move_nvlist(schema, name, entry);
|
||||
}
|
||||
|
||||
/* Allocate a new empty schema node. */
|
||||
nvlist_t *
|
||||
pci_iov_schema_alloc_node(void)
|
||||
{
|
||||
|
||||
return (nvlist_create(NV_FLAG_IGNORE_CASE));
|
||||
}
|
@ -152,7 +152,8 @@ struct resource *pci_alloc_multi_resource(device_t dev, device_t child,
|
||||
int type, int *rid, u_long start, u_long end, u_long count,
|
||||
u_long num, u_int flags);
|
||||
|
||||
int pci_iov_attach_method(device_t bus, device_t dev);
|
||||
int pci_iov_attach_method(device_t bus, device_t dev,
|
||||
struct nvlist *pf_schema, struct nvlist *vf_schema);
|
||||
int pci_iov_detach_method(device_t bus, device_t dev);
|
||||
|
||||
device_t pci_create_iov_child_method(device_t bus, device_t pf,
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
typedef uint64_t pci_addr_t;
|
||||
|
||||
struct nvlist;
|
||||
|
||||
/* Interesting values for PCI power management */
|
||||
struct pcicfg_pp {
|
||||
uint16_t pp_cap; /* PCI power management capabilities */
|
||||
@ -525,9 +527,10 @@ pci_child_added(device_t dev)
|
||||
}
|
||||
|
||||
static __inline int
|
||||
pci_iov_attach(device_t dev)
|
||||
pci_iov_attach(device_t dev, struct nvlist *pf_schema, struct nvlist *vf_schema)
|
||||
{
|
||||
return (PCI_IOV_ATTACH(device_get_parent(dev), dev));
|
||||
return (PCI_IOV_ATTACH(device_get_parent(dev), dev, pf_schema,
|
||||
vf_schema));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
|
35
sys/dev/pci/schema_private.h
Normal file
35
sys/dev/pci/schema_private.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 Sandvine Inc. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice unmodified, this list of conditions, and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SCHEMA_PRIVATE_H_
|
||||
#define _SCHEMA_PRIVATE_H_
|
||||
|
||||
int pci_iov_schema_validate_config(const nvlist_t *, nvlist_t *);
|
||||
uint16_t pci_iov_config_get_num_vfs(const nvlist_t *);
|
||||
|
||||
#endif
|
127
sys/sys/iov.h
127
sys/sys/iov.h
@ -31,14 +31,141 @@
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#define PF_CONFIG_NAME "PF"
|
||||
#define VF_SCHEMA_NAME "VF"
|
||||
|
||||
#define DRIVER_CONFIG_NAME "DRIVER"
|
||||
#define IOV_CONFIG_NAME "IOV"
|
||||
|
||||
#define TYPE_SCHEMA_NAME "TYPE"
|
||||
#define DEFAULT_SCHEMA_NAME "DEFAULT"
|
||||
#define REQUIRED_SCHEMA_NAME "REQUIRED"
|
||||
|
||||
struct pci_iov_arg
|
||||
{
|
||||
int num_vfs;
|
||||
int passthrough;
|
||||
};
|
||||
|
||||
/*
|
||||
* Because each PF device is expected to expose a unique set of possible
|
||||
* configurations, the SR-IOV infrastructure dynamically queries the PF
|
||||
* driver for its capabilities. These capabilities are exposed to userland
|
||||
* with a configuration schema. The schema is exported from the kernel as a
|
||||
* packed nvlist. See nv(3) for the details of the nvlist API. The expected
|
||||
* format of the nvlist is:
|
||||
*
|
||||
* BASIC RULES
|
||||
* 1) All keys are case-insensitive.
|
||||
* 2) No keys that are not specified below may exist at any level of the
|
||||
* schema.
|
||||
* 3) All keys are mandatory unless explicitly documented as optional. If a
|
||||
* key is mandatory then the associated value is also mandatory.
|
||||
* 4) Order of keys is irrelevant.
|
||||
*
|
||||
* TOP LEVEL
|
||||
* 1) There must be a top-level key with the name PF_CONFIG_NAME. The value
|
||||
* associated with this key is a nvlist that follows the device schema
|
||||
* node format. The parameters in this node specify the configuration
|
||||
* parameters that may be applied to a PF.
|
||||
* 2) There must be a top-level key with the name VF_SCHEMA_NAME. The value
|
||||
* associated with this key is a nvlist that follows the device schema
|
||||
* node format. The parameters in this node specify the configuration
|
||||
* parameters that may be applied to a VF.
|
||||
*
|
||||
* DEVICE SCHEMA NODE
|
||||
* 1) There must be a key with the name DRIVER_CONFIG_NAME. The value
|
||||
* associated with this key is a nvlist that follows the device/subsystem
|
||||
* schema node format. The parameters in this node specify the
|
||||
* configuration parameters that are specific to a particular device
|
||||
* driver.
|
||||
* 2) There must be a key with the name IOV_CONFIG_NAME. The value associated
|
||||
* with this key is an nvlist that follows the device/subsystem schema node
|
||||
* format. The parameters in this node specify the configuration
|
||||
* parameters that are applied by the SR-IOV infrastructure.
|
||||
*
|
||||
* DEVICE/SUBSYSTEM SCHEMA NODE
|
||||
* 1) All keys in the device/subsystem schema node are optional.
|
||||
* 2) Each key specifies the name of a valid configuration parameter that may
|
||||
* be applied to the device/subsystem combination specified by this node.
|
||||
* The value associated with the key specifies the format of valid
|
||||
* configuration values, and must be a nvlist in parameter schema node
|
||||
* format.
|
||||
*
|
||||
* PARAMETER SCHEMA NODE
|
||||
* 1) The parameter schema node must contain a key with the name
|
||||
* TYPE_SCHEMA_NAME. The value associated with this key must be a string.
|
||||
* This string specifies the type of value that the parameter specified by
|
||||
* this node must take. The string must have one of the following values:
|
||||
* - "bool" - The configuration value must be a boolean.
|
||||
* - "mac-addr" - The configuration value must be a binary value. In
|
||||
* addition, the value must be exactly 6 bytes long and
|
||||
* the value must not be a multicast or broadcast mac.
|
||||
* - "uint8_t" - The configuration value must be a integer value in
|
||||
* the range [0, UINT8_MAX].
|
||||
* - "uint16_t" - The configuration value must be a integer value in
|
||||
* the range [0, UINT16_MAX].
|
||||
* - "uint32_t" - The configuration value must be a integer value in
|
||||
* the range [0, UINT32_MAX].
|
||||
* - "uint64_t" - The configuration value must be a integer value in
|
||||
* the range [0, UINT64_MAX].
|
||||
* 2) The parameter schema may contain a key with the name
|
||||
* REQUIRED_SCHEMA_NAME. This key is optional. If this key is present, the
|
||||
* value associated with it must have a boolean type. If the value is true,
|
||||
* then the parameter specified by this schema is a required parameter. All
|
||||
* valid configurations must include all required parameters.
|
||||
* 3) The parameter schema may contain a key with the name DEFAULT_SCHEMA_NAME.
|
||||
* This key is optional. This key must not be present if the parameter
|
||||
* specified by this schema is required. If this key is present, the value
|
||||
* associated with the parent key must follow all restrictions specified by
|
||||
* the type specified by this schema. If a configuration does not supply a
|
||||
* value for the parameter specified by this schema, then the kernel will
|
||||
* apply the value associated with this key in its place.
|
||||
*
|
||||
* The following is an example of a valid schema, as printed by nvlist_dump.
|
||||
* Keys are printed followed by the type of the value in parantheses. The
|
||||
* value is displayed following a colon. The indentation level reflects the
|
||||
* level of nesting of nvlists. String values are displayed between []
|
||||
* brackets. Binary values are shown with the length of the binary value (in
|
||||
* bytes) followed by the actual binary values.
|
||||
*
|
||||
* PF (NVLIST):
|
||||
* IOV (NVLIST):
|
||||
* num_vfs (NVLIST):
|
||||
* type (STRING): [uint16_t]
|
||||
* required (BOOL): TRUE
|
||||
* device (NVLIST):
|
||||
* type (STRING): [string]
|
||||
* required (BOOL): TRUE
|
||||
* DRIVER (NVLIST):
|
||||
* VF (NVLIST):
|
||||
* IOV (NVLIST):
|
||||
* passthrough (NVLIST):
|
||||
* type (STRING): [bool]
|
||||
* default (BOOL): FALSE
|
||||
* DRIVER (NVLIST):
|
||||
* mac-addr (NVLIST):
|
||||
* type (STRING): [mac-addr]
|
||||
* default (BINARY): 6 000000000000
|
||||
* vlan (NVLIST):
|
||||
* type (STRING): [uint16_t]
|
||||
* spoof-check (NVLIST):
|
||||
* type (STRING): [bool]
|
||||
* default (BOOL): TRUE
|
||||
* allow-set-mac (NVLIST):
|
||||
* type (STRING): [bool]
|
||||
* default (BOOL): FALSE
|
||||
*/
|
||||
struct pci_iov_schema
|
||||
{
|
||||
void *schema;
|
||||
size_t len;
|
||||
int error;
|
||||
};
|
||||
|
||||
#define IOV_CONFIG _IOWR('p', 10, struct pci_iov_arg)
|
||||
#define IOV_DELETE _IO('p', 11)
|
||||
#define IOV_GET_SCHEMA _IOWR('p', 12, struct pci_iov_schema)
|
||||
|
||||
#endif
|
||||
|
||||
|
52
sys/sys/iov_schema.h
Normal file
52
sys/sys/iov_schema.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*-
|
||||
* Copyright (c) 2014-2015 Sandvine Inc. All rights reserved.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_IOV_SCHEMA_H_
|
||||
#define _SYS_IOV_SCHEMA_H_
|
||||
|
||||
#define IOV_SCHEMA_HASDEFAULT (1 << 0)
|
||||
#define IOV_SCHEMA_REQUIRED (1 << 1)
|
||||
|
||||
nvlist_t *pci_iov_schema_alloc_node(void);
|
||||
|
||||
void pci_iov_schema_add_bool(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, int defaultVal);
|
||||
void pci_iov_schema_add_string(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, const char *defaultVal);
|
||||
void pci_iov_schema_add_uint8(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, uint8_t defaultVal);
|
||||
void pci_iov_schema_add_uint16(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, uint16_t defaultVal);
|
||||
void pci_iov_schema_add_uint32(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, uint32_t defaultVal);
|
||||
void pci_iov_schema_add_uint64(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, uint64_t defaultVal);
|
||||
void pci_iov_schema_add_unicast_mac(nvlist_t *schema, const char *name,
|
||||
uint32_t flags, const uint8_t * defaultVal);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user