xref: /freebsd/sys/dev/iavf/iavf_lib.c (revision 71625ec9)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*  Copyright (c) 2021, Intel Corporation
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright notice,
9  *      this list of conditions and the following disclaimer.
10  *
11  *   2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *
15  *   3. Neither the name of the Intel Corporation nor the names of its
16  *      contributors may be used to endorse or promote products derived from
17  *      this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *  POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @file iavf_lib.c
34  * @brief library code common to both legacy and iflib
35  *
36  * Contains functions common to the iflib and legacy drivers. Includes
37  * hardware initialization and control functions, as well as sysctl handlers
38  * for the sysctls which are shared between the legacy and iflib drivers.
39  */
40 #include "iavf_iflib.h"
41 #include "iavf_vc_common.h"
42 
43 static void iavf_init_hw(struct iavf_hw *hw, device_t dev);
44 static u_int iavf_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int cnt);
45 
46 /**
47  * iavf_msec_pause - Pause for at least the specified number of milliseconds
48  * @msecs: number of milliseconds to pause for
49  *
50  * Pause execution of the current thread for a specified number of
51  * milliseconds. Used to enforce minimum delay times when waiting for various
52  * hardware events.
53  */
54 void
iavf_msec_pause(int msecs)55 iavf_msec_pause(int msecs)
56 {
57 	pause("iavf_msec_pause", MSEC_2_TICKS(msecs));
58 }
59 
60 /**
61  * iavf_get_default_rss_key - Get the default RSS key for this driver
62  * @key: output parameter to store the key in
63  *
64  * Copies the driver's default RSS key into the provided key variable.
65  *
66  * @pre assumes that key is not NULL and has at least IAVF_RSS_KEY_SIZE
67  * storage space.
68  */
69 void
iavf_get_default_rss_key(u32 * key)70 iavf_get_default_rss_key(u32 *key)
71 {
72 	MPASS(key != NULL);
73 
74 	u32 rss_seed[IAVF_RSS_KEY_SIZE_REG] = {0x41b01687,
75 	    0x183cfd8c, 0xce880440, 0x580cbc3c,
76 	    0x35897377, 0x328b25e1, 0x4fa98922,
77 	    0xb7d90c14, 0xd5bad70d, 0xcd15a2c1,
78 	    0x0, 0x0, 0x0};
79 
80 	bcopy(rss_seed, key, IAVF_RSS_KEY_SIZE);
81 }
82 
83 /**
84  * iavf_allocate_pci_resources_common - Allocate PCI resources
85  * @sc: the private device softc pointer
86  *
87  * @pre sc->dev is set
88  *
89  * Allocates the common PCI resources used by the driver.
90  *
91  * @returns zero on success, or an error code on failure.
92  */
93 int
iavf_allocate_pci_resources_common(struct iavf_sc * sc)94 iavf_allocate_pci_resources_common(struct iavf_sc *sc)
95 {
96 	struct iavf_hw *hw = &sc->hw;
97 	device_t dev = sc->dev;
98 	int rid;
99 
100 	/* Map PCI BAR0 */
101 	rid = PCIR_BAR(0);
102 	sc->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
103 	    &rid, RF_ACTIVE);
104 
105 	if (!(sc->pci_mem)) {
106 		device_printf(dev, "Unable to allocate bus resource: PCI memory\n");
107 		return (ENXIO);
108 	}
109 
110 	iavf_init_hw(hw, dev);
111 
112 	/* Save off register access information */
113 	sc->osdep.mem_bus_space_tag =
114 		rman_get_bustag(sc->pci_mem);
115 	sc->osdep.mem_bus_space_handle =
116 		rman_get_bushandle(sc->pci_mem);
117 	sc->osdep.mem_bus_space_size = rman_get_size(sc->pci_mem);
118 	sc->osdep.flush_reg = IAVF_VFGEN_RSTAT;
119 	sc->osdep.dev = dev;
120 
121 	sc->hw.hw_addr = (u8 *)&sc->osdep.mem_bus_space_handle;
122 	sc->hw.back = &sc->osdep;
123 
124 	return (0);
125 }
126 
127 /**
128  * iavf_init_hw - Initialize the device HW
129  * @hw: device hardware structure
130  * @dev: the stack device_t pointer
131  *
132  * Attach helper function. Gathers information about the (virtual) hardware
133  * for use elsewhere in the driver.
134  */
135 static void
iavf_init_hw(struct iavf_hw * hw,device_t dev)136 iavf_init_hw(struct iavf_hw *hw, device_t dev)
137 {
138 	/* Save off the information about this board */
139 	hw->vendor_id = pci_get_vendor(dev);
140 	hw->device_id = pci_get_device(dev);
141 	hw->revision_id = pci_read_config(dev, PCIR_REVID, 1);
142 	hw->subsystem_vendor_id =
143 	    pci_read_config(dev, PCIR_SUBVEND_0, 2);
144 	hw->subsystem_device_id =
145 	    pci_read_config(dev, PCIR_SUBDEV_0, 2);
146 
147 	hw->bus.device = pci_get_slot(dev);
148 	hw->bus.func = pci_get_function(dev);
149 }
150 
151 /**
152  * iavf_sysctl_current_speed - Sysctl to display the current device speed
153  * @oidp: syctl oid pointer
154  * @arg1: pointer to the device softc typecasted to void *
155  * @arg2: unused sysctl argument
156  * @req: sysctl request structure
157  *
158  * Reads the current speed reported from the physical device into a string for
159  * display by the current_speed sysctl.
160  *
161  * @returns zero or an error code on failure.
162  */
163 int
iavf_sysctl_current_speed(SYSCTL_HANDLER_ARGS)164 iavf_sysctl_current_speed(SYSCTL_HANDLER_ARGS)
165 {
166 	struct iavf_sc *sc = (struct iavf_sc *)arg1;
167 	int error = 0;
168 
169 	UNREFERENCED_PARAMETER(arg2);
170 
171 	if (iavf_driver_is_detaching(sc))
172 		return (ESHUTDOWN);
173 
174 	if (IAVF_CAP_ADV_LINK_SPEED(sc))
175 		error = sysctl_handle_string(oidp,
176 		  __DECONST(char *, iavf_ext_speed_to_str(iavf_adv_speed_to_ext_speed(sc->link_speed_adv))),
177 		  8, req);
178 	else
179 		error = sysctl_handle_string(oidp,
180 		  __DECONST(char *, iavf_vc_speed_to_string(sc->link_speed)),
181 		  8, req);
182 
183 	return (error);
184 }
185 
186 /**
187  * iavf_reset_complete - Wait for a device reset to complete
188  * @hw: pointer to the hardware structure
189  *
190  * Reads the reset registers and waits until they indicate that a device reset
191  * is complete.
192  *
193  * @pre this function may call pause() and must not be called from a context
194  * that cannot sleep.
195  *
196  * @returns zero on success, or EBUSY if it times out waiting for reset.
197  */
198 int
iavf_reset_complete(struct iavf_hw * hw)199 iavf_reset_complete(struct iavf_hw *hw)
200 {
201 	u32 reg;
202 
203 	/* Wait up to ~10 seconds */
204 	for (int i = 0; i < 100; i++) {
205 		reg = rd32(hw, IAVF_VFGEN_RSTAT) &
206 		    IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
207 
208                 if ((reg == VIRTCHNL_VFR_VFACTIVE) ||
209 		    (reg == VIRTCHNL_VFR_COMPLETED))
210 			return (0);
211 		iavf_msec_pause(100);
212 	}
213 
214 	return (EBUSY);
215 }
216 
217 /**
218  * iavf_setup_vc - Setup virtchnl communication
219  * @sc: device private softc
220  *
221  * iavf_attach() helper function. Initializes the admin queue and attempts to
222  * establish contact with the PF by retrying the initial "API version" message
223  * several times or until the PF responds.
224  *
225  * @returns zero on success, or an error code on failure.
226  */
227 int
iavf_setup_vc(struct iavf_sc * sc)228 iavf_setup_vc(struct iavf_sc *sc)
229 {
230 	struct iavf_hw *hw = &sc->hw;
231 	device_t dev = sc->dev;
232 	int error = 0, ret_error = 0, asq_retries = 0;
233 	bool send_api_ver_retried = 0;
234 
235 	/* Need to set these AQ parameters before initializing AQ */
236 	hw->aq.num_arq_entries = IAVF_AQ_LEN;
237 	hw->aq.num_asq_entries = IAVF_AQ_LEN;
238 	hw->aq.arq_buf_size = IAVF_AQ_BUF_SZ;
239 	hw->aq.asq_buf_size = IAVF_AQ_BUF_SZ;
240 
241 	for (int i = 0; i < IAVF_AQ_MAX_ERR; i++) {
242 		/* Initialize admin queue */
243 		error = iavf_init_adminq(hw);
244 		if (error) {
245 			device_printf(dev, "%s: init_adminq failed: %d\n",
246 			    __func__, error);
247 			ret_error = 1;
248 			continue;
249 		}
250 
251 		iavf_dbg_init(sc, "Initialized Admin Queue; starting"
252 		    " send_api_ver attempt %d", i+1);
253 
254 retry_send:
255 		/* Send VF's API version */
256 		error = iavf_send_api_ver(sc);
257 		if (error) {
258 			iavf_shutdown_adminq(hw);
259 			ret_error = 2;
260 			device_printf(dev, "%s: unable to send api"
261 			    " version to PF on attempt %d, error %d\n",
262 			    __func__, i+1, error);
263 		}
264 
265 		asq_retries = 0;
266 		while (!iavf_asq_done(hw)) {
267 			if (++asq_retries > IAVF_AQ_MAX_ERR) {
268 				iavf_shutdown_adminq(hw);
269 				device_printf(dev, "Admin Queue timeout "
270 				    "(waiting for send_api_ver), %d more tries...\n",
271 				    IAVF_AQ_MAX_ERR - (i + 1));
272 				ret_error = 3;
273 				break;
274 			}
275 			iavf_msec_pause(10);
276 		}
277 		if (asq_retries > IAVF_AQ_MAX_ERR)
278 			continue;
279 
280 		iavf_dbg_init(sc, "Sent API version message to PF");
281 
282 		/* Verify that the VF accepts the PF's API version */
283 		error = iavf_verify_api_ver(sc);
284 		if (error == ETIMEDOUT) {
285 			if (!send_api_ver_retried) {
286 				/* Resend message, one more time */
287 				send_api_ver_retried = true;
288 				device_printf(dev,
289 				    "%s: Timeout while verifying API version on first"
290 				    " try!\n", __func__);
291 				goto retry_send;
292 			} else {
293 				device_printf(dev,
294 				    "%s: Timeout while verifying API version on second"
295 				    " try!\n", __func__);
296 				ret_error = 4;
297 				break;
298 			}
299 		}
300 		if (error) {
301 			device_printf(dev,
302 			    "%s: Unable to verify API version,"
303 			    " error %d\n", __func__, error);
304 			ret_error = 5;
305 		}
306 		break;
307 	}
308 
309 	if (ret_error >= 4)
310 		iavf_shutdown_adminq(hw);
311 	return (ret_error);
312 }
313 
314 /**
315  * iavf_reset - Requests a VF reset from the PF.
316  * @sc: device private softc
317  *
318  * @pre Requires the VF's Admin Queue to be initialized.
319  * @returns zero on success, or an error code on failure.
320  */
321 int
iavf_reset(struct iavf_sc * sc)322 iavf_reset(struct iavf_sc *sc)
323 {
324 	struct iavf_hw	*hw = &sc->hw;
325 	device_t	dev = sc->dev;
326 	int		error = 0;
327 
328 	/* Ask the PF to reset us if we are initiating */
329 	if (!iavf_test_state(&sc->state, IAVF_STATE_RESET_PENDING))
330 		iavf_request_reset(sc);
331 
332 	iavf_msec_pause(100);
333 	error = iavf_reset_complete(hw);
334 	if (error) {
335 		device_printf(dev, "%s: VF reset failed\n",
336 		    __func__);
337 		return (error);
338 	}
339 	pci_enable_busmaster(dev);
340 
341 	error = iavf_shutdown_adminq(hw);
342 	if (error) {
343 		device_printf(dev, "%s: shutdown_adminq failed: %d\n",
344 		    __func__, error);
345 		return (error);
346 	}
347 
348 	error = iavf_init_adminq(hw);
349 	if (error) {
350 		device_printf(dev, "%s: init_adminq failed: %d\n",
351 		    __func__, error);
352 		return (error);
353 	}
354 
355 	/* IFLIB: This is called only in the iflib driver */
356 	iavf_enable_adminq_irq(hw);
357 	return (0);
358 }
359 
360 /**
361  * iavf_enable_admin_irq - Enable the administrative interrupt
362  * @hw: pointer to the hardware structure
363  *
364  * Writes to registers to enable the administrative interrupt cause, in order
365  * to handle non-queue related interrupt events.
366  */
367 void
iavf_enable_adminq_irq(struct iavf_hw * hw)368 iavf_enable_adminq_irq(struct iavf_hw *hw)
369 {
370 	wr32(hw, IAVF_VFINT_DYN_CTL01,
371 	    IAVF_VFINT_DYN_CTL01_INTENA_MASK |
372 	    IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
373 	    IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
374 	wr32(hw, IAVF_VFINT_ICR0_ENA1, IAVF_VFINT_ICR0_ENA1_ADMINQ_MASK);
375 	/* flush */
376 	rd32(hw, IAVF_VFGEN_RSTAT);
377 }
378 
379 /**
380  * iavf_disable_admin_irq - Disable the administrative interrupt cause
381  * @hw: pointer to the hardware structure
382  *
383  * Writes to registers to disable the administrative interrupt cause.
384  */
385 void
iavf_disable_adminq_irq(struct iavf_hw * hw)386 iavf_disable_adminq_irq(struct iavf_hw *hw)
387 {
388 	wr32(hw, IAVF_VFINT_DYN_CTL01, 0);
389 	wr32(hw, IAVF_VFINT_ICR0_ENA1, 0);
390 	iavf_flush(hw);
391 }
392 
393 /**
394  * iavf_vf_config - Configure this VF over the virtchnl
395  * @sc: device private softc
396  *
397  * iavf_attach() helper function. Asks the PF for this VF's configuration, and
398  * saves the information if it receives it.
399  *
400  * @returns zero on success, or an error code on failure.
401  */
402 int
iavf_vf_config(struct iavf_sc * sc)403 iavf_vf_config(struct iavf_sc *sc)
404 {
405 	struct iavf_hw *hw = &sc->hw;
406 	device_t dev = sc->dev;
407 	int bufsz, error = 0, ret_error = 0;
408 	int asq_retries, retried = 0;
409 
410 retry_config:
411 	error = iavf_send_vf_config_msg(sc);
412 	if (error) {
413 		device_printf(dev,
414 		    "%s: Unable to send VF config request, attempt %d,"
415 		    " error %d\n", __func__, retried + 1, error);
416 		ret_error = 2;
417 	}
418 
419 	asq_retries = 0;
420 	while (!iavf_asq_done(hw)) {
421 		if (++asq_retries > IAVF_AQ_MAX_ERR) {
422 			device_printf(dev, "%s: Admin Queue timeout "
423 			    "(waiting for send_vf_config_msg), attempt %d\n",
424 			    __func__, retried + 1);
425 			ret_error = 3;
426 			goto fail;
427 		}
428 		iavf_msec_pause(10);
429 	}
430 
431 	iavf_dbg_init(sc, "Sent VF config message to PF, attempt %d\n",
432 	    retried + 1);
433 
434 	if (!sc->vf_res) {
435 		bufsz = sizeof(struct virtchnl_vf_resource) +
436 		    (IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource));
437 		sc->vf_res = (struct virtchnl_vf_resource *)malloc(bufsz, M_IAVF, M_NOWAIT);
438 		if (!sc->vf_res) {
439 			device_printf(dev,
440 			    "%s: Unable to allocate memory for VF configuration"
441 			    " message from PF on attempt %d\n", __func__, retried + 1);
442 			ret_error = 1;
443 			goto fail;
444 		}
445 	}
446 
447 	/* Check for VF config response */
448 	error = iavf_get_vf_config(sc);
449 	if (error == ETIMEDOUT) {
450 		/* The 1st time we timeout, send the configuration message again */
451 		if (!retried) {
452 			retried++;
453 			goto retry_config;
454 		}
455 		device_printf(dev,
456 		    "%s: iavf_get_vf_config() timed out waiting for a response\n",
457 		    __func__);
458 	}
459 	if (error) {
460 		device_printf(dev,
461 		    "%s: Unable to get VF configuration from PF after %d tries!\n",
462 		    __func__, retried + 1);
463 		ret_error = 4;
464 	}
465 	goto done;
466 
467 fail:
468 	free(sc->vf_res, M_IAVF);
469 done:
470 	return (ret_error);
471 }
472 
473 /**
474  * iavf_print_device_info - Print some device parameters at attach
475  * @sc: device private softc
476  *
477  * Log a message about this virtual device's capabilities at attach time.
478  */
479 void
iavf_print_device_info(struct iavf_sc * sc)480 iavf_print_device_info(struct iavf_sc *sc)
481 {
482 	device_t dev = sc->dev;
483 
484 	device_printf(dev,
485 	    "VSIs %d, QPs %d, MSI-X %d, RSS sizes: key %d lut %d\n",
486 	    sc->vf_res->num_vsis,
487 	    sc->vf_res->num_queue_pairs,
488 	    sc->vf_res->max_vectors,
489 	    sc->vf_res->rss_key_size,
490 	    sc->vf_res->rss_lut_size);
491 	iavf_dbg_info(sc, "Capabilities=%b\n",
492 	    sc->vf_res->vf_cap_flags, IAVF_PRINTF_VF_OFFLOAD_FLAGS);
493 }
494 
495 /**
496  * iavf_get_vsi_res_from_vf_res - Get VSI parameters and info for this VF
497  * @sc: device private softc
498  *
499  * Get the VSI parameters and information from the general VF resource info
500  * received by the physical device.
501  *
502  * @returns zero on success, or an error code on failure.
503  */
504 int
iavf_get_vsi_res_from_vf_res(struct iavf_sc * sc)505 iavf_get_vsi_res_from_vf_res(struct iavf_sc *sc)
506 {
507 	struct iavf_vsi *vsi = &sc->vsi;
508 	device_t dev = sc->dev;
509 
510 	sc->vsi_res = NULL;
511 
512 	for (int i = 0; i < sc->vf_res->num_vsis; i++) {
513 		/* XXX: We only use the first VSI we find */
514 		if (sc->vf_res->vsi_res[i].vsi_type == IAVF_VSI_SRIOV)
515 			sc->vsi_res = &sc->vf_res->vsi_res[i];
516 	}
517 	if (!sc->vsi_res) {
518 		device_printf(dev, "%s: no LAN VSI found\n", __func__);
519 		return (EIO);
520 	}
521 
522 	vsi->id = sc->vsi_res->vsi_id;
523 	return (0);
524 }
525 
526 /**
527  * iavf_set_mac_addresses - Set the MAC address for this interface
528  * @sc: device private softc
529  *
530  * Set the permanent MAC address field in the HW structure. If a MAC address
531  * has not yet been set for this device by the physical function, generate one
532  * randomly.
533  */
534 void
iavf_set_mac_addresses(struct iavf_sc * sc)535 iavf_set_mac_addresses(struct iavf_sc *sc)
536 {
537 	struct iavf_hw *hw = &sc->hw;
538 	device_t dev = sc->dev;
539 	u8 addr[ETHER_ADDR_LEN];
540 
541 	/* If no mac address was assigned just make a random one */
542 	if (ETHER_IS_ZERO(hw->mac.addr)) {
543 		arc4rand(&addr, sizeof(addr), 0);
544 		addr[0] &= 0xFE;
545 		addr[0] |= 0x02;
546 		memcpy(hw->mac.addr, addr, sizeof(addr));
547 		device_printf(dev, "Generated random MAC address\n");
548 	}
549 	memcpy(hw->mac.perm_addr, hw->mac.addr, ETHER_ADDR_LEN);
550 }
551 
552 /**
553  * iavf_init_filters - Initialize filter structures
554  * @sc: device private softc
555  *
556  * Initialize the MAC and VLAN filter list heads.
557  *
558  * @remark this is intended to be called only once during the device attach
559  * process.
560  *
561  * @pre Because it uses M_WAITOK, this function should only be called in
562  * a context that is safe to sleep.
563  */
564 void
iavf_init_filters(struct iavf_sc * sc)565 iavf_init_filters(struct iavf_sc *sc)
566 {
567 	sc->mac_filters = (struct mac_list *)malloc(sizeof(struct iavf_mac_filter),
568 	    M_IAVF, M_WAITOK | M_ZERO);
569 	SLIST_INIT(sc->mac_filters);
570 	sc->vlan_filters = (struct vlan_list *)malloc(sizeof(struct iavf_vlan_filter),
571 	    M_IAVF, M_WAITOK | M_ZERO);
572 	SLIST_INIT(sc->vlan_filters);
573 }
574 
575 /**
576  * iavf_free_filters - Release filter lists
577  * @sc: device private softc
578  *
579  * Free the MAC and VLAN filter lists.
580  *
581  * @remark this is intended to be called only once during the device detach
582  * process.
583  */
584 void
iavf_free_filters(struct iavf_sc * sc)585 iavf_free_filters(struct iavf_sc *sc)
586 {
587 	struct iavf_mac_filter *f;
588 	struct iavf_vlan_filter *v;
589 
590 	while (!SLIST_EMPTY(sc->mac_filters)) {
591 		f = SLIST_FIRST(sc->mac_filters);
592 		SLIST_REMOVE_HEAD(sc->mac_filters, next);
593 		free(f, M_IAVF);
594 	}
595 	free(sc->mac_filters, M_IAVF);
596 	while (!SLIST_EMPTY(sc->vlan_filters)) {
597 		v = SLIST_FIRST(sc->vlan_filters);
598 		SLIST_REMOVE_HEAD(sc->vlan_filters, next);
599 		free(v, M_IAVF);
600 	}
601 	free(sc->vlan_filters, M_IAVF);
602 }
603 
604 /**
605  * iavf_add_device_sysctls_common - Initialize common device sysctls
606  * @sc: device private softc
607  *
608  * Setup sysctls common to both the iflib and legacy drivers.
609  */
610 void
iavf_add_device_sysctls_common(struct iavf_sc * sc)611 iavf_add_device_sysctls_common(struct iavf_sc *sc)
612 {
613 	device_t dev = sc->dev;
614 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
615 	struct sysctl_oid_list *ctx_list =
616 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
617 
618 	SYSCTL_ADD_PROC(ctx, ctx_list,
619 	    OID_AUTO, "current_speed", CTLTYPE_STRING | CTLFLAG_RD,
620 	    sc, 0, iavf_sysctl_current_speed, "A", "Current Port Speed");
621 
622 	SYSCTL_ADD_PROC(ctx, ctx_list,
623 	    OID_AUTO, "tx_itr", CTLTYPE_INT | CTLFLAG_RW,
624 	    sc, 0, iavf_sysctl_tx_itr, "I",
625 	    "Immediately set TX ITR value for all queues");
626 
627 	SYSCTL_ADD_PROC(ctx, ctx_list,
628 	    OID_AUTO, "rx_itr", CTLTYPE_INT | CTLFLAG_RW,
629 	    sc, 0, iavf_sysctl_rx_itr, "I",
630 	    "Immediately set RX ITR value for all queues");
631 
632 	SYSCTL_ADD_UQUAD(ctx, ctx_list,
633 	    OID_AUTO, "admin_irq", CTLFLAG_RD,
634 	    &sc->admin_irq, "Admin Queue IRQ Handled");
635 }
636 
637 /**
638  * iavf_add_debug_sysctls_common - Initialize common debug sysctls
639  * @sc: device private softc
640  * @debug_list: pionter to debug sysctl node
641  *
642  * Setup sysctls used for debugging the device driver into the debug sysctl
643  * node.
644  */
645 void
iavf_add_debug_sysctls_common(struct iavf_sc * sc,struct sysctl_oid_list * debug_list)646 iavf_add_debug_sysctls_common(struct iavf_sc *sc, struct sysctl_oid_list *debug_list)
647 {
648 	device_t dev = sc->dev;
649 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
650 
651 	SYSCTL_ADD_UINT(ctx, debug_list,
652 	    OID_AUTO, "shared_debug_mask", CTLFLAG_RW,
653 	    &sc->hw.debug_mask, 0, "Shared code debug message level");
654 
655 	SYSCTL_ADD_UINT(ctx, debug_list,
656 	    OID_AUTO, "core_debug_mask", CTLFLAG_RW,
657 	    (unsigned int *)&sc->dbg_mask, 0, "Non-shared code debug message level");
658 
659 	SYSCTL_ADD_PROC(ctx, debug_list,
660 	    OID_AUTO, "filter_list", CTLTYPE_STRING | CTLFLAG_RD,
661 	    sc, 0, iavf_sysctl_sw_filter_list, "A", "SW Filter List");
662 }
663 
664 /**
665  * iavf_sysctl_tx_itr - Sysctl to set the Tx ITR value
666  * @oidp: sysctl oid pointer
667  * @arg1: pointer to the device softc
668  * @arg2: unused sysctl argument
669  * @req: sysctl req pointer
670  *
671  * On read, returns the Tx ITR value for all of the VF queues. On write,
672  * update the Tx ITR registers with the new Tx ITR value.
673  *
674  * @returns zero on success, or an error code on failure.
675  */
676 int
iavf_sysctl_tx_itr(SYSCTL_HANDLER_ARGS)677 iavf_sysctl_tx_itr(SYSCTL_HANDLER_ARGS)
678 {
679 	struct iavf_sc *sc = (struct iavf_sc *)arg1;
680 	device_t dev = sc->dev;
681 	int requested_tx_itr;
682 	int error = 0;
683 
684 	UNREFERENCED_PARAMETER(arg2);
685 
686 	if (iavf_driver_is_detaching(sc))
687 		return (ESHUTDOWN);
688 
689 	requested_tx_itr = sc->tx_itr;
690 	error = sysctl_handle_int(oidp, &requested_tx_itr, 0, req);
691 	if ((error) || (req->newptr == NULL))
692 		return (error);
693 	if (requested_tx_itr < 0 || requested_tx_itr > IAVF_MAX_ITR) {
694 		device_printf(dev,
695 		    "Invalid TX itr value; value must be between 0 and %d\n",
696 		        IAVF_MAX_ITR);
697 		return (EINVAL);
698 	}
699 
700 	sc->tx_itr = requested_tx_itr;
701 	iavf_configure_tx_itr(sc);
702 
703 	return (error);
704 }
705 
706 /**
707  * iavf_sysctl_rx_itr - Sysctl to set the Rx ITR value
708  * @oidp: sysctl oid pointer
709  * @arg1: pointer to the device softc
710  * @arg2: unused sysctl argument
711  * @req: sysctl req pointer
712  *
713  * On read, returns the Rx ITR value for all of the VF queues. On write,
714  * update the ITR registers with the new Rx ITR value.
715  *
716  * @returns zero on success, or an error code on failure.
717  */
718 int
iavf_sysctl_rx_itr(SYSCTL_HANDLER_ARGS)719 iavf_sysctl_rx_itr(SYSCTL_HANDLER_ARGS)
720 {
721 	struct iavf_sc *sc = (struct iavf_sc *)arg1;
722 	device_t dev = sc->dev;
723 	int requested_rx_itr;
724 	int error = 0;
725 
726 	UNREFERENCED_PARAMETER(arg2);
727 
728 	if (iavf_driver_is_detaching(sc))
729 		return (ESHUTDOWN);
730 
731 	requested_rx_itr = sc->rx_itr;
732 	error = sysctl_handle_int(oidp, &requested_rx_itr, 0, req);
733 	if ((error) || (req->newptr == NULL))
734 		return (error);
735 	if (requested_rx_itr < 0 || requested_rx_itr > IAVF_MAX_ITR) {
736 		device_printf(dev,
737 		    "Invalid RX itr value; value must be between 0 and %d\n",
738 		        IAVF_MAX_ITR);
739 		return (EINVAL);
740 	}
741 
742 	sc->rx_itr = requested_rx_itr;
743 	iavf_configure_rx_itr(sc);
744 
745 	return (error);
746 }
747 
748 /**
749  * iavf_configure_tx_itr - Configure the Tx ITR
750  * @sc: device private softc
751  *
752  * Updates the ITR registers with a new Tx ITR setting.
753  */
754 void
iavf_configure_tx_itr(struct iavf_sc * sc)755 iavf_configure_tx_itr(struct iavf_sc *sc)
756 {
757 	struct iavf_hw		*hw = &sc->hw;
758 	struct iavf_vsi		*vsi = &sc->vsi;
759 	struct iavf_tx_queue	*que = vsi->tx_queues;
760 
761 	vsi->tx_itr_setting = sc->tx_itr;
762 
763 	for (int i = 0; i < IAVF_NTXQS(vsi); i++, que++) {
764 		struct tx_ring	*txr = &que->txr;
765 
766 		wr32(hw, IAVF_VFINT_ITRN1(IAVF_TX_ITR, i),
767 		    vsi->tx_itr_setting);
768 		txr->itr = vsi->tx_itr_setting;
769 		txr->latency = IAVF_AVE_LATENCY;
770 	}
771 }
772 
773 /**
774  * iavf_configure_rx_itr - Configure the Rx ITR
775  * @sc: device private softc
776  *
777  * Updates the ITR registers with a new Rx ITR setting.
778  */
779 void
iavf_configure_rx_itr(struct iavf_sc * sc)780 iavf_configure_rx_itr(struct iavf_sc *sc)
781 {
782 	struct iavf_hw		*hw = &sc->hw;
783 	struct iavf_vsi		*vsi = &sc->vsi;
784 	struct iavf_rx_queue	*que = vsi->rx_queues;
785 
786 	vsi->rx_itr_setting = sc->rx_itr;
787 
788 	for (int i = 0; i < IAVF_NRXQS(vsi); i++, que++) {
789 		struct rx_ring	*rxr = &que->rxr;
790 
791 		wr32(hw, IAVF_VFINT_ITRN1(IAVF_RX_ITR, i),
792 		    vsi->rx_itr_setting);
793 		rxr->itr = vsi->rx_itr_setting;
794 		rxr->latency = IAVF_AVE_LATENCY;
795 	}
796 }
797 
798 /**
799  * iavf_create_debug_sysctl_tree - Create a debug sysctl node
800  * @sc: device private softc
801  *
802  * Create a sysctl node meant to hold sysctls used to print debug information.
803  * Mark it as CTLFLAG_SKIP so that these sysctls do not show up in the
804  * "sysctl -a" output.
805  *
806  * @returns a pointer to the created sysctl node.
807  */
808 struct sysctl_oid_list *
iavf_create_debug_sysctl_tree(struct iavf_sc * sc)809 iavf_create_debug_sysctl_tree(struct iavf_sc *sc)
810 {
811 	device_t dev = sc->dev;
812 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
813 	struct sysctl_oid_list *ctx_list =
814 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
815 	struct sysctl_oid *debug_node;
816 
817 	debug_node = SYSCTL_ADD_NODE(ctx, ctx_list,
818 	    OID_AUTO, "debug", CTLFLAG_RD | CTLFLAG_SKIP, NULL, "Debug Sysctls");
819 
820 	return (SYSCTL_CHILDREN(debug_node));
821 }
822 
823 /**
824  * iavf_add_vsi_sysctls - Add sysctls for a given VSI
825  * @dev: device pointer
826  * @vsi: pointer to the VSI
827  * @ctx: sysctl context to add to
828  * @sysctl_name: name of the sysctl node (containing the VSI number)
829  *
830  * Adds a new sysctl node for holding specific sysctls for the given VSI.
831  */
832 void
iavf_add_vsi_sysctls(device_t dev,struct iavf_vsi * vsi,struct sysctl_ctx_list * ctx,const char * sysctl_name)833 iavf_add_vsi_sysctls(device_t dev, struct iavf_vsi *vsi,
834     struct sysctl_ctx_list *ctx, const char *sysctl_name)
835 {
836 	struct sysctl_oid *tree;
837 	struct sysctl_oid_list *child;
838 	struct sysctl_oid_list *vsi_list;
839 
840 	tree = device_get_sysctl_tree(dev);
841 	child = SYSCTL_CHILDREN(tree);
842 	vsi->vsi_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, sysctl_name,
843 				   CTLFLAG_RD, NULL, "VSI Number");
844 	vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
845 
846 	iavf_add_sysctls_eth_stats(ctx, vsi_list, &vsi->eth_stats);
847 }
848 
849 /**
850  * iavf_sysctl_sw_filter_list - Dump software filters
851  * @oidp: sysctl oid pointer
852  * @arg1: pointer to the device softc
853  * @arg2: unused sysctl argument
854  * @req: sysctl req pointer
855  *
856  * On read, generates a string which lists the MAC and VLAN filters added to
857  * this virtual device. Useful for debugging to see whether or not the
858  * expected filters have been configured by software.
859  *
860  * @returns zero on success, or an error code on failure.
861  */
862 int
iavf_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS)863 iavf_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS)
864 {
865 	struct iavf_sc *sc = (struct iavf_sc *)arg1;
866 	struct iavf_mac_filter *f;
867 	struct iavf_vlan_filter *v;
868 	device_t dev = sc->dev;
869 	int ftl_len, ftl_counter = 0, error = 0;
870 	struct sbuf *buf;
871 
872 	UNREFERENCED_2PARAMETER(arg2, oidp);
873 
874 	if (iavf_driver_is_detaching(sc))
875 		return (ESHUTDOWN);
876 
877 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
878 	if (!buf) {
879 		device_printf(dev, "Could not allocate sbuf for output.\n");
880 		return (ENOMEM);
881 	}
882 
883 	sbuf_printf(buf, "\n");
884 
885 	/* Print MAC filters */
886 	sbuf_printf(buf, "MAC Filters:\n");
887 	ftl_len = 0;
888 	SLIST_FOREACH(f, sc->mac_filters, next)
889 		ftl_len++;
890 	if (ftl_len < 1)
891 		sbuf_printf(buf, "(none)\n");
892 	else {
893 		SLIST_FOREACH(f, sc->mac_filters, next) {
894 			sbuf_printf(buf,
895 			    MAC_FORMAT ", flags %#06x\n",
896 			    MAC_FORMAT_ARGS(f->macaddr), f->flags);
897 		}
898 	}
899 
900 	/* Print VLAN filters */
901 	sbuf_printf(buf, "VLAN Filters:\n");
902 	ftl_len = 0;
903 	SLIST_FOREACH(v, sc->vlan_filters, next)
904 		ftl_len++;
905 	if (ftl_len < 1)
906 		sbuf_printf(buf, "(none)");
907 	else {
908 		SLIST_FOREACH(v, sc->vlan_filters, next) {
909 			sbuf_printf(buf,
910 			    "%d, flags %#06x",
911 			    v->vlan, v->flags);
912 			/* don't print '\n' for last entry */
913 			if (++ftl_counter != ftl_len)
914 				sbuf_printf(buf, "\n");
915 		}
916 	}
917 
918 	error = sbuf_finish(buf);
919 	if (error)
920 		device_printf(dev, "Error finishing sbuf: %d\n", error);
921 
922 	sbuf_delete(buf);
923 	return (error);
924 }
925 
926 /**
927  * iavf_media_status_common - Get media status for this device
928  * @sc: device softc pointer
929  * @ifmr: ifmedia request structure
930  *
931  * Report the media status for this device into the given ifmr structure.
932  */
933 void
iavf_media_status_common(struct iavf_sc * sc,struct ifmediareq * ifmr)934 iavf_media_status_common(struct iavf_sc *sc, struct ifmediareq *ifmr)
935 {
936 	enum iavf_ext_link_speed ext_speed;
937 
938 	iavf_update_link_status(sc);
939 
940 	ifmr->ifm_status = IFM_AVALID;
941 	ifmr->ifm_active = IFM_ETHER;
942 
943 	if (!sc->link_up)
944 		return;
945 
946 	ifmr->ifm_status |= IFM_ACTIVE;
947 	/* Hardware is always full-duplex */
948 	ifmr->ifm_active |= IFM_FDX;
949 
950 	/* Based on the link speed reported by the PF over the AdminQ, choose a
951 	 * PHY type to report. This isn't 100% correct since we don't really
952 	 * know the underlying PHY type of the PF, but at least we can report
953 	 * a valid link speed...
954 	 */
955 	if (IAVF_CAP_ADV_LINK_SPEED(sc))
956 		ext_speed = iavf_adv_speed_to_ext_speed(sc->link_speed_adv);
957 	else
958 		ext_speed = iavf_vc_speed_to_ext_speed(sc->link_speed);
959 
960 	ifmr->ifm_active |= iavf_ext_speed_to_ifmedia(ext_speed);
961 }
962 
963 /**
964  * iavf_media_change_common - Change the media type for this device
965  * @ifp: ifnet structure
966  *
967  * @returns ENODEV because changing the media and speed is not supported.
968  */
969 int
iavf_media_change_common(if_t ifp)970 iavf_media_change_common(if_t ifp)
971 {
972 	if_printf(ifp, "Changing speed is not supported\n");
973 
974 	return (ENODEV);
975 }
976 
977 /**
978  * iavf_set_initial_baudrate - Set the initial device baudrate
979  * @ifp: ifnet structure
980  *
981  * Set the baudrate for this ifnet structure to the expected initial value of
982  * 40Gbps. This maybe updated to a lower baudrate after the physical function
983  * reports speed to us over the virtchnl interface.
984  */
985 void
iavf_set_initial_baudrate(if_t ifp)986 iavf_set_initial_baudrate(if_t ifp)
987 {
988 	if_setbaudrate(ifp, IF_Gbps(40));
989 }
990 
991 /**
992  * iavf_add_sysctls_eth_stats - Add ethernet statistics sysctls
993  * @ctx: the sysctl ctx to add to
994  * @child: the node to add the sysctls to
995  * @eth_stats: ethernet stats structure
996  *
997  * Creates sysctls that report the values of the provided ethernet stats
998  * structure.
999  */
1000 void
iavf_add_sysctls_eth_stats(struct sysctl_ctx_list * ctx,struct sysctl_oid_list * child,struct iavf_eth_stats * eth_stats)1001 iavf_add_sysctls_eth_stats(struct sysctl_ctx_list *ctx,
1002 	struct sysctl_oid_list *child,
1003 	struct iavf_eth_stats *eth_stats)
1004 {
1005 	struct iavf_sysctl_info ctls[] =
1006 	{
1007 		{&eth_stats->rx_bytes, "good_octets_rcvd", "Good Octets Received"},
1008 		{&eth_stats->rx_unicast, "ucast_pkts_rcvd",
1009 			"Unicast Packets Received"},
1010 		{&eth_stats->rx_multicast, "mcast_pkts_rcvd",
1011 			"Multicast Packets Received"},
1012 		{&eth_stats->rx_broadcast, "bcast_pkts_rcvd",
1013 			"Broadcast Packets Received"},
1014 		{&eth_stats->rx_discards, "rx_discards", "Discarded RX packets"},
1015 		{&eth_stats->rx_unknown_protocol, "rx_unknown_proto",
1016 			"RX unknown protocol packets"},
1017 		{&eth_stats->tx_bytes, "good_octets_txd", "Good Octets Transmitted"},
1018 		{&eth_stats->tx_unicast, "ucast_pkts_txd", "Unicast Packets Transmitted"},
1019 		{&eth_stats->tx_multicast, "mcast_pkts_txd",
1020 			"Multicast Packets Transmitted"},
1021 		{&eth_stats->tx_broadcast, "bcast_pkts_txd",
1022 			"Broadcast Packets Transmitted"},
1023 		{&eth_stats->tx_errors, "tx_errors", "TX packet errors"},
1024 		// end
1025 		{0,0,0}
1026 	};
1027 
1028 	struct iavf_sysctl_info *entry = ctls;
1029 
1030 	while (entry->stat != 0)
1031 	{
1032 		SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, entry->name,
1033 				CTLFLAG_RD, entry->stat,
1034 				entry->description);
1035 		entry++;
1036 	}
1037 }
1038 
1039 /**
1040  * iavf_max_vc_speed_to_value - Convert link speed to IF speed value
1041  * @link_speeds: bitmap of supported link speeds
1042  *
1043  * @returns the link speed value for the highest speed reported in the
1044  * link_speeds bitmap.
1045  */
1046 u64
iavf_max_vc_speed_to_value(u8 link_speeds)1047 iavf_max_vc_speed_to_value(u8 link_speeds)
1048 {
1049 	if (link_speeds & VIRTCHNL_LINK_SPEED_40GB)
1050 		return IF_Gbps(40);
1051 	if (link_speeds & VIRTCHNL_LINK_SPEED_25GB)
1052 		return IF_Gbps(25);
1053 	if (link_speeds & VIRTCHNL_LINK_SPEED_20GB)
1054 		return IF_Gbps(20);
1055 	if (link_speeds & VIRTCHNL_LINK_SPEED_10GB)
1056 		return IF_Gbps(10);
1057 	if (link_speeds & VIRTCHNL_LINK_SPEED_1GB)
1058 		return IF_Gbps(1);
1059 	if (link_speeds & VIRTCHNL_LINK_SPEED_100MB)
1060 		return IF_Mbps(100);
1061 	else
1062 		/* Minimum supported link speed */
1063 		return IF_Mbps(100);
1064 }
1065 
1066 /**
1067  * iavf_config_rss_reg - Configure RSS using registers
1068  * @sc: device private softc
1069  *
1070  * Configures RSS for this function using the device registers. Called if the
1071  * PF does not support configuring RSS over the virtchnl interface.
1072  */
1073 void
iavf_config_rss_reg(struct iavf_sc * sc)1074 iavf_config_rss_reg(struct iavf_sc *sc)
1075 {
1076 	struct iavf_hw	*hw = &sc->hw;
1077 	struct iavf_vsi	*vsi = &sc->vsi;
1078 	u32		lut = 0;
1079 	u64		set_hena = 0, hena;
1080 	int		i, j, que_id;
1081 	u32		rss_seed[IAVF_RSS_KEY_SIZE_REG];
1082 #ifdef RSS
1083 	u32		rss_hash_config;
1084 #endif
1085 
1086 	/* Don't set up RSS if using a single queue */
1087 	if (IAVF_NRXQS(vsi) == 1) {
1088 		wr32(hw, IAVF_VFQF_HENA(0), 0);
1089 		wr32(hw, IAVF_VFQF_HENA(1), 0);
1090 		iavf_flush(hw);
1091 		return;
1092 	}
1093 
1094 #ifdef RSS
1095 	/* Fetch the configured RSS key */
1096 	rss_getkey((uint8_t *) &rss_seed);
1097 #else
1098 	iavf_get_default_rss_key(rss_seed);
1099 #endif
1100 
1101 	/* Fill out hash function seed */
1102 	for (i = 0; i < IAVF_RSS_KEY_SIZE_REG; i++)
1103                 wr32(hw, IAVF_VFQF_HKEY(i), rss_seed[i]);
1104 
1105 	/* Enable PCTYPES for RSS: */
1106 #ifdef RSS
1107 	rss_hash_config = rss_gethashconfig();
1108 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
1109                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV4_OTHER);
1110 	if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
1111                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV4_TCP);
1112 	if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
1113                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV4_UDP);
1114 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
1115                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV6_OTHER);
1116 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
1117 		set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_FRAG_IPV6);
1118 	if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
1119                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV6_TCP);
1120         if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
1121                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV6_UDP);
1122 #else
1123 	set_hena = IAVF_DEFAULT_RSS_HENA_XL710;
1124 #endif
1125 	hena = (u64)rd32(hw, IAVF_VFQF_HENA(0)) |
1126 	    ((u64)rd32(hw, IAVF_VFQF_HENA(1)) << 32);
1127 	hena |= set_hena;
1128 	wr32(hw, IAVF_VFQF_HENA(0), (u32)hena);
1129 	wr32(hw, IAVF_VFQF_HENA(1), (u32)(hena >> 32));
1130 
1131 	/* Populate the LUT with max no. of queues in round robin fashion */
1132 	for (i = 0, j = 0; i < IAVF_RSS_VSI_LUT_SIZE; i++, j++) {
1133                 if (j == IAVF_NRXQS(vsi))
1134                         j = 0;
1135 #ifdef RSS
1136 		/*
1137 		 * Fetch the RSS bucket id for the given indirection entry.
1138 		 * Cap it at the number of configured buckets (which is
1139 		 * num_rx_queues.)
1140 		 */
1141 		que_id = rss_get_indirection_to_bucket(i);
1142 		que_id = que_id % IAVF_NRXQS(vsi);
1143 #else
1144 		que_id = j;
1145 #endif
1146                 /* lut = 4-byte sliding window of 4 lut entries */
1147                 lut = (lut << 8) | (que_id & IAVF_RSS_VF_LUT_ENTRY_MASK);
1148                 /* On i = 3, we have 4 entries in lut; write to the register */
1149                 if ((i & 3) == 3) {
1150                         wr32(hw, IAVF_VFQF_HLUT(i >> 2), lut);
1151 			iavf_dbg_rss(sc, "%s: HLUT(%2d): %#010x", __func__,
1152 			    i, lut);
1153 		}
1154         }
1155 	iavf_flush(hw);
1156 }
1157 
1158 /**
1159  * iavf_config_rss_pf - Configure RSS using PF virtchnl messages
1160  * @sc: device private softc
1161  *
1162  * Configure RSS by sending virtchnl messages to the PF.
1163  */
1164 void
iavf_config_rss_pf(struct iavf_sc * sc)1165 iavf_config_rss_pf(struct iavf_sc *sc)
1166 {
1167 	iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIG_RSS_KEY);
1168 
1169 	iavf_send_vc_msg(sc, IAVF_FLAG_AQ_SET_RSS_HENA);
1170 
1171 	iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIG_RSS_LUT);
1172 }
1173 
1174 /**
1175  * iavf_config_rss - setup RSS
1176  * @sc: device private softc
1177  *
1178  * Configures RSS using the method determined by capability flags in the VF
1179  * resources structure sent from the PF over the virtchnl interface.
1180  *
1181  * @remark RSS keys and table are cleared on VF reset.
1182  */
1183 void
iavf_config_rss(struct iavf_sc * sc)1184 iavf_config_rss(struct iavf_sc *sc)
1185 {
1186 	if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_REG) {
1187 		iavf_dbg_info(sc, "Setting up RSS using VF registers...\n");
1188 		iavf_config_rss_reg(sc);
1189 	} else if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
1190 		iavf_dbg_info(sc, "Setting up RSS using messages to PF...\n");
1191 		iavf_config_rss_pf(sc);
1192 	} else
1193 		device_printf(sc->dev, "VF does not support RSS capability sent by PF.\n");
1194 }
1195 
1196 /**
1197  * iavf_config_promisc - setup promiscuous mode
1198  * @sc: device private softc
1199  * @flags: promiscuous flags to configure
1200  *
1201  * Request that promiscuous modes be enabled from the PF
1202  *
1203  * @returns zero on success, or an error code on failure.
1204  */
1205 int
iavf_config_promisc(struct iavf_sc * sc,int flags)1206 iavf_config_promisc(struct iavf_sc *sc, int flags)
1207 {
1208 	if_t ifp = sc->vsi.ifp;
1209 
1210 	sc->promisc_flags = 0;
1211 
1212 	if (flags & IFF_ALLMULTI ||
1213 		if_llmaddr_count(ifp) == MAX_MULTICAST_ADDR)
1214 		sc->promisc_flags |= FLAG_VF_MULTICAST_PROMISC;
1215 	if (flags & IFF_PROMISC)
1216 		sc->promisc_flags |= FLAG_VF_UNICAST_PROMISC;
1217 
1218 	iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIGURE_PROMISC);
1219 
1220 	return (0);
1221 }
1222 
1223 /**
1224  * iavf_mc_filter_apply - Program a MAC filter for this VF
1225  * @arg: pointer to the device softc
1226  * @sdl: MAC multicast address
1227  * @cnt: unused parameter
1228  *
1229  * Program a MAC address multicast filter for this device. Intended
1230  * to be used with the map-like function if_foreach_llmaddr().
1231  *
1232  * @returns 1 on success, or 0 on failure
1233  */
1234 static u_int
iavf_mc_filter_apply(void * arg,struct sockaddr_dl * sdl,u_int cnt __unused)1235 iavf_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int cnt __unused)
1236 {
1237 	struct iavf_sc *sc = (struct iavf_sc *)arg;
1238 	int error;
1239 
1240 	error = iavf_add_mac_filter(sc, (u8*)LLADDR(sdl), IAVF_FILTER_MC);
1241 
1242 	return (!error);
1243 }
1244 
1245 /**
1246  * iavf_init_multi - Initialize multicast address filters
1247  * @sc: device private softc
1248  *
1249  * Called during initialization to reset multicast address filters to a known
1250  * fresh state by deleting all currently active filters.
1251  */
1252 void
iavf_init_multi(struct iavf_sc * sc)1253 iavf_init_multi(struct iavf_sc *sc)
1254 {
1255 	struct iavf_mac_filter *f;
1256 	int mcnt = 0;
1257 
1258 	/* First clear any multicast filters */
1259 	SLIST_FOREACH(f, sc->mac_filters, next) {
1260 		if ((f->flags & IAVF_FILTER_USED)
1261 		    && (f->flags & IAVF_FILTER_MC)) {
1262 			f->flags |= IAVF_FILTER_DEL;
1263 			mcnt++;
1264 		}
1265 	}
1266 	if (mcnt > 0)
1267 		iavf_send_vc_msg(sc, IAVF_FLAG_AQ_DEL_MAC_FILTER);
1268 }
1269 
1270 /**
1271  * iavf_multi_set - Set multicast filters
1272  * @sc: device private softc
1273  *
1274  * Set multicast MAC filters for this device. If there are too many filters,
1275  * this will request the device to go into multicast promiscuous mode instead.
1276  */
1277 void
iavf_multi_set(struct iavf_sc * sc)1278 iavf_multi_set(struct iavf_sc *sc)
1279 {
1280 	if_t ifp = sc->vsi.ifp;
1281 	int mcnt = 0;
1282 
1283 	IOCTL_DEBUGOUT("iavf_multi_set: begin");
1284 
1285 	mcnt = if_llmaddr_count(ifp);
1286 	if (__predict_false(mcnt == MAX_MULTICAST_ADDR)) {
1287 		/* Delete MC filters and enable mulitcast promisc instead */
1288 		iavf_init_multi(sc);
1289 		sc->promisc_flags |= FLAG_VF_MULTICAST_PROMISC;
1290 		iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIGURE_PROMISC);
1291 		return;
1292 	}
1293 
1294 	/* If there aren't too many filters, delete existing MC filters */
1295 	iavf_init_multi(sc);
1296 
1297 	/* And (re-)install filters for all mcast addresses */
1298 	mcnt = if_foreach_llmaddr(ifp, iavf_mc_filter_apply, sc);
1299 
1300 	if (mcnt > 0)
1301 		iavf_send_vc_msg(sc, IAVF_FLAG_AQ_ADD_MAC_FILTER);
1302 }
1303 
1304 /**
1305  * iavf_add_mac_filter - Add a MAC filter to the sc MAC list
1306  * @sc: device private softc
1307  * @macaddr: MAC address to add
1308  * @flags: filter flags
1309  *
1310  * Add a new MAC filter to the softc MAC filter list. These will later be sent
1311  * to the physical function (and ultimately hardware) via the virtchnl
1312  * interface.
1313  *
1314  * @returns zero on success, EEXIST if the filter already exists, and ENOMEM
1315  * if we ran out of memory allocating the filter structure.
1316  */
1317 int
iavf_add_mac_filter(struct iavf_sc * sc,u8 * macaddr,u16 flags)1318 iavf_add_mac_filter(struct iavf_sc *sc, u8 *macaddr, u16 flags)
1319 {
1320 	struct iavf_mac_filter	*f;
1321 
1322 	/* Does one already exist? */
1323 	f = iavf_find_mac_filter(sc, macaddr);
1324 	if (f != NULL) {
1325 		iavf_dbg_filter(sc, "exists: " MAC_FORMAT "\n",
1326 		    MAC_FORMAT_ARGS(macaddr));
1327 		return (EEXIST);
1328 	}
1329 
1330 	/* If not, get a new empty filter */
1331 	f = iavf_get_mac_filter(sc);
1332 	if (f == NULL) {
1333 		device_printf(sc->dev, "%s: no filters available!!\n",
1334 		    __func__);
1335 		return (ENOMEM);
1336 	}
1337 
1338 	iavf_dbg_filter(sc, "marked: " MAC_FORMAT "\n",
1339 	    MAC_FORMAT_ARGS(macaddr));
1340 
1341 	bcopy(macaddr, f->macaddr, ETHER_ADDR_LEN);
1342 	f->flags |= (IAVF_FILTER_ADD | IAVF_FILTER_USED);
1343 	f->flags |= flags;
1344 	return (0);
1345 }
1346 
1347 /**
1348  * iavf_find_mac_filter - Find a MAC filter with the given address
1349  * @sc: device private softc
1350  * @macaddr: the MAC address to find
1351  *
1352  * Finds the filter structure in the MAC filter list with the corresponding
1353  * MAC address.
1354  *
1355  * @returns a pointer to the filter structure, or NULL if no such filter
1356  * exists in the list yet.
1357  */
1358 struct iavf_mac_filter *
iavf_find_mac_filter(struct iavf_sc * sc,u8 * macaddr)1359 iavf_find_mac_filter(struct iavf_sc *sc, u8 *macaddr)
1360 {
1361 	struct iavf_mac_filter	*f;
1362 	bool match = FALSE;
1363 
1364 	SLIST_FOREACH(f, sc->mac_filters, next) {
1365 		if (cmp_etheraddr(f->macaddr, macaddr)) {
1366 			match = TRUE;
1367 			break;
1368 		}
1369 	}
1370 
1371 	if (!match)
1372 		f = NULL;
1373 	return (f);
1374 }
1375 
1376 /**
1377  * iavf_get_mac_filter - Get a new MAC address filter
1378  * @sc: device private softc
1379  *
1380  * Allocates a new filter structure and inserts it into the MAC filter list.
1381  *
1382  * @post the caller must fill in the structure details after calling this
1383  * function, but does not need to insert it into the linked list.
1384  *
1385  * @returns a pointer to the new filter structure, or NULL of we failed to
1386  * allocate it.
1387  */
1388 struct iavf_mac_filter *
iavf_get_mac_filter(struct iavf_sc * sc)1389 iavf_get_mac_filter(struct iavf_sc *sc)
1390 {
1391 	struct iavf_mac_filter *f;
1392 
1393 	f = (struct iavf_mac_filter *)malloc(sizeof(struct iavf_mac_filter),
1394 	    M_IAVF, M_NOWAIT | M_ZERO);
1395 	if (f)
1396 		SLIST_INSERT_HEAD(sc->mac_filters, f, next);
1397 
1398 	return (f);
1399 }
1400 
1401 /**
1402  * iavf_baudrate_from_link_speed - Convert link speed to baudrate
1403  * @sc: device private softc
1404  *
1405  * @post The link_speed_adv field is in Mbps, so it is multipled by
1406  * 1,000,000 before it's returned.
1407  *
1408  * @returns the adapter link speed in bits/sec
1409  */
1410 u64
iavf_baudrate_from_link_speed(struct iavf_sc * sc)1411 iavf_baudrate_from_link_speed(struct iavf_sc *sc)
1412 {
1413 	if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
1414 		return (sc->link_speed_adv * IAVF_ADV_LINK_SPEED_SCALE);
1415 	else
1416 		return iavf_max_vc_speed_to_value(sc->link_speed);
1417 }
1418 
1419 /**
1420  * iavf_add_vlan_filter - Add a VLAN filter to the softc VLAN list
1421  * @sc: device private softc
1422  * @vtag: the VLAN id to filter
1423  *
1424  * Allocate a new VLAN filter structure and insert it into the VLAN list.
1425  */
1426 void
iavf_add_vlan_filter(struct iavf_sc * sc,u16 vtag)1427 iavf_add_vlan_filter(struct iavf_sc *sc, u16 vtag)
1428 {
1429 	struct iavf_vlan_filter	*v;
1430 
1431 	v = (struct iavf_vlan_filter *)malloc(sizeof(struct iavf_vlan_filter),
1432 	    M_IAVF, M_WAITOK | M_ZERO);
1433 	SLIST_INSERT_HEAD(sc->vlan_filters, v, next);
1434 	v->vlan = vtag;
1435 	v->flags = IAVF_FILTER_ADD;
1436 }
1437 
1438 /**
1439  * iavf_mark_del_vlan_filter - Mark a given VLAN id for deletion
1440  * @sc: device private softc
1441  * @vtag: the VLAN id to delete
1442  *
1443  * Marks all VLAN filters matching the given vtag for deletion.
1444  *
1445  * @returns the number of filters marked for deletion.
1446  *
1447  * @remark the filters are not removed immediately, but will be removed from
1448  * the list by another function that synchronizes over the virtchnl interface.
1449  */
1450 int
iavf_mark_del_vlan_filter(struct iavf_sc * sc,u16 vtag)1451 iavf_mark_del_vlan_filter(struct iavf_sc *sc, u16 vtag)
1452 {
1453 	struct iavf_vlan_filter	*v;
1454 	int i = 0;
1455 
1456 	SLIST_FOREACH(v, sc->vlan_filters, next) {
1457 		if (v->vlan == vtag) {
1458 			v->flags = IAVF_FILTER_DEL;
1459 			++i;
1460 		}
1461 	}
1462 
1463 	return (i);
1464 }
1465 
1466 /**
1467  * iavf_update_msix_devinfo - Fix MSIX values for pci_msix_count()
1468  * @dev: pointer to kernel device
1469  *
1470  * Fix cached MSI-X control register information. This is a workaround
1471  * for an issue where VFs spawned in non-passthrough mode on FreeBSD
1472  * will have their PCI information cached before the PF driver
1473  * finishes updating their PCI information.
1474  *
1475  * @pre Must be called before pci_msix_count()
1476  */
1477 void
iavf_update_msix_devinfo(device_t dev)1478 iavf_update_msix_devinfo(device_t dev)
1479 {
1480 	struct pci_devinfo *dinfo;
1481 	u32 msix_ctrl;
1482 
1483 	dinfo = (struct pci_devinfo *)device_get_ivars(dev);
1484 	/* We can hardcode this offset since we know the device */
1485 	msix_ctrl = pci_read_config(dev, 0x70 + PCIR_MSIX_CTRL, 2);
1486 	dinfo->cfg.msix.msix_ctrl = msix_ctrl;
1487 	dinfo->cfg.msix.msix_msgnum = (msix_ctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1;
1488 }
1489 
1490 /**
1491  * iavf_disable_queues_with_retries - Send PF multiple DISABLE_QUEUES messages
1492  * @sc: device softc
1493  *
1494  * Send a virtual channel message to the PF to DISABLE_QUEUES, but resend it up
1495  * to IAVF_MAX_DIS_Q_RETRY times if the response says that it wasn't
1496  * successful. This is intended to workaround a bug that can appear on the PF.
1497  */
1498 void
iavf_disable_queues_with_retries(struct iavf_sc * sc)1499 iavf_disable_queues_with_retries(struct iavf_sc *sc)
1500 {
1501 	bool in_detach = iavf_driver_is_detaching(sc);
1502 	int max_attempts = IAVF_MAX_DIS_Q_RETRY;
1503 	int msg_count = 0;
1504 
1505 	/* While the driver is detaching, it doesn't care if the queue
1506 	 * disable finishes successfully or not. Just send one message
1507 	 * to just notify the PF driver.
1508 	 */
1509 	if (in_detach)
1510 		max_attempts = 1;
1511 
1512 	while ((msg_count < max_attempts) &&
1513 	    atomic_load_acq_32(&sc->queues_enabled)) {
1514 		msg_count++;
1515 		iavf_send_vc_msg_sleep(sc, IAVF_FLAG_AQ_DISABLE_QUEUES);
1516 	}
1517 
1518 	/* Possibly print messages about retry attempts and issues */
1519 	if (msg_count > 1)
1520 		iavf_dbg_vc(sc, "DISABLE_QUEUES messages sent: %d\n",
1521 		    msg_count);
1522 
1523 	if (!in_detach && msg_count >= max_attempts)
1524 		device_printf(sc->dev, "%s: DISABLE_QUEUES may have failed\n",
1525 		    __func__);
1526 }
1527