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