Mon Jan 25 19:59:49 2021 UTC ()
s/boolean_t/bool/.  boolean_t is obsolete (from Mach), and this
also fixes a new build issue in libkvm on sparc*.


(mrg)
diff -r1.49 -r1.50 src/sys/dev/ofw/ofw_subr.c
diff -r1.41 -r1.42 src/sys/dev/ofw/openfirm.h
diff -r1.8 -r1.9 src/sys/dev/pci/ixgbe/if_sriov.c

cvs diff -r1.49 -r1.50 src/sys/dev/ofw/ofw_subr.c (switch to unified diff)

--- src/sys/dev/ofw/ofw_subr.c 2021/01/25 12:15:33 1.49
+++ src/sys/dev/ofw/ofw_subr.c 2021/01/25 19:59:49 1.50
@@ -1,642 +1,642 @@ @@ -1,642 +1,642 @@
1/* $NetBSD: ofw_subr.c,v 1.49 2021/01/25 12:15:33 jmcneill Exp $ */ 1/* $NetBSD: ofw_subr.c,v 1.50 2021/01/25 19:59:49 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright 1998 4 * Copyright 1998
5 * Digital Equipment Corporation. All rights reserved. 5 * Digital Equipment Corporation. All rights reserved.
6 * 6 *
7 * This software is furnished under license and may be used and 7 * This software is furnished under license and may be used and
8 * copied only in accordance with the following terms and conditions. 8 * copied only in accordance with the following terms and conditions.
9 * Subject to these conditions, you may download, copy, install, 9 * Subject to these conditions, you may download, copy, install,
10 * use, modify and distribute this software in source and/or binary 10 * use, modify and distribute this software in source and/or binary
11 * form. No title or ownership is transferred hereby. 11 * form. No title or ownership is transferred hereby.
12 * 12 *
13 * 1) Any source code used, modified or distributed must reproduce 13 * 1) Any source code used, modified or distributed must reproduce
14 * and retain this copyright notice and list of conditions as 14 * and retain this copyright notice and list of conditions as
15 * they appear in the source file. 15 * they appear in the source file.
16 * 16 *
17 * 2) No right is granted to use any trade name, trademark, or logo of 17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Digital Equipment Corporation. Neither the "Digital Equipment 18 * Digital Equipment Corporation. Neither the "Digital Equipment
19 * Corporation" name nor any trademark or logo of Digital Equipment 19 * Corporation" name nor any trademark or logo of Digital Equipment
20 * Corporation may be used to endorse or promote products derived 20 * Corporation may be used to endorse or promote products derived
21 * from this software without the prior written permission of 21 * from this software without the prior written permission of
22 * Digital Equipment Corporation. 22 * Digital Equipment Corporation.
23 * 23 *
24 * 3) This software is provided "AS-IS" and any express or implied 24 * 3) This software is provided "AS-IS" and any express or implied
25 * warranties, including but not limited to, any implied warranties 25 * warranties, including but not limited to, any implied warranties
26 * of merchantability, fitness for a particular purpose, or 26 * of merchantability, fitness for a particular purpose, or
27 * non-infringement are disclaimed. In no event shall DIGITAL be 27 * non-infringement are disclaimed. In no event shall DIGITAL be
28 * liable for any damages whatsoever, and in particular, DIGITAL 28 * liable for any damages whatsoever, and in particular, DIGITAL
29 * shall not be liable for special, indirect, consequential, or 29 * shall not be liable for special, indirect, consequential, or
30 * incidental damages or damages for lost profits, loss of 30 * incidental damages or damages for lost profits, loss of
31 * revenue or loss of use, whether such damages arise in contract, 31 * revenue or loss of use, whether such damages arise in contract,
32 * negligence, tort, under statute, in equity, at law or otherwise, 32 * negligence, tort, under statute, in equity, at law or otherwise,
33 * even if advised of the possibility of such damage. 33 * even if advised of the possibility of such damage.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v 1.49 2021/01/25 12:15:33 jmcneill Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v 1.50 2021/01/25 19:59:49 mrg Exp $");
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/kmem.h> 41#include <sys/kmem.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <dev/ofw/openfirm.h> 43#include <dev/ofw/openfirm.h>
44#include <dev/i2c/i2cvar.h> 44#include <dev/i2c/i2cvar.h>
45 45
46#define OFW_MAX_STACK_BUF_SIZE 256 46#define OFW_MAX_STACK_BUF_SIZE 256
47#define OFW_PATH_BUF_SIZE 512 47#define OFW_PATH_BUF_SIZE 512
48 48
49/* 49/*
50 * int of_decode_int(p) 50 * int of_decode_int(p)
51 * 51 *
52 * This routine converts OFW encoded-int datums 52 * This routine converts OFW encoded-int datums
53 * into the integer format of the host machine. 53 * into the integer format of the host machine.
54 * 54 *
55 * It is primarily used to convert integer properties 55 * It is primarily used to convert integer properties
56 * returned by the OF_getprop routine. 56 * returned by the OF_getprop routine.
57 * 57 *
58 * Arguments: 58 * Arguments:
59 * p pointer to unsigned char array which is an 59 * p pointer to unsigned char array which is an
60 * OFW-encoded integer. 60 * OFW-encoded integer.
61 * 61 *
62 * Return Value: 62 * Return Value:
63 * Decoded integer value of argument p. 63 * Decoded integer value of argument p.
64 * 64 *
65 * Side Effects: 65 * Side Effects:
66 * None. 66 * None.
67 */ 67 */
68int 68int
69of_decode_int(const unsigned char *p) 69of_decode_int(const unsigned char *p)
70{ 70{
71 unsigned int i = *p++ << 8; 71 unsigned int i = *p++ << 8;
72 i = (i + *p++) << 8; 72 i = (i + *p++) << 8;
73 i = (i + *p++) << 8; 73 i = (i + *p++) << 8;
74 return (i + *p); 74 return (i + *p);
75} 75}
76 76
77/* 77/*
78 * int of_compatible(phandle, strings) 78 * int of_compatible(phandle, strings)
79 * 79 *
80 * This routine checks an OFW node's "compatible" entry to see if 80 * This routine checks an OFW node's "compatible" entry to see if
81 * it matches any of the provided strings. 81 * it matches any of the provided strings.
82 * 82 *
83 * It should be used when determining whether a driver can drive 83 * It should be used when determining whether a driver can drive
84 * a particular device. 84 * a particular device.
85 * 85 *
86 * Arguments: 86 * Arguments:
87 * phandle OFW phandle of device to be checked for 87 * phandle OFW phandle of device to be checked for
88 * compatibility. 88 * compatibility.
89 * strings Array of containing expected "compatibility" 89 * strings Array of containing expected "compatibility"
90 * property values, presence of any of which 90 * property values, presence of any of which
91 * indicates compatibility. 91 * indicates compatibility.
92 * 92 *
93 * Return Value: 93 * Return Value:
94 * -1 if none of the strings are found in phandle's "compatibility" 94 * -1 if none of the strings are found in phandle's "compatibility"
95 * property, or the reverse index of the matching string in the 95 * property, or the reverse index of the matching string in the
96 * phandle's "compatibility" property. 96 * phandle's "compatibility" property.
97 * 97 *
98 * Side Effects: 98 * Side Effects:
99 * None. 99 * None.
100 */ 100 */
101int 101int
102of_compatible(int phandle, const char * const *strings) 102of_compatible(int phandle, const char * const *strings)
103{ 103{
104 char *prop, propbuf[OFW_MAX_STACK_BUF_SIZE]; 104 char *prop, propbuf[OFW_MAX_STACK_BUF_SIZE];
105 const char *cp; 105 const char *cp;
106 int proplen, match, rv = -1; 106 int proplen, match, rv = -1;
107 107
108 proplen = OF_getproplen(phandle, "compatible"); 108 proplen = OF_getproplen(phandle, "compatible");
109 if (proplen <= 0) { 109 if (proplen <= 0) {
110 return -1; 110 return -1;
111 } 111 }
112 112
113 prop = kmem_tmpbuf_alloc(proplen, propbuf, sizeof(propbuf), KM_SLEEP); 113 prop = kmem_tmpbuf_alloc(proplen, propbuf, sizeof(propbuf), KM_SLEEP);
114 114
115 if (OF_getprop(phandle, "compatible", prop, proplen) != proplen) { 115 if (OF_getprop(phandle, "compatible", prop, proplen) != proplen) {
116 goto out; 116 goto out;
117 } 117 }
118 118
119 for (; (cp = *strings) != NULL; strings++) { 119 for (; (cp = *strings) != NULL; strings++) {
120 if ((match = strlist_match(prop, proplen, cp)) != 0) { 120 if ((match = strlist_match(prop, proplen, cp)) != 0) {
121 rv = match - 1; 121 rv = match - 1;
122 break; 122 break;
123 } 123 }
124 } 124 }
125 125
126 out: 126 out:
127 kmem_tmpbuf_free(prop, proplen, propbuf); 127 kmem_tmpbuf_free(prop, proplen, propbuf);
128 return rv; 128 return rv;
129} 129}
130 130
131/* 131/*
132 * int of_match_compatible(phandle, strings) 132 * int of_match_compatible(phandle, strings)
133 * 133 *
134 * This routine checks an OFW node's "compatible" entry to see if 134 * This routine checks an OFW node's "compatible" entry to see if
135 * it matches any of the provided strings. 135 * it matches any of the provided strings.
136 * 136 *
137 * It should be used when determining whether a driver can drive 137 * It should be used when determining whether a driver can drive
138 * a particular device. 138 * a particular device.
139 * 139 *
140 * Arguments: 140 * Arguments:
141 * phandle OFW phandle of device to be checked for 141 * phandle OFW phandle of device to be checked for
142 * compatibility. 142 * compatibility.
143 * strings Array of containing expected "compatibility" 143 * strings Array of containing expected "compatibility"
144 * property values, presence of any of which 144 * property values, presence of any of which
145 * indicates compatibility. 145 * indicates compatibility.
146 * 146 *
147 * Return Value: 147 * Return Value:
148 * 0 if none of the strings are found in phandle's "compatibility" 148 * 0 if none of the strings are found in phandle's "compatibility"
149 * property, or a positive number based on the reverse index of the 149 * property, or a positive number based on the reverse index of the
150 * matching string in the phandle's "compatibility" property, plus 1. 150 * matching string in the phandle's "compatibility" property, plus 1.
151 * 151 *
152 * Side Effects: 152 * Side Effects:
153 * None. 153 * None.
154 */ 154 */
155int 155int
156of_match_compatible(int phandle, const char * const *strings) 156of_match_compatible(int phandle, const char * const *strings)
157{ 157{
158 return of_compatible(phandle, strings) + 1; 158 return of_compatible(phandle, strings) + 1;
159} 159}
160 160
161/* 161/*
162 * int of_match_compat_data(phandle, compat_data) 162 * int of_match_compat_data(phandle, compat_data)
163 * 163 *
164 * This routine searches an array of compat_data structures for a 164 * This routine searches an array of compat_data structures for a
165 * matching "compatible" entry matching the supplied OFW node. 165 * matching "compatible" entry matching the supplied OFW node.
166 * 166 *
167 * It should be used when determining whether a driver can drive 167 * It should be used when determining whether a driver can drive
168 * a particular device. 168 * a particular device.
169 * 169 *
170 * Arguments: 170 * Arguments:
171 * phandle OFW phandle of device to be checked for 171 * phandle OFW phandle of device to be checked for
172 * compatibility. 172 * compatibility.
173 * compat_data Array of possible compat entry strings and 173 * compat_data Array of possible compat entry strings and
174 * associated metadata. The last entry in the 174 * associated metadata. The last entry in the
175 * list should have a "compat" of NULL to terminate 175 * list should have a "compat" of NULL to terminate
176 * the list. 176 * the list.
177 * 177 *
178 * Return Value: 178 * Return Value:
179 * 0 if none of the strings are found in phandle's "compatibility" 179 * 0 if none of the strings are found in phandle's "compatibility"
180 * property, or a positive number based on the reverse index of the 180 * property, or a positive number based on the reverse index of the
181 * matching string in the phandle's "compatibility" property, plus 1. 181 * matching string in the phandle's "compatibility" property, plus 1.
182 * 182 *
183 * Side Effects: 183 * Side Effects:
184 * None. 184 * None.
185 */ 185 */
186int 186int
187of_match_compat_data(int phandle, 187of_match_compat_data(int phandle,
188 const struct device_compatible_entry *compat_data) 188 const struct device_compatible_entry *compat_data)
189{ 189{
190 char *prop, propbuf[OFW_MAX_STACK_BUF_SIZE]; 190 char *prop, propbuf[OFW_MAX_STACK_BUF_SIZE];
191 int proplen, match = 0; 191 int proplen, match = 0;
192 192
193 proplen = OF_getproplen(phandle, "compatible"); 193 proplen = OF_getproplen(phandle, "compatible");
194 if (proplen <= 0) { 194 if (proplen <= 0) {
195 return 0; 195 return 0;
196 } 196 }
197 197
198 prop = kmem_tmpbuf_alloc(proplen, propbuf, sizeof(propbuf), KM_SLEEP); 198 prop = kmem_tmpbuf_alloc(proplen, propbuf, sizeof(propbuf), KM_SLEEP);
199 199
200 if (OF_getprop(phandle, "compatible", prop, proplen) != proplen) { 200 if (OF_getprop(phandle, "compatible", prop, proplen) != proplen) {
201 goto out; 201 goto out;
202 } 202 }
203 203
204 match = device_compatible_match_strlist(prop, proplen, compat_data); 204 match = device_compatible_match_strlist(prop, proplen, compat_data);
205 205
206 out: 206 out:
207 kmem_tmpbuf_free(prop, proplen, propbuf); 207 kmem_tmpbuf_free(prop, proplen, propbuf);
208 return match; 208 return match;
209} 209}
210 210
211/* 211/*
212 * const struct device_compatible_entry *of_search_compatible(phandle, 212 * const struct device_compatible_entry *of_search_compatible(phandle,
213 * compat_data) 213 * compat_data)
214 * 214 *
215 * This routine searches an array of compat_data structures for a 215 * This routine searches an array of compat_data structures for a
216 * matching "compatible" entry matching the supplied OFW node. 216 * matching "compatible" entry matching the supplied OFW node.
217 * 217 *
218 * Arguments: 218 * Arguments:
219 * phandle OFW phandle of device to be checked for 219 * phandle OFW phandle of device to be checked for
220 * compatibility. 220 * compatibility.
221 * compat_data Array of possible compat entry strings and 221 * compat_data Array of possible compat entry strings and
222 * associated metadata. The last entry in the 222 * associated metadata. The last entry in the
223 * list should have a "compat" of NULL to terminate 223 * list should have a "compat" of NULL to terminate
224 * the list. 224 * the list.
225 * 225 *
226 * Return Value: 226 * Return Value:
227 * The first matching compat_data entry in the array. If no matches 227 * The first matching compat_data entry in the array. If no matches
228 * are found, NULL is returned. 228 * are found, NULL is returned.
229 * 229 *
230 * Side Effects: 230 * Side Effects:
231 * None. 231 * None.
232 */ 232 */
233const struct device_compatible_entry * 233const struct device_compatible_entry *
234of_search_compatible(int phandle, 234of_search_compatible(int phandle,
235 const struct device_compatible_entry *compat_data) 235 const struct device_compatible_entry *compat_data)
236{ 236{
237 char *prop, propbuf[OFW_MAX_STACK_BUF_SIZE]; 237 char *prop, propbuf[OFW_MAX_STACK_BUF_SIZE];
238 const struct device_compatible_entry *match = NULL; 238 const struct device_compatible_entry *match = NULL;
239 int proplen; 239 int proplen;
240 240
241 proplen = OF_getproplen(phandle, "compatible"); 241 proplen = OF_getproplen(phandle, "compatible");
242 if (proplen <= 0) { 242 if (proplen <= 0) {
243 return 0; 243 return 0;
244 } 244 }
245 245
246 prop = kmem_tmpbuf_alloc(proplen, propbuf, sizeof(propbuf), KM_SLEEP); 246 prop = kmem_tmpbuf_alloc(proplen, propbuf, sizeof(propbuf), KM_SLEEP);
247 247
248 if (OF_getprop(phandle, "compatible", prop, proplen) != proplen) { 248 if (OF_getprop(phandle, "compatible", prop, proplen) != proplen) {
249 goto out; 249 goto out;
250 } 250 }
251 251
252 match = device_compatible_lookup_strlist(prop, proplen, compat_data); 252 match = device_compatible_lookup_strlist(prop, proplen, compat_data);
253 253
254 out: 254 out:
255 kmem_tmpbuf_free(prop, proplen, propbuf); 255 kmem_tmpbuf_free(prop, proplen, propbuf);
256 return match; 256 return match;
257} 257}
258 258
259/* 259/*
260 * int of_packagename(phandle, buf, bufsize) 260 * int of_packagename(phandle, buf, bufsize)
261 * 261 *
262 * This routine places the last component of an OFW node's name 262 * This routine places the last component of an OFW node's name
263 * into a user-provided buffer. 263 * into a user-provided buffer.
264 * 264 *
265 * It can be used during autoconfiguration to make printing of 265 * It can be used during autoconfiguration to make printing of
266 * device names more informative. 266 * device names more informative.
267 * 267 *
268 * Arguments: 268 * Arguments:
269 * phandle OFW phandle of device whose name name is 269 * phandle OFW phandle of device whose name name is
270 * desired. 270 * desired.
271 * buf Buffer to contain device name, provided by 271 * buf Buffer to contain device name, provided by
272 * caller. (For now, must be at least 4 272 * caller. (For now, must be at least 4
273 * bytes long.) 273 * bytes long.)
274 * bufsize Length of buffer referenced by 'buf', in 274 * bufsize Length of buffer referenced by 'buf', in
275 * bytes. 275 * bytes.
276 * 276 *
277 * Return Value: 277 * Return Value:
278 * -1 if the device path name could not be obtained or would 278 * -1 if the device path name could not be obtained or would
279 * not fit in the allocated temporary buffer, or zero otherwise 279 * not fit in the allocated temporary buffer, or zero otherwise
280 * (meaning that the leaf node name was successfully extracted). 280 * (meaning that the leaf node name was successfully extracted).
281 * 281 *
282 * Side Effects: 282 * Side Effects:
283 * If the leaf node name was successfully extracted, 'buf' is 283 * If the leaf node name was successfully extracted, 'buf' is
284 * filled in with at most 'bufsize' bytes of the leaf node 284 * filled in with at most 'bufsize' bytes of the leaf node
285 * name. If the leaf node was not successfully extracted, a 285 * name. If the leaf node was not successfully extracted, a
286 * somewhat meaningful string is placed in the buffer. In 286 * somewhat meaningful string is placed in the buffer. In
287 * either case, the contents of 'buf' will be NUL-terminated. 287 * either case, the contents of 'buf' will be NUL-terminated.
288 */ 288 */
289int 289int
290of_packagename(int phandle, char *buf, int bufsize) 290of_packagename(int phandle, char *buf, int bufsize)
291{ 291{
292 char *pbuf; 292 char *pbuf;
293 const char *lastslash; 293 const char *lastslash;
294 int l, rv; 294 int l, rv;
295 295
296 pbuf = kmem_alloc(OFW_PATH_BUF_SIZE, KM_SLEEP); 296 pbuf = kmem_alloc(OFW_PATH_BUF_SIZE, KM_SLEEP);
297 l = OF_package_to_path(phandle, pbuf, OFW_PATH_BUF_SIZE); 297 l = OF_package_to_path(phandle, pbuf, OFW_PATH_BUF_SIZE);
298 298
299 /* check that we could get the name, and that it's not too long. */ 299 /* check that we could get the name, and that it's not too long. */
300 if (l < 0 || 300 if (l < 0 ||
301 (l == OFW_PATH_BUF_SIZE && pbuf[OFW_PATH_BUF_SIZE - 1] != '\0')) { 301 (l == OFW_PATH_BUF_SIZE && pbuf[OFW_PATH_BUF_SIZE - 1] != '\0')) {
302 if (bufsize >= 25) 302 if (bufsize >= 25)
303 snprintf(buf, bufsize, "??? (phandle 0x%x)", phandle); 303 snprintf(buf, bufsize, "??? (phandle 0x%x)", phandle);
304 else if (bufsize >= 4) 304 else if (bufsize >= 4)
305 strlcpy(buf, "???", bufsize); 305 strlcpy(buf, "???", bufsize);
306 else 306 else
307 panic("of_packagename: bufsize = %d is silly", 307 panic("of_packagename: bufsize = %d is silly",
308 bufsize); 308 bufsize);
309 rv = -1; 309 rv = -1;
310 } else { 310 } else {
311 pbuf[l] = '\0'; 311 pbuf[l] = '\0';
312 lastslash = strrchr(pbuf, '/'); 312 lastslash = strrchr(pbuf, '/');
313 strlcpy(buf, (lastslash == NULL) ? pbuf : (lastslash + 1), 313 strlcpy(buf, (lastslash == NULL) ? pbuf : (lastslash + 1),
314 bufsize); 314 bufsize);
315 rv = 0; 315 rv = 0;
316 } 316 }
317 317
318 kmem_free(pbuf, OFW_PATH_BUF_SIZE); 318 kmem_free(pbuf, OFW_PATH_BUF_SIZE);
319 return (rv); 319 return (rv);
320} 320}
321 321
322/*  322/*
323 * Find the first child of a given node that matches name. Does not recurse. 323 * Find the first child of a given node that matches name. Does not recurse.
324 */ 324 */
325int 325int
326of_find_firstchild_byname(int node, const char *name) 326of_find_firstchild_byname(int node, const char *name)
327{ 327{
328 char namex[32];  328 char namex[32];
329 int nn; 329 int nn;
330  330
331 for (nn = OF_child(node); nn; nn = OF_peer(nn)) { 331 for (nn = OF_child(node); nn; nn = OF_peer(nn)) {
332 memset(namex, 0, sizeof(namex)); 332 memset(namex, 0, sizeof(namex));
333 if (OF_getprop(nn, "name", namex, sizeof(namex)) == -1) 333 if (OF_getprop(nn, "name", namex, sizeof(namex)) == -1)
334 continue; 334 continue;
335 if (strcmp(name, namex) == 0) 335 if (strcmp(name, namex) == 0)
336 return nn; 336 return nn;
337 } 337 }
338 return -1; 338 return -1;
339} 339}
340 340
341/* 341/*
342 * Find a child node that is compatible with str. Recurses, starting at node. 342 * Find a child node that is compatible with str. Recurses, starting at node.
343 */ 343 */
344int 344int
345of_find_bycompat(int node, const char *str) 345of_find_bycompat(int node, const char *str)
346{ 346{
347 const char * compatible[] = { str, NULL }; 347 const char * compatible[] = { str, NULL };
348 int child, ret; 348 int child, ret;
349 349
350 for (child = OF_child(node); child; child = OF_peer(child)) { 350 for (child = OF_child(node); child; child = OF_peer(child)) {
351 if (of_match_compatible(child, compatible) != 0) 351 if (of_match_compatible(child, compatible) != 0)
352 return child; 352 return child;
353 ret = of_find_bycompat(child, str); 353 ret = of_find_bycompat(child, str);
354 if (ret != -1) 354 if (ret != -1)
355 return ret; 355 return ret;
356 } 356 }
357 357
358 return -1; 358 return -1;
359} 359}
360 360
361/* 361/*
362 * Find a give node by name. Recurses, and seems to walk upwards too. 362 * Find a give node by name. Recurses, and seems to walk upwards too.
363 */ 363 */
364 364
365int 365int
366of_getnode_byname(int start, const char *target) 366of_getnode_byname(int start, const char *target)
367{ 367{
368 int node, next; 368 int node, next;
369 char name[64]; 369 char name[64];
370 370
371 if (start == 0) 371 if (start == 0)
372 start = OF_peer(0); 372 start = OF_peer(0);
373 373
374 for (node = start; node; node = next) { 374 for (node = start; node; node = next) {
375 memset(name, 0, sizeof name); 375 memset(name, 0, sizeof name);
376 OF_getprop(node, "name", name, sizeof name - 1); 376 OF_getprop(node, "name", name, sizeof name - 1);
377 if (strcmp(name, target) == 0) 377 if (strcmp(name, target) == 0)
378 break; 378 break;
379 379
380 if ((next = OF_child(node)) != 0) 380 if ((next = OF_child(node)) != 0)
381 continue; 381 continue;
382 382
383 while (node) { 383 while (node) {
384 if ((next = OF_peer(node)) != 0) 384 if ((next = OF_peer(node)) != 0)
385 break; 385 break;
386 node = OF_parent(node); 386 node = OF_parent(node);
387 } 387 }
388 } 388 }
389 389
390 /* XXX is this correct? */ 390 /* XXX is this correct? */
391 return node; 391 return node;
392} 392}
393 393
394/* 394/*
395 * Create a uint32_t integer property from an OFW node property. 395 * Create a uint32_t integer property from an OFW node property.
396 */ 396 */
397 397
398boolean_t 398bool
399of_to_uint32_prop(prop_dictionary_t dict, int node, const char *ofname, 399of_to_uint32_prop(prop_dictionary_t dict, int node, const char *ofname,
400 const char *propname) 400 const char *propname)
401{ 401{
402 uint32_t prop; 402 uint32_t prop;
403 403
404 if (OF_getprop(node, ofname, &prop, sizeof(prop)) != sizeof(prop)) 404 if (OF_getprop(node, ofname, &prop, sizeof(prop)) != sizeof(prop))
405 return FALSE; 405 return FALSE;
406 406
407 return(prop_dictionary_set_uint32(dict, propname, prop)); 407 return(prop_dictionary_set_uint32(dict, propname, prop));
408} 408}
409 409
410/* 410/*
411 * Create a data property from an OFW node property. Max size of 256bytes. 411 * Create a data property from an OFW node property. Max size of 256bytes.
412 */ 412 */
413 413
414boolean_t 414bool
415of_to_dataprop(prop_dictionary_t dict, int node, const char *ofname, 415of_to_dataprop(prop_dictionary_t dict, int node, const char *ofname,
416 const char *propname) 416 const char *propname)
417{ 417{
418 int len; 418 int len;
419 uint8_t prop[256]; 419 uint8_t prop[256];
420 420
421 len = OF_getprop(node, ofname, prop, 256); 421 len = OF_getprop(node, ofname, prop, 256);
422 if (len < 1) 422 if (len < 1)
423 return FALSE; 423 return FALSE;
424 424
425 return prop_dictionary_set_data(dict, propname, prop, len); 425 return prop_dictionary_set_data(dict, propname, prop, len);
426} 426}
427 427
428/* 428/*
429 * look at output-device, see if there's a Sun-typical video mode specifier as 429 * look at output-device, see if there's a Sun-typical video mode specifier as
430 * in screen:r1024x768x60 attached. If found copy it into *buffer, otherwise 430 * in screen:r1024x768x60 attached. If found copy it into *buffer, otherwise
431 * return NULL 431 * return NULL
432 */ 432 */
433 433
434char * 434char *
435of_get_mode_string(char *buffer, int len) 435of_get_mode_string(char *buffer, int len)
436{ 436{
437 int options; 437 int options;
438 char *pos, output_device[256]; 438 char *pos, output_device[256];
439 439
440 /* 440 /*
441 * finally, let's see if there's a video mode specified in 441 * finally, let's see if there's a video mode specified in
442 * output-device and pass it on so there's at least some way 442 * output-device and pass it on so there's at least some way
443 * to program video modes 443 * to program video modes
444 */ 444 */
445 options = OF_finddevice("/options"); 445 options = OF_finddevice("/options");
446 if ((options == 0) || (options == -1)) 446 if ((options == 0) || (options == -1))
447 return NULL; 447 return NULL;
448 if (OF_getprop(options, "output-device", output_device, 256) == 0) 448 if (OF_getprop(options, "output-device", output_device, 256) == 0)
449 return NULL; 449 return NULL;
450 450
451 /* find the mode string if there is one */ 451 /* find the mode string if there is one */
452 pos = strstr(output_device, ":r"); 452 pos = strstr(output_device, ":r");
453 if (pos == NULL) 453 if (pos == NULL)
454 return NULL; 454 return NULL;
455 strncpy(buffer, pos + 2, len); 455 strncpy(buffer, pos + 2, len);
456 return buffer; 456 return buffer;
457} 457}
458 458
459/* 459/*
460 * Iterate over the subtree of a i2c controller node. 460 * Iterate over the subtree of a i2c controller node.
461 * Add all sub-devices into an array as part of the controller's 461 * Add all sub-devices into an array as part of the controller's
462 * device properties. 462 * device properties.
463 * This is used by the i2c bus attach code to do direct configuration. 463 * This is used by the i2c bus attach code to do direct configuration.
464 */ 464 */
465void 465void
466of_enter_i2c_devs(prop_dictionary_t props, int ofnode, size_t cell_size, 466of_enter_i2c_devs(prop_dictionary_t props, int ofnode, size_t cell_size,
467 int addr_shift) 467 int addr_shift)
468{ 468{
469 int node, len; 469 int node, len;
470 char name[32]; 470 char name[32];
471 uint64_t reg64; 471 uint64_t reg64;
472 uint32_t reg32; 472 uint32_t reg32;
473 uint64_t addr; 473 uint64_t addr;
474 prop_array_t array = NULL; 474 prop_array_t array = NULL;
475 prop_dictionary_t dev; 475 prop_dictionary_t dev;
476 476
477 for (node = OF_child(ofnode); node; node = OF_peer(node)) { 477 for (node = OF_child(ofnode); node; node = OF_peer(node)) {
478 if (OF_getprop(node, "name", name, sizeof(name)) <= 0) 478 if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
479 continue; 479 continue;
480 len = OF_getproplen(node, "reg"); 480 len = OF_getproplen(node, "reg");
481 addr = 0; 481 addr = 0;
482 if (cell_size == 8 && len >= sizeof(reg64)) { 482 if (cell_size == 8 && len >= sizeof(reg64)) {
483 if (OF_getprop(node, "reg", &reg64, sizeof(reg64)) 483 if (OF_getprop(node, "reg", &reg64, sizeof(reg64))
484 < sizeof(reg64)) 484 < sizeof(reg64))
485 continue; 485 continue;
486 addr = be64toh(reg64); 486 addr = be64toh(reg64);
487 /* 487 /*
488 * The i2c bus number (0 or 1) is encoded in bit 33 488 * The i2c bus number (0 or 1) is encoded in bit 33
489 * of the register, but we encode it in bit 8 of 489 * of the register, but we encode it in bit 8 of
490 * i2c_addr_t. 490 * i2c_addr_t.
491 */ 491 */
492 if (addr & 0x100000000) 492 if (addr & 0x100000000)
493 addr = (addr & 0xff) | 0x100; 493 addr = (addr & 0xff) | 0x100;
494 } else if (cell_size == 4 && len >= sizeof(reg32)) { 494 } else if (cell_size == 4 && len >= sizeof(reg32)) {
495 if (OF_getprop(node, "reg", &reg32, sizeof(reg32)) 495 if (OF_getprop(node, "reg", &reg32, sizeof(reg32))
496 < sizeof(reg32)) 496 < sizeof(reg32))
497 continue; 497 continue;
498 addr = be32toh(reg32); 498 addr = be32toh(reg32);
499 } else { 499 } else {
500 continue; 500 continue;
501 } 501 }
502 addr >>= addr_shift; 502 addr >>= addr_shift;
503 if (addr == 0) continue; 503 if (addr == 0) continue;
504 504
505 if (array == NULL) 505 if (array == NULL)
506 array = prop_array_create(); 506 array = prop_array_create();
507 507
508 dev = prop_dictionary_create(); 508 dev = prop_dictionary_create();
509 prop_dictionary_set_string(dev, "name", name); 509 prop_dictionary_set_string(dev, "name", name);
510 prop_dictionary_set_uint32(dev, "addr", addr); 510 prop_dictionary_set_uint32(dev, "addr", addr);
511 prop_dictionary_set_uint64(dev, "cookie", node); 511 prop_dictionary_set_uint64(dev, "cookie", node);
512 prop_dictionary_set_uint32(dev, "cookietype", I2C_COOKIE_OF); 512 prop_dictionary_set_uint32(dev, "cookietype", I2C_COOKIE_OF);
513 of_to_dataprop(dev, node, "compatible", "compatible"); 513 of_to_dataprop(dev, node, "compatible", "compatible");
514 prop_array_add(array, dev); 514 prop_array_add(array, dev);
515 prop_object_release(dev); 515 prop_object_release(dev);
516 } 516 }
517 517
518 if (array != NULL) { 518 if (array != NULL) {
519 prop_dictionary_set(props, "i2c-child-devices", array); 519 prop_dictionary_set(props, "i2c-child-devices", array);
520 prop_object_release(array); 520 prop_object_release(array);
521 } 521 }
522} 522}
523 523
524void 524void
525of_enter_spi_devs(prop_dictionary_t props, int ofnode, size_t cell_size) 525of_enter_spi_devs(prop_dictionary_t props, int ofnode, size_t cell_size)
526{ 526{
527 int node, len; 527 int node, len;
528 char name[32]; 528 char name[32];
529 uint64_t reg64; 529 uint64_t reg64;
530 uint32_t reg32; 530 uint32_t reg32;
531 uint32_t slave; 531 uint32_t slave;
532 u_int32_t maxfreq; 532 u_int32_t maxfreq;
533 prop_array_t array = NULL; 533 prop_array_t array = NULL;
534 prop_dictionary_t dev; 534 prop_dictionary_t dev;
535 int mode; 535 int mode;
536 536
537 for (node = OF_child(ofnode); node; node = OF_peer(node)) { 537 for (node = OF_child(ofnode); node; node = OF_peer(node)) {
538 if (OF_getprop(node, "name", name, sizeof(name)) <= 0) 538 if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
539 continue; 539 continue;
540 len = OF_getproplen(node, "reg"); 540 len = OF_getproplen(node, "reg");
541 slave = 0; 541 slave = 0;
542 if (cell_size == 8 && len >= sizeof(reg64)) { 542 if (cell_size == 8 && len >= sizeof(reg64)) {
543 if (OF_getprop(node, "reg", &reg64, sizeof(reg64)) 543 if (OF_getprop(node, "reg", &reg64, sizeof(reg64))
544 < sizeof(reg64)) 544 < sizeof(reg64))
545 continue; 545 continue;
546 slave = be64toh(reg64); 546 slave = be64toh(reg64);
547 } else if (cell_size == 4 && len >= sizeof(reg32)) { 547 } else if (cell_size == 4 && len >= sizeof(reg32)) {
548 if (OF_getprop(node, "reg", &reg32, sizeof(reg32)) 548 if (OF_getprop(node, "reg", &reg32, sizeof(reg32))
549 < sizeof(reg32)) 549 < sizeof(reg32))
550 continue; 550 continue;
551 slave = be32toh(reg32); 551 slave = be32toh(reg32);
552 } else { 552 } else {
553 continue; 553 continue;
554 } 554 }
555 if (of_getprop_uint32(node, "spi-max-frequency", &maxfreq)) { 555 if (of_getprop_uint32(node, "spi-max-frequency", &maxfreq)) {
556 maxfreq = 0; 556 maxfreq = 0;
557 } 557 }
558 mode = ((int)of_hasprop(node, "cpol") << 1) | (int)of_hasprop(node, "cpha"); 558 mode = ((int)of_hasprop(node, "cpol") << 1) | (int)of_hasprop(node, "cpha");
559 559
560 if (array == NULL) 560 if (array == NULL)
561 array = prop_array_create(); 561 array = prop_array_create();
562 562
563 dev = prop_dictionary_create(); 563 dev = prop_dictionary_create();
564 prop_dictionary_set_string(dev, "name", name); 564 prop_dictionary_set_string(dev, "name", name);
565 prop_dictionary_set_uint32(dev, "slave", slave); 565 prop_dictionary_set_uint32(dev, "slave", slave);
566 prop_dictionary_set_uint32(dev, "mode", mode); 566 prop_dictionary_set_uint32(dev, "mode", mode);
567 if (maxfreq > 0) 567 if (maxfreq > 0)
568 prop_dictionary_set_uint32(dev, "spi-max-frequency", maxfreq); 568 prop_dictionary_set_uint32(dev, "spi-max-frequency", maxfreq);
569 prop_dictionary_set_uint64(dev, "cookie", node); 569 prop_dictionary_set_uint64(dev, "cookie", node);
570 of_to_dataprop(dev, node, "compatible", "compatible"); 570 of_to_dataprop(dev, node, "compatible", "compatible");
571 prop_array_add(array, dev); 571 prop_array_add(array, dev);
572 prop_object_release(dev); 572 prop_object_release(dev);
573 } 573 }
574 574
575 if (array != NULL) { 575 if (array != NULL) {
576 prop_dictionary_set(props, "spi-child-devices", array); 576 prop_dictionary_set(props, "spi-child-devices", array);
577 prop_object_release(array); 577 prop_object_release(array);
578 } 578 }
579} 579}
580 580
581 581
582/* 582/*
583 * Returns true if the specified property is present. 583 * Returns true if the specified property is present.
584 */ 584 */
585bool 585bool
586of_hasprop(int node, const char *prop) 586of_hasprop(int node, const char *prop)
587{ 587{
588 return OF_getproplen(node, prop) >= 0; 588 return OF_getproplen(node, prop) >= 0;
589} 589}
590 590
591/* 591/*
592 * Get the value of a uint32 property, compensating for host byte order. 592 * Get the value of a uint32 property, compensating for host byte order.
593 * Returns 0 on success, non-zero on failure. 593 * Returns 0 on success, non-zero on failure.
594 */ 594 */
595int 595int
596of_getprop_uint32(int node, const char *prop, uint32_t *val) 596of_getprop_uint32(int node, const char *prop, uint32_t *val)
597{ 597{
598 uint32_t v; 598 uint32_t v;
599 int len; 599 int len;
600 600
601 len = OF_getprop(node, prop, &v, sizeof(v)); 601 len = OF_getprop(node, prop, &v, sizeof(v));
602 if (len != sizeof(v)) 602 if (len != sizeof(v))
603 return -1; 603 return -1;
604 604
605 *val = be32toh(v); 605 *val = be32toh(v);
606 return 0; 606 return 0;
607} 607}
608 608
609int 609int
610of_getprop_uint32_array(int node, const char *prop, uint32_t *array, int n) 610of_getprop_uint32_array(int node, const char *prop, uint32_t *array, int n)
611{ 611{
612 uint32_t *v = array; 612 uint32_t *v = array;
613 int len; 613 int len;
614 614
615 len = OF_getprop(node, prop, array, n * sizeof(*v)); 615 len = OF_getprop(node, prop, array, n * sizeof(*v));
616 if (len < (int)(n * sizeof(*v))) 616 if (len < (int)(n * sizeof(*v)))
617 return -1; 617 return -1;
618 618
619 for (; n > 0; n--) { 619 for (; n > 0; n--) {
620 BE32TOH(*v); 620 BE32TOH(*v);
621 v++; 621 v++;
622 } 622 }
623 623
624 return 0; 624 return 0;
625} 625}
626/* 626/*
627 * Get the value of a uint64 property, compensating for host byte order. 627 * Get the value of a uint64 property, compensating for host byte order.
628 * Returns 0 on success, non-zero on failure. 628 * Returns 0 on success, non-zero on failure.
629 */ 629 */
630int 630int
631of_getprop_uint64(int node, const char *prop, uint64_t *val) 631of_getprop_uint64(int node, const char *prop, uint64_t *val)
632{ 632{
633 uint64_t v; 633 uint64_t v;
634 int len; 634 int len;
635 635
636 len = OF_getprop(node, prop, &v, sizeof(v)); 636 len = OF_getprop(node, prop, &v, sizeof(v));
637 if (len != sizeof(v)) 637 if (len != sizeof(v))
638 return -1; 638 return -1;
639 639
640 *val = be64toh(v); 640 *val = be64toh(v);
641 return 0; 641 return 0;
642} 642}

cvs diff -r1.41 -r1.42 src/sys/dev/ofw/openfirm.h (switch to unified diff)

--- src/sys/dev/ofw/openfirm.h 2021/01/18 02:35:49 1.41
+++ src/sys/dev/ofw/openfirm.h 2021/01/25 19:59:49 1.42
@@ -1,135 +1,133 @@ @@ -1,135 +1,133 @@
1/* $NetBSD: openfirm.h,v 1.41 2021/01/18 02:35:49 thorpej Exp $ */ 1/* $NetBSD: openfirm.h,v 1.42 2021/01/25 19:59:49 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 4 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 * Copyright (C) 1995, 1996 TooLs GmbH. 5 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement: 17 * must display the following acknowledgement:
18 * This product includes software developed by TooLs GmbH. 18 * This product includes software developed by TooLs GmbH.
19 * 4. The name of TooLs GmbH may not be used to endorse or promote products 19 * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#ifndef _OPENFIRM_H_ 34#ifndef _OPENFIRM_H_
35#define _OPENFIRM_H_ 35#define _OPENFIRM_H_
36 36
37#include <prop/proplib.h> 37#include <prop/proplib.h>
38 38
39/* 39/*
40 * Prototypes for OpenFirmware Interface Routines 40 * Prototypes for OpenFirmware Interface Routines
41 */ 41 */
42 42
43/* 43/*
44 * Machine-independent OpenFirmware-related structures. 44 * Machine-independent OpenFirmware-related structures.
45 * XXX THESE DO NOT BELONG HERE. 45 * XXX THESE DO NOT BELONG HERE.
46 */ 46 */
47 47
48/* 48/*
49 * Generic OpenFirmware probe argument. 49 * Generic OpenFirmware probe argument.
50 * This is how all probe structures must start 50 * This is how all probe structures must start
51 * in order to support generic OpenFirmware device drivers. 51 * in order to support generic OpenFirmware device drivers.
52 */ 52 */
53struct ofbus_attach_args { 53struct ofbus_attach_args {
54 const char *oba_busname; 54 const char *oba_busname;
55 char oba_ofname[64]; 55 char oba_ofname[64];
56 int oba_phandle; 56 int oba_phandle;
57 57
58 /* 58 /*
59 * Special unit field for disk devices. 59 * Special unit field for disk devices.
60 * This is a KLUDGE to work around the fact that OpenFirmware 60 * This is a KLUDGE to work around the fact that OpenFirmware
61 * doesn't probe the scsi bus completely. 61 * doesn't probe the scsi bus completely.
62 * YES, I THINK THIS IS A BUG IN THE OPENFIRMWARE DEFINITION!!! XXX 62 * YES, I THINK THIS IS A BUG IN THE OPENFIRMWARE DEFINITION!!! XXX
63 * See also ofdisk.c. 63 * See also ofdisk.c.
64 */ 64 */
65 int oba_unit; 65 int oba_unit;
66}; 66};
67 67
68/* 68/*
69 * Functions and variables provided by machine-dependent code. 69 * Functions and variables provided by machine-dependent code.
70 */ 70 */
71extern char *OF_buf; 71extern char *OF_buf;
72 72
73void OF_boot(const char *) __dead; 73void OF_boot(const char *) __dead;
74int OF_call_method(const char *, int, int, int, ...); 74int OF_call_method(const char *, int, int, int, ...);
75int OF_call_method_1(const char *, int, int, ...); 75int OF_call_method_1(const char *, int, int, ...);
76int OF_child(int); 76int OF_child(int);
77void *OF_claim(void *, u_int, u_int); 77void *OF_claim(void *, u_int, u_int);
78void OF_close(int); 78void OF_close(int);
79void OF_enter(void); 79void OF_enter(void);
80void OF_exit(void) __dead; 80void OF_exit(void) __dead;
81int OF_finddevice(const char *); 81int OF_finddevice(const char *);
82int OF_getprop(int, const char *, void *, int); 82int OF_getprop(int, const char *, void *, int);
83int OF_getproplen(int, const char *); 83int OF_getproplen(int, const char *);
84int OF_instance_to_package(int); 84int OF_instance_to_package(int);
85int OF_instance_to_path(int, char *, int); 85int OF_instance_to_path(int, char *, int);
86int OF_interpret(const char *, int, int, ...); 86int OF_interpret(const char *, int, int, ...);
87int OF_milliseconds(void); 87int OF_milliseconds(void);
88int OF_nextprop(int, const char *, void *); 88int OF_nextprop(int, const char *, void *);
89int OF_open(const char *); 89int OF_open(const char *);
90int OF_package_to_path(int, char *, int); 90int OF_package_to_path(int, char *, int);
91int OF_parent(int); 91int OF_parent(int);
92int OF_peer(int); 92int OF_peer(int);
93void OF_quiesce(void); 93void OF_quiesce(void);
94int OF_read(int, void *, int); 94int OF_read(int, void *, int);
95void OF_release(void *, u_int); 95void OF_release(void *, u_int);
96int OF_seek(int, u_quad_t); 96int OF_seek(int, u_quad_t);
97void (*OF_set_callback(void(*)(void *)))(void *); 97void (*OF_set_callback(void(*)(void *)))(void *);
98int OF_setprop(int, const char *, const void *, int); 98int OF_setprop(int, const char *, const void *, int);
99int OF_write(int, const void *, int); 99int OF_write(int, const void *, int);
100 100
101int openfirmware(void *); 101int openfirmware(void *);
102 102
103/* 103/*
104 * Functions and variables provided by machine-independent code. 104 * Functions and variables provided by machine-independent code.
105 */ 105 */
106struct device_compatible_entry; 106struct device_compatible_entry;
107 107
108int of_compatible(int, const char * const *); 108int of_compatible(int, const char * const *);
109int of_match_compatible(int, const char * const *); 109int of_match_compatible(int, const char * const *);
110int of_match_compat_data(int, const struct device_compatible_entry *); 110int of_match_compat_data(int, const struct device_compatible_entry *);
111const struct device_compatible_entry * 111const struct device_compatible_entry *
112 of_search_compatible(int, const struct device_compatible_entry *); 112 of_search_compatible(int, const struct device_compatible_entry *);
113int of_decode_int(const unsigned char *); 113int of_decode_int(const unsigned char *);
114int of_packagename(int, char *, int); 114int of_packagename(int, char *, int);
115int of_find_firstchild_byname(int, const char *); 115int of_find_firstchild_byname(int, const char *);
116int of_find_bycompat(int, const char *); 116int of_find_bycompat(int, const char *);
117int of_getnode_byname(int, const char *); 117int of_getnode_byname(int, const char *);
118boolean_t of_to_uint32_prop(prop_dictionary_t, int, const char *, 118bool of_to_uint32_prop(prop_dictionary_t, int, const char *, const char *);
119 const char *); 119bool of_to_dataprop(prop_dictionary_t, int, const char *, const char *);
120boolean_t of_to_dataprop(prop_dictionary_t, int, const char *, 
121 const char *); 
122 120
123int *of_network_decode_media(int, int *, int *); 121int *of_network_decode_media(int, int *, int *);
124char *of_get_mode_string(char *, int); 122char *of_get_mode_string(char *, int);
125 123
126void of_enter_i2c_devs(prop_dictionary_t, int, size_t, int); 124void of_enter_i2c_devs(prop_dictionary_t, int, size_t, int);
127void of_enter_spi_devs(prop_dictionary_t, int, size_t); 125void of_enter_spi_devs(prop_dictionary_t, int, size_t);
128 126
129bool of_hasprop(int, const char *); 127bool of_hasprop(int, const char *);
130#define of_getprop_bool of_hasprop 128#define of_getprop_bool of_hasprop
131int of_getprop_uint32(int, const char *, uint32_t *); 129int of_getprop_uint32(int, const char *, uint32_t *);
132int of_getprop_uint32_array(int, const char *, uint32_t *, int); 130int of_getprop_uint32_array(int, const char *, uint32_t *, int);
133int of_getprop_uint64(int, const char *, uint64_t *); 131int of_getprop_uint64(int, const char *, uint64_t *);
134 132
135#endif /*_OPENFIRM_H_*/ 133#endif /*_OPENFIRM_H_*/

cvs diff -r1.8 -r1.9 src/sys/dev/pci/ixgbe/if_sriov.c (switch to unified diff)

--- src/sys/dev/pci/ixgbe/if_sriov.c 2020/09/07 05:50:58 1.8
+++ src/sys/dev/pci/ixgbe/if_sriov.c 2021/01/25 19:59:49 1.9
@@ -1,932 +1,932 @@ @@ -1,932 +1,932 @@
1/****************************************************************************** 1/******************************************************************************
2 2
3 Copyright (c) 2001-2017, Intel Corporation 3 Copyright (c) 2001-2017, Intel Corporation
4 All rights reserved. 4 All rights reserved.
5 5
6 Redistribution and use in source and binary forms, with or without 6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met: 7 modification, are permitted provided that the following conditions are met:
8 8
9 1. Redistributions of source code must retain the above copyright notice, 9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer. 10 this list of conditions and the following disclaimer.
11 11
12 2. Redistributions in binary form must reproduce the above copyright 12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the 13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution. 14 documentation and/or other materials provided with the distribution.
15 15
16 3. Neither the name of the Intel Corporation nor the names of its 16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from 17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission. 18 this software without specific prior written permission.
19 19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE. 30 POSSIBILITY OF SUCH DAMAGE.
31 31
32******************************************************************************/ 32******************************************************************************/
33/*$FreeBSD: head/sys/dev/ixgbe/if_sriov.c 327031 2017-12-20 18:15:06Z erj $*/ 33/*$FreeBSD: head/sys/dev/ixgbe/if_sriov.c 327031 2017-12-20 18:15:06Z erj $*/
34 34
35#include "ixgbe.h" 35#include "ixgbe.h"
36#include "ixgbe_sriov.h" 36#include "ixgbe_sriov.h"
37 37
38#ifdef PCI_IOV 38#ifdef PCI_IOV
39 39
40MALLOC_DEFINE(M_IXGBE_SRIOV, "ix_sriov", "ix SR-IOV allocations"); 40MALLOC_DEFINE(M_IXGBE_SRIOV, "ix_sriov", "ix SR-IOV allocations");
41 41
42/************************************************************************ 42/************************************************************************
43 * ixgbe_pci_iov_detach 43 * ixgbe_pci_iov_detach
44 ************************************************************************/ 44 ************************************************************************/
45int 45int
46ixgbe_pci_iov_detach(device_t dev) 46ixgbe_pci_iov_detach(device_t dev)
47{ 47{
48 return pci_iov_detach(dev); 48 return pci_iov_detach(dev);
49} 49}
50 50
51/************************************************************************ 51/************************************************************************
52 * ixgbe_define_iov_schemas 52 * ixgbe_define_iov_schemas
53 ************************************************************************/ 53 ************************************************************************/
54void 54void
55ixgbe_define_iov_schemas(device_t dev, int *error) 55ixgbe_define_iov_schemas(device_t dev, int *error)
56{ 56{
57 nvlist_t *pf_schema, *vf_schema; 57 nvlist_t *pf_schema, *vf_schema;
58 58
59 pf_schema = pci_iov_schema_alloc_node(); 59 pf_schema = pci_iov_schema_alloc_node();
60 vf_schema = pci_iov_schema_alloc_node(); 60 vf_schema = pci_iov_schema_alloc_node();
61 pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL); 61 pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
62 pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof", 62 pci_iov_schema_add_bool(vf_schema, "mac-anti-spoof",
63 IOV_SCHEMA_HASDEFAULT, TRUE); 63 IOV_SCHEMA_HASDEFAULT, TRUE);
64 pci_iov_schema_add_bool(vf_schema, "allow-set-mac", 64 pci_iov_schema_add_bool(vf_schema, "allow-set-mac",
65 IOV_SCHEMA_HASDEFAULT, FALSE); 65 IOV_SCHEMA_HASDEFAULT, FALSE);
66 pci_iov_schema_add_bool(vf_schema, "allow-promisc", 66 pci_iov_schema_add_bool(vf_schema, "allow-promisc",
67 IOV_SCHEMA_HASDEFAULT, FALSE); 67 IOV_SCHEMA_HASDEFAULT, FALSE);
68 *error = pci_iov_attach(dev, pf_schema, vf_schema); 68 *error = pci_iov_attach(dev, pf_schema, vf_schema);
69 if (*error != 0) { 69 if (*error != 0) {
70 device_printf(dev, 70 device_printf(dev,
71 "Error %d setting up SR-IOV\n", *error); 71 "Error %d setting up SR-IOV\n", *error);
72 } 72 }
73} /* ixgbe_define_iov_schemas */ 73} /* ixgbe_define_iov_schemas */
74 74
75/************************************************************************ 75/************************************************************************
76 * ixgbe_align_all_queue_indices 76 * ixgbe_align_all_queue_indices
77 ************************************************************************/ 77 ************************************************************************/
78inline void 78inline void
79ixgbe_align_all_queue_indices(struct adapter *adapter) 79ixgbe_align_all_queue_indices(struct adapter *adapter)
80{ 80{
81 int i; 81 int i;
82 int index; 82 int index;
83 83
84 for (i = 0; i < adapter->num_queues; i++) { 84 for (i = 0; i < adapter->num_queues; i++) {
85 index = ixgbe_vf_que_index(adapter->iov_mode, adapter->pool, i); 85 index = ixgbe_vf_que_index(adapter->iov_mode, adapter->pool, i);
86 adapter->rx_rings[i].me = index; 86 adapter->rx_rings[i].me = index;
87 adapter->tx_rings[i].me = index; 87 adapter->tx_rings[i].me = index;
88 } 88 }
89} 89}
90 90
91/* Support functions for SR-IOV/VF management */ 91/* Support functions for SR-IOV/VF management */
92static inline void 92static inline void
93ixgbe_send_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) 93ixgbe_send_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
94{ 94{
95 if (vf->flags & IXGBE_VF_CTS) 95 if (vf->flags & IXGBE_VF_CTS)
96 msg |= IXGBE_VT_MSGTYPE_CTS; 96 msg |= IXGBE_VT_MSGTYPE_CTS;
97 97
98 adapter->hw.mbx.ops.write(&adapter->hw, &msg, 1, vf->pool); 98 adapter->hw.mbx.ops.write(&adapter->hw, &msg, 1, vf->pool);
99} 99}
100 100
101static inline void 101static inline void
102ixgbe_send_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) 102ixgbe_send_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
103{ 103{
104 msg &= IXGBE_VT_MSG_MASK; 104 msg &= IXGBE_VT_MSG_MASK;
105 ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_ACK); 105 ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_ACK);
106} 106}
107 107
108static inline void 108static inline void
109ixgbe_send_vf_nack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg) 109ixgbe_send_vf_nack(struct adapter *adapter, struct ixgbe_vf *vf, u32 msg)
110{ 110{
111 msg &= IXGBE_VT_MSG_MASK; 111 msg &= IXGBE_VT_MSG_MASK;
112 ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_NACK); 112 ixgbe_send_vf_msg(adapter, vf, msg | IXGBE_VT_MSGTYPE_NACK);
113} 113}
114 114
115static inline void 115static inline void
116ixgbe_process_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf) 116ixgbe_process_vf_ack(struct adapter *adapter, struct ixgbe_vf *vf)
117{ 117{
118 if (!(vf->flags & IXGBE_VF_CTS)) 118 if (!(vf->flags & IXGBE_VF_CTS))
119 ixgbe_send_vf_nack(adapter, vf, 0); 119 ixgbe_send_vf_nack(adapter, vf, 0);
120} 120}
121 121
122static inline boolean_t 122static inline bool
123ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac) 123ixgbe_vf_mac_changed(struct ixgbe_vf *vf, const uint8_t *mac)
124{ 124{
125 return (bcmp(mac, vf->ether_addr, ETHER_ADDR_LEN) != 0); 125 return (bcmp(mac, vf->ether_addr, ETHER_ADDR_LEN) != 0);
126} 126}
127 127
128static inline int 128static inline int
129ixgbe_vf_queues(int mode) 129ixgbe_vf_queues(int mode)
130{ 130{
131 switch (mode) { 131 switch (mode) {
132 case IXGBE_64_VM: 132 case IXGBE_64_VM:
133 return (2); 133 return (2);
134 case IXGBE_32_VM: 134 case IXGBE_32_VM:
135 return (4); 135 return (4);
136 case IXGBE_NO_VM: 136 case IXGBE_NO_VM:
137 default: 137 default:
138 return (0); 138 return (0);
139 } 139 }
140} 140}
141 141
142inline int 142inline int
143ixgbe_vf_que_index(int mode, int vfnum, int num) 143ixgbe_vf_que_index(int mode, int vfnum, int num)
144{ 144{
145 return ((vfnum * ixgbe_vf_queues(mode)) + num); 145 return ((vfnum * ixgbe_vf_queues(mode)) + num);
146} 146}
147 147
148static inline void 148static inline void
149ixgbe_update_max_frame(struct adapter * adapter, int max_frame) 149ixgbe_update_max_frame(struct adapter * adapter, int max_frame)
150{ 150{
151 if (adapter->max_frame_size < max_frame) 151 if (adapter->max_frame_size < max_frame)
152 adapter->max_frame_size = max_frame; 152 adapter->max_frame_size = max_frame;
153} 153}
154 154
155inline u32 155inline u32
156ixgbe_get_mrqc(int iov_mode) 156ixgbe_get_mrqc(int iov_mode)
157{ 157{
158 u32 mrqc; 158 u32 mrqc;
159 159
160 switch (iov_mode) { 160 switch (iov_mode) {
161 case IXGBE_64_VM: 161 case IXGBE_64_VM:
162 mrqc = IXGBE_MRQC_VMDQRSS64EN; 162 mrqc = IXGBE_MRQC_VMDQRSS64EN;
163 break; 163 break;
164 case IXGBE_32_VM: 164 case IXGBE_32_VM:
165 mrqc = IXGBE_MRQC_VMDQRSS32EN; 165 mrqc = IXGBE_MRQC_VMDQRSS32EN;
166 break; 166 break;
167 case IXGBE_NO_VM: 167 case IXGBE_NO_VM:
168 mrqc = 0; 168 mrqc = 0;
169 break; 169 break;
170 default: 170 default:
171 panic("Unexpected SR-IOV mode %d", iov_mode); 171 panic("Unexpected SR-IOV mode %d", iov_mode);
172 } 172 }
173 173
174 return mrqc; 174 return mrqc;
175} 175}
176 176
177 177
178inline u32 178inline u32
179ixgbe_get_mtqc(int iov_mode) 179ixgbe_get_mtqc(int iov_mode)
180{ 180{
181 uint32_t mtqc; 181 uint32_t mtqc;
182 182
183 switch (iov_mode) { 183 switch (iov_mode) {
184 case IXGBE_64_VM: 184 case IXGBE_64_VM:
185 mtqc = IXGBE_MTQC_64VF | IXGBE_MTQC_VT_ENA; 185 mtqc = IXGBE_MTQC_64VF | IXGBE_MTQC_VT_ENA;
186 break; 186 break;
187 case IXGBE_32_VM: 187 case IXGBE_32_VM:
188 mtqc = IXGBE_MTQC_32VF | IXGBE_MTQC_VT_ENA; 188 mtqc = IXGBE_MTQC_32VF | IXGBE_MTQC_VT_ENA;
189 break; 189 break;
190 case IXGBE_NO_VM: 190 case IXGBE_NO_VM:
191 mtqc = IXGBE_MTQC_64Q_1PB; 191 mtqc = IXGBE_MTQC_64Q_1PB;
192 break; 192 break;
193 default: 193 default:
194 panic("Unexpected SR-IOV mode %d", iov_mode); 194 panic("Unexpected SR-IOV mode %d", iov_mode);
195 } 195 }
196 196
197 return mtqc; 197 return mtqc;
198} 198}
199 199
200void 200void
201ixgbe_ping_all_vfs(struct adapter *adapter) 201ixgbe_ping_all_vfs(struct adapter *adapter)
202{ 202{
203 struct ixgbe_vf *vf; 203 struct ixgbe_vf *vf;
204 204
205 for (int i = 0; i < adapter->num_vfs; i++) { 205 for (int i = 0; i < adapter->num_vfs; i++) {
206 vf = &adapter->vfs[i]; 206 vf = &adapter->vfs[i];
207 if (vf->flags & IXGBE_VF_ACTIVE) 207 if (vf->flags & IXGBE_VF_ACTIVE)
208 ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG); 208 ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG);
209 } 209 }
210} /* ixgbe_ping_all_vfs */ 210} /* ixgbe_ping_all_vfs */
211 211
212 212
213static void 213static void
214ixgbe_vf_set_default_vlan(struct adapter *adapter, struct ixgbe_vf *vf, 214ixgbe_vf_set_default_vlan(struct adapter *adapter, struct ixgbe_vf *vf,
215 uint16_t tag) 215 uint16_t tag)
216{ 216{
217 struct ixgbe_hw *hw; 217 struct ixgbe_hw *hw;
218 uint32_t vmolr, vmvir; 218 uint32_t vmolr, vmvir;
219 219
220 hw = &adapter->hw; 220 hw = &adapter->hw;
221 221
222 vf->vlan_tag = tag; 222 vf->vlan_tag = tag;
223 223
224 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf->pool)); 224 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf->pool));
225 225
226 /* Do not receive packets that pass inexact filters. */ 226 /* Do not receive packets that pass inexact filters. */
227 vmolr &= ~(IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE); 227 vmolr &= ~(IXGBE_VMOLR_ROMPE | IXGBE_VMOLR_ROPE);
228 228
229 /* Disable Multicast Promicuous Mode. */ 229 /* Disable Multicast Promicuous Mode. */
230 vmolr &= ~IXGBE_VMOLR_MPE; 230 vmolr &= ~IXGBE_VMOLR_MPE;
231 231
232 /* Accept broadcasts. */ 232 /* Accept broadcasts. */
233 vmolr |= IXGBE_VMOLR_BAM; 233 vmolr |= IXGBE_VMOLR_BAM;
234 234
235 if (tag == 0) { 235 if (tag == 0) {
236 /* Accept non-vlan tagged traffic. */ 236 /* Accept non-vlan tagged traffic. */
237 vmolr |= IXGBE_VMOLR_AUPE; 237 vmolr |= IXGBE_VMOLR_AUPE;
238 238
239 /* Allow VM to tag outgoing traffic; no default tag. */ 239 /* Allow VM to tag outgoing traffic; no default tag. */
240 vmvir = 0; 240 vmvir = 0;
241 } else { 241 } else {
242 /* Require vlan-tagged traffic. */ 242 /* Require vlan-tagged traffic. */
243 vmolr &= ~IXGBE_VMOLR_AUPE; 243 vmolr &= ~IXGBE_VMOLR_AUPE;
244 244
245 /* Tag all traffic with provided vlan tag. */ 245 /* Tag all traffic with provided vlan tag. */
246 vmvir = (tag | IXGBE_VMVIR_VLANA_DEFAULT); 246 vmvir = (tag | IXGBE_VMVIR_VLANA_DEFAULT);
247 } 247 }
248 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf->pool), vmolr); 248 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf->pool), vmolr);
249 IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf->pool), vmvir); 249 IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf->pool), vmvir);
250} /* ixgbe_vf_set_default_vlan */ 250} /* ixgbe_vf_set_default_vlan */
251 251
252 252
253static void 253static void
254ixgbe_clear_vfmbmem(struct ixgbe_hw *hw, struct ixgbe_vf *vf) 254ixgbe_clear_vfmbmem(struct ixgbe_hw *hw, struct ixgbe_vf *vf)
255{ 255{
256 uint32_t vf_index = IXGBE_VF_INDEX(vf->pool); 256 uint32_t vf_index = IXGBE_VF_INDEX(vf->pool);
257 uint16_t mbx_size = hw->mbx.size; 257 uint16_t mbx_size = hw->mbx.size;
258 uint16_t i; 258 uint16_t i;
259 259
260 IXGBE_CORE_LOCK_ASSERT(adapter); 260 IXGBE_CORE_LOCK_ASSERT(adapter);
261 261
262 for (i = 0; i < mbx_size; ++i) 262 for (i = 0; i < mbx_size; ++i)
263 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_index), i, 0x0); 263 IXGBE_WRITE_REG_ARRAY(hw, IXGBE_PFMBMEM(vf_index), i, 0x0);
264} /* ixgbe_clear_vfmbmem */ 264} /* ixgbe_clear_vfmbmem */
265 265
266 266
267static boolean_t 267static bool
268ixgbe_vf_frame_size_compatible(struct adapter *adapter, struct ixgbe_vf *vf) 268ixgbe_vf_frame_size_compatible(struct adapter *adapter, struct ixgbe_vf *vf)
269{ 269{
270 270
271 /* 271 /*
272 * Frame size compatibility between PF and VF is only a problem on 272 * Frame size compatibility between PF and VF is only a problem on
273 * 82599-based cards. X540 and later support any combination of jumbo 273 * 82599-based cards. X540 and later support any combination of jumbo
274 * frames on PFs and VFs. 274 * frames on PFs and VFs.
275 */ 275 */
276 if (adapter->hw.mac.type != ixgbe_mac_82599EB) 276 if (adapter->hw.mac.type != ixgbe_mac_82599EB)
277 return (TRUE); 277 return (TRUE);
278 278
279 switch (vf->api_ver) { 279 switch (vf->api_ver) {
280 case IXGBE_API_VER_1_0: 280 case IXGBE_API_VER_1_0:
281 case IXGBE_API_VER_UNKNOWN: 281 case IXGBE_API_VER_UNKNOWN:
282 /* 282 /*
283 * On legacy (1.0 and older) VF versions, we don't support jumbo 283 * On legacy (1.0 and older) VF versions, we don't support jumbo
284 * frames on either the PF or the VF. 284 * frames on either the PF or the VF.
285 */ 285 */
286 if (adapter->max_frame_size > ETHER_MAX_LEN || 286 if (adapter->max_frame_size > ETHER_MAX_LEN ||
287 vf->max_frame_size > ETHER_MAX_LEN) 287 vf->max_frame_size > ETHER_MAX_LEN)
288 return (FALSE); 288 return (FALSE);
289 289
290 return (TRUE); 290 return (TRUE);
291 291
292 break; 292 break;
293 case IXGBE_API_VER_1_1: 293 case IXGBE_API_VER_1_1:
294 default: 294 default:
295 /* 295 /*
296 * 1.1 or later VF versions always work if they aren't using 296 * 1.1 or later VF versions always work if they aren't using
297 * jumbo frames. 297 * jumbo frames.
298 */ 298 */
299 if (vf->max_frame_size <= ETHER_MAX_LEN) 299 if (vf->max_frame_size <= ETHER_MAX_LEN)
300 return (TRUE); 300 return (TRUE);
301 301
302 /* 302 /*
303 * Jumbo frames only work with VFs if the PF is also using jumbo 303 * Jumbo frames only work with VFs if the PF is also using jumbo
304 * frames. 304 * frames.
305 */ 305 */
306 if (adapter->max_frame_size <= ETHER_MAX_LEN) 306 if (adapter->max_frame_size <= ETHER_MAX_LEN)
307 return (TRUE); 307 return (TRUE);
308 308
309 return (FALSE); 309 return (FALSE);
310 } 310 }
311} /* ixgbe_vf_frame_size_compatible */ 311} /* ixgbe_vf_frame_size_compatible */
312 312
313 313
314static void 314static void
315ixgbe_process_vf_reset(struct adapter *adapter, struct ixgbe_vf *vf) 315ixgbe_process_vf_reset(struct adapter *adapter, struct ixgbe_vf *vf)
316{ 316{
317 ixgbe_vf_set_default_vlan(adapter, vf, vf->default_vlan); 317 ixgbe_vf_set_default_vlan(adapter, vf, vf->default_vlan);
318 318
319 // XXX clear multicast addresses 319 // XXX clear multicast addresses
320 320
321 ixgbe_clear_rar(&adapter->hw, vf->rar_index); 321 ixgbe_clear_rar(&adapter->hw, vf->rar_index);
322 ixgbe_clear_vfmbmem(&adapter->hw, vf); 322 ixgbe_clear_vfmbmem(&adapter->hw, vf);
323 ixgbe_toggle_txdctl(&adapter->hw, IXGBE_VF_INDEX(vf->pool)); 323 ixgbe_toggle_txdctl(&adapter->hw, IXGBE_VF_INDEX(vf->pool));
324 324
325 vf->api_ver = IXGBE_API_VER_UNKNOWN; 325 vf->api_ver = IXGBE_API_VER_UNKNOWN;
326} /* ixgbe_process_vf_reset */ 326} /* ixgbe_process_vf_reset */
327 327
328 328
329static void 329static void
330ixgbe_vf_enable_transmit(struct adapter *adapter, struct ixgbe_vf *vf) 330ixgbe_vf_enable_transmit(struct adapter *adapter, struct ixgbe_vf *vf)
331{ 331{
332 struct ixgbe_hw *hw; 332 struct ixgbe_hw *hw;
333 uint32_t vf_index, vfte; 333 uint32_t vf_index, vfte;
334 334
335 hw = &adapter->hw; 335 hw = &adapter->hw;
336 336
337 vf_index = IXGBE_VF_INDEX(vf->pool); 337 vf_index = IXGBE_VF_INDEX(vf->pool);
338 vfte = IXGBE_READ_REG(hw, IXGBE_VFTE(vf_index)); 338 vfte = IXGBE_READ_REG(hw, IXGBE_VFTE(vf_index));
339 vfte |= IXGBE_VF_BIT(vf->pool); 339 vfte |= IXGBE_VF_BIT(vf->pool);
340 IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_index), vfte); 340 IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_index), vfte);
341} /* ixgbe_vf_enable_transmit */ 341} /* ixgbe_vf_enable_transmit */
342 342
343 343
344static void 344static void
345ixgbe_vf_enable_receive(struct adapter *adapter, struct ixgbe_vf *vf) 345ixgbe_vf_enable_receive(struct adapter *adapter, struct ixgbe_vf *vf)
346{ 346{
347 struct ixgbe_hw *hw; 347 struct ixgbe_hw *hw;
348 uint32_t vf_index, vfre; 348 uint32_t vf_index, vfre;
349 349
350 hw = &adapter->hw; 350 hw = &adapter->hw;
351 351
352 vf_index = IXGBE_VF_INDEX(vf->pool); 352 vf_index = IXGBE_VF_INDEX(vf->pool);
353 vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index)); 353 vfre = IXGBE_READ_REG(hw, IXGBE_VFRE(vf_index));
354 if (ixgbe_vf_frame_size_compatible(adapter, vf)) 354 if (ixgbe_vf_frame_size_compatible(adapter, vf))
355 vfre |= IXGBE_VF_BIT(vf->pool); 355 vfre |= IXGBE_VF_BIT(vf->pool);
356 else 356 else
357 vfre &= ~IXGBE_VF_BIT(vf->pool); 357 vfre &= ~IXGBE_VF_BIT(vf->pool);
358 IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_index), vfre); 358 IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_index), vfre);
359} /* ixgbe_vf_enable_receive */ 359} /* ixgbe_vf_enable_receive */
360 360
361 361
362static void 362static void
363ixgbe_vf_reset_msg(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) 363ixgbe_vf_reset_msg(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
364{ 364{
365 struct ixgbe_hw *hw; 365 struct ixgbe_hw *hw;
366 uint32_t ack; 366 uint32_t ack;
367 uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN]; 367 uint32_t resp[IXGBE_VF_PERMADDR_MSG_LEN];
368 368
369 hw = &adapter->hw; 369 hw = &adapter->hw;
370 370
371 ixgbe_process_vf_reset(adapter, vf); 371 ixgbe_process_vf_reset(adapter, vf);
372 372
373 if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { 373 if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
374 ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, 374 ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr,
375 vf->pool, TRUE); 375 vf->pool, TRUE);
376 ack = IXGBE_VT_MSGTYPE_ACK; 376 ack = IXGBE_VT_MSGTYPE_ACK;
377 } else 377 } else
378 ack = IXGBE_VT_MSGTYPE_NACK; 378 ack = IXGBE_VT_MSGTYPE_NACK;
379 379
380 ixgbe_vf_enable_transmit(adapter, vf); 380 ixgbe_vf_enable_transmit(adapter, vf);
381 ixgbe_vf_enable_receive(adapter, vf); 381 ixgbe_vf_enable_receive(adapter, vf);
382 382
383 vf->flags |= IXGBE_VF_CTS; 383 vf->flags |= IXGBE_VF_CTS;
384 384
385 resp[0] = IXGBE_VF_RESET | ack; 385 resp[0] = IXGBE_VF_RESET | ack;
386 bcopy(vf->ether_addr, &resp[1], ETHER_ADDR_LEN); 386 bcopy(vf->ether_addr, &resp[1], ETHER_ADDR_LEN);
387 resp[3] = hw->mac.mc_filter_type; 387 resp[3] = hw->mac.mc_filter_type;
388 hw->mbx.ops.write(hw, resp, IXGBE_VF_PERMADDR_MSG_LEN, vf->pool); 388 hw->mbx.ops.write(hw, resp, IXGBE_VF_PERMADDR_MSG_LEN, vf->pool);
389} /* ixgbe_vf_reset_msg */ 389} /* ixgbe_vf_reset_msg */
390 390
391 391
392static void 392static void
393ixgbe_vf_set_mac(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) 393ixgbe_vf_set_mac(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
394{ 394{
395 uint8_t *mac; 395 uint8_t *mac;
396 396
397 mac = (uint8_t*)&msg[1]; 397 mac = (uint8_t*)&msg[1];
398 398
399 /* Check that the VF has permission to change the MAC address. */ 399 /* Check that the VF has permission to change the MAC address. */
400 if (!(vf->flags & IXGBE_VF_CAP_MAC) && ixgbe_vf_mac_changed(vf, mac)) { 400 if (!(vf->flags & IXGBE_VF_CAP_MAC) && ixgbe_vf_mac_changed(vf, mac)) {
401 ixgbe_send_vf_nack(adapter, vf, msg[0]); 401 ixgbe_send_vf_nack(adapter, vf, msg[0]);
402 return; 402 return;
403 } 403 }
404 404
405 if (ixgbe_validate_mac_addr(mac) != 0) { 405 if (ixgbe_validate_mac_addr(mac) != 0) {
406 ixgbe_send_vf_nack(adapter, vf, msg[0]); 406 ixgbe_send_vf_nack(adapter, vf, msg[0]);
407 return; 407 return;
408 } 408 }
409 409
410 bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN); 410 bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
411 411
412 ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, vf->pool, 412 ixgbe_set_rar(&adapter->hw, vf->rar_index, vf->ether_addr, vf->pool,
413 TRUE); 413 TRUE);
414 414
415 ixgbe_send_vf_ack(adapter, vf, msg[0]); 415 ixgbe_send_vf_ack(adapter, vf, msg[0]);
416} /* ixgbe_vf_set_mac */ 416} /* ixgbe_vf_set_mac */
417 417
418 418
419/* 419/*
420 * VF multicast addresses are set by using the appropriate bit in 420 * VF multicast addresses are set by using the appropriate bit in
421 * 1 of 128 32 bit addresses (4096 possible). 421 * 1 of 128 32 bit addresses (4096 possible).
422 */ 422 */
423static void 423static void
424ixgbe_vf_set_mc_addr(struct adapter *adapter, struct ixgbe_vf *vf, u32 *msg) 424ixgbe_vf_set_mc_addr(struct adapter *adapter, struct ixgbe_vf *vf, u32 *msg)
425{ 425{
426 u16 *list = (u16*)&msg[1]; 426 u16 *list = (u16*)&msg[1];
427 int entries; 427 int entries;
428 u32 vmolr, vec_bit, vec_reg, mta_reg; 428 u32 vmolr, vec_bit, vec_reg, mta_reg;
429 429
430 entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT; 430 entries = (msg[0] & IXGBE_VT_MSGINFO_MASK) >> IXGBE_VT_MSGINFO_SHIFT;
431 entries = uimin(entries, IXGBE_MAX_VF_MC); 431 entries = uimin(entries, IXGBE_MAX_VF_MC);
432 432
433 vmolr = IXGBE_READ_REG(&adapter->hw, IXGBE_VMOLR(vf->pool)); 433 vmolr = IXGBE_READ_REG(&adapter->hw, IXGBE_VMOLR(vf->pool));
434 434
435 vf->num_mc_hashes = entries; 435 vf->num_mc_hashes = entries;
436 436
437 /* Set the appropriate MTA bit */ 437 /* Set the appropriate MTA bit */
438 for (int i = 0; i < entries; i++) { 438 for (int i = 0; i < entries; i++) {
439 vf->mc_hash[i] = list[i]; 439 vf->mc_hash[i] = list[i];
440 vec_reg = (vf->mc_hash[i] >> 5) & 0x7F; 440 vec_reg = (vf->mc_hash[i] >> 5) & 0x7F;
441 vec_bit = vf->mc_hash[i] & 0x1F; 441 vec_bit = vf->mc_hash[i] & 0x1F;
442 mta_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_MTA(vec_reg)); 442 mta_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_MTA(vec_reg));
443 mta_reg |= (1 << vec_bit); 443 mta_reg |= (1 << vec_bit);
444 IXGBE_WRITE_REG(&adapter->hw, IXGBE_MTA(vec_reg), mta_reg); 444 IXGBE_WRITE_REG(&adapter->hw, IXGBE_MTA(vec_reg), mta_reg);
445 } 445 }
446 446
447 vmolr |= IXGBE_VMOLR_ROMPE; 447 vmolr |= IXGBE_VMOLR_ROMPE;
448 IXGBE_WRITE_REG(&adapter->hw, IXGBE_VMOLR(vf->pool), vmolr); 448 IXGBE_WRITE_REG(&adapter->hw, IXGBE_VMOLR(vf->pool), vmolr);
449 ixgbe_send_vf_ack(adapter, vf, msg[0]); 449 ixgbe_send_vf_ack(adapter, vf, msg[0]);
450} /* ixgbe_vf_set_mc_addr */ 450} /* ixgbe_vf_set_mc_addr */
451 451
452 452
453static void 453static void
454ixgbe_vf_set_vlan(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) 454ixgbe_vf_set_vlan(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
455{ 455{
456 struct ixgbe_hw *hw; 456 struct ixgbe_hw *hw;
457 int enable; 457 int enable;
458 uint16_t tag; 458 uint16_t tag;
459 459
460 hw = &adapter->hw; 460 hw = &adapter->hw;
461 enable = IXGBE_VT_MSGINFO(msg[0]); 461 enable = IXGBE_VT_MSGINFO(msg[0]);
462 tag = msg[1] & IXGBE_VLVF_VLANID_MASK; 462 tag = msg[1] & IXGBE_VLVF_VLANID_MASK;
463 463
464 if (!(vf->flags & IXGBE_VF_CAP_VLAN)) { 464 if (!(vf->flags & IXGBE_VF_CAP_VLAN)) {
465 ixgbe_send_vf_nack(adapter, vf, msg[0]); 465 ixgbe_send_vf_nack(adapter, vf, msg[0]);
466 return; 466 return;
467 } 467 }
468 468
469 /* It is illegal to enable vlan tag 0. */ 469 /* It is illegal to enable vlan tag 0. */
470 if (tag == 0 && enable != 0) { 470 if (tag == 0 && enable != 0) {
471 ixgbe_send_vf_nack(adapter, vf, msg[0]); 471 ixgbe_send_vf_nack(adapter, vf, msg[0]);
472 return; 472 return;
473 } 473 }
474 474
475 ixgbe_set_vfta(hw, tag, vf->pool, enable, false); 475 ixgbe_set_vfta(hw, tag, vf->pool, enable, false);
476 ixgbe_send_vf_ack(adapter, vf, msg[0]); 476 ixgbe_send_vf_ack(adapter, vf, msg[0]);
477} /* ixgbe_vf_set_vlan */ 477} /* ixgbe_vf_set_vlan */
478 478
479 479
480static void 480static void
481ixgbe_vf_set_lpe(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) 481ixgbe_vf_set_lpe(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
482{ 482{
483 struct ixgbe_hw *hw; 483 struct ixgbe_hw *hw;
484 uint32_t vf_max_size, pf_max_size, mhadd; 484 uint32_t vf_max_size, pf_max_size, mhadd;
485 485
486 hw = &adapter->hw; 486 hw = &adapter->hw;
487 vf_max_size = msg[1]; 487 vf_max_size = msg[1];
488 488
489 if (vf_max_size < ETHER_CRC_LEN) { 489 if (vf_max_size < ETHER_CRC_LEN) {
490 /* We intentionally ACK invalid LPE requests. */ 490 /* We intentionally ACK invalid LPE requests. */
491 ixgbe_send_vf_ack(adapter, vf, msg[0]); 491 ixgbe_send_vf_ack(adapter, vf, msg[0]);
492 return; 492 return;
493 } 493 }
494 494
495 vf_max_size -= ETHER_CRC_LEN; 495 vf_max_size -= ETHER_CRC_LEN;
496 496
497 if (vf_max_size > IXGBE_MAX_FRAME_SIZE) { 497 if (vf_max_size > IXGBE_MAX_FRAME_SIZE) {
498 /* We intentionally ACK invalid LPE requests. */ 498 /* We intentionally ACK invalid LPE requests. */
499 ixgbe_send_vf_ack(adapter, vf, msg[0]); 499 ixgbe_send_vf_ack(adapter, vf, msg[0]);
500 return; 500 return;
501 } 501 }
502 502
503 vf->max_frame_size = vf_max_size; 503 vf->max_frame_size = vf_max_size;
504 ixgbe_update_max_frame(adapter, vf->max_frame_size); 504 ixgbe_update_max_frame(adapter, vf->max_frame_size);
505 505
506 /* 506 /*
507 * We might have to disable reception to this VF if the frame size is 507 * We might have to disable reception to this VF if the frame size is
508 * not compatible with the config on the PF. 508 * not compatible with the config on the PF.
509 */ 509 */
510 ixgbe_vf_enable_receive(adapter, vf); 510 ixgbe_vf_enable_receive(adapter, vf);
511 511
512 mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); 512 mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
513 pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT; 513 pf_max_size = (mhadd & IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT;
514 514
515 if (pf_max_size < adapter->max_frame_size) { 515 if (pf_max_size < adapter->max_frame_size) {
516 mhadd &= ~IXGBE_MHADD_MFS_MASK; 516 mhadd &= ~IXGBE_MHADD_MFS_MASK;
517 mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT; 517 mhadd |= adapter->max_frame_size << IXGBE_MHADD_MFS_SHIFT;
518 IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); 518 IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd);
519 } 519 }
520 520
521 ixgbe_send_vf_ack(adapter, vf, msg[0]); 521 ixgbe_send_vf_ack(adapter, vf, msg[0]);
522} /* ixgbe_vf_set_lpe */ 522} /* ixgbe_vf_set_lpe */
523 523
524 524
525static void 525static void
526ixgbe_vf_set_macvlan(struct adapter *adapter, struct ixgbe_vf *vf, 526ixgbe_vf_set_macvlan(struct adapter *adapter, struct ixgbe_vf *vf,
527 uint32_t *msg) 527 uint32_t *msg)
528{ 528{
529 //XXX implement this 529 //XXX implement this
530 ixgbe_send_vf_nack(adapter, vf, msg[0]); 530 ixgbe_send_vf_nack(adapter, vf, msg[0]);
531} /* ixgbe_vf_set_macvlan */ 531} /* ixgbe_vf_set_macvlan */
532 532
533 533
534static void 534static void
535ixgbe_vf_api_negotiate(struct adapter *adapter, struct ixgbe_vf *vf, 535ixgbe_vf_api_negotiate(struct adapter *adapter, struct ixgbe_vf *vf,
536 uint32_t *msg) 536 uint32_t *msg)
537{ 537{
538 538
539 switch (msg[1]) { 539 switch (msg[1]) {
540 case IXGBE_API_VER_1_0: 540 case IXGBE_API_VER_1_0:
541 case IXGBE_API_VER_1_1: 541 case IXGBE_API_VER_1_1:
542 vf->api_ver = msg[1]; 542 vf->api_ver = msg[1];
543 ixgbe_send_vf_ack(adapter, vf, msg[0]); 543 ixgbe_send_vf_ack(adapter, vf, msg[0]);
544 break; 544 break;
545 default: 545 default:
546 vf->api_ver = IXGBE_API_VER_UNKNOWN; 546 vf->api_ver = IXGBE_API_VER_UNKNOWN;
547 ixgbe_send_vf_nack(adapter, vf, msg[0]); 547 ixgbe_send_vf_nack(adapter, vf, msg[0]);
548 break; 548 break;
549 } 549 }
550} /* ixgbe_vf_api_negotiate */ 550} /* ixgbe_vf_api_negotiate */
551 551
552 552
553static void 553static void
554ixgbe_vf_get_queues(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg) 554ixgbe_vf_get_queues(struct adapter *adapter, struct ixgbe_vf *vf, uint32_t *msg)
555{ 555{
556 struct ixgbe_hw *hw; 556 struct ixgbe_hw *hw;
557 uint32_t resp[IXGBE_VF_GET_QUEUES_RESP_LEN]; 557 uint32_t resp[IXGBE_VF_GET_QUEUES_RESP_LEN];
558 int num_queues; 558 int num_queues;
559 559
560 hw = &adapter->hw; 560 hw = &adapter->hw;
561 561
562 /* GET_QUEUES is not supported on pre-1.1 APIs. */ 562 /* GET_QUEUES is not supported on pre-1.1 APIs. */
563 switch (msg[0]) { 563 switch (msg[0]) {
564 case IXGBE_API_VER_1_0: 564 case IXGBE_API_VER_1_0:
565 case IXGBE_API_VER_UNKNOWN: 565 case IXGBE_API_VER_UNKNOWN:
566 ixgbe_send_vf_nack(adapter, vf, msg[0]); 566 ixgbe_send_vf_nack(adapter, vf, msg[0]);
567 return; 567 return;
568 } 568 }
569 569
570 resp[0] = IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK | 570 resp[0] = IXGBE_VF_GET_QUEUES | IXGBE_VT_MSGTYPE_ACK |
571 IXGBE_VT_MSGTYPE_CTS; 571 IXGBE_VT_MSGTYPE_CTS;
572 572
573 num_queues = ixgbe_vf_queues(adapter->iov_mode); 573 num_queues = ixgbe_vf_queues(adapter->iov_mode);
574 resp[IXGBE_VF_TX_QUEUES] = num_queues; 574 resp[IXGBE_VF_TX_QUEUES] = num_queues;
575 resp[IXGBE_VF_RX_QUEUES] = num_queues; 575 resp[IXGBE_VF_RX_QUEUES] = num_queues;
576 resp[IXGBE_VF_TRANS_VLAN] = (vf->default_vlan != 0); 576 resp[IXGBE_VF_TRANS_VLAN] = (vf->default_vlan != 0);
577 resp[IXGBE_VF_DEF_QUEUE] = 0; 577 resp[IXGBE_VF_DEF_QUEUE] = 0;
578 578
579 hw->mbx.ops.write(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool); 579 hw->mbx.ops.write(hw, resp, IXGBE_VF_GET_QUEUES_RESP_LEN, vf->pool);
580} /* ixgbe_vf_get_queues */ 580} /* ixgbe_vf_get_queues */
581 581
582 582
583static void 583static void
584ixgbe_process_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf) 584ixgbe_process_vf_msg(struct adapter *adapter, struct ixgbe_vf *vf)
585{ 585{
586 struct ixgbe_hw *hw; 586 struct ixgbe_hw *hw;
587 uint32_t msg[IXGBE_VFMAILBOX_SIZE]; 587 uint32_t msg[IXGBE_VFMAILBOX_SIZE];
588 int error; 588 int error;
589 589
590 hw = &adapter->hw; 590 hw = &adapter->hw;
591 591
592 error = hw->mbx.ops.read(hw, msg, IXGBE_VFMAILBOX_SIZE, vf->pool); 592 error = hw->mbx.ops.read(hw, msg, IXGBE_VFMAILBOX_SIZE, vf->pool);
593 593
594 if (error != 0) 594 if (error != 0)
595 return; 595 return;
596 596
597 CTR3(KTR_MALLOC, "%s: received msg %x from %d", adapter->ifp->if_xname, 597 CTR3(KTR_MALLOC, "%s: received msg %x from %d", adapter->ifp->if_xname,
598 msg[0], vf->pool); 598 msg[0], vf->pool);
599 if (msg[0] == IXGBE_VF_RESET) { 599 if (msg[0] == IXGBE_VF_RESET) {
600 ixgbe_vf_reset_msg(adapter, vf, msg); 600 ixgbe_vf_reset_msg(adapter, vf, msg);
601 return; 601 return;
602 } 602 }
603 603
604 if (!(vf->flags & IXGBE_VF_CTS)) { 604 if (!(vf->flags & IXGBE_VF_CTS)) {
605 ixgbe_send_vf_nack(adapter, vf, msg[0]); 605 ixgbe_send_vf_nack(adapter, vf, msg[0]);
606 return; 606 return;
607 } 607 }
608 608
609 switch (msg[0] & IXGBE_VT_MSG_MASK) { 609 switch (msg[0] & IXGBE_VT_MSG_MASK) {
610 case IXGBE_VF_SET_MAC_ADDR: 610 case IXGBE_VF_SET_MAC_ADDR:
611 ixgbe_vf_set_mac(adapter, vf, msg); 611 ixgbe_vf_set_mac(adapter, vf, msg);
612 break; 612 break;
613 case IXGBE_VF_SET_MULTICAST: 613 case IXGBE_VF_SET_MULTICAST:
614 ixgbe_vf_set_mc_addr(adapter, vf, msg); 614 ixgbe_vf_set_mc_addr(adapter, vf, msg);
615 break; 615 break;
616 case IXGBE_VF_SET_VLAN: 616 case IXGBE_VF_SET_VLAN:
617 ixgbe_vf_set_vlan(adapter, vf, msg); 617 ixgbe_vf_set_vlan(adapter, vf, msg);
618 break; 618 break;
619 case IXGBE_VF_SET_LPE: 619 case IXGBE_VF_SET_LPE:
620 ixgbe_vf_set_lpe(adapter, vf, msg); 620 ixgbe_vf_set_lpe(adapter, vf, msg);
621 break; 621 break;
622 case IXGBE_VF_SET_MACVLAN: 622 case IXGBE_VF_SET_MACVLAN:
623 ixgbe_vf_set_macvlan(adapter, vf, msg); 623 ixgbe_vf_set_macvlan(adapter, vf, msg);
624 break; 624 break;
625 case IXGBE_VF_API_NEGOTIATE: 625 case IXGBE_VF_API_NEGOTIATE:
626 ixgbe_vf_api_negotiate(adapter, vf, msg); 626 ixgbe_vf_api_negotiate(adapter, vf, msg);
627 break; 627 break;
628 case IXGBE_VF_GET_QUEUES: 628 case IXGBE_VF_GET_QUEUES:
629 ixgbe_vf_get_queues(adapter, vf, msg); 629 ixgbe_vf_get_queues(adapter, vf, msg);
630 break; 630 break;
631 default: 631 default:
632 ixgbe_send_vf_nack(adapter, vf, msg[0]); 632 ixgbe_send_vf_nack(adapter, vf, msg[0]);
633 } 633 }
634} /* ixgbe_process_vf_msg */ 634} /* ixgbe_process_vf_msg */
635 635
636 636
637/* Tasklet for handling VF -> PF mailbox messages */ 637/* Tasklet for handling VF -> PF mailbox messages */
638void 638void
639ixgbe_handle_mbx(void *context, int pending) 639ixgbe_handle_mbx(void *context, int pending)
640{ 640{
641 struct adapter *adapter = context; 641 struct adapter *adapter = context;
642 struct ixgbe_hw *hw; 642 struct ixgbe_hw *hw;
643 struct ixgbe_vf *vf; 643 struct ixgbe_vf *vf;
644 int i; 644 int i;
645 645
646 KASSERT(mutex_owned(&adapter->core_mtx)); 646 KASSERT(mutex_owned(&adapter->core_mtx));
647 647
648 hw = &adapter->hw; 648 hw = &adapter->hw;
649 649
650 for (i = 0; i < adapter->num_vfs; i++) { 650 for (i = 0; i < adapter->num_vfs; i++) {
651 vf = &adapter->vfs[i]; 651 vf = &adapter->vfs[i];
652 652
653 if (vf->flags & IXGBE_VF_ACTIVE) { 653 if (vf->flags & IXGBE_VF_ACTIVE) {
654 if (hw->mbx.ops.check_for_rst(hw, vf->pool) == 0) 654 if (hw->mbx.ops.check_for_rst(hw, vf->pool) == 0)
655 ixgbe_process_vf_reset(adapter, vf); 655 ixgbe_process_vf_reset(adapter, vf);
656 656
657 if (hw->mbx.ops.check_for_msg(hw, vf->pool) == 0) 657 if (hw->mbx.ops.check_for_msg(hw, vf->pool) == 0)
658 ixgbe_process_vf_msg(adapter, vf); 658 ixgbe_process_vf_msg(adapter, vf);
659 659
660 if (hw->mbx.ops.check_for_ack(hw, vf->pool) == 0) 660 if (hw->mbx.ops.check_for_ack(hw, vf->pool) == 0)
661 ixgbe_process_vf_ack(adapter, vf); 661 ixgbe_process_vf_ack(adapter, vf);
662 } 662 }
663 } 663 }
664} /* ixgbe_handle_mbx */ 664} /* ixgbe_handle_mbx */
665 665
666int 666int
667ixgbe_init_iov(device_t dev, u16 num_vfs, const nvlist_t *config) 667ixgbe_init_iov(device_t dev, u16 num_vfs, const nvlist_t *config)
668{ 668{
669 struct adapter *adapter; 669 struct adapter *adapter;
670 int retval = 0; 670 int retval = 0;
671 671
672 adapter = device_get_softc(dev); 672 adapter = device_get_softc(dev);
673 adapter->iov_mode = IXGBE_NO_VM; 673 adapter->iov_mode = IXGBE_NO_VM;
674 674
675 if (num_vfs == 0) { 675 if (num_vfs == 0) {
676 /* Would we ever get num_vfs = 0? */ 676 /* Would we ever get num_vfs = 0? */
677 retval = EINVAL; 677 retval = EINVAL;
678 goto err_init_iov; 678 goto err_init_iov;
679 } 679 }
680 680
681 /* 681 /*
682 * We've got to reserve a VM's worth of queues for the PF, 682 * We've got to reserve a VM's worth of queues for the PF,
683 * thus we go into "64 VF mode" if 32+ VFs are requested. 683 * thus we go into "64 VF mode" if 32+ VFs are requested.
684 * With 64 VFs, you can only have two queues per VF. 684 * With 64 VFs, you can only have two queues per VF.
685 * With 32 VFs, you can have up to four queues per VF. 685 * With 32 VFs, you can have up to four queues per VF.
686 */ 686 */
687 if (num_vfs >= IXGBE_32_VM) 687 if (num_vfs >= IXGBE_32_VM)
688 adapter->iov_mode = IXGBE_64_VM; 688 adapter->iov_mode = IXGBE_64_VM;
689 else 689 else
690 adapter->iov_mode = IXGBE_32_VM; 690 adapter->iov_mode = IXGBE_32_VM;
691 691
692 /* Again, reserving 1 VM's worth of queues for the PF */ 692 /* Again, reserving 1 VM's worth of queues for the PF */
693 adapter->pool = adapter->iov_mode - 1; 693 adapter->pool = adapter->iov_mode - 1;
694 694
695 if ((num_vfs > adapter->pool) || (num_vfs >= IXGBE_64_VM)) { 695 if ((num_vfs > adapter->pool) || (num_vfs >= IXGBE_64_VM)) {
696 retval = ENOSPC; 696 retval = ENOSPC;
697 goto err_init_iov; 697 goto err_init_iov;
698 } 698 }
699 699
700 IXGBE_CORE_LOCK(adapter); 700 IXGBE_CORE_LOCK(adapter);
701 701
702 adapter->vfs = malloc(sizeof(*adapter->vfs) * num_vfs, M_IXGBE_SRIOV, 702 adapter->vfs = malloc(sizeof(*adapter->vfs) * num_vfs, M_IXGBE_SRIOV,
703 M_NOWAIT | M_ZERO); 703 M_NOWAIT | M_ZERO);
704 704
705 if (adapter->vfs == NULL) { 705 if (adapter->vfs == NULL) {
706 retval = ENOMEM; 706 retval = ENOMEM;
707 IXGBE_CORE_UNLOCK(adapter); 707 IXGBE_CORE_UNLOCK(adapter);
708 goto err_init_iov; 708 goto err_init_iov;
709 } 709 }
710 710
711 adapter->num_vfs = num_vfs; 711 adapter->num_vfs = num_vfs;
712 712
713 /* set the SRIOV flag now as it's needed 713 /* set the SRIOV flag now as it's needed
714 * by ixgbe_init_locked() */ 714 * by ixgbe_init_locked() */
715 adapter->feat_en |= IXGBE_FEATURE_SRIOV; 715 adapter->feat_en |= IXGBE_FEATURE_SRIOV;
716 adapter->init_locked(adapter); 716 adapter->init_locked(adapter);
717 717
718 IXGBE_CORE_UNLOCK(adapter); 718 IXGBE_CORE_UNLOCK(adapter);
719 719
720 return (retval); 720 return (retval);
721 721
722err_init_iov: 722err_init_iov:
723 adapter->num_vfs = 0; 723 adapter->num_vfs = 0;
724 adapter->pool = 0; 724 adapter->pool = 0;
725 adapter->iov_mode = IXGBE_NO_VM; 725 adapter->iov_mode = IXGBE_NO_VM;
726 726
727 return (retval); 727 return (retval);
728} /* ixgbe_init_iov */ 728} /* ixgbe_init_iov */
729 729
730void 730void
731ixgbe_uninit_iov(device_t dev) 731ixgbe_uninit_iov(device_t dev)
732{ 732{
733 struct ixgbe_hw *hw; 733 struct ixgbe_hw *hw;
734 struct adapter *adapter; 734 struct adapter *adapter;
735 uint32_t pf_reg, vf_reg; 735 uint32_t pf_reg, vf_reg;
736 736
737 adapter = device_get_softc(dev); 737 adapter = device_get_softc(dev);
738 hw = &adapter->hw; 738 hw = &adapter->hw;
739 739
740 IXGBE_CORE_LOCK(adapter); 740 IXGBE_CORE_LOCK(adapter);
741 741
742 /* Enable rx/tx for the PF and disable it for all VFs. */ 742 /* Enable rx/tx for the PF and disable it for all VFs. */
743 pf_reg = IXGBE_VF_INDEX(adapter->pool); 743 pf_reg = IXGBE_VF_INDEX(adapter->pool);
744 IXGBE_WRITE_REG(hw, IXGBE_VFRE(pf_reg), IXGBE_VF_BIT(adapter->pool)); 744 IXGBE_WRITE_REG(hw, IXGBE_VFRE(pf_reg), IXGBE_VF_BIT(adapter->pool));
745 IXGBE_WRITE_REG(hw, IXGBE_VFTE(pf_reg), IXGBE_VF_BIT(adapter->pool)); 745 IXGBE_WRITE_REG(hw, IXGBE_VFTE(pf_reg), IXGBE_VF_BIT(adapter->pool));
746 746
747 if (pf_reg == 0) 747 if (pf_reg == 0)
748 vf_reg = 1; 748 vf_reg = 1;
749 else 749 else
750 vf_reg = 0; 750 vf_reg = 0;
751 IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0); 751 IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), 0);
752 IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0); 752 IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), 0);
753 753
754 IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0); 754 IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, 0);
755 755
756 free(adapter->vfs, M_IXGBE_SRIOV); 756 free(adapter->vfs, M_IXGBE_SRIOV);
757 adapter->vfs = NULL; 757 adapter->vfs = NULL;
758 adapter->num_vfs = 0; 758 adapter->num_vfs = 0;
759 adapter->feat_en &= ~IXGBE_FEATURE_SRIOV; 759 adapter->feat_en &= ~IXGBE_FEATURE_SRIOV;
760 760
761 IXGBE_CORE_UNLOCK(adapter); 761 IXGBE_CORE_UNLOCK(adapter);
762} /* ixgbe_uninit_iov */ 762} /* ixgbe_uninit_iov */
763 763
764static void 764static void
765ixgbe_init_vf(struct adapter *adapter, struct ixgbe_vf *vf) 765ixgbe_init_vf(struct adapter *adapter, struct ixgbe_vf *vf)
766{ 766{
767 struct ixgbe_hw *hw; 767 struct ixgbe_hw *hw;
768 uint32_t vf_index, pfmbimr; 768 uint32_t vf_index, pfmbimr;
769 769
770 IXGBE_CORE_LOCK_ASSERT(adapter); 770 IXGBE_CORE_LOCK_ASSERT(adapter);
771 771
772 hw = &adapter->hw; 772 hw = &adapter->hw;
773 773
774 if (!(vf->flags & IXGBE_VF_ACTIVE)) 774 if (!(vf->flags & IXGBE_VF_ACTIVE))
775 return; 775 return;
776 776
777 vf_index = IXGBE_VF_INDEX(vf->pool); 777 vf_index = IXGBE_VF_INDEX(vf->pool);
778 pfmbimr = IXGBE_READ_REG(hw, IXGBE_PFMBIMR(vf_index)); 778 pfmbimr = IXGBE_READ_REG(hw, IXGBE_PFMBIMR(vf_index));
779 pfmbimr |= IXGBE_VF_BIT(vf->pool); 779 pfmbimr |= IXGBE_VF_BIT(vf->pool);
780 IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr); 780 IXGBE_WRITE_REG(hw, IXGBE_PFMBIMR(vf_index), pfmbimr);
781 781
782 ixgbe_vf_set_default_vlan(adapter, vf, vf->vlan_tag); 782 ixgbe_vf_set_default_vlan(adapter, vf, vf->vlan_tag);
783 783
784 // XXX multicast addresses 784 // XXX multicast addresses
785 785
786 if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) { 786 if (ixgbe_validate_mac_addr(vf->ether_addr) == 0) {
787 ixgbe_set_rar(&adapter->hw, vf->rar_index, 787 ixgbe_set_rar(&adapter->hw, vf->rar_index,
788 vf->ether_addr, vf->pool, TRUE); 788 vf->ether_addr, vf->pool, TRUE);
789 } 789 }
790 790
791 ixgbe_vf_enable_transmit(adapter, vf); 791 ixgbe_vf_enable_transmit(adapter, vf);
792 ixgbe_vf_enable_receive(adapter, vf); 792 ixgbe_vf_enable_receive(adapter, vf);
793 793
794 ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG); 794 ixgbe_send_vf_msg(adapter, vf, IXGBE_PF_CONTROL_MSG);
795} /* ixgbe_init_vf */ 795} /* ixgbe_init_vf */
796 796
797void 797void
798ixgbe_initialize_iov(struct adapter *adapter) 798ixgbe_initialize_iov(struct adapter *adapter)
799{ 799{
800 struct ixgbe_hw *hw = &adapter->hw; 800 struct ixgbe_hw *hw = &adapter->hw;
801 uint32_t mrqc, mtqc, vt_ctl, vf_reg, gcr_ext, gpie; 801 uint32_t mrqc, mtqc, vt_ctl, vf_reg, gcr_ext, gpie;
802 int i; 802 int i;
803 803
804 if (adapter->iov_mode == IXGBE_NO_VM) 804 if (adapter->iov_mode == IXGBE_NO_VM)
805 return; 805 return;
806 806
807 IXGBE_CORE_LOCK_ASSERT(adapter); 807 IXGBE_CORE_LOCK_ASSERT(adapter);
808 808
809 /* RMW appropriate registers based on IOV mode */ 809 /* RMW appropriate registers based on IOV mode */
810 /* Read... */ 810 /* Read... */
811 mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC); 811 mrqc = IXGBE_READ_REG(hw, IXGBE_MRQC);
812 gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); 812 gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
813 gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); 813 gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
814 /* Modify... */ 814 /* Modify... */
815 mrqc &= ~IXGBE_MRQC_MRQE_MASK; 815 mrqc &= ~IXGBE_MRQC_MRQE_MASK;
816 mtqc = IXGBE_MTQC_VT_ENA; /* No initial MTQC read needed */ 816 mtqc = IXGBE_MTQC_VT_ENA; /* No initial MTQC read needed */
817 gcr_ext |= IXGBE_GCR_EXT_MSIX_EN; 817 gcr_ext |= IXGBE_GCR_EXT_MSIX_EN;
818 gcr_ext &= ~IXGBE_GCR_EXT_VT_MODE_MASK; 818 gcr_ext &= ~IXGBE_GCR_EXT_VT_MODE_MASK;
819 gpie &= ~IXGBE_GPIE_VTMODE_MASK; 819 gpie &= ~IXGBE_GPIE_VTMODE_MASK;
820 switch (adapter->iov_mode) { 820 switch (adapter->iov_mode) {
821 case IXGBE_64_VM: 821 case IXGBE_64_VM:
822 mrqc |= IXGBE_MRQC_VMDQRSS64EN; 822 mrqc |= IXGBE_MRQC_VMDQRSS64EN;
823 mtqc |= IXGBE_MTQC_64VF; 823 mtqc |= IXGBE_MTQC_64VF;
824 gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64; 824 gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64;
825 gpie |= IXGBE_GPIE_VTMODE_64; 825 gpie |= IXGBE_GPIE_VTMODE_64;
826 break; 826 break;
827 case IXGBE_32_VM: 827 case IXGBE_32_VM:
828 mrqc |= IXGBE_MRQC_VMDQRSS32EN; 828 mrqc |= IXGBE_MRQC_VMDQRSS32EN;
829 mtqc |= IXGBE_MTQC_32VF; 829 mtqc |= IXGBE_MTQC_32VF;
830 gcr_ext |= IXGBE_GCR_EXT_VT_MODE_32; 830 gcr_ext |= IXGBE_GCR_EXT_VT_MODE_32;
831 gpie |= IXGBE_GPIE_VTMODE_32; 831 gpie |= IXGBE_GPIE_VTMODE_32;
832 break; 832 break;
833 default: 833 default:
834 panic("Unexpected SR-IOV mode %d", adapter->iov_mode); 834 panic("Unexpected SR-IOV mode %d", adapter->iov_mode);
835 } 835 }
836 /* Write... */ 836 /* Write... */
837 IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); 837 IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc);
838 IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc); 838 IXGBE_WRITE_REG(hw, IXGBE_MTQC, mtqc);
839 IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); 839 IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext);
840 IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); 840 IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
841 841
842 /* Enable rx/tx for the PF. */ 842 /* Enable rx/tx for the PF. */
843 vf_reg = IXGBE_VF_INDEX(adapter->pool); 843 vf_reg = IXGBE_VF_INDEX(adapter->pool);
844 IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), IXGBE_VF_BIT(adapter->pool)); 844 IXGBE_WRITE_REG(hw, IXGBE_VFRE(vf_reg), IXGBE_VF_BIT(adapter->pool));
845 IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), IXGBE_VF_BIT(adapter->pool)); 845 IXGBE_WRITE_REG(hw, IXGBE_VFTE(vf_reg), IXGBE_VF_BIT(adapter->pool));
846 846
847 /* Allow VM-to-VM communication. */ 847 /* Allow VM-to-VM communication. */
848 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); 848 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
849 849
850 vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN; 850 vt_ctl = IXGBE_VT_CTL_VT_ENABLE | IXGBE_VT_CTL_REPLEN;
851 vt_ctl |= (adapter->pool << IXGBE_VT_CTL_POOL_SHIFT); 851 vt_ctl |= (adapter->pool << IXGBE_VT_CTL_POOL_SHIFT);
852 IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vt_ctl); 852 IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vt_ctl);
853 853
854 for (i = 0; i < adapter->num_vfs; i++) 854 for (i = 0; i < adapter->num_vfs; i++)
855 ixgbe_init_vf(adapter, &adapter->vfs[i]); 855 ixgbe_init_vf(adapter, &adapter->vfs[i]);
856} /* ixgbe_initialize_iov */ 856} /* ixgbe_initialize_iov */
857 857
858 858
859/* Check the max frame setting of all active VF's */ 859/* Check the max frame setting of all active VF's */
860void 860void
861ixgbe_recalculate_max_frame(struct adapter *adapter) 861ixgbe_recalculate_max_frame(struct adapter *adapter)
862{ 862{
863 struct ixgbe_vf *vf; 863 struct ixgbe_vf *vf;
864 864
865 IXGBE_CORE_LOCK_ASSERT(adapter); 865 IXGBE_CORE_LOCK_ASSERT(adapter);
866 866
867 for (int i = 0; i < adapter->num_vfs; i++) { 867 for (int i = 0; i < adapter->num_vfs; i++) {
868 vf = &adapter->vfs[i]; 868 vf = &adapter->vfs[i];
869 if (vf->flags & IXGBE_VF_ACTIVE) 869 if (vf->flags & IXGBE_VF_ACTIVE)
870 ixgbe_update_max_frame(adapter, vf->max_frame_size); 870 ixgbe_update_max_frame(adapter, vf->max_frame_size);
871 } 871 }
872} /* ixgbe_recalculate_max_frame */ 872} /* ixgbe_recalculate_max_frame */
873 873
874int 874int
875ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config) 875ixgbe_add_vf(device_t dev, u16 vfnum, const nvlist_t *config)
876{ 876{
877 struct adapter *adapter; 877 struct adapter *adapter;
878 struct ixgbe_vf *vf; 878 struct ixgbe_vf *vf;
879 const void *mac; 879 const void *mac;
880 880
881 adapter = device_get_softc(dev); 881 adapter = device_get_softc(dev);
882 882
883 KASSERT(vfnum < adapter->num_vfs, ("VF index %d is out of range %d", 883 KASSERT(vfnum < adapter->num_vfs, ("VF index %d is out of range %d",
884 vfnum, adapter->num_vfs)); 884 vfnum, adapter->num_vfs));
885 885
886 IXGBE_CORE_LOCK(adapter); 886 IXGBE_CORE_LOCK(adapter);
887 vf = &adapter->vfs[vfnum]; 887 vf = &adapter->vfs[vfnum];
888 vf->pool= vfnum; 888 vf->pool= vfnum;
889 889
890 /* RAR[0] is used by the PF so use vfnum + 1 for VF RAR. */ 890 /* RAR[0] is used by the PF so use vfnum + 1 for VF RAR. */
891 vf->rar_index = vfnum + 1; 891 vf->rar_index = vfnum + 1;
892 vf->default_vlan = 0; 892 vf->default_vlan = 0;
893 vf->max_frame_size = ETHER_MAX_LEN; 893 vf->max_frame_size = ETHER_MAX_LEN;
894 ixgbe_update_max_frame(adapter, vf->max_frame_size); 894 ixgbe_update_max_frame(adapter, vf->max_frame_size);
895 895
896 if (nvlist_exists_binary(config, "mac-addr")) { 896 if (nvlist_exists_binary(config, "mac-addr")) {
897 mac = nvlist_get_binary(config, "mac-addr", NULL); 897 mac = nvlist_get_binary(config, "mac-addr", NULL);
898 bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN); 898 bcopy(mac, vf->ether_addr, ETHER_ADDR_LEN);
899 if (nvlist_get_bool(config, "allow-set-mac")) 899 if (nvlist_get_bool(config, "allow-set-mac"))
900 vf->flags |= IXGBE_VF_CAP_MAC; 900 vf->flags |= IXGBE_VF_CAP_MAC;
901 } else 901 } else
902 /* 902 /*
903 * If the administrator has not specified a MAC address then 903 * If the administrator has not specified a MAC address then
904 * we must allow the VF to choose one. 904 * we must allow the VF to choose one.
905 */ 905 */
906 vf->flags |= IXGBE_VF_CAP_MAC; 906 vf->flags |= IXGBE_VF_CAP_MAC;
907 907
908 vf->flags |= IXGBE_VF_ACTIVE; 908 vf->flags |= IXGBE_VF_ACTIVE;
909 909
910 ixgbe_init_vf(adapter, vf); 910 ixgbe_init_vf(adapter, vf);
911 IXGBE_CORE_UNLOCK(adapter); 911 IXGBE_CORE_UNLOCK(adapter);
912 912
913 return (0); 913 return (0);
914} /* ixgbe_add_vf */ 914} /* ixgbe_add_vf */
915 915
916#else 916#else
917 917
918void 918void
919ixgbe_handle_mbx(void *context, int pending) 919ixgbe_handle_mbx(void *context, int pending)
920{ 920{
921 UNREFERENCED_2PARAMETER(context, pending); 921 UNREFERENCED_2PARAMETER(context, pending);
922} /* ixgbe_handle_mbx */ 922} /* ixgbe_handle_mbx */
923 923
924inline int 924inline int
925ixgbe_vf_que_index(int mode, int vfnum, int num) 925ixgbe_vf_que_index(int mode, int vfnum, int num)
926{ 926{
927 UNREFERENCED_2PARAMETER(mode, vfnum); 927 UNREFERENCED_2PARAMETER(mode, vfnum);
928 928
929 return num; 929 return num;
930} /* ixgbe_vf_que_index */ 930} /* ixgbe_vf_que_index */
931 931
932#endif 932#endif