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