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