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