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