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