xref: /freebsd/sys/dev/ixl/ixl_pf_main.c (revision e9d419a05357036ea2fd37218d853d2c713d55cc)
1 /******************************************************************************
2 
3   Copyright (c) 2013-2018, Intel Corporation
4   All rights reserved.
5 
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8 
9    1. Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11 
12    2. Redistributions in binary form must reproduce the above copyright
13       notice, this list of conditions and the following disclaimer in the
14       documentation and/or other materials provided with the distribution.
15 
16    3. Neither the name of the Intel Corporation nor the names of its
17       contributors may be used to endorse or promote products derived from
18       this software without specific prior written permission.
19 
20   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   POSSIBILITY OF SUCH DAMAGE.
31 
32 ******************************************************************************/
33 /*$FreeBSD$*/
34 
35 
36 #include "ixl_pf.h"
37 
38 #ifdef PCI_IOV
39 #include "ixl_pf_iov.h"
40 #endif
41 
42 #ifdef IXL_IW
43 #include "ixl_iw.h"
44 #include "ixl_iw_int.h"
45 #endif
46 
47 static u8	ixl_convert_sysctl_aq_link_speed(u8, bool);
48 static void	ixl_sbuf_print_bytes(struct sbuf *, u8 *, int, int, bool);
49 static const char * ixl_link_speed_string(enum i40e_aq_link_speed);
50 static u_int	ixl_add_maddr(void *, struct sockaddr_dl *, u_int);
51 static u_int	ixl_match_maddr(void *, struct sockaddr_dl *, u_int);
52 static char *	ixl_switch_element_string(struct sbuf *, u8, u16);
53 static enum ixl_fw_mode ixl_get_fw_mode(struct ixl_pf *);
54 
55 /* Sysctls */
56 static int	ixl_sysctl_set_advertise(SYSCTL_HANDLER_ARGS);
57 static int	ixl_sysctl_supported_speeds(SYSCTL_HANDLER_ARGS);
58 static int	ixl_sysctl_current_speed(SYSCTL_HANDLER_ARGS);
59 static int	ixl_sysctl_show_fw(SYSCTL_HANDLER_ARGS);
60 static int	ixl_sysctl_unallocated_queues(SYSCTL_HANDLER_ARGS);
61 static int	ixl_sysctl_pf_tx_itr(SYSCTL_HANDLER_ARGS);
62 static int	ixl_sysctl_pf_rx_itr(SYSCTL_HANDLER_ARGS);
63 
64 static int	ixl_sysctl_eee_enable(SYSCTL_HANDLER_ARGS);
65 
66 /* Debug Sysctls */
67 static int 	ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS);
68 static int	ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS);
69 static int	ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS);
70 static int	ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS);
71 static int	ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS);
72 static int	ixl_sysctl_switch_vlans(SYSCTL_HANDLER_ARGS);
73 static int	ixl_sysctl_hkey(SYSCTL_HANDLER_ARGS);
74 static int	ixl_sysctl_hena(SYSCTL_HANDLER_ARGS);
75 static int	ixl_sysctl_hlut(SYSCTL_HANDLER_ARGS);
76 static int	ixl_sysctl_fw_link_management(SYSCTL_HANDLER_ARGS);
77 static int	ixl_sysctl_read_i2c_byte(SYSCTL_HANDLER_ARGS);
78 static int	ixl_sysctl_write_i2c_byte(SYSCTL_HANDLER_ARGS);
79 static int	ixl_sysctl_fec_fc_ability(SYSCTL_HANDLER_ARGS);
80 static int	ixl_sysctl_fec_rs_ability(SYSCTL_HANDLER_ARGS);
81 static int	ixl_sysctl_fec_fc_request(SYSCTL_HANDLER_ARGS);
82 static int	ixl_sysctl_fec_rs_request(SYSCTL_HANDLER_ARGS);
83 static int	ixl_sysctl_fec_auto_enable(SYSCTL_HANDLER_ARGS);
84 static int	ixl_sysctl_dump_debug_data(SYSCTL_HANDLER_ARGS);
85 static int	ixl_sysctl_fw_lldp(SYSCTL_HANDLER_ARGS);
86 static int	ixl_sysctl_read_i2c_diag_data(SYSCTL_HANDLER_ARGS);
87 
88 /* Debug Sysctls */
89 static int	ixl_sysctl_do_pf_reset(SYSCTL_HANDLER_ARGS);
90 static int	ixl_sysctl_do_core_reset(SYSCTL_HANDLER_ARGS);
91 static int	ixl_sysctl_do_global_reset(SYSCTL_HANDLER_ARGS);
92 static int	ixl_sysctl_queue_interrupt_table(SYSCTL_HANDLER_ARGS);
93 #ifdef IXL_DEBUG
94 static int	ixl_sysctl_qtx_tail_handler(SYSCTL_HANDLER_ARGS);
95 static int	ixl_sysctl_qrx_tail_handler(SYSCTL_HANDLER_ARGS);
96 #endif
97 
98 #ifdef IXL_IW
99 extern int ixl_enable_iwarp;
100 extern int ixl_limit_iwarp_msix;
101 #endif
102 
103 static const char * const ixl_fc_string[6] = {
104 	"None",
105 	"Rx",
106 	"Tx",
107 	"Full",
108 	"Priority",
109 	"Default"
110 };
111 
112 static char *ixl_fec_string[3] = {
113        "CL108 RS-FEC",
114        "CL74 FC-FEC/BASE-R",
115        "None"
116 };
117 
118 MALLOC_DEFINE(M_IXL, "ixl", "ixl driver allocations");
119 
120 /*
121 ** Put the FW, API, NVM, EEtrackID, and OEM version information into a string
122 */
123 void
124 ixl_nvm_version_str(struct i40e_hw *hw, struct sbuf *buf)
125 {
126 	u8 oem_ver = (u8)(hw->nvm.oem_ver >> 24);
127 	u16 oem_build = (u16)((hw->nvm.oem_ver >> 16) & 0xFFFF);
128 	u8 oem_patch = (u8)(hw->nvm.oem_ver & 0xFF);
129 
130 	sbuf_printf(buf,
131 	    "fw %d.%d.%05d api %d.%d nvm %x.%02x etid %08x oem %d.%d.%d",
132 	    hw->aq.fw_maj_ver, hw->aq.fw_min_ver, hw->aq.fw_build,
133 	    hw->aq.api_maj_ver, hw->aq.api_min_ver,
134 	    (hw->nvm.version & IXL_NVM_VERSION_HI_MASK) >>
135 	    IXL_NVM_VERSION_HI_SHIFT,
136 	    (hw->nvm.version & IXL_NVM_VERSION_LO_MASK) >>
137 	    IXL_NVM_VERSION_LO_SHIFT,
138 	    hw->nvm.eetrack,
139 	    oem_ver, oem_build, oem_patch);
140 }
141 
142 void
143 ixl_print_nvm_version(struct ixl_pf *pf)
144 {
145 	struct i40e_hw *hw = &pf->hw;
146 	device_t dev = pf->dev;
147 	struct sbuf *sbuf;
148 
149 	sbuf = sbuf_new_auto();
150 	ixl_nvm_version_str(hw, sbuf);
151 	sbuf_finish(sbuf);
152 	device_printf(dev, "%s\n", sbuf_data(sbuf));
153 	sbuf_delete(sbuf);
154 }
155 
156 /**
157  * ixl_get_fw_mode - Check the state of FW
158  * @hw: device hardware structure
159  *
160  * Identify state of FW. It might be in a recovery mode
161  * which limits functionality and requires special handling
162  * from the driver.
163  *
164  * @returns FW mode (normal, recovery, unexpected EMP reset)
165  */
166 static enum ixl_fw_mode
167 ixl_get_fw_mode(struct ixl_pf *pf)
168 {
169 	struct i40e_hw *hw = &pf->hw;
170 	enum ixl_fw_mode fw_mode = IXL_FW_MODE_NORMAL;
171 	u32 fwsts;
172 
173 #ifdef IXL_DEBUG
174 	if (pf->recovery_mode)
175 		return IXL_FW_MODE_RECOVERY;
176 #endif
177 	fwsts = rd32(hw, I40E_GL_FWSTS) & I40E_GL_FWSTS_FWS1B_MASK;
178 
179 	/* Is set and has one of expected values */
180 	if ((fwsts >= I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK &&
181 	    fwsts <= I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_NVM_MASK) ||
182 	    fwsts == I40E_X722_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK ||
183 	    fwsts == I40E_X722_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK)
184 		fw_mode = IXL_FW_MODE_RECOVERY;
185 	else {
186 		if (fwsts > I40E_GL_FWSTS_FWS1B_EMPR_0 &&
187 		    fwsts <= I40E_GL_FWSTS_FWS1B_EMPR_10)
188 			fw_mode = IXL_FW_MODE_UEMPR;
189 	}
190 	return (fw_mode);
191 }
192 
193 /**
194  * ixl_pf_reset - Reset the PF
195  * @pf: PF structure
196  *
197  * Ensure that FW is in the right state and do the reset
198  * if needed.
199  *
200  * @returns zero on success, or an error code on failure.
201  */
202 int
203 ixl_pf_reset(struct ixl_pf *pf)
204 {
205 	struct i40e_hw *hw = &pf->hw;
206 	enum i40e_status_code status;
207 	enum ixl_fw_mode fw_mode;
208 
209 	fw_mode = ixl_get_fw_mode(pf);
210 	ixl_dbg_info(pf, "%s: before PF reset FW mode: 0x%08x\n", __func__, fw_mode);
211 	if (fw_mode == IXL_FW_MODE_RECOVERY) {
212 		atomic_set_32(&pf->state, IXL_PF_STATE_RECOVERY_MODE);
213 		/* Don't try to reset device if it's in recovery mode */
214 		return (0);
215 	}
216 
217 	status = i40e_pf_reset(hw);
218 	if (status == I40E_SUCCESS)
219 		return (0);
220 
221 	/* Check FW mode again in case it has changed while
222 	 * waiting for reset to complete */
223 	fw_mode = ixl_get_fw_mode(pf);
224 	ixl_dbg_info(pf, "%s: after PF reset FW mode: 0x%08x\n", __func__, fw_mode);
225 	if (fw_mode == IXL_FW_MODE_RECOVERY) {
226 		atomic_set_32(&pf->state, IXL_PF_STATE_RECOVERY_MODE);
227 		return (0);
228 	}
229 
230 	if (fw_mode == IXL_FW_MODE_UEMPR)
231 		device_printf(pf->dev,
232 		    "Entering recovery mode due to repeated FW resets. This may take several minutes. Refer to the Intel(R) Ethernet Adapters and Devices User Guide.\n");
233 	else
234 		device_printf(pf->dev, "PF reset failure %s\n",
235 		    i40e_stat_str(hw, status));
236 	return (EIO);
237 }
238 
239 /**
240  * ixl_setup_hmc - Setup LAN Host Memory Cache
241  * @pf: PF structure
242  *
243  * Init and configure LAN Host Memory Cache
244  *
245  * @returns 0 on success, EIO on error
246  */
247 int
248 ixl_setup_hmc(struct ixl_pf *pf)
249 {
250 	struct i40e_hw *hw = &pf->hw;
251 	enum i40e_status_code status;
252 
253 	status = i40e_init_lan_hmc(hw, hw->func_caps.num_tx_qp,
254 	    hw->func_caps.num_rx_qp, 0, 0);
255 	if (status) {
256 		device_printf(pf->dev, "init_lan_hmc failed: %s\n",
257 		    i40e_stat_str(hw, status));
258 		return (EIO);
259 	}
260 
261 	status = i40e_configure_lan_hmc(hw, I40E_HMC_MODEL_DIRECT_ONLY);
262 	if (status) {
263 		device_printf(pf->dev, "configure_lan_hmc failed: %s\n",
264 		    i40e_stat_str(hw, status));
265 		return (EIO);
266 	}
267 
268 	return (0);
269 }
270 
271 /**
272  * ixl_shutdown_hmc - Shutdown LAN Host Memory Cache
273  * @pf: PF structure
274  *
275  * Shutdown Host Memory Cache if configured.
276  *
277  */
278 void
279 ixl_shutdown_hmc(struct ixl_pf *pf)
280 {
281 	struct i40e_hw *hw = &pf->hw;
282 	enum i40e_status_code status;
283 
284 	/* HMC not configured, no need to shutdown */
285 	if (hw->hmc.hmc_obj == NULL)
286 		return;
287 
288 	status = i40e_shutdown_lan_hmc(hw);
289 	if (status)
290 		device_printf(pf->dev,
291 		    "Shutdown LAN HMC failed with code %s\n",
292 		    i40e_stat_str(hw, status));
293 }
294 /*
295  * Write PF ITR values to queue ITR registers.
296  */
297 void
298 ixl_configure_itr(struct ixl_pf *pf)
299 {
300 	ixl_configure_tx_itr(pf);
301 	ixl_configure_rx_itr(pf);
302 }
303 
304 /*********************************************************************
305  *
306  *  Get the hardware capabilities
307  *
308  **********************************************************************/
309 
310 int
311 ixl_get_hw_capabilities(struct ixl_pf *pf)
312 {
313 	struct i40e_aqc_list_capabilities_element_resp *buf;
314 	struct i40e_hw	*hw = &pf->hw;
315 	device_t 	dev = pf->dev;
316 	enum i40e_status_code status;
317 	int len, i2c_intfc_num;
318 	bool again = TRUE;
319 	u16 needed;
320 
321 	if (IXL_PF_IN_RECOVERY_MODE(pf)) {
322 		hw->func_caps.iwarp = 0;
323 		return (0);
324 	}
325 
326 	len = 40 * sizeof(struct i40e_aqc_list_capabilities_element_resp);
327 retry:
328 	if (!(buf = (struct i40e_aqc_list_capabilities_element_resp *)
329 	    malloc(len, M_IXL, M_NOWAIT | M_ZERO))) {
330 		device_printf(dev, "Unable to allocate cap memory\n");
331                 return (ENOMEM);
332 	}
333 
334 	/* This populates the hw struct */
335         status = i40e_aq_discover_capabilities(hw, buf, len,
336 	    &needed, i40e_aqc_opc_list_func_capabilities, NULL);
337 	free(buf, M_IXL);
338 	if ((pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) &&
339 	    (again == TRUE)) {
340 		/* retry once with a larger buffer */
341 		again = FALSE;
342 		len = needed;
343 		goto retry;
344 	} else if (status != I40E_SUCCESS) {
345 		device_printf(dev, "capability discovery failed; status %s, error %s\n",
346 		    i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
347 		return (ENODEV);
348 	}
349 
350 	/*
351 	 * Some devices have both MDIO and I2C; since this isn't reported
352 	 * by the FW, check registers to see if an I2C interface exists.
353 	 */
354 	i2c_intfc_num = ixl_find_i2c_interface(pf);
355 	if (i2c_intfc_num != -1)
356 		pf->has_i2c = true;
357 
358 	/* Determine functions to use for driver I2C accesses */
359 	switch (pf->i2c_access_method) {
360 	case IXL_I2C_ACCESS_METHOD_BEST_AVAILABLE: {
361 		if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE) {
362 			pf->read_i2c_byte = ixl_read_i2c_byte_aq;
363 			pf->write_i2c_byte = ixl_write_i2c_byte_aq;
364 		} else {
365 			pf->read_i2c_byte = ixl_read_i2c_byte_reg;
366 			pf->write_i2c_byte = ixl_write_i2c_byte_reg;
367 		}
368 		break;
369 	}
370 	case IXL_I2C_ACCESS_METHOD_AQ:
371 		pf->read_i2c_byte = ixl_read_i2c_byte_aq;
372 		pf->write_i2c_byte = ixl_write_i2c_byte_aq;
373 		break;
374 	case IXL_I2C_ACCESS_METHOD_REGISTER_I2CCMD:
375 		pf->read_i2c_byte = ixl_read_i2c_byte_reg;
376 		pf->write_i2c_byte = ixl_write_i2c_byte_reg;
377 		break;
378 	case IXL_I2C_ACCESS_METHOD_BIT_BANG_I2CPARAMS:
379 		pf->read_i2c_byte = ixl_read_i2c_byte_bb;
380 		pf->write_i2c_byte = ixl_write_i2c_byte_bb;
381 		break;
382 	default:
383 		/* Should not happen */
384 		device_printf(dev, "Error setting I2C access functions\n");
385 		break;
386 	}
387 
388 	/* Print a subset of the capability information. */
389 	device_printf(dev,
390 	    "PF-ID[%d]: VFs %d, MSI-X %d, VF MSI-X %d, QPs %d, %s\n",
391 	    hw->pf_id, hw->func_caps.num_vfs, hw->func_caps.num_msix_vectors,
392 	    hw->func_caps.num_msix_vectors_vf, hw->func_caps.num_tx_qp,
393 	    (hw->func_caps.mdio_port_mode == 2) ? "I2C" :
394 	    (hw->func_caps.mdio_port_mode == 1 && pf->has_i2c) ? "MDIO & I2C" :
395 	    (hw->func_caps.mdio_port_mode == 1) ? "MDIO dedicated" :
396 	    "MDIO shared");
397 
398 	return (0);
399 }
400 
401 /* For the set_advertise sysctl */
402 void
403 ixl_set_initial_advertised_speeds(struct ixl_pf *pf)
404 {
405 	device_t dev = pf->dev;
406 	int err;
407 
408 	/* Make sure to initialize the device to the complete list of
409 	 * supported speeds on driver load, to ensure unloading and
410 	 * reloading the driver will restore this value.
411 	 */
412 	err = ixl_set_advertised_speeds(pf, pf->supported_speeds, true);
413 	if (err) {
414 		/* Non-fatal error */
415 		device_printf(dev, "%s: ixl_set_advertised_speeds() error %d\n",
416 			      __func__, err);
417 		return;
418 	}
419 
420 	pf->advertised_speed =
421 	    ixl_convert_sysctl_aq_link_speed(pf->supported_speeds, false);
422 }
423 
424 int
425 ixl_teardown_hw_structs(struct ixl_pf *pf)
426 {
427 	enum i40e_status_code status = 0;
428 	struct i40e_hw *hw = &pf->hw;
429 	device_t dev = pf->dev;
430 
431 	/* Shutdown LAN HMC */
432 	if (hw->hmc.hmc_obj) {
433 		status = i40e_shutdown_lan_hmc(hw);
434 		if (status) {
435 			device_printf(dev,
436 			    "init: LAN HMC shutdown failure; status %s\n",
437 			    i40e_stat_str(hw, status));
438 			goto err_out;
439 		}
440 	}
441 
442 	/* Shutdown admin queue */
443 	ixl_disable_intr0(hw);
444 	status = i40e_shutdown_adminq(hw);
445 	if (status)
446 		device_printf(dev,
447 		    "init: Admin Queue shutdown failure; status %s\n",
448 		    i40e_stat_str(hw, status));
449 
450 	ixl_pf_qmgr_release(&pf->qmgr, &pf->qtag);
451 err_out:
452 	return (status);
453 }
454 
455 /*
456 ** Creates new filter with given MAC address and VLAN ID
457 */
458 static struct ixl_mac_filter *
459 ixl_new_filter(struct ixl_ftl_head *headp, const u8 *macaddr, s16 vlan)
460 {
461 	struct ixl_mac_filter  *f;
462 
463 	/* create a new empty filter */
464 	f = malloc(sizeof(struct ixl_mac_filter),
465 	    M_IXL, M_NOWAIT | M_ZERO);
466 	if (f) {
467 		LIST_INSERT_HEAD(headp, f, ftle);
468 		bcopy(macaddr, f->macaddr, ETHER_ADDR_LEN);
469 		f->vlan = vlan;
470 	}
471 
472 	return (f);
473 }
474 
475 /**
476  * ixl_free_filters - Free all filters in given list
477  * headp - pointer to list head
478  *
479  * Frees memory used by each entry in the list.
480  * Does not remove filters from HW.
481  */
482 void
483 ixl_free_filters(struct ixl_ftl_head *headp)
484 {
485 	struct ixl_mac_filter *f, *nf;
486 
487 	f = LIST_FIRST(headp);
488 	while (f != NULL) {
489 		nf = LIST_NEXT(f, ftle);
490 		free(f, M_IXL);
491 		f = nf;
492 	}
493 
494 	LIST_INIT(headp);
495 }
496 
497 static u_int
498 ixl_add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
499 {
500 	struct ixl_add_maddr_arg *ama = arg;
501 	struct ixl_vsi *vsi = ama->vsi;
502 	const u8 *macaddr = (u8*)LLADDR(sdl);
503 	struct ixl_mac_filter *f;
504 
505 	/* Does one already exist */
506 	f = ixl_find_filter(&vsi->ftl, macaddr, IXL_VLAN_ANY);
507 	if (f != NULL)
508 		return (0);
509 
510 	f = ixl_new_filter(&ama->to_add, macaddr, IXL_VLAN_ANY);
511 	if (f == NULL) {
512 		device_printf(vsi->dev, "WARNING: no filter available!!\n");
513 		return (0);
514 	}
515 	f->flags |= IXL_FILTER_MC;
516 
517 	return (1);
518 }
519 
520 /*********************************************************************
521  * 	Filter Routines
522  *
523  *	Routines for multicast and vlan filter management.
524  *
525  *********************************************************************/
526 void
527 ixl_add_multi(struct ixl_vsi *vsi)
528 {
529 	struct ifnet		*ifp = vsi->ifp;
530 	struct i40e_hw		*hw = vsi->hw;
531 	int			mcnt = 0;
532 	struct ixl_add_maddr_arg cb_arg;
533 
534 	IOCTL_DEBUGOUT("ixl_add_multi: begin");
535 
536 	mcnt = if_llmaddr_count(ifp);
537 	if (__predict_false(mcnt >= MAX_MULTICAST_ADDR)) {
538 		i40e_aq_set_vsi_multicast_promiscuous(hw,
539 		    vsi->seid, TRUE, NULL);
540 		/* delete all existing MC filters */
541 		ixl_del_multi(vsi, true);
542 		return;
543 	}
544 
545 	cb_arg.vsi = vsi;
546 	LIST_INIT(&cb_arg.to_add);
547 
548 	mcnt = if_foreach_llmaddr(ifp, ixl_add_maddr, &cb_arg);
549 	if (mcnt > 0)
550 		ixl_add_hw_filters(vsi, &cb_arg.to_add, mcnt);
551 
552 	IOCTL_DEBUGOUT("ixl_add_multi: end");
553 }
554 
555 static u_int
556 ixl_match_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
557 {
558 	struct ixl_mac_filter *f = arg;
559 
560 	if (ixl_ether_is_equal(f->macaddr, (u8 *)LLADDR(sdl)))
561 		return (1);
562 	else
563 		return (0);
564 }
565 
566 void
567 ixl_del_multi(struct ixl_vsi *vsi, bool all)
568 {
569 	struct ixl_ftl_head	to_del;
570 	struct ifnet		*ifp = vsi->ifp;
571 	struct ixl_mac_filter	*f, *fn;
572 	int			mcnt = 0;
573 
574 	IOCTL_DEBUGOUT("ixl_del_multi: begin");
575 
576 	LIST_INIT(&to_del);
577 	/* Search for removed multicast addresses */
578 	LIST_FOREACH_SAFE(f, &vsi->ftl, ftle, fn) {
579 		if ((f->flags & IXL_FILTER_MC) == 0 ||
580 		    (!all && (if_foreach_llmaddr(ifp, ixl_match_maddr, f) == 0)))
581 			continue;
582 
583 		LIST_REMOVE(f, ftle);
584 		LIST_INSERT_HEAD(&to_del, f, ftle);
585 		mcnt++;
586 	}
587 
588 	if (mcnt > 0)
589 		ixl_del_hw_filters(vsi, &to_del, mcnt);
590 }
591 
592 void
593 ixl_link_up_msg(struct ixl_pf *pf)
594 {
595 	struct i40e_hw *hw = &pf->hw;
596 	struct ifnet *ifp = pf->vsi.ifp;
597 	char *req_fec_string, *neg_fec_string;
598 	u8 fec_abilities;
599 
600 	fec_abilities = hw->phy.link_info.req_fec_info;
601 	/* If both RS and KR are requested, only show RS */
602 	if (fec_abilities & I40E_AQ_REQUEST_FEC_RS)
603 		req_fec_string = ixl_fec_string[0];
604 	else if (fec_abilities & I40E_AQ_REQUEST_FEC_KR)
605 		req_fec_string = ixl_fec_string[1];
606 	else
607 		req_fec_string = ixl_fec_string[2];
608 
609 	if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_RS_ENA)
610 		neg_fec_string = ixl_fec_string[0];
611 	else if (hw->phy.link_info.fec_info & I40E_AQ_CONFIG_FEC_KR_ENA)
612 		neg_fec_string = ixl_fec_string[1];
613 	else
614 		neg_fec_string = ixl_fec_string[2];
615 
616 	log(LOG_NOTICE, "%s: Link is up, %s Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg: %s, Flow Control: %s\n",
617 	    ifp->if_xname,
618 	    ixl_link_speed_string(hw->phy.link_info.link_speed),
619 	    req_fec_string, neg_fec_string,
620 	    (hw->phy.link_info.an_info & I40E_AQ_AN_COMPLETED) ? "True" : "False",
621 	    (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_TX &&
622 	        hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_RX) ?
623 		ixl_fc_string[3] : (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_TX) ?
624 		ixl_fc_string[2] : (hw->phy.link_info.an_info & I40E_AQ_LINK_PAUSE_RX) ?
625 		ixl_fc_string[1] : ixl_fc_string[0]);
626 }
627 
628 /*
629  * Configure admin queue/misc interrupt cause registers in hardware.
630  */
631 void
632 ixl_configure_intr0_msix(struct ixl_pf *pf)
633 {
634 	struct i40e_hw *hw = &pf->hw;
635 	u32 reg;
636 
637 	/* First set up the adminq - vector 0 */
638 	wr32(hw, I40E_PFINT_ICR0_ENA, 0);  /* disable all */
639 	rd32(hw, I40E_PFINT_ICR0);         /* read to clear */
640 
641 	reg = I40E_PFINT_ICR0_ENA_ECC_ERR_MASK |
642 	    I40E_PFINT_ICR0_ENA_GRST_MASK |
643 	    I40E_PFINT_ICR0_ENA_HMC_ERR_MASK |
644 	    I40E_PFINT_ICR0_ENA_ADMINQ_MASK |
645 	    I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK |
646 	    I40E_PFINT_ICR0_ENA_VFLR_MASK |
647 	    I40E_PFINT_ICR0_ENA_PE_CRITERR_MASK |
648 	    I40E_PFINT_ICR0_ENA_PCI_EXCEPTION_MASK;
649 	wr32(hw, I40E_PFINT_ICR0_ENA, reg);
650 
651 	/*
652 	 * 0x7FF is the end of the queue list.
653 	 * This means we won't use MSI-X vector 0 for a queue interrupt
654 	 * in MSI-X mode.
655 	 */
656 	wr32(hw, I40E_PFINT_LNKLST0, 0x7FF);
657 	/* Value is in 2 usec units, so 0x3E is 62*2 = 124 usecs. */
658 	wr32(hw, I40E_PFINT_ITR0(IXL_RX_ITR), 0x3E);
659 
660 	wr32(hw, I40E_PFINT_DYN_CTL0,
661 	    I40E_PFINT_DYN_CTL0_SW_ITR_INDX_MASK |
662 	    I40E_PFINT_DYN_CTL0_INTENA_MSK_MASK);
663 
664 	wr32(hw, I40E_PFINT_STAT_CTL0, 0);
665 }
666 
667 void
668 ixl_add_ifmedia(struct ifmedia *media, u64 phy_types)
669 {
670 	/* Display supported media types */
671 	if (phy_types & (I40E_CAP_PHY_TYPE_100BASE_TX))
672 		ifmedia_add(media, IFM_ETHER | IFM_100_TX, 0, NULL);
673 
674 	if (phy_types & (I40E_CAP_PHY_TYPE_1000BASE_T))
675 		ifmedia_add(media, IFM_ETHER | IFM_1000_T, 0, NULL);
676 	if (phy_types & (I40E_CAP_PHY_TYPE_1000BASE_SX))
677 		ifmedia_add(media, IFM_ETHER | IFM_1000_SX, 0, NULL);
678 	if (phy_types & (I40E_CAP_PHY_TYPE_1000BASE_LX))
679 		ifmedia_add(media, IFM_ETHER | IFM_1000_LX, 0, NULL);
680 
681 	if (phy_types & (I40E_CAP_PHY_TYPE_2_5GBASE_T))
682 		ifmedia_add(media, IFM_ETHER | IFM_2500_T, 0, NULL);
683 
684 	if (phy_types & (I40E_CAP_PHY_TYPE_5GBASE_T))
685 		ifmedia_add(media, IFM_ETHER | IFM_5000_T, 0, NULL);
686 
687 	if (phy_types & (I40E_CAP_PHY_TYPE_XAUI) ||
688 	    phy_types & (I40E_CAP_PHY_TYPE_XFI) ||
689 	    phy_types & (I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU))
690 		ifmedia_add(media, IFM_ETHER | IFM_10G_TWINAX, 0, NULL);
691 
692 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_SR))
693 		ifmedia_add(media, IFM_ETHER | IFM_10G_SR, 0, NULL);
694 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_LR))
695 		ifmedia_add(media, IFM_ETHER | IFM_10G_LR, 0, NULL);
696 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_T))
697 		ifmedia_add(media, IFM_ETHER | IFM_10G_T, 0, NULL);
698 
699 	if (phy_types & (I40E_CAP_PHY_TYPE_40GBASE_CR4) ||
700 	    phy_types & (I40E_CAP_PHY_TYPE_40GBASE_CR4_CU) ||
701 	    phy_types & (I40E_CAP_PHY_TYPE_40GBASE_AOC) ||
702 	    phy_types & (I40E_CAP_PHY_TYPE_XLAUI) ||
703 	    phy_types & (I40E_CAP_PHY_TYPE_40GBASE_KR4))
704 		ifmedia_add(media, IFM_ETHER | IFM_40G_CR4, 0, NULL);
705 	if (phy_types & (I40E_CAP_PHY_TYPE_40GBASE_SR4))
706 		ifmedia_add(media, IFM_ETHER | IFM_40G_SR4, 0, NULL);
707 	if (phy_types & (I40E_CAP_PHY_TYPE_40GBASE_LR4))
708 		ifmedia_add(media, IFM_ETHER | IFM_40G_LR4, 0, NULL);
709 
710 	if (phy_types & (I40E_CAP_PHY_TYPE_1000BASE_KX))
711 		ifmedia_add(media, IFM_ETHER | IFM_1000_KX, 0, NULL);
712 
713 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_CR1_CU)
714 	    || phy_types & (I40E_CAP_PHY_TYPE_10GBASE_CR1))
715 		ifmedia_add(media, IFM_ETHER | IFM_10G_CR1, 0, NULL);
716 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_AOC))
717 		ifmedia_add(media, IFM_ETHER | IFM_10G_AOC, 0, NULL);
718 	if (phy_types & (I40E_CAP_PHY_TYPE_SFI))
719 		ifmedia_add(media, IFM_ETHER | IFM_10G_SFI, 0, NULL);
720 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_KX4))
721 		ifmedia_add(media, IFM_ETHER | IFM_10G_KX4, 0, NULL);
722 	if (phy_types & (I40E_CAP_PHY_TYPE_10GBASE_KR))
723 		ifmedia_add(media, IFM_ETHER | IFM_10G_KR, 0, NULL);
724 
725 	if (phy_types & (I40E_CAP_PHY_TYPE_20GBASE_KR2))
726 		ifmedia_add(media, IFM_ETHER | IFM_20G_KR2, 0, NULL);
727 
728 	if (phy_types & (I40E_CAP_PHY_TYPE_40GBASE_KR4))
729 		ifmedia_add(media, IFM_ETHER | IFM_40G_KR4, 0, NULL);
730 	if (phy_types & (I40E_CAP_PHY_TYPE_XLPPI))
731 		ifmedia_add(media, IFM_ETHER | IFM_40G_XLPPI, 0, NULL);
732 
733 	if (phy_types & (I40E_CAP_PHY_TYPE_25GBASE_KR))
734 		ifmedia_add(media, IFM_ETHER | IFM_25G_KR, 0, NULL);
735 	if (phy_types & (I40E_CAP_PHY_TYPE_25GBASE_CR))
736 		ifmedia_add(media, IFM_ETHER | IFM_25G_CR, 0, NULL);
737 	if (phy_types & (I40E_CAP_PHY_TYPE_25GBASE_SR))
738 		ifmedia_add(media, IFM_ETHER | IFM_25G_SR, 0, NULL);
739 	if (phy_types & (I40E_CAP_PHY_TYPE_25GBASE_LR))
740 		ifmedia_add(media, IFM_ETHER | IFM_25G_LR, 0, NULL);
741 	if (phy_types & (I40E_CAP_PHY_TYPE_25GBASE_AOC))
742 		ifmedia_add(media, IFM_ETHER | IFM_25G_AOC, 0, NULL);
743 	if (phy_types & (I40E_CAP_PHY_TYPE_25GBASE_ACC))
744 		ifmedia_add(media, IFM_ETHER | IFM_25G_ACC, 0, NULL);
745 }
746 
747 /*********************************************************************
748  *
749  *  Get Firmware Switch configuration
750  *	- this will need to be more robust when more complex
751  *	  switch configurations are enabled.
752  *
753  **********************************************************************/
754 int
755 ixl_switch_config(struct ixl_pf *pf)
756 {
757 	struct i40e_hw	*hw = &pf->hw;
758 	struct ixl_vsi	*vsi = &pf->vsi;
759 	device_t 	dev = iflib_get_dev(vsi->ctx);
760 	struct i40e_aqc_get_switch_config_resp *sw_config;
761 	u8	aq_buf[I40E_AQ_LARGE_BUF];
762 	int	ret;
763 	u16	next = 0;
764 
765 	memset(&aq_buf, 0, sizeof(aq_buf));
766 	sw_config = (struct i40e_aqc_get_switch_config_resp *)aq_buf;
767 	ret = i40e_aq_get_switch_config(hw, sw_config,
768 	    sizeof(aq_buf), &next, NULL);
769 	if (ret) {
770 		device_printf(dev, "aq_get_switch_config() failed, error %d,"
771 		    " aq_error %d\n", ret, pf->hw.aq.asq_last_status);
772 		return (ret);
773 	}
774 	if (pf->dbg_mask & IXL_DBG_SWITCH_INFO) {
775 		device_printf(dev,
776 		    "Switch config: header reported: %d in structure, %d total\n",
777 		    LE16_TO_CPU(sw_config->header.num_reported),
778 		    LE16_TO_CPU(sw_config->header.num_total));
779 		for (int i = 0;
780 		    i < LE16_TO_CPU(sw_config->header.num_reported); i++) {
781 			device_printf(dev,
782 			    "-> %d: type=%d seid=%d uplink=%d downlink=%d\n", i,
783 			    sw_config->element[i].element_type,
784 			    LE16_TO_CPU(sw_config->element[i].seid),
785 			    LE16_TO_CPU(sw_config->element[i].uplink_seid),
786 			    LE16_TO_CPU(sw_config->element[i].downlink_seid));
787 		}
788 	}
789 	/* Simplified due to a single VSI */
790 	vsi->uplink_seid = LE16_TO_CPU(sw_config->element[0].uplink_seid);
791 	vsi->downlink_seid = LE16_TO_CPU(sw_config->element[0].downlink_seid);
792 	vsi->seid = LE16_TO_CPU(sw_config->element[0].seid);
793 	return (ret);
794 }
795 
796 void
797 ixl_vsi_add_sysctls(struct ixl_vsi * vsi, const char * sysctl_name, bool queues_sysctls)
798 {
799 	struct sysctl_oid *tree;
800 	struct sysctl_oid_list *child;
801 	struct sysctl_oid_list *vsi_list;
802 
803 	tree = device_get_sysctl_tree(vsi->dev);
804 	child = SYSCTL_CHILDREN(tree);
805 	vsi->vsi_node = SYSCTL_ADD_NODE(&vsi->sysctl_ctx, child, OID_AUTO, sysctl_name,
806 			CTLFLAG_RD, NULL, "VSI Number");
807 
808 	vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
809 	ixl_add_sysctls_eth_stats(&vsi->sysctl_ctx, vsi_list, &vsi->eth_stats);
810 
811 	if (queues_sysctls)
812 		ixl_vsi_add_queues_stats(vsi, &vsi->sysctl_ctx);
813 }
814 
815 /*
816  * Used to set the Tx ITR value for all of the PF LAN VSI's queues.
817  * Writes to the ITR registers immediately.
818  */
819 static int
820 ixl_sysctl_pf_tx_itr(SYSCTL_HANDLER_ARGS)
821 {
822 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
823 	device_t dev = pf->dev;
824 	int error = 0;
825 	int requested_tx_itr;
826 
827 	requested_tx_itr = pf->tx_itr;
828 	error = sysctl_handle_int(oidp, &requested_tx_itr, 0, req);
829 	if ((error) || (req->newptr == NULL))
830 		return (error);
831 	if (pf->dynamic_tx_itr) {
832 		device_printf(dev,
833 		    "Cannot set TX itr value while dynamic TX itr is enabled\n");
834 		    return (EINVAL);
835 	}
836 	if (requested_tx_itr < 0 || requested_tx_itr > IXL_MAX_ITR) {
837 		device_printf(dev,
838 		    "Invalid TX itr value; value must be between 0 and %d\n",
839 		        IXL_MAX_ITR);
840 		return (EINVAL);
841 	}
842 
843 	pf->tx_itr = requested_tx_itr;
844 	ixl_configure_tx_itr(pf);
845 
846 	return (error);
847 }
848 
849 /*
850  * Used to set the Rx ITR value for all of the PF LAN VSI's queues.
851  * Writes to the ITR registers immediately.
852  */
853 static int
854 ixl_sysctl_pf_rx_itr(SYSCTL_HANDLER_ARGS)
855 {
856 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
857 	device_t dev = pf->dev;
858 	int error = 0;
859 	int requested_rx_itr;
860 
861 	requested_rx_itr = pf->rx_itr;
862 	error = sysctl_handle_int(oidp, &requested_rx_itr, 0, req);
863 	if ((error) || (req->newptr == NULL))
864 		return (error);
865 	if (pf->dynamic_rx_itr) {
866 		device_printf(dev,
867 		    "Cannot set RX itr value while dynamic RX itr is enabled\n");
868 		    return (EINVAL);
869 	}
870 	if (requested_rx_itr < 0 || requested_rx_itr > IXL_MAX_ITR) {
871 		device_printf(dev,
872 		    "Invalid RX itr value; value must be between 0 and %d\n",
873 		        IXL_MAX_ITR);
874 		return (EINVAL);
875 	}
876 
877 	pf->rx_itr = requested_rx_itr;
878 	ixl_configure_rx_itr(pf);
879 
880 	return (error);
881 }
882 
883 void
884 ixl_add_sysctls_mac_stats(struct sysctl_ctx_list *ctx,
885 	struct sysctl_oid_list *child,
886 	struct i40e_hw_port_stats *stats)
887 {
888 	struct sysctl_oid *stat_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO,
889 	    "mac", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "Mac Statistics");
890 	struct sysctl_oid_list *stat_list = SYSCTL_CHILDREN(stat_node);
891 
892 	struct i40e_eth_stats *eth_stats = &stats->eth;
893 	ixl_add_sysctls_eth_stats(ctx, stat_list, eth_stats);
894 
895 	struct ixl_sysctl_info ctls[] =
896 	{
897 		{&stats->crc_errors, "crc_errors", "CRC Errors"},
898 		{&stats->illegal_bytes, "illegal_bytes", "Illegal Byte Errors"},
899 		{&stats->mac_local_faults, "local_faults", "MAC Local Faults"},
900 		{&stats->mac_remote_faults, "remote_faults", "MAC Remote Faults"},
901 		{&stats->rx_length_errors, "rx_length_errors", "Receive Length Errors"},
902 		/* Packet Reception Stats */
903 		{&stats->rx_size_64, "rx_frames_64", "64 byte frames received"},
904 		{&stats->rx_size_127, "rx_frames_65_127", "65-127 byte frames received"},
905 		{&stats->rx_size_255, "rx_frames_128_255", "128-255 byte frames received"},
906 		{&stats->rx_size_511, "rx_frames_256_511", "256-511 byte frames received"},
907 		{&stats->rx_size_1023, "rx_frames_512_1023", "512-1023 byte frames received"},
908 		{&stats->rx_size_1522, "rx_frames_1024_1522", "1024-1522 byte frames received"},
909 		{&stats->rx_size_big, "rx_frames_big", "1523-9522 byte frames received"},
910 		{&stats->rx_undersize, "rx_undersize", "Undersized packets received"},
911 		{&stats->rx_fragments, "rx_fragmented", "Fragmented packets received"},
912 		{&stats->rx_oversize, "rx_oversized", "Oversized packets received"},
913 		{&stats->rx_jabber, "rx_jabber", "Received Jabber"},
914 		{&stats->checksum_error, "checksum_errors", "Checksum Errors"},
915 		/* Packet Transmission Stats */
916 		{&stats->tx_size_64, "tx_frames_64", "64 byte frames transmitted"},
917 		{&stats->tx_size_127, "tx_frames_65_127", "65-127 byte frames transmitted"},
918 		{&stats->tx_size_255, "tx_frames_128_255", "128-255 byte frames transmitted"},
919 		{&stats->tx_size_511, "tx_frames_256_511", "256-511 byte frames transmitted"},
920 		{&stats->tx_size_1023, "tx_frames_512_1023", "512-1023 byte frames transmitted"},
921 		{&stats->tx_size_1522, "tx_frames_1024_1522", "1024-1522 byte frames transmitted"},
922 		{&stats->tx_size_big, "tx_frames_big", "1523-9522 byte frames transmitted"},
923 		/* Flow control */
924 		{&stats->link_xon_tx, "xon_txd", "Link XON transmitted"},
925 		{&stats->link_xon_rx, "xon_recvd", "Link XON received"},
926 		{&stats->link_xoff_tx, "xoff_txd", "Link XOFF transmitted"},
927 		{&stats->link_xoff_rx, "xoff_recvd", "Link XOFF received"},
928 		/* End */
929 		{0,0,0}
930 	};
931 
932 	struct ixl_sysctl_info *entry = ctls;
933 	while (entry->stat != 0)
934 	{
935 		SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, entry->name,
936 				CTLFLAG_RD, entry->stat,
937 				entry->description);
938 		entry++;
939 	}
940 }
941 
942 void
943 ixl_set_rss_key(struct ixl_pf *pf)
944 {
945 	struct i40e_hw *hw = &pf->hw;
946 	struct ixl_vsi *vsi = &pf->vsi;
947 	device_t	dev = pf->dev;
948 	u32 rss_seed[IXL_RSS_KEY_SIZE_REG];
949 	enum i40e_status_code status;
950 
951 #ifdef RSS
952         /* Fetch the configured RSS key */
953         rss_getkey((uint8_t *) &rss_seed);
954 #else
955 	ixl_get_default_rss_key(rss_seed);
956 #endif
957 	/* Fill out hash function seed */
958 	if (hw->mac.type == I40E_MAC_X722) {
959 		struct i40e_aqc_get_set_rss_key_data key_data;
960 		bcopy(rss_seed, &key_data, 52);
961 		status = i40e_aq_set_rss_key(hw, vsi->vsi_num, &key_data);
962 		if (status)
963 			device_printf(dev,
964 			    "i40e_aq_set_rss_key status %s, error %s\n",
965 			    i40e_stat_str(hw, status),
966 			    i40e_aq_str(hw, hw->aq.asq_last_status));
967 	} else {
968 		for (int i = 0; i < IXL_RSS_KEY_SIZE_REG; i++)
969 			i40e_write_rx_ctl(hw, I40E_PFQF_HKEY(i), rss_seed[i]);
970 	}
971 }
972 
973 /*
974  * Configure enabled PCTYPES for RSS.
975  */
976 void
977 ixl_set_rss_pctypes(struct ixl_pf *pf)
978 {
979 	struct i40e_hw *hw = &pf->hw;
980 	u64		set_hena = 0, hena;
981 
982 #ifdef RSS
983 	u32		rss_hash_config;
984 
985 	rss_hash_config = rss_gethashconfig();
986 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
987                 set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
988 	if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
989                 set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
990 	if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
991                 set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP);
992 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
993                 set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
994 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
995 		set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
996 	if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
997                 set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
998         if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
999                 set_hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP);
1000 #else
1001 	if (hw->mac.type == I40E_MAC_X722)
1002 		set_hena = IXL_DEFAULT_RSS_HENA_X722;
1003 	else
1004 		set_hena = IXL_DEFAULT_RSS_HENA_XL710;
1005 #endif
1006 	hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
1007 	    ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
1008 	hena |= set_hena;
1009 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), (u32)hena);
1010 	i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), (u32)(hena >> 32));
1011 
1012 }
1013 
1014 /*
1015 ** Setup the PF's RSS parameters.
1016 */
1017 void
1018 ixl_config_rss(struct ixl_pf *pf)
1019 {
1020 	ixl_set_rss_key(pf);
1021 	ixl_set_rss_pctypes(pf);
1022 	ixl_set_rss_hlut(pf);
1023 }
1024 
1025 /*
1026  * In some firmware versions there is default MAC/VLAN filter
1027  * configured which interferes with filters managed by driver.
1028  * Make sure it's removed.
1029  */
1030 void
1031 ixl_del_default_hw_filters(struct ixl_vsi *vsi)
1032 {
1033 	struct i40e_aqc_remove_macvlan_element_data e;
1034 
1035 	bzero(&e, sizeof(e));
1036 	bcopy(vsi->hw->mac.perm_addr, e.mac_addr, ETHER_ADDR_LEN);
1037 	e.vlan_tag = 0;
1038 	e.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
1039 	i40e_aq_remove_macvlan(vsi->hw, vsi->seid, &e, 1, NULL);
1040 
1041 	bzero(&e, sizeof(e));
1042 	bcopy(vsi->hw->mac.perm_addr, e.mac_addr, ETHER_ADDR_LEN);
1043 	e.vlan_tag = 0;
1044 	e.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH |
1045 		I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
1046 	i40e_aq_remove_macvlan(vsi->hw, vsi->seid, &e, 1, NULL);
1047 }
1048 
1049 /*
1050 ** Initialize filter list and add filters that the hardware
1051 ** needs to know about.
1052 **
1053 ** Requires VSI's seid to be set before calling.
1054 */
1055 void
1056 ixl_init_filters(struct ixl_vsi *vsi)
1057 {
1058 	struct ixl_pf *pf = (struct ixl_pf *)vsi->back;
1059 
1060 	ixl_dbg_filter(pf, "%s: start\n", __func__);
1061 
1062 	/* Initialize mac filter list for VSI */
1063 	LIST_INIT(&vsi->ftl);
1064 	vsi->num_hw_filters = 0;
1065 
1066 	/* Receive broadcast Ethernet frames */
1067 	i40e_aq_set_vsi_broadcast(&pf->hw, vsi->seid, TRUE, NULL);
1068 
1069 	if (IXL_VSI_IS_VF(vsi))
1070 		return;
1071 
1072 	ixl_del_default_hw_filters(vsi);
1073 
1074 	ixl_add_filter(vsi, vsi->hw->mac.addr, IXL_VLAN_ANY);
1075 
1076 	/*
1077 	 * Prevent Tx flow control frames from being sent out by
1078 	 * non-firmware transmitters.
1079 	 * This affects every VSI in the PF.
1080 	 */
1081 #ifndef IXL_DEBUG_FC
1082 	i40e_add_filter_to_drop_tx_flow_control_frames(vsi->hw, vsi->seid);
1083 #else
1084 	if (pf->enable_tx_fc_filter)
1085 		i40e_add_filter_to_drop_tx_flow_control_frames(vsi->hw, vsi->seid);
1086 #endif
1087 }
1088 
1089 void
1090 ixl_reconfigure_filters(struct ixl_vsi *vsi)
1091 {
1092 	struct i40e_hw *hw = vsi->hw;
1093 	struct ixl_ftl_head tmp;
1094 	int cnt;
1095 
1096 	/*
1097 	 * The ixl_add_hw_filters function adds filters configured
1098 	 * in HW to a list in VSI. Move all filters to a temporary
1099 	 * list to avoid corrupting it by concatenating to itself.
1100 	 */
1101 	LIST_INIT(&tmp);
1102 	LIST_CONCAT(&tmp, &vsi->ftl, ixl_mac_filter, ftle);
1103 	cnt = vsi->num_hw_filters;
1104 	vsi->num_hw_filters = 0;
1105 
1106 	ixl_add_hw_filters(vsi, &tmp, cnt);
1107 
1108 	/* Filter could be removed if MAC address was changed */
1109 	ixl_add_filter(vsi, hw->mac.addr, IXL_VLAN_ANY);
1110 
1111 	if ((if_getcapenable(vsi->ifp) & IFCAP_VLAN_HWFILTER) == 0)
1112 		return;
1113 	/*
1114 	 * VLAN HW filtering is enabled, make sure that filters
1115 	 * for all registered VLAN tags are configured
1116 	 */
1117 	ixl_add_vlan_filters(vsi, hw->mac.addr);
1118 }
1119 
1120 /*
1121  * This routine adds a MAC/VLAN filter to the software filter
1122  * list, then adds that new filter to the HW if it doesn't already
1123  * exist in the SW filter list.
1124  */
1125 void
1126 ixl_add_filter(struct ixl_vsi *vsi, const u8 *macaddr, s16 vlan)
1127 {
1128 	struct ixl_mac_filter	*f, *tmp;
1129 	struct ixl_pf		*pf;
1130 	device_t		dev;
1131 	struct ixl_ftl_head	to_add;
1132 	int			to_add_cnt;
1133 
1134 	pf = vsi->back;
1135 	dev = pf->dev;
1136 	to_add_cnt = 1;
1137 
1138 	ixl_dbg_filter(pf, "ixl_add_filter: " MAC_FORMAT ", vlan %4d\n",
1139 	    MAC_FORMAT_ARGS(macaddr), vlan);
1140 
1141 	/* Does one already exist */
1142 	f = ixl_find_filter(&vsi->ftl, macaddr, vlan);
1143 	if (f != NULL)
1144 		return;
1145 
1146 	LIST_INIT(&to_add);
1147 	f = ixl_new_filter(&to_add, macaddr, vlan);
1148 	if (f == NULL) {
1149 		device_printf(dev, "WARNING: no filter available!!\n");
1150 		return;
1151 	}
1152 	if (f->vlan != IXL_VLAN_ANY)
1153 		f->flags |= IXL_FILTER_VLAN;
1154 	else
1155 		vsi->num_macs++;
1156 
1157 	/*
1158 	** Is this the first vlan being registered, if so we
1159 	** need to remove the ANY filter that indicates we are
1160 	** not in a vlan, and replace that with a 0 filter.
1161 	*/
1162 	if ((vlan != IXL_VLAN_ANY) && (vsi->num_vlans == 1)) {
1163 		tmp = ixl_find_filter(&vsi->ftl, macaddr, IXL_VLAN_ANY);
1164 		if (tmp != NULL) {
1165 			struct ixl_ftl_head to_del;
1166 
1167 			/* Prepare new filter first to avoid removing
1168 			 * VLAN_ANY filter if allocation fails */
1169 			f = ixl_new_filter(&to_add, macaddr, 0);
1170 			if (f == NULL) {
1171 				device_printf(dev, "WARNING: no filter available!!\n");
1172 				free(LIST_FIRST(&to_add), M_IXL);
1173 				return;
1174 			}
1175 			to_add_cnt++;
1176 
1177 			LIST_REMOVE(tmp, ftle);
1178 			LIST_INIT(&to_del);
1179 			LIST_INSERT_HEAD(&to_del, tmp, ftle);
1180 			ixl_del_hw_filters(vsi, &to_del, 1);
1181 		}
1182 	}
1183 
1184 	ixl_add_hw_filters(vsi, &to_add, to_add_cnt);
1185 }
1186 
1187 /**
1188  * ixl_add_vlan_filters - Add MAC/VLAN filters for all registered VLANs
1189  * @vsi: pointer to VSI
1190  * @macaddr: MAC address
1191  *
1192  * Adds MAC/VLAN filter for each VLAN configured on the interface
1193  * if there is enough HW filters. Otherwise adds a single filter
1194  * for all tagged and untagged frames to allow all configured VLANs
1195  * to recieve traffic.
1196  */
1197 void
1198 ixl_add_vlan_filters(struct ixl_vsi *vsi, const u8 *macaddr)
1199 {
1200 	struct ixl_ftl_head to_add;
1201 	struct ixl_mac_filter *f;
1202 	int to_add_cnt = 0;
1203 	int i, vlan = 0;
1204 
1205 	if (vsi->num_vlans == 0 || vsi->num_vlans > IXL_MAX_VLAN_FILTERS) {
1206 		ixl_add_filter(vsi, macaddr, IXL_VLAN_ANY);
1207 		return;
1208 	}
1209 	LIST_INIT(&to_add);
1210 
1211 	/* Add filter for untagged frames if it does not exist yet */
1212 	f = ixl_find_filter(&vsi->ftl, macaddr, 0);
1213 	if (f == NULL) {
1214 		f = ixl_new_filter(&to_add, macaddr, 0);
1215 		if (f == NULL) {
1216 			device_printf(vsi->dev, "WARNING: no filter available!!\n");
1217 			return;
1218 		}
1219 		to_add_cnt++;
1220 	}
1221 
1222 	for (i = 1; i < EVL_VLID_MASK; i = vlan + 1) {
1223 		bit_ffs_at(vsi->vlans_map, i, IXL_VLANS_MAP_LEN, &vlan);
1224 		if (vlan == -1)
1225 			break;
1226 
1227 		/* Does one already exist */
1228 		f = ixl_find_filter(&vsi->ftl, macaddr, vlan);
1229 		if (f != NULL)
1230 			continue;
1231 
1232 		f = ixl_new_filter(&to_add, macaddr, vlan);
1233 		if (f == NULL) {
1234 			device_printf(vsi->dev, "WARNING: no filter available!!\n");
1235 			ixl_free_filters(&to_add);
1236 			return;
1237 		}
1238 		to_add_cnt++;
1239 	}
1240 
1241 	ixl_add_hw_filters(vsi, &to_add, to_add_cnt);
1242 }
1243 
1244 void
1245 ixl_del_filter(struct ixl_vsi *vsi, const u8 *macaddr, s16 vlan)
1246 {
1247 	struct ixl_mac_filter *f, *tmp;
1248 	struct ixl_ftl_head ftl_head;
1249 	int to_del_cnt = 1;
1250 
1251 	ixl_dbg_filter((struct ixl_pf *)vsi->back,
1252 	    "ixl_del_filter: " MAC_FORMAT ", vlan %4d\n",
1253 	    MAC_FORMAT_ARGS(macaddr), vlan);
1254 
1255 	f = ixl_find_filter(&vsi->ftl, macaddr, vlan);
1256 	if (f == NULL)
1257 		return;
1258 
1259 	LIST_REMOVE(f, ftle);
1260 	LIST_INIT(&ftl_head);
1261 	LIST_INSERT_HEAD(&ftl_head, f, ftle);
1262 	if (f->vlan == IXL_VLAN_ANY && (f->flags & IXL_FILTER_VLAN) != 0)
1263 		vsi->num_macs--;
1264 
1265 	/* If this is not the last vlan just remove the filter */
1266 	if (vlan == IXL_VLAN_ANY || vsi->num_vlans > 0) {
1267 		ixl_del_hw_filters(vsi, &ftl_head, to_del_cnt);
1268 		return;
1269 	}
1270 
1271 	/* It's the last vlan, we need to switch back to a non-vlan filter */
1272 	tmp = ixl_find_filter(&vsi->ftl, macaddr, 0);
1273 	if (tmp != NULL) {
1274 		LIST_REMOVE(tmp, ftle);
1275 		LIST_INSERT_AFTER(f, tmp, ftle);
1276 		to_del_cnt++;
1277 	}
1278 	ixl_del_hw_filters(vsi, &ftl_head, to_del_cnt);
1279 
1280 	ixl_add_filter(vsi, macaddr, IXL_VLAN_ANY);
1281 }
1282 
1283 /**
1284  * ixl_del_all_vlan_filters - Delete all VLAN filters with given MAC
1285  * @vsi: VSI which filters need to be removed
1286  * @macaddr: MAC address
1287  *
1288  * Remove all MAC/VLAN filters with a given MAC address. For multicast
1289  * addresses there is always single filter for all VLANs used (IXL_VLAN_ANY)
1290  * so skip them to speed up processing. Those filters should be removed
1291  * using ixl_del_filter function.
1292  */
1293 void
1294 ixl_del_all_vlan_filters(struct ixl_vsi *vsi, const u8 *macaddr)
1295 {
1296 	struct ixl_mac_filter *f, *tmp;
1297 	struct ixl_ftl_head to_del;
1298 	int to_del_cnt = 0;
1299 
1300 	LIST_INIT(&to_del);
1301 
1302 	LIST_FOREACH_SAFE(f, &vsi->ftl, ftle, tmp) {
1303 		if ((f->flags & IXL_FILTER_MC) != 0 ||
1304 		    !ixl_ether_is_equal(f->macaddr, macaddr))
1305 			continue;
1306 
1307 		LIST_REMOVE(f, ftle);
1308 		LIST_INSERT_HEAD(&to_del, f, ftle);
1309 		to_del_cnt++;
1310 	}
1311 
1312 	ixl_dbg_filter((struct ixl_pf *)vsi->back,
1313 	    "%s: " MAC_FORMAT ", to_del_cnt: %d\n",
1314 	    __func__, MAC_FORMAT_ARGS(macaddr), to_del_cnt);
1315 	if (to_del_cnt > 0)
1316 		ixl_del_hw_filters(vsi, &to_del, to_del_cnt);
1317 }
1318 
1319 /*
1320 ** Find the filter with both matching mac addr and vlan id
1321 */
1322 struct ixl_mac_filter *
1323 ixl_find_filter(struct ixl_ftl_head *headp, const u8 *macaddr, s16 vlan)
1324 {
1325 	struct ixl_mac_filter	*f;
1326 
1327 	LIST_FOREACH(f, headp, ftle) {
1328 		if (ixl_ether_is_equal(f->macaddr, macaddr) &&
1329 		    (f->vlan == vlan)) {
1330 			return (f);
1331 		}
1332 	}
1333 
1334 	return (NULL);
1335 }
1336 
1337 /*
1338 ** This routine takes additions to the vsi filter
1339 ** table and creates an Admin Queue call to create
1340 ** the filters in the hardware.
1341 */
1342 void
1343 ixl_add_hw_filters(struct ixl_vsi *vsi, struct ixl_ftl_head *to_add, int cnt)
1344 {
1345 	struct i40e_aqc_add_macvlan_element_data *a, *b;
1346 	struct ixl_mac_filter	*f, *fn;
1347 	struct ixl_pf		*pf;
1348 	struct i40e_hw		*hw;
1349 	device_t		dev;
1350 	enum i40e_status_code	status;
1351 	int			j = 0;
1352 
1353 	pf = vsi->back;
1354 	dev = vsi->dev;
1355 	hw = &pf->hw;
1356 
1357 	ixl_dbg_filter(pf, "ixl_add_hw_filters: cnt: %d\n", cnt);
1358 
1359 	if (cnt < 1) {
1360 		ixl_dbg_info(pf, "ixl_add_hw_filters: cnt == 0\n");
1361 		return;
1362 	}
1363 
1364 	a = malloc(sizeof(struct i40e_aqc_add_macvlan_element_data) * cnt,
1365 	    M_IXL, M_NOWAIT | M_ZERO);
1366 	if (a == NULL) {
1367 		device_printf(dev, "add_hw_filters failed to get memory\n");
1368 		return;
1369 	}
1370 
1371 	LIST_FOREACH(f, to_add, ftle) {
1372 		b = &a[j]; // a pox on fvl long names :)
1373 		bcopy(f->macaddr, b->mac_addr, ETHER_ADDR_LEN);
1374 		if (f->vlan == IXL_VLAN_ANY) {
1375 			b->vlan_tag = 0;
1376 			b->flags = I40E_AQC_MACVLAN_ADD_IGNORE_VLAN;
1377 		} else {
1378 			b->vlan_tag = f->vlan;
1379 			b->flags = 0;
1380 		}
1381 		b->flags |= I40E_AQC_MACVLAN_ADD_PERFECT_MATCH;
1382 		ixl_dbg_filter(pf, "ADD: " MAC_FORMAT "\n",
1383 		    MAC_FORMAT_ARGS(f->macaddr));
1384 
1385 		if (++j == cnt)
1386 			break;
1387 	}
1388 	if (j != cnt) {
1389 		/* Something went wrong */
1390 		device_printf(dev,
1391 		    "%s ERROR: list of filters to short expected: %d, found: %d\n",
1392 		    __func__, cnt, j);
1393 		ixl_free_filters(to_add);
1394 		goto out_free;
1395 	}
1396 
1397 	status = i40e_aq_add_macvlan(hw, vsi->seid, a, j, NULL);
1398 	if (status == I40E_SUCCESS) {
1399 		LIST_CONCAT(&vsi->ftl, to_add, ixl_mac_filter, ftle);
1400 		vsi->num_hw_filters += j;
1401 		goto out_free;
1402 	}
1403 
1404 	device_printf(dev,
1405 	    "i40e_aq_add_macvlan status %s, error %s\n",
1406 	    i40e_stat_str(hw, status),
1407 	    i40e_aq_str(hw, hw->aq.asq_last_status));
1408 	j = 0;
1409 
1410 	/* Verify which filters were actually configured in HW
1411 	 * and add them to the list */
1412 	LIST_FOREACH_SAFE(f, to_add, ftle, fn) {
1413 		LIST_REMOVE(f, ftle);
1414 		if (a[j].match_method == I40E_AQC_MM_ERR_NO_RES) {
1415 			ixl_dbg_filter(pf,
1416 			    "%s filter " MAC_FORMAT " VTAG: %d not added\n",
1417 			    __func__,
1418 			    MAC_FORMAT_ARGS(f->macaddr),
1419 			    f->vlan);
1420 			free(f, M_IXL);
1421 		} else {
1422 			LIST_INSERT_HEAD(&vsi->ftl, f, ftle);
1423 			vsi->num_hw_filters++;
1424 		}
1425 		j++;
1426 	}
1427 
1428 out_free:
1429 	free(a, M_IXL);
1430 }
1431 
1432 /*
1433 ** This routine takes removals in the vsi filter
1434 ** table and creates an Admin Queue call to delete
1435 ** the filters in the hardware.
1436 */
1437 void
1438 ixl_del_hw_filters(struct ixl_vsi *vsi, struct ixl_ftl_head *to_del, int cnt)
1439 {
1440 	struct i40e_aqc_remove_macvlan_element_data *d, *e;
1441 	struct ixl_pf		*pf;
1442 	struct i40e_hw		*hw;
1443 	device_t		dev;
1444 	struct ixl_mac_filter	*f, *f_temp;
1445 	enum i40e_status_code	status;
1446 	int			j = 0;
1447 
1448 	pf = vsi->back;
1449 	hw = &pf->hw;
1450 	dev = vsi->dev;
1451 
1452 	ixl_dbg_filter(pf, "%s: start, cnt: %d\n", __func__, cnt);
1453 
1454 	d = malloc(sizeof(struct i40e_aqc_remove_macvlan_element_data) * cnt,
1455 	    M_IXL, M_NOWAIT | M_ZERO);
1456 	if (d == NULL) {
1457 		device_printf(dev, "%s: failed to get memory\n", __func__);
1458 		return;
1459 	}
1460 
1461 	LIST_FOREACH_SAFE(f, to_del, ftle, f_temp) {
1462 		e = &d[j]; // a pox on fvl long names :)
1463 		bcopy(f->macaddr, e->mac_addr, ETHER_ADDR_LEN);
1464 		e->flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
1465 		if (f->vlan == IXL_VLAN_ANY) {
1466 			e->vlan_tag = 0;
1467 			e->flags |= I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
1468 		} else {
1469 			e->vlan_tag = f->vlan;
1470 		}
1471 
1472 		ixl_dbg_filter(pf, "DEL: " MAC_FORMAT "\n",
1473 		    MAC_FORMAT_ARGS(f->macaddr));
1474 
1475 		/* delete entry from the list */
1476 		LIST_REMOVE(f, ftle);
1477 		free(f, M_IXL);
1478 		if (++j == cnt)
1479 			break;
1480 	}
1481 	if (j != cnt || !LIST_EMPTY(to_del)) {
1482 		/* Something went wrong */
1483 		device_printf(dev,
1484 		    "%s ERROR: wrong size of list of filters, expected: %d, found: %d\n",
1485 		    __func__, cnt, j);
1486 		ixl_free_filters(to_del);
1487 		goto out_free;
1488 	}
1489 	status = i40e_aq_remove_macvlan(hw, vsi->seid, d, j, NULL);
1490 	if (status) {
1491 		device_printf(dev,
1492 		    "%s: i40e_aq_remove_macvlan status %s, error %s\n",
1493 		    __func__, i40e_stat_str(hw, status),
1494 		    i40e_aq_str(hw, hw->aq.asq_last_status));
1495 		for (int i = 0; i < j; i++) {
1496 			if (d[i].error_code == 0)
1497 				continue;
1498 			device_printf(dev,
1499 			    "%s Filter does not exist " MAC_FORMAT " VTAG: %d\n",
1500 			    __func__, MAC_FORMAT_ARGS(d[i].mac_addr),
1501 			    d[i].vlan_tag);
1502 		}
1503 	}
1504 
1505 	vsi->num_hw_filters -= j;
1506 
1507 out_free:
1508 	free(d, M_IXL);
1509 
1510 	ixl_dbg_filter(pf, "%s: end\n", __func__);
1511 }
1512 
1513 int
1514 ixl_enable_tx_ring(struct ixl_pf *pf, struct ixl_pf_qtag *qtag, u16 vsi_qidx)
1515 {
1516 	struct i40e_hw	*hw = &pf->hw;
1517 	int		error = 0;
1518 	u32		reg;
1519 	u16		pf_qidx;
1520 
1521 	pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
1522 
1523 	ixl_dbg(pf, IXL_DBG_EN_DIS,
1524 	    "Enabling PF TX ring %4d / VSI TX ring %4d...\n",
1525 	    pf_qidx, vsi_qidx);
1526 
1527 	i40e_pre_tx_queue_cfg(hw, pf_qidx, TRUE);
1528 
1529 	reg = rd32(hw, I40E_QTX_ENA(pf_qidx));
1530 	reg |= I40E_QTX_ENA_QENA_REQ_MASK |
1531 	    I40E_QTX_ENA_QENA_STAT_MASK;
1532 	wr32(hw, I40E_QTX_ENA(pf_qidx), reg);
1533 	/* Verify the enable took */
1534 	for (int j = 0; j < 10; j++) {
1535 		reg = rd32(hw, I40E_QTX_ENA(pf_qidx));
1536 		if (reg & I40E_QTX_ENA_QENA_STAT_MASK)
1537 			break;
1538 		i40e_usec_delay(10);
1539 	}
1540 	if ((reg & I40E_QTX_ENA_QENA_STAT_MASK) == 0) {
1541 		device_printf(pf->dev, "TX queue %d still disabled!\n",
1542 		    pf_qidx);
1543 		error = ETIMEDOUT;
1544 	}
1545 
1546 	return (error);
1547 }
1548 
1549 int
1550 ixl_enable_rx_ring(struct ixl_pf *pf, struct ixl_pf_qtag *qtag, u16 vsi_qidx)
1551 {
1552 	struct i40e_hw	*hw = &pf->hw;
1553 	int		error = 0;
1554 	u32		reg;
1555 	u16		pf_qidx;
1556 
1557 	pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
1558 
1559 	ixl_dbg(pf, IXL_DBG_EN_DIS,
1560 	    "Enabling PF RX ring %4d / VSI RX ring %4d...\n",
1561 	    pf_qidx, vsi_qidx);
1562 
1563 	reg = rd32(hw, I40E_QRX_ENA(pf_qidx));
1564 	reg |= I40E_QRX_ENA_QENA_REQ_MASK |
1565 	    I40E_QRX_ENA_QENA_STAT_MASK;
1566 	wr32(hw, I40E_QRX_ENA(pf_qidx), reg);
1567 	/* Verify the enable took */
1568 	for (int j = 0; j < 10; j++) {
1569 		reg = rd32(hw, I40E_QRX_ENA(pf_qidx));
1570 		if (reg & I40E_QRX_ENA_QENA_STAT_MASK)
1571 			break;
1572 		i40e_usec_delay(10);
1573 	}
1574 	if ((reg & I40E_QRX_ENA_QENA_STAT_MASK) == 0) {
1575 		device_printf(pf->dev, "RX queue %d still disabled!\n",
1576 		    pf_qidx);
1577 		error = ETIMEDOUT;
1578 	}
1579 
1580 	return (error);
1581 }
1582 
1583 int
1584 ixl_enable_ring(struct ixl_pf *pf, struct ixl_pf_qtag *qtag, u16 vsi_qidx)
1585 {
1586 	int error = 0;
1587 
1588 	error = ixl_enable_tx_ring(pf, qtag, vsi_qidx);
1589 	/* Called function already prints error message */
1590 	if (error)
1591 		return (error);
1592 	error = ixl_enable_rx_ring(pf, qtag, vsi_qidx);
1593 	return (error);
1594 }
1595 
1596 /*
1597  * Returns error on first ring that is detected hung.
1598  */
1599 int
1600 ixl_disable_tx_ring(struct ixl_pf *pf, struct ixl_pf_qtag *qtag, u16 vsi_qidx)
1601 {
1602 	struct i40e_hw	*hw = &pf->hw;
1603 	int		error = 0;
1604 	u32		reg;
1605 	u16		pf_qidx;
1606 
1607 	pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
1608 
1609 	ixl_dbg(pf, IXL_DBG_EN_DIS,
1610 	    "Disabling PF TX ring %4d / VSI TX ring %4d...\n",
1611 	    pf_qidx, vsi_qidx);
1612 
1613 	i40e_pre_tx_queue_cfg(hw, pf_qidx, FALSE);
1614 	i40e_usec_delay(500);
1615 
1616 	reg = rd32(hw, I40E_QTX_ENA(pf_qidx));
1617 	reg &= ~I40E_QTX_ENA_QENA_REQ_MASK;
1618 	wr32(hw, I40E_QTX_ENA(pf_qidx), reg);
1619 	/* Verify the disable took */
1620 	for (int j = 0; j < 10; j++) {
1621 		reg = rd32(hw, I40E_QTX_ENA(pf_qidx));
1622 		if (!(reg & I40E_QTX_ENA_QENA_STAT_MASK))
1623 			break;
1624 		i40e_msec_delay(10);
1625 	}
1626 	if (reg & I40E_QTX_ENA_QENA_STAT_MASK) {
1627 		device_printf(pf->dev, "TX queue %d still enabled!\n",
1628 		    pf_qidx);
1629 		error = ETIMEDOUT;
1630 	}
1631 
1632 	return (error);
1633 }
1634 
1635 /*
1636  * Returns error on first ring that is detected hung.
1637  */
1638 int
1639 ixl_disable_rx_ring(struct ixl_pf *pf, struct ixl_pf_qtag *qtag, u16 vsi_qidx)
1640 {
1641 	struct i40e_hw	*hw = &pf->hw;
1642 	int		error = 0;
1643 	u32		reg;
1644 	u16		pf_qidx;
1645 
1646 	pf_qidx = ixl_pf_qidx_from_vsi_qidx(qtag, vsi_qidx);
1647 
1648 	ixl_dbg(pf, IXL_DBG_EN_DIS,
1649 	    "Disabling PF RX ring %4d / VSI RX ring %4d...\n",
1650 	    pf_qidx, vsi_qidx);
1651 
1652 	reg = rd32(hw, I40E_QRX_ENA(pf_qidx));
1653 	reg &= ~I40E_QRX_ENA_QENA_REQ_MASK;
1654 	wr32(hw, I40E_QRX_ENA(pf_qidx), reg);
1655 	/* Verify the disable took */
1656 	for (int j = 0; j < 10; j++) {
1657 		reg = rd32(hw, I40E_QRX_ENA(pf_qidx));
1658 		if (!(reg & I40E_QRX_ENA_QENA_STAT_MASK))
1659 			break;
1660 		i40e_msec_delay(10);
1661 	}
1662 	if (reg & I40E_QRX_ENA_QENA_STAT_MASK) {
1663 		device_printf(pf->dev, "RX queue %d still enabled!\n",
1664 		    pf_qidx);
1665 		error = ETIMEDOUT;
1666 	}
1667 
1668 	return (error);
1669 }
1670 
1671 int
1672 ixl_disable_ring(struct ixl_pf *pf, struct ixl_pf_qtag *qtag, u16 vsi_qidx)
1673 {
1674 	int error = 0;
1675 
1676 	error = ixl_disable_tx_ring(pf, qtag, vsi_qidx);
1677 	/* Called function already prints error message */
1678 	if (error)
1679 		return (error);
1680 	error = ixl_disable_rx_ring(pf, qtag, vsi_qidx);
1681 	return (error);
1682 }
1683 
1684 static void
1685 ixl_handle_tx_mdd_event(struct ixl_pf *pf)
1686 {
1687 	struct i40e_hw *hw = &pf->hw;
1688 	device_t dev = pf->dev;
1689 	struct ixl_vf *vf;
1690 	bool mdd_detected = false;
1691 	bool pf_mdd_detected = false;
1692 	bool vf_mdd_detected = false;
1693 	u16 vf_num, queue;
1694 	u8 pf_num, event;
1695 	u8 pf_mdet_num, vp_mdet_num;
1696 	u32 reg;
1697 
1698 	/* find what triggered the MDD event */
1699 	reg = rd32(hw, I40E_GL_MDET_TX);
1700 	if (reg & I40E_GL_MDET_TX_VALID_MASK) {
1701 		pf_num = (reg & I40E_GL_MDET_TX_PF_NUM_MASK) >>
1702 		    I40E_GL_MDET_TX_PF_NUM_SHIFT;
1703 		vf_num = (reg & I40E_GL_MDET_TX_VF_NUM_MASK) >>
1704 		    I40E_GL_MDET_TX_VF_NUM_SHIFT;
1705 		event = (reg & I40E_GL_MDET_TX_EVENT_MASK) >>
1706 		    I40E_GL_MDET_TX_EVENT_SHIFT;
1707 		queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK) >>
1708 		    I40E_GL_MDET_TX_QUEUE_SHIFT;
1709 		wr32(hw, I40E_GL_MDET_TX, 0xffffffff);
1710 		mdd_detected = true;
1711 	}
1712 
1713 	if (!mdd_detected)
1714 		return;
1715 
1716 	reg = rd32(hw, I40E_PF_MDET_TX);
1717 	if (reg & I40E_PF_MDET_TX_VALID_MASK) {
1718 		wr32(hw, I40E_PF_MDET_TX, 0xFFFF);
1719 		pf_mdet_num = hw->pf_id;
1720 		pf_mdd_detected = true;
1721 	}
1722 
1723 	/* Check if MDD was caused by a VF */
1724 	for (int i = 0; i < pf->num_vfs; i++) {
1725 		vf = &(pf->vfs[i]);
1726 		reg = rd32(hw, I40E_VP_MDET_TX(i));
1727 		if (reg & I40E_VP_MDET_TX_VALID_MASK) {
1728 			wr32(hw, I40E_VP_MDET_TX(i), 0xFFFF);
1729 			vp_mdet_num = i;
1730 			vf->num_mdd_events++;
1731 			vf_mdd_detected = true;
1732 		}
1733 	}
1734 
1735 	/* Print out an error message */
1736 	if (vf_mdd_detected && pf_mdd_detected)
1737 		device_printf(dev,
1738 		    "Malicious Driver Detection event %d"
1739 		    " on TX queue %d, pf number %d (PF-%d), vf number %d (VF-%d)\n",
1740 		    event, queue, pf_num, pf_mdet_num, vf_num, vp_mdet_num);
1741 	else if (vf_mdd_detected && !pf_mdd_detected)
1742 		device_printf(dev,
1743 		    "Malicious Driver Detection event %d"
1744 		    " on TX queue %d, pf number %d, vf number %d (VF-%d)\n",
1745 		    event, queue, pf_num, vf_num, vp_mdet_num);
1746 	else if (!vf_mdd_detected && pf_mdd_detected)
1747 		device_printf(dev,
1748 		    "Malicious Driver Detection event %d"
1749 		    " on TX queue %d, pf number %d (PF-%d)\n",
1750 		    event, queue, pf_num, pf_mdet_num);
1751 	/* Theoretically shouldn't happen */
1752 	else
1753 		device_printf(dev,
1754 		    "TX Malicious Driver Detection event (unknown)\n");
1755 }
1756 
1757 static void
1758 ixl_handle_rx_mdd_event(struct ixl_pf *pf)
1759 {
1760 	struct i40e_hw *hw = &pf->hw;
1761 	device_t dev = pf->dev;
1762 	struct ixl_vf *vf;
1763 	bool mdd_detected = false;
1764 	bool pf_mdd_detected = false;
1765 	bool vf_mdd_detected = false;
1766 	u16 queue;
1767 	u8 pf_num, event;
1768 	u8 pf_mdet_num, vp_mdet_num;
1769 	u32 reg;
1770 
1771 	/*
1772 	 * GL_MDET_RX doesn't contain VF number information, unlike
1773 	 * GL_MDET_TX.
1774 	 */
1775 	reg = rd32(hw, I40E_GL_MDET_RX);
1776 	if (reg & I40E_GL_MDET_RX_VALID_MASK) {
1777 		pf_num = (reg & I40E_GL_MDET_RX_FUNCTION_MASK) >>
1778 		    I40E_GL_MDET_RX_FUNCTION_SHIFT;
1779 		event = (reg & I40E_GL_MDET_RX_EVENT_MASK) >>
1780 		    I40E_GL_MDET_RX_EVENT_SHIFT;
1781 		queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK) >>
1782 		    I40E_GL_MDET_RX_QUEUE_SHIFT;
1783 		wr32(hw, I40E_GL_MDET_RX, 0xffffffff);
1784 		mdd_detected = true;
1785 	}
1786 
1787 	if (!mdd_detected)
1788 		return;
1789 
1790 	reg = rd32(hw, I40E_PF_MDET_RX);
1791 	if (reg & I40E_PF_MDET_RX_VALID_MASK) {
1792 		wr32(hw, I40E_PF_MDET_RX, 0xFFFF);
1793 		pf_mdet_num = hw->pf_id;
1794 		pf_mdd_detected = true;
1795 	}
1796 
1797 	/* Check if MDD was caused by a VF */
1798 	for (int i = 0; i < pf->num_vfs; i++) {
1799 		vf = &(pf->vfs[i]);
1800 		reg = rd32(hw, I40E_VP_MDET_RX(i));
1801 		if (reg & I40E_VP_MDET_RX_VALID_MASK) {
1802 			wr32(hw, I40E_VP_MDET_RX(i), 0xFFFF);
1803 			vp_mdet_num = i;
1804 			vf->num_mdd_events++;
1805 			vf_mdd_detected = true;
1806 		}
1807 	}
1808 
1809 	/* Print out an error message */
1810 	if (vf_mdd_detected && pf_mdd_detected)
1811 		device_printf(dev,
1812 		    "Malicious Driver Detection event %d"
1813 		    " on RX queue %d, pf number %d (PF-%d), (VF-%d)\n",
1814 		    event, queue, pf_num, pf_mdet_num, vp_mdet_num);
1815 	else if (vf_mdd_detected && !pf_mdd_detected)
1816 		device_printf(dev,
1817 		    "Malicious Driver Detection event %d"
1818 		    " on RX queue %d, pf number %d, (VF-%d)\n",
1819 		    event, queue, pf_num, vp_mdet_num);
1820 	else if (!vf_mdd_detected && pf_mdd_detected)
1821 		device_printf(dev,
1822 		    "Malicious Driver Detection event %d"
1823 		    " on RX queue %d, pf number %d (PF-%d)\n",
1824 		    event, queue, pf_num, pf_mdet_num);
1825 	/* Theoretically shouldn't happen */
1826 	else
1827 		device_printf(dev,
1828 		    "RX Malicious Driver Detection event (unknown)\n");
1829 }
1830 
1831 /**
1832  * ixl_handle_mdd_event
1833  *
1834  * Called from interrupt handler to identify possibly malicious vfs
1835  * (But also detects events from the PF, as well)
1836  **/
1837 void
1838 ixl_handle_mdd_event(struct ixl_pf *pf)
1839 {
1840 	struct i40e_hw *hw = &pf->hw;
1841 	u32 reg;
1842 
1843 	/*
1844 	 * Handle both TX/RX because it's possible they could
1845 	 * both trigger in the same interrupt.
1846 	 */
1847 	ixl_handle_tx_mdd_event(pf);
1848 	ixl_handle_rx_mdd_event(pf);
1849 
1850 	atomic_clear_32(&pf->state, IXL_PF_STATE_MDD_PENDING);
1851 
1852 	/* re-enable mdd interrupt cause */
1853 	reg = rd32(hw, I40E_PFINT_ICR0_ENA);
1854 	reg |= I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK;
1855 	wr32(hw, I40E_PFINT_ICR0_ENA, reg);
1856 	ixl_flush(hw);
1857 }
1858 
1859 void
1860 ixl_enable_intr0(struct i40e_hw *hw)
1861 {
1862 	u32		reg;
1863 
1864 	/* Use IXL_ITR_NONE so ITR isn't updated here */
1865 	reg = I40E_PFINT_DYN_CTL0_INTENA_MASK |
1866 	    I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
1867 	    (IXL_ITR_NONE << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT);
1868 	wr32(hw, I40E_PFINT_DYN_CTL0, reg);
1869 }
1870 
1871 void
1872 ixl_disable_intr0(struct i40e_hw *hw)
1873 {
1874 	u32		reg;
1875 
1876 	reg = IXL_ITR_NONE << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT;
1877 	wr32(hw, I40E_PFINT_DYN_CTL0, reg);
1878 	ixl_flush(hw);
1879 }
1880 
1881 void
1882 ixl_enable_queue(struct i40e_hw *hw, int id)
1883 {
1884 	u32		reg;
1885 
1886 	reg = I40E_PFINT_DYN_CTLN_INTENA_MASK |
1887 	    I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
1888 	    (IXL_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT);
1889 	wr32(hw, I40E_PFINT_DYN_CTLN(id), reg);
1890 }
1891 
1892 void
1893 ixl_disable_queue(struct i40e_hw *hw, int id)
1894 {
1895 	u32		reg;
1896 
1897 	reg = IXL_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT;
1898 	wr32(hw, I40E_PFINT_DYN_CTLN(id), reg);
1899 }
1900 
1901 void
1902 ixl_handle_empr_reset(struct ixl_pf *pf)
1903 {
1904 	struct ixl_vsi	*vsi = &pf->vsi;
1905 	bool is_up = !!(vsi->ifp->if_drv_flags & IFF_DRV_RUNNING);
1906 
1907 	ixl_prepare_for_reset(pf, is_up);
1908 	/*
1909 	 * i40e_pf_reset checks the type of reset and acts
1910 	 * accordingly. If EMP or Core reset was performed
1911 	 * doing PF reset is not necessary and it sometimes
1912 	 * fails.
1913 	 */
1914 	ixl_pf_reset(pf);
1915 
1916 	if (!IXL_PF_IN_RECOVERY_MODE(pf) &&
1917 	    ixl_get_fw_mode(pf) == IXL_FW_MODE_RECOVERY) {
1918 		atomic_set_32(&pf->state, IXL_PF_STATE_RECOVERY_MODE);
1919 		device_printf(pf->dev,
1920 		    "Firmware recovery mode detected. Limiting functionality. Refer to Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n");
1921 		pf->link_up = FALSE;
1922 		ixl_update_link_status(pf);
1923 	}
1924 
1925 	ixl_rebuild_hw_structs_after_reset(pf, is_up);
1926 
1927 	atomic_clear_32(&pf->state, IXL_PF_STATE_RESETTING);
1928 }
1929 
1930 void
1931 ixl_update_stats_counters(struct ixl_pf *pf)
1932 {
1933 	struct i40e_hw	*hw = &pf->hw;
1934 	struct ixl_vsi	*vsi = &pf->vsi;
1935 	struct ixl_vf	*vf;
1936 	u64 prev_link_xoff_rx = pf->stats.link_xoff_rx;
1937 
1938 	struct i40e_hw_port_stats *nsd = &pf->stats;
1939 	struct i40e_hw_port_stats *osd = &pf->stats_offsets;
1940 
1941 	/* Update hw stats */
1942 	ixl_stat_update32(hw, I40E_GLPRT_CRCERRS(hw->port),
1943 			   pf->stat_offsets_loaded,
1944 			   &osd->crc_errors, &nsd->crc_errors);
1945 	ixl_stat_update32(hw, I40E_GLPRT_ILLERRC(hw->port),
1946 			   pf->stat_offsets_loaded,
1947 			   &osd->illegal_bytes, &nsd->illegal_bytes);
1948 	ixl_stat_update48(hw, I40E_GLPRT_GORCH(hw->port),
1949 			   I40E_GLPRT_GORCL(hw->port),
1950 			   pf->stat_offsets_loaded,
1951 			   &osd->eth.rx_bytes, &nsd->eth.rx_bytes);
1952 	ixl_stat_update48(hw, I40E_GLPRT_GOTCH(hw->port),
1953 			   I40E_GLPRT_GOTCL(hw->port),
1954 			   pf->stat_offsets_loaded,
1955 			   &osd->eth.tx_bytes, &nsd->eth.tx_bytes);
1956 	ixl_stat_update32(hw, I40E_GLPRT_RDPC(hw->port),
1957 			   pf->stat_offsets_loaded,
1958 			   &osd->eth.rx_discards,
1959 			   &nsd->eth.rx_discards);
1960 	ixl_stat_update48(hw, I40E_GLPRT_UPRCH(hw->port),
1961 			   I40E_GLPRT_UPRCL(hw->port),
1962 			   pf->stat_offsets_loaded,
1963 			   &osd->eth.rx_unicast,
1964 			   &nsd->eth.rx_unicast);
1965 	ixl_stat_update48(hw, I40E_GLPRT_UPTCH(hw->port),
1966 			   I40E_GLPRT_UPTCL(hw->port),
1967 			   pf->stat_offsets_loaded,
1968 			   &osd->eth.tx_unicast,
1969 			   &nsd->eth.tx_unicast);
1970 	ixl_stat_update48(hw, I40E_GLPRT_MPRCH(hw->port),
1971 			   I40E_GLPRT_MPRCL(hw->port),
1972 			   pf->stat_offsets_loaded,
1973 			   &osd->eth.rx_multicast,
1974 			   &nsd->eth.rx_multicast);
1975 	ixl_stat_update48(hw, I40E_GLPRT_MPTCH(hw->port),
1976 			   I40E_GLPRT_MPTCL(hw->port),
1977 			   pf->stat_offsets_loaded,
1978 			   &osd->eth.tx_multicast,
1979 			   &nsd->eth.tx_multicast);
1980 	ixl_stat_update48(hw, I40E_GLPRT_BPRCH(hw->port),
1981 			   I40E_GLPRT_BPRCL(hw->port),
1982 			   pf->stat_offsets_loaded,
1983 			   &osd->eth.rx_broadcast,
1984 			   &nsd->eth.rx_broadcast);
1985 	ixl_stat_update48(hw, I40E_GLPRT_BPTCH(hw->port),
1986 			   I40E_GLPRT_BPTCL(hw->port),
1987 			   pf->stat_offsets_loaded,
1988 			   &osd->eth.tx_broadcast,
1989 			   &nsd->eth.tx_broadcast);
1990 
1991 	ixl_stat_update32(hw, I40E_GLPRT_TDOLD(hw->port),
1992 			   pf->stat_offsets_loaded,
1993 			   &osd->tx_dropped_link_down,
1994 			   &nsd->tx_dropped_link_down);
1995 	ixl_stat_update32(hw, I40E_GLPRT_MLFC(hw->port),
1996 			   pf->stat_offsets_loaded,
1997 			   &osd->mac_local_faults,
1998 			   &nsd->mac_local_faults);
1999 	ixl_stat_update32(hw, I40E_GLPRT_MRFC(hw->port),
2000 			   pf->stat_offsets_loaded,
2001 			   &osd->mac_remote_faults,
2002 			   &nsd->mac_remote_faults);
2003 	ixl_stat_update32(hw, I40E_GLPRT_RLEC(hw->port),
2004 			   pf->stat_offsets_loaded,
2005 			   &osd->rx_length_errors,
2006 			   &nsd->rx_length_errors);
2007 
2008 	/* Flow control (LFC) stats */
2009 	ixl_stat_update32(hw, I40E_GLPRT_LXONRXC(hw->port),
2010 			   pf->stat_offsets_loaded,
2011 			   &osd->link_xon_rx, &nsd->link_xon_rx);
2012 	ixl_stat_update32(hw, I40E_GLPRT_LXONTXC(hw->port),
2013 			   pf->stat_offsets_loaded,
2014 			   &osd->link_xon_tx, &nsd->link_xon_tx);
2015 	ixl_stat_update32(hw, I40E_GLPRT_LXOFFRXC(hw->port),
2016 			   pf->stat_offsets_loaded,
2017 			   &osd->link_xoff_rx, &nsd->link_xoff_rx);
2018 	ixl_stat_update32(hw, I40E_GLPRT_LXOFFTXC(hw->port),
2019 			   pf->stat_offsets_loaded,
2020 			   &osd->link_xoff_tx, &nsd->link_xoff_tx);
2021 
2022 	/*
2023 	 * For watchdog management we need to know if we have been paused
2024 	 * during the last interval, so capture that here.
2025 	 */
2026 	if (pf->stats.link_xoff_rx != prev_link_xoff_rx)
2027 		vsi->shared->isc_pause_frames = 1;
2028 
2029 	/* Packet size stats rx */
2030 	ixl_stat_update48(hw, I40E_GLPRT_PRC64H(hw->port),
2031 			   I40E_GLPRT_PRC64L(hw->port),
2032 			   pf->stat_offsets_loaded,
2033 			   &osd->rx_size_64, &nsd->rx_size_64);
2034 	ixl_stat_update48(hw, I40E_GLPRT_PRC127H(hw->port),
2035 			   I40E_GLPRT_PRC127L(hw->port),
2036 			   pf->stat_offsets_loaded,
2037 			   &osd->rx_size_127, &nsd->rx_size_127);
2038 	ixl_stat_update48(hw, I40E_GLPRT_PRC255H(hw->port),
2039 			   I40E_GLPRT_PRC255L(hw->port),
2040 			   pf->stat_offsets_loaded,
2041 			   &osd->rx_size_255, &nsd->rx_size_255);
2042 	ixl_stat_update48(hw, I40E_GLPRT_PRC511H(hw->port),
2043 			   I40E_GLPRT_PRC511L(hw->port),
2044 			   pf->stat_offsets_loaded,
2045 			   &osd->rx_size_511, &nsd->rx_size_511);
2046 	ixl_stat_update48(hw, I40E_GLPRT_PRC1023H(hw->port),
2047 			   I40E_GLPRT_PRC1023L(hw->port),
2048 			   pf->stat_offsets_loaded,
2049 			   &osd->rx_size_1023, &nsd->rx_size_1023);
2050 	ixl_stat_update48(hw, I40E_GLPRT_PRC1522H(hw->port),
2051 			   I40E_GLPRT_PRC1522L(hw->port),
2052 			   pf->stat_offsets_loaded,
2053 			   &osd->rx_size_1522, &nsd->rx_size_1522);
2054 	ixl_stat_update48(hw, I40E_GLPRT_PRC9522H(hw->port),
2055 			   I40E_GLPRT_PRC9522L(hw->port),
2056 			   pf->stat_offsets_loaded,
2057 			   &osd->rx_size_big, &nsd->rx_size_big);
2058 
2059 	/* Packet size stats tx */
2060 	ixl_stat_update48(hw, I40E_GLPRT_PTC64H(hw->port),
2061 			   I40E_GLPRT_PTC64L(hw->port),
2062 			   pf->stat_offsets_loaded,
2063 			   &osd->tx_size_64, &nsd->tx_size_64);
2064 	ixl_stat_update48(hw, I40E_GLPRT_PTC127H(hw->port),
2065 			   I40E_GLPRT_PTC127L(hw->port),
2066 			   pf->stat_offsets_loaded,
2067 			   &osd->tx_size_127, &nsd->tx_size_127);
2068 	ixl_stat_update48(hw, I40E_GLPRT_PTC255H(hw->port),
2069 			   I40E_GLPRT_PTC255L(hw->port),
2070 			   pf->stat_offsets_loaded,
2071 			   &osd->tx_size_255, &nsd->tx_size_255);
2072 	ixl_stat_update48(hw, I40E_GLPRT_PTC511H(hw->port),
2073 			   I40E_GLPRT_PTC511L(hw->port),
2074 			   pf->stat_offsets_loaded,
2075 			   &osd->tx_size_511, &nsd->tx_size_511);
2076 	ixl_stat_update48(hw, I40E_GLPRT_PTC1023H(hw->port),
2077 			   I40E_GLPRT_PTC1023L(hw->port),
2078 			   pf->stat_offsets_loaded,
2079 			   &osd->tx_size_1023, &nsd->tx_size_1023);
2080 	ixl_stat_update48(hw, I40E_GLPRT_PTC1522H(hw->port),
2081 			   I40E_GLPRT_PTC1522L(hw->port),
2082 			   pf->stat_offsets_loaded,
2083 			   &osd->tx_size_1522, &nsd->tx_size_1522);
2084 	ixl_stat_update48(hw, I40E_GLPRT_PTC9522H(hw->port),
2085 			   I40E_GLPRT_PTC9522L(hw->port),
2086 			   pf->stat_offsets_loaded,
2087 			   &osd->tx_size_big, &nsd->tx_size_big);
2088 
2089 	ixl_stat_update32(hw, I40E_GLPRT_RUC(hw->port),
2090 			   pf->stat_offsets_loaded,
2091 			   &osd->rx_undersize, &nsd->rx_undersize);
2092 	ixl_stat_update32(hw, I40E_GLPRT_RFC(hw->port),
2093 			   pf->stat_offsets_loaded,
2094 			   &osd->rx_fragments, &nsd->rx_fragments);
2095 	ixl_stat_update32(hw, I40E_GLPRT_ROC(hw->port),
2096 			   pf->stat_offsets_loaded,
2097 			   &osd->rx_oversize, &nsd->rx_oversize);
2098 	ixl_stat_update32(hw, I40E_GLPRT_RJC(hw->port),
2099 			   pf->stat_offsets_loaded,
2100 			   &osd->rx_jabber, &nsd->rx_jabber);
2101 	/* EEE */
2102 	i40e_get_phy_lpi_status(hw, nsd);
2103 
2104 	i40e_lpi_stat_update(hw, pf->stat_offsets_loaded,
2105 			  &osd->tx_lpi_count, &nsd->tx_lpi_count,
2106 			  &osd->rx_lpi_count, &nsd->rx_lpi_count);
2107 
2108 	pf->stat_offsets_loaded = true;
2109 	/* End hw stats */
2110 
2111 	/* Update vsi stats */
2112 	ixl_update_vsi_stats(vsi);
2113 
2114 	for (int i = 0; i < pf->num_vfs; i++) {
2115 		vf = &pf->vfs[i];
2116 		if (vf->vf_flags & VF_FLAG_ENABLED)
2117 			ixl_update_eth_stats(&pf->vfs[i].vsi);
2118 	}
2119 }
2120 
2121 /**
2122  * Update VSI-specific ethernet statistics counters.
2123  **/
2124 void
2125 ixl_update_eth_stats(struct ixl_vsi *vsi)
2126 {
2127 	struct ixl_pf *pf = (struct ixl_pf *)vsi->back;
2128 	struct i40e_hw *hw = &pf->hw;
2129 	struct i40e_eth_stats *es;
2130 	struct i40e_eth_stats *oes;
2131 	u16 stat_idx = vsi->info.stat_counter_idx;
2132 
2133 	es = &vsi->eth_stats;
2134 	oes = &vsi->eth_stats_offsets;
2135 
2136 	/* Gather up the stats that the hw collects */
2137 	ixl_stat_update32(hw, I40E_GLV_TEPC(stat_idx),
2138 			   vsi->stat_offsets_loaded,
2139 			   &oes->tx_errors, &es->tx_errors);
2140 	ixl_stat_update32(hw, I40E_GLV_RDPC(stat_idx),
2141 			   vsi->stat_offsets_loaded,
2142 			   &oes->rx_discards, &es->rx_discards);
2143 
2144 	ixl_stat_update48(hw, I40E_GLV_GORCH(stat_idx),
2145 			   I40E_GLV_GORCL(stat_idx),
2146 			   vsi->stat_offsets_loaded,
2147 			   &oes->rx_bytes, &es->rx_bytes);
2148 	ixl_stat_update48(hw, I40E_GLV_UPRCH(stat_idx),
2149 			   I40E_GLV_UPRCL(stat_idx),
2150 			   vsi->stat_offsets_loaded,
2151 			   &oes->rx_unicast, &es->rx_unicast);
2152 	ixl_stat_update48(hw, I40E_GLV_MPRCH(stat_idx),
2153 			   I40E_GLV_MPRCL(stat_idx),
2154 			   vsi->stat_offsets_loaded,
2155 			   &oes->rx_multicast, &es->rx_multicast);
2156 	ixl_stat_update48(hw, I40E_GLV_BPRCH(stat_idx),
2157 			   I40E_GLV_BPRCL(stat_idx),
2158 			   vsi->stat_offsets_loaded,
2159 			   &oes->rx_broadcast, &es->rx_broadcast);
2160 
2161 	ixl_stat_update48(hw, I40E_GLV_GOTCH(stat_idx),
2162 			   I40E_GLV_GOTCL(stat_idx),
2163 			   vsi->stat_offsets_loaded,
2164 			   &oes->tx_bytes, &es->tx_bytes);
2165 	ixl_stat_update48(hw, I40E_GLV_UPTCH(stat_idx),
2166 			   I40E_GLV_UPTCL(stat_idx),
2167 			   vsi->stat_offsets_loaded,
2168 			   &oes->tx_unicast, &es->tx_unicast);
2169 	ixl_stat_update48(hw, I40E_GLV_MPTCH(stat_idx),
2170 			   I40E_GLV_MPTCL(stat_idx),
2171 			   vsi->stat_offsets_loaded,
2172 			   &oes->tx_multicast, &es->tx_multicast);
2173 	ixl_stat_update48(hw, I40E_GLV_BPTCH(stat_idx),
2174 			   I40E_GLV_BPTCL(stat_idx),
2175 			   vsi->stat_offsets_loaded,
2176 			   &oes->tx_broadcast, &es->tx_broadcast);
2177 	vsi->stat_offsets_loaded = true;
2178 }
2179 
2180 void
2181 ixl_update_vsi_stats(struct ixl_vsi *vsi)
2182 {
2183 	struct ixl_pf		*pf;
2184 	struct ifnet		*ifp;
2185 	struct i40e_eth_stats	*es;
2186 	u64			tx_discards;
2187 
2188 	struct i40e_hw_port_stats *nsd;
2189 
2190 	pf = vsi->back;
2191 	ifp = vsi->ifp;
2192 	es = &vsi->eth_stats;
2193 	nsd = &pf->stats;
2194 
2195 	ixl_update_eth_stats(vsi);
2196 
2197 	tx_discards = es->tx_discards + nsd->tx_dropped_link_down;
2198 
2199 	/* Update ifnet stats */
2200 	IXL_SET_IPACKETS(vsi, es->rx_unicast +
2201 	                   es->rx_multicast +
2202 			   es->rx_broadcast);
2203 	IXL_SET_OPACKETS(vsi, es->tx_unicast +
2204 	                   es->tx_multicast +
2205 			   es->tx_broadcast);
2206 	IXL_SET_IBYTES(vsi, es->rx_bytes);
2207 	IXL_SET_OBYTES(vsi, es->tx_bytes);
2208 	IXL_SET_IMCASTS(vsi, es->rx_multicast);
2209 	IXL_SET_OMCASTS(vsi, es->tx_multicast);
2210 
2211 	IXL_SET_IERRORS(vsi, nsd->crc_errors + nsd->illegal_bytes +
2212 	    nsd->rx_undersize + nsd->rx_oversize + nsd->rx_fragments +
2213 	    nsd->rx_jabber);
2214 	IXL_SET_OERRORS(vsi, es->tx_errors);
2215 	IXL_SET_IQDROPS(vsi, es->rx_discards + nsd->eth.rx_discards);
2216 	IXL_SET_OQDROPS(vsi, tx_discards);
2217 	IXL_SET_NOPROTO(vsi, es->rx_unknown_protocol);
2218 	IXL_SET_COLLISIONS(vsi, 0);
2219 }
2220 
2221 /**
2222  * Reset all of the stats for the given pf
2223  **/
2224 void
2225 ixl_pf_reset_stats(struct ixl_pf *pf)
2226 {
2227 	bzero(&pf->stats, sizeof(struct i40e_hw_port_stats));
2228 	bzero(&pf->stats_offsets, sizeof(struct i40e_hw_port_stats));
2229 	pf->stat_offsets_loaded = false;
2230 }
2231 
2232 /**
2233  * Resets all stats of the given vsi
2234  **/
2235 void
2236 ixl_vsi_reset_stats(struct ixl_vsi *vsi)
2237 {
2238 	bzero(&vsi->eth_stats, sizeof(struct i40e_eth_stats));
2239 	bzero(&vsi->eth_stats_offsets, sizeof(struct i40e_eth_stats));
2240 	vsi->stat_offsets_loaded = false;
2241 }
2242 
2243 /**
2244  * Read and update a 48 bit stat from the hw
2245  *
2246  * Since the device stats are not reset at PFReset, they likely will not
2247  * be zeroed when the driver starts.  We'll save the first values read
2248  * and use them as offsets to be subtracted from the raw values in order
2249  * to report stats that count from zero.
2250  **/
2251 void
2252 ixl_stat_update48(struct i40e_hw *hw, u32 hireg, u32 loreg,
2253 	bool offset_loaded, u64 *offset, u64 *stat)
2254 {
2255 	u64 new_data;
2256 
2257 #if defined(__FreeBSD__) && (__FreeBSD_version >= 1000000) && defined(__amd64__)
2258 	new_data = rd64(hw, loreg);
2259 #else
2260 	/*
2261 	 * Use two rd32's instead of one rd64; FreeBSD versions before
2262 	 * 10 don't support 64-bit bus reads/writes.
2263 	 */
2264 	new_data = rd32(hw, loreg);
2265 	new_data |= ((u64)(rd32(hw, hireg) & 0xFFFF)) << 32;
2266 #endif
2267 
2268 	if (!offset_loaded)
2269 		*offset = new_data;
2270 	if (new_data >= *offset)
2271 		*stat = new_data - *offset;
2272 	else
2273 		*stat = (new_data + ((u64)1 << 48)) - *offset;
2274 	*stat &= 0xFFFFFFFFFFFFULL;
2275 }
2276 
2277 /**
2278  * Read and update a 32 bit stat from the hw
2279  **/
2280 void
2281 ixl_stat_update32(struct i40e_hw *hw, u32 reg,
2282 	bool offset_loaded, u64 *offset, u64 *stat)
2283 {
2284 	u32 new_data;
2285 
2286 	new_data = rd32(hw, reg);
2287 	if (!offset_loaded)
2288 		*offset = new_data;
2289 	if (new_data >= *offset)
2290 		*stat = (u32)(new_data - *offset);
2291 	else
2292 		*stat = (u32)((new_data + ((u64)1 << 32)) - *offset);
2293 }
2294 
2295 /**
2296  * Add subset of device sysctls safe to use in recovery mode
2297  */
2298 void
2299 ixl_add_sysctls_recovery_mode(struct ixl_pf *pf)
2300 {
2301 	device_t dev = pf->dev;
2302 
2303 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
2304 	struct sysctl_oid_list *ctx_list =
2305 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
2306 
2307 	struct sysctl_oid *debug_node;
2308 	struct sysctl_oid_list *debug_list;
2309 
2310 	SYSCTL_ADD_PROC(ctx, ctx_list,
2311 	    OID_AUTO, "fw_version",
2312 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, pf, 0,
2313 	    ixl_sysctl_show_fw, "A", "Firmware version");
2314 
2315 	/* Add sysctls meant to print debug information, but don't list them
2316 	 * in "sysctl -a" output. */
2317 	debug_node = SYSCTL_ADD_NODE(ctx, ctx_list,
2318 	    OID_AUTO, "debug", CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, NULL,
2319 	    "Debug Sysctls");
2320 	debug_list = SYSCTL_CHILDREN(debug_node);
2321 
2322 	SYSCTL_ADD_UINT(ctx, debug_list,
2323 	    OID_AUTO, "shared_debug_mask", CTLFLAG_RW,
2324 	    &pf->hw.debug_mask, 0, "Shared code debug message level");
2325 
2326 	SYSCTL_ADD_UINT(ctx, debug_list,
2327 	    OID_AUTO, "core_debug_mask", CTLFLAG_RW,
2328 	    &pf->dbg_mask, 0, "Non-shared code debug message level");
2329 
2330 	SYSCTL_ADD_PROC(ctx, debug_list,
2331 	    OID_AUTO, "dump_debug_data",
2332 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2333 	    pf, 0, ixl_sysctl_dump_debug_data, "A", "Dump Debug Data from FW");
2334 
2335 	SYSCTL_ADD_PROC(ctx, debug_list,
2336 	    OID_AUTO, "do_pf_reset",
2337 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2338 	    pf, 0, ixl_sysctl_do_pf_reset, "I", "Tell HW to initiate a PF reset");
2339 
2340 	SYSCTL_ADD_PROC(ctx, debug_list,
2341 	    OID_AUTO, "do_core_reset",
2342 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2343 	    pf, 0, ixl_sysctl_do_core_reset, "I", "Tell HW to initiate a CORE reset");
2344 
2345 	SYSCTL_ADD_PROC(ctx, debug_list,
2346 	    OID_AUTO, "do_global_reset",
2347 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2348 	    pf, 0, ixl_sysctl_do_global_reset, "I", "Tell HW to initiate a GLOBAL reset");
2349 
2350 	SYSCTL_ADD_PROC(ctx, debug_list,
2351 	    OID_AUTO, "queue_interrupt_table",
2352 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2353 	    pf, 0, ixl_sysctl_queue_interrupt_table, "A", "View MSI-X indices for TX/RX queues");
2354 }
2355 
2356 void
2357 ixl_add_device_sysctls(struct ixl_pf *pf)
2358 {
2359 	device_t dev = pf->dev;
2360 	struct i40e_hw *hw = &pf->hw;
2361 
2362 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
2363 	struct sysctl_oid_list *ctx_list =
2364 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
2365 
2366 	struct sysctl_oid *debug_node;
2367 	struct sysctl_oid_list *debug_list;
2368 
2369 	struct sysctl_oid *fec_node;
2370 	struct sysctl_oid_list *fec_list;
2371 	struct sysctl_oid *eee_node;
2372 	struct sysctl_oid_list *eee_list;
2373 
2374 	/* Set up sysctls */
2375 	SYSCTL_ADD_PROC(ctx, ctx_list,
2376 	    OID_AUTO, "fc", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
2377 	    pf, 0, ixl_sysctl_set_flowcntl, "I", IXL_SYSCTL_HELP_FC);
2378 
2379 	SYSCTL_ADD_PROC(ctx, ctx_list,
2380 	    OID_AUTO, "advertise_speed",
2381 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2382 	    ixl_sysctl_set_advertise, "I", IXL_SYSCTL_HELP_SET_ADVERTISE);
2383 
2384 	SYSCTL_ADD_PROC(ctx, ctx_list,
2385 	    OID_AUTO, "supported_speeds",
2386 	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, pf, 0,
2387 	    ixl_sysctl_supported_speeds, "I", IXL_SYSCTL_HELP_SUPPORTED_SPEED);
2388 
2389 	SYSCTL_ADD_PROC(ctx, ctx_list,
2390 	    OID_AUTO, "current_speed",
2391 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, pf, 0,
2392 	    ixl_sysctl_current_speed, "A", "Current Port Speed");
2393 
2394 	SYSCTL_ADD_PROC(ctx, ctx_list,
2395 	    OID_AUTO, "fw_version",
2396 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT, pf, 0,
2397 	    ixl_sysctl_show_fw, "A", "Firmware version");
2398 
2399 	SYSCTL_ADD_PROC(ctx, ctx_list,
2400 	    OID_AUTO, "unallocated_queues",
2401 	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT, pf, 0,
2402 	    ixl_sysctl_unallocated_queues, "I",
2403 	    "Queues not allocated to a PF or VF");
2404 
2405 	SYSCTL_ADD_PROC(ctx, ctx_list,
2406 	    OID_AUTO, "tx_itr",
2407 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2408 	    ixl_sysctl_pf_tx_itr, "I",
2409 	    "Immediately set TX ITR value for all queues");
2410 
2411 	SYSCTL_ADD_PROC(ctx, ctx_list,
2412 	    OID_AUTO, "rx_itr",
2413 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2414 	    ixl_sysctl_pf_rx_itr, "I",
2415 	    "Immediately set RX ITR value for all queues");
2416 
2417 	SYSCTL_ADD_INT(ctx, ctx_list,
2418 	    OID_AUTO, "dynamic_rx_itr", CTLFLAG_RW,
2419 	    &pf->dynamic_rx_itr, 0, "Enable dynamic RX ITR");
2420 
2421 	SYSCTL_ADD_INT(ctx, ctx_list,
2422 	    OID_AUTO, "dynamic_tx_itr", CTLFLAG_RW,
2423 	    &pf->dynamic_tx_itr, 0, "Enable dynamic TX ITR");
2424 
2425 	/* Add FEC sysctls for 25G adapters */
2426 	if (i40e_is_25G_device(hw->device_id)) {
2427 		fec_node = SYSCTL_ADD_NODE(ctx, ctx_list,
2428 		    OID_AUTO, "fec", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
2429 		    "FEC Sysctls");
2430 		fec_list = SYSCTL_CHILDREN(fec_node);
2431 
2432 		SYSCTL_ADD_PROC(ctx, fec_list,
2433 		    OID_AUTO, "fc_ability",
2434 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2435 		    ixl_sysctl_fec_fc_ability, "I", "FC FEC ability enabled");
2436 
2437 		SYSCTL_ADD_PROC(ctx, fec_list,
2438 		    OID_AUTO, "rs_ability",
2439 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2440 		    ixl_sysctl_fec_rs_ability, "I", "RS FEC ability enabled");
2441 
2442 		SYSCTL_ADD_PROC(ctx, fec_list,
2443 		    OID_AUTO, "fc_requested",
2444 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2445 		    ixl_sysctl_fec_fc_request, "I",
2446 		    "FC FEC mode requested on link");
2447 
2448 		SYSCTL_ADD_PROC(ctx, fec_list,
2449 		    OID_AUTO, "rs_requested",
2450 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2451 		    ixl_sysctl_fec_rs_request, "I",
2452 		    "RS FEC mode requested on link");
2453 
2454 		SYSCTL_ADD_PROC(ctx, fec_list,
2455 		    OID_AUTO, "auto_fec_enabled",
2456 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, pf, 0,
2457 		    ixl_sysctl_fec_auto_enable, "I",
2458 		    "Let FW decide FEC ability/request modes");
2459 	}
2460 
2461 	SYSCTL_ADD_PROC(ctx, ctx_list,
2462 	    OID_AUTO, "fw_lldp", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
2463 	    pf, 0, ixl_sysctl_fw_lldp, "I", IXL_SYSCTL_HELP_FW_LLDP);
2464 
2465 	eee_node = SYSCTL_ADD_NODE(ctx, ctx_list,
2466 	    OID_AUTO, "eee", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
2467 	    "Energy Efficient Ethernet (EEE) Sysctls");
2468 	eee_list = SYSCTL_CHILDREN(eee_node);
2469 
2470 	SYSCTL_ADD_PROC(ctx, eee_list,
2471 	    OID_AUTO, "enable", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
2472 	    pf, 0, ixl_sysctl_eee_enable, "I",
2473 	    "Enable Energy Efficient Ethernet (EEE)");
2474 
2475 	SYSCTL_ADD_UINT(ctx, eee_list, OID_AUTO, "tx_lpi_status",
2476 	    CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.tx_lpi_status, 0,
2477 	    "TX LPI status");
2478 
2479 	SYSCTL_ADD_UINT(ctx, eee_list, OID_AUTO, "rx_lpi_status",
2480 	    CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.rx_lpi_status, 0,
2481 	    "RX LPI status");
2482 
2483 	SYSCTL_ADD_UQUAD(ctx, eee_list, OID_AUTO, "tx_lpi_count",
2484 	    CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.tx_lpi_count,
2485 	    "TX LPI count");
2486 
2487 	SYSCTL_ADD_UQUAD(ctx, eee_list, OID_AUTO, "rx_lpi_count",
2488 	    CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.rx_lpi_count,
2489 	    "RX LPI count");
2490 
2491 	/* Add sysctls meant to print debug information, but don't list them
2492 	 * in "sysctl -a" output. */
2493 	debug_node = SYSCTL_ADD_NODE(ctx, ctx_list,
2494 	    OID_AUTO, "debug", CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, NULL,
2495 	    "Debug Sysctls");
2496 	debug_list = SYSCTL_CHILDREN(debug_node);
2497 
2498 	SYSCTL_ADD_UINT(ctx, debug_list,
2499 	    OID_AUTO, "shared_debug_mask", CTLFLAG_RW,
2500 	    &pf->hw.debug_mask, 0, "Shared code debug message level");
2501 
2502 	SYSCTL_ADD_UINT(ctx, debug_list,
2503 	    OID_AUTO, "core_debug_mask", CTLFLAG_RW,
2504 	    &pf->dbg_mask, 0, "Non-shared code debug message level");
2505 
2506 	SYSCTL_ADD_PROC(ctx, debug_list,
2507 	    OID_AUTO, "link_status",
2508 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2509 	    pf, 0, ixl_sysctl_link_status, "A", IXL_SYSCTL_HELP_LINK_STATUS);
2510 
2511 	SYSCTL_ADD_PROC(ctx, debug_list,
2512 	    OID_AUTO, "phy_abilities",
2513 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2514 	    pf, 0, ixl_sysctl_phy_abilities, "A", "PHY Abilities");
2515 
2516 	SYSCTL_ADD_PROC(ctx, debug_list,
2517 	    OID_AUTO, "filter_list",
2518 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2519 	    pf, 0, ixl_sysctl_sw_filter_list, "A", "SW Filter List");
2520 
2521 	SYSCTL_ADD_PROC(ctx, debug_list,
2522 	    OID_AUTO, "hw_res_alloc",
2523 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2524 	    pf, 0, ixl_sysctl_hw_res_alloc, "A", "HW Resource Allocation");
2525 
2526 	SYSCTL_ADD_PROC(ctx, debug_list,
2527 	    OID_AUTO, "switch_config",
2528 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2529 	    pf, 0, ixl_sysctl_switch_config, "A", "HW Switch Configuration");
2530 
2531 	SYSCTL_ADD_PROC(ctx, debug_list,
2532 	    OID_AUTO, "switch_vlans",
2533 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2534 	    pf, 0, ixl_sysctl_switch_vlans, "I", "HW Switch VLAN Configuration");
2535 
2536 	SYSCTL_ADD_PROC(ctx, debug_list,
2537 	    OID_AUTO, "rss_key",
2538 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2539 	    pf, 0, ixl_sysctl_hkey, "A", "View RSS key");
2540 
2541 	SYSCTL_ADD_PROC(ctx, debug_list,
2542 	    OID_AUTO, "rss_lut",
2543 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2544 	    pf, 0, ixl_sysctl_hlut, "A", "View RSS lookup table");
2545 
2546 	SYSCTL_ADD_PROC(ctx, debug_list,
2547 	    OID_AUTO, "rss_hena",
2548 	    CTLTYPE_ULONG | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2549 	    pf, 0, ixl_sysctl_hena, "LU", "View enabled packet types for RSS");
2550 
2551 	SYSCTL_ADD_PROC(ctx, debug_list,
2552 	    OID_AUTO, "disable_fw_link_management",
2553 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2554 	    pf, 0, ixl_sysctl_fw_link_management, "I", "Disable FW Link Management");
2555 
2556 	SYSCTL_ADD_PROC(ctx, debug_list,
2557 	    OID_AUTO, "dump_debug_data",
2558 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2559 	    pf, 0, ixl_sysctl_dump_debug_data, "A", "Dump Debug Data from FW");
2560 
2561 	SYSCTL_ADD_PROC(ctx, debug_list,
2562 	    OID_AUTO, "do_pf_reset",
2563 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2564 	    pf, 0, ixl_sysctl_do_pf_reset, "I", "Tell HW to initiate a PF reset");
2565 
2566 	SYSCTL_ADD_PROC(ctx, debug_list,
2567 	    OID_AUTO, "do_core_reset",
2568 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2569 	    pf, 0, ixl_sysctl_do_core_reset, "I", "Tell HW to initiate a CORE reset");
2570 
2571 	SYSCTL_ADD_PROC(ctx, debug_list,
2572 	    OID_AUTO, "do_global_reset",
2573 	    CTLTYPE_INT | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
2574 	    pf, 0, ixl_sysctl_do_global_reset, "I", "Tell HW to initiate a GLOBAL reset");
2575 
2576 	SYSCTL_ADD_PROC(ctx, debug_list,
2577 	    OID_AUTO, "queue_interrupt_table",
2578 	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2579 	    pf, 0, ixl_sysctl_queue_interrupt_table, "A", "View MSI-X indices for TX/RX queues");
2580 
2581 	if (pf->has_i2c) {
2582 		SYSCTL_ADD_PROC(ctx, debug_list,
2583 		    OID_AUTO, "read_i2c_byte",
2584 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
2585 		    pf, 0, ixl_sysctl_read_i2c_byte, "I", IXL_SYSCTL_HELP_READ_I2C);
2586 
2587 		SYSCTL_ADD_PROC(ctx, debug_list,
2588 		    OID_AUTO, "write_i2c_byte",
2589 		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
2590 		    pf, 0, ixl_sysctl_write_i2c_byte, "I", IXL_SYSCTL_HELP_WRITE_I2C);
2591 
2592 		SYSCTL_ADD_PROC(ctx, debug_list,
2593 		    OID_AUTO, "read_i2c_diag_data",
2594 		    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
2595 		    pf, 0, ixl_sysctl_read_i2c_diag_data, "A", "Dump selected diagnostic data from FW");
2596 	}
2597 }
2598 
2599 /*
2600  * Primarily for finding out how many queues can be assigned to VFs,
2601  * at runtime.
2602  */
2603 static int
2604 ixl_sysctl_unallocated_queues(SYSCTL_HANDLER_ARGS)
2605 {
2606 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
2607 	int queues;
2608 
2609 	queues = (int)ixl_pf_qmgr_get_num_free(&pf->qmgr);
2610 
2611 	return sysctl_handle_int(oidp, NULL, queues, req);
2612 }
2613 
2614 static const char *
2615 ixl_link_speed_string(enum i40e_aq_link_speed link_speed)
2616 {
2617 	const char * link_speed_str[] = {
2618 		"Unknown",
2619 		"100 Mbps",
2620 		"1 Gbps",
2621 		"10 Gbps",
2622 		"40 Gbps",
2623 		"20 Gbps",
2624 		"25 Gbps",
2625 		"2.5 Gbps",
2626 		"5 Gbps"
2627 	};
2628 	int index;
2629 
2630 	switch (link_speed) {
2631 	case I40E_LINK_SPEED_100MB:
2632 		index = 1;
2633 		break;
2634 	case I40E_LINK_SPEED_1GB:
2635 		index = 2;
2636 		break;
2637 	case I40E_LINK_SPEED_10GB:
2638 		index = 3;
2639 		break;
2640 	case I40E_LINK_SPEED_40GB:
2641 		index = 4;
2642 		break;
2643 	case I40E_LINK_SPEED_20GB:
2644 		index = 5;
2645 		break;
2646 	case I40E_LINK_SPEED_25GB:
2647 		index = 6;
2648 		break;
2649 	case I40E_LINK_SPEED_2_5GB:
2650 		index = 7;
2651 		break;
2652 	case I40E_LINK_SPEED_5GB:
2653 		index = 8;
2654 		break;
2655 	case I40E_LINK_SPEED_UNKNOWN:
2656 	default:
2657 		index = 0;
2658 		break;
2659 	}
2660 
2661 	return (link_speed_str[index]);
2662 }
2663 
2664 int
2665 ixl_sysctl_current_speed(SYSCTL_HANDLER_ARGS)
2666 {
2667 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
2668 	struct i40e_hw *hw = &pf->hw;
2669 	int error = 0;
2670 
2671 	ixl_update_link_status(pf);
2672 
2673 	error = sysctl_handle_string(oidp,
2674 	    __DECONST(void *,
2675 		ixl_link_speed_string(hw->phy.link_info.link_speed)),
2676 	    8, req);
2677 
2678 	return (error);
2679 }
2680 
2681 /*
2682  * Converts 8-bit speeds value to and from sysctl flags and
2683  * Admin Queue flags.
2684  */
2685 static u8
2686 ixl_convert_sysctl_aq_link_speed(u8 speeds, bool to_aq)
2687 {
2688 #define SPEED_MAP_SIZE 8
2689 	static u16 speedmap[SPEED_MAP_SIZE] = {
2690 		(I40E_LINK_SPEED_100MB | (0x1 << 8)),
2691 		(I40E_LINK_SPEED_1GB   | (0x2 << 8)),
2692 		(I40E_LINK_SPEED_10GB  | (0x4 << 8)),
2693 		(I40E_LINK_SPEED_20GB  | (0x8 << 8)),
2694 		(I40E_LINK_SPEED_25GB  | (0x10 << 8)),
2695 		(I40E_LINK_SPEED_40GB  | (0x20 << 8)),
2696 		(I40E_LINK_SPEED_2_5GB | (0x40 << 8)),
2697 		(I40E_LINK_SPEED_5GB   | (0x80 << 8)),
2698 	};
2699 	u8 retval = 0;
2700 
2701 	for (int i = 0; i < SPEED_MAP_SIZE; i++) {
2702 		if (to_aq)
2703 			retval |= (speeds & (speedmap[i] >> 8)) ? (speedmap[i] & 0xff) : 0;
2704 		else
2705 			retval |= (speeds & speedmap[i]) ? (speedmap[i] >> 8) : 0;
2706 	}
2707 
2708 	return (retval);
2709 }
2710 
2711 int
2712 ixl_set_advertised_speeds(struct ixl_pf *pf, int speeds, bool from_aq)
2713 {
2714 	struct i40e_hw *hw = &pf->hw;
2715 	device_t dev = pf->dev;
2716 	struct i40e_aq_get_phy_abilities_resp abilities;
2717 	struct i40e_aq_set_phy_config config;
2718 	enum i40e_status_code aq_error = 0;
2719 
2720 	/* Get current capability information */
2721 	aq_error = i40e_aq_get_phy_capabilities(hw,
2722 	    FALSE, FALSE, &abilities, NULL);
2723 	if (aq_error) {
2724 		device_printf(dev,
2725 		    "%s: Error getting phy capabilities %d,"
2726 		    " aq error: %d\n", __func__, aq_error,
2727 		    hw->aq.asq_last_status);
2728 		return (EIO);
2729 	}
2730 
2731 	/* Prepare new config */
2732 	bzero(&config, sizeof(config));
2733 	if (from_aq)
2734 		config.link_speed = speeds;
2735 	else
2736 		config.link_speed = ixl_convert_sysctl_aq_link_speed(speeds, true);
2737 	config.phy_type = abilities.phy_type;
2738 	config.phy_type_ext = abilities.phy_type_ext;
2739 	config.abilities = abilities.abilities
2740 	    | I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
2741 	config.eee_capability = abilities.eee_capability;
2742 	config.eeer = abilities.eeer_val;
2743 	config.low_power_ctrl = abilities.d3_lpan;
2744 	config.fec_config = abilities.fec_cfg_curr_mod_ext_info
2745 	    & I40E_AQ_PHY_FEC_CONFIG_MASK;
2746 
2747 	/* Do aq command & restart link */
2748 	aq_error = i40e_aq_set_phy_config(hw, &config, NULL);
2749 	if (aq_error) {
2750 		device_printf(dev,
2751 		    "%s: Error setting new phy config %d,"
2752 		    " aq error: %d\n", __func__, aq_error,
2753 		    hw->aq.asq_last_status);
2754 		return (EIO);
2755 	}
2756 
2757 	return (0);
2758 }
2759 
2760 /*
2761 ** Supported link speeds
2762 **	Flags:
2763 **	 0x1 - 100 Mb
2764 **	 0x2 - 1G
2765 **	 0x4 - 10G
2766 **	 0x8 - 20G
2767 **	0x10 - 25G
2768 **	0x20 - 40G
2769 **	0x40 - 2.5G
2770 **	0x80 - 5G
2771 */
2772 static int
2773 ixl_sysctl_supported_speeds(SYSCTL_HANDLER_ARGS)
2774 {
2775 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
2776 	int supported = ixl_convert_sysctl_aq_link_speed(pf->supported_speeds, false);
2777 
2778 	return sysctl_handle_int(oidp, NULL, supported, req);
2779 }
2780 
2781 /*
2782 ** Control link advertise speed:
2783 **	Flags:
2784 **	 0x1 - advertise 100 Mb
2785 **	 0x2 - advertise 1G
2786 **	 0x4 - advertise 10G
2787 **	 0x8 - advertise 20G
2788 **	0x10 - advertise 25G
2789 **	0x20 - advertise 40G
2790 **	0x40 - advertise 2.5G
2791 **	0x80 - advertise 5G
2792 **
2793 **	Set to 0 to disable link
2794 */
2795 int
2796 ixl_sysctl_set_advertise(SYSCTL_HANDLER_ARGS)
2797 {
2798 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
2799 	device_t dev = pf->dev;
2800 	u8 converted_speeds;
2801 	int requested_ls = 0;
2802 	int error = 0;
2803 
2804 	/* Read in new mode */
2805 	requested_ls = pf->advertised_speed;
2806 	error = sysctl_handle_int(oidp, &requested_ls, 0, req);
2807 	if ((error) || (req->newptr == NULL))
2808 		return (error);
2809 	if (IXL_PF_IN_RECOVERY_MODE(pf)) {
2810 		device_printf(dev, "Interface is currently in FW recovery mode. "
2811 				"Setting advertise speed not supported\n");
2812 		return (EINVAL);
2813 	}
2814 
2815 	/* Error out if bits outside of possible flag range are set */
2816 	if ((requested_ls & ~((u8)0xFF)) != 0) {
2817 		device_printf(dev, "Input advertised speed out of range; "
2818 		    "valid flags are: 0x%02x\n",
2819 		    ixl_convert_sysctl_aq_link_speed(pf->supported_speeds, false));
2820 		return (EINVAL);
2821 	}
2822 
2823 	/* Check if adapter supports input value */
2824 	converted_speeds = ixl_convert_sysctl_aq_link_speed((u8)requested_ls, true);
2825 	if ((converted_speeds | pf->supported_speeds) != pf->supported_speeds) {
2826 		device_printf(dev, "Invalid advertised speed; "
2827 		    "valid flags are: 0x%02x\n",
2828 		    ixl_convert_sysctl_aq_link_speed(pf->supported_speeds, false));
2829 		return (EINVAL);
2830 	}
2831 
2832 	error = ixl_set_advertised_speeds(pf, requested_ls, false);
2833 	if (error)
2834 		return (error);
2835 
2836 	pf->advertised_speed = requested_ls;
2837 	ixl_update_link_status(pf);
2838 	return (0);
2839 }
2840 
2841 /*
2842  * Input: bitmap of enum i40e_aq_link_speed
2843  */
2844 u64
2845 ixl_max_aq_speed_to_value(u8 link_speeds)
2846 {
2847 	if (link_speeds & I40E_LINK_SPEED_40GB)
2848 		return IF_Gbps(40);
2849 	if (link_speeds & I40E_LINK_SPEED_25GB)
2850 		return IF_Gbps(25);
2851 	if (link_speeds & I40E_LINK_SPEED_20GB)
2852 		return IF_Gbps(20);
2853 	if (link_speeds & I40E_LINK_SPEED_10GB)
2854 		return IF_Gbps(10);
2855 	if (link_speeds & I40E_LINK_SPEED_5GB)
2856 		return IF_Gbps(5);
2857 	if (link_speeds & I40E_LINK_SPEED_2_5GB)
2858 		return IF_Mbps(2500);
2859 	if (link_speeds & I40E_LINK_SPEED_1GB)
2860 		return IF_Gbps(1);
2861 	if (link_speeds & I40E_LINK_SPEED_100MB)
2862 		return IF_Mbps(100);
2863 	else
2864 		/* Minimum supported link speed */
2865 		return IF_Mbps(100);
2866 }
2867 
2868 /*
2869 ** Get the width and transaction speed of
2870 ** the bus this adapter is plugged into.
2871 */
2872 void
2873 ixl_get_bus_info(struct ixl_pf *pf)
2874 {
2875 	struct i40e_hw *hw = &pf->hw;
2876 	device_t dev = pf->dev;
2877         u16 link;
2878         u32 offset, num_ports;
2879 	u64 max_speed;
2880 
2881 	/* Some devices don't use PCIE */
2882 	if (hw->mac.type == I40E_MAC_X722)
2883 		return;
2884 
2885         /* Read PCI Express Capabilities Link Status Register */
2886         pci_find_cap(dev, PCIY_EXPRESS, &offset);
2887         link = pci_read_config(dev, offset + PCIER_LINK_STA, 2);
2888 
2889 	/* Fill out hw struct with PCIE info */
2890 	i40e_set_pci_config_data(hw, link);
2891 
2892 	/* Use info to print out bandwidth messages */
2893         device_printf(dev,"PCI Express Bus: Speed %s %s\n",
2894             ((hw->bus.speed == i40e_bus_speed_8000) ? "8.0GT/s":
2895             (hw->bus.speed == i40e_bus_speed_5000) ? "5.0GT/s":
2896             (hw->bus.speed == i40e_bus_speed_2500) ? "2.5GT/s":"Unknown"),
2897             (hw->bus.width == i40e_bus_width_pcie_x8) ? "Width x8" :
2898             (hw->bus.width == i40e_bus_width_pcie_x4) ? "Width x4" :
2899             (hw->bus.width == i40e_bus_width_pcie_x2) ? "Width x2" :
2900             (hw->bus.width == i40e_bus_width_pcie_x1) ? "Width x1" :
2901             ("Unknown"));
2902 
2903 	/*
2904 	 * If adapter is in slot with maximum supported speed,
2905 	 * no warning message needs to be printed out.
2906 	 */
2907 	if (hw->bus.speed >= i40e_bus_speed_8000
2908 	    && hw->bus.width >= i40e_bus_width_pcie_x8)
2909 		return;
2910 
2911 	num_ports = bitcount32(hw->func_caps.valid_functions);
2912 	max_speed = ixl_max_aq_speed_to_value(pf->supported_speeds) / 1000000;
2913 
2914 	if ((num_ports * max_speed) > hw->bus.speed * hw->bus.width) {
2915                 device_printf(dev, "PCI-Express bandwidth available"
2916                     " for this device may be insufficient for"
2917                     " optimal performance.\n");
2918                 device_printf(dev, "Please move the device to a different"
2919 		    " PCI-e link with more lanes and/or higher"
2920 		    " transfer rate.\n");
2921         }
2922 }
2923 
2924 static int
2925 ixl_sysctl_show_fw(SYSCTL_HANDLER_ARGS)
2926 {
2927 	struct ixl_pf	*pf = (struct ixl_pf *)arg1;
2928 	struct i40e_hw	*hw = &pf->hw;
2929 	struct sbuf	*sbuf;
2930 
2931 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
2932 	ixl_nvm_version_str(hw, sbuf);
2933 	sbuf_finish(sbuf);
2934 	sbuf_delete(sbuf);
2935 
2936 	return (0);
2937 }
2938 
2939 void
2940 ixl_print_nvm_cmd(device_t dev, struct i40e_nvm_access *nvma)
2941 {
2942 	u8 nvma_ptr = nvma->config & 0xFF;
2943 	u8 nvma_flags = (nvma->config & 0xF00) >> 8;
2944 	const char * cmd_str;
2945 
2946 	switch (nvma->command) {
2947 	case I40E_NVM_READ:
2948 		if (nvma_ptr == 0xF && nvma_flags == 0xF &&
2949 		    nvma->offset == 0 && nvma->data_size == 1) {
2950 			device_printf(dev, "NVMUPD: Get Driver Status Command\n");
2951 			return;
2952 		}
2953 		cmd_str = "READ ";
2954 		break;
2955 	case I40E_NVM_WRITE:
2956 		cmd_str = "WRITE";
2957 		break;
2958 	default:
2959 		device_printf(dev, "NVMUPD: unknown command: 0x%08x\n", nvma->command);
2960 		return;
2961 	}
2962 	device_printf(dev,
2963 	    "NVMUPD: cmd: %s ptr: 0x%02x flags: 0x%01x offset: 0x%08x data_s: 0x%08x\n",
2964 	    cmd_str, nvma_ptr, nvma_flags, nvma->offset, nvma->data_size);
2965 }
2966 
2967 int
2968 ixl_handle_nvmupd_cmd(struct ixl_pf *pf, struct ifdrv *ifd)
2969 {
2970 	struct i40e_hw *hw = &pf->hw;
2971 	struct i40e_nvm_access *nvma;
2972 	device_t dev = pf->dev;
2973 	enum i40e_status_code status = 0;
2974 	size_t nvma_size, ifd_len, exp_len;
2975 	int err, perrno;
2976 
2977 	DEBUGFUNC("ixl_handle_nvmupd_cmd");
2978 
2979 	/* Sanity checks */
2980 	nvma_size = sizeof(struct i40e_nvm_access);
2981 	ifd_len = ifd->ifd_len;
2982 
2983 	if (ifd_len < nvma_size ||
2984 	    ifd->ifd_data == NULL) {
2985 		device_printf(dev, "%s: incorrect ifdrv length or data pointer\n",
2986 		    __func__);
2987 		device_printf(dev, "%s: ifdrv length: %zu, sizeof(struct i40e_nvm_access): %zu\n",
2988 		    __func__, ifd_len, nvma_size);
2989 		device_printf(dev, "%s: data pointer: %p\n", __func__,
2990 		    ifd->ifd_data);
2991 		return (EINVAL);
2992 	}
2993 
2994 	nvma = malloc(ifd_len, M_IXL, M_WAITOK);
2995 	err = copyin(ifd->ifd_data, nvma, ifd_len);
2996 	if (err) {
2997 		device_printf(dev, "%s: Cannot get request from user space\n",
2998 		    __func__);
2999 		free(nvma, M_IXL);
3000 		return (err);
3001 	}
3002 
3003 	if (pf->dbg_mask & IXL_DBG_NVMUPD)
3004 		ixl_print_nvm_cmd(dev, nvma);
3005 
3006 	if (IXL_PF_IS_RESETTING(pf)) {
3007 		int count = 0;
3008 		while (count++ < 100) {
3009 			i40e_msec_delay(100);
3010 			if (!(IXL_PF_IS_RESETTING(pf)))
3011 				break;
3012 		}
3013 	}
3014 
3015 	if (IXL_PF_IS_RESETTING(pf)) {
3016 		device_printf(dev,
3017 		    "%s: timeout waiting for EMP reset to finish\n",
3018 		    __func__);
3019 		free(nvma, M_IXL);
3020 		return (-EBUSY);
3021 	}
3022 
3023 	if (nvma->data_size < 1 || nvma->data_size > 4096) {
3024 		device_printf(dev,
3025 		    "%s: invalid request, data size not in supported range\n",
3026 		    __func__);
3027 		free(nvma, M_IXL);
3028 		return (EINVAL);
3029 	}
3030 
3031 	/*
3032 	 * Older versions of the NVM update tool don't set ifd_len to the size
3033 	 * of the entire buffer passed to the ioctl. Check the data_size field
3034 	 * in the contained i40e_nvm_access struct and ensure everything is
3035 	 * copied in from userspace.
3036 	 */
3037 	exp_len = nvma_size + nvma->data_size - 1; /* One byte is kept in struct */
3038 
3039 	if (ifd_len < exp_len) {
3040 		ifd_len = exp_len;
3041 		nvma = realloc(nvma, ifd_len, M_IXL, M_WAITOK);
3042 		err = copyin(ifd->ifd_data, nvma, ifd_len);
3043 		if (err) {
3044 			device_printf(dev, "%s: Cannot get request from user space\n",
3045 					__func__);
3046 			free(nvma, M_IXL);
3047 			return (err);
3048 		}
3049 	}
3050 
3051 	// TODO: Might need a different lock here
3052 	// IXL_PF_LOCK(pf);
3053 	status = i40e_nvmupd_command(hw, nvma, nvma->data, &perrno);
3054 	// IXL_PF_UNLOCK(pf);
3055 
3056 	err = copyout(nvma, ifd->ifd_data, ifd_len);
3057 	free(nvma, M_IXL);
3058 	if (err) {
3059 		device_printf(dev, "%s: Cannot return data to user space\n",
3060 				__func__);
3061 		return (err);
3062 	}
3063 
3064 	/* Let the nvmupdate report errors, show them only when debug is enabled */
3065 	if (status != 0 && (pf->dbg_mask & IXL_DBG_NVMUPD) != 0)
3066 		device_printf(dev, "i40e_nvmupd_command status %s, perrno %d\n",
3067 		    i40e_stat_str(hw, status), perrno);
3068 
3069 	/*
3070 	 * -EPERM is actually ERESTART, which the kernel interprets as it needing
3071 	 * to run this ioctl again. So use -EACCES for -EPERM instead.
3072 	 */
3073 	if (perrno == -EPERM)
3074 		return (-EACCES);
3075 	else
3076 		return (perrno);
3077 }
3078 
3079 int
3080 ixl_find_i2c_interface(struct ixl_pf *pf)
3081 {
3082 	struct i40e_hw *hw = &pf->hw;
3083 	bool i2c_en, port_matched;
3084 	u32 reg;
3085 
3086 	for (int i = 0; i < 4; i++) {
3087 		reg = rd32(hw, I40E_GLGEN_MDIO_I2C_SEL(i));
3088 		i2c_en = (reg & I40E_GLGEN_MDIO_I2C_SEL_MDIO_I2C_SEL_MASK);
3089 		port_matched = ((reg & I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_MASK)
3090 		    >> I40E_GLGEN_MDIO_I2C_SEL_PHY_PORT_NUM_SHIFT)
3091 		    & BIT(hw->port);
3092 		if (i2c_en && port_matched)
3093 			return (i);
3094 	}
3095 
3096 	return (-1);
3097 }
3098 
3099 static char *
3100 ixl_phy_type_string(u32 bit_pos, bool ext)
3101 {
3102 	static char * phy_types_str[32] = {
3103 		"SGMII",
3104 		"1000BASE-KX",
3105 		"10GBASE-KX4",
3106 		"10GBASE-KR",
3107 		"40GBASE-KR4",
3108 		"XAUI",
3109 		"XFI",
3110 		"SFI",
3111 		"XLAUI",
3112 		"XLPPI",
3113 		"40GBASE-CR4",
3114 		"10GBASE-CR1",
3115 		"SFP+ Active DA",
3116 		"QSFP+ Active DA",
3117 		"Reserved (14)",
3118 		"Reserved (15)",
3119 		"Reserved (16)",
3120 		"100BASE-TX",
3121 		"1000BASE-T",
3122 		"10GBASE-T",
3123 		"10GBASE-SR",
3124 		"10GBASE-LR",
3125 		"10GBASE-SFP+Cu",
3126 		"10GBASE-CR1",
3127 		"40GBASE-CR4",
3128 		"40GBASE-SR4",
3129 		"40GBASE-LR4",
3130 		"1000BASE-SX",
3131 		"1000BASE-LX",
3132 		"1000BASE-T Optical",
3133 		"20GBASE-KR2",
3134 		"Reserved (31)"
3135 	};
3136 	static char * ext_phy_types_str[8] = {
3137 		"25GBASE-KR",
3138 		"25GBASE-CR",
3139 		"25GBASE-SR",
3140 		"25GBASE-LR",
3141 		"25GBASE-AOC",
3142 		"25GBASE-ACC",
3143 		"2.5GBASE-T",
3144 		"5GBASE-T"
3145 	};
3146 
3147 	if (ext && bit_pos > 7) return "Invalid_Ext";
3148 	if (bit_pos > 31) return "Invalid";
3149 
3150 	return (ext) ? ext_phy_types_str[bit_pos] : phy_types_str[bit_pos];
3151 }
3152 
3153 /* TODO: ERJ: I don't this is necessary anymore. */
3154 int
3155 ixl_aq_get_link_status(struct ixl_pf *pf, struct i40e_aqc_get_link_status *link_status)
3156 {
3157 	device_t dev = pf->dev;
3158 	struct i40e_hw *hw = &pf->hw;
3159 	struct i40e_aq_desc desc;
3160 	enum i40e_status_code status;
3161 
3162 	struct i40e_aqc_get_link_status *aq_link_status =
3163 		(struct i40e_aqc_get_link_status *)&desc.params.raw;
3164 
3165 	i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_get_link_status);
3166 	link_status->command_flags = CPU_TO_LE16(I40E_AQ_LSE_ENABLE);
3167 	status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
3168 	if (status) {
3169 		device_printf(dev,
3170 		    "%s: i40e_aqc_opc_get_link_status status %s, aq error %s\n",
3171 		    __func__, i40e_stat_str(hw, status),
3172 		    i40e_aq_str(hw, hw->aq.asq_last_status));
3173 		return (EIO);
3174 	}
3175 
3176 	bcopy(aq_link_status, link_status, sizeof(struct i40e_aqc_get_link_status));
3177 	return (0);
3178 }
3179 
3180 static char *
3181 ixl_phy_type_string_ls(u8 val)
3182 {
3183 	if (val >= 0x1F)
3184 		return ixl_phy_type_string(val - 0x1F, true);
3185 	else
3186 		return ixl_phy_type_string(val, false);
3187 }
3188 
3189 static int
3190 ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS)
3191 {
3192 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3193 	device_t dev = pf->dev;
3194 	struct sbuf *buf;
3195 	int error = 0;
3196 
3197 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3198 	if (!buf) {
3199 		device_printf(dev, "Could not allocate sbuf for sysctl output.\n");
3200 		return (ENOMEM);
3201 	}
3202 
3203 	struct i40e_aqc_get_link_status link_status;
3204 	error = ixl_aq_get_link_status(pf, &link_status);
3205 	if (error) {
3206 		sbuf_delete(buf);
3207 		return (error);
3208 	}
3209 
3210 	sbuf_printf(buf, "\n"
3211 	    "PHY Type : 0x%02x<%s>\n"
3212 	    "Speed    : 0x%02x\n"
3213 	    "Link info: 0x%02x\n"
3214 	    "AN info  : 0x%02x\n"
3215 	    "Ext info : 0x%02x\n"
3216 	    "Loopback : 0x%02x\n"
3217 	    "Max Frame: %d\n"
3218 	    "Config   : 0x%02x\n"
3219 	    "Power    : 0x%02x",
3220 	    link_status.phy_type,
3221 	    ixl_phy_type_string_ls(link_status.phy_type),
3222 	    link_status.link_speed,
3223 	    link_status.link_info,
3224 	    link_status.an_info,
3225 	    link_status.ext_info,
3226 	    link_status.loopback,
3227 	    link_status.max_frame_size,
3228 	    link_status.config,
3229 	    link_status.power_desc);
3230 
3231 	error = sbuf_finish(buf);
3232 	if (error)
3233 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3234 
3235 	sbuf_delete(buf);
3236 	return (error);
3237 }
3238 
3239 static int
3240 ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS)
3241 {
3242 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3243 	struct i40e_hw *hw = &pf->hw;
3244 	device_t dev = pf->dev;
3245 	enum i40e_status_code status;
3246 	struct i40e_aq_get_phy_abilities_resp abilities;
3247 	struct sbuf *buf;
3248 	int error = 0;
3249 
3250 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3251 	if (!buf) {
3252 		device_printf(dev, "Could not allocate sbuf for sysctl output.\n");
3253 		return (ENOMEM);
3254 	}
3255 
3256 	status = i40e_aq_get_phy_capabilities(hw,
3257 	    FALSE, FALSE, &abilities, NULL);
3258 	if (status) {
3259 		device_printf(dev,
3260 		    "%s: i40e_aq_get_phy_capabilities() status %s, aq error %s\n",
3261 		    __func__, i40e_stat_str(hw, status),
3262 		    i40e_aq_str(hw, hw->aq.asq_last_status));
3263 		sbuf_delete(buf);
3264 		return (EIO);
3265 	}
3266 
3267 	sbuf_printf(buf, "\n"
3268 	    "PHY Type : %08x",
3269 	    abilities.phy_type);
3270 
3271 	if (abilities.phy_type != 0) {
3272 		sbuf_printf(buf, "<");
3273 		for (int i = 0; i < 32; i++)
3274 			if ((1 << i) & abilities.phy_type)
3275 				sbuf_printf(buf, "%s,", ixl_phy_type_string(i, false));
3276 		sbuf_printf(buf, ">");
3277 	}
3278 
3279 	sbuf_printf(buf, "\nPHY Ext  : %02x",
3280 	    abilities.phy_type_ext);
3281 
3282 	if (abilities.phy_type_ext != 0) {
3283 		sbuf_printf(buf, "<");
3284 		for (int i = 0; i < 4; i++)
3285 			if ((1 << i) & abilities.phy_type_ext)
3286 				sbuf_printf(buf, "%s,",
3287 				    ixl_phy_type_string(i, true));
3288 		sbuf_printf(buf, ">");
3289 	}
3290 
3291 	sbuf_printf(buf, "\nSpeed    : %02x", abilities.link_speed);
3292 	if (abilities.link_speed != 0) {
3293 		u8 link_speed;
3294 		sbuf_printf(buf, " <");
3295 		for (int i = 0; i < 8; i++) {
3296 			link_speed = (1 << i) & abilities.link_speed;
3297 			if (link_speed)
3298 				sbuf_printf(buf, "%s, ",
3299 				    ixl_link_speed_string(link_speed));
3300 		}
3301 		sbuf_printf(buf, ">");
3302 	}
3303 
3304 	sbuf_printf(buf, "\n"
3305 	    "Abilities: %02x\n"
3306 	    "EEE cap  : %04x\n"
3307 	    "EEER reg : %08x\n"
3308 	    "D3 Lpan  : %02x\n"
3309 	    "ID       : %02x %02x %02x %02x\n"
3310 	    "ModType  : %02x %02x %02x\n"
3311 	    "ModType E: %01x\n"
3312 	    "FEC Cfg  : %02x\n"
3313 	    "Ext CC   : %02x",
3314 	    abilities.abilities, abilities.eee_capability,
3315 	    abilities.eeer_val, abilities.d3_lpan,
3316 	    abilities.phy_id[0], abilities.phy_id[1],
3317 	    abilities.phy_id[2], abilities.phy_id[3],
3318 	    abilities.module_type[0], abilities.module_type[1],
3319 	    abilities.module_type[2], (abilities.fec_cfg_curr_mod_ext_info & 0xe0) >> 5,
3320 	    abilities.fec_cfg_curr_mod_ext_info & 0x1F,
3321 	    abilities.ext_comp_code);
3322 
3323 	error = sbuf_finish(buf);
3324 	if (error)
3325 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3326 
3327 	sbuf_delete(buf);
3328 	return (error);
3329 }
3330 
3331 static int
3332 ixl_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS)
3333 {
3334 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3335 	struct ixl_vsi *vsi = &pf->vsi;
3336 	struct ixl_mac_filter *f;
3337 	device_t dev = pf->dev;
3338 	int error = 0, ftl_len = 0, ftl_counter = 0;
3339 
3340 	struct sbuf *buf;
3341 
3342 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3343 	if (!buf) {
3344 		device_printf(dev, "Could not allocate sbuf for sysctl output.\n");
3345 		return (ENOMEM);
3346 	}
3347 
3348 	sbuf_printf(buf, "\n");
3349 
3350 	/* Print MAC filters */
3351 	sbuf_printf(buf, "PF Filters:\n");
3352 	LIST_FOREACH(f, &vsi->ftl, ftle)
3353 		ftl_len++;
3354 
3355 	if (ftl_len < 1)
3356 		sbuf_printf(buf, "(none)\n");
3357 	else {
3358 		LIST_FOREACH(f, &vsi->ftl, ftle) {
3359 			sbuf_printf(buf,
3360 			    MAC_FORMAT ", vlan %4d, flags %#06x",
3361 			    MAC_FORMAT_ARGS(f->macaddr), f->vlan, f->flags);
3362 			/* don't print '\n' for last entry */
3363 			if (++ftl_counter != ftl_len)
3364 				sbuf_printf(buf, "\n");
3365 		}
3366 	}
3367 
3368 #ifdef PCI_IOV
3369 	/* TODO: Give each VF its own filter list sysctl */
3370 	struct ixl_vf *vf;
3371 	if (pf->num_vfs > 0) {
3372 		sbuf_printf(buf, "\n\n");
3373 		for (int i = 0; i < pf->num_vfs; i++) {
3374 			vf = &pf->vfs[i];
3375 			if (!(vf->vf_flags & VF_FLAG_ENABLED))
3376 				continue;
3377 
3378 			vsi = &vf->vsi;
3379 			ftl_len = 0, ftl_counter = 0;
3380 			sbuf_printf(buf, "VF-%d Filters:\n", vf->vf_num);
3381 			LIST_FOREACH(f, &vsi->ftl, ftle)
3382 				ftl_len++;
3383 
3384 			if (ftl_len < 1)
3385 				sbuf_printf(buf, "(none)\n");
3386 			else {
3387 				LIST_FOREACH(f, &vsi->ftl, ftle) {
3388 					sbuf_printf(buf,
3389 					    MAC_FORMAT ", vlan %4d, flags %#06x\n",
3390 					    MAC_FORMAT_ARGS(f->macaddr), f->vlan, f->flags);
3391 				}
3392 			}
3393 		}
3394 	}
3395 #endif
3396 
3397 	error = sbuf_finish(buf);
3398 	if (error)
3399 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3400 	sbuf_delete(buf);
3401 
3402 	return (error);
3403 }
3404 
3405 #define IXL_SW_RES_SIZE 0x14
3406 int
3407 ixl_res_alloc_cmp(const void *a, const void *b)
3408 {
3409 	const struct i40e_aqc_switch_resource_alloc_element_resp *one, *two;
3410 	one = (const struct i40e_aqc_switch_resource_alloc_element_resp *)a;
3411 	two = (const struct i40e_aqc_switch_resource_alloc_element_resp *)b;
3412 
3413 	return ((int)one->resource_type - (int)two->resource_type);
3414 }
3415 
3416 /*
3417  * Longest string length: 25
3418  */
3419 const char *
3420 ixl_switch_res_type_string(u8 type)
3421 {
3422 	static const char * ixl_switch_res_type_strings[IXL_SW_RES_SIZE] = {
3423 		"VEB",
3424 		"VSI",
3425 		"Perfect Match MAC address",
3426 		"S-tag",
3427 		"(Reserved)",
3428 		"Multicast hash entry",
3429 		"Unicast hash entry",
3430 		"VLAN",
3431 		"VSI List entry",
3432 		"(Reserved)",
3433 		"VLAN Statistic Pool",
3434 		"Mirror Rule",
3435 		"Queue Set",
3436 		"Inner VLAN Forward filter",
3437 		"(Reserved)",
3438 		"Inner MAC",
3439 		"IP",
3440 		"GRE/VN1 Key",
3441 		"VN2 Key",
3442 		"Tunneling Port"
3443 	};
3444 
3445 	if (type < IXL_SW_RES_SIZE)
3446 		return ixl_switch_res_type_strings[type];
3447 	else
3448 		return "(Reserved)";
3449 }
3450 
3451 static int
3452 ixl_sysctl_hw_res_alloc(SYSCTL_HANDLER_ARGS)
3453 {
3454 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3455 	struct i40e_hw *hw = &pf->hw;
3456 	device_t dev = pf->dev;
3457 	struct sbuf *buf;
3458 	enum i40e_status_code status;
3459 	int error = 0;
3460 
3461 	u8 num_entries;
3462 	struct i40e_aqc_switch_resource_alloc_element_resp resp[IXL_SW_RES_SIZE];
3463 
3464 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3465 	if (!buf) {
3466 		device_printf(dev, "Could not allocate sbuf for output.\n");
3467 		return (ENOMEM);
3468 	}
3469 
3470 	bzero(resp, sizeof(resp));
3471 	status = i40e_aq_get_switch_resource_alloc(hw, &num_entries,
3472 				resp,
3473 				IXL_SW_RES_SIZE,
3474 				NULL);
3475 	if (status) {
3476 		device_printf(dev,
3477 		    "%s: get_switch_resource_alloc() error %s, aq error %s\n",
3478 		    __func__, i40e_stat_str(hw, status),
3479 		    i40e_aq_str(hw, hw->aq.asq_last_status));
3480 		sbuf_delete(buf);
3481 		return (error);
3482 	}
3483 
3484 	/* Sort entries by type for display */
3485 	qsort(resp, num_entries,
3486 	    sizeof(struct i40e_aqc_switch_resource_alloc_element_resp),
3487 	    &ixl_res_alloc_cmp);
3488 
3489 	sbuf_cat(buf, "\n");
3490 	sbuf_printf(buf, "# of entries: %d\n", num_entries);
3491 	sbuf_printf(buf,
3492 	    "                     Type | Guaranteed | Total | Used   | Un-allocated\n"
3493 	    "                          | (this)     | (all) | (this) | (all)       \n");
3494 	for (int i = 0; i < num_entries; i++) {
3495 		sbuf_printf(buf,
3496 		    "%25s | %10d   %5d   %6d   %12d",
3497 		    ixl_switch_res_type_string(resp[i].resource_type),
3498 		    resp[i].guaranteed,
3499 		    resp[i].total,
3500 		    resp[i].used,
3501 		    resp[i].total_unalloced);
3502 		if (i < num_entries - 1)
3503 			sbuf_cat(buf, "\n");
3504 	}
3505 
3506 	error = sbuf_finish(buf);
3507 	if (error)
3508 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3509 
3510 	sbuf_delete(buf);
3511 	return (error);
3512 }
3513 
3514 enum ixl_sw_seid_offset {
3515 	IXL_SW_SEID_EMP = 1,
3516 	IXL_SW_SEID_MAC_START = 2,
3517 	IXL_SW_SEID_MAC_END = 5,
3518 	IXL_SW_SEID_PF_START = 16,
3519 	IXL_SW_SEID_PF_END = 31,
3520 	IXL_SW_SEID_VF_START = 32,
3521 	IXL_SW_SEID_VF_END = 159,
3522 };
3523 
3524 /*
3525  * Caller must init and delete sbuf; this function will clear and
3526  * finish it for caller.
3527  *
3528  * Note: The SEID argument only applies for elements defined by FW at
3529  * power-on; these include the EMP, Ports, PFs and VFs.
3530  */
3531 static char *
3532 ixl_switch_element_string(struct sbuf *s, u8 element_type, u16 seid)
3533 {
3534 	sbuf_clear(s);
3535 
3536 	/* If SEID is in certain ranges, then we can infer the
3537 	 * mapping of SEID to switch element.
3538 	 */
3539 	if (seid == IXL_SW_SEID_EMP) {
3540 		sbuf_cat(s, "EMP");
3541 		goto out;
3542 	} else if (seid >= IXL_SW_SEID_MAC_START &&
3543 	    seid <= IXL_SW_SEID_MAC_END) {
3544 		sbuf_printf(s, "MAC  %2d",
3545 		    seid - IXL_SW_SEID_MAC_START);
3546 		goto out;
3547 	} else if (seid >= IXL_SW_SEID_PF_START &&
3548 	    seid <= IXL_SW_SEID_PF_END) {
3549 		sbuf_printf(s, "PF  %3d",
3550 		    seid - IXL_SW_SEID_PF_START);
3551 		goto out;
3552 	} else if (seid >= IXL_SW_SEID_VF_START &&
3553 	    seid <= IXL_SW_SEID_VF_END) {
3554 		sbuf_printf(s, "VF  %3d",
3555 		    seid - IXL_SW_SEID_VF_START);
3556 		goto out;
3557 	}
3558 
3559 	switch (element_type) {
3560 	case I40E_AQ_SW_ELEM_TYPE_BMC:
3561 		sbuf_cat(s, "BMC");
3562 		break;
3563 	case I40E_AQ_SW_ELEM_TYPE_PV:
3564 		sbuf_cat(s, "PV");
3565 		break;
3566 	case I40E_AQ_SW_ELEM_TYPE_VEB:
3567 		sbuf_cat(s, "VEB");
3568 		break;
3569 	case I40E_AQ_SW_ELEM_TYPE_PA:
3570 		sbuf_cat(s, "PA");
3571 		break;
3572 	case I40E_AQ_SW_ELEM_TYPE_VSI:
3573 		sbuf_printf(s, "VSI");
3574 		break;
3575 	default:
3576 		sbuf_cat(s, "?");
3577 		break;
3578 	}
3579 
3580 out:
3581 	sbuf_finish(s);
3582 	return sbuf_data(s);
3583 }
3584 
3585 static int
3586 ixl_sw_cfg_elem_seid_cmp(const void *a, const void *b)
3587 {
3588 	const struct i40e_aqc_switch_config_element_resp *one, *two;
3589 	one = (const struct i40e_aqc_switch_config_element_resp *)a;
3590 	two = (const struct i40e_aqc_switch_config_element_resp *)b;
3591 
3592 	return ((int)one->seid - (int)two->seid);
3593 }
3594 
3595 static int
3596 ixl_sysctl_switch_config(SYSCTL_HANDLER_ARGS)
3597 {
3598 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3599 	struct i40e_hw *hw = &pf->hw;
3600 	device_t dev = pf->dev;
3601 	struct sbuf *buf;
3602 	struct sbuf *nmbuf;
3603 	enum i40e_status_code status;
3604 	int error = 0;
3605 	u16 next = 0;
3606 	u8 aq_buf[I40E_AQ_LARGE_BUF];
3607 
3608 	struct i40e_aqc_switch_config_element_resp *elem;
3609 	struct i40e_aqc_get_switch_config_resp *sw_config;
3610 	sw_config = (struct i40e_aqc_get_switch_config_resp *)aq_buf;
3611 
3612 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3613 	if (!buf) {
3614 		device_printf(dev, "Could not allocate sbuf for sysctl output.\n");
3615 		return (ENOMEM);
3616 	}
3617 
3618 	status = i40e_aq_get_switch_config(hw, sw_config,
3619 	    sizeof(aq_buf), &next, NULL);
3620 	if (status) {
3621 		device_printf(dev,
3622 		    "%s: aq_get_switch_config() error %s, aq error %s\n",
3623 		    __func__, i40e_stat_str(hw, status),
3624 		    i40e_aq_str(hw, hw->aq.asq_last_status));
3625 		sbuf_delete(buf);
3626 		return error;
3627 	}
3628 	if (next)
3629 		device_printf(dev, "%s: TODO: get more config with SEID %d\n",
3630 		    __func__, next);
3631 
3632 	nmbuf = sbuf_new_auto();
3633 	if (!nmbuf) {
3634 		device_printf(dev, "Could not allocate sbuf for name output.\n");
3635 		sbuf_delete(buf);
3636 		return (ENOMEM);
3637 	}
3638 
3639 	/* Sort entries by SEID for display */
3640 	qsort(sw_config->element, sw_config->header.num_reported,
3641 	    sizeof(struct i40e_aqc_switch_config_element_resp),
3642 	    &ixl_sw_cfg_elem_seid_cmp);
3643 
3644 	sbuf_cat(buf, "\n");
3645 	/* Assuming <= 255 elements in switch */
3646 	sbuf_printf(buf, "# of reported elements: %d\n", sw_config->header.num_reported);
3647 	sbuf_printf(buf, "total # of elements: %d\n", sw_config->header.num_total);
3648 	/* Exclude:
3649 	 * Revision -- all elements are revision 1 for now
3650 	 */
3651 	sbuf_printf(buf,
3652 	    "SEID (  Name  ) |  Up  (  Name  ) | Down (  Name  ) | Conn Type\n"
3653 	    "                |                 |                 | (uplink)\n");
3654 	for (int i = 0; i < sw_config->header.num_reported; i++) {
3655 		elem = &sw_config->element[i];
3656 
3657 		// "%4d (%8s) | %8s   %8s   %#8x",
3658 		sbuf_printf(buf, "%4d", elem->seid);
3659 		sbuf_cat(buf, " ");
3660 		sbuf_printf(buf, "(%8s)", ixl_switch_element_string(nmbuf,
3661 		    elem->element_type, elem->seid));
3662 		sbuf_cat(buf, " | ");
3663 		sbuf_printf(buf, "%4d", elem->uplink_seid);
3664 		sbuf_cat(buf, " ");
3665 		sbuf_printf(buf, "(%8s)", ixl_switch_element_string(nmbuf,
3666 		    0, elem->uplink_seid));
3667 		sbuf_cat(buf, " | ");
3668 		sbuf_printf(buf, "%4d", elem->downlink_seid);
3669 		sbuf_cat(buf, " ");
3670 		sbuf_printf(buf, "(%8s)", ixl_switch_element_string(nmbuf,
3671 		    0, elem->downlink_seid));
3672 		sbuf_cat(buf, " | ");
3673 		sbuf_printf(buf, "%8d", elem->connection_type);
3674 		if (i < sw_config->header.num_reported - 1)
3675 			sbuf_cat(buf, "\n");
3676 	}
3677 	sbuf_delete(nmbuf);
3678 
3679 	error = sbuf_finish(buf);
3680 	if (error)
3681 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3682 
3683 	sbuf_delete(buf);
3684 
3685 	return (error);
3686 }
3687 
3688 static int
3689 ixl_sysctl_switch_vlans(SYSCTL_HANDLER_ARGS)
3690 {
3691 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3692 	struct i40e_hw *hw = &pf->hw;
3693 	device_t dev = pf->dev;
3694 	int requested_vlan = -1;
3695 	enum i40e_status_code status = 0;
3696 	int error = 0;
3697 
3698 	error = sysctl_handle_int(oidp, &requested_vlan, 0, req);
3699 	if ((error) || (req->newptr == NULL))
3700 	    return (error);
3701 
3702 	if ((hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) == 0) {
3703 		device_printf(dev, "Flags disallow setting of vlans\n");
3704 		return (ENODEV);
3705 	}
3706 
3707 	hw->switch_tag = requested_vlan;
3708 	device_printf(dev,
3709 	    "Setting switch config to switch_tag=%04x, first_tag=%04x, second_tag=%04x\n",
3710 	    hw->switch_tag, hw->first_tag, hw->second_tag);
3711 	status = i40e_aq_set_switch_config(hw, 0, 0, 0, NULL);
3712 	if (status) {
3713 		device_printf(dev,
3714 		    "%s: aq_set_switch_config() error %s, aq error %s\n",
3715 		    __func__, i40e_stat_str(hw, status),
3716 		    i40e_aq_str(hw, hw->aq.asq_last_status));
3717 		return (status);
3718 	}
3719 	return (0);
3720 }
3721 
3722 static int
3723 ixl_sysctl_hkey(SYSCTL_HANDLER_ARGS)
3724 {
3725 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3726 	struct i40e_hw *hw = &pf->hw;
3727 	device_t dev = pf->dev;
3728 	struct sbuf *buf;
3729 	int error = 0;
3730 	enum i40e_status_code status;
3731 	u32 reg;
3732 
3733 	struct i40e_aqc_get_set_rss_key_data key_data;
3734 
3735 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3736 	if (!buf) {
3737 		device_printf(dev, "Could not allocate sbuf for output.\n");
3738 		return (ENOMEM);
3739 	}
3740 
3741 	bzero(&key_data, sizeof(key_data));
3742 
3743 	sbuf_cat(buf, "\n");
3744 	if (hw->mac.type == I40E_MAC_X722) {
3745 		status = i40e_aq_get_rss_key(hw, pf->vsi.vsi_num, &key_data);
3746 		if (status)
3747 			device_printf(dev, "i40e_aq_get_rss_key status %s, error %s\n",
3748 			    i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
3749 	} else {
3750 		for (int i = 0; i < IXL_RSS_KEY_SIZE_REG; i++) {
3751 			reg = i40e_read_rx_ctl(hw, I40E_PFQF_HKEY(i));
3752 			bcopy(&reg, ((caddr_t)&key_data) + (i << 2), 4);
3753 		}
3754 	}
3755 
3756 	ixl_sbuf_print_bytes(buf, (u8 *)&key_data, sizeof(key_data), 0, true);
3757 
3758 	error = sbuf_finish(buf);
3759 	if (error)
3760 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3761 	sbuf_delete(buf);
3762 
3763 	return (error);
3764 }
3765 
3766 static void
3767 ixl_sbuf_print_bytes(struct sbuf *sb, u8 *buf, int length, int label_offset, bool text)
3768 {
3769 	int i, j, k, width;
3770 	char c;
3771 
3772 	if (length < 1 || buf == NULL) return;
3773 
3774 	int byte_stride = 16;
3775 	int lines = length / byte_stride;
3776 	int rem = length % byte_stride;
3777 	if (rem > 0)
3778 		lines++;
3779 
3780 	for (i = 0; i < lines; i++) {
3781 		width = (rem > 0 && i == lines - 1)
3782 		    ? rem : byte_stride;
3783 
3784 		sbuf_printf(sb, "%4d | ", label_offset + i * byte_stride);
3785 
3786 		for (j = 0; j < width; j++)
3787 			sbuf_printf(sb, "%02x ", buf[i * byte_stride + j]);
3788 
3789 		if (width < byte_stride) {
3790 			for (k = 0; k < (byte_stride - width); k++)
3791 				sbuf_printf(sb, "   ");
3792 		}
3793 
3794 		if (!text) {
3795 			sbuf_printf(sb, "\n");
3796 			continue;
3797 		}
3798 
3799 		for (j = 0; j < width; j++) {
3800 			c = (char)buf[i * byte_stride + j];
3801 			if (c < 32 || c > 126)
3802 				sbuf_printf(sb, ".");
3803 			else
3804 				sbuf_printf(sb, "%c", c);
3805 
3806 			if (j == width - 1)
3807 				sbuf_printf(sb, "\n");
3808 		}
3809 	}
3810 }
3811 
3812 static int
3813 ixl_sysctl_hlut(SYSCTL_HANDLER_ARGS)
3814 {
3815 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3816 	struct i40e_hw *hw = &pf->hw;
3817 	device_t dev = pf->dev;
3818 	struct sbuf *buf;
3819 	int error = 0;
3820 	enum i40e_status_code status;
3821 	u8 hlut[512];
3822 	u32 reg;
3823 
3824 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3825 	if (!buf) {
3826 		device_printf(dev, "Could not allocate sbuf for output.\n");
3827 		return (ENOMEM);
3828 	}
3829 
3830 	bzero(hlut, sizeof(hlut));
3831 	sbuf_cat(buf, "\n");
3832 	if (hw->mac.type == I40E_MAC_X722) {
3833 		status = i40e_aq_get_rss_lut(hw, pf->vsi.vsi_num, TRUE, hlut, sizeof(hlut));
3834 		if (status)
3835 			device_printf(dev, "i40e_aq_get_rss_lut status %s, error %s\n",
3836 			    i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
3837 	} else {
3838 		for (int i = 0; i < hw->func_caps.rss_table_size >> 2; i++) {
3839 			reg = rd32(hw, I40E_PFQF_HLUT(i));
3840 			bcopy(&reg, &hlut[i << 2], 4);
3841 		}
3842 	}
3843 	ixl_sbuf_print_bytes(buf, hlut, 512, 0, false);
3844 
3845 	error = sbuf_finish(buf);
3846 	if (error)
3847 		device_printf(dev, "Error finishing sbuf: %d\n", error);
3848 	sbuf_delete(buf);
3849 
3850 	return (error);
3851 }
3852 
3853 static int
3854 ixl_sysctl_hena(SYSCTL_HANDLER_ARGS)
3855 {
3856 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3857 	struct i40e_hw *hw = &pf->hw;
3858 	u64 hena;
3859 
3860 	hena = (u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0)) |
3861 	    ((u64)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1)) << 32);
3862 
3863 	return sysctl_handle_long(oidp, NULL, hena, req);
3864 }
3865 
3866 /*
3867  * Sysctl to disable firmware's link management
3868  *
3869  * 1 - Disable link management on this port
3870  * 0 - Re-enable link management
3871  *
3872  * On normal NVMs, firmware manages link by default.
3873  */
3874 static int
3875 ixl_sysctl_fw_link_management(SYSCTL_HANDLER_ARGS)
3876 {
3877 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3878 	struct i40e_hw *hw = &pf->hw;
3879 	device_t dev = pf->dev;
3880 	int requested_mode = -1;
3881 	enum i40e_status_code status = 0;
3882 	int error = 0;
3883 
3884 	/* Read in new mode */
3885 	error = sysctl_handle_int(oidp, &requested_mode, 0, req);
3886 	if ((error) || (req->newptr == NULL))
3887 		return (error);
3888 	/* Check for sane value */
3889 	if (requested_mode < 0 || requested_mode > 1) {
3890 		device_printf(dev, "Valid modes are 0 or 1\n");
3891 		return (EINVAL);
3892 	}
3893 
3894 	/* Set new mode */
3895 	status = i40e_aq_set_phy_debug(hw, !!(requested_mode) << 4, NULL);
3896 	if (status) {
3897 		device_printf(dev,
3898 		    "%s: Error setting new phy debug mode %s,"
3899 		    " aq error: %s\n", __func__, i40e_stat_str(hw, status),
3900 		    i40e_aq_str(hw, hw->aq.asq_last_status));
3901 		return (EIO);
3902 	}
3903 
3904 	return (0);
3905 }
3906 
3907 /*
3908  * Read some diagnostic data from a (Q)SFP+ module
3909  *
3910  *             SFP A2   QSFP Lower Page
3911  * Temperature 96-97	22-23
3912  * Vcc         98-99    26-27
3913  * TX power    102-103  34-35..40-41
3914  * RX power    104-105  50-51..56-57
3915  */
3916 static int
3917 ixl_sysctl_read_i2c_diag_data(SYSCTL_HANDLER_ARGS)
3918 {
3919 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
3920 	device_t dev = pf->dev;
3921 	struct sbuf *sbuf;
3922 	int error = 0;
3923 	u8 output;
3924 
3925 	if (req->oldptr == NULL) {
3926 		error = SYSCTL_OUT(req, 0, 128);
3927 		return (0);
3928 	}
3929 
3930 	error = pf->read_i2c_byte(pf, 0, 0xA0, &output);
3931 	if (error) {
3932 		device_printf(dev, "Error reading from i2c\n");
3933 		return (error);
3934 	}
3935 
3936 	/* 0x3 for SFP; 0xD/0x11 for QSFP+/QSFP28 */
3937 	if (output == 0x3) {
3938 		/*
3939 		 * Check for:
3940 		 * - Internally calibrated data
3941 		 * - Diagnostic monitoring is implemented
3942 		 */
3943 		pf->read_i2c_byte(pf, 92, 0xA0, &output);
3944 		if (!(output & 0x60)) {
3945 			device_printf(dev, "Module doesn't support diagnostics: %02X\n", output);
3946 			return (0);
3947 		}
3948 
3949 		sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3950 
3951 		for (u8 offset = 96; offset < 100; offset++) {
3952 			pf->read_i2c_byte(pf, offset, 0xA2, &output);
3953 			sbuf_printf(sbuf, "%02X ", output);
3954 		}
3955 		for (u8 offset = 102; offset < 106; offset++) {
3956 			pf->read_i2c_byte(pf, offset, 0xA2, &output);
3957 			sbuf_printf(sbuf, "%02X ", output);
3958 		}
3959 	} else if (output == 0xD || output == 0x11) {
3960 		/*
3961 		 * QSFP+ modules are always internally calibrated, and must indicate
3962 		 * what types of diagnostic monitoring are implemented
3963 		 */
3964 		sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3965 
3966 		for (u8 offset = 22; offset < 24; offset++) {
3967 			pf->read_i2c_byte(pf, offset, 0xA0, &output);
3968 			sbuf_printf(sbuf, "%02X ", output);
3969 		}
3970 		for (u8 offset = 26; offset < 28; offset++) {
3971 			pf->read_i2c_byte(pf, offset, 0xA0, &output);
3972 			sbuf_printf(sbuf, "%02X ", output);
3973 		}
3974 		/* Read the data from the first lane */
3975 		for (u8 offset = 34; offset < 36; offset++) {
3976 			pf->read_i2c_byte(pf, offset, 0xA0, &output);
3977 			sbuf_printf(sbuf, "%02X ", output);
3978 		}
3979 		for (u8 offset = 50; offset < 52; offset++) {
3980 			pf->read_i2c_byte(pf, offset, 0xA0, &output);
3981 			sbuf_printf(sbuf, "%02X ", output);
3982 		}
3983 	} else {
3984 		device_printf(dev, "Module is not SFP/SFP+/SFP28/QSFP+ (%02X)\n", output);
3985 		return (0);
3986 	}
3987 
3988 	sbuf_finish(sbuf);
3989 	sbuf_delete(sbuf);
3990 
3991 	return (0);
3992 }
3993 
3994 /*
3995  * Sysctl to read a byte from I2C bus.
3996  *
3997  * Input: 32-bit value:
3998  * 	bits 0-7:   device address (0xA0 or 0xA2)
3999  * 	bits 8-15:  offset (0-255)
4000  *	bits 16-31: unused
4001  * Output: 8-bit value read
4002  */
4003 static int
4004 ixl_sysctl_read_i2c_byte(SYSCTL_HANDLER_ARGS)
4005 {
4006 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4007 	device_t dev = pf->dev;
4008 	int input = -1, error = 0;
4009 	u8 dev_addr, offset, output;
4010 
4011 	/* Read in I2C read parameters */
4012 	error = sysctl_handle_int(oidp, &input, 0, req);
4013 	if ((error) || (req->newptr == NULL))
4014 		return (error);
4015 	/* Validate device address */
4016 	dev_addr = input & 0xFF;
4017 	if (dev_addr != 0xA0 && dev_addr != 0xA2) {
4018 		return (EINVAL);
4019 	}
4020 	offset = (input >> 8) & 0xFF;
4021 
4022 	error = pf->read_i2c_byte(pf, offset, dev_addr, &output);
4023 	if (error)
4024 		return (error);
4025 
4026 	device_printf(dev, "%02X\n", output);
4027 	return (0);
4028 }
4029 
4030 /*
4031  * Sysctl to write a byte to the I2C bus.
4032  *
4033  * Input: 32-bit value:
4034  * 	bits 0-7:   device address (0xA0 or 0xA2)
4035  * 	bits 8-15:  offset (0-255)
4036  *	bits 16-23: value to write
4037  *	bits 24-31: unused
4038  * Output: 8-bit value written
4039  */
4040 static int
4041 ixl_sysctl_write_i2c_byte(SYSCTL_HANDLER_ARGS)
4042 {
4043 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4044 	device_t dev = pf->dev;
4045 	int input = -1, error = 0;
4046 	u8 dev_addr, offset, value;
4047 
4048 	/* Read in I2C write parameters */
4049 	error = sysctl_handle_int(oidp, &input, 0, req);
4050 	if ((error) || (req->newptr == NULL))
4051 		return (error);
4052 	/* Validate device address */
4053 	dev_addr = input & 0xFF;
4054 	if (dev_addr != 0xA0 && dev_addr != 0xA2) {
4055 		return (EINVAL);
4056 	}
4057 	offset = (input >> 8) & 0xFF;
4058 	value = (input >> 16) & 0xFF;
4059 
4060 	error = pf->write_i2c_byte(pf, offset, dev_addr, value);
4061 	if (error)
4062 		return (error);
4063 
4064 	device_printf(dev, "%02X written\n", value);
4065 	return (0);
4066 }
4067 
4068 static int
4069 ixl_get_fec_config(struct ixl_pf *pf, struct i40e_aq_get_phy_abilities_resp *abilities,
4070     u8 bit_pos, int *is_set)
4071 {
4072 	device_t dev = pf->dev;
4073 	struct i40e_hw *hw = &pf->hw;
4074 	enum i40e_status_code status;
4075 
4076 	if (IXL_PF_IN_RECOVERY_MODE(pf))
4077 		return (EIO);
4078 
4079 	status = i40e_aq_get_phy_capabilities(hw,
4080 	    FALSE, FALSE, abilities, NULL);
4081 	if (status) {
4082 		device_printf(dev,
4083 		    "%s: i40e_aq_get_phy_capabilities() status %s, aq error %s\n",
4084 		    __func__, i40e_stat_str(hw, status),
4085 		    i40e_aq_str(hw, hw->aq.asq_last_status));
4086 		return (EIO);
4087 	}
4088 
4089 	*is_set = !!(abilities->fec_cfg_curr_mod_ext_info & bit_pos);
4090 	return (0);
4091 }
4092 
4093 static int
4094 ixl_set_fec_config(struct ixl_pf *pf, struct i40e_aq_get_phy_abilities_resp *abilities,
4095     u8 bit_pos, int set)
4096 {
4097 	device_t dev = pf->dev;
4098 	struct i40e_hw *hw = &pf->hw;
4099 	struct i40e_aq_set_phy_config config;
4100 	enum i40e_status_code status;
4101 
4102 	/* Set new PHY config */
4103 	memset(&config, 0, sizeof(config));
4104 	config.fec_config = abilities->fec_cfg_curr_mod_ext_info & ~(bit_pos);
4105 	if (set)
4106 		config.fec_config |= bit_pos;
4107 	if (config.fec_config != abilities->fec_cfg_curr_mod_ext_info) {
4108 		config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
4109 		config.phy_type = abilities->phy_type;
4110 		config.phy_type_ext = abilities->phy_type_ext;
4111 		config.link_speed = abilities->link_speed;
4112 		config.eee_capability = abilities->eee_capability;
4113 		config.eeer = abilities->eeer_val;
4114 		config.low_power_ctrl = abilities->d3_lpan;
4115 		status = i40e_aq_set_phy_config(hw, &config, NULL);
4116 
4117 		if (status) {
4118 			device_printf(dev,
4119 			    "%s: i40e_aq_set_phy_config() status %s, aq error %s\n",
4120 			    __func__, i40e_stat_str(hw, status),
4121 			    i40e_aq_str(hw, hw->aq.asq_last_status));
4122 			return (EIO);
4123 		}
4124 	}
4125 
4126 	return (0);
4127 }
4128 
4129 static int
4130 ixl_sysctl_fec_fc_ability(SYSCTL_HANDLER_ARGS)
4131 {
4132 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4133 	int mode, error = 0;
4134 
4135 	struct i40e_aq_get_phy_abilities_resp abilities;
4136 	error = ixl_get_fec_config(pf, &abilities, I40E_AQ_ENABLE_FEC_KR, &mode);
4137 	if (error)
4138 		return (error);
4139 	/* Read in new mode */
4140 	error = sysctl_handle_int(oidp, &mode, 0, req);
4141 	if ((error) || (req->newptr == NULL))
4142 		return (error);
4143 
4144 	return ixl_set_fec_config(pf, &abilities, I40E_AQ_SET_FEC_ABILITY_KR, !!(mode));
4145 }
4146 
4147 static int
4148 ixl_sysctl_fec_rs_ability(SYSCTL_HANDLER_ARGS)
4149 {
4150 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4151 	int mode, error = 0;
4152 
4153 	struct i40e_aq_get_phy_abilities_resp abilities;
4154 	error = ixl_get_fec_config(pf, &abilities, I40E_AQ_ENABLE_FEC_RS, &mode);
4155 	if (error)
4156 		return (error);
4157 	/* Read in new mode */
4158 	error = sysctl_handle_int(oidp, &mode, 0, req);
4159 	if ((error) || (req->newptr == NULL))
4160 		return (error);
4161 
4162 	return ixl_set_fec_config(pf, &abilities, I40E_AQ_SET_FEC_ABILITY_RS, !!(mode));
4163 }
4164 
4165 static int
4166 ixl_sysctl_fec_fc_request(SYSCTL_HANDLER_ARGS)
4167 {
4168 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4169 	int mode, error = 0;
4170 
4171 	struct i40e_aq_get_phy_abilities_resp abilities;
4172 	error = ixl_get_fec_config(pf, &abilities, I40E_AQ_REQUEST_FEC_KR, &mode);
4173 	if (error)
4174 		return (error);
4175 	/* Read in new mode */
4176 	error = sysctl_handle_int(oidp, &mode, 0, req);
4177 	if ((error) || (req->newptr == NULL))
4178 		return (error);
4179 
4180 	return ixl_set_fec_config(pf, &abilities, I40E_AQ_SET_FEC_REQUEST_KR, !!(mode));
4181 }
4182 
4183 static int
4184 ixl_sysctl_fec_rs_request(SYSCTL_HANDLER_ARGS)
4185 {
4186 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4187 	int mode, error = 0;
4188 
4189 	struct i40e_aq_get_phy_abilities_resp abilities;
4190 	error = ixl_get_fec_config(pf, &abilities, I40E_AQ_REQUEST_FEC_RS, &mode);
4191 	if (error)
4192 		return (error);
4193 	/* Read in new mode */
4194 	error = sysctl_handle_int(oidp, &mode, 0, req);
4195 	if ((error) || (req->newptr == NULL))
4196 		return (error);
4197 
4198 	return ixl_set_fec_config(pf, &abilities, I40E_AQ_SET_FEC_REQUEST_RS, !!(mode));
4199 }
4200 
4201 static int
4202 ixl_sysctl_fec_auto_enable(SYSCTL_HANDLER_ARGS)
4203 {
4204 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4205 	int mode, error = 0;
4206 
4207 	struct i40e_aq_get_phy_abilities_resp abilities;
4208 	error = ixl_get_fec_config(pf, &abilities, I40E_AQ_ENABLE_FEC_AUTO, &mode);
4209 	if (error)
4210 		return (error);
4211 	/* Read in new mode */
4212 	error = sysctl_handle_int(oidp, &mode, 0, req);
4213 	if ((error) || (req->newptr == NULL))
4214 		return (error);
4215 
4216 	return ixl_set_fec_config(pf, &abilities, I40E_AQ_SET_FEC_AUTO, !!(mode));
4217 }
4218 
4219 static int
4220 ixl_sysctl_dump_debug_data(SYSCTL_HANDLER_ARGS)
4221 {
4222 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4223 	struct i40e_hw *hw = &pf->hw;
4224 	device_t dev = pf->dev;
4225 	struct sbuf *buf;
4226 	int error = 0;
4227 	enum i40e_status_code status;
4228 
4229 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
4230 	if (!buf) {
4231 		device_printf(dev, "Could not allocate sbuf for output.\n");
4232 		return (ENOMEM);
4233 	}
4234 
4235 	u8 *final_buff;
4236 	/* This amount is only necessary if reading the entire cluster into memory */
4237 #define IXL_FINAL_BUFF_SIZE	(1280 * 1024)
4238 	final_buff = malloc(IXL_FINAL_BUFF_SIZE, M_IXL, M_NOWAIT);
4239 	if (final_buff == NULL) {
4240 		device_printf(dev, "Could not allocate memory for output.\n");
4241 		goto out;
4242 	}
4243 	int final_buff_len = 0;
4244 
4245 	u8 cluster_id = 1;
4246 	bool more = true;
4247 
4248 	u8 dump_buf[4096];
4249 	u16 curr_buff_size = 4096;
4250 	u8 curr_next_table = 0;
4251 	u32 curr_next_index = 0;
4252 
4253 	u16 ret_buff_size;
4254 	u8 ret_next_table;
4255 	u32 ret_next_index;
4256 
4257 	sbuf_cat(buf, "\n");
4258 
4259 	while (more) {
4260 		status = i40e_aq_debug_dump(hw, cluster_id, curr_next_table, curr_next_index, curr_buff_size,
4261 		    dump_buf, &ret_buff_size, &ret_next_table, &ret_next_index, NULL);
4262 		if (status) {
4263 			device_printf(dev, "i40e_aq_debug_dump status %s, error %s\n",
4264 			    i40e_stat_str(hw, status), i40e_aq_str(hw, hw->aq.asq_last_status));
4265 			goto free_out;
4266 		}
4267 
4268 		/* copy info out of temp buffer */
4269 		bcopy(dump_buf, (caddr_t)final_buff + final_buff_len, ret_buff_size);
4270 		final_buff_len += ret_buff_size;
4271 
4272 		if (ret_next_table != curr_next_table) {
4273 			/* We're done with the current table; we can dump out read data. */
4274 			sbuf_printf(buf, "%d:", curr_next_table);
4275 			int bytes_printed = 0;
4276 			while (bytes_printed <= final_buff_len) {
4277 				sbuf_printf(buf, "%16D", ((caddr_t)final_buff + bytes_printed), "");
4278 				bytes_printed += 16;
4279 			}
4280 				sbuf_cat(buf, "\n");
4281 
4282 			/* The entire cluster has been read; we're finished */
4283 			if (ret_next_table == 0xFF)
4284 				break;
4285 
4286 			/* Otherwise clear the output buffer and continue reading */
4287 			bzero(final_buff, IXL_FINAL_BUFF_SIZE);
4288 			final_buff_len = 0;
4289 		}
4290 
4291 		if (ret_next_index == 0xFFFFFFFF)
4292 			ret_next_index = 0;
4293 
4294 		bzero(dump_buf, sizeof(dump_buf));
4295 		curr_next_table = ret_next_table;
4296 		curr_next_index = ret_next_index;
4297 	}
4298 
4299 free_out:
4300 	free(final_buff, M_IXL);
4301 out:
4302 	error = sbuf_finish(buf);
4303 	if (error)
4304 		device_printf(dev, "Error finishing sbuf: %d\n", error);
4305 	sbuf_delete(buf);
4306 
4307 	return (error);
4308 }
4309 
4310 static int
4311 ixl_start_fw_lldp(struct ixl_pf *pf)
4312 {
4313 	struct i40e_hw *hw = &pf->hw;
4314 	enum i40e_status_code status;
4315 
4316 	status = i40e_aq_start_lldp(hw, false, NULL);
4317 	if (status != I40E_SUCCESS) {
4318 		switch (hw->aq.asq_last_status) {
4319 		case I40E_AQ_RC_EEXIST:
4320 			device_printf(pf->dev,
4321 			    "FW LLDP agent is already running\n");
4322 			break;
4323 		case I40E_AQ_RC_EPERM:
4324 			device_printf(pf->dev,
4325 			    "Device configuration forbids SW from starting "
4326 			    "the LLDP agent. Set the \"LLDP Agent\" UEFI HII "
4327 			    "attribute to \"Enabled\" to use this sysctl\n");
4328 			return (EINVAL);
4329 		default:
4330 			device_printf(pf->dev,
4331 			    "Starting FW LLDP agent failed: error: %s, %s\n",
4332 			    i40e_stat_str(hw, status),
4333 			    i40e_aq_str(hw, hw->aq.asq_last_status));
4334 			return (EINVAL);
4335 		}
4336 	}
4337 
4338 	atomic_clear_32(&pf->state, IXL_PF_STATE_FW_LLDP_DISABLED);
4339 	return (0);
4340 }
4341 
4342 static int
4343 ixl_stop_fw_lldp(struct ixl_pf *pf)
4344 {
4345 	struct i40e_hw *hw = &pf->hw;
4346 	device_t dev = pf->dev;
4347 	enum i40e_status_code status;
4348 
4349 	if (hw->func_caps.npar_enable != 0) {
4350 		device_printf(dev,
4351 		    "Disabling FW LLDP agent is not supported on this device\n");
4352 		return (EINVAL);
4353 	}
4354 
4355 	if ((hw->flags & I40E_HW_FLAG_FW_LLDP_STOPPABLE) == 0) {
4356 		device_printf(dev,
4357 		    "Disabling FW LLDP agent is not supported in this FW version. Please update FW to enable this feature.\n");
4358 		return (EINVAL);
4359 	}
4360 
4361 	status = i40e_aq_stop_lldp(hw, true, false, NULL);
4362 	if (status != I40E_SUCCESS) {
4363 		if (hw->aq.asq_last_status != I40E_AQ_RC_EPERM) {
4364 			device_printf(dev,
4365 			    "Disabling FW LLDP agent failed: error: %s, %s\n",
4366 			    i40e_stat_str(hw, status),
4367 			    i40e_aq_str(hw, hw->aq.asq_last_status));
4368 			return (EINVAL);
4369 		}
4370 
4371 		device_printf(dev, "FW LLDP agent is already stopped\n");
4372 	}
4373 
4374 	i40e_aq_set_dcb_parameters(hw, true, NULL);
4375 	atomic_set_32(&pf->state, IXL_PF_STATE_FW_LLDP_DISABLED);
4376 	return (0);
4377 }
4378 
4379 static int
4380 ixl_sysctl_fw_lldp(SYSCTL_HANDLER_ARGS)
4381 {
4382 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4383 	int state, new_state, error = 0;
4384 
4385 	state = new_state = ((pf->state & IXL_PF_STATE_FW_LLDP_DISABLED) == 0);
4386 
4387 	/* Read in new mode */
4388 	error = sysctl_handle_int(oidp, &new_state, 0, req);
4389 	if ((error) || (req->newptr == NULL))
4390 		return (error);
4391 
4392 	/* Already in requested state */
4393 	if (new_state == state)
4394 		return (error);
4395 
4396 	if (new_state == 0)
4397 		return ixl_stop_fw_lldp(pf);
4398 
4399 	return ixl_start_fw_lldp(pf);
4400 }
4401 
4402 static int
4403 ixl_sysctl_eee_enable(SYSCTL_HANDLER_ARGS)
4404 {
4405 	struct ixl_pf         *pf = (struct ixl_pf *)arg1;
4406 	int                   state, new_state;
4407 	int                   sysctl_handle_status = 0;
4408 	enum i40e_status_code cmd_status;
4409 
4410 	/* Init states' values */
4411 	state = new_state = (!!(pf->state & IXL_PF_STATE_EEE_ENABLED));
4412 
4413 	/* Get requested mode */
4414 	sysctl_handle_status = sysctl_handle_int(oidp, &new_state, 0, req);
4415 	if ((sysctl_handle_status) || (req->newptr == NULL))
4416 		return (sysctl_handle_status);
4417 
4418 	/* Check if state has changed */
4419 	if (new_state == state)
4420 		return (0);
4421 
4422 	/* Set new state */
4423 	cmd_status = i40e_enable_eee(&pf->hw, (bool)(!!new_state));
4424 
4425 	/* Save new state or report error */
4426 	if (!cmd_status) {
4427 		if (new_state == 0)
4428 			atomic_clear_32(&pf->state, IXL_PF_STATE_EEE_ENABLED);
4429 		else
4430 			atomic_set_32(&pf->state, IXL_PF_STATE_EEE_ENABLED);
4431 	} else if (cmd_status == I40E_ERR_CONFIG)
4432 		return (EPERM);
4433 	else
4434 		return (EIO);
4435 
4436 	return (0);
4437 }
4438 
4439 int
4440 ixl_attach_get_link_status(struct ixl_pf *pf)
4441 {
4442 	struct i40e_hw *hw = &pf->hw;
4443 	device_t dev = pf->dev;
4444 	int error = 0;
4445 
4446 	if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
4447 	    (hw->aq.fw_maj_ver < 4)) {
4448 		i40e_msec_delay(75);
4449 		error = i40e_aq_set_link_restart_an(hw, TRUE, NULL);
4450 		if (error) {
4451 			device_printf(dev, "link restart failed, aq_err=%d\n",
4452 			    pf->hw.aq.asq_last_status);
4453 			return error;
4454 		}
4455 	}
4456 
4457 	/* Determine link state */
4458 	hw->phy.get_link_info = TRUE;
4459 	i40e_get_link_status(hw, &pf->link_up);
4460 	return (0);
4461 }
4462 
4463 static int
4464 ixl_sysctl_do_pf_reset(SYSCTL_HANDLER_ARGS)
4465 {
4466 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4467 	int requested = 0, error = 0;
4468 
4469 	/* Read in new mode */
4470 	error = sysctl_handle_int(oidp, &requested, 0, req);
4471 	if ((error) || (req->newptr == NULL))
4472 		return (error);
4473 
4474 	/* Initiate the PF reset later in the admin task */
4475 	atomic_set_32(&pf->state, IXL_PF_STATE_PF_RESET_REQ);
4476 
4477 	return (error);
4478 }
4479 
4480 static int
4481 ixl_sysctl_do_core_reset(SYSCTL_HANDLER_ARGS)
4482 {
4483 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4484 	struct i40e_hw *hw = &pf->hw;
4485 	int requested = 0, error = 0;
4486 
4487 	/* Read in new mode */
4488 	error = sysctl_handle_int(oidp, &requested, 0, req);
4489 	if ((error) || (req->newptr == NULL))
4490 		return (error);
4491 
4492 	wr32(hw, I40E_GLGEN_RTRIG, I40E_GLGEN_RTRIG_CORER_MASK);
4493 
4494 	return (error);
4495 }
4496 
4497 static int
4498 ixl_sysctl_do_global_reset(SYSCTL_HANDLER_ARGS)
4499 {
4500 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4501 	struct i40e_hw *hw = &pf->hw;
4502 	int requested = 0, error = 0;
4503 
4504 	/* Read in new mode */
4505 	error = sysctl_handle_int(oidp, &requested, 0, req);
4506 	if ((error) || (req->newptr == NULL))
4507 		return (error);
4508 
4509 	wr32(hw, I40E_GLGEN_RTRIG, I40E_GLGEN_RTRIG_GLOBR_MASK);
4510 
4511 	return (error);
4512 }
4513 
4514 /*
4515  * Print out mapping of TX queue indexes and Rx queue indexes
4516  * to MSI-X vectors.
4517  */
4518 static int
4519 ixl_sysctl_queue_interrupt_table(SYSCTL_HANDLER_ARGS)
4520 {
4521 	struct ixl_pf *pf = (struct ixl_pf *)arg1;
4522 	struct ixl_vsi *vsi = &pf->vsi;
4523 	device_t dev = pf->dev;
4524 	struct sbuf *buf;
4525 	int error = 0;
4526 
4527 	struct ixl_rx_queue *rx_que = vsi->rx_queues;
4528 	struct ixl_tx_queue *tx_que = vsi->tx_queues;
4529 
4530 	buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
4531 	if (!buf) {
4532 		device_printf(dev, "Could not allocate sbuf for output.\n");
4533 		return (ENOMEM);
4534 	}
4535 
4536 	sbuf_cat(buf, "\n");
4537 	for (int i = 0; i < vsi->num_rx_queues; i++) {
4538 		rx_que = &vsi->rx_queues[i];
4539 		sbuf_printf(buf, "(rxq %3d): %d\n", i, rx_que->msix);
4540 	}
4541 	for (int i = 0; i < vsi->num_tx_queues; i++) {
4542 		tx_que = &vsi->tx_queues[i];
4543 		sbuf_printf(buf, "(txq %3d): %d\n", i, tx_que->msix);
4544 	}
4545 
4546 	error = sbuf_finish(buf);
4547 	if (error)
4548 		device_printf(dev, "Error finishing sbuf: %d\n", error);
4549 	sbuf_delete(buf);
4550 
4551 	return (error);
4552 }
4553