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