1/*- 2 * Copyright 2021 Intel Corp 3 * Copyright 2021 Rubicon Communications, LLC (Netgate) 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7#include <sys/cdefs.h> 8#include "igc_api.h" 9 10/** 11 * igc_init_mac_params - Initialize MAC function pointers 12 * @hw: pointer to the HW structure 13 * 14 * This function initializes the function pointers for the MAC 15 * set of functions. Called by drivers or by igc_setup_init_funcs. 16 **/ 17s32 igc_init_mac_params(struct igc_hw *hw) 18{ 19 s32 ret_val = IGC_SUCCESS; 20 21 if (hw->mac.ops.init_params) { 22 ret_val = hw->mac.ops.init_params(hw); 23 if (ret_val) { 24 DEBUGOUT("MAC Initialization Error\n"); 25 goto out; 26 } 27 } else { 28 DEBUGOUT("mac.init_mac_params was NULL\n"); 29 ret_val = -IGC_ERR_CONFIG; 30 } 31 32out: 33 return ret_val; 34} 35 36/** 37 * igc_init_nvm_params - Initialize NVM function pointers 38 * @hw: pointer to the HW structure 39 * 40 * This function initializes the function pointers for the NVM 41 * set of functions. Called by drivers or by igc_setup_init_funcs. 42 **/ 43s32 igc_init_nvm_params(struct igc_hw *hw) 44{ 45 s32 ret_val = IGC_SUCCESS; 46 47 if (hw->nvm.ops.init_params) { 48 ret_val = hw->nvm.ops.init_params(hw); 49 if (ret_val) { 50 DEBUGOUT("NVM Initialization Error\n"); 51 goto out; 52 } 53 } else { 54 DEBUGOUT("nvm.init_nvm_params was NULL\n"); 55 ret_val = -IGC_ERR_CONFIG; 56 } 57 58out: 59 return ret_val; 60} 61 62/** 63 * igc_init_phy_params - Initialize PHY function pointers 64 * @hw: pointer to the HW structure 65 * 66 * This function initializes the function pointers for the PHY 67 * set of functions. Called by drivers or by igc_setup_init_funcs. 68 **/ 69s32 igc_init_phy_params(struct igc_hw *hw) 70{ 71 s32 ret_val = IGC_SUCCESS; 72 73 if (hw->phy.ops.init_params) { 74 ret_val = hw->phy.ops.init_params(hw); 75 if (ret_val) { 76 DEBUGOUT("PHY Initialization Error\n"); 77 goto out; 78 } 79 } else { 80 DEBUGOUT("phy.init_phy_params was NULL\n"); 81 ret_val = -IGC_ERR_CONFIG; 82 } 83 84out: 85 return ret_val; 86} 87 88/** 89 * igc_set_mac_type - Sets MAC type 90 * @hw: pointer to the HW structure 91 * 92 * This function sets the mac type of the adapter based on the 93 * device ID stored in the hw structure. 94 * MUST BE FIRST FUNCTION CALLED (explicitly or through 95 * igc_setup_init_funcs()). 96 **/ 97s32 igc_set_mac_type(struct igc_hw *hw) 98{ 99 struct igc_mac_info *mac = &hw->mac; 100 s32 ret_val = IGC_SUCCESS; 101 102 DEBUGFUNC("igc_set_mac_type"); 103 104 switch (hw->device_id) { 105 case IGC_DEV_ID_I225_LM: 106 case IGC_DEV_ID_I225_V: 107 case IGC_DEV_ID_I225_K: 108 case IGC_DEV_ID_I225_I: 109 case IGC_DEV_ID_I220_V: 110 case IGC_DEV_ID_I225_K2: 111 case IGC_DEV_ID_I225_LMVP: 112 case IGC_DEV_ID_I225_IT: 113 case IGC_DEV_ID_I226_LM: 114 case IGC_DEV_ID_I226_V: 115 case IGC_DEV_ID_I226_IT: 116 case IGC_DEV_ID_I221_V: 117 case IGC_DEV_ID_I226_BLANK_NVM: 118 case IGC_DEV_ID_I225_BLANK_NVM: 119 mac->type = igc_i225; 120 break; 121 default: 122 /* Should never have loaded on this device */ 123 ret_val = -IGC_ERR_MAC_INIT; 124 break; 125 } 126 127 return ret_val; 128} 129 130/** 131 * igc_setup_init_funcs - Initializes function pointers 132 * @hw: pointer to the HW structure 133 * @init_device: true will initialize the rest of the function pointers 134 * getting the device ready for use. FALSE will only set 135 * MAC type and the function pointers for the other init 136 * functions. Passing FALSE will not generate any hardware 137 * reads or writes. 138 * 139 * This function must be called by a driver in order to use the rest 140 * of the 'shared' code files. Called by drivers only. 141 **/ 142s32 igc_setup_init_funcs(struct igc_hw *hw, bool init_device) 143{ 144 s32 ret_val; 145 146 /* Can't do much good without knowing the MAC type. */ 147 ret_val = igc_set_mac_type(hw); 148 if (ret_val) { 149 DEBUGOUT("ERROR: MAC type could not be set properly.\n"); 150 goto out; 151 } 152 153 if (!hw->hw_addr) { 154 DEBUGOUT("ERROR: Registers not mapped\n"); 155 ret_val = -IGC_ERR_CONFIG; 156 goto out; 157 } 158 159 /* 160 * Init function pointers to generic implementations. We do this first 161 * allowing a driver module to override it afterward. 162 */ 163 igc_init_mac_ops_generic(hw); 164 igc_init_phy_ops_generic(hw); 165 igc_init_nvm_ops_generic(hw); 166 167 /* 168 * Set up the init function pointers. These are functions within the 169 * adapter family file that sets up function pointers for the rest of 170 * the functions in that family. 171 */ 172 switch (hw->mac.type) { 173 case igc_i225: 174 igc_init_function_pointers_i225(hw); 175 break; 176 default: 177 DEBUGOUT("Hardware not supported\n"); 178 ret_val = -IGC_ERR_CONFIG; 179 break; 180 } 181 182 /* 183 * Initialize the rest of the function pointers. These require some 184 * register reads/writes in some cases. 185 */ 186 if (!(ret_val) && init_device) { 187 ret_val = igc_init_mac_params(hw); 188 if (ret_val) 189 goto out; 190 191 ret_val = igc_init_nvm_params(hw); 192 if (ret_val) 193 goto out; 194 195 ret_val = igc_init_phy_params(hw); 196 if (ret_val) 197 goto out; 198 } 199 200out: 201 return ret_val; 202} 203 204/** 205 * igc_get_bus_info - Obtain bus information for adapter 206 * @hw: pointer to the HW structure 207 * 208 * This will obtain information about the HW bus for which the 209 * adapter is attached and stores it in the hw structure. This is a 210 * function pointer entry point called by drivers. 211 **/ 212s32 igc_get_bus_info(struct igc_hw *hw) 213{ 214 if (hw->mac.ops.get_bus_info) 215 return hw->mac.ops.get_bus_info(hw); 216 217 return IGC_SUCCESS; 218} 219 220/** 221 * igc_clear_vfta - Clear VLAN filter table 222 * @hw: pointer to the HW structure 223 * 224 * This clears the VLAN filter table on the adapter. This is a function 225 * pointer entry point called by drivers. 226 **/ 227void igc_clear_vfta(struct igc_hw *hw) 228{ 229 if (hw->mac.ops.clear_vfta) 230 hw->mac.ops.clear_vfta(hw); 231} 232 233/** 234 * igc_write_vfta - Write value to VLAN filter table 235 * @hw: pointer to the HW structure 236 * @offset: the 32-bit offset in which to write the value to. 237 * @value: the 32-bit value to write at location offset. 238 * 239 * This writes a 32-bit value to a 32-bit offset in the VLAN filter 240 * table. This is a function pointer entry point called by drivers. 241 **/ 242void igc_write_vfta(struct igc_hw *hw, u32 offset, u32 value) 243{ 244 if (hw->mac.ops.write_vfta) 245 hw->mac.ops.write_vfta(hw, offset, value); 246} 247 248/** 249 * igc_update_mc_addr_list - Update Multicast addresses 250 * @hw: pointer to the HW structure 251 * @mc_addr_list: array of multicast addresses to program 252 * @mc_addr_count: number of multicast addresses to program 253 * 254 * Updates the Multicast Table Array. 255 * The caller must have a packed mc_addr_list of multicast addresses. 256 **/ 257void igc_update_mc_addr_list(struct igc_hw *hw, u8 *mc_addr_list, 258 u32 mc_addr_count) 259{ 260 if (hw->mac.ops.update_mc_addr_list) 261 hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, 262 mc_addr_count); 263} 264 265/** 266 * igc_force_mac_fc - Force MAC flow control 267 * @hw: pointer to the HW structure 268 * 269 * Force the MAC's flow control settings. Currently no func pointer exists 270 * and all implementations are handled in the generic version of this 271 * function. 272 **/ 273s32 igc_force_mac_fc(struct igc_hw *hw) 274{ 275 return igc_force_mac_fc_generic(hw); 276} 277 278/** 279 * igc_check_for_link - Check/Store link connection 280 * @hw: pointer to the HW structure 281 * 282 * This checks the link condition of the adapter and stores the 283 * results in the hw->mac structure. This is a function pointer entry 284 * point called by drivers. 285 **/ 286s32 igc_check_for_link(struct igc_hw *hw) 287{ 288 if (hw->mac.ops.check_for_link) 289 return hw->mac.ops.check_for_link(hw); 290 291 return -IGC_ERR_CONFIG; 292} 293 294/** 295 * igc_reset_hw - Reset hardware 296 * @hw: pointer to the HW structure 297 * 298 * This resets the hardware into a known state. This is a function pointer 299 * entry point called by drivers. 300 **/ 301s32 igc_reset_hw(struct igc_hw *hw) 302{ 303 if (hw->mac.ops.reset_hw) 304 return hw->mac.ops.reset_hw(hw); 305 306 return -IGC_ERR_CONFIG; 307} 308 309/** 310 * igc_init_hw - Initialize hardware 311 * @hw: pointer to the HW structure 312 * 313 * This inits the hardware readying it for operation. This is a function 314 * pointer entry point called by drivers. 315 **/ 316s32 igc_init_hw(struct igc_hw *hw) 317{ 318 if (hw->mac.ops.init_hw) 319 return hw->mac.ops.init_hw(hw); 320 321 return -IGC_ERR_CONFIG; 322} 323 324/** 325 * igc_setup_link - Configures link and flow control 326 * @hw: pointer to the HW structure 327 * 328 * This configures link and flow control settings for the adapter. This 329 * is a function pointer entry point called by drivers. While modules can 330 * also call this, they probably call their own version of this function. 331 **/ 332s32 igc_setup_link(struct igc_hw *hw) 333{ 334 if (hw->mac.ops.setup_link) 335 return hw->mac.ops.setup_link(hw); 336 337 return -IGC_ERR_CONFIG; 338} 339 340/** 341 * igc_get_speed_and_duplex - Returns current speed and duplex 342 * @hw: pointer to the HW structure 343 * @speed: pointer to a 16-bit value to store the speed 344 * @duplex: pointer to a 16-bit value to store the duplex. 345 * 346 * This returns the speed and duplex of the adapter in the two 'out' 347 * variables passed in. This is a function pointer entry point called 348 * by drivers. 349 **/ 350s32 igc_get_speed_and_duplex(struct igc_hw *hw, u16 *speed, u16 *duplex) 351{ 352 if (hw->mac.ops.get_link_up_info) 353 return hw->mac.ops.get_link_up_info(hw, speed, duplex); 354 355 return -IGC_ERR_CONFIG; 356} 357 358/** 359 * igc_disable_pcie_master - Disable PCI-Express master access 360 * @hw: pointer to the HW structure 361 * 362 * Disables PCI-Express master access and verifies there are no pending 363 * requests. Currently no func pointer exists and all implementations are 364 * handled in the generic version of this function. 365 **/ 366s32 igc_disable_pcie_master(struct igc_hw *hw) 367{ 368 return igc_disable_pcie_master_generic(hw); 369} 370 371/** 372 * igc_config_collision_dist - Configure collision distance 373 * @hw: pointer to the HW structure 374 * 375 * Configures the collision distance to the default value and is used 376 * during link setup. 377 **/ 378void igc_config_collision_dist(struct igc_hw *hw) 379{ 380 if (hw->mac.ops.config_collision_dist) 381 hw->mac.ops.config_collision_dist(hw); 382} 383 384/** 385 * igc_rar_set - Sets a receive address register 386 * @hw: pointer to the HW structure 387 * @addr: address to set the RAR to 388 * @index: the RAR to set 389 * 390 * Sets a Receive Address Register (RAR) to the specified address. 391 **/ 392int igc_rar_set(struct igc_hw *hw, u8 *addr, u32 index) 393{ 394 if (hw->mac.ops.rar_set) 395 return hw->mac.ops.rar_set(hw, addr, index); 396 397 return IGC_SUCCESS; 398} 399 400/** 401 * igc_validate_mdi_setting - Ensures valid MDI/MDIX SW state 402 * @hw: pointer to the HW structure 403 * 404 * Ensures that the MDI/MDIX SW state is valid. 405 **/ 406s32 igc_validate_mdi_setting(struct igc_hw *hw) 407{ 408 if (hw->mac.ops.validate_mdi_setting) 409 return hw->mac.ops.validate_mdi_setting(hw); 410 411 return IGC_SUCCESS; 412} 413 414/** 415 * igc_hash_mc_addr - Determines address location in multicast table 416 * @hw: pointer to the HW structure 417 * @mc_addr: Multicast address to hash. 418 * 419 * This hashes an address to determine its location in the multicast 420 * table. Currently no func pointer exists and all implementations 421 * are handled in the generic version of this function. 422 **/ 423u32 igc_hash_mc_addr(struct igc_hw *hw, u8 *mc_addr) 424{ 425 return igc_hash_mc_addr_generic(hw, mc_addr); 426} 427 428/** 429 * igc_check_reset_block - Verifies PHY can be reset 430 * @hw: pointer to the HW structure 431 * 432 * Checks if the PHY is in a state that can be reset or if manageability 433 * has it tied up. This is a function pointer entry point called by drivers. 434 **/ 435s32 igc_check_reset_block(struct igc_hw *hw) 436{ 437 if (hw->phy.ops.check_reset_block) 438 return hw->phy.ops.check_reset_block(hw); 439 440 return IGC_SUCCESS; 441} 442 443/** 444 * igc_read_phy_reg - Reads PHY register 445 * @hw: pointer to the HW structure 446 * @offset: the register to read 447 * @data: the buffer to store the 16-bit read. 448 * 449 * Reads the PHY register and returns the value in data. 450 * This is a function pointer entry point called by drivers. 451 **/ 452s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data) 453{ 454 if (hw->phy.ops.read_reg) 455 return hw->phy.ops.read_reg(hw, offset, data); 456 457 return IGC_SUCCESS; 458} 459 460/** 461 * igc_write_phy_reg - Writes PHY register 462 * @hw: pointer to the HW structure 463 * @offset: the register to write 464 * @data: the value to write. 465 * 466 * Writes the PHY register at offset with the value in data. 467 * This is a function pointer entry point called by drivers. 468 **/ 469s32 igc_write_phy_reg(struct igc_hw *hw, u32 offset, u16 data) 470{ 471 if (hw->phy.ops.write_reg) 472 return hw->phy.ops.write_reg(hw, offset, data); 473 474 return IGC_SUCCESS; 475} 476 477/** 478 * igc_release_phy - Generic release PHY 479 * @hw: pointer to the HW structure 480 * 481 * Return if silicon family does not require a semaphore when accessing the 482 * PHY. 483 **/ 484void igc_release_phy(struct igc_hw *hw) 485{ 486 if (hw->phy.ops.release) 487 hw->phy.ops.release(hw); 488} 489 490/** 491 * igc_acquire_phy - Generic acquire PHY 492 * @hw: pointer to the HW structure 493 * 494 * Return success if silicon family does not require a semaphore when 495 * accessing the PHY. 496 **/ 497s32 igc_acquire_phy(struct igc_hw *hw) 498{ 499 if (hw->phy.ops.acquire) 500 return hw->phy.ops.acquire(hw); 501 502 return IGC_SUCCESS; 503} 504 505/** 506 * igc_get_phy_info - Retrieves PHY information from registers 507 * @hw: pointer to the HW structure 508 * 509 * This function gets some information from various PHY registers and 510 * populates hw->phy values with it. This is a function pointer entry 511 * point called by drivers. 512 **/ 513s32 igc_get_phy_info(struct igc_hw *hw) 514{ 515 if (hw->phy.ops.get_info) 516 return hw->phy.ops.get_info(hw); 517 518 return IGC_SUCCESS; 519} 520 521/** 522 * igc_phy_hw_reset - Hard PHY reset 523 * @hw: pointer to the HW structure 524 * 525 * Performs a hard PHY reset. This is a function pointer entry point called 526 * by drivers. 527 **/ 528s32 igc_phy_hw_reset(struct igc_hw *hw) 529{ 530 if (hw->phy.ops.reset) 531 return hw->phy.ops.reset(hw); 532 533 return IGC_SUCCESS; 534} 535 536/** 537 * igc_set_d0_lplu_state - Sets low power link up state for D0 538 * @hw: pointer to the HW structure 539 * @active: boolean used to enable/disable lplu 540 * 541 * Success returns 0, Failure returns 1 542 * 543 * The low power link up (lplu) state is set to the power management level D0 544 * and SmartSpeed is disabled when active is true, else clear lplu for D0 545 * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU 546 * is used during Dx states where the power conservation is most important. 547 * During driver activity, SmartSpeed should be enabled so performance is 548 * maintained. This is a function pointer entry point called by drivers. 549 **/ 550s32 igc_set_d0_lplu_state(struct igc_hw *hw, bool active) 551{ 552 if (hw->phy.ops.set_d0_lplu_state) 553 return hw->phy.ops.set_d0_lplu_state(hw, active); 554 555 return IGC_SUCCESS; 556} 557 558/** 559 * igc_set_d3_lplu_state - Sets low power link up state for D3 560 * @hw: pointer to the HW structure 561 * @active: boolean used to enable/disable lplu 562 * 563 * Success returns 0, Failure returns 1 564 * 565 * The low power link up (lplu) state is set to the power management level D3 566 * and SmartSpeed is disabled when active is true, else clear lplu for D3 567 * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU 568 * is used during Dx states where the power conservation is most important. 569 * During driver activity, SmartSpeed should be enabled so performance is 570 * maintained. This is a function pointer entry point called by drivers. 571 **/ 572s32 igc_set_d3_lplu_state(struct igc_hw *hw, bool active) 573{ 574 if (hw->phy.ops.set_d3_lplu_state) 575 return hw->phy.ops.set_d3_lplu_state(hw, active); 576 577 return IGC_SUCCESS; 578} 579 580/** 581 * igc_read_mac_addr - Reads MAC address 582 * @hw: pointer to the HW structure 583 * 584 * Reads the MAC address out of the adapter and stores it in the HW structure. 585 * Currently no func pointer exists and all implementations are handled in the 586 * generic version of this function. 587 **/ 588s32 igc_read_mac_addr(struct igc_hw *hw) 589{ 590 if (hw->mac.ops.read_mac_addr) 591 return hw->mac.ops.read_mac_addr(hw); 592 593 return igc_read_mac_addr_generic(hw); 594} 595 596/** 597 * igc_read_pba_string - Read device part number string 598 * @hw: pointer to the HW structure 599 * @pba_num: pointer to device part number 600 * @pba_num_size: size of part number buffer 601 * 602 * Reads the product board assembly (PBA) number from the EEPROM and stores 603 * the value in pba_num. 604 * Currently no func pointer exists and all implementations are handled in the 605 * generic version of this function. 606 **/ 607s32 igc_read_pba_string(struct igc_hw *hw, u8 *pba_num, u32 pba_num_size) 608{ 609 return igc_read_pba_string_generic(hw, pba_num, pba_num_size); 610} 611 612/** 613 * igc_validate_nvm_checksum - Verifies NVM (EEPROM) checksum 614 * @hw: pointer to the HW structure 615 * 616 * Validates the NVM checksum is correct. This is a function pointer entry 617 * point called by drivers. 618 **/ 619s32 igc_validate_nvm_checksum(struct igc_hw *hw) 620{ 621 if (hw->nvm.ops.validate) 622 return hw->nvm.ops.validate(hw); 623 624 return -IGC_ERR_CONFIG; 625} 626 627/** 628 * igc_update_nvm_checksum - Updates NVM (EEPROM) checksum 629 * @hw: pointer to the HW structure 630 * 631 * Updates the NVM checksum. Currently no func pointer exists and all 632 * implementations are handled in the generic version of this function. 633 **/ 634s32 igc_update_nvm_checksum(struct igc_hw *hw) 635{ 636 if (hw->nvm.ops.update) 637 return hw->nvm.ops.update(hw); 638 639 return -IGC_ERR_CONFIG; 640} 641 642/** 643 * igc_reload_nvm - Reloads EEPROM 644 * @hw: pointer to the HW structure 645 * 646 * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the 647 * extended control register. 648 **/ 649void igc_reload_nvm(struct igc_hw *hw) 650{ 651 if (hw->nvm.ops.reload) 652 hw->nvm.ops.reload(hw); 653} 654 655/** 656 * igc_read_nvm - Reads NVM (EEPROM) 657 * @hw: pointer to the HW structure 658 * @offset: the word offset to read 659 * @words: number of 16-bit words to read 660 * @data: pointer to the properly sized buffer for the data. 661 * 662 * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function 663 * pointer entry point called by drivers. 664 **/ 665s32 igc_read_nvm(struct igc_hw *hw, u16 offset, u16 words, u16 *data) 666{ 667 if (hw->nvm.ops.read) 668 return hw->nvm.ops.read(hw, offset, words, data); 669 670 return -IGC_ERR_CONFIG; 671} 672 673/** 674 * igc_write_nvm - Writes to NVM (EEPROM) 675 * @hw: pointer to the HW structure 676 * @offset: the word offset to read 677 * @words: number of 16-bit words to write 678 * @data: pointer to the properly sized buffer for the data. 679 * 680 * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function 681 * pointer entry point called by drivers. 682 **/ 683s32 igc_write_nvm(struct igc_hw *hw, u16 offset, u16 words, u16 *data) 684{ 685 if (hw->nvm.ops.write) 686 return hw->nvm.ops.write(hw, offset, words, data); 687 688 return IGC_SUCCESS; 689} 690 691/** 692 * igc_power_up_phy - Restores link in case of PHY power down 693 * @hw: pointer to the HW structure 694 * 695 * The phy may be powered down to save power, to turn off link when the 696 * driver is unloaded, or wake on lan is not enabled (among others). 697 **/ 698void igc_power_up_phy(struct igc_hw *hw) 699{ 700 if (hw->phy.ops.power_up) 701 hw->phy.ops.power_up(hw); 702 703 igc_setup_link(hw); 704} 705 706/** 707 * igc_power_down_phy - Power down PHY 708 * @hw: pointer to the HW structure 709 * 710 * The phy may be powered down to save power, to turn off link when the 711 * driver is unloaded, or wake on lan is not enabled (among others). 712 **/ 713void igc_power_down_phy(struct igc_hw *hw) 714{ 715 if (hw->phy.ops.power_down) 716 hw->phy.ops.power_down(hw); 717} 718 719