xref: /freebsd/sys/dev/pci/pci_iov_schema.c (revision 1191f7156fa8a1a32a3781b599c85fc6fa2290d0)
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 }