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(®, ((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(®, &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