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