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