1*1191f715SRyan Stone /*- 2*1191f715SRyan Stone * Copyright (c) 2014-2015 Sandvine Inc. All rights reserved. 3*1191f715SRyan Stone * All rights reserved. 4*1191f715SRyan Stone * 5*1191f715SRyan Stone * Redistribution and use in source and binary forms, with or without 6*1191f715SRyan Stone * modification, are permitted provided that the following conditions 7*1191f715SRyan Stone * are met: 8*1191f715SRyan Stone * 1. Redistributions of source code must retain the above copyright 9*1191f715SRyan Stone * notice, this list of conditions and the following disclaimer. 10*1191f715SRyan Stone * 2. Redistributions in binary form must reproduce the above copyright 11*1191f715SRyan Stone * notice, this list of conditions and the following disclaimer in the 12*1191f715SRyan Stone * documentation and/or other materials provided with the distribution. 13*1191f715SRyan Stone * 14*1191f715SRyan Stone * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*1191f715SRyan Stone * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*1191f715SRyan Stone * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*1191f715SRyan Stone * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*1191f715SRyan Stone * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*1191f715SRyan Stone * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*1191f715SRyan Stone * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*1191f715SRyan Stone * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*1191f715SRyan Stone * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*1191f715SRyan Stone * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*1191f715SRyan Stone * SUCH DAMAGE. 25*1191f715SRyan Stone */ 26*1191f715SRyan Stone 27*1191f715SRyan Stone #include <sys/cdefs.h> 28*1191f715SRyan Stone __FBSDID("$FreeBSD$"); 29*1191f715SRyan Stone 30*1191f715SRyan Stone #include <sys/param.h> 31*1191f715SRyan Stone #include <sys/conf.h> 32*1191f715SRyan Stone #include <sys/kernel.h> 33*1191f715SRyan Stone #include <sys/systm.h> 34*1191f715SRyan Stone #include <sys/malloc.h> 35*1191f715SRyan Stone #include <sys/module.h> 36*1191f715SRyan Stone #include <sys/queue.h> 37*1191f715SRyan Stone 38*1191f715SRyan Stone #include <machine/stdarg.h> 39*1191f715SRyan Stone 40*1191f715SRyan Stone #include <sys/nv.h> 41*1191f715SRyan Stone #include <sys/iov_schema.h> 42*1191f715SRyan Stone 43*1191f715SRyan Stone #include <dev/pci/schema_private.h> 44*1191f715SRyan Stone 45*1191f715SRyan Stone static const char *pci_iov_schema_valid_types[] = { 46*1191f715SRyan Stone "bool", 47*1191f715SRyan Stone "string", 48*1191f715SRyan Stone "uint8_t", 49*1191f715SRyan Stone "uint16_t", 50*1191f715SRyan Stone "uint32_t", 51*1191f715SRyan Stone "uint64_t", 52*1191f715SRyan Stone "unicast-mac", 53*1191f715SRyan Stone }; 54*1191f715SRyan Stone 55*1191f715SRyan Stone static void 56*1191f715SRyan Stone pci_iov_schema_add_type(nvlist_t *entry, const char *type) 57*1191f715SRyan Stone { 58*1191f715SRyan Stone int i, error; 59*1191f715SRyan Stone 60*1191f715SRyan Stone error = EINVAL; 61*1191f715SRyan Stone for (i = 0; i < nitems(pci_iov_schema_valid_types); i++) { 62*1191f715SRyan Stone if (strcmp(type, pci_iov_schema_valid_types[i]) == 0) { 63*1191f715SRyan Stone error = 0; 64*1191f715SRyan Stone break; 65*1191f715SRyan Stone } 66*1191f715SRyan Stone } 67*1191f715SRyan Stone 68*1191f715SRyan Stone if (error != 0) { 69*1191f715SRyan Stone nvlist_set_error(entry, error); 70*1191f715SRyan Stone return; 71*1191f715SRyan Stone } 72*1191f715SRyan Stone 73*1191f715SRyan Stone nvlist_add_string(entry, "type", type); 74*1191f715SRyan Stone } 75*1191f715SRyan Stone 76*1191f715SRyan Stone static void 77*1191f715SRyan Stone pci_iov_schema_add_required(nvlist_t *entry, uint32_t flags) 78*1191f715SRyan Stone { 79*1191f715SRyan Stone 80*1191f715SRyan Stone if (flags & IOV_SCHEMA_REQUIRED) { 81*1191f715SRyan Stone if (flags & IOV_SCHEMA_HASDEFAULT) { 82*1191f715SRyan Stone nvlist_set_error(entry, EINVAL); 83*1191f715SRyan Stone return; 84*1191f715SRyan Stone } 85*1191f715SRyan Stone 86*1191f715SRyan Stone nvlist_add_bool(entry, "required", 1); 87*1191f715SRyan Stone } 88*1191f715SRyan Stone } 89*1191f715SRyan Stone 90*1191f715SRyan Stone void 91*1191f715SRyan Stone pci_iov_schema_add_bool(nvlist_t *schema, const char *name, uint32_t flags, 92*1191f715SRyan Stone int defaultVal) 93*1191f715SRyan Stone { 94*1191f715SRyan Stone nvlist_t *entry; 95*1191f715SRyan Stone 96*1191f715SRyan Stone entry = nvlist_create(NV_FLAG_IGNORE_CASE); 97*1191f715SRyan Stone if (entry == NULL) { 98*1191f715SRyan Stone nvlist_set_error(schema, ENOMEM); 99*1191f715SRyan Stone return; 100*1191f715SRyan Stone } 101*1191f715SRyan Stone 102*1191f715SRyan Stone pci_iov_schema_add_type(entry, "bool"); 103*1191f715SRyan Stone if (flags & IOV_SCHEMA_HASDEFAULT) 104*1191f715SRyan Stone nvlist_add_bool(entry, "default", defaultVal); 105*1191f715SRyan Stone pci_iov_schema_add_required(entry, flags); 106*1191f715SRyan Stone 107*1191f715SRyan Stone nvlist_move_nvlist(schema, name, entry); 108*1191f715SRyan Stone } 109*1191f715SRyan Stone 110*1191f715SRyan Stone void 111*1191f715SRyan Stone pci_iov_schema_add_string(nvlist_t *schema, const char *name, uint32_t flags, 112*1191f715SRyan Stone const char *defaultVal) 113*1191f715SRyan Stone { 114*1191f715SRyan Stone nvlist_t *entry; 115*1191f715SRyan Stone 116*1191f715SRyan Stone entry = nvlist_create(NV_FLAG_IGNORE_CASE); 117*1191f715SRyan Stone if (entry == NULL) { 118*1191f715SRyan Stone nvlist_set_error(schema, ENOMEM); 119*1191f715SRyan Stone return; 120*1191f715SRyan Stone } 121*1191f715SRyan Stone 122*1191f715SRyan Stone pci_iov_schema_add_type(entry, "string"); 123*1191f715SRyan Stone if (flags & IOV_SCHEMA_HASDEFAULT) 124*1191f715SRyan Stone nvlist_add_string(entry, "default", defaultVal); 125*1191f715SRyan Stone pci_iov_schema_add_required(entry, flags); 126*1191f715SRyan Stone 127*1191f715SRyan Stone nvlist_move_nvlist(schema, name, entry); 128*1191f715SRyan Stone } 129*1191f715SRyan Stone 130*1191f715SRyan Stone static void 131*1191f715SRyan Stone pci_iov_schema_int(nvlist_t *schema, const char *name, const char *type, 132*1191f715SRyan Stone uint32_t flags, uint64_t defaultVal) 133*1191f715SRyan Stone { 134*1191f715SRyan Stone nvlist_t *entry; 135*1191f715SRyan Stone 136*1191f715SRyan Stone entry = nvlist_create(NV_FLAG_IGNORE_CASE); 137*1191f715SRyan Stone if (entry == NULL) { 138*1191f715SRyan Stone nvlist_set_error(schema, ENOMEM); 139*1191f715SRyan Stone return; 140*1191f715SRyan Stone } 141*1191f715SRyan Stone 142*1191f715SRyan Stone pci_iov_schema_add_type(entry, type); 143*1191f715SRyan Stone if (flags & IOV_SCHEMA_HASDEFAULT) 144*1191f715SRyan Stone nvlist_add_number(entry, "default", defaultVal); 145*1191f715SRyan Stone pci_iov_schema_add_required(entry, flags); 146*1191f715SRyan Stone 147*1191f715SRyan Stone nvlist_move_nvlist(schema, name, entry); 148*1191f715SRyan Stone } 149*1191f715SRyan Stone 150*1191f715SRyan Stone void 151*1191f715SRyan Stone pci_iov_schema_add_uint8(nvlist_t *schema, const char *name, uint32_t flags, 152*1191f715SRyan Stone uint8_t defaultVal) 153*1191f715SRyan Stone { 154*1191f715SRyan Stone 155*1191f715SRyan Stone pci_iov_schema_int(schema, name, "uint8_t", flags, defaultVal); 156*1191f715SRyan Stone } 157*1191f715SRyan Stone 158*1191f715SRyan Stone void 159*1191f715SRyan Stone pci_iov_schema_add_uint16(nvlist_t *schema, const char *name, uint32_t flags, 160*1191f715SRyan Stone uint16_t defaultVal) 161*1191f715SRyan Stone { 162*1191f715SRyan Stone 163*1191f715SRyan Stone pci_iov_schema_int(schema, name, "uint16_t", flags, defaultVal); 164*1191f715SRyan Stone } 165*1191f715SRyan Stone 166*1191f715SRyan Stone void 167*1191f715SRyan Stone pci_iov_schema_add_uint32(nvlist_t *schema, const char *name, uint32_t flags, 168*1191f715SRyan Stone uint32_t defaultVal) 169*1191f715SRyan Stone { 170*1191f715SRyan Stone 171*1191f715SRyan Stone pci_iov_schema_int(schema, name, "uint32_t", flags, defaultVal); 172*1191f715SRyan Stone } 173*1191f715SRyan Stone 174*1191f715SRyan Stone void 175*1191f715SRyan Stone pci_iov_schema_add_uint64(nvlist_t *schema, const char *name, uint32_t flags, 176*1191f715SRyan Stone uint64_t defaultVal) 177*1191f715SRyan Stone { 178*1191f715SRyan Stone 179*1191f715SRyan Stone pci_iov_schema_int(schema, name, "uint64_t", flags, defaultVal); 180*1191f715SRyan Stone } 181*1191f715SRyan Stone 182*1191f715SRyan Stone void 183*1191f715SRyan Stone pci_iov_schema_add_unicast_mac(nvlist_t *schema, const char *name, 184*1191f715SRyan Stone uint32_t flags, const uint8_t * defaultVal) 185*1191f715SRyan Stone { 186*1191f715SRyan Stone nvlist_t *entry; 187*1191f715SRyan Stone 188*1191f715SRyan Stone entry = nvlist_create(NV_FLAG_IGNORE_CASE); 189*1191f715SRyan Stone if (entry == NULL) { 190*1191f715SRyan Stone nvlist_set_error(schema, ENOMEM); 191*1191f715SRyan Stone return; 192*1191f715SRyan Stone } 193*1191f715SRyan Stone 194*1191f715SRyan Stone pci_iov_schema_add_type(entry, "unicast-mac"); 195*1191f715SRyan Stone if (flags & IOV_SCHEMA_HASDEFAULT) 196*1191f715SRyan Stone nvlist_add_binary(entry, "default", defaultVal, ETHER_ADDR_LEN); 197*1191f715SRyan Stone pci_iov_schema_add_required(entry, flags); 198*1191f715SRyan Stone 199*1191f715SRyan Stone nvlist_move_nvlist(schema, name, entry); 200*1191f715SRyan Stone } 201*1191f715SRyan Stone 202*1191f715SRyan Stone /* Allocate a new empty schema node. */ 203*1191f715SRyan Stone nvlist_t * 204*1191f715SRyan Stone pci_iov_schema_alloc_node(void) 205*1191f715SRyan Stone { 206*1191f715SRyan Stone 207*1191f715SRyan Stone return (nvlist_create(NV_FLAG_IGNORE_CASE)); 208*1191f715SRyan Stone }